Merge branch 'auth_md_processor' of github.com:jboeuf/grpc into complain-with-both-passion-and-meaning

pull/2492/head
Craig Tiller 9 years ago
commit be043d9ce7
  1. 53
      include/grpc/grpc_security.h
  2. 48
      src/core/security/credentials.c
  3. 13
      src/core/security/credentials.h
  4. 32
      src/core/security/security_connector.c
  5. 100
      src/core/security/security_context.c
  6. 33
      src/core/security/security_context.h
  7. 151
      src/core/security/server_auth_filter.c
  8. 4
      test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
  9. 226
      test/core/end2end/tests/request_response_with_payload_and_call_creds.c
  10. 73
      test/core/security/auth_context_test.c
  11. 8
      test/core/security/credentials_test.c
  12. 15
      test/cpp/common/auth_property_iterator_test.cc
  13. 22
      test/cpp/common/secure_auth_context_test.cc

@ -199,8 +199,6 @@ grpc_call_error grpc_call_set_credentials(grpc_call *call,
/* --- Authentication Context. --- */
/* TODO(jboeuf): Define some well-known property names. */
#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME "transport_security_type"
#define GRPC_SSL_TRANSPORT_SECURITY_TYPE "ssl"
@ -255,6 +253,57 @@ 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 that will augment the channel auth context (see below).
-- */
/* Creates a new auth context based off a chained context. */
grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained);
/* 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 --- */
/* Opaque data structure useful for processors defined in core. */
typedef struct grpc_auth_ticket grpc_auth_ticket;
/* Callback function that is called when the metadata processing is done.
success is 1 if processing succeeded, 0 otherwise. */
typedef void (*grpc_process_auth_metadata_done_cb)(
void *user_data, const grpc_metadata *consumed_md, size_t num_consumed_md,
int success, grpc_auth_context *result);
/* Pluggable server-side metadata processor object */
typedef struct {
void (*process)(void *state, grpc_auth_ticket *ticket,
grpc_auth_context *channel_ctx, const grpc_metadata *md,
size_t md_count, grpc_process_auth_metadata_done_cb cb,
void *user_data);
void *state;
} grpc_auth_metadata_processor;
/* XXXX: this is a temporarty interface. Please do NOT use.
This function will be moved to the server_credentials in a subsequent
pull request. XXXX
Registration function for metadata processing.
Should be called before the server is started. */
void grpc_server_register_auth_metadata_processor(
grpc_auth_metadata_processor processor);
#ifdef __cplusplus
}
#endif

