From 366f42c12d3a99248b15f55463ca27c41df68c6d Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Wed, 16 Dec 2015 22:05:46 -0800 Subject: [PATCH] Removing the auth context from the security connector. The security connector is a channel/server port wide construct. On the other hand, the auth_context is a per-connection construct. --- src/core/httpcli/httpcli_security_connector.c | 17 ++-- src/core/security/client_auth_filter.c | 22 ++++-- src/core/security/handshake.c | 24 +++--- src/core/security/security_connector.c | 79 +++++++++---------- src/core/security/security_connector.h | 47 +++++------ src/core/security/server_secure_chttp2.c | 10 ++- src/core/surface/secure_channel_create.c | 14 +++- 7 files changed, 117 insertions(+), 96 deletions(-) diff --git a/src/core/httpcli/httpcli_security_connector.c b/src/core/httpcli/httpcli_security_connector.c index a5aa5513735..60c6cf6ac2c 100644 --- a/src/core/httpcli/httpcli_security_connector.c +++ b/src/core/httpcli/httpcli_security_connector.c @@ -68,7 +68,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, tsi_result result = TSI_OK; tsi_handshaker *handshaker; if (c->handshaker_factory == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); return; } result = tsi_ssl_handshaker_factory_create_handshaker( @@ -76,17 +76,17 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", tsi_result_to_string(result)); - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, user_data); } } -static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc, - tsi_peer peer, - grpc_security_check_cb cb, - void *user_data) { +static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, + void *user_data) { grpc_httpcli_ssl_channel_security_connector *c = (grpc_httpcli_ssl_channel_security_connector *)sc; grpc_security_status status = GRPC_SECURITY_OK; @@ -99,7 +99,7 @@ static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc, status = GRPC_SECURITY_ERROR; } tsi_peer_destruct(&peer); - return status; + cb(exec_ctx, user_data, status, NULL); } static grpc_security_connector_vtable httpcli_ssl_vtable = { @@ -149,7 +149,8 @@ typedef struct { static void on_secure_transport_setup_done(grpc_exec_ctx *exec_ctx, void *rp, grpc_security_status status, - grpc_endpoint *secure_endpoint) { + grpc_endpoint *secure_endpoint, + grpc_auth_context *auth_context) { on_done_closure *c = rp; if (status != GRPC_SECURITY_OK) { gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status); diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index b1fd733c912..c55990025bc 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -68,6 +68,7 @@ typedef struct { /* We can have a per-channel credentials. */ typedef struct { grpc_channel_security_connector *security_connector; + grpc_auth_context *auth_context; } channel_data; static void reset_auth_metadata_context( @@ -122,6 +123,7 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data, } void build_auth_metadata_context(grpc_security_connector *sc, + grpc_auth_context *auth_context, call_data *calld) { char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method)); char *last_slash = strrchr(service, '/'); @@ -145,7 +147,7 @@ void build_auth_metadata_context(grpc_security_connector *sc, calld->auth_md_context.service_url = service_url; calld->auth_md_context.method_name = method_name; calld->auth_md_context.channel_auth_context = - GRPC_AUTH_CONTEXT_REF(sc->auth_context, "grpc_auth_metadata_context"); + GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context"); gpr_free(service); } @@ -179,7 +181,8 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx, call_creds_has_md ? ctx->creds : channel_call_creds); } - build_auth_metadata_context(&chand->security_connector->base, calld); + build_auth_metadata_context(&chand->security_connector->base, + chand->auth_context, calld); calld->op = *op; /* Copy op (originates from the caller's stack). */ GPR_ASSERT(calld->pollset); grpc_call_credentials_get_request_metadata( @@ -230,7 +233,7 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, sec_ctx = op->context[GRPC_CONTEXT_SECURITY].value; GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter"); sec_ctx->auth_context = GRPC_AUTH_CONTEXT_REF( - chand->security_connector->base.auth_context, "client_auth_filter"); + chand->auth_context, "client_auth_filter"); } if (op->send_initial_metadata != NULL) { @@ -307,6 +310,9 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element_args *args) { grpc_security_connector *sc = grpc_find_security_connector_in_args(args->channel_args); + grpc_auth_context *auth_context = + grpc_find_auth_context_in_args(args->channel_args); + /* grab pointers to our data from the channel element */ channel_data *chand = elem->channel_data; @@ -315,12 +321,15 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, path */ GPR_ASSERT(!args->is_last); GPR_ASSERT(sc != NULL); + GPR_ASSERT(auth_context != NULL); /* initialize members */ GPR_ASSERT(sc->is_client_side); chand->security_connector = (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF( sc, "client_auth_filter"); + chand->auth_context = + GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter"); } /* Destructor for channel data */ @@ -328,10 +337,11 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { /* grab pointers to our data from the channel element */ channel_data *chand = elem->channel_data; - grpc_channel_security_connector *ctx = chand->security_connector; - if (ctx != NULL) { - GRPC_SECURITY_CONNECTOR_UNREF(&ctx->base, "client_auth_filter"); + grpc_channel_security_connector *sc = chand->security_connector; + if (sc != NULL) { + GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter"); } + GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter"); } const grpc_channel_filter grpc_client_auth_filter = { diff --git a/src/core/security/handshake.c b/src/core/security/handshake.c index 6734187fce8..364b7653965 100644 --- a/src/core/security/handshake.c +++ b/src/core/security/handshake.c @@ -35,6 +35,7 @@ #include +#include "src/core/security/security_context.h" #include "src/core/security/secure_endpoint.h" #include #include @@ -56,6 +57,7 @@ typedef struct { void *user_data; grpc_closure on_handshake_data_sent_to_peer; grpc_closure on_handshake_data_received_from_peer; + grpc_auth_context *auth_context; } grpc_security_handshake; static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx, @@ -96,7 +98,8 @@ static void security_handshake_done(grpc_exec_ctx *exec_ctx, security_connector_remove_handshake(h); } if (is_success) { - h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->secure_endpoint); + h->cb(exec_ctx, h->user_data, GRPC_SECURITY_OK, h->secure_endpoint, + h->auth_context); } else { if (h->secure_endpoint != NULL) { grpc_endpoint_shutdown(exec_ctx, h->secure_endpoint); @@ -104,19 +107,21 @@ static void security_handshake_done(grpc_exec_ctx *exec_ctx, } else { grpc_endpoint_destroy(exec_ctx, h->wrapped_endpoint); } - h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL); + h->cb(exec_ctx, h->user_data, GRPC_SECURITY_ERROR, NULL, NULL); } if (h->handshaker != NULL) tsi_handshaker_destroy(h->handshaker); if (h->handshake_buffer != NULL) gpr_free(h->handshake_buffer); gpr_slice_buffer_destroy(&h->left_overs); gpr_slice_buffer_destroy(&h->outgoing); gpr_slice_buffer_destroy(&h->incoming); + GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake"); GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake"); gpr_free(h); } static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_security_status status) { + grpc_security_status status, + grpc_auth_context *auth_context) { grpc_security_handshake *h = user_data; tsi_frame_protector *protector; tsi_result result; @@ -125,6 +130,7 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *user_data, security_handshake_done(exec_ctx, h, 0); return; } + h->auth_context = GRPC_AUTH_CONTEXT_REF(auth_context, "handshake"); result = tsi_handshaker_create_frame_protector(h->handshaker, NULL, &protector); if (result != TSI_OK) { @@ -143,7 +149,6 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *user_data, } static void check_peer(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h) { - grpc_security_status peer_status; tsi_peer peer; tsi_result result = tsi_handshaker_extract_peer(h->handshaker, &peer); @@ -153,15 +158,8 @@ static void check_peer(grpc_exec_ctx *exec_ctx, grpc_security_handshake *h) { security_handshake_done(exec_ctx, h, 0); return; } - peer_status = grpc_security_connector_check_peer(h->connector, peer, - on_peer_checked, h); - if (peer_status == GRPC_SECURITY_ERROR) { - gpr_log(GPR_ERROR, "Peer check failed."); - security_handshake_done(exec_ctx, h, 0); - return; - } else if (peer_status == GRPC_SECURITY_OK) { - on_peer_checked(exec_ctx, h, peer_status); - } + grpc_security_connector_check_peer(exec_ctx, h->connector, peer, + on_peer_checked, h); } static void send_handshake_bytes_to_peer(grpc_exec_ctx *exec_ctx, diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c index 8c6ab0b8a46..3828451795a 100644 --- a/src/core/security/security_connector.c +++ b/src/core/security/security_connector.c @@ -124,25 +124,26 @@ void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx, grpc_security_handshake_done_cb cb, void *user_data) { if (sc == NULL || nonsecure_endpoint == NULL) { - cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); } else { sc->vtable->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data); } } -grpc_security_status grpc_security_connector_check_peer( - grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb, - void *user_data) { +void grpc_security_connector_check_peer( + grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, void *user_data) { if (sc == NULL) { tsi_peer_destruct(&peer); - return GRPC_SECURITY_ERROR; + cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL); + } else { + sc->vtable->check_peer(exec_ctx, sc, peer, cb, user_data); } - return sc->vtable->check_peer(sc, peer, cb, user_data); } grpc_security_status grpc_channel_security_connector_check_call_host( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - const char *host, grpc_security_check_cb cb, void *user_data) { + const char *host, grpc_security_call_host_check_cb cb, void *user_data) { if (sc == NULL || sc->check_call_host == NULL) return GRPC_SECURITY_ERROR; return sc->check_call_host(exec_ctx, sc, host, cb, user_data); } @@ -229,22 +230,20 @@ typedef struct { static void fake_channel_destroy(grpc_security_connector *sc) { grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc; grpc_call_credentials_unref(c->request_metadata_creds); - GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector"); gpr_free(sc); } static void fake_server_destroy(grpc_security_connector *sc) { - GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector"); gpr_mu_destroy(&sc->mu); gpr_free(sc); } -static grpc_security_status fake_check_peer(grpc_security_connector *sc, - tsi_peer peer, - grpc_security_check_cb cb, - void *user_data) { +static void fake_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, void *user_data) { const char *prop_name; grpc_security_status status = GRPC_SECURITY_OK; + grpc_auth_context *auth_context = NULL; if (peer.property_count != 1) { gpr_log(GPR_ERROR, "Fake peers should only have 1 property."); status = GRPC_SECURITY_ERROR; @@ -264,20 +263,20 @@ static grpc_security_status fake_check_peer(grpc_security_connector *sc, status = GRPC_SECURITY_ERROR; goto end; } - GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector"); - sc->auth_context = grpc_auth_context_create(NULL); + auth_context = grpc_auth_context_create(NULL); grpc_auth_context_add_cstring_property( - sc->auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_FAKE_TRANSPORT_SECURITY_TYPE); end: + cb(exec_ctx, user_data, status, auth_context); tsi_peer_destruct(&peer); - return status; + grpc_auth_context_unref(auth_context); } static grpc_security_status fake_channel_check_call_host( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - const char *host, grpc_security_check_cb cb, void *user_data) { + const char *host, grpc_security_call_host_check_cb cb, void *user_data) { grpc_fake_channel_security_connector *c = (grpc_fake_channel_security_connector *)sc; if (c->call_host_check_is_async) { @@ -347,6 +346,8 @@ typedef struct { tsi_ssl_handshaker_factory *handshaker_factory; char *target_name; char *overridden_target_name; + /* TODO(jboeuf): Remove this: the security connector is channel-wide construct + as opposed to the peer which is for one transport (or sub-channel). */ tsi_peer peer; } grpc_ssl_channel_security_connector; @@ -365,7 +366,6 @@ static void ssl_channel_destroy(grpc_security_connector *sc) { if (c->target_name != NULL) gpr_free(c->target_name); if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name); tsi_peer_destruct(&c->peer); - GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector"); gpr_free(sc); } @@ -376,7 +376,6 @@ static void ssl_server_destroy(grpc_security_connector *sc) { if (c->handshaker_factory != NULL) { tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); } - GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector"); gpr_mu_destroy(&sc->mu); gpr_free(sc); } @@ -410,7 +409,7 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, : c->target_name, &handshaker); if (status != GRPC_SECURITY_OK) { - cb(exec_ctx, user_data, status, NULL); + cb(exec_ctx, user_data, status, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, user_data); @@ -428,7 +427,7 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, grpc_security_status status = ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker); if (status != GRPC_SECURITY_OK) { - cb(exec_ctx, user_data, status, NULL); + cb(exec_ctx, user_data, status, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, user_data); @@ -488,7 +487,8 @@ grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) { static grpc_security_status ssl_check_peer(grpc_security_connector *sc, const char *peer_name, - const tsi_peer *peer) { + const tsi_peer *peer, + grpc_auth_context **auth_context) { /* Check the ALPN. */ const tsi_peer_property *p = tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); @@ -506,41 +506,40 @@ static grpc_security_status ssl_check_peer(grpc_security_connector *sc, gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name); return GRPC_SECURITY_ERROR; } - if (sc->auth_context != NULL) { - GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector"); - } - sc->auth_context = tsi_ssl_peer_to_auth_context(peer); + *auth_context = tsi_ssl_peer_to_auth_context(peer); return GRPC_SECURITY_OK; } -static grpc_security_status ssl_channel_check_peer(grpc_security_connector *sc, - tsi_peer peer, - grpc_security_check_cb cb, - void *user_data) { +static void ssl_channel_check_peer( + grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, void *user_data) { grpc_ssl_channel_security_connector *c = (grpc_ssl_channel_security_connector *)sc; grpc_security_status status; + grpc_auth_context *auth_context = NULL; tsi_peer_destruct(&c->peer); c->peer = peer; status = ssl_check_peer(sc, c->overridden_target_name != NULL ? c->overridden_target_name : c->target_name, - &peer); - return status; + &peer, &auth_context); + cb(exec_ctx, user_data, status, auth_context); + grpc_auth_context_unref(auth_context); } -static grpc_security_status ssl_server_check_peer(grpc_security_connector *sc, - tsi_peer peer, - grpc_security_check_cb cb, - void *user_data) { - grpc_security_status status = ssl_check_peer(sc, NULL, &peer); +static void ssl_server_check_peer( + grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, tsi_peer peer, + grpc_security_peer_check_cb cb, void *user_data) { + grpc_auth_context *auth_context = NULL; + grpc_security_status status = ssl_check_peer(sc, NULL, &peer, &auth_context); tsi_peer_destruct(&peer); - return status; + cb(exec_ctx, user_data, status, auth_context); + grpc_auth_context_unref(auth_context); } static grpc_security_status ssl_channel_check_call_host( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - const char *host, grpc_security_check_cb cb, void *user_data) { + const char *host, grpc_security_call_host_check_cb cb, void *user_data) { grpc_ssl_channel_security_connector *c = (grpc_ssl_channel_security_connector *)sc; diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h index 7edb05a662e..3f7103699e2 100644 --- a/src/core/security/security_connector.h +++ b/src/core/security/security_connector.h @@ -60,23 +60,24 @@ typedef struct grpc_security_connector grpc_security_connector; #define GRPC_SECURITY_CONNECTOR_ARG "grpc.security_connector" -typedef void (*grpc_security_check_cb)(grpc_exec_ctx *exec_ctx, void *user_data, - grpc_security_status status); +typedef void (*grpc_security_peer_check_cb)(grpc_exec_ctx *exec_ctx, + void *user_data, + grpc_security_status status, + grpc_auth_context *auth_context); /* Ownership of the secure_endpoint is transfered. */ -typedef void (*grpc_security_handshake_done_cb)(grpc_exec_ctx *exec_ctx, - void *user_data, - grpc_security_status status, - grpc_endpoint *secure_endpoint); +typedef void (*grpc_security_handshake_done_cb)( + grpc_exec_ctx *exec_ctx, void *user_data, grpc_security_status status, + grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context); typedef struct { void (*destroy)(grpc_security_connector *sc); void (*do_handshake)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb, void *user_data); - grpc_security_status (*check_peer)(grpc_security_connector *sc, tsi_peer peer, - grpc_security_check_cb cb, - void *user_data); + void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, + tsi_peer peer, grpc_security_peer_check_cb cb, + void *user_data); } grpc_security_connector_vtable; typedef struct grpc_security_connector_handshake_list { @@ -89,9 +90,8 @@ struct grpc_security_connector { gpr_refcount refcount; int is_client_side; const char *url_scheme; - grpc_auth_context *auth_context; /* Populated after the peer is checked. */ /* Used on server side only. */ - /* TODO(yangg) maybe create a grpc_server_security_connector with these */ + /* TODO(yangg): Create a grpc_server_security_connector with these. */ gpr_mu mu; grpc_security_connector_handshake_list *handshaking_handshakes; const grpc_channel_args *channel_args; @@ -125,15 +125,13 @@ void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx, void *user_data); /* Check the peer. - Implementations can choose to check the peer either synchronously or - asynchronously. In the first case, a successful call will return - GRPC_SECURITY_OK. In the asynchronous case, the call will return - GRPC_SECURITY_PENDING unless an error is detected early on. Ownership of the peer is transfered. -*/ -grpc_security_status grpc_security_connector_check_peer( - grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb, - void *user_data); + TODO(jboeuf): Pass the peer by const pointer and do not pass ownership. */ +void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx, + grpc_security_connector *sc, + tsi_peer peer, + grpc_security_peer_check_cb cb, + void *user_data); void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_security_connector *connector); @@ -155,13 +153,17 @@ grpc_security_connector *grpc_find_security_connector_in_args( typedef struct grpc_channel_security_connector grpc_channel_security_connector; +typedef void (*grpc_security_call_host_check_cb)(grpc_exec_ctx *exec_ctx, + void *user_data, + grpc_security_status status); + struct grpc_channel_security_connector { grpc_security_connector base; /* requires is_client_side to be non 0. */ grpc_call_credentials *request_metadata_creds; grpc_security_status (*check_call_host)(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, const char *host, - grpc_security_check_cb cb, + grpc_security_call_host_check_cb cb, void *user_data); }; @@ -169,10 +171,11 @@ struct grpc_channel_security_connector { Implementations can choose do the check either synchronously or asynchronously. In the first case, a successful call will return GRPC_SECURITY_OK. In the asynchronous case, the call will return - GRPC_SECURITY_PENDING unless an error is detected early on. */ + GRPC_SECURITY_PENDING unless an error is detected early on. + TODO(jboeuf): add a grpc_auth_context param to test against. */ grpc_security_status grpc_channel_security_connector_check_call_host( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - const char *host, grpc_security_check_cb cb, void *user_data); + const char *host, grpc_security_call_host_check_cb cb, void *user_data); /* --- Creation security connectors. --- */ diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index d1468e40e05..d7fad338549 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -81,14 +81,15 @@ static void state_unref(grpc_server_secure_state *state) { } static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep, - grpc_transport *transport) { + grpc_transport *transport, + grpc_auth_context *auth_context) { static grpc_channel_filter const *extra_filters[] = { &grpc_server_auth_filter, &grpc_http_server_filter}; grpc_server_secure_state *state = statep; grpc_channel_args *args_copy; grpc_arg args_to_add[2]; args_to_add[0] = grpc_server_credentials_to_arg(state->creds); - args_to_add[1] = grpc_auth_context_to_arg(state->sc->auth_context); + args_to_add[1] = grpc_auth_context_to_arg(auth_context); args_copy = grpc_channel_args_copy_and_add( grpc_server_get_channel_args(state->server), args_to_add, GPR_ARRAY_SIZE(args_to_add)); @@ -99,7 +100,8 @@ static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep, static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, grpc_security_status status, - grpc_endpoint *secure_endpoint) { + grpc_endpoint *secure_endpoint, + grpc_auth_context *auth_context) { grpc_server_secure_state *state = statep; grpc_transport *transport; if (status == GRPC_SECURITY_OK) { @@ -109,7 +111,7 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, transport = grpc_create_chttp2_transport( exec_ctx, grpc_server_get_channel_args(state->server), secure_endpoint, 0); - setup_transport(exec_ctx, state, transport); + setup_transport(exec_ctx, state, transport, auth_context); grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); } else { /* We need to consume this here, because the server may already have diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index 92bd53411d5..8ff3c786817 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -49,6 +49,7 @@ #include "src/core/iomgr/tcp_client.h" #include "src/core/security/auth_filters.h" #include "src/core/security/credentials.h" +#include "src/core/security/security_context.h" #include "src/core/surface/api_trace.h" #include "src/core/surface/channel.h" #include "src/core/transport/chttp2_transport.h" @@ -88,7 +89,8 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_security_status status, - grpc_endpoint *secure_endpoint) { + grpc_endpoint *secure_endpoint, + grpc_auth_context *auth_context) { connector *c = arg; grpc_closure *notify; gpr_mu_lock(&c->mu); @@ -103,8 +105,14 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, } else { c->connecting_endpoint = NULL; gpr_mu_unlock(&c->mu); - c->result->transport = grpc_create_chttp2_transport( - exec_ctx, c->args.channel_args, secure_endpoint, 1); + { + grpc_arg auth_context_arg = grpc_auth_context_to_arg(auth_context); + grpc_channel_args *args_copy = grpc_channel_args_copy_and_add( + c->args.channel_args, &auth_context_arg, 1); + c->result->transport = grpc_create_chttp2_transport( + exec_ctx, args_copy, secure_endpoint, 1); + grpc_channel_args_destroy(args_copy); + } grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, 0); c->result->filters = gpr_malloc(sizeof(grpc_channel_filter *) * 2);