Merge pull request #4154 from jboeuf/new_creds_plugin_api

Changing the credentials plugin API.
pull/4208/head
jboeuf 9 years ago
commit b1c41d7b0d
  1. 177
      include/grpc/grpc_security.h
  2. 48
      src/core/security/client_auth_filter.c
  3. 74
      src/core/security/credentials.c
  4. 5
      src/core/security/credentials.h
  5. 8
      src/cpp/client/secure_credentials.cc
  6. 2
      src/cpp/client/secure_credentials.h
  7. 8
      src/csharp/ext/grpc_csharp_ext.c
  8. 5
      src/node/ext/call_credentials.cc
  9. 2
      src/node/ext/call_credentials.h
  10. 74
      test/core/security/credentials_test.c
  11. 4
      test/core/security/oauth2_utils.c
  12. 5
      test/core/security/print_google_default_creds_token.c

@ -41,6 +41,81 @@
extern "C" { extern "C" {
#endif #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. --- /* --- grpc_channel_credentials object. ---
A channel credentials object represents a way to authenticate a client on a A channel credentials object represents a way to authenticate a client on a
@ -165,6 +240,24 @@ typedef void (*grpc_credentials_plugin_metadata_cb)(
void *user_data, const grpc_metadata *creds_md, size_t num_creds_md, void *user_data, const grpc_metadata *creds_md, size_t num_creds_md,
grpc_status_code status, const char *error_details); 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).
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. */
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 /* 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 create grpc_credentials objects that can be set on a channel (composed) or
a call. See grpc_credentials_metadata_create_from_plugin below. a call. See grpc_credentials_metadata_create_from_plugin below.
@ -172,11 +265,11 @@ typedef void (*grpc_credentials_plugin_metadata_cb)(
every call in scope for the credentials created from it. */ every call in scope for the credentials created from it. */
typedef struct { typedef struct {
/* The implementation of this method has to be non-blocking. /* The implementation of this method has to be non-blocking.
- service_url is the fully qualified URL that the client stack is - context is the information that can be used by the plugin to create auth
connecting to. metadata.
- cb is the callback that needs to be called when the metadata is ready. - 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. */ - 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); grpc_credentials_plugin_metadata_cb cb, void *user_data);
/* Destroys the plugin state. */ /* Destroys the plugin state. */
@ -184,6 +277,9 @@ typedef struct {
/* State that will be set as the first parameter of the methods above. */ /* State that will be set as the first parameter of the methods above. */
void *state; void *state;
/* Type of credentials that this plugin is implementing. */
const char *type;
} grpc_metadata_credentials_plugin; } grpc_metadata_credentials_plugin;
/* Creates a credentials object from a plugin. */ /* Creates a credentials object from a plugin. */
@ -239,81 +335,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_error grpc_call_set_credentials(grpc_call *call,
grpc_call_credentials *creds); 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 --- */ /* --- Auth Metadata Processing --- */
/* Callback function that is called when the metadata processing is done. /* Callback function that is called when the metadata processing is done.

@ -63,7 +63,7 @@ typedef struct {
int sent_initial_metadata; int sent_initial_metadata;
gpr_uint8 security_context_set; gpr_uint8 security_context_set;
grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT]; grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
char *service_url; grpc_auth_metadata_context auth_md_context;
} call_data; } call_data;
/* We can have a per-channel credentials. */ /* We can have a per-channel credentials. */
@ -76,11 +76,20 @@ typedef struct {
grpc_mdstr *status_key; grpc_mdstr *status_key;
} channel_data; } channel_data;
static void reset_service_url(call_data *calld) { static void reset_auth_metadata_context(
if (calld->service_url != NULL) { grpc_auth_metadata_context *auth_md_context) {
gpr_free(calld->service_url); if (auth_md_context->service_url != NULL) {
calld->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, 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_transport_stream_op *op = &calld->op;
grpc_metadata_batch *mdb; grpc_metadata_batch *mdb;
size_t i; size_t i;
reset_service_url(calld); reset_auth_metadata_context(&calld->auth_md_context);
if (status != GRPC_CREDENTIALS_OK) { if (status != GRPC_CREDENTIALS_OK) {
bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED, bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
"Credentials failed to get metadata."); "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); 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 *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method));
char *last_slash = strrchr(service, '/'); 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) { if (last_slash == NULL) {
gpr_log(GPR_ERROR, "No '/' found in fully qualified method name"); gpr_log(GPR_ERROR, "No '/' found in fully qualified method name");
service[0] = '\0'; service[0] = '\0';
@ -131,11 +144,16 @@ void build_service_url(const char *url_scheme, call_data *calld) {
service[1] = '\0'; service[1] = '\0';
} else { } else {
*last_slash = '\0'; *last_slash = '\0';
method_name = gpr_strdup(last_slash + 1);
} }
if (url_scheme == NULL) url_scheme = ""; if (method_name == NULL) method_name = gpr_strdup("");
reset_service_url(calld); gpr_asprintf(&service_url, "%s://%s%s",
gpr_asprintf(&calld->service_url, "%s://%s%s", url_scheme, sc->url_scheme == NULL ? "" : sc->url_scheme,
grpc_mdstr_as_c_string(calld->host), service); 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); gpr_free(service);
} }
@ -169,12 +187,12 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
call_creds_has_md ? ctx->creds : channel_call_creds); 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). */ calld->op = *op; /* Copy op (originates from the caller's stack). */
GPR_ASSERT(calld->pollset); GPR_ASSERT(calld->pollset);
grpc_call_credentials_get_request_metadata(exec_ctx, calld->creds, grpc_call_credentials_get_request_metadata(
calld->pollset, calld->service_url, exec_ctx, calld->creds, calld->pollset, calld->auth_md_context,
on_credentials_metadata, elem); on_credentials_metadata, elem);
} }
static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data, static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
@ -297,7 +315,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
if (calld->method != NULL) { if (calld->method != NULL) {
GRPC_MDSTR_UNREF(calld->method); GRPC_MDSTR_UNREF(calld->method);
} }
reset_service_url(calld); reset_auth_metadata_context(&calld->auth_md_context);
} }
/* Constructor for channel_data */ /* Constructor for channel_data */

