diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index a6760a1400e2da2dbea9bf48ca0582b2893ba4f5..d7ed2d8ce0c7feb4d47b5de17667cfe19e54ee25 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -204,7 +204,12 @@ grpc_call_error grpc_call_set_credentials(grpc_call *call, #define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name" typedef struct grpc_auth_context grpc_auth_context; -typedef struct grpc_auth_property_iterator grpc_auth_property_iterator; + +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 { @@ -216,20 +221,19 @@ typedef struct 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); -void grpc_auth_property_iterator_destroy(grpc_auth_property_iterator *it); -grpc_auth_property_iterator *grpc_auth_context_property_iterator( +/* Iterates over the auth context. */ +grpc_auth_property_iterator grpc_auth_context_property_iterator( const grpc_auth_context *ctx); -/* Gets the peer identity. Returns NULL if the peer is not authenticated. - An identity may consist of multiple values (e.g. Subject Alternative Names - in X509 SSL certificates). */ -grpc_auth_property_iterator *grpc_auth_context_peer_identity( +/* 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 if no property - with this name was found in the context. Will return NULL on NULL input. */ -grpc_auth_property_iterator *grpc_auth_context_find_properties_by_name( +/* 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 @@ -237,6 +241,9 @@ grpc_auth_property_iterator *grpc_auth_context_find_properties_by_name( 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. */ const grpc_auth_context *grpc_call_auth_context(grpc_call *call); diff --git a/src/core/channel/context.h b/src/core/channel/context.h index 85de60d81ae01c09e3ae6e2c9faeca0cb57d529a..ac5796b9ef19fce5968790a791d56c0e86708dc3 100644 --- a/src/core/channel/context.h +++ b/src/core/channel/context.h @@ -44,6 +44,6 @@ typedef enum { typedef struct { void *value; void (*destroy)(void *); -} grpc_call_context; +} grpc_call_context_element; #endif /* GRPC_INTERNAL_CORE_CHANNEL_CONTEXT_H */ diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index 9e1198919bf9e05c71afa64032e4604298b92d81..72002ee5c203413e0368f2d3e165b1a327f2b285 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -125,7 +125,7 @@ static void send_security_metadata(grpc_call_element *elem, call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_client_security_context *ctx = - (grpc_client_security_context *)op->contexts[GRPC_CONTEXT_SECURITY].value; + (grpc_client_security_context *)op->context[GRPC_CONTEXT_SECURITY].value; char *service_url = NULL; grpc_credentials *channel_creds = chand->security_connector->request_metadata_creds; diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index c9fcff661f5e118ca794d4f81d3b63d6b0bc3f7d..14c194c8f6f645578f29c06362a168ff2e0307f1 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -109,6 +109,8 @@ void grpc_server_security_context_destroy(void *ctx) { /* --- grpc_auth_context --- */ +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 *ctx = gpr_malloc(sizeof(grpc_auth_context)); @@ -138,6 +140,7 @@ void grpc_auth_context_unref(grpc_auth_context *ctx) { } gpr_free(ctx->properties); } + gpr_free(ctx); } } @@ -146,19 +149,22 @@ const char *grpc_auth_context_peer_identity_property_name( return ctx->peer_identity_property_name; } -grpc_auth_property_iterator *grpc_auth_context_property_iterator( +int grpc_auth_context_peer_is_authenticated( const grpc_auth_context *ctx) { - grpc_auth_property_iterator *it; - if (ctx == NULL) return NULL; - it = gpr_malloc(sizeof(grpc_auth_property_iterator)); - memset(it, 0, sizeof(grpc_auth_property_iterator)); - it->ctx = ctx; + return ctx->peer_identity_property_name == NULL ? 0 : 1; +} + +grpc_auth_property_iterator grpc_auth_context_property_iterator( + const grpc_auth_context *ctx) { + grpc_auth_property_iterator it = empty_iterator; + if (ctx == NULL) return it; + it.ctx = ctx; return it; } const grpc_auth_property *grpc_auth_property_iterator_next( grpc_auth_property_iterator *it) { - if (it == NULL) return NULL; + if (it == NULL || it->ctx == NULL) return NULL; while (it->index == it->ctx->property_count) { if (it->ctx->chained == NULL) return NULL; it->ctx = it->ctx->chained; @@ -179,28 +185,22 @@ const grpc_auth_property *grpc_auth_property_iterator_next( } } -grpc_auth_property_iterator *grpc_auth_context_find_properties_by_name( +grpc_auth_property_iterator grpc_auth_context_find_properties_by_name( const grpc_auth_context *ctx, const char *name) { - grpc_auth_property_iterator *it; - if (ctx == NULL || name == NULL) return NULL; - it = grpc_auth_context_property_iterator(ctx); - it->name = gpr_strdup(name); + grpc_auth_property_iterator it = empty_iterator; + if (ctx == NULL || name == NULL) return empty_iterator; + it.ctx = ctx; + it.name = name; return it; } -grpc_auth_property_iterator *grpc_auth_context_peer_identity( +grpc_auth_property_iterator grpc_auth_context_peer_identity( const grpc_auth_context *ctx) { - if (ctx == NULL || ctx->peer_identity_property_name == NULL) return NULL; + if (ctx == NULL) return empty_iterator; return grpc_auth_context_find_properties_by_name( ctx, ctx->peer_identity_property_name); } -void grpc_auth_property_iterator_destroy(grpc_auth_property_iterator *it) { - if (it == NULL) return; - if (it->name != NULL) gpr_free(it->name); - gpr_free(it); -} - grpc_auth_property grpc_auth_property_init_from_cstring(const char *name, const char *value) { grpc_auth_property prop; diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h index 60a31777736a06822f84299a988d21fe946a2032..d8909cd6f1e29c664a70932a3f923cb7e15fc1fb 100644 --- a/src/core/security/security_context.h +++ b/src/core/security/security_context.h @@ -42,12 +42,6 @@ /* Property names are always NULL terminated. */ -struct grpc_auth_property_iterator { - const grpc_auth_context *ctx; - size_t index; - char *name; -}; - struct grpc_auth_context { struct grpc_auth_context *chained; grpc_auth_property *properties; diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index 03372328edb62367db8bc3c03c21516465f96ee4..1823f758081544a4e8f9590183f0c3dc321b5277 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -77,17 +77,17 @@ static void init_call_elem(grpc_call_element *elem, /* initialize members */ calld->unused = 0; - GPR_ASSERT(initial_op && initial_op->contexts != NULL && + GPR_ASSERT(initial_op && initial_op->context != NULL && chand->security_connector->auth_context != NULL && - initial_op->contexts[GRPC_CONTEXT_SECURITY].value == NULL); + initial_op->context[GRPC_CONTEXT_SECURITY].value == NULL); /* Create a security context for the call and reference the auth context from the channel. */ server_ctx = grpc_server_security_context_create(); server_ctx->auth_context = grpc_auth_context_ref(chand->security_connector->auth_context); - initial_op->contexts[GRPC_CONTEXT_SECURITY].value = server_ctx; - initial_op->contexts[GRPC_CONTEXT_SECURITY].destroy = + initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx; + initial_op->context[GRPC_CONTEXT_SECURITY].destroy = grpc_server_security_context_destroy; } diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 0169ce3158823f5b48e28508f175daf05aada98f..db76c3a3b3c71fe10209e1587f05286063c109e2 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -206,7 +206,7 @@ struct grpc_call { received_status status[STATUS_SOURCE_COUNT]; /* Contexts for various subsystems (security, tracing, ...). */ - grpc_call_context contexts[GRPC_CONTEXT_COUNT]; + grpc_call_context_element context[GRPC_CONTEXT_COUNT]; /* Deadline alarm - if have_alarm is non-zero */ grpc_alarm alarm; @@ -290,7 +290,7 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq, initial_op.recv_state = &call->recv_state; initial_op.on_done_recv = call_on_done_recv; initial_op.recv_user_data = call; - initial_op.contexts = call->contexts; + initial_op.context = call->context; call->receiving = 1; GRPC_CALL_INTERNAL_REF(call, "receiving"); initial_op_ptr = &initial_op; @@ -344,8 +344,8 @@ static void destroy_call(void *call, int ignored_success) { grpc_mdelem_unref(c->send_initial_metadata[i].md); } for (i = 0; i < GRPC_CONTEXT_COUNT; i++) { - if (c->contexts[i].destroy) { - c->contexts[i].destroy(c->contexts[i].value); + if (c->context[i].destroy) { + c->context[i].destroy(c->context[i].value); } } grpc_sopb_destroy(&c->send_ops); @@ -1048,7 +1048,7 @@ static grpc_call_error cancel_with_status( static void execute_op(grpc_call *call, grpc_transport_op *op) { grpc_call_element *elem; elem = CALL_ELEM_FROM_CALL(call, 0); - op->contexts = call->contexts; + op->context = call->context; elem->filter->start_transport_op(elem, op); } @@ -1289,15 +1289,15 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops, void grpc_call_context_set(grpc_call *call, grpc_context_index elem, void *value, void (*destroy)(void *value)) { - if (call->contexts[elem].destroy) { - call->contexts[elem].destroy(call->contexts[elem].value); + if (call->context[elem].destroy) { + call->context[elem].destroy(call->context[elem].value); } - call->contexts[elem].value = value; - call->contexts[elem].destroy = destroy; + call->context[elem].value = value; + call->context[elem].destroy = destroy; } void *grpc_call_context_get(grpc_call *call, grpc_context_index elem) { - return call->contexts[elem].value; + return call->context[elem].value; } gpr_uint8 grpc_call_is_client(grpc_call *call) { return call->is_client; } diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h index dd6bee8ce955c0a622d4fa26a00ebce809526763..6f8d39e352f040fff7b5adc413ba6d779d2e528b 100644 --- a/src/core/transport/transport.h +++ b/src/core/transport/transport.h @@ -79,7 +79,7 @@ typedef struct grpc_transport_op { grpc_mdstr *cancel_message; /* Indexes correspond to grpc_context_index enum values */ - grpc_call_context *contexts; + grpc_call_context_element *context; } grpc_transport_op; /* Callbacks made from the transport to the upper layers of grpc. */ diff --git a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c index 8e1fb63d744457648d05362b7d07fd6072818ec4..6eae92f28cd9b11a929efd4a7e8e67a7300545c4 100644 --- a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c +++ b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c @@ -113,23 +113,19 @@ static void end_test(grpc_end2end_test_fixture *f) { static void print_auth_context(int is_client, const grpc_auth_context *ctx) { const grpc_auth_property *p; - grpc_auth_property_iterator *it; + grpc_auth_property_iterator it; gpr_log(GPR_INFO, "%s peer:", is_client ? "client" : "server"); + gpr_log(GPR_INFO, "\tauthenticated: %s", + grpc_auth_context_peer_is_authenticated(ctx) ? "YES" : "NO"); it = grpc_auth_context_peer_identity(ctx); - gpr_log(GPR_INFO, "\tauthenticated: %s", it != NULL ? "YES" : "NO"); - if (it != NULL) { - while ((p = grpc_auth_property_iterator_next(it)) != NULL) { - gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); - } - grpc_auth_property_iterator_destroy(it); + while ((p = grpc_auth_property_iterator_next(&it)) != NULL) { + gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); } gpr_log(GPR_INFO, "\tall properties:"); it = grpc_auth_context_property_iterator(ctx); - GPR_ASSERT(it != NULL); - while ((p = grpc_auth_property_iterator_next(it)) != NULL) { + while ((p = grpc_auth_property_iterator_next(&it)) != NULL) { gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); } - grpc_auth_property_iterator_destroy(it); } static void test_call_creds_failure(grpc_end2end_test_config config) { diff --git a/test/core/security/auth_context_test.c b/test/core/security/auth_context_test.c index 88f7522fce30fb082cc4d1b0d115d93b5876294f..54548bf1fc1c3a346db6d2e60feb684aebb34d9f 100644 --- a/test/core/security/auth_context_test.c +++ b/test/core/security/auth_context_test.c @@ -41,26 +41,23 @@ static void test_empty_context(void) { grpc_auth_context *ctx = grpc_auth_context_create(NULL, 0); - grpc_auth_property_iterator *it; + grpc_auth_property_iterator it; gpr_log(GPR_INFO, __FUNCTION__); GPR_ASSERT(ctx != NULL); GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == NULL); - GPR_ASSERT(grpc_auth_context_peer_identity(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(it != NULL); - GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL); - grpc_auth_property_iterator_destroy(it); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); it = grpc_auth_context_find_properties_by_name(ctx, "foo"); - GPR_ASSERT(it != NULL); - GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL); - grpc_auth_property_iterator_destroy(it); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); grpc_auth_context_unref(ctx); } static void test_simple_context(void) { grpc_auth_context *ctx = grpc_auth_context_create(NULL, 3); - grpc_auth_property_iterator *it; + grpc_auth_property_iterator it; size_t i; gpr_log(GPR_INFO, __FUNCTION__); @@ -75,24 +72,19 @@ static void test_simple_context(void) { 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++) { - const grpc_auth_property *p = grpc_auth_property_iterator_next(it); + const grpc_auth_property *p = grpc_auth_property_iterator_next(&it); GPR_ASSERT(p == &ctx->properties[i]); } - GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL); - grpc_auth_property_iterator_destroy(it); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); it = grpc_auth_context_find_properties_by_name(ctx, "foo"); - GPR_ASSERT(it != NULL); - GPR_ASSERT(grpc_auth_property_iterator_next(it) == &ctx->properties[2]); - GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL); - grpc_auth_property_iterator_destroy(it); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[2]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); it = grpc_auth_context_peer_identity(ctx); - GPR_ASSERT(it != NULL); - 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) == NULL); - grpc_auth_property_iterator_destroy(it); + 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) == NULL); grpc_auth_context_unref(ctx); } @@ -100,7 +92,7 @@ static void test_simple_context(void) { 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_property_iterator *it; + grpc_auth_property_iterator it; size_t i; gpr_log(GPR_INFO, __FUNCTION__); @@ -117,30 +109,25 @@ static void test_chained_context(void) { 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++) { - const grpc_auth_property *p = grpc_auth_property_iterator_next(it); + const grpc_auth_property *p = grpc_auth_property_iterator_next(&it); GPR_ASSERT(p == &ctx->properties[i]); } for (i = 0; i < chained->property_count; i++) { - const grpc_auth_property *p = grpc_auth_property_iterator_next(it); + const grpc_auth_property *p = grpc_auth_property_iterator_next(&it); GPR_ASSERT(p == &chained->properties[i]); } - GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL); - grpc_auth_property_iterator_destroy(it); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); it = grpc_auth_context_find_properties_by_name(ctx, "foo"); - GPR_ASSERT(it != NULL); - 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) == NULL); - grpc_auth_property_iterator_destroy(it); + 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) == NULL); it = grpc_auth_context_peer_identity(ctx); - GPR_ASSERT(it != NULL); - 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) == NULL); - grpc_auth_property_iterator_destroy(it); + 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) == NULL); grpc_auth_context_unref(ctx); }