From ea44bba3b97dc2834456cc6fa96e2b341ad56f13 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Wed, 18 Nov 2015 15:56:01 -0800 Subject: [PATCH 1/5] Changing the credentials plugin API. - The plugin is now passed more information that it can use to create auth metadata: - service_url (as before) - method name - channel_auth_context --- include/grpc/grpc_security.h | 172 +++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 78 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index c8da59331db..108240d7486 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -41,6 +41,81 @@ extern "C" { #endif +/* --- Authentication Context. --- */ + +#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME "transport_security_type" +#define GRPC_SSL_TRANSPORT_SECURITY_TYPE "ssl" + +#define GRPC_X509_CN_PROPERTY_NAME "x509_common_name" +#define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name" + +typedef struct grpc_auth_context grpc_auth_context; + +typedef struct grpc_auth_property_iterator { + const grpc_auth_context *ctx; + size_t index; + const char *name; +} grpc_auth_property_iterator; + +/* value, if not NULL, is guaranteed to be NULL terminated. */ +typedef struct grpc_auth_property { + char *name; + char *value; + size_t value_length; +} grpc_auth_property; + +/* Returns NULL when the iterator is at the end. */ +const grpc_auth_property *grpc_auth_property_iterator_next( + grpc_auth_property_iterator *it); + +/* Iterates over the auth context. */ +grpc_auth_property_iterator grpc_auth_context_property_iterator( + const grpc_auth_context *ctx); + +/* Gets the peer identity. Returns an empty iterator (first _next will return + NULL) if the peer is not authenticated. */ +grpc_auth_property_iterator grpc_auth_context_peer_identity( + const grpc_auth_context *ctx); + +/* Finds a property in the context. May return an empty iterator (first _next + will return NULL) if no property with this name was found in the context. */ +grpc_auth_property_iterator grpc_auth_context_find_properties_by_name( + const grpc_auth_context *ctx, const char *name); + +/* Gets the name of the property that indicates the peer identity. Will return + NULL if the peer is not authenticated. */ +const char *grpc_auth_context_peer_identity_property_name( + const grpc_auth_context *ctx); + +/* Returns 1 if the peer is authenticated, 0 otherwise. */ +int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx); + +/* Gets the auth context from the call. Caller needs to call + grpc_auth_context_release on the returned context. */ +grpc_auth_context *grpc_call_auth_context(grpc_call *call); + +/* Releases the auth context returned from grpc_call_auth_context. */ +void grpc_auth_context_release(grpc_auth_context *context); + +/* -- + The following auth context methods should only be called by a server metadata + processor to set properties extracted from auth metadata. + -- */ + +/* Add a property. */ +void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name, + const char *value, size_t value_length); + +/* Add a C string property. */ +void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx, + const char *name, + const char *value); + +/* Sets the property name. Returns 1 if successful or 0 in case of failure + (which means that no property with this name exists). */ +int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx, + const char *name); + /* --- grpc_channel_credentials object. --- A channel credentials object represents a way to authenticate a client on a @@ -165,6 +240,22 @@ typedef void (*grpc_credentials_plugin_metadata_cb)( void *user_data, const grpc_metadata *creds_md, size_t num_creds_md, grpc_status_code status, const char *error_details); +/* Context that can be used by metadata credentials plugin in order to create + auth related metadata. */ +typedef struct { + /* The fully qualifed service url. */ + const char *service_url; + + /* The method name of the RPC being called (not fully qualified). */ + const char *method_name; + + /* The auth_context of the channel which gives the server's identity. */ + const grpc_auth_context *channel_auth_context; + + /* Reserved for future use. */ + void *reserved; +} grpc_auth_metadata_context; + /* grpc_metadata_credentials plugin is an API user provided structure used to create grpc_credentials objects that can be set on a channel (composed) or a call. See grpc_credentials_metadata_create_from_plugin below. @@ -172,11 +263,11 @@ typedef void (*grpc_credentials_plugin_metadata_cb)( every call in scope for the credentials created from it. */ typedef struct { /* The implementation of this method has to be non-blocking. - - service_url is the fully qualified URL that the client stack is - connecting to. + - context is the information that can be used by the plugin to create auth + metadata. - cb is the callback that needs to be called when the metadata is ready. - user_data needs to be passed as the first parameter of the callback. */ - void (*get_metadata)(void *state, const char *service_url, + void (*get_metadata)(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data); /* Destroys the plugin state. */ @@ -239,81 +330,6 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_call_error grpc_call_set_credentials(grpc_call *call, grpc_call_credentials *creds); -/* --- Authentication Context. --- */ - -#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME "transport_security_type" -#define GRPC_SSL_TRANSPORT_SECURITY_TYPE "ssl" - -#define GRPC_X509_CN_PROPERTY_NAME "x509_common_name" -#define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name" - -typedef struct grpc_auth_context grpc_auth_context; - -typedef struct grpc_auth_property_iterator { - const grpc_auth_context *ctx; - size_t index; - const char *name; -} grpc_auth_property_iterator; - -/* value, if not NULL, is guaranteed to be NULL terminated. */ -typedef struct grpc_auth_property { - char *name; - char *value; - size_t value_length; -} grpc_auth_property; - -/* Returns NULL when the iterator is at the end. */ -const grpc_auth_property *grpc_auth_property_iterator_next( - grpc_auth_property_iterator *it); - -/* Iterates over the auth context. */ -grpc_auth_property_iterator grpc_auth_context_property_iterator( - const grpc_auth_context *ctx); - -/* Gets the peer identity. Returns an empty iterator (first _next will return - NULL) if the peer is not authenticated. */ -grpc_auth_property_iterator grpc_auth_context_peer_identity( - const grpc_auth_context *ctx); - -/* Finds a property in the context. May return an empty iterator (first _next - will return NULL) if no property with this name was found in the context. */ -grpc_auth_property_iterator grpc_auth_context_find_properties_by_name( - const grpc_auth_context *ctx, const char *name); - -/* Gets the name of the property that indicates the peer identity. Will return - NULL if the peer is not authenticated. */ -const char *grpc_auth_context_peer_identity_property_name( - const grpc_auth_context *ctx); - -/* Returns 1 if the peer is authenticated, 0 otherwise. */ -int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx); - -/* Gets the auth context from the call. Caller needs to call - grpc_auth_context_release on the returned context. */ -grpc_auth_context *grpc_call_auth_context(grpc_call *call); - -/* Releases the auth context returned from grpc_call_auth_context. */ -void grpc_auth_context_release(grpc_auth_context *context); - -/* -- - The following auth context methods should only be called by a server metadata - processor to set properties extracted from auth metadata. - -- */ - -/* Add a property. */ -void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name, - const char *value, size_t value_length); - -/* Add a C string property. */ -void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx, - const char *name, - const char *value); - -/* Sets the property name. Returns 1 if successful or 0 in case of failure - (which means that no property with this name exists). */ -int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx, - const char *name); - /* --- Auth Metadata Processing --- */ /* Callback function that is called when the metadata processing is done. From 3c957e60a3901d2d56ce57e2c1b900a8c3697ea7 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Wed, 18 Nov 2015 21:33:58 -0800 Subject: [PATCH 2/5] Fixing implementations. --- include/grpc/grpc_security.h | 3 +- src/core/security/client_auth_filter.c | 47 ++++++++---- src/core/security/credentials.c | 72 +++++++++--------- src/core/security/credentials.h | 4 +- src/cpp/client/secure_credentials.cc | 6 +- src/cpp/client/secure_credentials.h | 2 +- src/csharp/ext/grpc_csharp_ext.c | 7 +- src/node/ext/call_credentials.cc | 4 +- test/core/security/credentials_test.c | 74 +++++++++++++------ test/core/security/oauth2_utils.c | 4 +- .../print_google_default_creds_token.c | 5 +- 11 files changed, 145 insertions(+), 83 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 108240d7486..4f3efae4be5 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -246,7 +246,8 @@ typedef struct { /* The fully qualifed service url. */ const char *service_url; - /* The method name of the RPC being called (not fully qualified). */ + /* The method name of the RPC being called (not fully qualified). + Can be NULL if no method name was found. */ const char *method_name; /* The auth_context of the channel which gives the server's identity. */ diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index f257502a989..d822164233d 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -63,7 +63,7 @@ typedef struct { int sent_initial_metadata; gpr_uint8 security_context_set; grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT]; - char *service_url; + grpc_auth_metadata_context auth_md_context; } call_data; /* We can have a per-channel credentials. */ @@ -76,11 +76,20 @@ typedef struct { grpc_mdstr *status_key; } channel_data; -static void reset_service_url(call_data *calld) { - if (calld->service_url != NULL) { - gpr_free(calld->service_url); - calld->service_url = NULL; +static void reset_auth_metadata_context( + grpc_auth_metadata_context *auth_md_context) { + if (auth_md_context->service_url != NULL) { + gpr_free((char *)auth_md_context->service_url); + auth_md_context->service_url = NULL; } + if (auth_md_context->method_name != NULL) { + gpr_free((char *)auth_md_context->method_name); + auth_md_context->method_name = NULL; + } + GRPC_AUTH_CONTEXT_UNREF( + (grpc_auth_context *)auth_md_context->channel_auth_context, + "grpc_auth_metadata_context"); + auth_md_context->channel_auth_context = NULL; } static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, @@ -101,7 +110,7 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data, grpc_transport_stream_op *op = &calld->op; grpc_metadata_batch *mdb; size_t i; - reset_service_url(calld); + reset_auth_metadata_context(&calld->auth_md_context); if (status != GRPC_CREDENTIALS_OK) { bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED, "Credentials failed to get metadata."); @@ -120,9 +129,13 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data, grpc_call_next_op(exec_ctx, elem, op); } -void build_service_url(const char *url_scheme, call_data *calld) { +void build_auth_metadata_context(grpc_security_connector *sc, + call_data *calld) { char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method)); char *last_slash = strrchr(service, '/'); + char *method_name = NULL; + char *service_url = NULL; + reset_auth_metadata_context(&calld->auth_md_context); if (last_slash == NULL) { gpr_log(GPR_ERROR, "No '/' found in fully qualified method name"); service[0] = '\0'; @@ -131,11 +144,15 @@ void build_service_url(const char *url_scheme, call_data *calld) { service[1] = '\0'; } else { *last_slash = '\0'; + method_name = gpr_strdup(last_slash + 1); } - if (url_scheme == NULL) url_scheme = ""; - reset_service_url(calld); - gpr_asprintf(&calld->service_url, "%s://%s%s", url_scheme, + gpr_asprintf(&service_url, "%s://%s%s", + sc->url_scheme == NULL ? "" : sc->url_scheme, grpc_mdstr_as_c_string(calld->host), service); + 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"); gpr_free(service); } @@ -169,12 +186,12 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx, call_creds_has_md ? ctx->creds : channel_call_creds); } - build_service_url(chand->security_connector->base.url_scheme, calld); + build_auth_metadata_context(&chand->security_connector->base, calld); calld->op = *op; /* Copy op (originates from the caller's stack). */ GPR_ASSERT(calld->pollset); - grpc_call_credentials_get_request_metadata(exec_ctx, calld->creds, - calld->pollset, calld->service_url, - on_credentials_metadata, elem); + grpc_call_credentials_get_request_metadata( + exec_ctx, calld->creds, calld->pollset, calld->auth_md_context, + on_credentials_metadata, elem); } static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data, @@ -297,7 +314,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, if (calld->method != NULL) { GRPC_MDSTR_UNREF(calld->method); } - reset_service_url(calld); + reset_auth_metadata_context(&calld->auth_md_context); } /* Constructor for channel_data */ diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 5c9d89c7646..806f9a6f1c5 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -33,16 +33,16 @@ #include "src/core/security/credentials.h" -#include #include +#include #include "src/core/channel/channel_args.h" #include "src/core/channel/http_client_filter.h" -#include "src/core/json/json.h" #include "src/core/httpcli/httpcli.h" #include "src/core/iomgr/iomgr.h" -#include "src/core/surface/api_trace.h" +#include "src/core/json/json.h" #include "src/core/support/string.h" +#include "src/core/surface/api_trace.h" #include #include @@ -117,15 +117,16 @@ void grpc_call_credentials_release(grpc_call_credentials *creds) { } void grpc_call_credentials_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { if (creds == NULL || creds->vtable->get_request_metadata == NULL) { if (cb != NULL) { cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); } return; } - creds->vtable->get_request_metadata(exec_ctx, creds, pollset, service_url, cb, + creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb, user_data); } @@ -207,8 +208,7 @@ grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) { return arg; } -grpc_server_credentials *grpc_server_credentials_from_arg( - const grpc_arg *arg) { +grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg) { if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL; if (arg->type != GRPC_ARG_POINTER) { gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, @@ -424,9 +424,12 @@ static void jwt_destruct(grpc_call_credentials *creds) { gpr_mu_destroy(&c->cache_mu); } -static void jwt_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { +static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx, + grpc_call_credentials *creds, + grpc_pollset *pollset, + grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, + void *user_data) { grpc_service_account_jwt_access_credentials *c = (grpc_service_account_jwt_access_credentials *)creds; gpr_timespec refresh_threshold = gpr_time_from_seconds( @@ -437,7 +440,7 @@ static void jwt_get_request_metadata( { gpr_mu_lock(&c->cache_mu); if (c->cached.service_url != NULL && - strcmp(c->cached.service_url, service_url) == 0 && + strcmp(c->cached.service_url, context.service_url) == 0 && c->cached.jwt_md != NULL && (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)), @@ -452,14 +455,15 @@ static void jwt_get_request_metadata( /* Generate a new jwt. */ gpr_mu_lock(&c->cache_mu); jwt_reset_cache(c); - jwt = grpc_jwt_encode_and_sign(&c->key, service_url, c->jwt_lifetime, NULL); + jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url, + c->jwt_lifetime, NULL); if (jwt != NULL) { char *md_value; gpr_asprintf(&md_value, "Bearer %s", jwt); gpr_free(jwt); c->cached.jwt_expiration = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); - c->cached.service_url = gpr_strdup(service_url); + c->cached.service_url = gpr_strdup(context.service_url); c->cached.jwt_md = grpc_credentials_md_store_create(1); grpc_credentials_md_store_add_cstrings( c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value); @@ -644,7 +648,7 @@ static void on_oauth2_token_fetcher_http_response( static void oauth2_token_fetcher_get_request_metadata( grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, - grpc_pollset *pollset, const char *service_url, + grpc_pollset *pollset, grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_oauth2_token_fetcher_credentials *c = (grpc_oauth2_token_fetcher_credentials *)creds; @@ -800,8 +804,9 @@ static void on_simulated_token_fetch_done(void *user_data) { } static void md_only_test_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds; if (c->is_async) { @@ -839,8 +844,9 @@ static void access_token_destruct(grpc_call_credentials *creds) { } static void access_token_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context context, + grpc_credentials_metadata_cb cb, void *user_data) { grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds; cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK); } @@ -921,7 +927,7 @@ typedef struct { grpc_composite_call_credentials *composite_creds; size_t creds_index; grpc_credentials_md_store *md_elems; - char *service_url; + grpc_auth_metadata_context auth_md_context; void *user_data; grpc_pollset *pollset; grpc_credentials_metadata_cb cb; @@ -939,7 +945,6 @@ static void composite_call_destruct(grpc_call_credentials *creds) { static void composite_call_md_context_destroy( grpc_composite_call_credentials_metadata_context *ctx) { grpc_credentials_md_store_unref(ctx->md_elems); - if (ctx->service_url != NULL) gpr_free(ctx->service_url); gpr_free(ctx); } @@ -967,9 +972,9 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data, if (ctx->creds_index < ctx->composite_creds->inner.num_creds) { grpc_call_credentials *inner_creds = ctx->composite_creds->inner.creds_array[ctx->creds_index++]; - grpc_call_credentials_get_request_metadata(exec_ctx, inner_creds, - ctx->pollset, ctx->service_url, - composite_call_metadata_cb, ctx); + grpc_call_credentials_get_request_metadata( + exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context, + composite_call_metadata_cb, ctx); return; } @@ -980,22 +985,23 @@ static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data, } static void composite_call_get_request_metadata( - grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { + grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, + grpc_pollset *pollset, grpc_auth_metadata_context auth_md_context, + grpc_credentials_metadata_cb cb, void *user_data) { grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds; grpc_composite_call_credentials_metadata_context *ctx; ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context)); memset(ctx, 0, sizeof(grpc_composite_call_credentials_metadata_context)); - ctx->service_url = gpr_strdup(service_url); + ctx->auth_md_context = auth_md_context; ctx->user_data = user_data; ctx->cb = cb; ctx->composite_creds = c; ctx->pollset = pollset; ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds); grpc_call_credentials_get_request_metadata( - exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset, service_url, - composite_call_metadata_cb, ctx); + exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset, + auth_md_context, composite_call_metadata_cb, ctx); } static grpc_call_credentials_vtable composite_call_credentials_vtable = { @@ -1089,7 +1095,7 @@ static void iam_destruct(grpc_call_credentials *creds) { static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, + grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds; @@ -1098,7 +1104,7 @@ static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx, } static grpc_call_credentials_vtable iam_vtable = {iam_destruct, - iam_get_request_metadata}; + iam_get_request_metadata}; grpc_call_credentials *grpc_google_iam_credentials_create( const char *token, const char *authority_selector, void *reserved) { @@ -1178,7 +1184,7 @@ static void plugin_md_request_metadata_ready(void *request, static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, + grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data) { grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds; @@ -1187,7 +1193,7 @@ static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx, memset(request, 0, sizeof(*request)); request->user_data = user_data; request->cb = cb; - c->plugin.get_metadata(c->plugin.state, service_url, + c->plugin.get_metadata(c->plugin.state, context, plugin_md_request_metadata_ready, request); } else { cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index 5189a6d8167..79caee7f99d 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -162,7 +162,7 @@ typedef struct { void (*destruct)(grpc_call_credentials *c); void (*get_request_metadata)(grpc_exec_ctx *exec_ctx, grpc_call_credentials *c, grpc_pollset *pollset, - const char *service_url, + grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data); } grpc_call_credentials_vtable; @@ -178,7 +178,7 @@ void grpc_call_credentials_unref(grpc_call_credentials *creds); void grpc_call_credentials_get_request_metadata(grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, - const char *service_url, + grpc_auth_metadata_context context, grpc_credentials_metadata_cb cb, void *user_data); diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index a1b9a3018e8..fa374f808a0 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -160,7 +160,7 @@ void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) { } void MetadataCredentialsPluginWrapper::GetMetadata( - void* wrapper, const char* service_url, + void* wrapper, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data) { GPR_ASSERT(wrapper); MetadataCredentialsPluginWrapper* w = @@ -172,9 +172,9 @@ void MetadataCredentialsPluginWrapper::GetMetadata( if (w->plugin_->IsBlocking()) { w->thread_pool_->Add( std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, - service_url, cb, user_data)); + context.service_url, cb, user_data)); } else { - w->InvokePlugin(service_url, cb, user_data); + w->InvokePlugin(context.service_url, cb, user_data); } } diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index b241761a7c4..b8fe075dc7d 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -80,7 +80,7 @@ class SecureCallCredentials GRPC_FINAL : public CallCredentials { class MetadataCredentialsPluginWrapper GRPC_FINAL { public: static void Destroy(void* wrapper); - static void GetMetadata(void* wrapper, const char* service_url, + static void GetMetadata(void* wrapper, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data); diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 183931936e7..e6a2664c53d 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -930,11 +930,12 @@ typedef void(GPR_CALLTYPE *grpcsharp_metadata_interceptor_func)( void *state, const char *service_url, grpc_credentials_plugin_metadata_cb cb, void *user_data, gpr_int32 is_destroy); -static void grpcsharp_get_metadata_handler(void *state, const char *service_url, - grpc_credentials_plugin_metadata_cb cb, void *user_data) { +static void grpcsharp_get_metadata_handler( + void *state, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, void *user_data) { grpcsharp_metadata_interceptor_func interceptor = (grpcsharp_metadata_interceptor_func)(gpr_intptr)state; - interceptor(state, service_url, cb, user_data, 0); + interceptor(state, context.service_url, cb, user_data, 0); } static void grpcsharp_metadata_credentials_destroy_handler(void *state) { diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc index 9c5d9d291b7..d0d7140bb44 100644 --- a/src/node/ext/call_credentials.cc +++ b/src/node/ext/call_credentials.cc @@ -225,7 +225,7 @@ NAUV_WORK_CB(SendPluginCallback) { uv_close((uv_handle_t *)async, (uv_close_cb)free); } -void plugin_get_metadata(void *state, const char *service_url, +void plugin_get_metadata(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data) { uv_async_t *async = static_cast(malloc(sizeof(uv_async_t))); @@ -234,7 +234,7 @@ void plugin_get_metadata(void *state, const char *service_url, SendPluginCallback); plugin_callback_data *data = new plugin_callback_data; data->state = reinterpret_cast(state); - data->service_url = service_url; + data->service_url = context.service_url; data->cb = cb; data->user_data = user_data; async->data = data; diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index dcb35e53096..ad17b059f16 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -126,6 +126,8 @@ static const char test_signed_jwt[] = static const char test_service_url[] = "https://foo.com/foo.v1"; static const char other_test_service_url[] = "https://bar.com/bar.v1"; +static const char test_method[] = "ThisIsNotAMethod"; + /* -- Utils. -- */ static char *test_json_key_str(void) { @@ -352,9 +354,10 @@ static void test_google_iam_creds(void) { grpc_call_credentials *creds = grpc_google_iam_credentials_create( test_google_iam_authorization_token, test_google_iam_authority_selector, NULL); - grpc_call_credentials_get_request_metadata(&exec_ctx, creds, NULL, - test_service_url, - check_google_iam_metadata, creds); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; + grpc_call_credentials_get_request_metadata( + &exec_ctx, creds, NULL, auth_md_ctx, check_google_iam_metadata, creds); grpc_exec_ctx_finish(&exec_ctx); } @@ -375,9 +378,11 @@ static void test_access_token_creds(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_call_credentials *creds = grpc_access_token_credentials_create("blah", NULL); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0); grpc_call_credentials_get_request_metadata( - &exec_ctx, creds, NULL, test_service_url, check_access_token_metadata, + &exec_ctx, creds, NULL, auth_md_ctx, check_access_token_metadata, creds); grpc_exec_ctx_finish(&exec_ctx); } @@ -430,6 +435,8 @@ static void check_oauth2_google_iam_composite_metadata( static void test_oauth2_google_iam_composite_creds(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const grpc_call_credentials_array *creds_array; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; grpc_call_credentials *oauth2_creds = grpc_md_only_test_credentials_create( "authorization", test_oauth2_bearer_token, 0); grpc_call_credentials *google_iam_creds = grpc_google_iam_credentials_create( @@ -449,7 +456,7 @@ static void test_oauth2_google_iam_composite_creds(void) { GPR_ASSERT(strcmp(creds_array->creds_array[1]->type, GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); grpc_call_credentials_get_request_metadata( - &exec_ctx, composite_creds, NULL, test_service_url, + &exec_ctx, composite_creds, NULL, auth_md_ctx, check_oauth2_google_iam_composite_metadata, composite_creds); grpc_exec_ctx_finish(&exec_ctx); } @@ -576,12 +583,14 @@ static void test_compute_engine_creds_success(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_call_credentials *compute_engine_creds = grpc_google_compute_engine_credentials_create(NULL); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; /* First request: http get should be called. */ grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, httpcli_post_should_not_be_called); grpc_call_credentials_get_request_metadata( - &exec_ctx, compute_engine_creds, NULL, test_service_url, + &exec_ctx, compute_engine_creds, NULL, auth_md_ctx, on_oauth2_creds_get_metadata_success, (void *)test_user_data); grpc_exec_ctx_flush(&exec_ctx); @@ -589,7 +598,7 @@ static void test_compute_engine_creds_success(void) { grpc_httpcli_set_override(httpcli_get_should_not_be_called, httpcli_post_should_not_be_called); grpc_call_credentials_get_request_metadata( - &exec_ctx, compute_engine_creds, NULL, test_service_url, + &exec_ctx, compute_engine_creds, NULL, auth_md_ctx, on_oauth2_creds_get_metadata_success, (void *)test_user_data); grpc_exec_ctx_finish(&exec_ctx); @@ -599,12 +608,14 @@ static void test_compute_engine_creds_success(void) { static void test_compute_engine_creds_failure(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; grpc_call_credentials *compute_engine_creds = grpc_google_compute_engine_credentials_create(NULL); grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override, httpcli_post_should_not_be_called); grpc_call_credentials_get_request_metadata( - &exec_ctx, compute_engine_creds, NULL, test_service_url, + &exec_ctx, compute_engine_creds, NULL, auth_md_ctx, on_oauth2_creds_get_metadata_failure, (void *)test_user_data); grpc_call_credentials_unref(compute_engine_creds); grpc_httpcli_set_override(NULL, NULL); @@ -656,6 +667,8 @@ static int refresh_token_httpcli_post_failure( static void test_refresh_token_creds_success(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; grpc_call_credentials *refresh_token_creds = grpc_google_refresh_token_credentials_create(test_refresh_token_str, NULL); @@ -664,7 +677,7 @@ static void test_refresh_token_creds_success(void) { grpc_httpcli_set_override(httpcli_get_should_not_be_called, refresh_token_httpcli_post_success); grpc_call_credentials_get_request_metadata( - &exec_ctx, refresh_token_creds, NULL, test_service_url, + &exec_ctx, refresh_token_creds, NULL, auth_md_ctx, on_oauth2_creds_get_metadata_success, (void *)test_user_data); grpc_exec_ctx_flush(&exec_ctx); @@ -672,7 +685,7 @@ static void test_refresh_token_creds_success(void) { grpc_httpcli_set_override(httpcli_get_should_not_be_called, httpcli_post_should_not_be_called); grpc_call_credentials_get_request_metadata( - &exec_ctx, refresh_token_creds, NULL, test_service_url, + &exec_ctx, refresh_token_creds, NULL, auth_md_ctx, on_oauth2_creds_get_metadata_success, (void *)test_user_data); grpc_exec_ctx_flush(&exec_ctx); @@ -683,13 +696,15 @@ static void test_refresh_token_creds_success(void) { static void test_refresh_token_creds_failure(void) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; grpc_call_credentials *refresh_token_creds = grpc_google_refresh_token_credentials_create(test_refresh_token_str, NULL); grpc_httpcli_set_override(httpcli_get_should_not_be_called, refresh_token_httpcli_post_failure); grpc_call_credentials_get_request_metadata( - &exec_ctx, refresh_token_creds, NULL, test_service_url, + &exec_ctx, refresh_token_creds, NULL, auth_md_ctx, on_oauth2_creds_get_metadata_failure, (void *)test_user_data); grpc_call_credentials_unref(refresh_token_creds); grpc_httpcli_set_override(NULL, NULL); @@ -772,6 +787,8 @@ static void on_jwt_creds_get_metadata_failure(grpc_exec_ctx *exec_ctx, static void test_jwt_creds_success(void) { char *json_key_string = test_json_key_str(); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; grpc_call_credentials *jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, grpc_max_auth_token_lifetime, NULL); @@ -779,7 +796,7 @@ static void test_jwt_creds_success(void) { /* First request: jwt_encode_and_sign should be called. */ grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success); grpc_call_credentials_get_request_metadata( - &exec_ctx, jwt_creds, NULL, test_service_url, + &exec_ctx, jwt_creds, NULL, auth_md_ctx, on_jwt_creds_get_metadata_success, (void *)test_user_data); grpc_exec_ctx_flush(&exec_ctx); @@ -787,15 +804,16 @@ static void test_jwt_creds_success(void) { grpc_jwt_encode_and_sign_set_override( encode_and_sign_jwt_should_not_be_called); grpc_call_credentials_get_request_metadata( - &exec_ctx, jwt_creds, NULL, test_service_url, + &exec_ctx, jwt_creds, NULL, auth_md_ctx, on_jwt_creds_get_metadata_success, (void *)test_user_data); grpc_exec_ctx_flush(&exec_ctx); /* Third request: Different service url so jwt_encode_and_sign should be called again (no caching). */ + auth_md_ctx.service_url = other_test_service_url; grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success); grpc_call_credentials_get_request_metadata( - &exec_ctx, jwt_creds, NULL, other_test_service_url, + &exec_ctx, jwt_creds, NULL, auth_md_ctx, on_jwt_creds_get_metadata_success, (void *)test_user_data); grpc_exec_ctx_flush(&exec_ctx); @@ -807,13 +825,15 @@ static void test_jwt_creds_success(void) { static void test_jwt_creds_signing_failure(void) { char *json_key_string = test_json_key_str(); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; grpc_call_credentials *jwt_creds = grpc_service_account_jwt_access_credentials_create( json_key_string, grpc_max_auth_token_lifetime, NULL); grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure); grpc_call_credentials_get_request_metadata( - &exec_ctx, jwt_creds, NULL, test_service_url, + &exec_ctx, jwt_creds, NULL, auth_md_ctx, on_jwt_creds_get_metadata_failure, (void *)test_user_data); gpr_free(json_key_string); @@ -884,13 +904,17 @@ typedef struct { static const plugin_metadata plugin_md[] = {{"foo", "bar"}, {"hi", "there"}}; -static void plugin_get_metadata_success(void *state, const char *service_url, +static void plugin_get_metadata_success(void *state, + grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data) { size_t i; grpc_metadata md[GPR_ARRAY_SIZE(plugin_md)]; plugin_state *s = (plugin_state *)state; - GPR_ASSERT(strcmp(service_url, test_service_url) == 0); + GPR_ASSERT(strcmp(context.service_url, test_service_url) == 0); + GPR_ASSERT(strcmp(context.method_name, test_method) == 0); + GPR_ASSERT(context.channel_auth_context == NULL); + GPR_ASSERT(context.reserved == NULL); *s = PLUGIN_GET_METADATA_CALLED_STATE; for (i = 0; i < GPR_ARRAY_SIZE(plugin_md); i++) { memset(&md[i], 0, sizeof(grpc_metadata)); @@ -901,11 +925,15 @@ static void plugin_get_metadata_success(void *state, const char *service_url, cb(user_data, md, GPR_ARRAY_SIZE(md), GRPC_STATUS_OK, NULL); } -static void plugin_get_metadata_failure(void *state, const char *service_url, +static void plugin_get_metadata_failure(void *state, + grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data) { plugin_state *s = (plugin_state *)state; - GPR_ASSERT(strcmp(service_url, test_service_url) == 0); + GPR_ASSERT(strcmp(context.service_url, test_service_url) == 0); + GPR_ASSERT(strcmp(context.method_name, test_method) == 0); + GPR_ASSERT(context.channel_auth_context == NULL); + GPR_ASSERT(context.reserved == NULL); *s = PLUGIN_GET_METADATA_CALLED_STATE; cb(user_data, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, "Could not get metadata for plugin."); @@ -943,6 +971,8 @@ static void test_metadata_plugin_success(void) { plugin_state state = PLUGIN_INITIAL_STATE; grpc_metadata_credentials_plugin plugin; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; plugin.state = &state; plugin.get_metadata = plugin_get_metadata_success; @@ -951,7 +981,7 @@ static void test_metadata_plugin_success(void) { creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL); GPR_ASSERT(state == PLUGIN_INITIAL_STATE); grpc_call_credentials_get_request_metadata( - &exec_ctx, creds, NULL, test_service_url, + &exec_ctx, creds, NULL, auth_md_ctx, on_plugin_metadata_received_success, NULL); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); grpc_call_credentials_release(creds); @@ -964,6 +994,8 @@ static void test_metadata_plugin_failure(void) { plugin_state state = PLUGIN_INITIAL_STATE; grpc_metadata_credentials_plugin plugin; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL, + NULL}; plugin.state = &state; plugin.get_metadata = plugin_get_metadata_failure; @@ -972,7 +1004,7 @@ static void test_metadata_plugin_failure(void) { creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL); GPR_ASSERT(state == PLUGIN_INITIAL_STATE); grpc_call_credentials_get_request_metadata( - &exec_ctx, creds, NULL, test_service_url, + &exec_ctx, creds, NULL, auth_md_ctx, on_plugin_metadata_received_failure, NULL); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); grpc_call_credentials_release(creds); diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c index fcfe8a63777..a283a881e0d 100644 --- a/test/core/security/oauth2_utils.c +++ b/test/core/security/oauth2_utils.c @@ -80,13 +80,15 @@ char *grpc_test_fetch_oauth2_token_with_credentials( oauth2_request request; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_closure do_nothing_closure; + grpc_auth_metadata_context null_ctx = {"", "", NULL, NULL}; + grpc_pollset_init(&request.pollset); request.is_done = 0; grpc_closure_init(&do_nothing_closure, do_nothing, NULL); grpc_call_credentials_get_request_metadata(&exec_ctx, creds, &request.pollset, - "", on_oauth2_response, &request); + null_ctx, on_oauth2_response, &request); grpc_exec_ctx_finish(&exec_ctx); diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c index eb637247153..50fe61c9969 100644 --- a/test/core/security/print_google_default_creds_token.c +++ b/test/core/security/print_google_default_creds_token.c @@ -74,10 +74,13 @@ int main(int argc, char **argv) { synchronizer sync; grpc_channel_credentials *creds = NULL; char *service_url = "https://test.foo.google.com/Foo"; + grpc_auth_metadata_context context; gpr_cmdline *cl = gpr_cmdline_create("print_google_default_creds_token"); gpr_cmdline_add_string(cl, "service_url", "Service URL for the token request.", &service_url); gpr_cmdline_parse(cl, argc, argv); + memset(&context, 0, sizeof(context)); + context.service_url = service_url; grpc_init(); @@ -93,7 +96,7 @@ int main(int argc, char **argv) { grpc_call_credentials_get_request_metadata( &exec_ctx, ((grpc_composite_channel_credentials *)creds)->call_creds, - &sync.pollset, service_url, on_metadata_response, &sync); + &sync.pollset, context, on_metadata_response, &sync); gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset)); while (!sync.is_done) { From 35b6b94667daeb2246e1c68aafea6cb589acae75 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Wed, 18 Nov 2015 22:12:29 -0800 Subject: [PATCH 3/5] Fixing node build. --- src/node/ext/call_credentials.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/ext/call_credentials.h b/src/node/ext/call_credentials.h index 1cd8d8dd5d5..a9bfe30f940 100644 --- a/src/node/ext/call_credentials.h +++ b/src/node/ext/call_credentials.h @@ -84,7 +84,7 @@ typedef struct plugin_callback_data { void *user_data; } plugin_callback_data; -void plugin_get_metadata(void *state, const char *service_url, +void plugin_get_metadata(void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data); From caf9935e456436a54931bf8112c25515100ccd20 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Thu, 19 Nov 2015 22:00:30 -0800 Subject: [PATCH 4/5] Also adding a credentials type to the plugin API. The purpose of this is to be able to install a composition policy that describes which types are incompatible and that will be enforced during call creds composition. If this functionality is wanted it will be done in an additive function in the API like : void grpc_call_credentials_set_composite_policy( grpc_call_credentials_composite_policy policy); --- include/grpc/grpc_security.h | 3 +++ src/core/security/credentials.c | 2 +- src/core/security/credentials.h | 1 - src/cpp/client/secure_credentials.cc | 2 +- src/csharp/ext/grpc_csharp_ext.c | 1 + src/node/ext/call_credentials.cc | 1 + 6 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 4f3efae4be5..f4e90a5ef58 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -276,6 +276,9 @@ typedef struct { /* State that will be set as the first parameter of the methods above. */ void *state; + + /* Type of credentials that this plugin is implementing. */ + const char *type; } grpc_metadata_credentials_plugin; /* Creates a credentials object from a plugin. */ diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 806f9a6f1c5..751665b4947 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -1210,7 +1210,7 @@ grpc_call_credentials *grpc_metadata_credentials_create_from_plugin( (reserved)); GPR_ASSERT(reserved == NULL); memset(c, 0, sizeof(*c)); - c->base.type = GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN; + c->base.type = plugin.type; c->base.vtable = &plugin_vtable; gpr_ref_init(&c->base.refcount, 1); c->plugin = plugin; diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index 79caee7f99d..0ce33d5e7cd 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -59,7 +59,6 @@ typedef enum { "FakeTransportSecurity" #define GRPC_CALL_CREDENTIALS_TYPE_OAUTH2 "Oauth2" -#define GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN "Plugin" #define GRPC_CALL_CREDENTIALS_TYPE_JWT "Jwt" #define GRPC_CALL_CREDENTIALS_TYPE_IAM "Iam" #define GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE "Composite" diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index fa374f808a0..bd682284602 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -208,7 +208,7 @@ std::shared_ptr MetadataCredentialsFromPlugin( new MetadataCredentialsPluginWrapper(std::move(plugin)); grpc_metadata_credentials_plugin c_plugin = { MetadataCredentialsPluginWrapper::GetMetadata, - MetadataCredentialsPluginWrapper::Destroy, wrapper}; + MetadataCredentialsPluginWrapper::Destroy, wrapper, ""}; return WrapCallCredentials( grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); } diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index e6a2664c53d..b8705c49d32 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -950,6 +950,7 @@ GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_cr plugin.get_metadata = grpcsharp_get_metadata_handler; plugin.destroy = grpcsharp_metadata_credentials_destroy_handler; plugin.state = (void*)(gpr_intptr)metadata_interceptor; + plugin.type = ""; return grpc_metadata_credentials_create_from_plugin(plugin, NULL); } diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc index d0d7140bb44..8cbfb1ebea0 100644 --- a/src/node/ext/call_credentials.cc +++ b/src/node/ext/call_credentials.cc @@ -162,6 +162,7 @@ NAN_METHOD(CallCredentials::CreateFromPlugin) { plugin.get_metadata = plugin_get_metadata; plugin.destroy = plugin_destroy_state; plugin.state = reinterpret_cast(state); + plugin.type = ""; grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin( plugin, NULL); info.GetReturnValue().Set(WrapStruct(creds)); From eb029c93fb273925102bd25e6972b9d9edf0ccde Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Wed, 25 Nov 2015 13:47:56 -0800 Subject: [PATCH 5/5] Better documentation of the method_name field. Also passing empty string as opposed to NULL when the method name is not found. This is much less error-prone. --- include/grpc/grpc_security.h | 3 ++- src/core/security/client_auth_filter.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index f4e90a5ef58..655f45a29b9 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -247,7 +247,8 @@ typedef struct { const char *service_url; /* The method name of the RPC being called (not fully qualified). - Can be NULL if no method name was found. */ + The fully qualified method name can be built from the service_url: + full_qualified_method_name = ctx->service_url + '/' + ctx->method_name. */ const char *method_name; /* The auth_context of the channel which gives the server's identity. */ diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index d822164233d..e7057051e0a 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -146,6 +146,7 @@ void build_auth_metadata_context(grpc_security_connector *sc, *last_slash = '\0'; method_name = gpr_strdup(last_slash + 1); } + if (method_name == NULL) method_name = gpr_strdup(""); gpr_asprintf(&service_url, "%s://%s%s", sc->url_scheme == NULL ? "" : sc->url_scheme, grpc_mdstr_as_c_string(calld->host), service);