@ -33,16 +33,16 @@
#include "src/core/security/credentials.h" #include "src/core/security/credentials.h"
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include "src/core/channel/channel_args.h" #include "src/core/channel/channel_args.h"
#include "src/core/channel/http_client_filter.h" #include "src/core/channel/http_client_filter.h"
#include "src/core/json/json.h"
#include "src/core/httpcli/httpcli.h" #include "src/core/httpcli/httpcli.h"
#include "src/core/iomgr/iomgr.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/support/string.h"
#include "src/core/surface/api_trace.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
@ -117,15 +117,16 @@ void grpc_call_credentials_release(grpc_call_credentials *creds) {
} }
void grpc_call_credentials_get_request_metadata( void grpc_call_credentials_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { 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 (creds == NULL || creds->vtable->get_request_metadata == NULL) {
if (cb != NULL) { if (cb != NULL) {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
} }
return; 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); user_data);
} }
@ -207,8 +208,7 @@ grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) {
return arg; return arg;
} }
grpc_server_credentials *grpc_server_credentials_from_arg( grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg) {
const grpc_arg *arg) {
if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL; if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL;
if (arg->type != GRPC_ARG_POINTER) { if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, 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); gpr_mu_destroy(&c->cache_mu);
} }
static void jwt_get_request_metadata( static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, grpc_call_credentials *creds,
const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { 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 *c =
(grpc_service_account_jwt_access_credentials *)creds; (grpc_service_account_jwt_access_credentials *)creds;
gpr_timespec refresh_threshold = gpr_time_from_seconds( gpr_timespec refresh_threshold = gpr_time_from_seconds(
@ -437,7 +440,7 @@ static void jwt_get_request_metadata(
{ {
gpr_mu_lock(&c->cache_mu); gpr_mu_lock(&c->cache_mu);
if (c->cached.service_url != NULL && 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 && c->cached.jwt_md != NULL &&
(gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration, (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration,
gpr_now(GPR_CLOCK_REALTIME)), gpr_now(GPR_CLOCK_REALTIME)),
@ -452,14 +455,15 @@ static void jwt_get_request_metadata(
/* Generate a new jwt. */ /* Generate a new jwt. */
gpr_mu_lock(&c->cache_mu); gpr_mu_lock(&c->cache_mu);
jwt_reset_cache(c); 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) { if (jwt != NULL) {
char *md_value; char *md_value;
gpr_asprintf(&md_value, "Bearer %s", jwt); gpr_asprintf(&md_value, "Bearer %s", jwt);
gpr_free(jwt); gpr_free(jwt);
c->cached.jwt_expiration = c->cached.jwt_expiration =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime); 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); c->cached.jwt_md = grpc_credentials_md_store_create(1);
grpc_credentials_md_store_add_cstrings( grpc_credentials_md_store_add_cstrings(
c->cached.jwt_md, GRPC_AUTHORIZATION_METADATA_KEY, md_value); 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( static void oauth2_token_fetcher_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, 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_credentials_metadata_cb cb, void *user_data) {
grpc_oauth2_token_fetcher_credentials *c = grpc_oauth2_token_fetcher_credentials *c =
(grpc_oauth2_token_fetcher_credentials *)creds; (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( static void md_only_test_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { 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; grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
if (c->is_async) { if (c->is_async) {
@ -839,8 +844,9 @@ static void access_token_destruct(grpc_call_credentials *creds) {
} }
static void access_token_get_request_metadata( static void access_token_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { 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; grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK); 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; grpc_composite_call_credentials *composite_creds;
size_t creds_index; size_t creds_index;
grpc_credentials_md_store *md_elems; grpc_credentials_md_store *md_elems;
char *service_url; grpc_auth_metadata_context auth_md_context;
void *user_data; void *user_data;
grpc_pollset *pollset; grpc_pollset *pollset;
grpc_credentials_metadata_cb cb; 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( static void composite_call_md_context_destroy(
grpc_composite_call_credentials_metadata_context *ctx) { grpc_composite_call_credentials_metadata_context *ctx) {
grpc_credentials_md_store_unref(ctx->md_elems); grpc_credentials_md_store_unref(ctx->md_elems);
if (ctx->service_url != NULL) gpr_free(ctx->service_url);
gpr_free(ctx); 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) { if (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
grpc_call_credentials *inner_creds = grpc_call_credentials *inner_creds =
ctx->composite_creds->inner.creds_array[ctx->creds_index++]; ctx->composite_creds->inner.creds_array[ctx->creds_index++];
grpc_call_credentials_get_request_metadata(exec_ctx, inner_creds, grpc_call_credentials_get_request_metadata(
ctx->pollset, ctx->service_url, exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context,
composite_call_metadata_cb, ctx); composite_call_metadata_cb, ctx);
return; 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( static void composite_call_get_request_metadata(
grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds, grpc_pollset *pollset, grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) { 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 *c = (grpc_composite_call_credentials *)creds;
grpc_composite_call_credentials_metadata_context *ctx; grpc_composite_call_credentials_metadata_context *ctx;
ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context)); ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context));
memset(ctx, 0, 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->user_data = user_data;
ctx->cb = cb; ctx->cb = cb;
ctx->composite_creds = c; ctx->composite_creds = c;
ctx->pollset = pollset; ctx->pollset = pollset;
ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds); ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds);
grpc_call_credentials_get_request_metadata( grpc_call_credentials_get_request_metadata(
exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset, service_url, exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset,
composite_call_metadata_cb, ctx); auth_md_context, composite_call_metadata_cb, ctx);
} }
static grpc_call_credentials_vtable composite_call_credentials_vtable = { 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, static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds, grpc_call_credentials *creds,
grpc_pollset *pollset, grpc_pollset *pollset,
const char *service_url, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, grpc_credentials_metadata_cb cb,
void *user_data) { void *user_data) {
grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds; 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, 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( grpc_call_credentials *grpc_google_iam_credentials_create(
const char *token, const char *authority_selector, void *reserved) { 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, static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds, grpc_call_credentials *creds,
grpc_pollset *pollset, grpc_pollset *pollset,
const char *service_url, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, grpc_credentials_metadata_cb cb,
void *user_data) { void *user_data) {
grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds; 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)); memset(request, 0, sizeof(*request));
request->user_data = user_data; request->user_data = user_data;
request->cb = cb; 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); plugin_md_request_metadata_ready, request);
} else { } else {
cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK); cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
@ -1204,7 +1210,7 @@ grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
(reserved)); (reserved));
GPR_ASSERT(reserved == NULL); GPR_ASSERT(reserved == NULL);
memset(c, 0, sizeof(*c)); memset(c, 0, sizeof(*c));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN; c->base.type = plugin.type;
c->base.vtable = &plugin_vtable; c->base.vtable = &plugin_vtable;
gpr_ref_init(&c->base.refcount, 1); gpr_ref_init(&c->base.refcount, 1);
c->plugin = plugin; c->plugin = plugin;

@ -59,7 +59,6 @@ typedef enum {
"FakeTransportSecurity" "FakeTransportSecurity"
#define GRPC_CALL_CREDENTIALS_TYPE_OAUTH2 "Oauth2" #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_JWT "Jwt"
#define GRPC_CALL_CREDENTIALS_TYPE_IAM "Iam" #define GRPC_CALL_CREDENTIALS_TYPE_IAM "Iam"
#define GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE "Composite" #define GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE "Composite"
@ -162,7 +161,7 @@ typedef struct {
void (*destruct)(grpc_call_credentials *c); void (*destruct)(grpc_call_credentials *c);
void (*get_request_metadata)(grpc_exec_ctx *exec_ctx, void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *c, grpc_pollset *pollset, grpc_call_credentials *c, grpc_pollset *pollset,
const char *service_url, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, grpc_credentials_metadata_cb cb,
void *user_data); void *user_data);
} grpc_call_credentials_vtable; } grpc_call_credentials_vtable;
@ -178,7 +177,7 @@ void grpc_call_credentials_unref(grpc_call_credentials *creds);
void grpc_call_credentials_get_request_metadata(grpc_exec_ctx *exec_ctx, void grpc_call_credentials_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds, grpc_call_credentials *creds,
grpc_pollset *pollset, grpc_pollset *pollset,
const char *service_url, grpc_auth_metadata_context context,
grpc_credentials_metadata_cb cb, grpc_credentials_metadata_cb cb,
void *user_data); void *user_data);

@ -160,7 +160,7 @@ void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) {
} }
void MetadataCredentialsPluginWrapper::GetMetadata( 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) { grpc_credentials_plugin_metadata_cb cb, void* user_data) {
GPR_ASSERT(wrapper); GPR_ASSERT(wrapper);
MetadataCredentialsPluginWrapper* w = MetadataCredentialsPluginWrapper* w =
@ -172,9 +172,9 @@ void MetadataCredentialsPluginWrapper::GetMetadata(
if (w->plugin_->IsBlocking()) { if (w->plugin_->IsBlocking()) {
w->thread_pool_->Add( w->thread_pool_->Add(
std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w,
service_url, cb, user_data)); context.service_url, cb, user_data));
} else { } else {
w->InvokePlugin(service_url, cb, user_data); w->InvokePlugin(context.service_url, cb, user_data);
} }
} }
@ -208,7 +208,7 @@ std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
new MetadataCredentialsPluginWrapper(std::move(plugin)); new MetadataCredentialsPluginWrapper(std::move(plugin));
grpc_metadata_credentials_plugin c_plugin = { grpc_metadata_credentials_plugin c_plugin = {
MetadataCredentialsPluginWrapper::GetMetadata, MetadataCredentialsPluginWrapper::GetMetadata,
MetadataCredentialsPluginWrapper::Destroy, wrapper}; MetadataCredentialsPluginWrapper::Destroy, wrapper, ""};
return WrapCallCredentials( return WrapCallCredentials(
grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr));
} }

@ -80,7 +80,7 @@ class SecureCallCredentials GRPC_FINAL : public CallCredentials {
class MetadataCredentialsPluginWrapper GRPC_FINAL { class MetadataCredentialsPluginWrapper GRPC_FINAL {
public: public:
static void Destroy(void* wrapper); 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, grpc_credentials_plugin_metadata_cb cb,
void* user_data); void* user_data);

@ -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 *state, const char *service_url, grpc_credentials_plugin_metadata_cb cb,
void *user_data, gpr_int32 is_destroy); void *user_data, gpr_int32 is_destroy);
static void grpcsharp_get_metadata_handler(void *state, const char *service_url, static void grpcsharp_get_metadata_handler(
grpc_credentials_plugin_metadata_cb cb, void *user_data) { 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 interceptor =
(grpcsharp_metadata_interceptor_func)(gpr_intptr)state; (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) { static void grpcsharp_metadata_credentials_destroy_handler(void *state) {
@ -949,6 +950,7 @@ GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_cr
plugin.get_metadata = grpcsharp_get_metadata_handler; plugin.get_metadata = grpcsharp_get_metadata_handler;
plugin.destroy = grpcsharp_metadata_credentials_destroy_handler; plugin.destroy = grpcsharp_metadata_credentials_destroy_handler;
plugin.state = (void*)(gpr_intptr)metadata_interceptor; plugin.state = (void*)(gpr_intptr)metadata_interceptor;
plugin.type = "";
return grpc_metadata_credentials_create_from_plugin(plugin, NULL); return grpc_metadata_credentials_create_from_plugin(plugin, NULL);
} }

@ -162,6 +162,7 @@ NAN_METHOD(CallCredentials::CreateFromPlugin) {
plugin.get_metadata = plugin_get_metadata; plugin.get_metadata = plugin_get_metadata;
plugin.destroy = plugin_destroy_state; plugin.destroy = plugin_destroy_state;
plugin.state = reinterpret_cast<void*>(state); plugin.state = reinterpret_cast<void*>(state);
plugin.type = "";
grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin( grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin(
plugin, NULL); plugin, NULL);
info.GetReturnValue().Set(WrapStruct(creds)); info.GetReturnValue().Set(WrapStruct(creds));
@ -225,7 +226,7 @@ NAUV_WORK_CB(SendPluginCallback) {
uv_close((uv_handle_t *)async, (uv_close_cb)free); 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, grpc_credentials_plugin_metadata_cb cb,
void *user_data) { void *user_data) {
uv_async_t *async = static_cast<uv_async_t*>(malloc(sizeof(uv_async_t))); uv_async_t *async = static_cast<uv_async_t*>(malloc(sizeof(uv_async_t)));
@ -234,7 +235,7 @@ void plugin_get_metadata(void *state, const char *service_url,
SendPluginCallback); SendPluginCallback);
plugin_callback_data *data = new plugin_callback_data; plugin_callback_data *data = new plugin_callback_data;
data->state = reinterpret_cast<plugin_state*>(state); data->state = reinterpret_cast<plugin_state*>(state);
data->service_url = service_url; data->service_url = context.service_url;
data->cb = cb; data->cb = cb;
data->user_data = user_data; data->user_data = user_data;
async->data = data; async->data = data;

@ -84,7 +84,7 @@ typedef struct plugin_callback_data {
void *user_data; void *user_data;
} plugin_callback_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, grpc_credentials_plugin_metadata_cb cb,
void *user_data); void *user_data);

@ -126,6 +126,8 @@ static const char test_signed_jwt[] =
static const char test_service_url[] = "https://foo.com/foo.v1"; 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 other_test_service_url[] = "https://bar.com/bar.v1";
static const char test_method[] = "ThisIsNotAMethod";
/* -- Utils. -- */ /* -- Utils. -- */
static char *test_json_key_str(void) { 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( grpc_call_credentials *creds = grpc_google_iam_credentials_create(
test_google_iam_authorization_token, test_google_iam_authority_selector, test_google_iam_authorization_token, test_google_iam_authority_selector,
NULL); NULL);
grpc_call_credentials_get_request_metadata(&exec_ctx, creds, NULL, grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, NULL,
test_service_url, NULL};
check_google_iam_metadata, creds); grpc_call_credentials_get_request_metadata(
&exec_ctx, creds, NULL, auth_md_ctx, check_google_iam_metadata, creds);
grpc_exec_ctx_finish(&exec_ctx); 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_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_call_credentials *creds = grpc_call_credentials *creds =
grpc_access_token_credentials_create("blah", NULL); 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); GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
grpc_call_credentials_get_request_metadata( 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); creds);
grpc_exec_ctx_finish(&exec_ctx); 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) { static void test_oauth2_google_iam_composite_creds(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
const grpc_call_credentials_array *creds_array; 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( grpc_call_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
"authorization", test_oauth2_bearer_token, 0); "authorization", test_oauth2_bearer_token, 0);
grpc_call_credentials *google_iam_creds = grpc_google_iam_credentials_create( 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, GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0); GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0);
grpc_call_credentials_get_request_metadata( 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); check_oauth2_google_iam_composite_metadata, composite_creds);
grpc_exec_ctx_finish(&exec_ctx); 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_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_call_credentials *compute_engine_creds = grpc_call_credentials *compute_engine_creds =
grpc_google_compute_engine_credentials_create(NULL); 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. */ /* First request: http get should be called. */
grpc_httpcli_set_override(compute_engine_httpcli_get_success_override, grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
httpcli_post_should_not_be_called); httpcli_post_should_not_be_called);
grpc_call_credentials_get_request_metadata( 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); on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx); 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, grpc_httpcli_set_override(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called); httpcli_post_should_not_be_called);
grpc_call_credentials_get_request_metadata( 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); on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_finish(&exec_ctx); 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) { static void test_compute_engine_creds_failure(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 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_call_credentials *compute_engine_creds =
grpc_google_compute_engine_credentials_create(NULL); grpc_google_compute_engine_credentials_create(NULL);
grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override, grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
httpcli_post_should_not_be_called); httpcli_post_should_not_be_called);
grpc_call_credentials_get_request_metadata( 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); on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
grpc_call_credentials_unref(compute_engine_creds); grpc_call_credentials_unref(compute_engine_creds);
grpc_httpcli_set_override(NULL, NULL); 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) { static void test_refresh_token_creds_success(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 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_call_credentials *refresh_token_creds =
grpc_google_refresh_token_credentials_create(test_refresh_token_str, grpc_google_refresh_token_credentials_create(test_refresh_token_str,
NULL); NULL);
@ -664,7 +677,7 @@ static void test_refresh_token_creds_success(void) {
grpc_httpcli_set_override(httpcli_get_should_not_be_called, grpc_httpcli_set_override(httpcli_get_should_not_be_called,
refresh_token_httpcli_post_success); refresh_token_httpcli_post_success);
grpc_call_credentials_get_request_metadata( 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); on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx); 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, grpc_httpcli_set_override(httpcli_get_should_not_be_called,
httpcli_post_should_not_be_called); httpcli_post_should_not_be_called);
grpc_call_credentials_get_request_metadata( 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); on_oauth2_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx); 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) { static void test_refresh_token_creds_failure(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 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_call_credentials *refresh_token_creds =
grpc_google_refresh_token_credentials_create(test_refresh_token_str, grpc_google_refresh_token_credentials_create(test_refresh_token_str,
NULL); NULL);
grpc_httpcli_set_override(httpcli_get_should_not_be_called, grpc_httpcli_set_override(httpcli_get_should_not_be_called,
refresh_token_httpcli_post_failure); refresh_token_httpcli_post_failure);
grpc_call_credentials_get_request_metadata( 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); on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
grpc_call_credentials_unref(refresh_token_creds); grpc_call_credentials_unref(refresh_token_creds);
grpc_httpcli_set_override(NULL, NULL); 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) { static void test_jwt_creds_success(void) {
char *json_key_string = test_json_key_str(); char *json_key_string = test_json_key_str();
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 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_call_credentials *jwt_creds =
grpc_service_account_jwt_access_credentials_create( grpc_service_account_jwt_access_credentials_create(
json_key_string, grpc_max_auth_token_lifetime, NULL); 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. */ /* First request: jwt_encode_and_sign should be called. */
grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success); grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
grpc_call_credentials_get_request_metadata( 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); on_jwt_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx); grpc_exec_ctx_flush(&exec_ctx);
@ -787,15 +804,16 @@ static void test_jwt_creds_success(void) {
grpc_jwt_encode_and_sign_set_override( grpc_jwt_encode_and_sign_set_override(
encode_and_sign_jwt_should_not_be_called); encode_and_sign_jwt_should_not_be_called);
grpc_call_credentials_get_request_metadata( 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); on_jwt_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx); grpc_exec_ctx_flush(&exec_ctx);
/* Third request: Different service url so jwt_encode_and_sign should be /* Third request: Different service url so jwt_encode_and_sign should be
called again (no caching). */ 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_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
grpc_call_credentials_get_request_metadata( 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); on_jwt_creds_get_metadata_success, (void *)test_user_data);
grpc_exec_ctx_flush(&exec_ctx); 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) { static void test_jwt_creds_signing_failure(void) {
char *json_key_string = test_json_key_str(); char *json_key_string = test_json_key_str();
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 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_call_credentials *jwt_creds =
grpc_service_account_jwt_access_credentials_create( grpc_service_account_jwt_access_credentials_create(
json_key_string, grpc_max_auth_token_lifetime, NULL); json_key_string, grpc_max_auth_token_lifetime, NULL);
grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure); grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure);
grpc_call_credentials_get_request_metadata( 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); on_jwt_creds_get_metadata_failure, (void *)test_user_data);
gpr_free(json_key_string); gpr_free(json_key_string);
@ -884,13 +904,17 @@ typedef struct {
static const plugin_metadata plugin_md[] = {{"foo", "bar"}, {"hi", "there"}}; 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, grpc_credentials_plugin_metadata_cb cb,
void *user_data) { void *user_data) {
size_t i; size_t i;
grpc_metadata md[GPR_ARRAY_SIZE(plugin_md)]; grpc_metadata md[GPR_ARRAY_SIZE(plugin_md)];
plugin_state *s = (plugin_state *)state; 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; *s = PLUGIN_GET_METADATA_CALLED_STATE;
for (i = 0; i < GPR_ARRAY_SIZE(plugin_md); i++) { for (i = 0; i < GPR_ARRAY_SIZE(plugin_md); i++) {
memset(&md[i], 0, sizeof(grpc_metadata)); 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); 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, grpc_credentials_plugin_metadata_cb cb,
void *user_data) { void *user_data) {
plugin_state *s = (plugin_state *)state; 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; *s = PLUGIN_GET_METADATA_CALLED_STATE;
cb(user_data, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, cb(user_data, NULL, 0, GRPC_STATUS_UNAUTHENTICATED,
"Could not get metadata for plugin."); "Could not get metadata for plugin.");
@ -943,6 +971,8 @@ static void test_metadata_plugin_success(void) {
plugin_state state = PLUGIN_INITIAL_STATE; plugin_state state = PLUGIN_INITIAL_STATE;
grpc_metadata_credentials_plugin plugin; grpc_metadata_credentials_plugin plugin;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 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.state = &state;
plugin.get_metadata = plugin_get_metadata_success; 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); creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
GPR_ASSERT(state == PLUGIN_INITIAL_STATE); GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
grpc_call_credentials_get_request_metadata( 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); on_plugin_metadata_received_success, NULL);
GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
grpc_call_credentials_release(creds); grpc_call_credentials_release(creds);
@ -964,6 +994,8 @@ static void test_metadata_plugin_failure(void) {
plugin_state state = PLUGIN_INITIAL_STATE; plugin_state state = PLUGIN_INITIAL_STATE;
grpc_metadata_credentials_plugin plugin; grpc_metadata_credentials_plugin plugin;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 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.state = &state;
plugin.get_metadata = plugin_get_metadata_failure; 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); creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
GPR_ASSERT(state == PLUGIN_INITIAL_STATE); GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
grpc_call_credentials_get_request_metadata( 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); on_plugin_metadata_received_failure, NULL);
GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE); GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
grpc_call_credentials_release(creds); grpc_call_credentials_release(creds);

