grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) { size_t i; grpc_auth_context *ctx = 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, 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; } ctx->properties[ctx->property_count++] = grpc_auth_property_init( 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); } } return ctx; }
static void fake_check_peer(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, tsi_peer peer, grpc_security_peer_check_cb cb, void *user_data) { const char *prop_name; grpc_security_status status = GRPC_SECURITY_OK; grpc_auth_context *auth_context = NULL; if (peer.property_count != 1) { gpr_log(GPR_ERROR, "Fake peers should only have 1 property."); status = GRPC_SECURITY_ERROR; goto end; } prop_name = peer.properties[0].name; if (prop_name == NULL || strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) { gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.", prop_name == NULL ? "<EMPTY>" : prop_name); status = GRPC_SECURITY_ERROR; goto end; } if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE, peer.properties[0].value.length)) { gpr_log(GPR_ERROR, "Invalid value for cert type property."); status = GRPC_SECURITY_ERROR; goto end; } auth_context = grpc_auth_context_create(NULL); grpc_auth_context_add_cstring_property( auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, GRPC_FAKE_TRANSPORT_SECURITY_TYPE); end: cb(exec_ctx, user_data, status, auth_context); grpc_auth_context_unref(auth_context); tsi_peer_destruct(&peer); }
static grpc_security_status fake_check_peer(grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb, void *user_data) { const char *prop_name; grpc_security_status status = GRPC_SECURITY_OK; if (peer.property_count != 1) { gpr_log(GPR_ERROR, "Fake peers should only have 1 property."); status = GRPC_SECURITY_ERROR; goto end; } prop_name = peer.properties[0].name; if (prop_name == NULL || strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) { gpr_log(GPR_ERROR, "Unexpected property in fake peer: %s.", prop_name == NULL ? "<EMPTY>" : prop_name); status = GRPC_SECURITY_ERROR; goto end; } if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE, peer.properties[0].value.length)) { gpr_log(GPR_ERROR, "Invalid value for cert type property."); status = GRPC_SECURITY_ERROR; 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, GRPC_FAKE_TRANSPORT_SECURITY_TYPE); end: tsi_peer_destruct(&peer); return status; }
/* Constructor for call_data */ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const void *server_transport_data, grpc_transport_stream_op *initial_op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_server_security_context *server_ctx = NULL; /* initialize members */ memset(calld, 0, sizeof(*calld)); grpc_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); /* Create a security context for the call and reference the auth context from the channel. */ if (initial_op->context[GRPC_CONTEXT_SECURITY].value != NULL) { initial_op->context[GRPC_CONTEXT_SECURITY].destroy( initial_op->context[GRPC_CONTEXT_SECURITY].value); } server_ctx = grpc_server_security_context_create(); server_ctx->auth_context = grpc_auth_context_create(chand->security_connector->auth_context); server_ctx->auth_context->pollset = initial_op->bind_pollset; initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx; initial_op->context[GRPC_CONTEXT_SECURITY].destroy = grpc_server_security_context_destroy; calld->auth_context = server_ctx->auth_context; /* Set the metadata callbacks. */ set_recv_ops_md_callbacks(elem, initial_op); }
static void test_chained_context(void) { 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"); 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->properties.count; i++) { const grpc_auth_property *p = grpc_auth_property_iterator_next(&it); GPR_ASSERT(p == &ctx->properties.array[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.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.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.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"); }
static void test_empty_context(void) { grpc_auth_context *ctx = grpc_auth_context_create(NULL); grpc_auth_property_iterator it; gpr_log(GPR_INFO, "test_empty_context"); GPR_ASSERT(ctx != NULL); GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == NULL); it = grpc_auth_context_peer_identity(ctx); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); it = grpc_auth_context_property_iterator(ctx); 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 grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer) { /* We bet that iterating over a handful of properties twice will be faster than having to realloc on average . */ size_t auth_prop_count = 1; /* for transport_security_type. */ size_t i; const char *peer_identity_property_name = NULL; grpc_auth_context *ctx = NULL; 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) { auth_prop_count++; /* If there is no subject alt name, have the CN as the identity. */ if (peer_identity_property_name == NULL) { peer_identity_property_name = prop->name; } } else if (strcmp(prop->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { auth_prop_count++; peer_identity_property_name = prop->name; } } ctx = grpc_auth_context_create(NULL, auth_prop_count); ctx->properties[0] = grpc_auth_property_init_from_cstring( 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) { ctx->properties[ctx->property_count++] = grpc_auth_property_init( 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->properties[ctx->property_count++] = grpc_auth_property_init( GRPC_X509_SAN_PROPERTY_NAME, prop->value.data, prop->value.length); } } GPR_ASSERT(auth_prop_count == ctx->property_count); return ctx; }
/* Constructor for call_data */ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_call_element_args *args) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_server_security_context *server_ctx = NULL; /* initialize members */ memset(calld, 0, sizeof(*calld)); grpc_closure_init(&calld->auth_on_recv, auth_on_recv, elem); if (args->context[GRPC_CONTEXT_SECURITY].value != NULL) { args->context[GRPC_CONTEXT_SECURITY].destroy( args->context[GRPC_CONTEXT_SECURITY].value); } server_ctx = grpc_server_security_context_create(); server_ctx->auth_context = grpc_auth_context_create(chand->auth_context); calld->auth_context = server_ctx->auth_context; args->context[GRPC_CONTEXT_SECURITY].value = server_ctx; args->context[GRPC_CONTEXT_SECURITY].destroy = grpc_server_security_context_destroy; }