Cannot figure out server filter logic for error in auth md processing.

- Positive tests pass even if we will have to change the interface to
  add the processor to the server credentials (will be done in a
  separate pull request).
- ASAN leaks for the error case.
- The client should get a GRPC_STATUS_UNAUTHENTICATED as opposed to
  GPRC_STATUS_INTERNAL.
pull/2492/head
Julien Boeuf 10 years ago
parent ea456fc2bf
commit a87d6c2af6
  1. 25
      include/grpc/grpc_security.h
  2. 13
      src/core/security/security_context.c
  3. 3
      src/core/security/security_context.h
  4. 55
      src/core/security/server_auth_filter.c
  5. 248
      test/core/end2end/tests/request_response_with_payload_and_call_creds.c

@ -291,16 +291,23 @@ typedef void (*grpc_process_auth_metadata_done_cb)(
void *user_data, const grpc_metadata *consumed_md, size_t num_consumed_md, void *user_data, const grpc_metadata *consumed_md, size_t num_consumed_md,
int success, grpc_auth_context *result); int success, grpc_auth_context *result);
/* Pluggable metadata processing function */ /* Pluggable server-side metadata processor object */
typedef void (*grpc_process_auth_metadata_func)( typedef struct {
grpc_auth_ticket *ticket, grpc_auth_context *channel_ctx, void (*process)(void *state, grpc_auth_ticket *ticket,
const grpc_metadata *md, size_t md_count, grpc_auth_context *channel_ctx, const grpc_metadata *md,
grpc_process_auth_metadata_done_cb cb, void *user_data); size_t md_count, grpc_process_auth_metadata_done_cb cb,
void *user_data);
/* Registration function for metadata processing. 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. */ Should be called before the server is started. */
void grpc_server_auth_context_register_process_metadata_func( void grpc_server_register_auth_metadata_processor(
grpc_process_auth_metadata_func func); grpc_auth_metadata_processor processor);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -44,16 +44,15 @@
/* --- grpc_process_auth_metadata_func --- */ /* --- grpc_process_auth_metadata_func --- */
static grpc_process_auth_metadata_func server_md_func = NULL; static grpc_auth_metadata_processor server_processor = {NULL, NULL};
void grpc_server_auth_context_register_process_metadata_func( grpc_auth_metadata_processor grpc_server_get_auth_metadata_processor(void) {
grpc_process_auth_metadata_func func) { return server_processor;
server_md_func = func;
} }
grpc_process_auth_metadata_func void grpc_server_register_auth_metadata_processor(
grpc_server_auth_context_get_process_metadata_func(void) { grpc_auth_metadata_processor processor) {
return server_md_func; server_processor = processor;
} }
/* --- grpc_call --- */ /* --- grpc_call --- */

@ -106,8 +106,7 @@ void grpc_server_security_context_destroy(void *ctx);
/* --- Auth metadata processing. --- */ /* --- Auth metadata processing. --- */
grpc_process_auth_metadata_func grpc_auth_metadata_processor grpc_server_get_auth_metadata_processor(void);
grpc_server_auth_context_get_process_metadata_func(void);
#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */ #endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */

@ -42,16 +42,14 @@
typedef struct call_data { typedef struct call_data {
gpr_uint8 got_client_metadata; gpr_uint8 got_client_metadata;
gpr_uint8 sent_status;
gpr_uint8 success;
grpc_linked_mdelem status;
grpc_stream_op_buffer *recv_ops; grpc_stream_op_buffer *recv_ops;
/* Closure to call when finished with the hs_on_recv hook. */ /* Closure to call when finished with the auth_on_recv hook. */
grpc_iomgr_closure *on_done_recv; grpc_iomgr_closure *on_done_recv;
/* Receive closures are chained: we inject this closure as the 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 up-call on transport_op, and remember to call our on_done_recv member after
handling it. */ handling it. */
grpc_iomgr_closure auth_on_recv; grpc_iomgr_closure auth_on_recv;
grpc_transport_stream_op transport_op;
const grpc_metadata *consumed_md; const grpc_metadata *consumed_md;
size_t num_consumed_md; size_t num_consumed_md;
grpc_stream_op *md_op; grpc_stream_op *md_op;
@ -61,7 +59,7 @@ typedef struct call_data {
typedef struct channel_data { typedef struct channel_data {
grpc_security_connector *security_connector; grpc_security_connector *security_connector;
grpc_mdelem *status_auth_failure; grpc_mdctx *mdctx;
} channel_data; } channel_data;
static grpc_metadata_array metadata_batch_to_md_array( static grpc_metadata_array metadata_batch_to_md_array(
@ -112,8 +110,8 @@ static void on_md_processing_done(void *user_data,
grpc_auth_context *result) { grpc_auth_context *result) {
grpc_call_element *elem = user_data; grpc_call_element *elem = user_data;
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
calld->success = success;
if (success) { if (success) {
calld->consumed_md = consumed_md; calld->consumed_md = consumed_md;
calld->num_consumed_md = num_consumed_md; calld->num_consumed_md = num_consumed_md;
@ -124,11 +122,14 @@ static void on_md_processing_done(void *user_data,
"releasing old context."); "releasing old context.");
*calld->call_auth_context = *calld->call_auth_context =
GRPC_AUTH_CONTEXT_REF(result, "refing new context."); GRPC_AUTH_CONTEXT_REF(result, "refing new context.");
calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success);
} else { } else {
grpc_call_element_send_cancel(elem); 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);
} }
calld->on_done_recv->cb(calld->on_done_recv->cb_arg, success);
} }
static void auth_on_recv(void *user_data, int success) { static void auth_on_recv(void *user_data, int success) {
@ -141,16 +142,18 @@ static void auth_on_recv(void *user_data, int success) {
grpc_stream_op *ops = calld->recv_ops->ops; grpc_stream_op *ops = calld->recv_ops->ops;
for (i = 0; i < nops; i++) { for (i = 0; i < nops; i++) {
grpc_metadata_array md_array; grpc_metadata_array md_array;
grpc_process_auth_metadata_func processor = grpc_auth_metadata_processor processor =
grpc_server_auth_context_get_process_metadata_func(); grpc_server_get_auth_metadata_processor();
grpc_stream_op *op = &ops[i]; grpc_stream_op *op = &ops[i];
if (op->type != GRPC_OP_METADATA) continue; if (op->type != GRPC_OP_METADATA || calld->got_client_metadata) continue;
calld->got_client_metadata = 1; calld->got_client_metadata = 1;
if (processor == NULL) continue; if (processor.process == NULL) continue;
calld->md_op = op; calld->md_op = op;
md_array = metadata_batch_to_md_array(&op->data.metadata); md_array = metadata_batch_to_md_array(&op->data.metadata);
processor(&calld->ticket, chand->security_connector->auth_context, processor.process(processor.state, &calld->ticket,
md_array.metadata, md_array.count, on_md_processing_done, elem); chand->security_connector->auth_context,
md_array.metadata, md_array.count,
on_md_processing_done, elem);
grpc_metadata_array_destroy(&md_array); grpc_metadata_array_destroy(&md_array);
return; return;
} }
@ -161,28 +164,13 @@ static void auth_on_recv(void *user_data, int success) {
static void set_recv_ops_md_callbacks(grpc_call_element *elem, static void set_recv_ops_md_callbacks(grpc_call_element *elem,
grpc_transport_stream_op *op) { grpc_transport_stream_op *op) {
call_data *calld = elem->call_data; call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
if (op->send_ops && !calld->sent_status && !calld->success) {
size_t i;
size_t nops = op->send_ops->nops;
grpc_stream_op *ops = op->send_ops->ops;
for (i = 0; i < nops; i++) {
grpc_stream_op *op = &ops[i];
if (op->type != GRPC_OP_METADATA) continue;
calld->sent_status = 1;
grpc_metadata_batch_add_head(
&op->data.metadata, &calld->status,
GRPC_MDELEM_REF(chand->status_auth_failure));
break;
}
}
if (op->recv_ops && !calld->got_client_metadata) { if (op->recv_ops && !calld->got_client_metadata) {
/* substitute our callback for the higher callback */ /* substitute our callback for the higher callback */
calld->recv_ops = op->recv_ops; calld->recv_ops = op->recv_ops;
calld->on_done_recv = op->on_done_recv; calld->on_done_recv = op->on_done_recv;
op->on_done_recv = &calld->auth_on_recv; op->on_done_recv = &calld->auth_on_recv;
calld->transport_op = *op;
} }
} }
@ -209,7 +197,6 @@ static void init_call_elem(grpc_call_element *elem,
/* initialize members */ /* initialize members */
memset(calld, 0, sizeof(*calld)); memset(calld, 0, sizeof(*calld));
grpc_iomgr_closure_init(&calld->auth_on_recv, auth_on_recv, elem); grpc_iomgr_closure_init(&calld->auth_on_recv, auth_on_recv, elem);
calld->success = 1;
GPR_ASSERT(initial_op && initial_op->context != NULL && GPR_ASSERT(initial_op && initial_op->context != NULL &&
initial_op->context[GRPC_CONTEXT_SECURITY].value == NULL); initial_op->context[GRPC_CONTEXT_SECURITY].value == NULL);
@ -260,8 +247,7 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
GPR_ASSERT(!sc->is_client_side); GPR_ASSERT(!sc->is_client_side);
chand->security_connector = chand->security_connector =
GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter"); GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter");
chand->status_auth_failure = chand->mdctx = mdctx;
grpc_mdelem_from_strings(mdctx, ":status", "401");
} }
/* Destructor for channel data */ /* Destructor for channel data */
@ -270,7 +256,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector, GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector,
"server_auth_filter"); "server_auth_filter");
GRPC_MDELEM_UNREF(chand->status_auth_failure);
} }
const grpc_channel_filter grpc_server_auth_filter = { const grpc_channel_filter grpc_server_auth_filter = {

@ -84,45 +84,51 @@ static void check_peer_identity(grpc_auth_context *ctx,
GPR_ASSERT(strcmp(expected_identity, prop->value) == 0); GPR_ASSERT(strcmp(expected_identity, prop->value) == 0);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
} }
static void process_auth_md_success(grpc_auth_ticket *t, static void process_auth_md_success(void *state, grpc_auth_ticket *t,
grpc_auth_context *channel_ctx, grpc_auth_context *channel_ctx,
const grpc_metadata *md, size_t md_count, const grpc_metadata *md, size_t md_count,
grpc_process_auth_metadata_done_cb cb, grpc_process_auth_metadata_done_cb cb,
void *user_data) { void *user_data) {
grpc_auth_context *new_auth_ctx = grpc_auth_context_create(channel_ctx); override_mode *mode;
const grpc_metadata *custom_creds_md = GPR_ASSERT(state != NULL);
find_metadata(md, md_count, custom_creds_md_name, custom_creds_md_value); mode = (override_mode *)state;
GPR_ASSERT(custom_creds_md != NULL); if (*mode != DESTROY) {
grpc_auth_context_add_cstring_property( grpc_auth_context *new_auth_ctx = grpc_auth_context_create(channel_ctx);
new_auth_ctx, client_identity_property_name, client_identity); const grpc_metadata *custom_creds_md = find_metadata(
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( md, md_count, custom_creds_md_name, custom_creds_md_value);
new_auth_ctx, client_identity_property_name) == 1); GPR_ASSERT(custom_creds_md != NULL);
cb(user_data, custom_creds_md, 1, 1, new_auth_ctx); grpc_auth_context_add_cstring_property(
grpc_auth_context_release(new_auth_ctx); 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);
}
} }
#if 0 static void process_auth_md_failure(void *state, grpc_auth_ticket *t,
static void process_auth_md_failure(grpc_auth_ticket *t,
grpc_auth_context *channel_ctx, grpc_auth_context *channel_ctx,
const grpc_metadata *md, size_t md_count, const grpc_metadata *md, size_t md_count,
grpc_process_auth_metadata_done_cb cb, grpc_process_auth_metadata_done_cb cb,
void *user_data) { void *user_data) {
const grpc_metadata *custom_creds_md = override_mode *mode;
find_metadata(md, md_count, custom_creds_md_name, custom_creds_md_value); GPR_ASSERT(state != NULL);
GPR_ASSERT(custom_creds_md != 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. */ cb(user_data, NULL, 0, 0, NULL); /* Fail. */
} }
#endif
static grpc_end2end_test_fixture begin_test( static grpc_end2end_test_fixture begin_test(
grpc_end2end_test_config config, const char *test_name, grpc_end2end_test_config config, const char *test_name,
grpc_process_auth_metadata_func md_func, override_mode mode) { grpc_auth_metadata_processor processor) {
grpc_end2end_test_fixture f; grpc_end2end_test_fixture f;
if (mode != DESTROY) { grpc_server_register_auth_metadata_processor(processor);
grpc_server_auth_context_register_process_metadata_func(md_func);
} else {
grpc_server_auth_context_register_process_metadata_func(NULL);
}
gpr_log(GPR_INFO, "%s/%s", test_name, config.name); gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
f = config.create_fixture(NULL, NULL); f = config.create_fixture(NULL, NULL);
config.init_client(&f, NULL); config.init_client(&f, NULL);
@ -200,8 +206,9 @@ static grpc_credentials *iam_custom_composite_creds_create(
static void test_call_creds_failure(grpc_end2end_test_config config) { static void test_call_creds_failure(grpc_end2end_test_config config) {
grpc_call *c; grpc_call *c;
grpc_credentials *creds = NULL; grpc_credentials *creds = NULL;
grpc_auth_metadata_processor p = {NULL, NULL};
grpc_end2end_test_fixture f = grpc_end2end_test_fixture f =
begin_test(config, "test_call_creds_failure", NULL, NONE); begin_test(config, "test_call_creds_failure", p);
gpr_timespec deadline = five_seconds_time(); gpr_timespec deadline = five_seconds_time();
c = grpc_channel_create_call(f.client, f.cq, "/foo", "foo.test.google.fr", c = grpc_channel_create_call(f.client, f.cq, "/foo", "foo.test.google.fr",
deadline); deadline);
@ -230,10 +237,9 @@ static void request_response_with_payload_and_call_creds(
grpc_byte_buffer *response_payload = grpc_byte_buffer *response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1); grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_timespec deadline = five_seconds_time(); gpr_timespec deadline = five_seconds_time();
grpc_auth_metadata_processor p;
grpc_end2end_test_fixture f = grpc_end2end_test_fixture f;
begin_test(config, test_name, process_auth_md_success, mode); cq_verifier *cqv;
cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_op ops[6]; grpc_op ops[6];
grpc_op *op; grpc_op *op;
grpc_metadata_array initial_metadata_recv; grpc_metadata_array initial_metadata_recv;
@ -250,6 +256,11 @@ static void request_response_with_payload_and_call_creds(
grpc_auth_context *s_auth_context = NULL; grpc_auth_context *s_auth_context = NULL;
grpc_auth_context *c_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", c = grpc_channel_create_call(f.client, f.cq, "/foo", "foo.test.google.fr",
deadline); deadline);
GPR_ASSERT(c); GPR_ASSERT(c);
@ -446,54 +457,41 @@ static void test_request_response_with_payload_and_deleted_call_creds(
DESTROY); DESTROY);
} }
static void test_request_with_bad_creds(void) { static void test_request_with_server_rejecting_client_creds(
#if 0 grpc_end2end_test_config config) {
grpc_call *c;
grpc_call *s;
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);
gpr_timespec deadline = five_seconds_time();
grpc_end2end_test_fixture f =
begin_test(config, test_name, process_auth_md_failure, NONE);
cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_op ops[6]; grpc_op ops[6];
grpc_op *op; 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 initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv; grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv; grpc_metadata_array request_metadata_recv;
grpc_byte_buffer *request_payload_recv = NULL;
grpc_byte_buffer *response_payload_recv = NULL;
grpc_call_details call_details; grpc_call_details call_details;
grpc_status_code status; grpc_status_code status;
char *details = NULL; char *details = NULL;
size_t details_capacity = 0; size_t details_capacity = 0;
int was_cancelled = 2; grpc_byte_buffer *response_payload_recv = NULL;
grpc_credentials *creds = NULL; gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
grpc_auth_context *s_auth_context = NULL; grpc_byte_buffer *request_payload =
grpc_auth_context *c_auth_context = NULL; 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", c = grpc_channel_create_call(f.client, f.cq, "/foo", "foo.test.google.fr",
deadline); deadline);
GPR_ASSERT(c); GPR_ASSERT(c);
creds = iam_custom_composite_creds_create(iam_token, iam_selector); creds = iam_custom_composite_creds_create(iam_token, iam_selector);
GPR_ASSERT(creds != NULL); GPR_ASSERT(creds != NULL);
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK); GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
switch (mode) {
case NONE:
break;
case OVERRIDE:
grpc_credentials_release(creds);
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);
break;
case DESTROY:
GPR_ASSERT(grpc_call_set_credentials(c, NULL) == GRPC_CALL_OK);
break;
}
grpc_credentials_release(creds); grpc_credentials_release(creds);
grpc_metadata_array_init(&initial_metadata_recv); grpc_metadata_array_init(&initial_metadata_recv);
@ -502,6 +500,13 @@ static void test_request_with_bad_creds(void) {
grpc_call_details_init(&call_details); grpc_call_details_init(&call_details);
op = ops; 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->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0; op->data.send_initial_metadata.count = 0;
op->flags = 0; op->flags = 0;
@ -521,134 +526,31 @@ static void test_request_with_bad_creds(void) {
op->data.recv_message = &response_payload_recv; op->data.recv_message = &response_payload_recv;
op->flags = 0; op->flags = 0;
op++; op++;
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++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1))); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
f.server, &s, &call_details,
&request_metadata_recv, f.cq, f.cq, tag(101)));
cq_expect_completion(cqv, tag(101), 1);
cq_verify(cqv);
s_auth_context = grpc_call_auth_context(s);
GPR_ASSERT(s_auth_context != NULL);
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);
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = 0;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = &request_payload_recv;
op->flags = 0;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
cq_expect_completion(cqv, tag(102), 1);
cq_verify(cqv);
op = ops;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op->flags = 0;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = response_payload;
op->flags = 0;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
op->data.send_status_from_server.status_details = "xyz";
op->flags = 0;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103)));
cq_expect_completion(cqv, tag(103), 1);
cq_expect_completion(cqv, tag(1), 1); cq_expect_completion(cqv, tag(1), 1);
cq_verify(cqv); cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK); /* XXX Should be GRPC_STATUS_UNAUTHENTICATED but it looks like there is a bug
GPR_ASSERT(0 == strcmp(details, "xyz")); (probably in the server_auth_context.c code) where this error on the server
GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); does not get to the client. The current error code we are getting is
GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GRPC_STATUS_INTERNAL. */
GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(status != GRPC_STATUS_OK);
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,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
iam_token));
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,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
overridden_iam_token));
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,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
iam_token));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
iam_selector));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
overridden_iam_token));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
overridden_iam_selector));
break;
}
gpr_free(details);
grpc_metadata_array_destroy(&initial_metadata_recv); grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv); grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv); grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details); grpc_call_details_destroy(&call_details);
grpc_call_destroy(c);
grpc_call_destroy(s);
cq_verifier_destroy(cqv);
grpc_byte_buffer_destroy(request_payload); grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(response_payload);
grpc_byte_buffer_destroy(request_payload_recv);
grpc_byte_buffer_destroy(response_payload_recv); grpc_byte_buffer_destroy(response_payload_recv);
gpr_free(details);
grpc_call_destroy(c);
cq_verifier_destroy(cqv);
end_test(&f); end_test(&f);
config.tear_down_data(&f); config.tear_down_data(&f);
#endif
} }
void grpc_end2end_tests(grpc_end2end_test_config config) { void grpc_end2end_tests(grpc_end2end_test_config config) {
@ -657,6 +559,6 @@ void grpc_end2end_tests(grpc_end2end_test_config config) {
test_request_response_with_payload_and_call_creds(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_overridden_call_creds(config);
test_request_response_with_payload_and_deleted_call_creds(config); test_request_response_with_payload_and_deleted_call_creds(config);
test_request_with_bad_creds(); test_request_with_server_rejecting_client_creds(config);
} }
} }

Loading…
Cancel
Save