diff options
Diffstat (limited to 'src/core/security')
-rw-r--r-- | src/core/security/auth.c | 5 | ||||
-rw-r--r-- | src/core/security/auth.h | 2 | ||||
-rw-r--r-- | src/core/security/credentials.c | 21 | ||||
-rw-r--r-- | src/core/security/credentials.h | 12 | ||||
-rw-r--r-- | src/core/security/factories.c | 80 | ||||
-rw-r--r-- | src/core/security/google_root_certs.h | 2 | ||||
-rw-r--r-- | src/core/security/secure_endpoint.h | 2 | ||||
-rw-r--r-- | src/core/security/secure_transport_setup.h | 2 | ||||
-rw-r--r-- | src/core/security/security_context.c | 131 | ||||
-rw-r--r-- | src/core/security/security_context.h | 36 | ||||
-rw-r--r-- | src/core/security/server_secure_chttp2.c | 3 |
11 files changed, 190 insertions, 106 deletions
diff --git a/src/core/security/auth.c b/src/core/security/auth.c index f743b25838..e36bf2382f 100644 --- a/src/core/security/auth.c +++ b/src/core/security/auth.c @@ -157,6 +157,5 @@ static void destroy_channel_elem(grpc_channel_element *elem) { } const grpc_channel_filter grpc_client_auth_filter = { - call_op, channel_op, sizeof(call_data), - init_call_elem, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, "auth"}; + call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem, + sizeof(channel_data), init_channel_elem, destroy_channel_elem, "auth"}; diff --git a/src/core/security/auth.h b/src/core/security/auth.h index 0b279f8740..94fa2aba7d 100644 --- a/src/core/security/auth.h +++ b/src/core/security/auth.h @@ -38,4 +38,4 @@ extern const grpc_channel_filter grpc_client_auth_filter; -#endif /* __GRPC_INTERNAL_SECURITY_AUTH_H__ */ +#endif /* __GRPC_INTERNAL_SECURITY_AUTH_H__ */ diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index c99ac8021d..d3bba0fb1f 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -819,6 +819,26 @@ const grpc_credentials_array *grpc_composite_credentials_get_credentials( return &c->inner; } +grpc_credentials *grpc_credentials_contains_type( + grpc_credentials *creds, const char *type, + grpc_credentials **composite_creds) { + size_t i; + if (!strcmp(creds->type, type)) { + if (composite_creds != NULL) *composite_creds = NULL; + return creds; + } else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) { + const grpc_credentials_array *inner_creds_array = + grpc_composite_credentials_get_credentials(creds); + for (i = 0; i < inner_creds_array->num_creds; i++) { + if (!strcmp(type, inner_creds_array->creds_array[i]->type)) { + if (composite_creds != NULL) *composite_creds = creds; + return inner_creds_array->creds_array[i]; + } + } + } + return NULL; +} + /* -- IAM credentials. -- */ typedef struct { @@ -877,4 +897,3 @@ grpc_credentials *grpc_iam_credentials_create(const char *token, /* -- Default credentials TODO(jboeuf). -- */ grpc_credentials *grpc_default_credentials_create(void) { return NULL; } - diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index 036a44493e..4a2532d7c4 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -108,6 +108,14 @@ typedef struct { const grpc_credentials_array *grpc_composite_credentials_get_credentials( grpc_credentials *composite_creds); +/* Returns creds if creds is of the specified type or the inner creds of the + specified type (if found), if the creds is of type COMPOSITE. + If composite_creds is not NULL, *composite_creds will point to creds if of + type COMPOSITE in case of success. */ +grpc_credentials *grpc_credentials_contains_type( + grpc_credentials *creds, const char *type, + grpc_credentials **composite_creds); + /* Exposed for testing only. */ grpc_credentials_status grpc_oauth2_token_fetcher_credentials_parse_server_response( @@ -118,7 +126,6 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response( grpc_credentials *grpc_fake_oauth2_credentials_create( const char *token_md_value, int is_async); - /* --- grpc_server_credentials. --- */ typedef struct { @@ -136,5 +143,4 @@ struct grpc_server_credentials { const grpc_ssl_config *grpc_ssl_server_credentials_get_config( const grpc_server_credentials *ssl_creds); - -#endif /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */ +#endif /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */ diff --git a/src/core/security/factories.c b/src/core/security/factories.c new file mode 100644 index 0000000000..d89c692989 --- /dev/null +++ b/src/core/security/factories.c @@ -0,0 +1,80 @@ +/* + * + * Copyright 2014, 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.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> + +grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, + const char *target, + const grpc_channel_args *args) { + grpc_secure_channel_factory factories[] = { + {GRPC_CREDENTIALS_TYPE_SSL, grpc_ssl_channel_create}, + {GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY, + grpc_fake_transport_security_channel_create}}; + 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/google_root_certs.h b/src/core/security/google_root_certs.h index 4bcfaddcdb..30ed16c03b 100644 --- a/src/core/security/google_root_certs.h +++ b/src/core/security/google_root_certs.h @@ -37,4 +37,4 @@ extern unsigned char grpc_google_root_certs[]; extern unsigned int grpc_google_root_certs_size; -#endif /* __GRPC_INTERNAL_SECURITY_GOOGLE_ROOT_CERTS_H__ */ +#endif /* __GRPC_INTERNAL_SECURITY_GOOGLE_ROOT_CERTS_H__ */ diff --git a/src/core/security/secure_endpoint.h b/src/core/security/secure_endpoint.h index d0f0fa7d5b..20143150e0 100644 --- a/src/core/security/secure_endpoint.h +++ b/src/core/security/secure_endpoint.h @@ -44,4 +44,4 @@ grpc_endpoint *grpc_secure_endpoint_create( struct tsi_frame_protector *protector, grpc_endpoint *to_wrap, gpr_slice *leftover_slices, size_t leftover_nslices); -#endif /* __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__ */ +#endif /* __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__ */ diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/secure_transport_setup.h index 50f2b08529..b13d065fbf 100644 --- a/src/core/security/secure_transport_setup.h +++ b/src/core/security/secure_transport_setup.h @@ -50,4 +50,4 @@ void grpc_setup_secure_transport(grpc_security_context *ctx, grpc_secure_transport_setup_done_cb cb, void *user_data); -#endif /* __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__ */ +#endif /* __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__ */ diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index 13b9a847ee..d519ecab87 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -100,8 +100,7 @@ grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx) { return result; } -grpc_security_context *grpc_security_context_from_arg( - const grpc_arg *arg) { +grpc_security_context *grpc_security_context_from_arg(const grpc_arg *arg) { if (strcmp(arg->key, GRPC_SECURITY_CONTEXT_ARG)) return NULL; if (arg->type != GRPC_ARG_POINTER) { gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, @@ -140,9 +139,7 @@ static void fake_channel_destroy(grpc_security_context *ctx) { gpr_free(ctx); } -static void fake_server_destroy(grpc_security_context *ctx) { - gpr_free(ctx); -} +static void fake_server_destroy(grpc_security_context *ctx) { gpr_free(ctx); } static grpc_security_status fake_channel_create_handshaker( grpc_security_context *ctx, tsi_handshaker **handshaker) { @@ -234,8 +231,7 @@ static void ssl_channel_destroy(grpc_security_context *ctx) { } static void ssl_server_destroy(grpc_security_context *ctx) { - grpc_ssl_server_security_context *c = - (grpc_ssl_server_security_context *)ctx; + grpc_ssl_server_security_context *c = (grpc_ssl_server_security_context *)ctx; if (c->handshaker_factory != NULL) { tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); } @@ -267,8 +263,7 @@ static grpc_security_status ssl_channel_create_handshaker( static grpc_security_status ssl_server_create_handshaker( grpc_security_context *ctx, tsi_handshaker **handshaker) { - grpc_ssl_server_security_context *c = - (grpc_ssl_server_security_context *)ctx; + grpc_ssl_server_security_context *c = (grpc_ssl_server_security_context *)ctx; return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker); } @@ -438,20 +433,19 @@ error: return GRPC_SECURITY_ERROR; } - - /* -- High level objects. -- */ -static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds, - const grpc_ssl_config *config, - const char *target, - const grpc_channel_args *args) { +grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds, + grpc_credentials *request_metadata_creds, + const char *target, + const grpc_channel_args *args) { grpc_channel_security_context *ctx = NULL; grpc_channel *channel = NULL; grpc_security_status status = GRPC_SECURITY_OK; size_t i = 0; const char *secure_peer_name = target; - for (i = 0; i < args->num_args; i++) { + + for (i = 0; args && i < args->num_args; i++) { grpc_arg *arg = &args->args[i]; if (!strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) && arg->type == GRPC_ARG_STRING) { @@ -459,8 +453,9 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds, break; } } - status = grpc_ssl_channel_security_context_create(creds, config, - secure_peer_name, &ctx); + status = grpc_ssl_channel_security_context_create( + request_metadata_creds, grpc_ssl_credentials_get_config(ssl_creds), + secure_peer_name, &ctx); if (status != GRPC_SECURITY_OK) { return grpc_lame_client_channel_create(); } @@ -469,58 +464,47 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds, return channel; } - -static grpc_credentials *get_creds_from_composite( - grpc_credentials *composite_creds, const char *type) { - size_t i; - const grpc_credentials_array *inner_creds_array = - grpc_composite_credentials_get_credentials(composite_creds); - for (i = 0; i < inner_creds_array->num_creds; i++) { - if (!strcmp(type, inner_creds_array->creds_array[i]->type)) { - return inner_creds_array->creds_array[i]; - } - } - return NULL; +grpc_channel *grpc_fake_transport_security_channel_create( + grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds, + const char *target, const grpc_channel_args *args) { + grpc_channel_security_context *ctx = + grpc_fake_channel_security_context_create(request_metadata_creds); + grpc_channel *channel = + grpc_secure_channel_create_internal(target, args, ctx); + grpc_security_context_unref(&ctx->base); + return channel; } -static grpc_channel *grpc_channel_create_from_composite_creds( - grpc_credentials *composite_creds, const char *target, +grpc_channel *grpc_secure_channel_create_with_factories( + const grpc_secure_channel_factory *factories, size_t num_factories, + grpc_credentials *creds, const char *target, const grpc_channel_args *args) { - grpc_credentials *creds = - get_creds_from_composite(composite_creds, GRPC_CREDENTIALS_TYPE_SSL); - if (creds != NULL) { - return grpc_ssl_channel_create( - composite_creds, grpc_ssl_credentials_get_config(creds), target, args); + size_t i; + if (creds == NULL) { + gpr_log(GPR_ERROR, "No credentials to create a secure channel."); + return grpc_lame_client_channel_create(); } - return NULL; /* TODO(ctiller): return lame channel. */ -} - -grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, - const char *target, - const grpc_channel_args *args) { if (grpc_credentials_has_request_metadata_only(creds)) { gpr_log(GPR_ERROR, "Credentials is insufficient to create a secure channel."); return grpc_lame_client_channel_create(); } - if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) { - return grpc_ssl_channel_create(NULL, grpc_ssl_credentials_get_config(creds), - target, args); - } else if (!strcmp(creds->type, - GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) { - grpc_channel_security_context *ctx = - grpc_fake_channel_security_context_create(NULL); - grpc_channel *channel = - grpc_secure_channel_create_internal(target, args, ctx); - grpc_security_context_unref(&ctx->base); - return channel; - } else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) { - return grpc_channel_create_from_composite_creds(creds, target, args); - } else { - gpr_log(GPR_ERROR, - "Unknown credentials type %s for creating a secure channel."); - return grpc_lame_client_channel_create(); + + for (i = 0; i < num_factories; i++) { + grpc_credentials *composite_creds = NULL; + grpc_credentials *transport_security_creds = NULL; + transport_security_creds = grpc_credentials_contains_type( + creds, factories[i].creds_type, &composite_creds); + if (transport_security_creds != NULL) { + return factories[i].factory(transport_security_creds, composite_creds, + target, args); + } } + + gpr_log(GPR_ERROR, + "Unknown credentials type %s for creating a secure channel.", + creds->type); + return grpc_lame_client_channel_create(); } grpc_channel *grpc_default_secure_channel_create( @@ -528,30 +512,3 @@ grpc_channel *grpc_default_secure_channel_create( return grpc_secure_channel_create(grpc_default_credentials_create(), 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; - } else { - gpr_log(GPR_ERROR, - "Unable to create secure server with credentials of type %s.", - creds->type); - } - if (status != GRPC_SECURITY_OK) { - 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.h b/src/core/security/security_context.h index bbd7ff3b1a..9ace7f1ccb 100644 --- a/src/core/security/security_context.h +++ b/src/core/security/security_context.h @@ -118,7 +118,7 @@ grpc_security_context *grpc_find_security_context_in_args( typedef struct grpc_channel_security_context grpc_channel_security_context; struct grpc_channel_security_context { - grpc_security_context base; /* requires is_client_side to be non 0. */ + grpc_security_context base; /* requires is_client_side to be non 0. */ grpc_credentials *request_metadata_creds; }; @@ -159,17 +159,41 @@ grpc_security_status grpc_ssl_channel_security_context_create( grpc_security_status grpc_ssl_server_security_context_create( const grpc_ssl_config *config, grpc_security_context **ctx); - /* --- Creation of high level objects. --- */ /* Secure client channel creation. */ + +grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds, + grpc_credentials *request_metadata_creds, + const char *target, + const grpc_channel_args *args); + +grpc_channel *grpc_fake_transport_security_channel_create( + grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds, + const char *target, const grpc_channel_args *args); + grpc_channel *grpc_secure_channel_create_internal( const char *target, const grpc_channel_args *args, grpc_channel_security_context *ctx); +typedef grpc_channel *(*grpc_secure_channel_factory_func)( + grpc_credentials *transport_security_creds, + grpc_credentials *request_metadata_creds, const char *target, + const grpc_channel_args *args); + +typedef struct { + const char *creds_type; + grpc_secure_channel_factory_func factory; +} grpc_secure_channel_factory; + +grpc_channel *grpc_secure_channel_create_with_factories( + const grpc_secure_channel_factory *factories, size_t num_factories, + grpc_credentials *creds, const char *target, const grpc_channel_args *args); + /* Secure server creation. */ -grpc_server *grpc_secure_server_create_internal( - grpc_completion_queue *cq, const grpc_channel_args *args, - grpc_security_context *ctx); -#endif /* __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__ */ +grpc_server *grpc_secure_server_create_internal(grpc_completion_queue *cq, + const grpc_channel_args *args, + grpc_security_context *ctx); + +#endif /* __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__ */ diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index 9d7c0e5e5a..931fa95651 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -70,8 +70,7 @@ static void on_accept(void *server, grpc_endpoint *tcp) { const grpc_channel_args *args = grpc_server_get_channel_args(server); grpc_security_context *ctx = grpc_find_security_context_in_args(args); GPR_ASSERT(ctx); - grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, - server); + grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, server); } /* Note: the following code is the same with server_chttp2.c */ |