aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/security/transport/client_auth_filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lib/security/transport/client_auth_filter.c')
-rw-r--r--src/core/lib/security/transport/client_auth_filter.c115
1 files changed, 45 insertions, 70 deletions
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index cf056e8008..b7f6fd23e3 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -45,7 +45,6 @@
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/call.h"
#include "src/core/lib/transport/static_metadata.h"
@@ -55,10 +54,8 @@
/* We can have a per-call credentials. */
typedef struct {
grpc_call_credentials *creds;
- bool have_host;
- bool have_method;
- grpc_slice host;
- grpc_slice method;
+ grpc_mdstr *host;
+ grpc_mdstr *method;
/* pollset{_set} bound to this call; if we need to make external
network requests, they should be done under a pollset added to this
pollset_set so that work can progress when this call wants work to progress
@@ -92,12 +89,14 @@ static void reset_auth_metadata_context(
auth_md_context->channel_auth_context = NULL;
}
-static void add_error(grpc_error **combined, grpc_error *error) {
- if (error == GRPC_ERROR_NONE) return;
- if (*combined == GRPC_ERROR_NONE) {
- *combined = GRPC_ERROR_CREATE("Client auth metadata plugin error");
- }
- *combined = grpc_error_add_child(*combined, error);
+static void bubble_up_error(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+ grpc_status_code status, const char *error_msg) {
+ call_data *calld = elem->call_data;
+ gpr_log(GPR_ERROR, "Client side authentication failure: %s", error_msg);
+ grpc_slice error_slice = grpc_slice_from_copied_string(error_msg);
+ grpc_transport_stream_op_add_close(exec_ctx, &calld->op, status,
+ &error_slice);
+ grpc_call_next_op(exec_ctx, elem, &calld->op);
}
static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
@@ -111,37 +110,30 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_metadata_batch *mdb;
size_t i;
reset_auth_metadata_context(&calld->auth_md_context);
- grpc_error *error = GRPC_ERROR_NONE;
if (status != GRPC_CREDENTIALS_OK) {
- error = grpc_error_set_int(
- GRPC_ERROR_CREATE(error_details != NULL && strlen(error_details) > 0
- ? error_details
- : "Credentials failed to get metadata."),
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED);
- } else {
- GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
- GPR_ASSERT(op->send_initial_metadata != NULL);
- mdb = op->send_initial_metadata;
- for (i = 0; i < num_md; i++) {
- add_error(&error,
- grpc_metadata_batch_add_tail(
- exec_ctx, mdb, &calld->md_links[i],
- grpc_mdelem_from_slices(
- exec_ctx, grpc_slice_ref_internal(md_elems[i].key),
- grpc_slice_ref_internal(md_elems[i].value))));
- }
+ bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
+ (error_details != NULL && strlen(error_details) > 0)
+ ? error_details
+ : "Credentials failed to get metadata.");
+ return;
}
- if (error == GRPC_ERROR_NONE) {
- grpc_call_next_op(exec_ctx, elem, op);
- } else {
- grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
+ GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
+ GPR_ASSERT(op->send_initial_metadata != NULL);
+ mdb = op->send_initial_metadata;
+ for (i = 0; i < num_md; i++) {
+ grpc_metadata_batch_add_tail(
+ mdb, &calld->md_links[i],
+ grpc_mdelem_from_slices(exec_ctx,
+ grpc_slice_ref_internal(md_elems[i].key),
+ grpc_slice_ref_internal(md_elems[i].value)));
}
+ grpc_call_next_op(exec_ctx, elem, op);
}
void build_auth_metadata_context(grpc_security_connector *sc,
grpc_auth_context *auth_context,
call_data *calld) {
- char *service = grpc_slice_to_c_string(calld->method);
+ char *service = gpr_strdup(grpc_mdstr_as_c_string(calld->method));
char *last_slash = strrchr(service, '/');
char *method_name = NULL;
char *service_url = NULL;
@@ -157,15 +149,14 @@ void build_auth_metadata_context(grpc_security_connector *sc,
method_name = gpr_strdup(last_slash + 1);
}
if (method_name == NULL) method_name = gpr_strdup("");
- char *host = grpc_slice_to_c_string(calld->host);
gpr_asprintf(&service_url, "%s://%s%s",
- sc->url_scheme == NULL ? "" : sc->url_scheme, host, service);
+ sc->url_scheme == NULL ? "" : sc->url_scheme,
+ grpc_mdstr_as_c_string(calld->host), service);
calld->auth_md_context.service_url = service_url;
calld->auth_md_context.method_name = method_name;
calld->auth_md_context.channel_auth_context =
GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context");
gpr_free(service);
- gpr_free(host);
}
static void send_security_metadata(grpc_exec_ctx *exec_ctx,
@@ -189,12 +180,8 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
calld->creds = grpc_composite_call_credentials_create(channel_call_creds,
ctx->creds, NULL);
if (calld->creds == NULL) {
- grpc_transport_stream_op_finish_with_failure(
- exec_ctx, op,
- grpc_error_set_int(
- GRPC_ERROR_CREATE(
- "Incompatible credentials set on channel and call."),
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED));
+ bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED,
+ "Incompatible credentials set on channel and call.");
return;
}
} else {
@@ -220,14 +207,9 @@ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
send_security_metadata(exec_ctx, elem, &calld->op);
} else {
char *error_msg;
- char *host = grpc_slice_to_c_string(calld->host);
gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
- host);
- gpr_free(host);
- grpc_call_element_signal_error(
- exec_ctx, elem, grpc_error_set_int(GRPC_ERROR_CREATE(error_msg),
- GRPC_ERROR_INT_GRPC_STATUS,
- GRPC_STATUS_UNAUTHENTICATED));
+ grpc_mdstr_as_c_string(calld->host));
+ bubble_up_error(exec_ctx, elem, GRPC_STATUS_UNAUTHENTICATED, error_msg);
gpr_free(error_msg);
}
}
@@ -265,30 +247,23 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx,
if (op->send_initial_metadata != NULL) {
for (l = op->send_initial_metadata->list.head; l != NULL; l = l->next) {
- grpc_mdelem md = l->md;
+ grpc_mdelem *md = l->md;
/* Pointer comparison is OK for md_elems created from the same context.
*/
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_AUTHORITY)) {
- if (calld->have_host) {
- grpc_slice_unref_internal(exec_ctx, calld->host);
- }
- calld->host = grpc_slice_ref_internal(GRPC_MDVALUE(md));
- calld->have_host = true;
- } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_PATH)) {
- if (calld->have_method) {
- grpc_slice_unref_internal(exec_ctx, calld->method);
- }
- calld->method = grpc_slice_ref_internal(GRPC_MDVALUE(md));
- calld->have_method = true;
+ if (md->key == GRPC_MDSTR_AUTHORITY) {
+ if (calld->host != NULL) GRPC_MDSTR_UNREF(exec_ctx, calld->host);
+ calld->host = GRPC_MDSTR_REF(md->value);
+ } else if (md->key == GRPC_MDSTR_PATH) {
+ if (calld->method != NULL) GRPC_MDSTR_UNREF(exec_ctx, calld->method);
+ calld->method = GRPC_MDSTR_REF(md->value);
}
}
- if (calld->have_host) {
- char *call_host = grpc_slice_to_c_string(calld->host);
+ if (calld->host != NULL) {
+ const char *call_host = grpc_mdstr_as_c_string(calld->host);
calld->op = *op; /* Copy op (originates from the caller's stack). */
grpc_channel_security_connector_check_call_host(
exec_ctx, chand->security_connector, call_host, chand->auth_context,
on_host_checked, elem);
- gpr_free(call_host);
GPR_TIMER_END("auth_start_transport_op", 0);
return; /* early exit */
}
@@ -321,11 +296,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
void *ignored) {
call_data *calld = elem->call_data;
grpc_call_credentials_unref(exec_ctx, calld->creds);
- if (calld->have_host) {
- grpc_slice_unref_internal(exec_ctx, calld->host);
+ if (calld->host != NULL) {
+ GRPC_MDSTR_UNREF(exec_ctx, calld->host);
}
- if (calld->have_method) {
- grpc_slice_unref_internal(exec_ctx, calld->method);
+ if (calld->method != NULL) {
+ GRPC_MDSTR_UNREF(exec_ctx, calld->method);
}
reset_auth_metadata_context(&calld->auth_md_context);
}