diff options
author | Nicolas Noble <nicolasnoble@users.noreply.github.com> | 2015-03-06 17:40:46 -0800 |
---|---|---|
committer | Nicolas Noble <nicolasnoble@users.noreply.github.com> | 2015-03-06 17:40:46 -0800 |
commit | 3631e82c890de1ff0382ab3062b2d05193604046 (patch) | |
tree | 9f999024080fb56afb24684c24adb2235ed1dfcc /src | |
parent | 3aca2a624523e8bb27891d759b6fbbe71277be3d (diff) | |
parent | ede76da1b5cb17f0a9d62c4b93c023c2fbaccc1a (diff) |
Merge pull request #835 from ctiller/credit
C++ Credentials Rework
Diffstat (limited to 'src')
32 files changed, 409 insertions, 419 deletions
diff --git a/src/core/security/factories.c b/src/core/security/factories.c index c9701b9080..02267d5545 100644 --- a/src/core/security/factories.c +++ b/src/core/security/factories.c @@ -33,9 +33,9 @@ #include <string.h> +#include <grpc/grpc.h> #include "src/core/security/credentials.h" #include "src/core/security/security_context.h" -#include "src/core/surface/lame_client.h" #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/useful.h> @@ -50,31 +50,3 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, return grpc_secure_channel_create_with_factories( factories, GPR_ARRAY_SIZE(factories), creds, target, args); } - -grpc_server *grpc_secure_server_create(grpc_server_credentials *creds, - grpc_completion_queue *cq, - const grpc_channel_args *args) { - grpc_security_status status = GRPC_SECURITY_ERROR; - grpc_security_context *ctx = NULL; - grpc_server *server = NULL; - if (creds == NULL) return NULL; /* TODO(ctiller): Return lame server. */ - - if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) { - status = grpc_ssl_server_security_context_create( - grpc_ssl_server_credentials_get_config(creds), &ctx); - } else if (!strcmp(creds->type, - GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) { - ctx = grpc_fake_server_security_context_create(); - status = GRPC_SECURITY_OK; - } - - if (status != GRPC_SECURITY_OK) { - gpr_log(GPR_ERROR, - "Unable to create secure server with credentials of type %s.", - creds->type); - return NULL; /* TODO(ctiller): Return lame server. */ - } - server = grpc_secure_server_create_internal(cq, args, ctx); - grpc_security_context_unref(ctx); - return server; -} diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index 0dc37fa73c..62264e4105 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -42,7 +42,6 @@ #include "src/core/support/env.h" #include "src/core/support/file.h" #include "src/core/support/string.h" -#include "src/core/surface/lame_client.h" #include "src/core/transport/chttp2/alpn.h" #include <grpc/support/alloc.h> diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index bd6f8473cb..b15c553b82 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -33,6 +33,8 @@ #include <grpc/grpc.h> +#include <string.h> + #include "src/core/channel/http_filter.h" #include "src/core/channel/http_server_filter.h" #include "src/core/iomgr/endpoint.h" @@ -50,6 +52,7 @@ typedef struct grpc_server_secure_state { grpc_server *server; grpc_tcp_server *tcp; + grpc_security_context *ctx; int is_shutdown; gpr_mu mu; gpr_refcount refcount; @@ -61,6 +64,7 @@ static void state_ref(grpc_server_secure_state *state) { static void state_unref(grpc_server_secure_state *state) { if (gpr_unref(&state->refcount)) { + grpc_security_context_unref(state->ctx); gpr_free(state); } } @@ -99,15 +103,10 @@ static void on_secure_transport_setup_done(void *statep, static void on_accept(void *statep, grpc_endpoint *tcp) { grpc_server_secure_state *state = statep; - const grpc_channel_args *args = grpc_server_get_channel_args(state->server); - grpc_security_context *ctx = grpc_find_security_context_in_args(args); - GPR_ASSERT(ctx); state_ref(state); - grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, state); + grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, state); } -/* Note: the following code is the same with server_chttp2.c */ - /* Server callback: start listening on our ports */ static void start(grpc_server *server, void *statep, grpc_pollset **pollsets, size_t pollset_count) { @@ -126,7 +125,7 @@ static void destroy(grpc_server *server, void *statep) { state_unref(state); } -int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { +int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) { grpc_resolved_addresses *resolved = NULL; grpc_tcp_server *tcp = NULL; grpc_server_secure_state *state = NULL; @@ -134,7 +133,29 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { unsigned count = 0; int port_num = -1; int port_temp; + grpc_security_status status = GRPC_SECURITY_ERROR; + grpc_security_context *ctx = NULL; + + /* create security context */ + if (creds == NULL) goto error; + + if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) { + status = grpc_ssl_server_security_context_create( + grpc_ssl_server_credentials_get_config(creds), &ctx); + } else if (!strcmp(creds->type, + GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) { + ctx = grpc_fake_server_security_context_create(); + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, + "Unable to create secure server with credentials of type %s.", + creds->type); + goto error; + } + + /* resolve address */ resolved = grpc_blocking_resolve_address(addr, "https"); if (!resolved) { goto error; @@ -173,6 +194,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { state = gpr_malloc(sizeof(*state)); state->server = server; state->tcp = tcp; + state->ctx = ctx; state->is_shutdown = 0; gpr_mu_init(&state->mu); gpr_ref_init(&state->refcount, 1); @@ -184,11 +206,17 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { /* Error path: cleanup and return */ error: + if (ctx) { + grpc_security_context_unref(ctx); + } if (resolved) { grpc_resolved_addresses_destroy(resolved); } if (tcp) { grpc_tcp_server_destroy(tcp); } + if (state) { + gpr_free(state); + } return 0; } diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c index 57f6ddf0f7..b40c48381f 100644 --- a/src/core/surface/lame_client.c +++ b/src/core/surface/lame_client.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/lame_client.h" +#include <grpc/grpc.h> #include <string.h> diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc index 450cf67ac8..5380d3a232 100644 --- a/src/cpp/client/channel.cc +++ b/src/cpp/client/channel.cc @@ -53,43 +53,23 @@ namespace grpc { -Channel::Channel(const grpc::string &target, const ChannelArguments &args) - : target_(target) { - grpc_channel_args channel_args; - args.SetChannelArgs(&channel_args); - c_channel_ = grpc_channel_create( - target_.c_str(), channel_args.num_args > 0 ? &channel_args : nullptr); -} - -Channel::Channel(const grpc::string &target, - const std::unique_ptr<Credentials> &creds, - const ChannelArguments &args) - : target_(args.GetSslTargetNameOverride().empty() - ? target - : args.GetSslTargetNameOverride()) { - grpc_channel_args channel_args; - args.SetChannelArgs(&channel_args); - grpc_credentials *c_creds = creds ? creds->GetRawCreds() : nullptr; - c_channel_ = grpc_secure_channel_create( - c_creds, target.c_str(), - channel_args.num_args > 0 ? &channel_args : nullptr); -} +Channel::Channel(const grpc::string& target, grpc_channel* channel) + : target_(target), c_channel_(channel) {} Channel::~Channel() { grpc_channel_destroy(c_channel_); } -Call Channel::CreateCall(const RpcMethod &method, ClientContext *context, - CompletionQueue *cq) { - auto c_call = - grpc_channel_create_call( - c_channel_, cq->cq(), method.name(), - context->authority().empty() ? target_.c_str() - : context->authority().c_str(), - context->RawDeadline()); +Call Channel::CreateCall(const RpcMethod& method, ClientContext* context, + CompletionQueue* cq) { + auto c_call = grpc_channel_create_call(c_channel_, cq->cq(), method.name(), + context->authority().empty() + ? target_.c_str() + : context->authority().c_str(), + context->RawDeadline()); context->set_call(c_call); return Call(c_call, this, cq); } -void Channel::PerformOpsOnCall(CallOpBuffer *buf, Call *call) { +void Channel::PerformOpsOnCall(CallOpBuffer* buf, Call* call) { static const size_t MAX_OPS = 8; size_t nops = MAX_OPS; grpc_op ops[MAX_OPS]; diff --git a/src/cpp/client/channel.h b/src/cpp/client/channel.h index 63c6e2bde6..a1de3817e6 100644 --- a/src/cpp/client/channel.h +++ b/src/cpp/client/channel.h @@ -51,10 +51,7 @@ class StreamContextInterface; class Channel GRPC_FINAL : public ChannelInterface { public: - Channel(const grpc::string &target, const ChannelArguments &args); - Channel(const grpc::string &target, const std::unique_ptr<Credentials> &creds, - const ChannelArguments &args); - + Channel(const grpc::string &target, grpc_channel *c_channel); ~Channel() GRPC_OVERRIDE; virtual Call CreateCall(const RpcMethod &method, ClientContext *context, @@ -63,7 +60,7 @@ class Channel GRPC_FINAL : public ChannelInterface { private: const grpc::string target_; - grpc_channel *c_channel_; // owned + grpc_channel *const c_channel_; // owned }; } // namespace grpc diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 583e072799..57d215d0f3 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -40,14 +40,10 @@ namespace grpc { class ChannelArguments; -std::shared_ptr<ChannelInterface> CreateChannelDeprecated( - const grpc::string &target, const ChannelArguments &args) { - return std::shared_ptr<ChannelInterface>(new Channel(target, args)); -} - std::shared_ptr<ChannelInterface> CreateChannel( const grpc::string &target, const std::unique_ptr<Credentials> &creds, const ChannelArguments &args) { - return std::shared_ptr<ChannelInterface>(new Channel(target, creds, args)); + return creds ? creds->CreateChannel(target, args) : + std::shared_ptr<ChannelInterface>(new Channel(target, grpc_lame_client_channel_create())); } } // namespace grpc diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc index eff0892810..e806284988 100644 --- a/src/cpp/client/credentials.cc +++ b/src/cpp/client/credentials.cc @@ -31,98 +31,10 @@ * */ -#include <string> - -#include <grpc/grpc_security.h> -#include <grpc/support/log.h> - #include <grpc++/credentials.h> namespace grpc { -Credentials::Credentials(grpc_credentials *c_creds) : creds_(c_creds) {} - -Credentials::~Credentials() { grpc_credentials_release(creds_); } -grpc_credentials *Credentials::GetRawCreds() { return creds_; } - -std::unique_ptr<Credentials> CredentialsFactory::GoogleDefaultCredentials() { - grpc_credentials *c_creds = grpc_google_default_credentials_create(); - std::unique_ptr<Credentials> cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Builds SSL Credentials given SSL specific options -std::unique_ptr<Credentials> CredentialsFactory::SslCredentials( - const SslCredentialsOptions &options) { - grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { - options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; - - grpc_credentials *c_creds = grpc_ssl_credentials_create( - options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), - options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair); - std::unique_ptr<Credentials> cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Builds credentials for use when running in GCE -std::unique_ptr<Credentials> CredentialsFactory::ComputeEngineCredentials() { - grpc_credentials *c_creds = grpc_compute_engine_credentials_create(); - std::unique_ptr<Credentials> cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Builds service account credentials. -std::unique_ptr<Credentials> CredentialsFactory::ServiceAccountCredentials( - const grpc::string &json_key, const grpc::string &scope, - std::chrono::seconds token_lifetime) { - gpr_timespec lifetime = gpr_time_from_seconds( - token_lifetime.count() > 0 ? token_lifetime.count() : 0); - grpc_credentials *c_creds = grpc_service_account_credentials_create( - json_key.c_str(), scope.c_str(), lifetime); - std::unique_ptr<Credentials> cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Builds JWT credentials. -std::unique_ptr<Credentials> CredentialsFactory::JWTCredentials( - const grpc::string &json_key, std::chrono::seconds token_lifetime) { - gpr_timespec lifetime = gpr_time_from_seconds( - token_lifetime.count() > 0 ? token_lifetime.count() : 0); - grpc_credentials *c_creds = - grpc_jwt_credentials_create(json_key.c_str(), lifetime); - std::unique_ptr<Credentials> cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Builds IAM credentials. -std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials( - const grpc::string &authorization_token, - const grpc::string &authority_selector) { - grpc_credentials *c_creds = grpc_iam_credentials_create( - authorization_token.c_str(), authority_selector.c_str()); - std::unique_ptr<Credentials> cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Combines two credentials objects into a composite credentials. -std::unique_ptr<Credentials> CredentialsFactory::CompositeCredentials( - const std::unique_ptr<Credentials> &creds1, - const std::unique_ptr<Credentials> &creds2) { - // Note that we are not saving unique_ptrs to the two credentials - // passed in here. This is OK because the underlying C objects (i.e., - // creds1 and creds2) into grpc_composite_credentials_create will see their - // refcounts incremented. - grpc_credentials *c_creds = grpc_composite_credentials_create( - creds1->GetRawCreds(), creds2->GetRawCreds()); - std::unique_ptr<Credentials> cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} +Credentials::~Credentials() {} } // namespace grpc diff --git a/src/core/surface/secure_server_create.c b/src/cpp/client/insecure_credentials.cc index 1d5b927997..2dcfe69591 100644 --- a/src/core/surface/secure_server_create.c +++ b/src/cpp/client/insecure_credentials.cc @@ -31,27 +31,35 @@ * */ -#include <grpc/grpc.h> +#include <string> -#include "src/core/channel/channel_args.h" -#include "src/core/security/security_context.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/surface/server.h" +#include <grpc/grpc.h> #include <grpc/support/log.h> -grpc_server *grpc_secure_server_create_internal( - grpc_completion_queue *cq, const grpc_channel_args *args, - grpc_security_context *context) { - grpc_arg context_arg; - grpc_channel_args *args_copy; - grpc_server *server; - if (grpc_find_security_context_in_args(args) != NULL) { - gpr_log(GPR_ERROR, "Cannot set security context in channel args."); +#include <grpc++/channel_arguments.h> +#include <grpc++/config.h> +#include <grpc++/credentials.h> +#include "src/cpp/client/channel.h" + +namespace grpc { + +namespace { +class InsecureCredentialsImpl GRPC_FINAL : public Credentials { + public: + std::shared_ptr<grpc::ChannelInterface> CreateChannel( + const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE { + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return std::shared_ptr<ChannelInterface>(new Channel( + target, grpc_channel_create(target.c_str(), &channel_args))); } - context_arg = grpc_security_context_to_arg(context); - args_copy = grpc_channel_args_copy_and_add(args, &context_arg); - server = grpc_server_create_from_filters(cq, NULL, 0, args_copy); - grpc_channel_args_destroy(args_copy); - return server; + SecureCredentials* AsSecureCredentials() { return nullptr; } +}; +} // namespace + +std::unique_ptr<Credentials> InsecureCredentials() { + return std::unique_ptr<Credentials>(new InsecureCredentialsImpl()); } + +} // namespace grpc diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc new file mode 100644 index 0000000000..5eb5c54794 --- /dev/null +++ b/src/cpp/client/secure_credentials.cc @@ -0,0 +1,131 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <string> + +#include <grpc/grpc_security.h> +#include <grpc/support/log.h> + +#include <grpc++/channel_arguments.h> +#include <grpc++/config.h> +#include <grpc++/credentials.h> +#include "src/cpp/client/channel.h" + +namespace grpc { + +class SecureCredentials GRPC_FINAL : public Credentials { + public: + explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} + ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); } + grpc_credentials* GetRawCreds() { return c_creds_; } + + std::shared_ptr<grpc::ChannelInterface> CreateChannel( + const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE { + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return std::shared_ptr<ChannelInterface>(new Channel( + target, + grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args))); + } + + SecureCredentials* AsSecureCredentials() { return this; } + + private: + grpc_credentials* const c_creds_; +}; + +namespace { +std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) { + return creds == nullptr + ? nullptr + : std::unique_ptr<Credentials>(new SecureCredentials(creds)); +} +} // namespace + +std::unique_ptr<Credentials> GoogleDefaultCredentials() { + return WrapCredentials(grpc_google_default_credentials_create()); +} + +// Builds SSL Credentials given SSL specific options +std::unique_ptr<Credentials> SslCredentials( + const SslCredentialsOptions& options) { + grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { + options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; + + grpc_credentials* c_creds = grpc_ssl_credentials_create( + options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), + options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair); + return WrapCredentials(c_creds); +} + +// Builds credentials for use when running in GCE +std::unique_ptr<Credentials> ComputeEngineCredentials() { + return WrapCredentials(grpc_compute_engine_credentials_create()); +} + +// Builds service account credentials. +std::unique_ptr<Credentials> ServiceAccountCredentials( + const grpc::string& json_key, const grpc::string& scope, + std::chrono::seconds token_lifetime) { + gpr_timespec lifetime = gpr_time_from_seconds( + token_lifetime.count() > 0 ? token_lifetime.count() : 0); + return WrapCredentials(grpc_service_account_credentials_create( + json_key.c_str(), scope.c_str(), lifetime)); +} + +// Builds IAM credentials. +std::unique_ptr<Credentials> IAMCredentials( + const grpc::string& authorization_token, + const grpc::string& authority_selector) { + return WrapCredentials(grpc_iam_credentials_create( + authorization_token.c_str(), authority_selector.c_str())); +} + +// Combines two credentials objects into a composite credentials. +std::unique_ptr<Credentials> CompositeCredentials( + const std::unique_ptr<Credentials>& creds1, + const std::unique_ptr<Credentials>& creds2) { + // Note that we are not saving unique_ptrs to the two credentials + // passed in here. This is OK because the underlying C objects (i.e., + // creds1 and creds2) into grpc_composite_credentials_create will see their + // refcounts incremented. + SecureCredentials* s1 = creds1->AsSecureCredentials(); + SecureCredentials* s2 = creds2->AsSecureCredentials(); + if (s1 && s2) { + return WrapCredentials(grpc_composite_credentials_create( + s1->GetRawCreds(), s2->GetRawCreds())); + } + return nullptr; +} + +} // namespace grpc diff --git a/src/core/surface/lame_client.h b/src/cpp/server/insecure_server_credentials.cc index b13e8cb6ef..f5e4732f73 100644 --- a/src/core/surface/lame_client.h +++ b/src/cpp/server/insecure_server_credentials.cc @@ -31,12 +31,22 @@ * */ -#ifndef GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H -#define GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H +#include <grpc/grpc_security.h> +#include <grpc++/server_credentials.h> -#include <grpc/grpc.h> +namespace grpc { +namespace { +class InsecureServerCredentialsImpl GRPC_FINAL : public ServerCredentials { + public: + int AddPortToServer(const grpc::string& addr, + grpc_server* server) GRPC_OVERRIDE { + return grpc_server_add_http2_port(server, addr.c_str()); + } +}; +} // namespace -/* Create a lame client: this client fails every operation attempted on it. */ -grpc_channel *grpc_lame_client_channel_create(void); +std::shared_ptr<ServerCredentials> InsecureServerCredentials() { + return std::shared_ptr<ServerCredentials>(new InsecureServerCredentialsImpl()); +} -#endif /* GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H */ +} // namespace grpc diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc new file mode 100644 index 0000000000..ff35638503 --- /dev/null +++ b/src/cpp/server/secure_server_credentials.cc @@ -0,0 +1,71 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <grpc/grpc_security.h> + +#include <grpc++/server_credentials.h> + +namespace grpc { + +namespace { +class SecureServerCredentials GRPC_FINAL : public ServerCredentials { + public: + explicit SecureServerCredentials(grpc_server_credentials* creds) : creds_(creds) {} + ~SecureServerCredentials() GRPC_OVERRIDE { + grpc_server_credentials_release(creds_); + } + + int AddPortToServer(const grpc::string& addr, + grpc_server* server) GRPC_OVERRIDE { + return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_); + } + + private: + grpc_server_credentials* const creds_; +}; +} // namespace + +std::shared_ptr<ServerCredentials> SslServerCredentials( + const SslServerCredentialsOptions &options) { + std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs; + for (const auto &key_cert_pair : options.pem_key_cert_pairs) { + pem_key_cert_pairs.push_back( + {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()}); + } + grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create( + options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), + &pem_key_cert_pairs[0], pem_key_cert_pairs.size()); + return std::shared_ptr<ServerCredentials>(new SecureServerCredentials(c_creds)); +} + +} // namespace grpc diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 2a5a7fe5eb..e69032a657 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -170,26 +170,13 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { grpc_completion_queue* cq_; }; -Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, - ServerCredentials* creds) +Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned) : started_(false), shutdown_(false), num_running_cb_(0), + server_(grpc_server_create(cq_.cq(), nullptr)), thread_pool_(thread_pool), - thread_pool_owned_(thread_pool_owned), - secure_(creds != nullptr) { - if (creds) { - server_ = - grpc_secure_server_create(creds->GetRawCreds(), cq_.cq(), nullptr); - } else { - server_ = grpc_server_create(cq_.cq(), nullptr); - } -} - -Server::Server() { - // Should not be called. - GPR_ASSERT(false); -} + thread_pool_owned_(thread_pool_owned) {} Server::~Server() { std::unique_lock<std::mutex> lock(mu_); @@ -239,13 +226,9 @@ bool Server::RegisterAsyncService(AsynchronousService* service) { return true; } -int Server::AddPort(const grpc::string& addr) { +int Server::AddPort(const grpc::string& addr, ServerCredentials* creds) { GPR_ASSERT(!started_); - if (secure_) { - return grpc_server_add_secure_http2_port(server_, addr.c_str()); - } else { - return grpc_server_add_http2_port(server_, addr.c_str()); - } + return creds->AddPortToServer(addr, server_); } bool Server::Start() { diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index ae60f3d8b6..5de592334d 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -51,14 +51,10 @@ void ServerBuilder::RegisterAsyncService(AsynchronousService* service) { async_services_.push_back(service); } -void ServerBuilder::AddPort(const grpc::string& addr) { - ports_.push_back(addr); -} - -void ServerBuilder::SetCredentials( - const std::shared_ptr<ServerCredentials>& creds) { - GPR_ASSERT(!creds_); - creds_ = creds; +void ServerBuilder::AddPort(const grpc::string& addr, + std::shared_ptr<ServerCredentials> creds, + int* selected_port) { + ports_.push_back(Port{addr, creds, selected_port}); } void ServerBuilder::SetThreadPool(ThreadPoolInterface* thread_pool) { @@ -71,14 +67,13 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() { gpr_log(GPR_ERROR, "Mixing async and sync services is unsupported for now"); return nullptr; } - if (!thread_pool_ && services_.size()) { + if (!thread_pool_ && !services_.empty()) { int cores = gpr_cpu_num_cores(); if (!cores) cores = 4; thread_pool_ = new ThreadPool(cores); thread_pool_owned = true; } - std::unique_ptr<Server> server( - new Server(thread_pool_, thread_pool_owned, creds_.get())); + std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned)); for (auto* service : services_) { if (!server->RegisterService(service)) { return nullptr; @@ -90,8 +85,10 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() { } } for (auto& port : ports_) { - if (!server->AddPort(port)) { - return nullptr; + int r = server->AddPort(port.addr, port.creds.get()); + if (!r) return nullptr; + if (port.selected_port != nullptr) { + *port.selected_port = r; } } if (!server->Start()) { diff --git a/src/cpp/server/server_credentials.cc b/src/cpp/server/server_credentials.cc index 69ad000ccc..6bdb465baa 100644 --- a/src/cpp/server/server_credentials.cc +++ b/src/cpp/server/server_credentials.cc @@ -37,26 +37,6 @@ namespace grpc { -ServerCredentials::ServerCredentials(grpc_server_credentials *c_creds) - : creds_(c_creds) {} - -ServerCredentials::~ServerCredentials() { - grpc_server_credentials_release(creds_); -} - -grpc_server_credentials *ServerCredentials::GetRawCreds() { return creds_; } - -std::shared_ptr<ServerCredentials> ServerCredentialsFactory::SslCredentials( - const SslServerCredentialsOptions &options) { - std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs; - for (const auto &key_cert_pair : options.pem_key_cert_pairs) { - pem_key_cert_pairs.push_back( - {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()}); - } - grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create( - options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), - &pem_key_cert_pairs[0], pem_key_cert_pairs.size()); - return std::shared_ptr<ServerCredentials>(new ServerCredentials(c_creds)); -} +ServerCredentials::~ServerCredentials() {} } // namespace grpc diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc index 5050042daa..e47bac833b 100644 --- a/src/node/ext/server.cc +++ b/src/node/ext/server.cc @@ -165,19 +165,7 @@ NAN_METHOD(Server::New) { if (args[0]->IsUndefined()) { wrapped_server = grpc_server_create(queue, NULL); } else if (args[0]->IsObject()) { - grpc_server_credentials *creds = NULL; - Handle<Object> args_hash(args[0]->ToObject()->Clone()); - if (args_hash->HasOwnProperty(NanNew("credentials"))) { - Handle<Value> creds_value = args_hash->Get(NanNew("credentials")); - if (!ServerCredentials::HasInstance(creds_value)) { - return NanThrowTypeError( - "credentials arg must be a ServerCredentials object"); - } - ServerCredentials *creds_object = - ObjectWrap::Unwrap<ServerCredentials>(creds_value->ToObject()); - creds = creds_object->GetWrappedServerCredentials(); - args_hash->Delete(NanNew("credentials")); - } + Handle<Object> args_hash(args[0]->ToObject()); Handle<Array> keys(args_hash->GetOwnPropertyNames()); grpc_channel_args channel_args; channel_args.num_args = keys->Length(); @@ -204,11 +192,7 @@ NAN_METHOD(Server::New) { return NanThrowTypeError("Arg values must be strings"); } } - if (creds == NULL) { - wrapped_server = grpc_server_create(queue, &channel_args); - } else { - wrapped_server = grpc_secure_server_create(creds, queue, &channel_args); - } + wrapped_server = grpc_server_create(queue, &channel_args); free(channel_args.args); } else { return NanThrowTypeError("Server expects an object"); @@ -259,11 +243,19 @@ NAN_METHOD(Server::AddSecureHttp2Port) { "addSecureHttp2Port can only be called on a Server"); } if (!args[0]->IsString()) { - return NanThrowTypeError("addSecureHttp2Port's argument must be a String"); + return NanThrowTypeError( + "addSecureHttp2Port's first argument must be a String"); + } + if (!ServerCredentials::HasInstance(args[1])) { + return NanThrowTypeError( + "addSecureHttp2Port's second argument must be ServerCredentials"); } Server *server = ObjectWrap::Unwrap<Server>(args.This()); + ServerCredentials *creds = ObjectWrap::Unwrap<ServerCredentials>( + args[1]->ToObject()); NanReturnValue(NanNew<Number>(grpc_server_add_secure_http2_port( - server->wrapped_server, *NanUtf8String(args[0])))); + server->wrapped_server, *NanUtf8String(args[0]), + creds->GetWrappedServerCredentials()))); } NAN_METHOD(Server::Start) { diff --git a/src/node/interop/interop_server.js b/src/node/interop/interop_server.js index 125ede1746..8e5c03666f 100644 --- a/src/node/interop/interop_server.js +++ b/src/node/interop/interop_server.js @@ -165,16 +165,16 @@ function handleHalfDuplex(call) { function getServer(port, tls) { // TODO(mlumish): enable TLS functionality var options = {}; + var server_creds = null; if (tls) { var key_path = path.join(__dirname, '../test/data/server1.key'); var pem_path = path.join(__dirname, '../test/data/server1.pem'); var key_data = fs.readFileSync(key_path); var pem_data = fs.readFileSync(pem_path); - var server_creds = grpc.ServerCredentials.createSsl(null, - key_data, - pem_data); - options.credentials = server_creds; + server_creds = grpc.ServerCredentials.createSsl(null, + key_data, + pem_data); } var server = new Server({ 'grpc.testing.TestService' : { @@ -186,7 +186,7 @@ function getServer(port, tls) { halfDuplexCall: handleHalfDuplex } }, null, options); - var port_num = server.bind('0.0.0.0:' + port, tls); + var port_num = server.bind('0.0.0.0:' + port, server_creds); return {server: server, port: port_num}; } diff --git a/src/node/src/server.js b/src/node/src/server.js index 91dde02251..b72d110666 100644 --- a/src/node/src/server.js +++ b/src/node/src/server.js @@ -517,14 +517,15 @@ Server.prototype.register = function(name, handler, serialize, deserialize, }; /** - * Binds the server to the given port, with SSL enabled if secure is specified + * Binds the server to the given port, with SSL enabled if creds is given * @param {string} port The port that the server should bind on, in the format * "address:port" - * @param {boolean=} secure Whether the server should open a secure port + * @param {boolean=} creds Server credential object to be used for SSL. Pass + * nothing for an insecure port */ -Server.prototype.bind = function(port, secure) { - if (secure) { - return this._server.addSecureHttp2Port(port); +Server.prototype.bind = function(port, creds) { + if (creds) { + return this._server.addSecureHttp2Port(port, creds); } else { return this._server.addHttp2Port(port); } @@ -604,14 +605,14 @@ function makeServerConstructor(services) { } /** - * Binds the server to the given port, with SSL enabled if secure is specified + * Binds the server to the given port, with SSL enabled if creds is supplied * @param {string} port The port that the server should bind on, in the format * "address:port" - * @param {boolean=} secure Whether the server should open a secure port + * @param {boolean=} creds Credentials to use for SSL * @return {SurfaceServer} this */ - SurfaceServer.prototype.bind = function(port, secure) { - return this.inner_server.bind(port, secure); + SurfaceServer.prototype.bind = function(port, creds) { + return this.inner_server.bind(port, creds); }; /** diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c index 32cc19775c..00d08c6ecf 100644 --- a/src/php/ext/grpc/server.c +++ b/src/php/ext/grpc/server.c @@ -96,9 +96,6 @@ PHP_METHOD(Server, __construct) { zval *queue_obj; zval *args_array = NULL; grpc_channel_args args; - HashTable *array_hash; - zval **creds_obj = NULL; - wrapped_grpc_server_credentials *creds = NULL; /* "O|a" == 1 Object, 1 optional array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a", &queue_obj, grpc_ce_completion_queue, &args_array) == FAILURE) { @@ -114,28 +111,8 @@ PHP_METHOD(Server, __construct) { if (args_array == NULL) { server->wrapped = grpc_server_create(queue->wrapped, NULL); } else { - array_hash = Z_ARRVAL_P(args_array); - if (zend_hash_find(array_hash, "credentials", sizeof("credentials"), - (void **)&creds_obj) == SUCCESS) { - if (zend_get_class_entry(*creds_obj TSRMLS_CC) != - grpc_ce_server_credentials) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "credentials must be a ServerCredentials object", - 1 TSRMLS_CC); - return; - } - creds = (wrapped_grpc_server_credentials *)zend_object_store_get_object( - *creds_obj TSRMLS_CC); - zend_hash_del(array_hash, "credentials", sizeof("credentials")); - } php_grpc_read_args_array(args_array, &args); - if (creds == NULL) { - server->wrapped = grpc_server_create(queue->wrapped, &args); - } else { - gpr_log(GPR_DEBUG, "Initialized secure server"); - server->wrapped = - grpc_secure_server_create(creds->wrapped, queue->wrapped, &args); - } + server->wrapped = grpc_server_create(queue->wrapped, &args); efree(args.args); } } @@ -187,14 +164,21 @@ PHP_METHOD(Server, add_secure_http2_port) { (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; int addr_len; - /* "s" == 1 string */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) == + zval *creds_obj; + /* "sO" == 1 string, 1 object */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len, + &creds_obj, grpc_ce_server_credentials) == FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "add_http2_port expects a string", 1 TSRMLS_CC); + zend_throw_exception( + spl_ce_InvalidArgumentException, + "add_http2_port expects a string and a ServerCredentials", 1 TSRMLS_CC); return; } - RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr)); + wrapped_grpc_server_credentials *creds = + (wrapped_grpc_server_credentials *)zend_object_store_get_object( + creds_obj TSRMLS_CC); + RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr, + creds->wrapped)); } /** diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php index c23dd791ac..896afeac49 100755 --- a/src/php/tests/unit_tests/SecureEndToEndTest.php +++ b/src/php/tests/unit_tests/SecureEndToEndTest.php @@ -41,9 +41,9 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{ null, file_get_contents(dirname(__FILE__) . '/../data/server1.key'), file_get_contents(dirname(__FILE__) . '/../data/server1.pem')); - $this->server = new Grpc\Server($this->server_queue, - ['credentials' => $server_credentials]); - $port = $this->server->add_secure_http2_port('0.0.0.0:0'); + $this->server = new Grpc\Server($this->server_queue); + $port = $this->server->add_secure_http2_port('0.0.0.0:0', + $server_credentials); $this->channel = new Grpc\Channel( 'localhost:' . $port, [ diff --git a/src/python/src/grpc/_adapter/_c_test.py b/src/python/src/grpc/_adapter/_c_test.py index e11835746b..437a6730cd 100644 --- a/src/python/src/grpc/_adapter/_c_test.py +++ b/src/python/src/grpc/_adapter/_c_test.py @@ -93,7 +93,7 @@ class _CTest(unittest.TestCase): _c.init() completion_queue = _c.CompletionQueue() - server = _c.Server(completion_queue, None) + server = _c.Server(completion_queue) server.add_http2_addr('[::]:0') server.start() server.stop() @@ -103,7 +103,7 @@ class _CTest(unittest.TestCase): service_tag = object() completion_queue = _c.CompletionQueue() - server = _c.Server(completion_queue, None) + server = _c.Server(completion_queue) server.add_http2_addr('[::]:0') server.start() server.service(service_tag) @@ -120,7 +120,7 @@ class _CTest(unittest.TestCase): del completion_queue completion_queue = _c.CompletionQueue() - server = _c.Server(completion_queue, None) + server = _c.Server(completion_queue) server.add_http2_addr('[::]:0') server.start() thread = threading.Thread(target=completion_queue.get, args=(_FUTURE,)) diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py index 03e3f473a3..b04ac1c950 100644 --- a/src/python/src/grpc/_adapter/_low_test.py +++ b/src/python/src/grpc/_adapter/_low_test.py @@ -82,7 +82,7 @@ class EchoTest(unittest.TestCase): self.host = 'localhost' self.server_completion_queue = _low.CompletionQueue() - self.server = _low.Server(self.server_completion_queue, None) + self.server = _low.Server(self.server_completion_queue) port = self.server.add_http2_addr('[::]:0') self.server.start() @@ -260,7 +260,7 @@ class CancellationTest(unittest.TestCase): self.host = 'localhost' self.server_completion_queue = _low.CompletionQueue() - self.server = _low.Server(self.server_completion_queue, None) + self.server = _low.Server(self.server_completion_queue) port = self.server.add_http2_addr('[::]:0') self.server.start() diff --git a/src/python/src/grpc/_adapter/_server.c b/src/python/src/grpc/_adapter/_server.c index ae7ae5b5d2..181b6c21fc 100644 --- a/src/python/src/grpc/_adapter/_server.c +++ b/src/python/src/grpc/_adapter/_server.c @@ -42,30 +42,16 @@ static int pygrpc_server_init(Server *self, PyObject *args, PyObject *kwds) { const PyObject *completion_queue; - PyObject *server_credentials; - static char *kwlist[] = {"completion_queue", "server_credentials", NULL}; + static char *kwlist[] = {"completion_queue", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O:Server", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:Server", kwlist, &pygrpc_CompletionQueueType, - &completion_queue, &server_credentials)) { - return -1; - } - if (server_credentials == Py_None) { - self->c_server = grpc_server_create( - ((CompletionQueue *)completion_queue)->c_completion_queue, NULL); - return 0; - } else if (PyObject_TypeCheck(server_credentials, - &pygrpc_ServerCredentialsType)) { - self->c_server = grpc_secure_server_create( - ((ServerCredentials *)server_credentials)->c_server_credentials, - ((CompletionQueue *)completion_queue)->c_completion_queue, NULL); - return 0; - } else { - PyErr_Format(PyExc_TypeError, - "server_credentials must be _grpc.ServerCredentials, not %s", - Py_TYPE(server_credentials)->tp_name); + &completion_queue)) { return -1; } + self->c_server = grpc_server_create( + ((CompletionQueue *)completion_queue)->c_completion_queue, NULL); + return 0; } static void pygrpc_server_dealloc(Server *self) { @@ -92,13 +78,21 @@ static PyObject *pygrpc_server_add_http2_addr(Server *self, PyObject *args) { } static PyObject *pygrpc_server_add_secure_http2_addr(Server *self, - PyObject *args) { + PyObject *args, + PyObject *kwargs) { const char *addr; + PyObject *server_credentials; + static char *kwlist[] = {"addr", "server_credentials", NULL}; int port; - if (!PyArg_ParseTuple(args, "s:add_secure_http2_addr", &addr)) { + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!:add_secure_http2_addr", + kwlist, &addr, &pygrpc_ServerCredentialsType, + &server_credentials)) { return NULL; } - port = grpc_server_add_secure_http2_port(self->c_server, addr); + port = grpc_server_add_secure_http2_port( + self->c_server, addr, + ((ServerCredentials *)server_credentials)->c_server_credentials); if (port == 0) { PyErr_SetString(PyExc_RuntimeError, "Couldn't add port to server!"); return NULL; @@ -138,8 +132,7 @@ static PyMethodDef methods[] = { METH_VARARGS, "Add a secure HTTP2 address."}, {"start", (PyCFunction)pygrpc_server_start, METH_NOARGS, "Starts the server."}, - {"service", (PyCFunction)pygrpc_server_service, METH_O, - "Services a call."}, + {"service", (PyCFunction)pygrpc_server_service, METH_O, "Services a call."}, {"stop", (PyCFunction)pygrpc_server_stop, METH_NOARGS, "Stops the server."}, {NULL}}; diff --git a/src/python/src/grpc/_adapter/fore.py b/src/python/src/grpc/_adapter/fore.py index b08b9f48bc..6ef9e60006 100644 --- a/src/python/src/grpc/_adapter/fore.py +++ b/src/python/src/grpc/_adapter/fore.py @@ -280,13 +280,14 @@ class ForeLink(ticket_interfaces.ForeLink, activated.Activated): 0 if self._requested_port is None else self._requested_port) self._completion_queue = _low.CompletionQueue() if self._root_certificates is None and not self._key_chain_pairs: - self._server = _low.Server(self._completion_queue, None) + self._server = _low.Server(self._completion_queue) self._port = self._server.add_http2_addr(address) else: server_credentials = _low.ServerCredentials( self._root_certificates, self._key_chain_pairs) - self._server = _low.Server(self._completion_queue, server_credentials) - self._port = self._server.add_secure_http2_addr(address) + self._server = _low.Server(self._completion_queue) + self._port = self._server.add_secure_http2_addr( + address, server_credentials) self._server.start() self._server.service(None) diff --git a/src/ruby/bin/interop/interop_server.rb b/src/ruby/bin/interop/interop_server.rb index b3b7d0c5a3..0819ba9bbc 100755 --- a/src/ruby/bin/interop/interop_server.rb +++ b/src/ruby/bin/interop/interop_server.rb @@ -176,12 +176,11 @@ end def main opts = parse_options host = "0.0.0.0:#{opts['port']}" + s = GRPC::RpcServer.new if opts['secure'] - s = GRPC::RpcServer.new(creds: test_server_creds) - s.add_http2_port(host, true) + s.add_http2_port(host, test_server_creds) logger.info("... running securely on #{host}") else - s = GRPC::RpcServer.new s.add_http2_port(host) logger.info("... running insecurely on #{host}") end diff --git a/src/ruby/bin/math_server.rb b/src/ruby/bin/math_server.rb index 93277e3932..5cc7613489 100755 --- a/src/ruby/bin/math_server.rb +++ b/src/ruby/bin/math_server.rb @@ -173,12 +173,11 @@ def main end end.parse! + s = GRPC::RpcServer.new if options['secure'] - s = GRPC::RpcServer.new(creds: test_server_creds) - s.add_http2_port(options['host'], true) + s.add_http2_port(options['host'], test_server_creds) logger.info("... running securely on #{options['host']}") else - s = GRPC::RpcServer.new s.add_http2_port(options['host']) logger.info("... running insecurely on #{options['host']}") end diff --git a/src/ruby/bin/noproto_server.rb b/src/ruby/bin/noproto_server.rb index 435f8f4ebf..9979cb7ebb 100755 --- a/src/ruby/bin/noproto_server.rb +++ b/src/ruby/bin/noproto_server.rb @@ -95,12 +95,11 @@ def main end end.parse! + s = GRPC::RpcServer.new if options['secure'] - s = GRPC::RpcServer.new(creds: test_server_creds) - s.add_http2_port(options['host'], true) + s.add_http2_port(options['host'], test_server_creds) logger.info("... running securely on #{options['host']}") else - s = GRPC::RpcServer.new s.add_http2_port(options['host']) logger.info("... running insecurely on #{options['host']}") end diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c index 5954e27d02..c54f02e87a 100644 --- a/src/ruby/ext/grpc/rb_server.c +++ b/src/ruby/ext/grpc/rb_server.c @@ -97,35 +97,19 @@ static VALUE grpc_rb_server_alloc(VALUE cls) { /* call-seq: cq = CompletionQueue.new - insecure_server = Server.new(cq, {'arg1': 'value1'}) - server_creds = ... - secure_server = Server.new(cq, {'arg1': 'value1'}, server_creds) + server = Server.new(cq, {'arg1': 'value1'}) Initializes server instances. */ -static VALUE grpc_rb_server_init(int argc, VALUE *argv, VALUE self) { - VALUE cqueue = Qnil; - VALUE credentials = Qnil; - VALUE channel_args = Qnil; +static VALUE grpc_rb_server_init(VALUE self, VALUE cqueue, VALUE channel_args) { grpc_completion_queue *cq = NULL; - grpc_server_credentials *creds = NULL; grpc_rb_server *wrapper = NULL; grpc_server *srv = NULL; grpc_channel_args args; MEMZERO(&args, grpc_channel_args, 1); - - /* "21" == 2 mandatory args, 1 (credentials) is optional */ - rb_scan_args(argc, argv, "21", &cqueue, &channel_args, &credentials); cq = grpc_rb_get_wrapped_completion_queue(cqueue); - Data_Get_Struct(self, grpc_rb_server, wrapper); grpc_rb_hash_convert_to_channel_args(channel_args, &args); srv = grpc_server_create(cq, &args); - if (credentials == Qnil) { - srv = grpc_server_create(cq, &args); - } else { - creds = grpc_rb_get_wrapped_server_credentials(credentials); - srv = grpc_secure_server_create(creds, cq, &args); - } if (args.args != NULL) { xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */ @@ -215,33 +199,36 @@ static VALUE grpc_rb_server_destroy(VALUE self) { // secure port server_creds = ... - secure_server = Server.new(cq, {'arg1': 'value1'}, creds) - secure_server.add_http_port('mydomain:7575', True) + secure_server = Server.new(cq, {'arg1': 'value1'}) + secure_server.add_http_port('mydomain:7575', server_creds) Adds a http2 port to server */ static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) { VALUE port = Qnil; - VALUE is_secure = Qnil; + VALUE rb_creds = Qnil; grpc_rb_server *s = NULL; + grpc_server_credentials *creds = NULL; int recvd_port = 0; - /* "11" == 1 mandatory args, 1 (is_secure) is optional */ - rb_scan_args(argc, argv, "11", &port, &is_secure); + /* "11" == 1 mandatory args, 1 (rb_creds) is optional */ + rb_scan_args(argc, argv, "11", &port, &rb_creds); Data_Get_Struct(self, grpc_rb_server, s); if (s->wrapped == NULL) { rb_raise(rb_eRuntimeError, "closed!"); return Qnil; - } else if (is_secure == Qnil || TYPE(is_secure) != T_TRUE) { + } else if (rb_creds == Qnil) { recvd_port = grpc_server_add_http2_port(s->wrapped, StringValueCStr(port)); if (recvd_port == 0) { rb_raise(rb_eRuntimeError, "could not add port %s to server, not sure why", StringValueCStr(port)); } - } else if (TYPE(is_secure) != T_FALSE) { + } else { + creds = grpc_rb_get_wrapped_server_credentials(rb_creds); recvd_port = - grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port)); + grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port), + creds); if (recvd_port == 0) { rb_raise(rb_eRuntimeError, "could not add secure port %s to server, not sure why", @@ -258,7 +245,7 @@ void Init_grpc_server() { rb_define_alloc_func(rb_cServer, grpc_rb_server_alloc); /* Provides a ruby constructor and support for dup/clone. */ - rb_define_method(rb_cServer, "initialize", grpc_rb_server_init, -1); + rb_define_method(rb_cServer, "initialize", grpc_rb_server_init, 2); rb_define_method(rb_cServer, "initialize_copy", grpc_rb_server_init_copy, 1); /* Add the server methods. */ diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 6938f71892..35e84023be 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -81,7 +81,6 @@ module GRPC max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS, poll_period:INFINITE_FUTURE, completion_queue_override:nil, - creds:nil, server_override:nil, **kw) if completion_queue_override.nil? @@ -95,13 +94,7 @@ module GRPC @cq = cq if server_override.nil? - if creds.nil? - srv = Core::Server.new(@cq, kw) - elsif !creds.is_a? Core::ServerCredentials - fail(ArgumentError, 'not a ServerCredentials') - else - srv = Core::Server.new(@cq, kw, creds) - end + srv = Core::Server.new(@cq, kw) else srv = server_override fail(ArgumentError, 'not a Server') unless srv.is_a? Core::Server diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb index 35d9db1a89..49a2d3bb4d 100644 --- a/src/ruby/spec/client_server_spec.rb +++ b/src/ruby/spec/client_server_spec.rb @@ -350,8 +350,8 @@ describe 'the secure http client/server' do @client_queue = GRPC::Core::CompletionQueue.new @server_queue = GRPC::Core::CompletionQueue.new server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) - @server = GRPC::Core::Server.new(@server_queue, nil, server_creds) - server_port = @server.add_http2_port(server_host, true) + @server = GRPC::Core::Server.new(@server_queue, nil) + server_port = @server.add_http2_port(server_host, server_creds) @server.start args = { Channel::SSL_TARGET => 'foo.test.google.fr' } @ch = Channel.new("0.0.0.0:#{server_port}", args, @@ -362,11 +362,9 @@ describe 'the secure http client/server' do @server.close end - # TODO: uncomment after updating the to the new c api it_behaves_like 'basic GRPC message delivery is OK' do end - # TODO: uncomment after updating the to the new c api it_behaves_like 'GRPC metadata delivery works OK' do end end diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb index e8c7060446..d5421d400c 100644 --- a/src/ruby/spec/generic/rpc_server_spec.rb +++ b/src/ruby/spec/generic/rpc_server_spec.rb @@ -164,19 +164,6 @@ describe GRPC::RpcServer do expect(&blk).to raise_error end - it 'can be created with the creds as valid ServerCedentials' do - certs = load_test_certs - server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) - blk = proc do - opts = { - a_channel_arg: 'an_arg', - creds: server_creds - } - RpcServer.new(**opts) - end - expect(&blk).to_not raise_error - end - it 'can be created with a server override' do opts = { a_channel_arg: 'an_arg', server_override: @server } blk = proc do diff --git a/src/ruby/spec/server_spec.rb b/src/ruby/spec/server_spec.rb index 5b81f19537..a47e484f97 100644 --- a/src/ruby/spec/server_spec.rb +++ b/src/ruby/spec/server_spec.rb @@ -118,10 +118,11 @@ describe Server do end describe 'for secure servers' do + let(:cert) { create_test_cert } it 'runs without failing' do blk = proc do s = Server.new(@cq, nil) - s.add_http2_port('localhost:0', true) + s.add_http2_port('localhost:0', cert) s.close end expect(&blk).to_not raise_error @@ -130,7 +131,7 @@ describe Server do it 'fails if the server is closed' do s = Server.new(@cq, nil) s.close - blk = proc { s.add_http2_port('localhost:0', true) } + blk = proc { s.add_http2_port('localhost:0', cert) } expect(&blk).to raise_error(RuntimeError) end end @@ -138,7 +139,7 @@ describe Server do shared_examples '#new' do it 'takes a completion queue with nil channel args' do - expect { Server.new(@cq, nil, create_test_cert) }.to_not raise_error + expect { Server.new(@cq, nil) }.to_not raise_error end it 'does not take a hash with bad keys as channel args' do @@ -195,14 +196,6 @@ describe Server do it_behaves_like '#new' end - describe '#new with a secure channel' do - def construct_with_args(a) - proc { Server.new(@cq, a, create_test_cert) } - end - - it_behaves_like '#new' - end - def start_a_server s = Server.new(@cq, nil) s.add_http2_port('0.0.0.0:0') |