@ -80,13 +80,15 @@ char *grpc_test_fetch_oauth2_token_with_credentials(
oauth2_request request; oauth2_request request;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_closure do_nothing_closure; grpc_closure do_nothing_closure;
grpc_auth_metadata_context null_ctx = {"", "", NULL, NULL};
grpc_pollset_init(&request.pollset); grpc_pollset_init(&request.pollset);
request.is_done = 0; request.is_done = 0;
grpc_closure_init(&do_nothing_closure, do_nothing, NULL); grpc_closure_init(&do_nothing_closure, do_nothing, NULL);
grpc_call_credentials_get_request_metadata(&exec_ctx, creds, &request.pollset, 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); grpc_exec_ctx_finish(&exec_ctx);

@ -74,10 +74,13 @@ int main(int argc, char **argv) {
synchronizer sync; synchronizer sync;
grpc_channel_credentials *creds = NULL; grpc_channel_credentials *creds = NULL;
char *service_url = "https://test.foo.google.com/Foo"; 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 *cl = gpr_cmdline_create("print_google_default_creds_token");
gpr_cmdline_add_string(cl, "service_url", gpr_cmdline_add_string(cl, "service_url",
"Service URL for the token request.", &service_url); "Service URL for the token request.", &service_url);
gpr_cmdline_parse(cl, argc, argv); gpr_cmdline_parse(cl, argc, argv);
memset(&context, 0, sizeof(context));
context.service_url = service_url;
grpc_init(); grpc_init();
@ -93,7 +96,7 @@ int main(int argc, char **argv) {
grpc_call_credentials_get_request_metadata( grpc_call_credentials_get_request_metadata(
&exec_ctx, ((grpc_composite_channel_credentials *)creds)->call_creds, &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)); gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
while (!sync.is_done) { while (!sync.is_done) {

Loading…
Cancel
Save