@ -765,19 +765,19 @@ grpc_credentials *grpc_refresh_token_credentials_create(
grpc_auth_refresh_token_create_from_string(json_refresh_token));
}
/* -- Fake Oauth2 credentials. -- */
/* -- Metadata-only credentials. -- */
static void fake_oauth2_destroy(grpc_credentials *creds) {
grpc_fake_oauth2_credentials *c = (grpc_fake_oauth2_credentials *)creds;
grpc_credentials_md_store_unref(c->access_token_md);
static void md_only_test_destroy(grpc_credentials *creds) {
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
grpc_credentials_md_store_unref(c->md_store);
gpr_free(c);
}
static int fake_oauth2_has_request_metadata(const grpc_credentials *creds) {
static int md_only_test_has_request_metadata(const grpc_credentials *creds) {
return 1;
}
static int fake_oauth2_has_request_metadata_only(
static int md_only_test_has_request_metadata_only(
const grpc_credentials *creds) {
return 1;
}
@ -785,19 +785,19 @@ static int fake_oauth2_has_request_metadata_only(
void on_simulated_token_fetch_done(void *user_data, int success) {
grpc_credentials_metadata_request *r =
(grpc_credentials_metadata_request *)user_data;
grpc_fake_oauth2_credentials *c = (grpc_fake_oauth2_credentials *)r->creds;
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)r->creds;
GPR_ASSERT(success);
r->cb(r->user_data, c->access_token_md->entries,
c->access_token_md->num_entries, GRPC_CREDENTIALS_OK);
r->cb(r->user_data, c->md_store->entries,
c->md_store->num_entries, GRPC_CREDENTIALS_OK);
grpc_credentials_metadata_request_destroy(r);
}
static void fake_oauth2_get_request_metadata(grpc_credentials *creds,
static void md_only_test_get_request_metadata(grpc_credentials *creds,
grpc_pollset *pollset,
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data) {
grpc_fake_oauth2_credentials *c = (grpc_fake_oauth2_credentials *)creds;
grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
if (c->is_async) {
grpc_credentials_metadata_request *cb_arg =
@ -806,26 +806,26 @@ static void fake_oauth2_get_request_metadata(grpc_credentials *creds,
on_simulated_token_fetch_done, cb_arg);
grpc_iomgr_add_callback(cb_arg->on_simulated_token_fetch_done_closure);
} else {
cb(user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
cb(user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK);
}
}
static grpc_credentials_vtable fake_oauth2_vtable = {
fake_oauth2_destroy, fake_oauth2_has_request_metadata,
fake_oauth2_has_request_metadata_only, fake_oauth2_get_request_metadata,
static grpc_credentials_vtable md_only_test_vtable = {
md_only_test_destroy, md_only_test_has_request_metadata,
md_only_test_has_request_metadata_only, md_only_test_get_request_metadata,
NULL};
grpc_credentials *grpc_fake_oauth2_credentials_create(
const char *token_md_value, int is_async) {
grpc_fake_oauth2_credentials *c =
gpr_malloc(sizeof(grpc_fake_oauth2_credentials));
memset(c, 0, sizeof(grpc_fake_oauth2_credentials));
grpc_credentials *grpc_md_only_test_credentials_create(const char *md_key,
const char *md_value,
int is_async) {
grpc_md_only_test_credentials *c =
gpr_malloc(sizeof(grpc_md_only_test_credentials));
memset(c, 0, sizeof(grpc_md_only_test_credentials));
c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
c->base.vtable = &fake_oauth2_vtable;
c->base.vtable = &md_only_test_vtable;
gpr_ref_init(&c->base.refcount, 1);
c->access_token_md = grpc_credentials_md_store_create(1);
grpc_credentials_md_store_add_cstrings(
c->access_token_md, GRPC_AUTHORIZATION_METADATA_KEY, token_md_value);
c->md_store = grpc_credentials_md_store_create(1);
grpc_credentials_md_store_add_cstrings(c->md_store, md_key, md_value);
c->is_async = is_async;
return &c->base;
}

@ -190,9 +190,10 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
grpc_credentials_md_store **token_md, gpr_timespec *token_lifetime);
void grpc_flush_cached_google_default_credentials(void);
/* Simulates an oauth2 token fetch with the specified value for testing. */
grpc_credentials *grpc_fake_oauth2_credentials_create(
const char *token_md_value, int is_async);
/* Metadata-only credentials with the specified key and value where
asynchronicity can be simulated for testing. */
grpc_credentials *grpc_md_only_test_credentials_create(
const char *md_key, const char *md_value, int is_async);
/* Private constructor for jwt credentials from an already parsed json key.
Takes ownership of the key. */
@ -297,13 +298,13 @@ typedef struct {
grpc_credentials_md_store *access_token_md;
} grpc_access_token_credentials;
/* -- Fake Oauth2 credentials. -- */
/* -- Metadata-only Test credentials. -- */
typedef struct {
grpc_credentials base;
grpc_credentials_md_store *access_token_md;
grpc_credentials_md_store *md_store;
int is_async;
} grpc_fake_oauth2_credentials;
} grpc_md_only_test_credentials;
/* -- IAM credentials. -- */

@ -263,9 +263,9 @@ static grpc_security_status fake_check_peer(grpc_security_connector *sc,
goto end;
}
GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
sc->auth_context = grpc_auth_context_create(NULL, 1);
sc->auth_context->properties[0] = grpc_auth_property_init_from_cstring(
GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
sc->auth_context = grpc_auth_context_create(NULL);
grpc_auth_context_add_cstring_property(
sc->auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_FAKE_TRANSPORT_SECURITY_TYPE);
end:
@ -409,31 +409,35 @@ static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) {
grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) {
size_t i;
grpc_auth_context *ctx = NULL;
const char *peer_identity_property_name = NULL;
/* The caller has checked the certificate type property. */
GPR_ASSERT(peer->property_count >= 1);
ctx = grpc_auth_context_create(NULL, peer->property_count);
ctx->properties[0] = grpc_auth_property_init_from_cstring(
GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
ctx = grpc_auth_context_create(NULL);
grpc_auth_context_add_cstring_property(
ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_SSL_TRANSPORT_SECURITY_TYPE);
ctx->property_count = 1;
for (i = 0; i < peer->property_count; i++) {
const tsi_peer_property *prop = &peer->properties[i];
if (prop->name == NULL) continue;
if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) {
/* If there is no subject alt name, have the CN as the identity. */
if (ctx->peer_identity_property_name == NULL) {
ctx->peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME;
if (peer_identity_property_name == NULL) {
peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME;
}
ctx->properties[ctx->property_count++] = grpc_auth_property_init(
GRPC_X509_CN_PROPERTY_NAME, prop->value.data, prop->value.length);
grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME,
prop->value.data, prop->value.length);
} else if (strcmp(prop->name,
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
ctx->peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME;
ctx->properties[ctx->property_count++] = grpc_auth_property_init(
GRPC_X509_SAN_PROPERTY_NAME, prop->value.data, prop->value.length);
peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME;
grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME,
prop->value.data, prop->value.length);
}
}
if (peer_identity_property_name != NULL) {
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
ctx, peer_identity_property_name) == 1);
}
return ctx;
}

@ -42,6 +42,19 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
/* --- grpc_process_auth_metadata_func --- */
static grpc_auth_metadata_processor server_processor = {NULL, NULL};
grpc_auth_metadata_processor grpc_server_get_auth_metadata_processor(void) {
return server_processor;
}
void grpc_server_register_auth_metadata_processor(
grpc_auth_metadata_processor processor) {
server_processor = processor;
}
/* --- grpc_call --- */
grpc_call_error grpc_call_set_credentials(grpc_call *call,
@ -120,15 +133,15 @@ void grpc_server_security_context_destroy(void *ctx) {
static grpc_auth_property_iterator empty_iterator = {NULL, 0, NULL};
grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained,
size_t property_count) {
grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained) {
grpc_auth_context *ctx = gpr_malloc(sizeof(grpc_auth_context));
memset(ctx, 0, sizeof(grpc_auth_context));
ctx->properties = gpr_malloc(property_count * sizeof(grpc_auth_property));
memset(ctx->properties, 0, property_count * sizeof(grpc_auth_property));
ctx->property_count = property_count;
gpr_ref_init(&ctx->refcount, 1);
if (chained != NULL) ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained");
if (chained != NULL) {
ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained");
ctx->peer_identity_property_name =
ctx->chained->peer_identity_property_name;
}
return ctx;
}
@ -162,11 +175,11 @@ void grpc_auth_context_unref(grpc_auth_context *ctx) {
if (gpr_unref(&ctx->refcount)) {
size_t i;
GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained");
if (ctx->properties != NULL) {
for (i = 0; i < ctx->property_count; i++) {
grpc_auth_property_reset(&ctx->properties[i]);
if (ctx->properties.array != NULL) {
for (i = 0; i < ctx->properties.count; i++) {
grpc_auth_property_reset(&ctx->properties.array[i]);
}
gpr_free(ctx->properties);
gpr_free(ctx->properties.array);
}
gpr_free(ctx);
}
@ -177,6 +190,20 @@ const char *grpc_auth_context_peer_identity_property_name(
return ctx->peer_identity_property_name;
}
int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context *ctx,
const char *name) {
grpc_auth_property_iterator it =
grpc_auth_context_find_properties_by_name(ctx, name);
const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it);
if (prop == NULL) {
gpr_log(GPR_ERROR, "Property name %s not found in auth context.",
name != NULL ? name : "NULL");
return 0;
}
ctx->peer_identity_property_name = prop->name;
return 1;
}
int grpc_auth_context_peer_is_authenticated(
const grpc_auth_context *ctx) {
return ctx->peer_identity_property_name == NULL ? 0 : 1;
@ -193,16 +220,16 @@ grpc_auth_property_iterator grpc_auth_context_property_iterator(
const grpc_auth_property *grpc_auth_property_iterator_next(
grpc_auth_property_iterator *it) {
if (it == NULL || it->ctx == NULL) return NULL;
while (it->index == it->ctx->property_count) {
while (it->index == it->ctx->properties.count) {
if (it->ctx->chained == NULL) return NULL;
it->ctx = it->ctx->chained;
it->index = 0;
}
if (it->name == NULL) {
return &it->ctx->properties[it->index++];
return &it->ctx->properties.array[it->index++];
} else {
while (it->index < it->ctx->property_count) {
const grpc_auth_property *prop = &it->ctx->properties[it->index++];
while (it->index < it->ctx->properties.count) {
const grpc_auth_property *prop = &it->ctx->properties.array[it->index++];
GPR_ASSERT(prop->name != NULL);
if (strcmp(it->name, prop->name) == 0) {
return prop;
@ -229,24 +256,37 @@ grpc_auth_property_iterator grpc_auth_context_peer_identity(
ctx, ctx->peer_identity_property_name);
}
grpc_auth_property grpc_auth_property_init_from_cstring(const char *name,
const char *value) {
grpc_auth_property prop;
prop.name = gpr_strdup(name);
prop.value = gpr_strdup(value);
prop.value_length = strlen(value);
return prop;
static void ensure_auth_context_capacity(grpc_auth_context *ctx) {
if (ctx->properties.count == ctx->properties.capacity) {
ctx->properties.capacity =
GPR_MAX(ctx->properties.capacity + 8, ctx->properties.capacity * 2);
ctx->properties.array =
gpr_realloc(ctx->properties.array,
ctx->properties.capacity * sizeof(grpc_auth_property));
}
}
grpc_auth_property grpc_auth_property_init(const char *name, const char *value,
size_t value_length) {
grpc_auth_property prop;
prop.name = gpr_strdup(name);
prop.value = gpr_malloc(value_length + 1);
memcpy(prop.value, value, value_length);
prop.value[value_length] = '\0';
prop.value_length = value_length;
return prop;
void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name,
const char *value, size_t value_length) {
grpc_auth_property *prop;
ensure_auth_context_capacity(ctx);
prop = &ctx->properties.array[ctx->properties.count++];
prop->name = gpr_strdup(name);
prop->value = gpr_malloc(value_length + 1);
memcpy(prop->value, value, value_length);
prop->value[value_length] = '\0';
prop->value_length = value_length;
}
void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx,
const char *name,
const char *value) {
grpc_auth_property *prop;
ensure_auth_context_capacity(ctx);
prop = &ctx->properties.array[ctx->properties.count++];
prop->name = gpr_strdup(name);
prop->value = gpr_strdup(value);
prop->value_length = strlen(value);
}
void grpc_auth_property_reset(grpc_auth_property *property) {

@ -34,11 +34,13 @@
#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
#define GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
#include "src/core/iomgr/pollset.h"
#include "src/core/security/credentials.h"
#ifdef __cplusplus
extern "C" {
#endif
/* --- grpc_auth_ticket --- */
struct grpc_auth_ticket {
grpc_pollset *pollset;
};
/* --- grpc_auth_context ---
@ -46,18 +48,19 @@ extern "C" {
/* Property names are always NULL terminated. */
typedef struct {
grpc_auth_property *array;
size_t count;
size_t capacity;
} grpc_auth_property_array;
struct grpc_auth_context {
struct grpc_auth_context *chained;
grpc_auth_property *properties;
size_t property_count;
grpc_auth_property_array properties;
gpr_refcount refcount;
const char *peer_identity_property_name;
};
/* Constructor. */
grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained,
size_t property_count);
/* Refcounting. */
#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
#define GRPC_AUTH_CONTEXT_REF(p, r) \
@ -76,12 +79,6 @@ grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy);
void grpc_auth_context_unref(grpc_auth_context *policy);
#endif
grpc_auth_property grpc_auth_property_init_from_cstring(const char *name,
const char *value);
grpc_auth_property grpc_auth_property_init(const char *name, const char *value,
size_t value_length);
void grpc_auth_property_reset(grpc_auth_property *property);
/* --- grpc_client_security_context ---
@ -107,9 +104,9 @@ typedef struct {
grpc_server_security_context *grpc_server_security_context_create(void);
void grpc_server_security_context_destroy(void *ctx);
#ifdef __cplusplus
}
#endif
/* --- Auth metadata processing. --- */
grpc_auth_metadata_processor grpc_server_get_auth_metadata_processor(void);
#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */

@ -31,20 +31,149 @@
*
*/
#include <string.h>
#include "src/core/security/auth_filters.h"
#include "src/core/security/security_connector.h"
#include "src/core/security/security_context.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
typedef struct call_data {
int unused; /* C89 requires at least one struct element */
gpr_uint8 got_client_metadata;
grpc_stream_op_buffer *recv_ops;
/* Closure to call when finished with the auth_on_recv hook. */
grpc_iomgr_closure *on_done_recv;
/* Receive closures are chained: we inject this closure as the on_done_recv
up-call on transport_op, and remember to call our on_done_recv member after
handling it. */
grpc_iomgr_closure auth_on_recv;
grpc_transport_stream_op transport_op;
const grpc_metadata *consumed_md;
size_t num_consumed_md;
grpc_stream_op *md_op;
grpc_auth_context **call_auth_context;
grpc_auth_ticket ticket;
} call_data;
typedef struct channel_data {
grpc_security_connector *security_connector;
grpc_mdctx *mdctx;
} channel_data;
static grpc_metadata_array metadata_batch_to_md_array(
const grpc_metadata_batch *batch) {
grpc_linked_mdelem *l;
grpc_metadata_array result;
grpc_metadata_array_init(&result);
for (l = batch->list.head; l != NULL; l = l->next) {
grpc_metadata *usr_md = NULL;
grpc_mdelem *md = l->md;
grpc_mdstr *key = md->key;
grpc_mdstr *value = md->value;
if (result.count == result.capacity) {
result.capacity = GPR_MAX(result.capacity + 8, result.capacity * 2);
result.metadata =
gpr_realloc(result.metadata, result.capacity * sizeof(grpc_metadata));
}
usr_md = &result.metadata[result.count++];
usr_md->key = grpc_mdstr_as_c_string(key);
usr_md->value = grpc_mdstr_as_c_string(value);
usr_md->value_length = GPR_SLICE_LENGTH(value->slice);
}
return result;
}
static grpc_mdelem *remove_consumed_md(void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
size_t i;
for (i = 0; i < calld->num_consumed_md; i++) {
/* Maybe we could do a pointer comparison but we do not have any guarantee
that the metadata processor used the same pointers for consumed_md in the
callback. */
if (memcmp(GPR_SLICE_START_PTR(md->key->slice), calld->consumed_md[i].key,
GPR_SLICE_LENGTH(md->key->slice)) == 0 &&
memcmp(GPR_SLICE_START_PTR(md->value->slice),
calld->consumed_md[i].value,
GPR_SLICE_LENGTH(md->value->slice)) == 0) {
return NULL; /* Delete. */
}
}
return md;
}
static void on_md_processing_done(void *user_data,
const grpc_metadata *consumed_md,
size_t num_consumed_md, int success,
grpc_auth_context *result) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
if (success) {
calld->consumed_md = consumed_md;
calld->num_consumed_md = num_consumed_md;
grpc_metadata_batch_filter(&calld->md_op->data.metadata, remove_consumed_md,
elem);
GPR_ASSERT(calld->call_auth_context != NULL);
GRPC_AUTH_CONTEXT_UNREF(*calld->call_auth_context,
"releasing old context.");
*calld->call_auth_context =
GRPC_AUTH_CONTEXT_REF(result, "refing new context.");
calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success);
} else {
grpc_transport_stream_op_add_cancellation(
&calld->transport_op, GRPC_STATUS_UNAUTHENTICATED,
grpc_mdstr_from_string(chand->mdctx,
"Authentication metadata processing failed."));
grpc_call_next_op(elem, &calld->transport_op);
}
}
static void auth_on_recv(void *user_data, int success) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
if (success) {
size_t i;
size_t nops = calld->recv_ops->nops;
grpc_stream_op *ops = calld->recv_ops->ops;
for (i = 0; i < nops; i++) {
grpc_metadata_array md_array;
grpc_auth_metadata_processor processor =
grpc_server_get_auth_metadata_processor();
grpc_stream_op *op = &ops[i];
if (op->type != GRPC_OP_METADATA || calld->got_client_metadata) continue;
calld->got_client_metadata = 1;
if (processor.process == NULL) continue;
calld->md_op = op;
md_array = metadata_batch_to_md_array(&op->data.metadata);
processor.process(processor.state, &calld->ticket,
chand->security_connector->auth_context,
md_array.metadata, md_array.count,
on_md_processing_done, elem);
grpc_metadata_array_destroy(&md_array);
return;
}
}
calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success);
}
static void set_recv_ops_md_callbacks(grpc_call_element *elem,
grpc_transport_stream_op *op) {
call_data *calld = elem->call_data;
if (op->recv_ops && !calld->got_client_metadata) {
/* substitute our callback for the higher callback */
calld->recv_ops = op->recv_ops;
calld->on_done_recv = op->on_done_recv;
op->on_done_recv = &calld->auth_on_recv;
calld->transport_op = *op;
}
}
/* Called either:
- in response to an API call (or similar) from above, to send something
- a network event (or similar) from below, to receive something
@ -52,9 +181,7 @@ typedef struct channel_data {
that is being sent or received. */
static void auth_start_transport_op(grpc_call_element *elem,
grpc_transport_stream_op *op) {
/* TODO(jboeuf): Get the metadata and get a new context from it. */
/* pass control down the stack */
set_recv_ops_md_callbacks(elem, op);
grpc_call_next_op(elem, op);
}
@ -68,11 +195,17 @@ static void init_call_elem(grpc_call_element *elem,
grpc_server_security_context *server_ctx = NULL;
/* initialize members */
calld->unused = 0;
memset(calld, 0, sizeof(*calld));
grpc_iomgr_closure_init(&calld->auth_on_recv, auth_on_recv, elem);
GPR_ASSERT(initial_op && initial_op->context != NULL &&
initial_op->context[GRPC_CONTEXT_SECURITY].value == NULL);
/* Get the pollset for the ticket. */
if (initial_op->bind_pollset) {
calld->ticket.pollset = initial_op->bind_pollset;
}
/* Create a security context for the call and reference the auth context from
the channel. */
if (initial_op->context[GRPC_CONTEXT_SECURITY].value != NULL) {
@ -85,10 +218,15 @@ static void init_call_elem(grpc_call_element *elem,
initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx;
initial_op->context[GRPC_CONTEXT_SECURITY].destroy =
grpc_server_security_context_destroy;
calld->call_auth_context = &server_ctx->auth_context;
/* Set the metadata callbacks. */
set_recv_ops_md_callbacks(elem, initial_op);
}
/* Destructor for call_data */
static void destroy_call_elem(grpc_call_element *elem) {}
static void destroy_call_elem(grpc_call_element *elem) {
}
/* Constructor for channel_data */
static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
@ -109,6 +247,7 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
GPR_ASSERT(!sc->is_client_side);
chand->security_connector =
GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter");
chand->mdctx = mdctx;
}
/* Destructor for channel data */

@ -100,8 +100,8 @@ static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack(
grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
grpc_credentials *ssl_creds =
grpc_ssl_credentials_create(test_root_cert, NULL);
grpc_credentials *oauth2_creds =
grpc_fake_oauth2_credentials_create("Bearer aaslkfjs424535asdf", 1);
grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
"Authorization", "Bearer aaslkfjs424535asdf", 1);
grpc_credentials *ssl_oauth2_creds =
grpc_composite_credentials_create(ssl_creds, oauth2_creds);
grpc_arg ssl_name_override = {GRPC_ARG_STRING,

@ -46,6 +46,11 @@
#include "src/core/security/credentials.h"
#include "src/core/support/string.h"
static const char *custom_creds_md_name = "custom_creds";
static const char *custom_creds_md_value = "custom_value";
static const char *client_identity_property_name = "smurf_name";
static const char *client_identity = "Brainy Smurf";
static const char iam_token[] = "token";
static const char iam_selector[] = "selector";
static const char overridden_iam_token[] = "overridden_token";
@ -57,15 +62,77 @@ enum { TIMEOUT = 200000 };
static void *tag(gpr_intptr t) { return (void *)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char *test_name,
grpc_channel_args *client_args,
grpc_channel_args *server_args) {
static const grpc_metadata *find_metadata(const grpc_metadata *md,
size_t md_count,
const char *key,
const char *value) {
size_t i;
for (i = 0; i < md_count; i++) {
if (strcmp(key, md[i].key) == 0 && strlen(value) == md[i].value_length &&
memcmp(md[i].value, value, md[i].value_length) == 0) {
return &md[i];
}
}
return NULL;
}
static void check_peer_identity(grpc_auth_context *ctx,
const char *expected_identity) {
grpc_auth_property_iterator it = grpc_auth_context_peer_identity(ctx);
const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it);
GPR_ASSERT(prop != NULL);
GPR_ASSERT(strcmp(expected_identity, prop->value) == 0);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
}
static void process_auth_md_success(void *state, grpc_auth_ticket *t,
grpc_auth_context *channel_ctx,
const grpc_metadata *md, size_t md_count,
grpc_process_auth_metadata_done_cb cb,
void *user_data) {
override_mode *mode;
GPR_ASSERT(state != NULL);
mode = (override_mode *)state;
if (*mode != DESTROY) {
grpc_auth_context *new_auth_ctx = grpc_auth_context_create(channel_ctx);
const grpc_metadata *custom_creds_md = find_metadata(
md, md_count, custom_creds_md_name, custom_creds_md_value);
GPR_ASSERT(custom_creds_md != NULL);
grpc_auth_context_add_cstring_property(
new_auth_ctx, client_identity_property_name, client_identity);
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
new_auth_ctx, client_identity_property_name) == 1);
cb(user_data, custom_creds_md, 1, 1, new_auth_ctx);
grpc_auth_context_release(new_auth_ctx);
} else {
cb(user_data, NULL, 0, 1, channel_ctx);
}
}
static void process_auth_md_failure(void *state, grpc_auth_ticket *t,
grpc_auth_context *channel_ctx,
const grpc_metadata *md, size_t md_count,
grpc_process_auth_metadata_done_cb cb,
void *user_data) {
override_mode *mode;
GPR_ASSERT(state != NULL);
mode = (override_mode *)state;
if (*mode != DESTROY) {
const grpc_metadata *custom_creds_md = find_metadata(
md, md_count, custom_creds_md_name, custom_creds_md_value);
GPR_ASSERT(custom_creds_md != NULL);
}
cb(user_data, NULL, 0, 0, NULL); /* Fail. */
}
static grpc_end2end_test_fixture begin_test(
grpc_end2end_test_config config, const char *test_name,
grpc_auth_metadata_processor processor) {
grpc_end2end_test_fixture f;
grpc_server_register_auth_metadata_processor(processor);
gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(client_args, server_args);
config.init_client(&f, client_args);
config.init_server(&f, server_args);
f = config.create_fixture(NULL, NULL);
config.init_client(&f, NULL);
config.init_server(&f, NULL);
return f;
}
@ -124,11 +191,24 @@ static void print_auth_context(int is_client, const grpc_auth_context *ctx) {
}
}
static grpc_credentials *iam_custom_composite_creds_create(
const char *iam_tok, const char *iam_sel) {
grpc_credentials *iam_creds = grpc_iam_credentials_create(iam_tok, iam_sel);
grpc_credentials *custom_creds = grpc_md_only_test_credentials_create(
custom_creds_md_name, custom_creds_md_value, 1);
grpc_credentials *result =
grpc_composite_credentials_create(iam_creds, custom_creds);
grpc_credentials_release(iam_creds);
grpc_credentials_release(custom_creds);
return result;
}
static void test_call_creds_failure(grpc_end2end_test_config config) {
grpc_call *c;
grpc_credentials *creds = NULL;
grpc_auth_metadata_processor p = {NULL, NULL};
grpc_end2end_test_fixture f =
begin_test(config, "test_call_creds_failure", NULL, NULL);
begin_test(config, "test_call_creds_failure", p);
gpr_timespec deadline = five_seconds_time();
c = grpc_channel_create_call(f.client, f.cq, "/foo", "foo.test.google.fr",
deadline);
@ -157,9 +237,9 @@ static void request_response_with_payload_and_call_creds(
grpc_byte_buffer *response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_timespec deadline = five_seconds_time();
grpc_end2end_test_fixture f = begin_test(config, test_name, NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_auth_metadata_processor p;
grpc_end2end_test_fixture f;
cq_verifier *cqv;
grpc_op ops[6];
grpc_op *op;
grpc_metadata_array initial_metadata_recv;
@ -174,11 +254,17 @@ static void request_response_with_payload_and_call_creds(
int was_cancelled = 2;
grpc_credentials *creds = NULL;
grpc_auth_context *s_auth_context = NULL;
grpc_auth_context *c_auth_context = NULL;
p.process = process_auth_md_success;
p.state = &mode;
f = begin_test(config, test_name, p);
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(f.client, f.cq, "/foo", "foo.test.google.fr",
deadline);
GPR_ASSERT(c);
creds = grpc_iam_credentials_create(iam_token, iam_selector);
creds = iam_custom_composite_creds_create(iam_token, iam_selector);
GPR_ASSERT(creds != NULL);
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
switch (mode) {
@ -186,7 +272,7 @@ static void request_response_with_payload_and_call_creds(
break;
case OVERRIDE:
grpc_credentials_release(creds);
creds = grpc_iam_credentials_create(overridden_iam_token,
creds = iam_custom_composite_creds_create(overridden_iam_token,
overridden_iam_selector);
GPR_ASSERT(creds != NULL);
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
@ -241,6 +327,11 @@ static void request_response_with_payload_and_call_creds(
print_auth_context(0, s_auth_context);
grpc_auth_context_release(s_auth_context);
c_auth_context = grpc_call_auth_context(c);
GPR_ASSERT(c_auth_context != NULL);
print_auth_context(1, c_auth_context);
grpc_auth_context_release(c_auth_context);
/* Cannot set creds on the server call object. */
GPR_ASSERT(grpc_call_set_credentials(s, NULL) != GRPC_CALL_OK);
@ -287,6 +378,10 @@ static void request_response_with_payload_and_call_creds(
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
/* Has been processed by the auth metadata processor. */
GPR_ASSERT(!contains_metadata(&request_metadata_recv, custom_creds_md_name,
custom_creds_md_value));
switch (mode) {
case NONE:
GPR_ASSERT(contains_metadata(&request_metadata_recv,
@ -295,6 +390,7 @@ static void request_response_with_payload_and_call_creds(
GPR_ASSERT(contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
iam_selector));
check_peer_identity(s_auth_context, client_identity);
break;
case OVERRIDE:
GPR_ASSERT(contains_metadata(&request_metadata_recv,
@ -303,6 +399,7 @@ static void request_response_with_payload_and_call_creds(
GPR_ASSERT(contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
overridden_iam_selector));
check_peer_identity(s_auth_context, client_identity);
break;
case DESTROY:
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
@ -340,31 +437,128 @@ static void request_response_with_payload_and_call_creds(
config.tear_down_data(&f);
}
void test_request_response_with_payload_and_call_creds(
static void test_request_response_with_payload_and_call_creds(
grpc_end2end_test_config config) {
request_response_with_payload_and_call_creds(
"test_request_response_with_payload_and_call_creds", config, NONE);
}
void test_request_response_with_payload_and_overridden_call_creds(
static void test_request_response_with_payload_and_overridden_call_creds(
grpc_end2end_test_config config) {
request_response_with_payload_and_call_creds(
"test_request_response_with_payload_and_overridden_call_creds", config,
OVERRIDE);
}
void test_request_response_with_payload_and_deleted_call_creds(
static void test_request_response_with_payload_and_deleted_call_creds(
grpc_end2end_test_config config) {
request_response_with_payload_and_call_creds(
"test_request_response_with_payload_and_deleted_call_creds", config,
DESTROY);
}
static void test_request_with_server_rejecting_client_creds(
grpc_end2end_test_config config) {
grpc_op ops[6];
grpc_op *op;
grpc_call *c;
grpc_auth_metadata_processor p;
grpc_end2end_test_fixture f;
gpr_timespec deadline = five_seconds_time();
cq_verifier *cqv;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
char *details = NULL;
size_t details_capacity = 0;
grpc_byte_buffer *response_payload_recv = NULL;
gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
grpc_byte_buffer *request_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
override_mode mode = NONE;
grpc_credentials *creds;
p.process = process_auth_md_failure;
p.state = &mode;
f = begin_test(config, "test_request_with_server_rejecting_client_creds", p);
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(f.client, f.cq, "/foo", "foo.test.google.fr",
deadline);
GPR_ASSERT(c);
creds = iam_custom_composite_creds_create(iam_token, iam_selector);
GPR_ASSERT(creds != NULL);
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
grpc_credentials_release(creds);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->data.recv_status_on_client.status_details_capacity = &details_capacity;
op->flags = 0;
op++;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = request_payload;
op->flags = 0;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op->flags = 0;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = &initial_metadata_recv;
op->flags = 0;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &response_payload_recv;
op->flags = 0;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
cq_expect_completion(cqv, tag(1), 1);
cq_verify(cqv);
/* XXX Should be GRPC_STATUS_UNAUTHENTICATED but it looks like there is a bug
(probably in the server_auth_context.c code) where this error on the server
does not get to the client. The current error code we are getting is
GRPC_STATUS_INTERNAL. */
GPR_ASSERT(status != GRPC_STATUS_OK);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload_recv);
gpr_free(details);
grpc_call_destroy(c);
cq_verifier_destroy(cqv);
end_test(&f);
config.tear_down_data(&f);
}
void grpc_end2end_tests(grpc_end2end_test_config config) {
if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS) {
test_call_creds_failure(config);
test_request_response_with_payload_and_call_creds(config);
test_request_response_with_payload_and_overridden_call_creds(config);
test_request_response_with_payload_and_deleted_call_creds(config);
test_request_with_server_rejecting_client_creds(config);
}
}

@ -40,7 +40,7 @@
#include <grpc/support/log.h>
static void test_empty_context(void) {
grpc_auth_context *ctx = grpc_auth_context_create(NULL, 0);
grpc_auth_context *ctx = grpc_auth_context_create(NULL);
grpc_auth_property_iterator it;
gpr_log(GPR_INFO, "test_empty_context");
@ -52,87 +52,98 @@ static void test_empty_context(void) {
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
it = grpc_auth_context_find_properties_by_name(ctx, "foo");
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "bar") ==
0);
GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == NULL);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
static void test_simple_context(void) {
grpc_auth_context *ctx = grpc_auth_context_create(NULL, 3);
grpc_auth_context *ctx = grpc_auth_context_create(NULL);
grpc_auth_property_iterator it;
size_t i;
gpr_log(GPR_INFO, "test_simple_context");
GPR_ASSERT(ctx != NULL);
GPR_ASSERT(ctx->property_count == 3);
ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
ctx->peer_identity_property_name = ctx->properties[0].name;
grpc_auth_context_add_cstring_property(ctx, "name", "chapi");
grpc_auth_context_add_cstring_property(ctx, "name", "chapo");
grpc_auth_context_add_cstring_property(ctx, "foo", "bar");
GPR_ASSERT(ctx->properties.count == 3);
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") ==
1);
GPR_ASSERT(
strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0);
it = grpc_auth_context_property_iterator(ctx);
for (i = 0; i < ctx->property_count; i++) {
for (i = 0; i < ctx->properties.count; i++) {
const grpc_auth_property *p = grpc_auth_property_iterator_next(&it);
GPR_ASSERT(p == &ctx->properties[i]);
GPR_ASSERT(p == &ctx->properties.array[i]);
}
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
it = grpc_auth_context_find_properties_by_name(ctx, "foo");
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[2]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
&ctx->properties.array[2]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
it = grpc_auth_context_peer_identity(ctx);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
&ctx->properties.array[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
&ctx->properties.array[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
static void test_chained_context(void) {
grpc_auth_context *chained = grpc_auth_context_create(NULL, 2);
grpc_auth_context *ctx = grpc_auth_context_create(chained, 3);
grpc_auth_context *chained = grpc_auth_context_create(NULL);
grpc_auth_context *ctx = grpc_auth_context_create(chained);
grpc_auth_property_iterator it;
size_t i;
gpr_log(GPR_INFO, "test_chained_context");
GRPC_AUTH_CONTEXT_UNREF(chained, "chained");
chained->properties[0] =
grpc_auth_property_init_from_cstring("name", "padapo");
chained->properties[1] = grpc_auth_property_init_from_cstring("foo", "baz");
ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
ctx->peer_identity_property_name = ctx->properties[0].name;
grpc_auth_context_add_cstring_property(chained, "name", "padapo");
grpc_auth_context_add_cstring_property(chained, "foo", "baz");
grpc_auth_context_add_cstring_property(ctx, "name", "chapi");
grpc_auth_context_add_cstring_property(ctx, "name", "chap0");
grpc_auth_context_add_cstring_property(ctx, "foo", "bar");
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") ==
1);
GPR_ASSERT(
strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0);
it = grpc_auth_context_property_iterator(ctx);
for (i = 0; i < ctx->property_count; i++) {
for (i = 0; i < ctx->properties.count; i++) {
const grpc_auth_property *p = grpc_auth_property_iterator_next(&it);
GPR_ASSERT(p == &ctx->properties[i]);
GPR_ASSERT(p == &ctx->properties.array[i]);
}
for (i = 0; i < chained->property_count; i++) {
for (i = 0; i < chained->properties.count; i++) {
const grpc_auth_property *p = grpc_auth_property_iterator_next(&it);
GPR_ASSERT(p == &chained->properties[i]);
GPR_ASSERT(p == &chained->properties.array[i]);
}
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
it = grpc_auth_context_find_properties_by_name(ctx, "foo");
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[2]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &chained->properties[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
&ctx->properties.array[2]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
&chained->properties.array[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
it = grpc_auth_context_peer_identity(ctx);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &chained->properties[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
&ctx->properties.array[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
&ctx->properties.array[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
&chained->properties.array[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_empty_context();

@ -373,8 +373,8 @@ static void test_ssl_oauth2_composite_creds(void) {
grpc_credentials *ssl_creds =
grpc_ssl_credentials_create(test_root_cert, NULL);
const grpc_credentials_array *creds_array;
grpc_credentials *oauth2_creds =
grpc_fake_oauth2_credentials_create(test_oauth2_bearer_token, 0);
grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
"Authorization", test_oauth2_bearer_token, 0);
grpc_credentials *composite_creds =
grpc_composite_credentials_create(ssl_creds, oauth2_creds);
grpc_credentials_unref(ssl_creds);
@ -424,8 +424,8 @@ static void test_ssl_oauth2_iam_composite_creds(void) {
grpc_credentials *ssl_creds =
grpc_ssl_credentials_create(test_root_cert, NULL);
const grpc_credentials_array *creds_array;
grpc_credentials *oauth2_creds =
grpc_fake_oauth2_credentials_create(test_oauth2_bearer_token, 0);
grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
"Authorization", test_oauth2_bearer_token, 0);
grpc_credentials *aux_creds =
grpc_composite_credentials_create(ssl_creds, oauth2_creds);
grpc_credentials *iam_creds = grpc_iam_credentials_create(

@ -31,10 +31,10 @@
*
*/
#include <grpc/grpc_security.h>
#include <grpc++/auth_context.h>
#include <gtest/gtest.h>
#include "src/cpp/common/secure_auth_context.h"
#include "src/core/security/security_context.h"
namespace grpc {
namespace {
@ -50,14 +50,15 @@ class TestAuthPropertyIterator : public AuthPropertyIterator {
class AuthPropertyIteratorTest : public ::testing::Test {
protected:
void SetUp() GRPC_OVERRIDE {
ctx_ = grpc_auth_context_create(NULL, 3);
ctx_->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
ctx_->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
ctx_->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
ctx_->peer_identity_property_name = ctx_->properties[0].name;
ctx_ = grpc_auth_context_create(NULL);
grpc_auth_context_add_cstring_property(ctx_, "name", "chapi");
grpc_auth_context_add_cstring_property(ctx_, "name", "chapo");
grpc_auth_context_add_cstring_property(ctx_, "foo", "bar");
EXPECT_EQ(1,
grpc_auth_context_set_peer_identity_property_name(ctx_, "name"));
}
void TearDown() GRPC_OVERRIDE {
GRPC_AUTH_CONTEXT_UNREF(ctx_, "AuthPropertyIteratorTest");
grpc_auth_context_release(ctx_);
}
grpc_auth_context* ctx_;

@ -31,10 +31,10 @@
*
*/
#include <grpc/grpc_security.h>
#include <grpc++/auth_context.h>
#include <gtest/gtest.h>
#include "src/cpp/common/secure_auth_context.h"
#include "src/core/security/security_context.h"
namespace grpc {
namespace {
@ -52,11 +52,11 @@ TEST_F(SecureAuthContextTest, EmptyContext) {
}
TEST_F(SecureAuthContextTest, Properties) {
grpc_auth_context* ctx = grpc_auth_context_create(NULL, 3);
ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
ctx->peer_identity_property_name = ctx->properties[0].name;
grpc_auth_context* ctx = grpc_auth_context_create(NULL);
grpc_auth_context_add_cstring_property(ctx, "name", "chapi");
grpc_auth_context_add_cstring_property(ctx, "name", "chapo");
grpc_auth_context_add_cstring_property(ctx, "foo", "bar");
EXPECT_EQ(1, grpc_auth_context_set_peer_identity_property_name(ctx, "name"));
SecureAuthContext context(ctx);
std::vector<grpc::string> peer_identity = context.GetPeerIdentity();
@ -70,11 +70,11 @@ TEST_F(SecureAuthContextTest, Properties) {
}
TEST_F(SecureAuthContextTest, Iterators) {
grpc_auth_context* ctx = grpc_auth_context_create(NULL, 3);
ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
ctx->peer_identity_property_name = ctx->properties[0].name;
grpc_auth_context* ctx = grpc_auth_context_create(NULL);
grpc_auth_context_add_cstring_property(ctx, "name", "chapi");
grpc_auth_context_add_cstring_property(ctx, "name", "chapo");
grpc_auth_context_add_cstring_property(ctx, "foo", "bar");
EXPECT_EQ(1, grpc_auth_context_set_peer_identity_property_name(ctx, "name"));
SecureAuthContext context(ctx);
AuthPropertyIterator iter = context.begin();

Loading…
Cancel
Save