aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/security
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lib/security')
-rw-r--r--src/core/lib/security/context/security_context.cc (renamed from src/core/lib/security/context/security_context.c)26
-rw-r--r--src/core/lib/security/credentials/composite/composite_credentials.cc (renamed from src/core/lib/security/credentials/composite/composite_credentials.c)26
-rw-r--r--src/core/lib/security/credentials/composite/composite_credentials.h8
-rw-r--r--src/core/lib/security/credentials/credentials.cc (renamed from src/core/lib/security/credentials/credentials.c)22
-rw-r--r--src/core/lib/security/credentials/credentials.h8
-rw-r--r--src/core/lib/security/credentials/credentials_metadata.cc (renamed from src/core/lib/security/credentials/credentials_metadata.c)3
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.cc (renamed from src/core/lib/security/credentials/fake/fake_credentials.c)18
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.h8
-rw-r--r--src/core/lib/security/credentials/google_default/credentials_generic.cc (renamed from src/core/lib/security/credentials/google_default/credentials_generic.c)0
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.cc (renamed from src/core/lib/security/credentials/google_default/google_default_credentials.c)19
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.h8
-rw-r--r--src/core/lib/security/credentials/iam/iam_credentials.cc (renamed from src/core/lib/security/credentials/iam/iam_credentials.c)3
-rw-r--r--src/core/lib/security/credentials/jwt/json_token.cc (renamed from src/core/lib/security/credentials/jwt/json_token.c)9
-rw-r--r--src/core/lib/security/credentials/jwt/json_token.h8
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_credentials.cc (renamed from src/core/lib/security/credentials/jwt/jwt_credentials.c)6
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_credentials.h8
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_verifier.cc (renamed from src/core/lib/security/credentials/jwt/jwt_verifier.c)43
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_verifier.h10
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.cc (renamed from src/core/lib/security/credentials/oauth2/oauth2_credentials.c)62
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.h14
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.cc (renamed from src/core/lib/security/credentials/plugin/plugin_credentials.c)185
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.h2
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.c194
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.cc343
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.h27
-rw-r--r--src/core/lib/security/transport/auth_filters.h8
-rw-r--r--src/core/lib/security/transport/client_auth_filter.cc (renamed from src/core/lib/security/transport/client_auth_filter.c)235
-rw-r--r--src/core/lib/security/transport/lb_targets_info.cc (renamed from src/core/lib/security/transport/lb_targets_info.c)13
-rw-r--r--src/core/lib/security/transport/lb_targets_info.h8
-rw-r--r--src/core/lib/security/transport/secure_endpoint.cc (renamed from src/core/lib/security/transport/secure_endpoint.c)208
-rw-r--r--src/core/lib/security/transport/secure_endpoint.h19
-rw-r--r--src/core/lib/security/transport/security_connector.cc (renamed from src/core/lib/security/transport/security_connector.c)415
-rw-r--r--src/core/lib/security/transport/security_connector.h42
-rw-r--r--src/core/lib/security/transport/security_handshaker.cc (renamed from src/core/lib/security/transport/security_handshaker.c)69
-rw-r--r--src/core/lib/security/transport/security_handshaker.h8
-rw-r--r--src/core/lib/security/transport/server_auth_filter.cc (renamed from src/core/lib/security/transport/server_auth_filter.c)115
-rw-r--r--src/core/lib/security/transport/tsi_error.cc (renamed from src/core/lib/security/transport/tsi_error.c)0
-rw-r--r--src/core/lib/security/transport/tsi_error.h8
-rw-r--r--src/core/lib/security/util/json_util.cc (renamed from src/core/lib/security/util/json_util.c)0
-rw-r--r--src/core/lib/security/util/json_util.h8
40 files changed, 1441 insertions, 775 deletions
diff --git a/src/core/lib/security/context/security_context.c b/src/core/lib/security/context/security_context.cc
index 8fff2c92c5..31d800b9b4 100644
--- a/src/core/lib/security/context/security_context.c
+++ b/src/core/lib/security/context/security_context.cc
@@ -82,7 +82,8 @@ void grpc_auth_context_release(grpc_auth_context *context) {
/* --- grpc_client_security_context --- */
grpc_client_security_context *grpc_client_security_context_create(void) {
- return gpr_zalloc(sizeof(grpc_client_security_context));
+ return (grpc_client_security_context *)gpr_zalloc(
+ sizeof(grpc_client_security_context));
}
void grpc_client_security_context_destroy(void *ctx) {
@@ -100,7 +101,8 @@ void grpc_client_security_context_destroy(void *ctx) {
/* --- grpc_server_security_context --- */
grpc_server_security_context *grpc_server_security_context_create(void) {
- return gpr_zalloc(sizeof(grpc_server_security_context));
+ return (grpc_server_security_context *)gpr_zalloc(
+ sizeof(grpc_server_security_context));
}
void grpc_server_security_context_destroy(void *ctx) {
@@ -117,7 +119,8 @@ 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) {
- grpc_auth_context *ctx = gpr_zalloc(sizeof(grpc_auth_context));
+ grpc_auth_context *ctx =
+ (grpc_auth_context *)gpr_zalloc(sizeof(grpc_auth_context));
gpr_ref_init(&ctx->refcount, 1);
if (chained != NULL) {
ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained");
@@ -258,9 +261,9 @@ 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));
+ ctx->properties.array = (grpc_auth_property *)gpr_realloc(
+ ctx->properties.array,
+ ctx->properties.capacity * sizeof(grpc_auth_property));
}
}
@@ -275,7 +278,7 @@ void grpc_auth_context_add_property(grpc_auth_context *ctx, const char *name,
ensure_auth_context_capacity(ctx);
prop = &ctx->properties.array[ctx->properties.count++];
prop->name = gpr_strdup(name);
- prop->value = gpr_malloc(value_length + 1);
+ prop->value = (char *)gpr_malloc(value_length + 1);
memcpy(prop->value, value, value_length);
prop->value[value_length] = '\0';
prop->value_length = value_length;
@@ -302,11 +305,12 @@ void grpc_auth_property_reset(grpc_auth_property *property) {
}
static void auth_context_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
- GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg");
+ GRPC_AUTH_CONTEXT_UNREF((grpc_auth_context *)p, "auth_context_pointer_arg");
}
static void *auth_context_pointer_arg_copy(void *p) {
- return GRPC_AUTH_CONTEXT_REF(p, "auth_context_pointer_arg");
+ return GRPC_AUTH_CONTEXT_REF((grpc_auth_context *)p,
+ "auth_context_pointer_arg");
}
static int auth_context_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
@@ -316,7 +320,7 @@ static const grpc_arg_pointer_vtable auth_context_pointer_vtable = {
auth_context_pointer_cmp};
grpc_arg grpc_auth_context_to_arg(grpc_auth_context *p) {
- return grpc_channel_arg_pointer_create(GRPC_AUTH_CONTEXT_ARG, p,
+ return grpc_channel_arg_pointer_create((char *)GRPC_AUTH_CONTEXT_ARG, p,
&auth_context_pointer_vtable);
}
@@ -327,7 +331,7 @@ grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg) {
GRPC_AUTH_CONTEXT_ARG);
return NULL;
}
- return arg->value.pointer.p;
+ return (grpc_auth_context *)arg->value.pointer.p;
}
grpc_auth_context *grpc_find_auth_context_in_args(
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.c b/src/core/lib/security/credentials/composite/composite_credentials.cc
index 09fd60a12c..779300ac07 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.c
+++ b/src/core/lib/security/credentials/composite/composite_credentials.cc
@@ -79,7 +79,8 @@ static bool composite_call_get_request_metadata(
grpc_error **error) {
grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
grpc_composite_call_credentials_metadata_context *ctx;
- ctx = gpr_zalloc(sizeof(grpc_composite_call_credentials_metadata_context));
+ ctx = (grpc_composite_call_credentials_metadata_context *)gpr_zalloc(
+ sizeof(grpc_composite_call_credentials_metadata_context));
ctx->composite_creds = c;
ctx->pollent = pollent;
ctx->auth_md_context = auth_md_context;
@@ -87,6 +88,7 @@ static bool composite_call_get_request_metadata(
ctx->on_request_metadata = on_request_metadata;
GRPC_CLOSURE_INIT(&ctx->internal_on_request_metadata,
composite_call_metadata_cb, ctx, grpc_schedule_on_exec_ctx);
+ bool synchronous = true;
while (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
grpc_call_credentials *inner_creds =
ctx->composite_creds->inner.creds_array[ctx->creds_index++];
@@ -95,19 +97,12 @@ static bool composite_call_get_request_metadata(
ctx->md_array, &ctx->internal_on_request_metadata, error)) {
if (*error != GRPC_ERROR_NONE) break;
} else {
+ synchronous = false; // Async return.
break;
}
}
- // If we got through all creds synchronously or we got a synchronous
- // error on one of them, return synchronously.
- if (ctx->creds_index == ctx->composite_creds->inner.num_creds ||
- *error != GRPC_ERROR_NONE) {
- gpr_free(ctx);
- return true;
- }
- // At least one inner cred is returning asynchronously, so we'll
- // return asynchronously as well.
- return false;
+ if (synchronous) gpr_free(ctx);
+ return synchronous;
}
static void composite_call_cancel_get_request_metadata(
@@ -152,7 +147,8 @@ grpc_call_credentials *grpc_composite_call_credentials_create(
GPR_ASSERT(reserved == NULL);
GPR_ASSERT(creds1 != NULL);
GPR_ASSERT(creds2 != NULL);
- c = gpr_zalloc(sizeof(grpc_composite_call_credentials));
+ c = (grpc_composite_call_credentials *)gpr_zalloc(
+ sizeof(grpc_composite_call_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE;
c->base.vtable = &composite_call_credentials_vtable;
gpr_ref_init(&c->base.refcount, 1);
@@ -160,7 +156,8 @@ grpc_call_credentials *grpc_composite_call_credentials_create(
creds2_array = get_creds_array(&creds2);
c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds;
creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials *);
- c->inner.creds_array = gpr_zalloc(creds_array_byte_size);
+ c->inner.creds_array =
+ (grpc_call_credentials **)gpr_zalloc(creds_array_byte_size);
for (i = 0; i < creds1_array.num_creds; i++) {
grpc_call_credentials *cur_creds = creds1_array.creds_array[i];
c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds);
@@ -254,7 +251,8 @@ static grpc_channel_credentials_vtable composite_channel_credentials_vtable = {
grpc_channel_credentials *grpc_composite_channel_credentials_create(
grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds,
void *reserved) {
- grpc_composite_channel_credentials *c = gpr_zalloc(sizeof(*c));
+ grpc_composite_channel_credentials *c =
+ (grpc_composite_channel_credentials *)gpr_zalloc(sizeof(*c));
GPR_ASSERT(channel_creds != NULL && call_creds != NULL && reserved == NULL);
GRPC_API_TRACE(
"grpc_composite_channel_credentials_create(channel_creds=%p, "
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h
index 3076afcb7e..6e9f9a8f6f 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.h
+++ b/src/core/lib/security/credentials/composite/composite_credentials.h
@@ -21,6 +21,10 @@
#include "src/core/lib/security/credentials/credentials.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct {
grpc_call_credentials **creds_array;
size_t num_creds;
@@ -53,5 +57,9 @@ typedef struct {
grpc_call_credentials_array inner;
} grpc_composite_call_credentials;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H \
*/
diff --git a/src/core/lib/security/credentials/credentials.c b/src/core/lib/security/credentials/credentials.cc
index 8a67c9865b..ebbf350865 100644
--- a/src/core/lib/security/credentials/credentials.c
+++ b/src/core/lib/security/credentials/credentials.cc
@@ -40,7 +40,8 @@
grpc_credentials_metadata_request *grpc_credentials_metadata_request_create(
grpc_call_credentials *creds) {
grpc_credentials_metadata_request *r =
- gpr_zalloc(sizeof(grpc_credentials_metadata_request));
+ (grpc_credentials_metadata_request *)gpr_zalloc(
+ sizeof(grpc_credentials_metadata_request));
r->creds = grpc_call_credentials_ref(creds);
return r;
}
@@ -148,11 +149,11 @@ grpc_channel_credentials_duplicate_without_call_credentials(
}
static void credentials_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
- grpc_channel_credentials_unref(exec_ctx, p);
+ grpc_channel_credentials_unref(exec_ctx, (grpc_channel_credentials *)p);
}
static void *credentials_pointer_arg_copy(void *p) {
- return grpc_channel_credentials_ref(p);
+ return grpc_channel_credentials_ref((grpc_channel_credentials *)p);
}
static int credentials_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
@@ -163,8 +164,9 @@ static const grpc_arg_pointer_vtable credentials_pointer_vtable = {
grpc_arg grpc_channel_credentials_to_arg(
grpc_channel_credentials *credentials) {
- return grpc_channel_arg_pointer_create(
- GRPC_ARG_CHANNEL_CREDENTIALS, credentials, &credentials_pointer_vtable);
+ return grpc_channel_arg_pointer_create((char *)GRPC_ARG_CHANNEL_CREDENTIALS,
+ credentials,
+ &credentials_pointer_vtable);
}
grpc_channel_credentials *grpc_channel_credentials_from_arg(
@@ -175,7 +177,7 @@ grpc_channel_credentials *grpc_channel_credentials_from_arg(
GRPC_ARG_CHANNEL_CREDENTIALS);
return NULL;
}
- return arg->value.pointer.p;
+ return (grpc_channel_credentials *)arg->value.pointer.p;
}
grpc_channel_credentials *grpc_channel_credentials_find_in_args(
@@ -244,11 +246,11 @@ void grpc_server_credentials_set_auth_metadata_processor(
static void server_credentials_pointer_arg_destroy(grpc_exec_ctx *exec_ctx,
void *p) {
- grpc_server_credentials_unref(exec_ctx, p);
+ grpc_server_credentials_unref(exec_ctx, (grpc_server_credentials *)p);
}
static void *server_credentials_pointer_arg_copy(void *p) {
- return grpc_server_credentials_ref(p);
+ return grpc_server_credentials_ref((grpc_server_credentials *)p);
}
static int server_credentials_pointer_cmp(void *a, void *b) {
@@ -260,7 +262,7 @@ static const grpc_arg_pointer_vtable cred_ptr_vtable = {
server_credentials_pointer_cmp};
grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) {
- return grpc_channel_arg_pointer_create(GRPC_SERVER_CREDENTIALS_ARG, p,
+ return grpc_channel_arg_pointer_create((char *)GRPC_SERVER_CREDENTIALS_ARG, p,
&cred_ptr_vtable);
}
@@ -271,7 +273,7 @@ grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg) {
GRPC_SERVER_CREDENTIALS_ARG);
return NULL;
}
- return arg->value.pointer.p;
+ return (grpc_server_credentials *)arg->value.pointer.p;
}
grpc_server_credentials *grpc_find_server_credentials_in_args(
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 04a54b0ca8..73e39ae039 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -29,6 +29,10 @@
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/security/transport/security_connector.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct grpc_http_response;
/* --- Constants. --- */
@@ -252,4 +256,8 @@ grpc_credentials_metadata_request *grpc_credentials_metadata_request_create(
void grpc_credentials_metadata_request_destroy(
grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *r);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/credentials_metadata.c b/src/core/lib/security/credentials/credentials_metadata.cc
index ccd39e610f..5ba98bda4e 100644
--- a/src/core/lib/security/credentials/credentials_metadata.c
+++ b/src/core/lib/security/credentials/credentials_metadata.cc
@@ -33,7 +33,8 @@ static void mdelem_list_ensure_capacity(grpc_credentials_mdelem_array *list,
while (new_size < target_size) {
new_size *= 2;
}
- list->md = gpr_realloc(list->md, sizeof(grpc_mdelem) * new_size);
+ list->md =
+ (grpc_mdelem *)gpr_realloc(list->md, sizeof(grpc_mdelem) * new_size);
}
void grpc_credentials_mdelem_array_add(grpc_credentials_mdelem_array *list,
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.c b/src/core/lib/security/credentials/fake/fake_credentials.cc
index ac9017850f..cf10bf24c8 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.c
+++ b/src/core/lib/security/credentials/fake/fake_credentials.cc
@@ -38,7 +38,8 @@ static grpc_security_status fake_transport_security_create_security_connector(
grpc_call_credentials *call_creds, const char *target,
const grpc_channel_args *args, grpc_channel_security_connector **sc,
grpc_channel_args **new_args) {
- *sc = grpc_fake_channel_security_connector_create(call_creds, target, args);
+ *sc =
+ grpc_fake_channel_security_connector_create(c, call_creds, target, args);
return GRPC_SECURITY_OK;
}
@@ -46,7 +47,7 @@ static grpc_security_status
fake_transport_security_server_create_security_connector(
grpc_exec_ctx *exec_ctx, grpc_server_credentials *c,
grpc_server_security_connector **sc) {
- *sc = grpc_fake_server_security_connector_create();
+ *sc = grpc_fake_server_security_connector_create(c);
return GRPC_SECURITY_OK;
}
@@ -60,7 +61,8 @@ static grpc_server_credentials_vtable
grpc_channel_credentials *grpc_fake_transport_security_credentials_create(
void) {
- grpc_channel_credentials *c = gpr_zalloc(sizeof(grpc_channel_credentials));
+ grpc_channel_credentials *c =
+ (grpc_channel_credentials *)gpr_zalloc(sizeof(grpc_channel_credentials));
c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
c->vtable = &fake_transport_security_credentials_vtable;
gpr_ref_init(&c->refcount, 1);
@@ -69,7 +71,8 @@ grpc_channel_credentials *grpc_fake_transport_security_credentials_create(
grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
void) {
- grpc_server_credentials *c = gpr_malloc(sizeof(grpc_server_credentials));
+ grpc_server_credentials *c =
+ (grpc_server_credentials *)gpr_malloc(sizeof(grpc_server_credentials));
memset(c, 0, sizeof(grpc_server_credentials));
c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
gpr_ref_init(&c->refcount, 1);
@@ -78,8 +81,8 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
}
grpc_arg grpc_fake_transport_expected_targets_arg(char *expected_targets) {
- return grpc_channel_arg_string_create(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS,
- expected_targets);
+ return grpc_channel_arg_string_create(
+ (char *)GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets);
}
const char *grpc_fake_transport_get_expected_targets(
@@ -129,7 +132,8 @@ grpc_call_credentials *grpc_md_only_test_credentials_create(
grpc_exec_ctx *exec_ctx, const char *md_key, const char *md_value,
bool is_async) {
grpc_md_only_test_credentials *c =
- gpr_zalloc(sizeof(grpc_md_only_test_credentials));
+ (grpc_md_only_test_credentials *)gpr_zalloc(
+ sizeof(grpc_md_only_test_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
c->base.vtable = &md_only_test_vtable;
gpr_ref_init(&c->base.refcount, 1);
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h
index aa0f3b6e20..ed3f893c58 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.h
+++ b/src/core/lib/security/credentials/fake/fake_credentials.h
@@ -21,6 +21,10 @@
#include "src/core/lib/security/credentials/credentials.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* -- Fake transport security credentials. -- */
/* Creates a fake transport security credentials object for testing. */
@@ -56,4 +60,8 @@ typedef struct {
bool is_async;
} grpc_md_only_test_credentials;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/google_default/credentials_generic.c b/src/core/lib/security/credentials/google_default/credentials_generic.cc
index 4f79718f3d..4f79718f3d 100644
--- a/src/core/lib/security/credentials/google_default/credentials_generic.c
+++ b/src/core/lib/security/credentials/google_default/credentials_generic.cc
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
index a2a8e289ee..5b2ddceb4a 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
@@ -28,6 +28,7 @@
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/iomgr/polling_entity.h"
+#include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
#include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -79,12 +80,13 @@ static void on_compute_engine_detection_http_response(grpc_exec_ctx *exec_ctx,
detector->is_done = 1;
GRPC_LOG_IF_ERROR(
"Pollset kick",
- grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent), NULL));
+ grpc_pollset_kick(exec_ctx,
+ grpc_polling_entity_pollset(&detector->pollent), NULL));
gpr_mu_unlock(g_polling_mu);
}
static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, grpc_error *e) {
- grpc_pollset_destroy(exec_ctx, p);
+ grpc_pollset_destroy(exec_ctx, (grpc_pollset *)p);
}
static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
@@ -95,9 +97,9 @@ static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
/* The http call is local. If it takes more than one sec, it is for sure not
on compute engine. */
- gpr_timespec max_detection_delay = gpr_time_from_seconds(1, GPR_TIMESPAN);
+ grpc_millis max_detection_delay = GPR_MS_PER_SEC;
- grpc_pollset *pollset = gpr_zalloc(grpc_pollset_size());
+ grpc_pollset *pollset = (grpc_pollset *)gpr_zalloc(grpc_pollset_size());
grpc_pollset_init(pollset, &g_polling_mu);
detector.pollent = grpc_polling_entity_create_from_pollset(pollset);
detector.is_done = 0;
@@ -105,8 +107,8 @@ static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
memset(&detector.response, 0, sizeof(detector.response));
memset(&request, 0, sizeof(grpc_httpcli_request));
- request.host = GRPC_COMPUTE_ENGINE_DETECTION_HOST;
- request.http.path = "/";
+ request.host = (char *)GRPC_COMPUTE_ENGINE_DETECTION_HOST;
+ request.http.path = (char *)"/";
grpc_httpcli_context_init(&context);
@@ -114,7 +116,7 @@ static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
grpc_resource_quota_create("google_default_credentials");
grpc_httpcli_get(
exec_ctx, &context, &detector.pollent, resource_quota, &request,
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
+ grpc_exec_ctx_now(exec_ctx) + max_detection_delay,
GRPC_CLOSURE_CREATE(on_compute_engine_detection_http_response, &detector,
grpc_schedule_on_exec_ctx),
&detector.response);
@@ -131,8 +133,7 @@ static int is_stack_running_on_compute_engine(grpc_exec_ctx *exec_ctx) {
"pollset_work",
grpc_pollset_work(exec_ctx,
grpc_polling_entity_pollset(&detector.pollent),
- &worker, gpr_now(GPR_CLOCK_MONOTONIC),
- gpr_inf_future(GPR_CLOCK_MONOTONIC)))) {
+ &worker, GRPC_MILLIS_INF_FUTURE))) {
detector.is_done = 1;
detector.success = 0;
}
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.h b/src/core/lib/security/credentials/google_default/google_default_credentials.h
index c3755e01a6..66677873ca 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.h
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.h
@@ -23,6 +23,10 @@
#include "src/core/lib/security/credentials/credentials.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud"
#define GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE \
"application_default_credentials.json"
@@ -41,5 +45,9 @@
void grpc_flush_cached_google_default_credentials(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_GOOGLE_DEFAULT_GOOGLE_DEFAULT_CREDENTIALS_H \
*/
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.c b/src/core/lib/security/credentials/iam/iam_credentials.cc
index 3de8319d98..e9cf208c16 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.c
+++ b/src/core/lib/security/credentials/iam/iam_credentials.cc
@@ -64,7 +64,8 @@ grpc_call_credentials *grpc_google_iam_credentials_create(
GPR_ASSERT(reserved == NULL);
GPR_ASSERT(token != NULL);
GPR_ASSERT(authority_selector != NULL);
- grpc_google_iam_credentials *c = gpr_zalloc(sizeof(*c));
+ grpc_google_iam_credentials *c =
+ (grpc_google_iam_credentials *)gpr_zalloc(sizeof(*c));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM;
c->base.vtable = &iam_vtable;
gpr_ref_init(&c->base.refcount, 1);
diff --git a/src/core/lib/security/credentials/jwt/json_token.c b/src/core/lib/security/credentials/jwt/json_token.cc
index fff71255a5..8c30353470 100644
--- a/src/core/lib/security/credentials/jwt/json_token.c
+++ b/src/core/lib/security/credentials/jwt/json_token.cc
@@ -20,6 +20,7 @@
#include <string.h>
+#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@@ -29,9 +30,11 @@
#include "src/core/lib/slice/b64.h"
#include "src/core/lib/support/string.h"
+extern "C" {
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
+}
/* --- Constants. --- */
@@ -96,7 +99,7 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json *json) {
gpr_log(GPR_ERROR, "Could not write into openssl BIO.");
goto end;
}
- result.private_key = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, "");
+ result.private_key = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, (void *)"");
if (result.private_key == NULL) {
gpr_log(GPR_ERROR, "Could not deserialize private key.");
goto end;
@@ -214,7 +217,7 @@ static char *dot_concat_and_free_strings(char *str1, char *str2) {
size_t str1_len = strlen(str1);
size_t str2_len = strlen(str2);
size_t result_len = str1_len + 1 /* dot */ + str2_len;
- char *result = gpr_malloc(result_len + 1 /* NULL terminated */);
+ char *result = (char *)gpr_malloc(result_len + 1 /* NULL terminated */);
char *current = result;
memcpy(current, str1, str1_len);
current += str1_len;
@@ -266,7 +269,7 @@ char *compute_and_encode_signature(const grpc_auth_json_key *json_key,
gpr_log(GPR_ERROR, "DigestFinal (get signature length) failed.");
goto end;
}
- sig = gpr_malloc(sig_len);
+ sig = (unsigned char *)gpr_malloc(sig_len);
if (EVP_DigestSignFinal(md_ctx, sig, &sig_len) != 1) {
gpr_log(GPR_ERROR, "DigestFinal (signature compute) failed.");
goto end;
diff --git a/src/core/lib/security/credentials/jwt/json_token.h b/src/core/lib/security/credentials/jwt/json_token.h
index e50790ef2e..b923b02df6 100644
--- a/src/core/lib/security/credentials/jwt/json_token.h
+++ b/src/core/lib/security/credentials/jwt/json_token.h
@@ -19,6 +19,10 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JSON_TOKEN_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JSON_TOKEN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <grpc/slice.h>
#include <openssl/rsa.h>
@@ -70,4 +74,8 @@ typedef char *(*grpc_jwt_encode_and_sign_override)(
void grpc_jwt_encode_and_sign_set_override(
grpc_jwt_encode_and_sign_override func);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JSON_TOKEN_H */
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.c b/src/core/lib/security/credentials/jwt/jwt_credentials.cc
index 02c82e99ba..835dd677ed 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.c
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.cc
@@ -16,8 +16,11 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
+#include <inttypes.h>
#include <string.h>
#include "src/core/lib/surface/api_trace.h"
@@ -125,7 +128,8 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
return NULL;
}
- c = gpr_zalloc(sizeof(grpc_service_account_jwt_access_credentials));
+ c = (grpc_service_account_jwt_access_credentials *)gpr_zalloc(
+ sizeof(grpc_service_account_jwt_access_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT;
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &jwt_vtable;
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h
index 07f4022669..5cee6ed0da 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.h
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h
@@ -22,6 +22,10 @@
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/jwt/json_token.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct {
grpc_call_credentials base;
@@ -45,4 +49,8 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_exec_ctx *exec_ctx, grpc_auth_json_key key,
gpr_timespec token_lifetime);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.cc
index a27284bc50..39e72c195b 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc
@@ -26,7 +26,10 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
+
+extern "C" {
#include <openssl/pem.h>
+}
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/iomgr/polling_entity.h"
@@ -129,7 +132,7 @@ static void jose_header_destroy(grpc_exec_ctx *exec_ctx, jose_header *h) {
static jose_header *jose_header_from_json(grpc_exec_ctx *exec_ctx,
grpc_json *json, grpc_slice buffer) {
grpc_json *cur;
- jose_header *h = gpr_zalloc(sizeof(jose_header));
+ jose_header *h = (jose_header *)gpr_zalloc(sizeof(jose_header));
h->buffer = buffer;
for (cur = json->child; cur != NULL; cur = cur->next) {
if (strcmp(cur->key, "alg") == 0) {
@@ -231,7 +234,8 @@ gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims *claims) {
grpc_jwt_claims *grpc_jwt_claims_from_json(grpc_exec_ctx *exec_ctx,
grpc_json *json, grpc_slice buffer) {
grpc_json *cur;
- grpc_jwt_claims *claims = gpr_malloc(sizeof(grpc_jwt_claims));
+ grpc_jwt_claims *claims =
+ (grpc_jwt_claims *)gpr_malloc(sizeof(grpc_jwt_claims));
memset(claims, 0, sizeof(grpc_jwt_claims));
claims->json = json;
claims->buffer = buffer;
@@ -347,7 +351,7 @@ static verifier_cb_ctx *verifier_cb_ctx_create(
const char *signed_jwt, size_t signed_jwt_len, void *user_data,
grpc_jwt_verification_done_cb cb) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- verifier_cb_ctx *ctx = gpr_zalloc(sizeof(verifier_cb_ctx));
+ verifier_cb_ctx *ctx = (verifier_cb_ctx *)gpr_zalloc(sizeof(verifier_cb_ctx));
ctx->verifier = verifier;
ctx->pollent = grpc_polling_entity_create_from_pollset(pollset);
ctx->header = header;
@@ -380,7 +384,7 @@ void verifier_cb_ctx_destroy(grpc_exec_ctx *exec_ctx, verifier_cb_ctx *ctx) {
gpr_timespec grpc_jwt_verifier_clock_skew = {60, 0, GPR_TIMESPAN};
/* Max delay defaults to one minute. */
-gpr_timespec grpc_jwt_verifier_max_delay = {60, 0, GPR_TIMESPAN};
+grpc_millis grpc_jwt_verifier_max_delay = 60 * GPR_MS_PER_SEC;
typedef struct {
char *email_domain;
@@ -676,6 +680,7 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_json *json = json_from_http(response);
grpc_httpcli_request req;
const char *jwks_uri;
+ grpc_resource_quota *resource_quota = NULL;
/* TODO(jboeuf): Cache the jwks_uri in order to avoid this hop next time. */
if (json == NULL) goto error;
@@ -693,9 +698,9 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
jwks_uri += 8;
req.handshaker = &grpc_httpcli_ssl;
req.host = gpr_strdup(jwks_uri);
- req.http.path = strchr(jwks_uri, '/');
+ req.http.path = (char *)strchr(jwks_uri, '/');
if (req.http.path == NULL) {
- req.http.path = "";
+ req.http.path = (char *)"";
} else {
*(req.host + (req.http.path - jwks_uri)) = '\0';
}
@@ -703,11 +708,10 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
channel. This would allow us to cancel an authentication query when under
extreme memory pressure. */
- grpc_resource_quota *resource_quota =
- grpc_resource_quota_create("jwt_verifier");
+ resource_quota = grpc_resource_quota_create("jwt_verifier");
grpc_httpcli_get(
exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req,
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
+ grpc_exec_ctx_now(exec_ctx) + grpc_jwt_verifier_max_delay,
GRPC_CLOSURE_CREATE(on_keys_retrieved, ctx, grpc_schedule_on_exec_ctx),
&ctx->responses[HTTP_RESPONSE_KEYS]);
grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
@@ -760,7 +764,8 @@ const char *grpc_jwt_issuer_email_domain(const char *issuer) {
if (dot == NULL || dot == email_domain) return email_domain;
GPR_ASSERT(dot > email_domain);
/* There may be a subdomain, we just want the domain. */
- dot = gpr_memrchr(email_domain, '.', (size_t)(dot - email_domain));
+ dot = (const char *)gpr_memrchr((void *)email_domain, '.',
+ (size_t)(dot - email_domain));
if (dot == NULL) return email_domain;
return dot + 1;
}
@@ -773,6 +778,7 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
char *path_prefix = NULL;
const char *iss;
grpc_httpcli_request req;
+ grpc_resource_quota *resource_quota = NULL;
memset(&req, 0, sizeof(grpc_httpcli_request));
req.handshaker = &grpc_httpcli_ssl;
http_response_index rsp_idx;
@@ -831,12 +837,11 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
channel. This would allow us to cancel an authentication query when under
extreme memory pressure. */
- grpc_resource_quota *resource_quota =
- grpc_resource_quota_create("jwt_verifier");
- grpc_httpcli_get(
- exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req,
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
- http_cb, &ctx->responses[rsp_idx]);
+ resource_quota = grpc_resource_quota_create("jwt_verifier");
+ grpc_httpcli_get(exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent,
+ resource_quota, &req,
+ grpc_exec_ctx_now(exec_ctx) + grpc_jwt_verifier_max_delay,
+ http_cb, &ctx->responses[rsp_idx]);
grpc_resource_quota_unref_internal(exec_ctx, resource_quota);
gpr_free(req.host);
gpr_free(req.http.path);
@@ -901,12 +906,14 @@ error:
grpc_jwt_verifier *grpc_jwt_verifier_create(
const grpc_jwt_verifier_email_domain_key_url_mapping *mappings,
size_t num_mappings) {
- grpc_jwt_verifier *v = gpr_zalloc(sizeof(grpc_jwt_verifier));
+ grpc_jwt_verifier *v =
+ (grpc_jwt_verifier *)gpr_zalloc(sizeof(grpc_jwt_verifier));
grpc_httpcli_context_init(&v->http_ctx);
/* We know at least of one mapping. */
v->allocated_mappings = 1 + num_mappings;
- v->mappings = gpr_malloc(v->allocated_mappings * sizeof(email_key_mapping));
+ v->mappings = (email_key_mapping *)gpr_malloc(v->allocated_mappings *
+ sizeof(email_key_mapping));
verifier_put_mapping(v, GRPC_GOOGLE_SERVICE_ACCOUNTS_EMAIL_DOMAIN,
GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX);
/* User-Provided mappings. */
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h
index 8fac452d4e..998365e75c 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.h
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h
@@ -32,6 +32,10 @@
#define GRPC_GOOGLE_SERVICE_ACCOUNTS_KEY_URL_PREFIX \
"www.googleapis.com/robot/v1/metadata/x509"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* --- grpc_jwt_verifier_status. --- */
typedef enum {
@@ -81,7 +85,7 @@ typedef struct {
/* Globals to control the verifier. Not thread-safe. */
extern gpr_timespec grpc_jwt_verifier_clock_skew;
-extern gpr_timespec grpc_jwt_verifier_max_delay;
+extern grpc_millis grpc_jwt_verifier_max_delay;
/* The verifier can be created with some custom mappings to help with key
discovery in the case where the issuer is an email address.
@@ -122,4 +126,8 @@ grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
const char *audience);
const char *grpc_jwt_issuer_email_domain(const char *issuer);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H */
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
index 10b270c49c..7867105f56 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
@@ -117,7 +117,7 @@ static void oauth2_token_fetcher_destruct(grpc_exec_ctx *exec_ctx,
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
grpc_exec_ctx *exec_ctx, const grpc_http_response *response,
- grpc_mdelem *token_md, gpr_timespec *token_lifetime) {
+ grpc_mdelem *token_md, grpc_millis *token_lifetime) {
char *null_terminated_body = NULL;
char *new_access_token = NULL;
grpc_credentials_status status = GRPC_CREDENTIALS_OK;
@@ -130,7 +130,7 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
}
if (response->body_length > 0) {
- null_terminated_body = gpr_malloc(response->body_length + 1);
+ null_terminated_body = (char *)gpr_malloc(response->body_length + 1);
null_terminated_body[response->body_length] = '\0';
memcpy(null_terminated_body, response->body, response->body_length);
}
@@ -183,9 +183,7 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response(
}
gpr_asprintf(&new_access_token, "%s %s", token_type->value,
access_token->value);
- token_lifetime->tv_sec = strtol(expires_in->value, NULL, 10);
- token_lifetime->tv_nsec = 0;
- token_lifetime->clock_type = GPR_TIMESPAN;
+ *token_lifetime = strtol(expires_in->value, NULL, 10) * GPR_MS_PER_SEC;
if (!GRPC_MDISNULL(*token_md)) GRPC_MDELEM_UNREF(exec_ctx, *token_md);
*token_md = grpc_mdelem_from_slices(
exec_ctx,
@@ -214,7 +212,7 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
grpc_oauth2_token_fetcher_credentials *c =
(grpc_oauth2_token_fetcher_credentials *)r->creds;
grpc_mdelem access_token_md = GRPC_MDNULL;
- gpr_timespec token_lifetime;
+ grpc_millis token_lifetime;
grpc_credentials_status status =
grpc_oauth2_token_fetcher_credentials_parse_server_response(
exec_ctx, &r->response, &access_token_md, &token_lifetime);
@@ -222,10 +220,9 @@ static void on_oauth2_token_fetcher_http_response(grpc_exec_ctx *exec_ctx,
gpr_mu_lock(&c->mu);
c->token_fetch_pending = false;
c->access_token_md = GRPC_MDELEM_REF(access_token_md);
- c->token_expiration =
- status == GRPC_CREDENTIALS_OK
- ? gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), token_lifetime)
- : gpr_inf_past(GPR_CLOCK_REALTIME);
+ c->token_expiration = status == GRPC_CREDENTIALS_OK
+ ? grpc_exec_ctx_now(exec_ctx) + token_lifetime
+ : 0;
grpc_oauth2_pending_get_request_metadata *pending_request =
c->pending_requests;
c->pending_requests = NULL;
@@ -260,14 +257,12 @@ static bool oauth2_token_fetcher_get_request_metadata(
grpc_oauth2_token_fetcher_credentials *c =
(grpc_oauth2_token_fetcher_credentials *)creds;
// Check if we can use the cached token.
- gpr_timespec refresh_threshold = gpr_time_from_seconds(
- GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN);
+ grpc_millis refresh_threshold =
+ GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS * GPR_MS_PER_SEC;
grpc_mdelem cached_access_token_md = GRPC_MDNULL;
gpr_mu_lock(&c->mu);
if (!GRPC_MDISNULL(c->access_token_md) &&
- (gpr_time_cmp(
- gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_REALTIME)),
- refresh_threshold) > 0)) {
+ (c->token_expiration - grpc_exec_ctx_now(exec_ctx) > refresh_threshold)) {
cached_access_token_md = GRPC_MDELEM_REF(c->access_token_md);
}
if (!GRPC_MDISNULL(cached_access_token_md)) {
@@ -296,10 +291,10 @@ static bool oauth2_token_fetcher_get_request_metadata(
gpr_mu_unlock(&c->mu);
if (start_fetch) {
grpc_call_credentials_ref(creds);
- c->fetch_func(
- exec_ctx, grpc_credentials_metadata_request_create(creds),
- &c->httpcli_context, &c->pollent, on_oauth2_token_fetcher_http_response,
- gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), refresh_threshold));
+ c->fetch_func(exec_ctx, grpc_credentials_metadata_request_create(creds),
+ &c->httpcli_context, &c->pollent,
+ on_oauth2_token_fetcher_http_response,
+ grpc_exec_ctx_now(exec_ctx) + refresh_threshold);
}
return false;
}
@@ -340,7 +335,7 @@ static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c,
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
gpr_ref_init(&c->base.refcount, 1);
gpr_mu_init(&c->mu);
- c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
+ c->token_expiration = 0;
c->fetch_func = fetch_func;
c->pollent =
grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create());
@@ -358,12 +353,12 @@ static grpc_call_credentials_vtable compute_engine_vtable = {
static void compute_engine_fetch_oauth2(
grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
grpc_httpcli_context *httpcli_context, grpc_polling_entity *pollent,
- grpc_iomgr_cb_func response_cb, gpr_timespec deadline) {
- grpc_http_header header = {"Metadata-Flavor", "Google"};
+ grpc_iomgr_cb_func response_cb, grpc_millis deadline) {
+ grpc_http_header header = {(char *)"Metadata-Flavor", (char *)"Google"};
grpc_httpcli_request request;
memset(&request, 0, sizeof(grpc_httpcli_request));
- request.host = GRPC_COMPUTE_ENGINE_METADATA_HOST;
- request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
+ request.host = (char *)GRPC_COMPUTE_ENGINE_METADATA_HOST;
+ request.http.path = (char *)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
request.http.hdr_count = 1;
request.http.hdrs = &header;
/* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
@@ -381,7 +376,8 @@ static void compute_engine_fetch_oauth2(
grpc_call_credentials *grpc_google_compute_engine_credentials_create(
void *reserved) {
grpc_oauth2_token_fetcher_credentials *c =
- gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials));
+ (grpc_oauth2_token_fetcher_credentials *)gpr_malloc(
+ sizeof(grpc_oauth2_token_fetcher_credentials));
GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1,
(reserved));
GPR_ASSERT(reserved == NULL);
@@ -409,19 +405,19 @@ static grpc_call_credentials_vtable refresh_token_vtable = {
static void refresh_token_fetch_oauth2(
grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
grpc_httpcli_context *httpcli_context, grpc_polling_entity *pollent,
- grpc_iomgr_cb_func response_cb, gpr_timespec deadline) {
+ grpc_iomgr_cb_func response_cb, grpc_millis deadline) {
grpc_google_refresh_token_credentials *c =
(grpc_google_refresh_token_credentials *)metadata_req->creds;
- grpc_http_header header = {"Content-Type",
- "application/x-www-form-urlencoded"};
+ grpc_http_header header = {(char *)"Content-Type",
+ (char *)"application/x-www-form-urlencoded"};
grpc_httpcli_request request;
char *body = NULL;
gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
c->refresh_token.client_id, c->refresh_token.client_secret,
c->refresh_token.refresh_token);
memset(&request, 0, sizeof(grpc_httpcli_request));
- request.host = GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
- request.http.path = GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
+ request.host = (char *)GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
+ request.http.path = (char *)GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
request.http.hdr_count = 1;
request.http.hdrs = &header;
request.handshaker = &grpc_httpcli_ssl;
@@ -447,7 +443,8 @@ grpc_refresh_token_credentials_create_from_auth_refresh_token(
gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation");
return NULL;
}
- c = gpr_zalloc(sizeof(grpc_google_refresh_token_credentials));
+ c = (grpc_google_refresh_token_credentials *)gpr_zalloc(
+ sizeof(grpc_google_refresh_token_credentials));
init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2);
c->base.base.vtable = &refresh_token_vtable;
c->refresh_token = refresh_token;
@@ -515,7 +512,8 @@ static grpc_call_credentials_vtable access_token_vtable = {
grpc_call_credentials *grpc_access_token_credentials_create(
const char *access_token, void *reserved) {
grpc_access_token_credentials *c =
- gpr_zalloc(sizeof(grpc_access_token_credentials));
+ (grpc_access_token_credentials *)gpr_zalloc(
+ sizeof(grpc_access_token_credentials));
GRPC_API_TRACE(
"grpc_access_token_credentials_create(access_token=<redacted>, "
"reserved=%p)",
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
index d9ad6691b8..c12db896f3 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
@@ -22,6 +22,10 @@
#include "src/core/lib/json/json.h"
#include "src/core/lib/security/credentials/credentials.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
// auth_refresh_token parsing.
typedef struct {
const char *type;
@@ -57,7 +61,7 @@ typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx,
grpc_httpcli_context *http_context,
grpc_polling_entity *pollent,
grpc_iomgr_cb_func cb,
- gpr_timespec deadline);
+ grpc_millis deadline);
typedef struct grpc_oauth2_pending_get_request_metadata {
grpc_credentials_mdelem_array *md_array;
@@ -70,7 +74,7 @@ typedef struct {
grpc_call_credentials base;
gpr_mu mu;
grpc_mdelem access_token_md;
- gpr_timespec token_expiration;
+ grpc_millis token_expiration;
bool token_fetch_pending;
grpc_oauth2_pending_get_request_metadata *pending_requests;
grpc_httpcli_context httpcli_context;
@@ -100,6 +104,10 @@ grpc_refresh_token_credentials_create_from_auth_refresh_token(
grpc_credentials_status
grpc_oauth2_token_fetcher_credentials_parse_server_response(
grpc_exec_ctx *exec_ctx, const struct grpc_http_response *response,
- grpc_mdelem *token_md, gpr_timespec *token_lifetime);
+ grpc_mdelem *token_md, grpc_millis *token_lifetime);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.c b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
index 73e0c23e0f..8106a730fe 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.c
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
@@ -31,6 +31,9 @@
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/validate_metadata.h"
+grpc_tracer_flag grpc_plugin_credentials_trace =
+ GRPC_TRACER_INITIALIZER(false, "plugin_credentials");
+
static void plugin_destruct(grpc_exec_ctx *exec_ctx,
grpc_call_credentials *creds) {
grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
@@ -53,6 +56,62 @@ static void pending_request_remove_locked(
}
}
+// Checks if the request has been cancelled.
+// If not, removes it from the pending list, so that it cannot be
+// cancelled out from under us.
+// When this returns, r->cancelled indicates whether the request was
+// cancelled before completion.
+static void pending_request_complete(
+ grpc_exec_ctx *exec_ctx, grpc_plugin_credentials_pending_request *r) {
+ gpr_mu_lock(&r->creds->mu);
+ if (!r->cancelled) pending_request_remove_locked(r->creds, r);
+ gpr_mu_unlock(&r->creds->mu);
+ // Ref to credentials not needed anymore.
+ grpc_call_credentials_unref(exec_ctx, &r->creds->base);
+}
+
+static grpc_error *process_plugin_result(
+ grpc_exec_ctx *exec_ctx, grpc_plugin_credentials_pending_request *r,
+ const grpc_metadata *md, size_t num_md, grpc_status_code status,
+ const char *error_details) {
+ grpc_error *error = GRPC_ERROR_NONE;
+ if (status != GRPC_STATUS_OK) {
+ char *msg;
+ gpr_asprintf(&msg, "Getting metadata from plugin failed with error: %s",
+ error_details);
+ error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
+ gpr_free(msg);
+ } else {
+ bool seen_illegal_header = false;
+ for (size_t i = 0; i < num_md; ++i) {
+ if (!GRPC_LOG_IF_ERROR("validate_metadata_from_plugin",
+ grpc_validate_header_key_is_legal(md[i].key))) {
+ seen_illegal_header = true;
+ break;
+ } else if (!grpc_is_binary_header(md[i].key) &&
+ !GRPC_LOG_IF_ERROR(
+ "validate_metadata_from_plugin",
+ grpc_validate_header_nonbin_value_is_legal(md[i].value))) {
+ gpr_log(GPR_ERROR, "Plugin added invalid metadata value.");
+ seen_illegal_header = true;
+ break;
+ }
+ }
+ if (seen_illegal_header) {
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal metadata");
+ } else {
+ for (size_t i = 0; i < num_md; ++i) {
+ grpc_mdelem mdelem = grpc_mdelem_from_slices(
+ exec_ctx, grpc_slice_ref_internal(md[i].key),
+ grpc_slice_ref_internal(md[i].value));
+ grpc_credentials_mdelem_array_add(r->md_array, mdelem);
+ GRPC_MDELEM_UNREF(exec_ctx, mdelem);
+ }
+ }
+ }
+ return error;
+}
+
static void plugin_md_request_metadata_ready(void *request,
const grpc_metadata *md,
size_t num_md,
@@ -64,54 +123,24 @@ static void plugin_md_request_metadata_ready(void *request,
NULL, NULL);
grpc_plugin_credentials_pending_request *r =
(grpc_plugin_credentials_pending_request *)request;
- // Check if the request has been cancelled.
- // If not, remove it from the pending list, so that it cannot be
- // cancelled out from under us.
- gpr_mu_lock(&r->creds->mu);
- if (!r->cancelled) pending_request_remove_locked(r->creds, r);
- gpr_mu_unlock(&r->creds->mu);
- grpc_call_credentials_unref(&exec_ctx, &r->creds->base);
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ gpr_log(GPR_INFO,
+ "plugin_credentials[%p]: request %p: plugin returned "
+ "asynchronously",
+ r->creds, r);
+ }
+ // Remove request from pending list if not previously cancelled.
+ pending_request_complete(&exec_ctx, r);
// If it has not been cancelled, process it.
if (!r->cancelled) {
- if (status != GRPC_STATUS_OK) {
- char *msg;
- gpr_asprintf(&msg, "Getting metadata from plugin failed with error: %s",
- error_details);
- GRPC_CLOSURE_SCHED(&exec_ctx, r->on_request_metadata,
- GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
- gpr_free(msg);
- } else {
- bool seen_illegal_header = false;
- for (size_t i = 0; i < num_md; ++i) {
- if (!GRPC_LOG_IF_ERROR("validate_metadata_from_plugin",
- grpc_validate_header_key_is_legal(md[i].key))) {
- seen_illegal_header = true;
- break;
- } else if (!grpc_is_binary_header(md[i].key) &&
- !GRPC_LOG_IF_ERROR(
- "validate_metadata_from_plugin",
- grpc_validate_header_nonbin_value_is_legal(
- md[i].value))) {
- gpr_log(GPR_ERROR, "Plugin added invalid metadata value.");
- seen_illegal_header = true;
- break;
- }
- }
- if (seen_illegal_header) {
- GRPC_CLOSURE_SCHED(
- &exec_ctx, r->on_request_metadata,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal metadata"));
- } else {
- for (size_t i = 0; i < num_md; ++i) {
- grpc_mdelem mdelem = grpc_mdelem_from_slices(
- &exec_ctx, grpc_slice_ref_internal(md[i].key),
- grpc_slice_ref_internal(md[i].value));
- grpc_credentials_mdelem_array_add(r->md_array, mdelem);
- GRPC_MDELEM_UNREF(&exec_ctx, mdelem);
- }
- GRPC_CLOSURE_SCHED(&exec_ctx, r->on_request_metadata, GRPC_ERROR_NONE);
- }
- }
+ grpc_error *error =
+ process_plugin_result(&exec_ctx, r, md, num_md, status, error_details);
+ GRPC_CLOSURE_SCHED(&exec_ctx, r->on_request_metadata, error);
+ } else if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ gpr_log(GPR_INFO,
+ "plugin_credentials[%p]: request %p: plugin was previously "
+ "cancelled",
+ r->creds, r);
}
gpr_free(r);
grpc_exec_ctx_finish(&exec_ctx);
@@ -125,6 +154,7 @@ static bool plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
grpc_closure *on_request_metadata,
grpc_error **error) {
grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
+ bool retval = true; // Synchronous return.
if (c->plugin.get_metadata != NULL) {
// Create pending_request object.
grpc_plugin_credentials_pending_request *pending_request =
@@ -142,12 +172,60 @@ static bool plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
c->pending_requests = pending_request;
gpr_mu_unlock(&c->mu);
// Invoke the plugin. The callback holds a ref to us.
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: invoking plugin",
+ c, pending_request);
+ }
grpc_call_credentials_ref(creds);
- c->plugin.get_metadata(c->plugin.state, context,
- plugin_md_request_metadata_ready, pending_request);
- return false;
+ grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX];
+ size_t num_creds_md = 0;
+ grpc_status_code status = GRPC_STATUS_OK;
+ const char *error_details = NULL;
+ if (!c->plugin.get_metadata(c->plugin.state, context,
+ plugin_md_request_metadata_ready,
+ pending_request, creds_md, &num_creds_md,
+ &status, &error_details)) {
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ gpr_log(GPR_INFO,
+ "plugin_credentials[%p]: request %p: plugin will return "
+ "asynchronously",
+ c, pending_request);
+ }
+ return false; // Asynchronous return.
+ }
+ // Returned synchronously.
+ // Remove request from pending list if not previously cancelled.
+ pending_request_complete(exec_ctx, pending_request);
+ // If the request was cancelled, the error will have been returned
+ // asynchronously by plugin_cancel_get_request_metadata(), so return
+ // false. Otherwise, process the result.
+ if (pending_request->cancelled) {
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ gpr_log(GPR_INFO,
+ "plugin_credentials[%p]: request %p was cancelled, error "
+ "will be returned asynchronously",
+ c, pending_request);
+ }
+ retval = false;
+ } else {
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ gpr_log(GPR_INFO,
+ "plugin_credentials[%p]: request %p: plugin returned "
+ "synchronously",
+ c, pending_request);
+ }
+ *error = process_plugin_result(exec_ctx, pending_request, creds_md,
+ num_creds_md, status, error_details);
+ }
+ // Clean up.
+ for (size_t i = 0; i < num_creds_md; ++i) {
+ grpc_slice_unref_internal(exec_ctx, creds_md[i].key);
+ grpc_slice_unref_internal(exec_ctx, creds_md[i].value);
+ }
+ gpr_free((void *)error_details);
+ gpr_free(pending_request);
}
- return true;
+ return retval;
}
static void plugin_cancel_get_request_metadata(
@@ -159,6 +237,10 @@ static void plugin_cancel_get_request_metadata(
c->pending_requests;
pending_request != NULL; pending_request = pending_request->next) {
if (pending_request->md_array == md_array) {
+ if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", c,
+ pending_request);
+ }
pending_request->cancelled = true;
GRPC_CLOSURE_SCHED(exec_ctx, pending_request->on_request_metadata,
GRPC_ERROR_REF(error));
@@ -176,7 +258,8 @@ static grpc_call_credentials_vtable plugin_vtable = {
grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
grpc_metadata_credentials_plugin plugin, void *reserved) {
- grpc_plugin_credentials *c = gpr_zalloc(sizeof(*c));
+ grpc_plugin_credentials *c =
+ (grpc_plugin_credentials *)gpr_zalloc(sizeof(*c));
GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1,
(reserved));
GPR_ASSERT(reserved == NULL);
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h
index 57266d589a..f56df9eac5 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.h
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h
@@ -21,6 +21,8 @@
#include "src/core/lib/security/credentials/credentials.h"
+extern grpc_tracer_flag grpc_plugin_credentials_trace;
+
struct grpc_plugin_credentials;
typedef struct grpc_plugin_credentials_pending_request {
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.c b/src/core/lib/security/credentials/ssl/ssl_credentials.c
deleted file mode 100644
index 006db1ec76..0000000000
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
-
-#include <string.h>
-
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/surface/api_trace.h"
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-
-//
-// SSL Channel Credentials.
-//
-
-static void ssl_config_pem_key_cert_pair_destroy(
- tsi_ssl_pem_key_cert_pair *kp) {
- if (kp == NULL) return;
- gpr_free((void *)kp->private_key);
- gpr_free((void *)kp->cert_chain);
-}
-
-static void ssl_destruct(grpc_exec_ctx *exec_ctx,
- grpc_channel_credentials *creds) {
- grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
- gpr_free(c->config.pem_root_certs);
- ssl_config_pem_key_cert_pair_destroy(&c->config.pem_key_cert_pair);
-}
-
-static grpc_security_status ssl_create_security_connector(
- grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
- grpc_call_credentials *call_creds, const char *target,
- const grpc_channel_args *args, grpc_channel_security_connector **sc,
- grpc_channel_args **new_args) {
- grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
- grpc_security_status status = GRPC_SECURITY_OK;
- const char *overridden_target_name = NULL;
- for (size_t i = 0; args && i < args->num_args; i++) {
- grpc_arg *arg = &args->args[i];
- if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
- arg->type == GRPC_ARG_STRING) {
- overridden_target_name = arg->value.string;
- break;
- }
- }
- status = grpc_ssl_channel_security_connector_create(
- exec_ctx, call_creds, &c->config, target, overridden_target_name, sc);
- if (status != GRPC_SECURITY_OK) {
- return status;
- }
- grpc_arg new_arg =
- grpc_channel_arg_string_create(GRPC_ARG_HTTP2_SCHEME, "https");
- *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
- return status;
-}
-
-static grpc_channel_credentials_vtable ssl_vtable = {
- ssl_destruct, ssl_create_security_connector, NULL};
-
-static void ssl_build_config(const char *pem_root_certs,
- grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
- grpc_ssl_config *config) {
- if (pem_root_certs != NULL) {
- config->pem_root_certs = gpr_strdup(pem_root_certs);
- }
- if (pem_key_cert_pair != NULL) {
- GPR_ASSERT(pem_key_cert_pair->private_key != NULL);
- GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL);
- config->pem_key_cert_pair.cert_chain =
- gpr_strdup(pem_key_cert_pair->cert_chain);
- config->pem_key_cert_pair.private_key =
- gpr_strdup(pem_key_cert_pair->private_key);
- }
-}
-
-grpc_channel_credentials *grpc_ssl_credentials_create(
- const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
- void *reserved) {
- grpc_ssl_credentials *c = gpr_zalloc(sizeof(grpc_ssl_credentials));
- GRPC_API_TRACE(
- "grpc_ssl_credentials_create(pem_root_certs=%s, "
- "pem_key_cert_pair=%p, "
- "reserved=%p)",
- 3, (pem_root_certs, pem_key_cert_pair, reserved));
- GPR_ASSERT(reserved == NULL);
- c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
- c->base.vtable = &ssl_vtable;
- gpr_ref_init(&c->base.refcount, 1);
- ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config);
- return &c->base;
-}
-
-//
-// SSL Server Credentials.
-//
-
-static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
- grpc_server_credentials *creds) {
- grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
- size_t i;
- for (i = 0; i < c->config.num_key_cert_pairs; i++) {
- ssl_config_pem_key_cert_pair_destroy(&c->config.pem_key_cert_pairs[i]);
- }
- gpr_free(c->config.pem_key_cert_pairs);
- gpr_free(c->config.pem_root_certs);
-}
-
-static grpc_security_status ssl_server_create_security_connector(
- grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
- grpc_server_security_connector **sc) {
- grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
- return grpc_ssl_server_security_connector_create(exec_ctx, &c->config, sc);
-}
-
-static grpc_server_credentials_vtable ssl_server_vtable = {
- ssl_server_destruct, ssl_server_create_security_connector};
-
-static void ssl_build_server_config(
- const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
- size_t num_key_cert_pairs,
- grpc_ssl_client_certificate_request_type client_certificate_request,
- grpc_ssl_server_config *config) {
- size_t i;
- config->client_certificate_request = client_certificate_request;
- if (pem_root_certs != NULL) {
- config->pem_root_certs = gpr_strdup(pem_root_certs);
- }
- if (num_key_cert_pairs > 0) {
- GPR_ASSERT(pem_key_cert_pairs != NULL);
- config->pem_key_cert_pairs =
- gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair));
- }
- config->num_key_cert_pairs = num_key_cert_pairs;
- for (i = 0; i < num_key_cert_pairs; i++) {
- GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
- GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
- config->pem_key_cert_pairs[i].cert_chain =
- gpr_strdup(pem_key_cert_pairs[i].cert_chain);
- config->pem_key_cert_pairs[i].private_key =
- gpr_strdup(pem_key_cert_pairs[i].private_key);
- }
-}
-
-grpc_server_credentials *grpc_ssl_server_credentials_create(
- const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
- size_t num_key_cert_pairs, int force_client_auth, void *reserved) {
- return grpc_ssl_server_credentials_create_ex(
- pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs,
- force_client_auth
- ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
- : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
- reserved);
-}
-
-grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
- const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
- size_t num_key_cert_pairs,
- grpc_ssl_client_certificate_request_type client_certificate_request,
- void *reserved) {
- grpc_ssl_server_credentials *c =
- gpr_zalloc(sizeof(grpc_ssl_server_credentials));
- GRPC_API_TRACE(
- "grpc_ssl_server_credentials_create_ex("
- "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, "
- "client_certificate_request=%d, reserved=%p)",
- 5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs,
- client_certificate_request, reserved));
- GPR_ASSERT(reserved == NULL);
- c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
- gpr_ref_init(&c->base.refcount, 1);
- c->base.vtable = &ssl_server_vtable;
- ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
- num_key_cert_pairs, client_certificate_request,
- &c->config);
- return &c->base;
-}
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
new file mode 100644
index 0000000000..2085e2b8e7
--- /dev/null
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
@@ -0,0 +1,343 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
+
+#include <string.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/surface/api_trace.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+//
+// SSL Channel Credentials.
+//
+
+void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair *kp,
+ size_t num_key_cert_pairs) {
+ if (kp == NULL) return;
+ for (size_t i = 0; i < num_key_cert_pairs; i++) {
+ gpr_free((void *)kp[i].private_key);
+ gpr_free((void *)kp[i].cert_chain);
+ }
+ gpr_free(kp);
+}
+
+static void ssl_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_channel_credentials *creds) {
+ grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
+ gpr_free(c->config.pem_root_certs);
+ grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pair, 1);
+}
+
+static grpc_security_status ssl_create_security_connector(
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *creds,
+ grpc_call_credentials *call_creds, const char *target,
+ const grpc_channel_args *args, grpc_channel_security_connector **sc,
+ grpc_channel_args **new_args) {
+ grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
+ grpc_security_status status = GRPC_SECURITY_OK;
+ const char *overridden_target_name = NULL;
+ for (size_t i = 0; args && i < args->num_args; i++) {
+ grpc_arg *arg = &args->args[i];
+ if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
+ arg->type == GRPC_ARG_STRING) {
+ overridden_target_name = arg->value.string;
+ break;
+ }
+ }
+ status = grpc_ssl_channel_security_connector_create(
+ exec_ctx, creds, call_creds, &c->config, target, overridden_target_name,
+ sc);
+ if (status != GRPC_SECURITY_OK) {
+ return status;
+ }
+ grpc_arg new_arg = grpc_channel_arg_string_create(
+ (char *)GRPC_ARG_HTTP2_SCHEME, (char *)"https");
+ *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
+ return status;
+}
+
+static grpc_channel_credentials_vtable ssl_vtable = {
+ ssl_destruct, ssl_create_security_connector, NULL};
+
+static void ssl_build_config(const char *pem_root_certs,
+ grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
+ grpc_ssl_config *config) {
+ if (pem_root_certs != NULL) {
+ config->pem_root_certs = gpr_strdup(pem_root_certs);
+ }
+ if (pem_key_cert_pair != NULL) {
+ GPR_ASSERT(pem_key_cert_pair->private_key != NULL);
+ GPR_ASSERT(pem_key_cert_pair->cert_chain != NULL);
+ config->pem_key_cert_pair = (tsi_ssl_pem_key_cert_pair *)gpr_zalloc(
+ sizeof(tsi_ssl_pem_key_cert_pair));
+ config->pem_key_cert_pair->cert_chain =
+ gpr_strdup(pem_key_cert_pair->cert_chain);
+ config->pem_key_cert_pair->private_key =
+ gpr_strdup(pem_key_cert_pair->private_key);
+ }
+}
+
+grpc_channel_credentials *grpc_ssl_credentials_create(
+ const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
+ void *reserved) {
+ grpc_ssl_credentials *c =
+ (grpc_ssl_credentials *)gpr_zalloc(sizeof(grpc_ssl_credentials));
+ GRPC_API_TRACE(
+ "grpc_ssl_credentials_create(pem_root_certs=%s, "
+ "pem_key_cert_pair=%p, "
+ "reserved=%p)",
+ 3, (pem_root_certs, pem_key_cert_pair, reserved));
+ GPR_ASSERT(reserved == NULL);
+ c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
+ c->base.vtable = &ssl_vtable;
+ gpr_ref_init(&c->base.refcount, 1);
+ ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config);
+ return &c->base;
+}
+
+//
+// SSL Server Credentials.
+//
+
+struct grpc_ssl_server_credentials_options {
+ grpc_ssl_client_certificate_request_type client_certificate_request;
+ grpc_ssl_server_certificate_config *certificate_config;
+ grpc_ssl_server_certificate_config_fetcher *certificate_config_fetcher;
+};
+
+static void ssl_server_destruct(grpc_exec_ctx *exec_ctx,
+ grpc_server_credentials *creds) {
+ grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
+ grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pairs,
+ c->config.num_key_cert_pairs);
+ gpr_free(c->config.pem_root_certs);
+}
+
+static grpc_security_status ssl_server_create_security_connector(
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *creds,
+ grpc_server_security_connector **sc) {
+ return grpc_ssl_server_security_connector_create(exec_ctx, creds, sc);
+}
+
+static grpc_server_credentials_vtable ssl_server_vtable = {
+ ssl_server_destruct, ssl_server_create_security_connector};
+
+tsi_ssl_pem_key_cert_pair *grpc_convert_grpc_to_tsi_cert_pairs(
+ const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs) {
+ tsi_ssl_pem_key_cert_pair *tsi_pairs = NULL;
+ if (num_key_cert_pairs > 0) {
+ GPR_ASSERT(pem_key_cert_pairs != NULL);
+ tsi_pairs = (tsi_ssl_pem_key_cert_pair *)gpr_zalloc(
+ num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair));
+ }
+ for (size_t i = 0; i < num_key_cert_pairs; i++) {
+ GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
+ GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
+ tsi_pairs[i].cert_chain = gpr_strdup(pem_key_cert_pairs[i].cert_chain);
+ tsi_pairs[i].private_key = gpr_strdup(pem_key_cert_pairs[i].private_key);
+ }
+ return tsi_pairs;
+}
+
+static void ssl_build_server_config(
+ const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs,
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_config *config) {
+ config->client_certificate_request = client_certificate_request;
+ if (pem_root_certs != NULL) {
+ config->pem_root_certs = gpr_strdup(pem_root_certs);
+ }
+ config->pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
+ pem_key_cert_pairs, num_key_cert_pairs);
+ config->num_key_cert_pairs = num_key_cert_pairs;
+}
+
+grpc_ssl_server_certificate_config *grpc_ssl_server_certificate_config_create(
+ const char *pem_root_certs,
+ const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs) {
+ grpc_ssl_server_certificate_config *config =
+ (grpc_ssl_server_certificate_config *)gpr_zalloc(
+ sizeof(grpc_ssl_server_certificate_config));
+ if (pem_root_certs != NULL) {
+ config->pem_root_certs = gpr_strdup(pem_root_certs);
+ }
+ if (num_key_cert_pairs > 0) {
+ GPR_ASSERT(pem_key_cert_pairs != NULL);
+ config->pem_key_cert_pairs = (grpc_ssl_pem_key_cert_pair *)gpr_zalloc(
+ num_key_cert_pairs * sizeof(grpc_ssl_pem_key_cert_pair));
+ }
+ config->num_key_cert_pairs = num_key_cert_pairs;
+ for (size_t i = 0; i < num_key_cert_pairs; i++) {
+ GPR_ASSERT(pem_key_cert_pairs[i].private_key != NULL);
+ GPR_ASSERT(pem_key_cert_pairs[i].cert_chain != NULL);
+ config->pem_key_cert_pairs[i].cert_chain =
+ gpr_strdup(pem_key_cert_pairs[i].cert_chain);
+ config->pem_key_cert_pairs[i].private_key =
+ gpr_strdup(pem_key_cert_pairs[i].private_key);
+ }
+ return config;
+}
+
+void grpc_ssl_server_certificate_config_destroy(
+ grpc_ssl_server_certificate_config *config) {
+ if (config == NULL) return;
+ for (size_t i = 0; i < config->num_key_cert_pairs; i++) {
+ gpr_free((void *)config->pem_key_cert_pairs[i].private_key);
+ gpr_free((void *)config->pem_key_cert_pairs[i].cert_chain);
+ }
+ gpr_free(config->pem_key_cert_pairs);
+ gpr_free(config->pem_root_certs);
+ gpr_free(config);
+}
+
+grpc_ssl_server_credentials_options *
+grpc_ssl_server_credentials_create_options_using_config(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config *config) {
+ grpc_ssl_server_credentials_options *options = NULL;
+ if (config == NULL) {
+ gpr_log(GPR_ERROR, "Certificate config must not be NULL.");
+ goto done;
+ }
+ options = (grpc_ssl_server_credentials_options *)gpr_zalloc(
+ sizeof(grpc_ssl_server_credentials_options));
+ options->client_certificate_request = client_certificate_request;
+ options->certificate_config = config;
+done:
+ return options;
+}
+
+grpc_ssl_server_credentials_options *
+grpc_ssl_server_credentials_create_options_using_config_fetcher(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config_callback cb, void *user_data) {
+ if (cb == NULL) {
+ gpr_log(GPR_ERROR, "Invalid certificate config callback parameter.");
+ return NULL;
+ }
+
+ grpc_ssl_server_certificate_config_fetcher *fetcher =
+ (grpc_ssl_server_certificate_config_fetcher *)gpr_zalloc(
+ sizeof(grpc_ssl_server_certificate_config_fetcher));
+ fetcher->cb = cb;
+ fetcher->user_data = user_data;
+
+ grpc_ssl_server_credentials_options *options =
+ (grpc_ssl_server_credentials_options *)gpr_zalloc(
+ sizeof(grpc_ssl_server_credentials_options));
+ options->client_certificate_request = client_certificate_request;
+ options->certificate_config_fetcher = fetcher;
+
+ return options;
+}
+
+grpc_server_credentials *grpc_ssl_server_credentials_create(
+ const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs, int force_client_auth, void *reserved) {
+ return grpc_ssl_server_credentials_create_ex(
+ pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs,
+ force_client_auth
+ ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+ : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
+ reserved);
+}
+
+grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
+ const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs,
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ void *reserved) {
+ GRPC_API_TRACE(
+ "grpc_ssl_server_credentials_create_ex("
+ "pem_root_certs=%s, pem_key_cert_pairs=%p, num_key_cert_pairs=%lu, "
+ "client_certificate_request=%d, reserved=%p)",
+ 5, (pem_root_certs, pem_key_cert_pairs, (unsigned long)num_key_cert_pairs,
+ client_certificate_request, reserved));
+ GPR_ASSERT(reserved == NULL);
+
+ grpc_ssl_server_certificate_config *cert_config =
+ grpc_ssl_server_certificate_config_create(
+ pem_root_certs, pem_key_cert_pairs, num_key_cert_pairs);
+ grpc_ssl_server_credentials_options *options =
+ grpc_ssl_server_credentials_create_options_using_config(
+ client_certificate_request, cert_config);
+
+ return grpc_ssl_server_credentials_create_with_options(options);
+}
+
+grpc_server_credentials *grpc_ssl_server_credentials_create_with_options(
+ grpc_ssl_server_credentials_options *options) {
+ grpc_server_credentials *retval = NULL;
+ grpc_ssl_server_credentials *c = NULL;
+
+ if (options == NULL) {
+ gpr_log(GPR_ERROR,
+ "Invalid options trying to create SSL server credentials.");
+ goto done;
+ }
+
+ if (options->certificate_config == NULL &&
+ options->certificate_config_fetcher == NULL) {
+ gpr_log(GPR_ERROR,
+ "SSL server credentials options must specify either "
+ "certificate config or fetcher.");
+ goto done;
+ } else if (options->certificate_config_fetcher != NULL &&
+ options->certificate_config_fetcher->cb == NULL) {
+ gpr_log(GPR_ERROR, "Certificate config fetcher callback must not be NULL.");
+ goto done;
+ }
+
+ c = (grpc_ssl_server_credentials *)gpr_zalloc(
+ sizeof(grpc_ssl_server_credentials));
+ c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
+ gpr_ref_init(&c->base.refcount, 1);
+ c->base.vtable = &ssl_server_vtable;
+
+ if (options->certificate_config_fetcher != NULL) {
+ c->config.client_certificate_request = options->client_certificate_request;
+ c->certificate_config_fetcher = *options->certificate_config_fetcher;
+ } else {
+ ssl_build_server_config(options->certificate_config->pem_root_certs,
+ options->certificate_config->pem_key_cert_pairs,
+ options->certificate_config->num_key_cert_pairs,
+ options->client_certificate_request, &c->config);
+ }
+
+ retval = &c->base;
+
+done:
+ grpc_ssl_server_credentials_options_destroy(options);
+ return retval;
+}
+
+void grpc_ssl_server_credentials_options_destroy(
+ grpc_ssl_server_credentials_options *o) {
+ if (o == NULL) return;
+ gpr_free(o->certificate_config_fetcher);
+ grpc_ssl_server_certificate_config_destroy(o->certificate_config);
+ gpr_free(o);
+}
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h
index b43c656cd7..5542484aae 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.h
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h
@@ -20,14 +20,41 @@
#include "src/core/lib/security/credentials/credentials.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct {
grpc_channel_credentials base;
grpc_ssl_config config;
} grpc_ssl_credentials;
+struct grpc_ssl_server_certificate_config {
+ grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs;
+ size_t num_key_cert_pairs;
+ char *pem_root_certs;
+};
+
+typedef struct {
+ grpc_ssl_server_certificate_config_callback cb;
+ void *user_data;
+} grpc_ssl_server_certificate_config_fetcher;
+
typedef struct {
grpc_server_credentials base;
grpc_ssl_server_config config;
+ grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher;
} grpc_ssl_server_credentials;
+tsi_ssl_pem_key_cert_pair *grpc_convert_grpc_to_tsi_cert_pairs(
+ const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs);
+
+void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair *kp,
+ size_t num_key_cert_pairs);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_SSL_SSL_CREDENTIALS_H */
diff --git a/src/core/lib/security/transport/auth_filters.h b/src/core/lib/security/transport/auth_filters.h
index bd5902a128..ba5df7fe70 100644
--- a/src/core/lib/security/transport/auth_filters.h
+++ b/src/core/lib/security/transport/auth_filters.h
@@ -21,7 +21,15 @@
#include "src/core/lib/channel/channel_stack.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern const grpc_channel_filter grpc_client_auth_filter;
extern const grpc_channel_filter grpc_server_auth_filter;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H */
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.cc
index 531a88434f..a8464dbf9e 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.cc
@@ -39,6 +39,8 @@
/* We can have a per-call credentials. */
typedef struct {
+ grpc_call_stack *owning_call;
+ grpc_call_combiner *call_combiner;
grpc_call_credentials *creds;
bool have_host;
bool have_method;
@@ -49,17 +51,12 @@ typedef struct {
pollset_set so that work can progress when this call wants work to progress
*/
grpc_polling_entity *pollent;
- gpr_atm security_context_set;
- gpr_mu security_context_mu;
grpc_credentials_mdelem_array md_array;
grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
grpc_auth_metadata_context auth_md_context;
- grpc_closure closure;
- // Either 0 (no cancellation and no async operation in flight),
- // a grpc_closure* (if the lowest bit is 0),
- // or a grpc_error* (if the lowest bit is 1).
- gpr_atm cancellation_state;
- grpc_closure cancel_closure;
+ grpc_closure async_result_closure;
+ grpc_closure check_call_host_cancel_closure;
+ grpc_closure get_request_metadata_cancel_closure;
} call_data;
/* We can have a per-channel credentials. */
@@ -68,43 +65,6 @@ typedef struct {
grpc_auth_context *auth_context;
} channel_data;
-static void decode_cancel_state(gpr_atm cancel_state, grpc_closure **func,
- grpc_error **error) {
- // If the lowest bit is 1, the value is a grpc_error*.
- // Otherwise, if non-zdero, the value is a grpc_closure*.
- if (cancel_state & 1) {
- *error = (grpc_error *)(cancel_state & ~(gpr_atm)1);
- } else if (cancel_state != 0) {
- *func = (grpc_closure *)cancel_state;
- }
-}
-
-static gpr_atm encode_cancel_state_error(grpc_error *error) {
- // Set the lowest bit to 1 to indicate that it's an error.
- return (gpr_atm)1 | (gpr_atm)error;
-}
-
-// Returns an error if the call has been cancelled. Otherwise, sets the
-// cancellation function to be called upon cancellation.
-static grpc_error *set_cancel_func(grpc_call_element *elem,
- grpc_iomgr_cb_func func) {
- call_data *calld = (call_data *)elem->call_data;
- // Decode original state.
- gpr_atm original_state = gpr_atm_acq_load(&calld->cancellation_state);
- grpc_error *original_error = GRPC_ERROR_NONE;
- grpc_closure *original_func = NULL;
- decode_cancel_state(original_state, &original_func, &original_error);
- // If error is set, return it.
- if (original_error != GRPC_ERROR_NONE) return GRPC_ERROR_REF(original_error);
- // Otherwise, store func.
- GRPC_CLOSURE_INIT(&calld->cancel_closure, func, elem,
- grpc_schedule_on_exec_ctx);
- GPR_ASSERT(((gpr_atm)&calld->cancel_closure & (gpr_atm)1) == 0);
- gpr_atm_rel_store(&calld->cancellation_state,
- (gpr_atm)&calld->cancel_closure);
- return GRPC_ERROR_NONE;
-}
-
static void reset_auth_metadata_context(
grpc_auth_metadata_context *auth_md_context) {
if (auth_md_context->service_url != NULL) {
@@ -133,8 +93,9 @@ static void add_error(grpc_error **combined, grpc_error *error) {
static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *input_error) {
grpc_transport_stream_op_batch *batch = (grpc_transport_stream_op_batch *)arg;
- grpc_call_element *elem = batch->handler_private.extra_arg;
- call_data *calld = elem->call_data;
+ grpc_call_element *elem =
+ (grpc_call_element *)batch->handler_private.extra_arg;
+ call_data *calld = (call_data *)elem->call_data;
reset_auth_metadata_context(&calld->auth_md_context);
grpc_error *error = GRPC_ERROR_REF(input_error);
if (error == GRPC_ERROR_NONE) {
@@ -153,7 +114,8 @@ static void on_credentials_metadata(grpc_exec_ctx *exec_ctx, void *arg,
} else {
error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_UNAUTHENTICATED);
- grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch, error);
+ grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch, error,
+ calld->call_combiner);
}
}
@@ -191,15 +153,19 @@ static void cancel_get_request_metadata(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_call_element *elem = (grpc_call_element *)arg;
call_data *calld = (call_data *)elem->call_data;
- grpc_call_credentials_cancel_get_request_metadata(
- exec_ctx, calld->creds, &calld->md_array, GRPC_ERROR_REF(error));
+ if (error != GRPC_ERROR_NONE) {
+ grpc_call_credentials_cancel_get_request_metadata(
+ exec_ctx, calld->creds, &calld->md_array, GRPC_ERROR_REF(error));
+ }
+ GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
+ "cancel_get_request_metadata");
}
static void send_security_metadata(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op_batch *batch) {
- call_data *calld = elem->call_data;
- channel_data *chand = elem->channel_data;
+ call_data *calld = (call_data *)elem->call_data;
+ channel_data *chand = (channel_data *)elem->channel_data;
grpc_client_security_context *ctx =
(grpc_client_security_context *)batch->payload
->context[GRPC_CONTEXT_SECURITY]
@@ -223,7 +189,8 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Incompatible credentials set on channel and call."),
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED));
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAUTHENTICATED),
+ calld->call_combiner);
return;
}
} else {
@@ -234,31 +201,34 @@ static void send_security_metadata(grpc_exec_ctx *exec_ctx,
build_auth_metadata_context(&chand->security_connector->base,
chand->auth_context, calld);
- grpc_error *cancel_error = set_cancel_func(elem, cancel_get_request_metadata);
- if (cancel_error != GRPC_ERROR_NONE) {
- grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch,
- cancel_error);
- return;
- }
GPR_ASSERT(calld->pollent != NULL);
- GRPC_CLOSURE_INIT(&calld->closure, on_credentials_metadata, batch,
- grpc_schedule_on_exec_ctx);
+
+ GRPC_CLOSURE_INIT(&calld->async_result_closure, on_credentials_metadata,
+ batch, grpc_schedule_on_exec_ctx);
grpc_error *error = GRPC_ERROR_NONE;
if (grpc_call_credentials_get_request_metadata(
exec_ctx, calld->creds, calld->pollent, calld->auth_md_context,
- &calld->md_array, &calld->closure, &error)) {
+ &calld->md_array, &calld->async_result_closure, &error)) {
// Synchronous return; invoke on_credentials_metadata() directly.
on_credentials_metadata(exec_ctx, batch, error);
GRPC_ERROR_UNREF(error);
+ } else {
+ // Async return; register cancellation closure with call combiner.
+ GRPC_CALL_STACK_REF(calld->owning_call, "cancel_get_request_metadata");
+ grpc_call_combiner_set_notify_on_cancel(
+ exec_ctx, calld->call_combiner,
+ GRPC_CLOSURE_INIT(&calld->get_request_metadata_cancel_closure,
+ cancel_get_request_metadata, elem,
+ grpc_schedule_on_exec_ctx));
}
}
static void on_host_checked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_transport_stream_op_batch *batch = (grpc_transport_stream_op_batch *)arg;
- grpc_call_element *elem = batch->handler_private.extra_arg;
- call_data *calld = elem->call_data;
-
+ grpc_call_element *elem =
+ (grpc_call_element *)batch->handler_private.extra_arg;
+ call_data *calld = (call_data *)elem->call_data;
if (error == GRPC_ERROR_NONE) {
send_security_metadata(exec_ctx, elem, batch);
} else {
@@ -271,7 +241,8 @@ static void on_host_checked(grpc_exec_ctx *exec_ctx, void *arg,
exec_ctx, batch,
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg),
GRPC_ERROR_INT_GRPC_STATUS,
- GRPC_STATUS_UNAUTHENTICATED));
+ GRPC_STATUS_UNAUTHENTICATED),
+ calld->call_combiner);
gpr_free(error_msg);
}
}
@@ -281,9 +252,12 @@ static void cancel_check_call_host(grpc_exec_ctx *exec_ctx, void *arg,
grpc_call_element *elem = (grpc_call_element *)arg;
call_data *calld = (call_data *)elem->call_data;
channel_data *chand = (channel_data *)elem->channel_data;
- grpc_channel_security_connector_cancel_check_call_host(
- exec_ctx, chand->security_connector, &calld->closure,
- GRPC_ERROR_REF(error));
+ if (error != GRPC_ERROR_NONE) {
+ grpc_channel_security_connector_cancel_check_call_host(
+ exec_ctx, chand->security_connector, &calld->async_result_closure,
+ GRPC_ERROR_REF(error));
+ }
+ GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "cancel_check_call_host");
}
static void auth_start_transport_stream_op_batch(
@@ -292,55 +266,24 @@ static void auth_start_transport_stream_op_batch(
GPR_TIMER_BEGIN("auth_start_transport_stream_op_batch", 0);
/* grab pointers to our data from the call element */
- call_data *calld = elem->call_data;
- channel_data *chand = elem->channel_data;
-
- if (batch->cancel_stream) {
- while (true) {
- // Decode the original cancellation state.
- gpr_atm original_state = gpr_atm_acq_load(&calld->cancellation_state);
- grpc_error *cancel_error = GRPC_ERROR_NONE;
- grpc_closure *func = NULL;
- decode_cancel_state(original_state, &func, &cancel_error);
- // If we had already set a cancellation error, there's nothing
- // more to do.
- if (cancel_error != GRPC_ERROR_NONE) break;
- // If there's a cancel func, call it.
- // Note that even if the cancel func has been changed by some
- // other thread between when we decoded it and now, it will just
- // be a no-op.
- cancel_error = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
- if (func != NULL) {
- GRPC_CLOSURE_SCHED(exec_ctx, func, GRPC_ERROR_REF(cancel_error));
- }
- // Encode the new error into cancellation state.
- if (gpr_atm_full_cas(&calld->cancellation_state, original_state,
- encode_cancel_state_error(cancel_error))) {
- break; // Success.
- }
- // The cas failed, so try again.
- }
- } else {
- /* double checked lock over security context to ensure it's set once */
- if (gpr_atm_acq_load(&calld->security_context_set) == 0) {
- gpr_mu_lock(&calld->security_context_mu);
- if (gpr_atm_acq_load(&calld->security_context_set) == 0) {
- GPR_ASSERT(batch->payload->context != NULL);
- if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == NULL) {
- batch->payload->context[GRPC_CONTEXT_SECURITY].value =
- grpc_client_security_context_create();
- batch->payload->context[GRPC_CONTEXT_SECURITY].destroy =
- grpc_client_security_context_destroy;
- }
- grpc_client_security_context *sec_ctx =
- batch->payload->context[GRPC_CONTEXT_SECURITY].value;
- GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
- sec_ctx->auth_context =
- GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter");
- gpr_atm_rel_store(&calld->security_context_set, 1);
- }
- gpr_mu_unlock(&calld->security_context_mu);
+ call_data *calld = (call_data *)elem->call_data;
+ channel_data *chand = (channel_data *)elem->channel_data;
+
+ if (!batch->cancel_stream) {
+ GPR_ASSERT(batch->payload->context != NULL);
+ if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == NULL) {
+ batch->payload->context[GRPC_CONTEXT_SECURITY].value =
+ grpc_client_security_context_create();
+ batch->payload->context[GRPC_CONTEXT_SECURITY].destroy =
+ grpc_client_security_context_destroy;
}
+ grpc_client_security_context *sec_ctx =
+ (grpc_client_security_context *)batch->payload
+ ->context[GRPC_CONTEXT_SECURITY]
+ .value;
+ GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
+ sec_ctx->auth_context =
+ GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter");
}
if (batch->send_initial_metadata) {
@@ -365,26 +308,27 @@ static void auth_start_transport_stream_op_batch(
}
}
if (calld->have_host) {
- grpc_error *cancel_error = set_cancel_func(elem, cancel_check_call_host);
- if (cancel_error != GRPC_ERROR_NONE) {
- grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, batch,
- cancel_error);
+ batch->handler_private.extra_arg = elem;
+ GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch,
+ grpc_schedule_on_exec_ctx);
+ char *call_host = grpc_slice_to_c_string(calld->host);
+ grpc_error *error = GRPC_ERROR_NONE;
+ if (grpc_channel_security_connector_check_call_host(
+ exec_ctx, chand->security_connector, call_host,
+ chand->auth_context, &calld->async_result_closure, &error)) {
+ // Synchronous return; invoke on_host_checked() directly.
+ on_host_checked(exec_ctx, batch, error);
+ GRPC_ERROR_UNREF(error);
} else {
- char *call_host = grpc_slice_to_c_string(calld->host);
- batch->handler_private.extra_arg = elem;
- grpc_error *error = GRPC_ERROR_NONE;
- if (grpc_channel_security_connector_check_call_host(
- exec_ctx, chand->security_connector, call_host,
- chand->auth_context,
- GRPC_CLOSURE_INIT(&calld->closure, on_host_checked, batch,
- grpc_schedule_on_exec_ctx),
- &error)) {
- // Synchronous return; invoke on_host_checked() directly.
- on_host_checked(exec_ctx, batch, error);
- GRPC_ERROR_UNREF(error);
- }
- gpr_free(call_host);
+ // Async return; register cancellation closure with call combiner.
+ GRPC_CALL_STACK_REF(calld->owning_call, "cancel_check_call_host");
+ grpc_call_combiner_set_notify_on_cancel(
+ exec_ctx, calld->call_combiner,
+ GRPC_CLOSURE_INIT(&calld->check_call_host_cancel_closure,
+ cancel_check_call_host, elem,
+ grpc_schedule_on_exec_ctx));
}
+ gpr_free(call_host);
GPR_TIMER_END("auth_start_transport_stream_op_batch", 0);
return; /* early exit */
}
@@ -399,16 +343,16 @@ static void auth_start_transport_stream_op_batch(
static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
const grpc_call_element_args *args) {
- call_data *calld = elem->call_data;
- memset(calld, 0, sizeof(*calld));
- gpr_mu_init(&calld->security_context_mu);
+ call_data *calld = (call_data *)elem->call_data;
+ calld->owning_call = args->call_stack;
+ calld->call_combiner = args->call_combiner;
return GRPC_ERROR_NONE;
}
static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_polling_entity *pollent) {
- call_data *calld = elem->call_data;
+ call_data *calld = (call_data *)elem->call_data;
calld->pollent = pollent;
}
@@ -416,7 +360,7 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info,
grpc_closure *ignored) {
- call_data *calld = elem->call_data;
+ call_data *calld = (call_data *)elem->call_data;
grpc_credentials_mdelem_array_destroy(exec_ctx, &calld->md_array);
grpc_call_credentials_unref(exec_ctx, calld->creds);
if (calld->have_host) {
@@ -426,12 +370,6 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_slice_unref_internal(exec_ctx, calld->method);
}
reset_auth_metadata_context(&calld->auth_md_context);
- gpr_mu_destroy(&calld->security_context_mu);
- gpr_atm cancel_state = gpr_atm_acq_load(&calld->cancellation_state);
- grpc_error *cancel_error = GRPC_ERROR_NONE;
- grpc_closure *cancel_func = NULL;
- decode_cancel_state(cancel_state, &cancel_func, &cancel_error);
- GRPC_ERROR_UNREF(cancel_error);
}
/* Constructor for channel_data */
@@ -452,7 +390,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
}
/* grab pointers to our data from the channel element */
- channel_data *chand = elem->channel_data;
+ channel_data *chand = (channel_data *)elem->channel_data;
/* The first and the last filters tend to be implemented differently to
handle the case that there's no 'next' filter to call on the up or down
@@ -472,7 +410,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */
- channel_data *chand = elem->channel_data;
+ channel_data *chand = (channel_data *)elem->channel_data;
grpc_channel_security_connector *sc = chand->security_connector;
if (sc != NULL) {
GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, &sc->base, "client_auth_filter");
@@ -490,6 +428,5 @@ const grpc_channel_filter grpc_client_auth_filter = {
sizeof(channel_data),
init_channel_elem,
destroy_channel_elem,
- grpc_call_next_get_peer,
grpc_channel_next_get_info,
"client-auth"};
diff --git a/src/core/lib/security/transport/lb_targets_info.c b/src/core/lib/security/transport/lb_targets_info.cc
index 5583a4e0ff..947fc1addf 100644
--- a/src/core/lib/security/transport/lb_targets_info.c
+++ b/src/core/lib/security/transport/lb_targets_info.cc
@@ -25,19 +25,22 @@
* secure naming purposes. */
#define GRPC_ARG_LB_SECURE_NAMING_MAP "grpc.lb_secure_naming_map"
-static void *targets_info_copy(void *p) { return grpc_slice_hash_table_ref(p); }
+static void *targets_info_copy(void *p) {
+ return grpc_slice_hash_table_ref((grpc_slice_hash_table *)p);
+}
static void targets_info_destroy(grpc_exec_ctx *exec_ctx, void *p) {
- grpc_slice_hash_table_unref(exec_ctx, p);
+ grpc_slice_hash_table_unref(exec_ctx, (grpc_slice_hash_table *)p);
}
static int targets_info_cmp(void *a, void *b) {
- return grpc_slice_hash_table_cmp(a, b);
+ return grpc_slice_hash_table_cmp((const grpc_slice_hash_table *)a,
+ (const grpc_slice_hash_table *)b);
}
static const grpc_arg_pointer_vtable server_to_balancer_names_vtable = {
targets_info_copy, targets_info_destroy, targets_info_cmp};
grpc_arg grpc_lb_targets_info_create_channel_arg(
grpc_slice_hash_table *targets_info) {
- return grpc_channel_arg_pointer_create(GRPC_ARG_LB_SECURE_NAMING_MAP,
+ return grpc_channel_arg_pointer_create((char *)GRPC_ARG_LB_SECURE_NAMING_MAP,
targets_info,
&server_to_balancer_names_vtable);
}
@@ -48,7 +51,7 @@ grpc_slice_hash_table *grpc_lb_targets_info_find_in_args(
grpc_channel_args_find(args, GRPC_ARG_LB_SECURE_NAMING_MAP);
if (targets_info_arg != NULL) {
GPR_ASSERT(targets_info_arg->type == GRPC_ARG_POINTER);
- return targets_info_arg->value.pointer.p;
+ return (grpc_slice_hash_table *)targets_info_arg->value.pointer.p;
}
return NULL;
}
diff --git a/src/core/lib/security/transport/lb_targets_info.h b/src/core/lib/security/transport/lb_targets_info.h
index c3d685df5f..43f0e64556 100644
--- a/src/core/lib/security/transport/lb_targets_info.h
+++ b/src/core/lib/security/transport/lb_targets_info.h
@@ -21,6 +21,10 @@
#include "src/core/lib/slice/slice_hash_table.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** Return a channel argument containing \a targets_info. */
grpc_arg grpc_lb_targets_info_create_channel_arg(
grpc_slice_hash_table *targets_info);
@@ -29,4 +33,8 @@ grpc_arg grpc_lb_targets_info_create_channel_arg(
grpc_slice_hash_table *grpc_lb_targets_info_find_in_args(
const grpc_channel_args *args);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H */
diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.cc
index 5e41b94ff8..859d04ae5a 100644
--- a/src/core/lib/security/transport/secure_endpoint.c
+++ b/src/core/lib/security/transport/secure_endpoint.cc
@@ -34,7 +34,7 @@
#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/tsi/transport_security_interface.h"
+#include "src/core/tsi/transport_security_grpc.h"
#define STAGING_BUFFER_SIZE 8192
@@ -42,6 +42,7 @@ typedef struct {
grpc_endpoint base;
grpc_endpoint *wrapped_ep;
struct tsi_frame_protector *protector;
+ struct tsi_zero_copy_grpc_protector *zero_copy_protector;
gpr_mu protector_mu;
/* saved upper level callbacks and user_data. */
grpc_closure *read_cb;
@@ -67,6 +68,7 @@ static void destroy(grpc_exec_ctx *exec_ctx, secure_endpoint *secure_ep) {
secure_endpoint *ep = secure_ep;
grpc_endpoint_destroy(exec_ctx, ep->wrapped_ep);
tsi_frame_protector_destroy(ep->protector);
+ tsi_zero_copy_grpc_protector_destroy(exec_ctx, ep->zero_copy_protector);
grpc_slice_buffer_destroy_internal(exec_ctx, &ep->leftover_bytes);
grpc_slice_unref_internal(exec_ctx, ep->read_staging_buffer);
grpc_slice_unref_internal(exec_ctx, ep->write_staging_buffer);
@@ -159,51 +161,58 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *user_data,
return;
}
- /* TODO(yangg) check error, maybe bail out early */
- for (i = 0; i < ep->source_buffer.count; i++) {
- grpc_slice encrypted = ep->source_buffer.slices[i];
- uint8_t *message_bytes = GRPC_SLICE_START_PTR(encrypted);
- size_t message_size = GRPC_SLICE_LENGTH(encrypted);
-
- while (message_size > 0 || keep_looping) {
- size_t unprotected_buffer_size_written = (size_t)(end - cur);
- size_t processed_message_size = message_size;
- gpr_mu_lock(&ep->protector_mu);
- result = tsi_frame_protector_unprotect(ep->protector, message_bytes,
- &processed_message_size, cur,
- &unprotected_buffer_size_written);
- gpr_mu_unlock(&ep->protector_mu);
- if (result != TSI_OK) {
- gpr_log(GPR_ERROR, "Decryption error: %s",
- tsi_result_to_string(result));
- break;
- }
- message_bytes += processed_message_size;
- message_size -= processed_message_size;
- cur += unprotected_buffer_size_written;
-
- if (cur == end) {
- flush_read_staging_buffer(ep, &cur, &end);
- /* Force to enter the loop again to extract buffered bytes in protector.
- The bytes could be buffered because of running out of staging_buffer.
- If this happens at the end of all slices, doing another unprotect
- avoids leaving data in the protector. */
- keep_looping = 1;
- } else if (unprotected_buffer_size_written > 0) {
- keep_looping = 1;
- } else {
- keep_looping = 0;
+ if (ep->zero_copy_protector != NULL) {
+ // Use zero-copy grpc protector to unprotect.
+ result = tsi_zero_copy_grpc_protector_unprotect(
+ exec_ctx, ep->zero_copy_protector, &ep->source_buffer, ep->read_buffer);
+ } else {
+ // Use frame protector to unprotect.
+ /* TODO(yangg) check error, maybe bail out early */
+ for (i = 0; i < ep->source_buffer.count; i++) {
+ grpc_slice encrypted = ep->source_buffer.slices[i];
+ uint8_t *message_bytes = GRPC_SLICE_START_PTR(encrypted);
+ size_t message_size = GRPC_SLICE_LENGTH(encrypted);
+
+ while (message_size > 0 || keep_looping) {
+ size_t unprotected_buffer_size_written = (size_t)(end - cur);
+ size_t processed_message_size = message_size;
+ gpr_mu_lock(&ep->protector_mu);
+ result = tsi_frame_protector_unprotect(
+ ep->protector, message_bytes, &processed_message_size, cur,
+ &unprotected_buffer_size_written);
+ gpr_mu_unlock(&ep->protector_mu);
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Decryption error: %s",
+ tsi_result_to_string(result));
+ break;
+ }
+ message_bytes += processed_message_size;
+ message_size -= processed_message_size;
+ cur += unprotected_buffer_size_written;
+
+ if (cur == end) {
+ flush_read_staging_buffer(ep, &cur, &end);
+ /* Force to enter the loop again to extract buffered bytes in
+ protector. The bytes could be buffered because of running out of
+ staging_buffer. If this happens at the end of all slices, doing
+ another unprotect avoids leaving data in the protector. */
+ keep_looping = 1;
+ } else if (unprotected_buffer_size_written > 0) {
+ keep_looping = 1;
+ } else {
+ keep_looping = 0;
+ }
}
+ if (result != TSI_OK) break;
}
- if (result != TSI_OK) break;
- }
- if (cur != GRPC_SLICE_START_PTR(ep->read_staging_buffer)) {
- grpc_slice_buffer_add(
- ep->read_buffer,
- grpc_slice_split_head(
- &ep->read_staging_buffer,
- (size_t)(cur - GRPC_SLICE_START_PTR(ep->read_staging_buffer))));
+ if (cur != GRPC_SLICE_START_PTR(ep->read_staging_buffer)) {
+ grpc_slice_buffer_add(
+ ep->read_buffer,
+ grpc_slice_split_head(
+ &ep->read_staging_buffer,
+ (size_t)(cur - GRPC_SLICE_START_PTR(ep->read_staging_buffer))));
+ }
}
/* TODO(yangg) experiment with moving this block after read_cb to see if it
@@ -270,54 +279,62 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep,
}
}
- for (i = 0; i < slices->count; i++) {
- grpc_slice plain = slices->slices[i];
- uint8_t *message_bytes = GRPC_SLICE_START_PTR(plain);
- size_t message_size = GRPC_SLICE_LENGTH(plain);
- while (message_size > 0) {
- size_t protected_buffer_size_to_send = (size_t)(end - cur);
- size_t processed_message_size = message_size;
- gpr_mu_lock(&ep->protector_mu);
- result = tsi_frame_protector_protect(ep->protector, message_bytes,
- &processed_message_size, cur,
- &protected_buffer_size_to_send);
- gpr_mu_unlock(&ep->protector_mu);
- if (result != TSI_OK) {
- gpr_log(GPR_ERROR, "Encryption error: %s",
- tsi_result_to_string(result));
- break;
- }
- message_bytes += processed_message_size;
- message_size -= processed_message_size;
- cur += protected_buffer_size_to_send;
-
- if (cur == end) {
- flush_write_staging_buffer(ep, &cur, &end);
+ if (ep->zero_copy_protector != NULL) {
+ // Use zero-copy grpc protector to protect.
+ result = tsi_zero_copy_grpc_protector_protect(
+ exec_ctx, ep->zero_copy_protector, slices, &ep->output_buffer);
+ } else {
+ // Use frame protector to protect.
+ for (i = 0; i < slices->count; i++) {
+ grpc_slice plain = slices->slices[i];
+ uint8_t *message_bytes = GRPC_SLICE_START_PTR(plain);
+ size_t message_size = GRPC_SLICE_LENGTH(plain);
+ while (message_size > 0) {
+ size_t protected_buffer_size_to_send = (size_t)(end - cur);
+ size_t processed_message_size = message_size;
+ gpr_mu_lock(&ep->protector_mu);
+ result = tsi_frame_protector_protect(ep->protector, message_bytes,
+ &processed_message_size, cur,
+ &protected_buffer_size_to_send);
+ gpr_mu_unlock(&ep->protector_mu);
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Encryption error: %s",
+ tsi_result_to_string(result));
+ break;
+ }
+ message_bytes += processed_message_size;
+ message_size -= processed_message_size;
+ cur += protected_buffer_size_to_send;
+
+ if (cur == end) {
+ flush_write_staging_buffer(ep, &cur, &end);
+ }
}
- }
- if (result != TSI_OK) break;
- }
- if (result == TSI_OK) {
- size_t still_pending_size;
- do {
- size_t protected_buffer_size_to_send = (size_t)(end - cur);
- gpr_mu_lock(&ep->protector_mu);
- result = tsi_frame_protector_protect_flush(ep->protector, cur,
- &protected_buffer_size_to_send,
- &still_pending_size);
- gpr_mu_unlock(&ep->protector_mu);
if (result != TSI_OK) break;
- cur += protected_buffer_size_to_send;
- if (cur == end) {
- flush_write_staging_buffer(ep, &cur, &end);
+ }
+ if (result == TSI_OK) {
+ size_t still_pending_size;
+ do {
+ size_t protected_buffer_size_to_send = (size_t)(end - cur);
+ gpr_mu_lock(&ep->protector_mu);
+ result = tsi_frame_protector_protect_flush(
+ ep->protector, cur, &protected_buffer_size_to_send,
+ &still_pending_size);
+ gpr_mu_unlock(&ep->protector_mu);
+ if (result != TSI_OK) break;
+ cur += protected_buffer_size_to_send;
+ if (cur == end) {
+ flush_write_staging_buffer(ep, &cur, &end);
+ }
+ } while (still_pending_size > 0);
+ if (cur != GRPC_SLICE_START_PTR(ep->write_staging_buffer)) {
+ grpc_slice_buffer_add(
+ &ep->output_buffer,
+ grpc_slice_split_head(
+ &ep->write_staging_buffer,
+ (size_t)(cur -
+ GRPC_SLICE_START_PTR(ep->write_staging_buffer))));
}
- } while (still_pending_size > 0);
- if (cur != GRPC_SLICE_START_PTR(ep->write_staging_buffer)) {
- grpc_slice_buffer_add(
- &ep->output_buffer,
- grpc_slice_split_head(
- &ep->write_staging_buffer,
- (size_t)(cur - GRPC_SLICE_START_PTR(ep->write_staging_buffer))));
}
}
@@ -362,6 +379,13 @@ static void endpoint_add_to_pollset_set(grpc_exec_ctx *exec_ctx,
grpc_endpoint_add_to_pollset_set(exec_ctx, ep->wrapped_ep, pollset_set);
}
+static void endpoint_delete_from_pollset_set(grpc_exec_ctx *exec_ctx,
+ grpc_endpoint *secure_ep,
+ grpc_pollset_set *pollset_set) {
+ secure_endpoint *ep = (secure_endpoint *)secure_ep;
+ grpc_endpoint_delete_from_pollset_set(exec_ctx, ep->wrapped_ep, pollset_set);
+}
+
static char *endpoint_get_peer(grpc_endpoint *secure_ep) {
secure_endpoint *ep = (secure_endpoint *)secure_ep;
return grpc_endpoint_get_peer(ep->wrapped_ep);
@@ -382,6 +406,7 @@ static const grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_write,
endpoint_add_to_pollset,
endpoint_add_to_pollset_set,
+ endpoint_delete_from_pollset_set,
endpoint_shutdown,
endpoint_destroy,
endpoint_get_resource_user,
@@ -389,13 +414,16 @@ static const grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_get_fd};
grpc_endpoint *grpc_secure_endpoint_create(
- struct tsi_frame_protector *protector, grpc_endpoint *transport,
- grpc_slice *leftover_slices, size_t leftover_nslices) {
+ struct tsi_frame_protector *protector,
+ struct tsi_zero_copy_grpc_protector *zero_copy_protector,
+ grpc_endpoint *transport, grpc_slice *leftover_slices,
+ size_t leftover_nslices) {
size_t i;
secure_endpoint *ep = (secure_endpoint *)gpr_malloc(sizeof(secure_endpoint));
ep->base.vtable = &vtable;
ep->wrapped_ep = transport;
ep->protector = protector;
+ ep->zero_copy_protector = zero_copy_protector;
grpc_slice_buffer_init(&ep->leftover_bytes);
for (i = 0; i < leftover_nslices; i++) {
grpc_slice_buffer_add(&ep->leftover_bytes,
diff --git a/src/core/lib/security/transport/secure_endpoint.h b/src/core/lib/security/transport/secure_endpoint.h
index 1c5555f3df..980449c03e 100644
--- a/src/core/lib/security/transport/secure_endpoint.h
+++ b/src/core/lib/security/transport/secure_endpoint.h
@@ -22,13 +22,26 @@
#include <grpc/slice.h>
#include "src/core/lib/iomgr/endpoint.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct tsi_frame_protector;
+struct tsi_zero_copy_grpc_protector;
extern grpc_tracer_flag grpc_trace_secure_endpoint;
-/* Takes ownership of protector and to_wrap, and refs leftover_slices. */
+/* Takes ownership of protector, zero_copy_protector, and to_wrap, and refs
+ * leftover_slices. If zero_copy_protector is not NULL, protector will never be
+ * used. */
grpc_endpoint *grpc_secure_endpoint_create(
- struct tsi_frame_protector *protector, grpc_endpoint *to_wrap,
- grpc_slice *leftover_slices, size_t leftover_nslices);
+ struct tsi_frame_protector *protector,
+ struct tsi_zero_copy_grpc_protector *zero_copy_protector,
+ grpc_endpoint *to_wrap, grpc_slice *leftover_slices,
+ size_t leftover_nslices);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURE_ENDPOINT_H */
diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.cc
index a7568b995f..06160d0caa 100644
--- a/src/core/lib/security/transport/security_connector.c
+++ b/src/core/lib/security/transport/security_connector.cc
@@ -34,6 +34,7 @@
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/security_handshaker.h"
@@ -136,6 +137,39 @@ void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
}
}
+int grpc_security_connector_cmp(grpc_security_connector *sc,
+ grpc_security_connector *other) {
+ if (sc == NULL || other == NULL) return GPR_ICMP(sc, other);
+ int c = GPR_ICMP(sc->vtable, other->vtable);
+ if (c != 0) return c;
+ return sc->vtable->cmp(sc, other);
+}
+
+int grpc_channel_security_connector_cmp(grpc_channel_security_connector *sc1,
+ grpc_channel_security_connector *sc2) {
+ GPR_ASSERT(sc1->channel_creds != NULL);
+ GPR_ASSERT(sc2->channel_creds != NULL);
+ int c = GPR_ICMP(sc1->channel_creds, sc2->channel_creds);
+ if (c != 0) return c;
+ c = GPR_ICMP(sc1->request_metadata_creds, sc2->request_metadata_creds);
+ if (c != 0) return c;
+ c = GPR_ICMP((void *)sc1->check_call_host, (void *)sc2->check_call_host);
+ if (c != 0) return c;
+ c = GPR_ICMP((void *)sc1->cancel_check_call_host,
+ (void *)sc2->cancel_check_call_host);
+ if (c != 0) return c;
+ return GPR_ICMP((void *)sc1->add_handshakers, (void *)sc2->add_handshakers);
+}
+
+int grpc_server_security_connector_cmp(grpc_server_security_connector *sc1,
+ grpc_server_security_connector *sc2) {
+ GPR_ASSERT(sc1->server_creds != NULL);
+ GPR_ASSERT(sc2->server_creds != NULL);
+ int c = GPR_ICMP(sc1->server_creds, sc2->server_creds);
+ if (c != 0) return c;
+ return GPR_ICMP((void *)sc1->add_handshakers, (void *)sc2->add_handshakers);
+}
+
bool grpc_channel_security_connector_check_call_host(
grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
const char *host, grpc_auth_context *auth_context,
@@ -199,23 +233,27 @@ void grpc_security_connector_unref(grpc_exec_ctx *exec_ctx,
if (gpr_unref(&sc->refcount)) sc->vtable->destroy(exec_ctx, sc);
}
-static void connector_pointer_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
- GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, p, "connector_pointer_arg_destroy");
+static void connector_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
+ GRPC_SECURITY_CONNECTOR_UNREF(exec_ctx, (grpc_security_connector *)p,
+ "connector_arg_destroy");
}
-static void *connector_pointer_arg_copy(void *p) {
- return GRPC_SECURITY_CONNECTOR_REF(p, "connector_pointer_arg_copy");
+static void *connector_arg_copy(void *p) {
+ return GRPC_SECURITY_CONNECTOR_REF((grpc_security_connector *)p,
+ "connector_arg_copy");
}
-static int connector_pointer_cmp(void *a, void *b) { return GPR_ICMP(a, b); }
+static int connector_cmp(void *a, void *b) {
+ return grpc_security_connector_cmp((grpc_security_connector *)a,
+ (grpc_security_connector *)b);
+}
-static const grpc_arg_pointer_vtable connector_pointer_vtable = {
- connector_pointer_arg_copy, connector_pointer_arg_destroy,
- connector_pointer_cmp};
+static const grpc_arg_pointer_vtable connector_arg_vtable = {
+ connector_arg_copy, connector_arg_destroy, connector_cmp};
grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) {
- return grpc_channel_arg_pointer_create(GRPC_ARG_SECURITY_CONNECTOR, sc,
- &connector_pointer_vtable);
+ return grpc_channel_arg_pointer_create((char *)GRPC_ARG_SECURITY_CONNECTOR,
+ sc, &connector_arg_vtable);
}
grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) {
@@ -225,7 +263,7 @@ grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) {
GRPC_ARG_SECURITY_CONNECTOR);
return NULL;
}
- return arg->value.pointer.p;
+ return (grpc_security_connector *)arg->value.pointer.p;
}
grpc_security_connector *grpc_security_connector_find_in_args(
@@ -240,6 +278,30 @@ grpc_security_connector *grpc_security_connector_find_in_args(
return NULL;
}
+static tsi_client_certificate_request_type
+get_tsi_client_certificate_request_type(
+ grpc_ssl_client_certificate_request_type grpc_request_type) {
+ switch (grpc_request_type) {
+ case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
+ return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
+
+ case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+ return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
+
+ case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
+ return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
+
+ case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+ return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
+
+ case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
+ return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
+
+ default:
+ return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
+ }
+}
+
/* -- Fake implementation. -- */
typedef struct {
@@ -380,6 +442,32 @@ static void fake_server_check_peer(grpc_exec_ctx *exec_ctx,
fake_check_peer(exec_ctx, sc, peer, auth_context, on_peer_checked);
}
+static int fake_channel_cmp(grpc_security_connector *sc1,
+ grpc_security_connector *sc2) {
+ grpc_fake_channel_security_connector *c1 =
+ (grpc_fake_channel_security_connector *)sc1;
+ grpc_fake_channel_security_connector *c2 =
+ (grpc_fake_channel_security_connector *)sc2;
+ int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
+ if (c != 0) return c;
+ c = strcmp(c1->target, c2->target);
+ if (c != 0) return c;
+ if (c1->expected_targets == NULL || c2->expected_targets == NULL) {
+ c = GPR_ICMP(c1->expected_targets, c2->expected_targets);
+ } else {
+ c = strcmp(c1->expected_targets, c2->expected_targets);
+ }
+ if (c != 0) return c;
+ return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel);
+}
+
+static int fake_server_cmp(grpc_security_connector *sc1,
+ grpc_security_connector *sc2) {
+ return grpc_server_security_connector_cmp(
+ (grpc_server_security_connector *)sc1,
+ (grpc_server_security_connector *)sc2);
+}
+
static bool fake_channel_check_call_host(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc,
const char *host,
@@ -416,18 +504,21 @@ static void fake_server_add_handshakers(grpc_exec_ctx *exec_ctx,
}
static grpc_security_connector_vtable fake_channel_vtable = {
- fake_channel_destroy, fake_channel_check_peer};
+ fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp};
static grpc_security_connector_vtable fake_server_vtable = {
- fake_server_destroy, fake_server_check_peer};
+ fake_server_destroy, fake_server_check_peer, fake_server_cmp};
grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
+ grpc_channel_credentials *channel_creds,
grpc_call_credentials *request_metadata_creds, const char *target,
const grpc_channel_args *args) {
- grpc_fake_channel_security_connector *c = gpr_zalloc(sizeof(*c));
+ grpc_fake_channel_security_connector *c =
+ (grpc_fake_channel_security_connector *)gpr_zalloc(sizeof(*c));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
c->base.base.vtable = &fake_channel_vtable;
+ c->base.channel_creds = channel_creds;
c->base.request_metadata_creds =
grpc_call_credentials_ref(request_metadata_creds);
c->base.check_call_host = fake_channel_check_call_host;
@@ -441,12 +532,14 @@ grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
}
grpc_server_security_connector *grpc_fake_server_security_connector_create(
- void) {
+ grpc_server_credentials *server_creds) {
grpc_server_security_connector *c =
- gpr_zalloc(sizeof(grpc_server_security_connector));
+ (grpc_server_security_connector *)gpr_zalloc(
+ sizeof(grpc_server_security_connector));
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &fake_server_vtable;
c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
+ c->server_creds = server_creds;
c->add_handshakers = fake_server_add_handshakers;
return c;
}
@@ -455,24 +548,33 @@ grpc_server_security_connector *grpc_fake_server_security_connector_create(
typedef struct {
grpc_channel_security_connector base;
- tsi_ssl_client_handshaker_factory *handshaker_factory;
+ tsi_ssl_client_handshaker_factory *client_handshaker_factory;
char *target_name;
char *overridden_target_name;
} grpc_ssl_channel_security_connector;
typedef struct {
grpc_server_security_connector base;
- tsi_ssl_server_handshaker_factory *handshaker_factory;
+ tsi_ssl_server_handshaker_factory *server_handshaker_factory;
} grpc_ssl_server_security_connector;
+static bool server_connector_has_cert_config_fetcher(
+ grpc_ssl_server_security_connector *c) {
+ GPR_ASSERT(c != NULL);
+ grpc_ssl_server_credentials *server_creds =
+ (grpc_ssl_server_credentials *)c->base.server_creds;
+ GPR_ASSERT(server_creds != NULL);
+ return server_creds->certificate_config_fetcher.cb != NULL;
+}
+
static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc) {
grpc_ssl_channel_security_connector *c =
(grpc_ssl_channel_security_connector *)sc;
+ grpc_channel_credentials_unref(exec_ctx, c->base.channel_creds);
grpc_call_credentials_unref(exec_ctx, c->base.request_metadata_creds);
- if (c->handshaker_factory != NULL) {
- tsi_ssl_client_handshaker_factory_destroy(c->handshaker_factory);
- }
+ tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory);
+ c->client_handshaker_factory = NULL;
if (c->target_name != NULL) gpr_free(c->target_name);
if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
gpr_free(sc);
@@ -482,9 +584,9 @@ static void ssl_server_destroy(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
- if (c->handshaker_factory != NULL) {
- tsi_ssl_server_handshaker_factory_destroy(c->handshaker_factory);
- }
+ grpc_server_credentials_unref(exec_ctx, c->base.server_creds);
+ tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory);
+ c->server_handshaker_factory = NULL;
gpr_free(sc);
}
@@ -496,7 +598,7 @@ static void ssl_channel_add_handshakers(grpc_exec_ctx *exec_ctx,
// Instantiate TSI handshaker.
tsi_handshaker *tsi_hs = NULL;
tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
- c->handshaker_factory,
+ c->client_handshaker_factory,
c->overridden_target_name != NULL ? c->overridden_target_name
: c->target_name,
&tsi_hs);
@@ -505,7 +607,6 @@ static void ssl_channel_add_handshakers(grpc_exec_ctx *exec_ctx,
tsi_result_to_string(result));
return;
}
-
// Create handshakers.
grpc_handshake_manager_add(
handshake_mgr,
@@ -513,21 +614,110 @@ static void ssl_channel_add_handshakers(grpc_exec_ctx *exec_ctx,
exec_ctx, tsi_create_adapter_handshaker(tsi_hs), &sc->base));
}
+static const char **fill_alpn_protocol_strings(size_t *num_alpn_protocols) {
+ GPR_ASSERT(num_alpn_protocols != NULL);
+ *num_alpn_protocols = grpc_chttp2_num_alpn_versions();
+ const char **alpn_protocol_strings =
+ (const char **)gpr_malloc(sizeof(const char *) * (*num_alpn_protocols));
+ for (size_t i = 0; i < *num_alpn_protocols; i++) {
+ alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
+ }
+ return alpn_protocol_strings;
+}
+
+/* Attempts to replace the server_handshaker_factory with a new factory using
+ * the provided grpc_ssl_server_certificate_config. Should new factory creation
+ * fail, the existing factory will not be replaced. Returns true on success (new
+ * factory created). */
+static bool try_replace_server_handshaker_factory(
+ grpc_ssl_server_security_connector *sc,
+ const grpc_ssl_server_certificate_config *config) {
+ if (config == NULL) {
+ gpr_log(GPR_ERROR,
+ "Server certificate config callback returned invalid (NULL) "
+ "config.");
+ return false;
+ }
+ gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config);
+
+ size_t num_alpn_protocols = 0;
+ const char **alpn_protocol_strings =
+ fill_alpn_protocol_strings(&num_alpn_protocols);
+ tsi_ssl_pem_key_cert_pair *cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
+ config->pem_key_cert_pairs, config->num_key_cert_pairs);
+ tsi_ssl_server_handshaker_factory *new_handshaker_factory = NULL;
+ grpc_ssl_server_credentials *server_creds =
+ (grpc_ssl_server_credentials *)sc->base.server_creds;
+ tsi_result result = tsi_create_ssl_server_handshaker_factory_ex(
+ cert_pairs, config->num_key_cert_pairs, config->pem_root_certs,
+ get_tsi_client_certificate_request_type(
+ server_creds->config.client_certificate_request),
+ ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
+ &new_handshaker_factory);
+ gpr_free(cert_pairs);
+ gpr_free((void *)alpn_protocol_strings);
+
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
+ tsi_result_to_string(result));
+ return false;
+ }
+ tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory);
+ sc->server_handshaker_factory = new_handshaker_factory;
+ return true;
+}
+
+/* Attempts to fetch the server certificate config if a callback is available.
+ * Current certificate config will continue to be used if the callback returns
+ * an error. Returns true if new credentials were sucessfully loaded. */
+static bool try_fetch_ssl_server_credentials(
+ grpc_ssl_server_security_connector *sc) {
+ grpc_ssl_server_certificate_config *certificate_config = NULL;
+ bool status;
+
+ GPR_ASSERT(sc != NULL);
+ if (!server_connector_has_cert_config_fetcher(sc)) return false;
+
+ grpc_ssl_server_credentials *server_creds =
+ (grpc_ssl_server_credentials *)sc->base.server_creds;
+ grpc_ssl_certificate_config_reload_status cb_result =
+ server_creds->certificate_config_fetcher.cb(
+ server_creds->certificate_config_fetcher.user_data,
+ &certificate_config);
+ if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) {
+ gpr_log(GPR_DEBUG, "No change in SSL server credentials.");
+ status = false;
+ } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) {
+ status = try_replace_server_handshaker_factory(sc, certificate_config);
+ } else {
+ // Log error, continue using previously-loaded credentials.
+ gpr_log(GPR_ERROR,
+ "Failed fetching new server credentials, continuing to "
+ "use previously-loaded credentials.");
+ status = false;
+ }
+
+ if (certificate_config != NULL) {
+ grpc_ssl_server_certificate_config_destroy(certificate_config);
+ }
+ return status;
+}
+
static void ssl_server_add_handshakers(grpc_exec_ctx *exec_ctx,
grpc_server_security_connector *sc,
grpc_handshake_manager *handshake_mgr) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
// Instantiate TSI handshaker.
+ try_fetch_ssl_server_credentials(c);
tsi_handshaker *tsi_hs = NULL;
tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
- c->handshaker_factory, &tsi_hs);
+ c->server_handshaker_factory, &tsi_hs);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
return;
}
-
// Create handshakers.
grpc_handshake_manager_add(
handshake_mgr,
@@ -639,6 +829,29 @@ static void ssl_server_check_peer(grpc_exec_ctx *exec_ctx,
GRPC_CLOSURE_SCHED(exec_ctx, on_peer_checked, error);
}
+static int ssl_channel_cmp(grpc_security_connector *sc1,
+ grpc_security_connector *sc2) {
+ grpc_ssl_channel_security_connector *c1 =
+ (grpc_ssl_channel_security_connector *)sc1;
+ grpc_ssl_channel_security_connector *c2 =
+ (grpc_ssl_channel_security_connector *)sc2;
+ int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
+ if (c != 0) return c;
+ c = strcmp(c1->target_name, c2->target_name);
+ if (c != 0) return c;
+ return (c1->overridden_target_name == NULL ||
+ c2->overridden_target_name == NULL)
+ ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name)
+ : strcmp(c1->overridden_target_name, c2->overridden_target_name);
+}
+
+static int ssl_server_cmp(grpc_security_connector *sc1,
+ grpc_security_connector *sc2) {
+ return grpc_server_security_connector_cmp(
+ (grpc_server_security_connector *)sc1,
+ (grpc_server_security_connector *)sc2);
+}
+
static void add_shallow_auth_property_to_peer(tsi_peer *peer,
const grpc_auth_property *prop,
const char *tsi_prop_name) {
@@ -660,7 +873,8 @@ tsi_peer tsi_shallow_peer_from_ssl_auth_context(
while (grpc_auth_property_iterator_next(&it) != NULL) max_num_props++;
if (max_num_props > 0) {
- peer.properties = gpr_malloc(max_num_props * sizeof(tsi_peer_property));
+ peer.properties = (tsi_peer_property *)gpr_malloc(
+ max_num_props * sizeof(tsi_peer_property));
it = grpc_auth_context_property_iterator(auth_context);
while ((prop = grpc_auth_property_iterator_next(&it)) != NULL) {
if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) {
@@ -714,10 +928,10 @@ static void ssl_channel_cancel_check_call_host(
}
static grpc_security_connector_vtable ssl_channel_vtable = {
- ssl_channel_destroy, ssl_channel_check_peer};
+ ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp};
static grpc_security_connector_vtable ssl_server_vtable = {
- ssl_server_destroy, ssl_server_check_peer};
+ ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp};
/* returns a NULL terminated slice. */
static grpc_slice compute_default_pem_root_certs_once(void) {
@@ -765,31 +979,6 @@ grpc_slice grpc_get_default_ssl_roots_for_testing(void) {
return compute_default_pem_root_certs_once();
}
-static tsi_client_certificate_request_type
-get_tsi_client_certificate_request_type(
- grpc_ssl_client_certificate_request_type grpc_request_type) {
- switch (grpc_request_type) {
- case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE:
- return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
-
- case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
- return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
-
- case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
- return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY;
-
- case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
- return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY;
-
- case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
- return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY;
-
- default:
- // Is this a sane default
- return TSI_DONT_REQUEST_CLIENT_CERTIFICATE;
- }
-}
-
const char *grpc_get_default_ssl_roots(void) {
/* TODO(jboeuf@google.com): Maybe revisit the approach which consists in
loading all the roots once for the lifetime of the process. */
@@ -801,21 +990,18 @@ const char *grpc_get_default_ssl_roots(void) {
}
grpc_security_status grpc_ssl_channel_security_connector_create(
- grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *channel_creds,
+ grpc_call_credentials *request_metadata_creds,
const grpc_ssl_config *config, const char *target_name,
const char *overridden_target_name, grpc_channel_security_connector **sc) {
- size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
+ size_t num_alpn_protocols = 0;
const char **alpn_protocol_strings =
- gpr_malloc(sizeof(const char *) * num_alpn_protocols);
+ fill_alpn_protocol_strings(&num_alpn_protocols);
tsi_result result = TSI_OK;
grpc_ssl_channel_security_connector *c;
- size_t i;
const char *pem_root_certs;
char *port;
-
- for (i = 0; i < num_alpn_protocols; i++) {
- alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
- }
+ bool has_key_cert_pair;
if (config == NULL || target_name == NULL) {
gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
@@ -831,11 +1017,13 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
pem_root_certs = config->pem_root_certs;
}
- c = gpr_zalloc(sizeof(grpc_ssl_channel_security_connector));
+ c = (grpc_ssl_channel_security_connector *)gpr_zalloc(
+ sizeof(grpc_ssl_channel_security_connector));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.vtable = &ssl_channel_vtable;
c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
+ c->base.channel_creds = grpc_channel_credentials_ref(channel_creds);
c->base.request_metadata_creds =
grpc_call_credentials_ref(request_metadata_creds);
c->base.check_call_host = ssl_channel_check_call_host;
@@ -847,12 +1035,13 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
c->overridden_target_name = gpr_strdup(overridden_target_name);
}
- bool has_key_cert_pair = config->pem_key_cert_pair.private_key != NULL &&
- config->pem_key_cert_pair.cert_chain != NULL;
+ has_key_cert_pair = config->pem_key_cert_pair != NULL &&
+ config->pem_key_cert_pair->private_key != NULL &&
+ config->pem_key_cert_pair->cert_chain != NULL;
result = tsi_create_ssl_client_handshaker_factory(
- has_key_cert_pair ? &config->pem_key_cert_pair : NULL, pem_root_certs,
+ has_key_cert_pair ? config->pem_key_cert_pair : NULL, pem_root_certs,
ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
- &c->handshaker_factory);
+ &c->client_handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
@@ -869,48 +1058,64 @@ error:
return GRPC_SECURITY_ERROR;
}
+static grpc_ssl_server_security_connector *
+grpc_ssl_server_security_connector_initialize(
+ grpc_server_credentials *server_creds) {
+ grpc_ssl_server_security_connector *c =
+ (grpc_ssl_server_security_connector *)gpr_zalloc(
+ sizeof(grpc_ssl_server_security_connector));
+ gpr_ref_init(&c->base.base.refcount, 1);
+ c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
+ c->base.base.vtable = &ssl_server_vtable;
+ c->base.add_handshakers = ssl_server_add_handshakers;
+ c->base.server_creds = grpc_server_credentials_ref(server_creds);
+ return c;
+}
+
grpc_security_status grpc_ssl_server_security_connector_create(
- grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *gsc,
grpc_server_security_connector **sc) {
- size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
- const char **alpn_protocol_strings =
- gpr_malloc(sizeof(const char *) * num_alpn_protocols);
tsi_result result = TSI_OK;
- grpc_ssl_server_security_connector *c;
- size_t i;
+ grpc_ssl_server_credentials *server_credentials =
+ (grpc_ssl_server_credentials *)gsc;
+ grpc_security_status retval = GRPC_SECURITY_OK;
- for (i = 0; i < num_alpn_protocols; i++) {
- alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i);
- }
+ GPR_ASSERT(server_credentials != NULL);
+ GPR_ASSERT(sc != NULL);
- if (config == NULL || config->num_key_cert_pairs == 0) {
- gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
- goto error;
+ grpc_ssl_server_security_connector *c =
+ grpc_ssl_server_security_connector_initialize(gsc);
+ if (server_connector_has_cert_config_fetcher(c)) {
+ // Load initial credentials from certificate_config_fetcher:
+ if (!try_fetch_ssl_server_credentials(c)) {
+ gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher.");
+ retval = GRPC_SECURITY_ERROR;
+ }
+ } else {
+ size_t num_alpn_protocols = 0;
+ const char **alpn_protocol_strings =
+ fill_alpn_protocol_strings(&num_alpn_protocols);
+ result = tsi_create_ssl_server_handshaker_factory_ex(
+ server_credentials->config.pem_key_cert_pairs,
+ server_credentials->config.num_key_cert_pairs,
+ server_credentials->config.pem_root_certs,
+ get_tsi_client_certificate_request_type(
+ server_credentials->config.client_certificate_request),
+ ssl_cipher_suites(), alpn_protocol_strings,
+ (uint16_t)num_alpn_protocols, &c->server_handshaker_factory);
+ gpr_free((void *)alpn_protocol_strings);
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
+ tsi_result_to_string(result));
+ retval = GRPC_SECURITY_ERROR;
+ }
}
- c = gpr_zalloc(sizeof(grpc_ssl_server_security_connector));
- gpr_ref_init(&c->base.base.refcount, 1);
- c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
- c->base.base.vtable = &ssl_server_vtable;
- result = tsi_create_ssl_server_handshaker_factory_ex(
- config->pem_key_cert_pairs, config->num_key_cert_pairs,
- config->pem_root_certs, get_tsi_client_certificate_request_type(
- config->client_certificate_request),
- ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
- &c->handshaker_factory);
- if (result != TSI_OK) {
- gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
- tsi_result_to_string(result));
- ssl_server_destroy(exec_ctx, &c->base.base);
- *sc = NULL;
- goto error;
+ if (retval == GRPC_SECURITY_OK) {
+ *sc = &c->base;
+ } else {
+ if (c != NULL) ssl_server_destroy(exec_ctx, &c->base.base);
+ if (sc != NULL) *sc = NULL;
}
- c->base.add_handshakers = ssl_server_add_handshakers;
- *sc = &c->base;
- gpr_free((void *)alpn_protocol_strings);
- return GRPC_SECURITY_OK;
-
-error:
- gpr_free((void *)alpn_protocol_strings);
- return GRPC_SECURITY_ERROR;
+ return retval;
}
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index 4f9b63ad20..54a563bb2c 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -29,6 +29,10 @@
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security_interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef NDEBUG
extern grpc_tracer_flag grpc_trace_security_connector_refcount;
#endif
@@ -56,13 +60,9 @@ typedef struct {
void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
tsi_peer peer, grpc_auth_context **auth_context,
grpc_closure *on_peer_checked);
+ int (*cmp)(grpc_security_connector *sc, grpc_security_connector *other);
} grpc_security_connector_vtable;
-typedef struct grpc_security_connector_handshake_list {
- void *handshake;
- struct grpc_security_connector_handshake_list *next;
-} grpc_security_connector_handshake_list;
-
struct grpc_security_connector {
const grpc_security_connector_vtable *vtable;
gpr_refcount refcount;
@@ -100,6 +100,10 @@ void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
grpc_auth_context **auth_context,
grpc_closure *on_peer_checked);
+/* Compares two security connectors. */
+int grpc_security_connector_cmp(grpc_security_connector *sc,
+ grpc_security_connector *other);
+
/* Util to encapsulate the connector in a channel arg. */
grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);
@@ -112,13 +116,14 @@ grpc_security_connector *grpc_security_connector_find_in_args(
/* --- channel_security_connector object. ---
- A channel security connector object represents away to configure the
+ A channel security connector object represents a way to configure the
underlying transport security mechanism on the client side. */
typedef struct grpc_channel_security_connector grpc_channel_security_connector;
struct grpc_channel_security_connector {
grpc_security_connector base;
+ grpc_channel_credentials *channel_creds;
grpc_call_credentials *request_metadata_creds;
bool (*check_call_host)(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc, const char *host,
@@ -134,6 +139,10 @@ struct grpc_channel_security_connector {
grpc_handshake_manager *handshake_mgr);
};
+/// A helper function for use in grpc_security_connector_cmp() implementations.
+int grpc_channel_security_connector_cmp(grpc_channel_security_connector *sc1,
+ grpc_channel_security_connector *sc2);
+
/// Checks that the host that will be set for a call is acceptable.
/// Returns true if completed synchronously, in which case \a error will
/// be set to indicate the result. Otherwise, \a on_call_host_checked
@@ -157,18 +166,23 @@ void grpc_channel_security_connector_add_handshakers(
/* --- server_security_connector object. ---
- A server security connector object represents away to configure the
+ A server security connector object represents a way to configure the
underlying transport security mechanism on the server side. */
typedef struct grpc_server_security_connector grpc_server_security_connector;
struct grpc_server_security_connector {
grpc_security_connector base;
+ grpc_server_credentials *server_creds;
void (*add_handshakers)(grpc_exec_ctx *exec_ctx,
grpc_server_security_connector *sc,
grpc_handshake_manager *handshake_mgr);
};
+/// A helper function for use in grpc_security_connector_cmp() implementations.
+int grpc_server_security_connector_cmp(grpc_server_security_connector *sc1,
+ grpc_server_security_connector *sc2);
+
void grpc_server_security_connector_add_handshakers(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
grpc_handshake_manager *handshake_mgr);
@@ -178,18 +192,19 @@ void grpc_server_security_connector_add_handshakers(
/* For TESTING ONLY!
Creates a fake connector that emulates real channel security. */
grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
+ grpc_channel_credentials *channel_creds,
grpc_call_credentials *request_metadata_creds, const char *target,
const grpc_channel_args *args);
/* For TESTING ONLY!
Creates a fake connector that emulates real server security. */
grpc_server_security_connector *grpc_fake_server_security_connector_create(
- void);
+ grpc_server_credentials *server_creds);
/* Config for ssl clients. */
typedef struct {
- tsi_ssl_pem_key_cert_pair pem_key_cert_pair;
+ tsi_ssl_pem_key_cert_pair *pem_key_cert_pair;
char *pem_root_certs;
} grpc_ssl_config;
@@ -207,7 +222,8 @@ typedef struct {
specific error code otherwise.
*/
grpc_security_status grpc_ssl_channel_security_connector_create(
- grpc_exec_ctx *exec_ctx, grpc_call_credentials *request_metadata_creds,
+ grpc_exec_ctx *exec_ctx, grpc_channel_credentials *channel_creds,
+ grpc_call_credentials *request_metadata_creds,
const grpc_ssl_config *config, const char *target_name,
const char *overridden_target_name, grpc_channel_security_connector **sc);
@@ -232,7 +248,7 @@ typedef struct {
specific error code otherwise.
*/
grpc_security_status grpc_ssl_server_security_connector_create(
- grpc_exec_ctx *exec_ctx, const grpc_ssl_server_config *config,
+ grpc_exec_ctx *exec_ctx, grpc_server_credentials *server_credentials,
grpc_server_security_connector **sc);
/* Util. */
@@ -245,4 +261,8 @@ tsi_peer tsi_shallow_peer_from_ssl_auth_context(
const grpc_auth_context *auth_context);
void tsi_shallow_peer_destruct(tsi_peer *peer);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H */
diff --git a/src/core/lib/security/transport/security_handshaker.c b/src/core/lib/security/transport/security_handshaker.cc
index fc9c9f980f..3d19605617 100644
--- a/src/core/lib/security/transport/security_handshaker.c
+++ b/src/core/lib/security/transport/security_handshaker.cc
@@ -32,6 +32,7 @@
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/tsi_error.h"
#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/tsi/transport_security_grpc.h"
#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
@@ -127,24 +128,36 @@ static void security_handshake_failed_locked(grpc_exec_ctx *exec_ctx,
GRPC_CLOSURE_SCHED(exec_ctx, h->on_handshake_done, error);
}
-static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
- grpc_error *error) {
- security_handshaker *h = arg;
- gpr_mu_lock(&h->mu);
+static void on_peer_checked_inner(grpc_exec_ctx *exec_ctx,
+ security_handshaker *h, grpc_error *error) {
if (error != GRPC_ERROR_NONE || h->shutdown) {
security_handshake_failed_locked(exec_ctx, h, GRPC_ERROR_REF(error));
- goto done;
+ return;
}
- // Create frame protector.
- tsi_frame_protector *protector;
- tsi_result result = tsi_handshaker_result_create_frame_protector(
- h->handshaker_result, NULL, &protector);
- if (result != TSI_OK) {
+ // Create zero-copy frame protector, if implemented.
+ tsi_zero_copy_grpc_protector *zero_copy_protector = NULL;
+ tsi_result result = tsi_handshaker_result_create_zero_copy_grpc_protector(
+ exec_ctx, h->handshaker_result, NULL, &zero_copy_protector);
+ if (result != TSI_OK && result != TSI_UNIMPLEMENTED) {
error = grpc_set_tsi_error_result(
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Frame protector creation failed"),
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Zero-copy frame protector creation failed"),
result);
security_handshake_failed_locked(exec_ctx, h, error);
- goto done;
+ return;
+ }
+ // Create frame protector if zero-copy frame protector is NULL.
+ tsi_frame_protector *protector = NULL;
+ if (zero_copy_protector == NULL) {
+ result = tsi_handshaker_result_create_frame_protector(h->handshaker_result,
+ NULL, &protector);
+ if (result != TSI_OK) {
+ error = grpc_set_tsi_error_result(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Frame protector creation failed"),
+ result);
+ security_handshake_failed_locked(exec_ctx, h, error);
+ return;
+ }
}
// Get unused bytes.
const unsigned char *unused_bytes = NULL;
@@ -155,12 +168,12 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
if (unused_bytes_size > 0) {
grpc_slice slice =
grpc_slice_from_copied_buffer((char *)unused_bytes, unused_bytes_size);
- h->args->endpoint =
- grpc_secure_endpoint_create(protector, h->args->endpoint, &slice, 1);
+ h->args->endpoint = grpc_secure_endpoint_create(
+ protector, zero_copy_protector, h->args->endpoint, &slice, 1);
grpc_slice_unref_internal(exec_ctx, slice);
} else {
- h->args->endpoint =
- grpc_secure_endpoint_create(protector, h->args->endpoint, NULL, 0);
+ h->args->endpoint = grpc_secure_endpoint_create(
+ protector, zero_copy_protector, h->args->endpoint, NULL, 0);
}
tsi_handshaker_result_destroy(h->handshaker_result);
h->handshaker_result = NULL;
@@ -177,7 +190,13 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
// Set shutdown to true so that subsequent calls to
// security_handshaker_shutdown() do nothing.
h->shutdown = true;
-done:
+}
+
+static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ security_handshaker *h = (security_handshaker *)arg;
+ gpr_mu_lock(&h->mu);
+ on_peer_checked_inner(exec_ctx, h, error);
gpr_mu_unlock(&h->mu);
security_handshaker_unref(exec_ctx, h);
}
@@ -239,7 +258,7 @@ static grpc_error *on_handshake_next_done_locked(
static void on_handshake_next_done_grpc_wrapper(
tsi_result result, void *user_data, const unsigned char *bytes_to_send,
size_t bytes_to_send_size, tsi_handshaker_result *handshaker_result) {
- security_handshaker *h = user_data;
+ security_handshaker *h = (security_handshaker *)user_data;
// This callback will be invoked by TSI in a non-grpc thread, so it's
// safe to create our own exec_ctx here.
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -281,7 +300,7 @@ static grpc_error *do_handshaker_next_locked(
static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
void *arg, grpc_error *error) {
- security_handshaker *h = arg;
+ security_handshaker *h = (security_handshaker *)arg;
gpr_mu_lock(&h->mu);
if (error != GRPC_ERROR_NONE || h->shutdown) {
security_handshake_failed_locked(
@@ -298,7 +317,8 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
bytes_received_size += GRPC_SLICE_LENGTH(h->args->read_buffer->slices[i]);
}
if (bytes_received_size > h->handshake_buffer_size) {
- h->handshake_buffer = gpr_realloc(h->handshake_buffer, bytes_received_size);
+ h->handshake_buffer =
+ (uint8_t *)gpr_realloc(h->handshake_buffer, bytes_received_size);
h->handshake_buffer_size = bytes_received_size;
}
size_t offset = 0;
@@ -323,7 +343,7 @@ static void on_handshake_data_received_from_peer(grpc_exec_ctx *exec_ctx,
static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
- security_handshaker *h = arg;
+ security_handshaker *h = (security_handshaker *)arg;
gpr_mu_lock(&h->mu);
if (error != GRPC_ERROR_NONE || h->shutdown) {
security_handshake_failed_locked(
@@ -400,14 +420,15 @@ static const grpc_handshaker_vtable security_handshaker_vtable = {
static grpc_handshaker *security_handshaker_create(
grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
grpc_security_connector *connector) {
- security_handshaker *h = gpr_zalloc(sizeof(security_handshaker));
+ security_handshaker *h =
+ (security_handshaker *)gpr_zalloc(sizeof(security_handshaker));
grpc_handshaker_init(&security_handshaker_vtable, &h->base);
h->handshaker = handshaker;
h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
gpr_mu_init(&h->mu);
gpr_ref_init(&h->refs, 1);
h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
- h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
+ h->handshake_buffer = (uint8_t *)gpr_malloc(h->handshake_buffer_size);
GRPC_CLOSURE_INIT(&h->on_handshake_data_sent_to_peer,
on_handshake_data_sent_to_peer, h,
grpc_schedule_on_exec_ctx);
@@ -450,7 +471,7 @@ static const grpc_handshaker_vtable fail_handshaker_vtable = {
fail_handshaker_do_handshake};
static grpc_handshaker *fail_handshaker_create() {
- grpc_handshaker *h = gpr_malloc(sizeof(*h));
+ grpc_handshaker *h = (grpc_handshaker *)gpr_malloc(sizeof(*h));
grpc_handshaker_init(&fail_handshaker_vtable, h);
return h;
}
diff --git a/src/core/lib/security/transport/security_handshaker.h b/src/core/lib/security/transport/security_handshaker.h
index 95bf127fc6..178099bb94 100644
--- a/src/core/lib/security/transport/security_handshaker.h
+++ b/src/core/lib/security/transport/security_handshaker.h
@@ -23,6 +23,10 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/security/transport/security_connector.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/// Creates a security handshaker using \a handshaker.
grpc_handshaker *grpc_security_handshaker_create(
grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker,
@@ -31,4 +35,8 @@ grpc_handshaker *grpc_security_handshaker_create(
/// Registers security handshaker factories.
void grpc_security_register_handshaker_factories();
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H */
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.cc
index 9bf3f0ca0f..f5e02f42fe 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.cc
@@ -26,7 +26,15 @@
#include "src/core/lib/security/transport/auth_filters.h"
#include "src/core/lib/slice/slice_internal.h"
+typedef enum {
+ STATE_INIT = 0,
+ STATE_DONE,
+ STATE_CANCELLED,
+} async_state;
+
typedef struct call_data {
+ grpc_call_combiner *call_combiner;
+ grpc_call_stack *owning_call;
grpc_transport_stream_op_batch *recv_initial_metadata_batch;
grpc_closure *original_recv_initial_metadata_ready;
grpc_closure recv_initial_metadata_ready;
@@ -34,6 +42,8 @@ typedef struct call_data {
const grpc_metadata *consumed_md;
size_t num_consumed_md;
grpc_auth_context *auth_context;
+ grpc_closure cancel_closure;
+ gpr_atm state; // async_state
} call_data;
typedef struct channel_data {
@@ -53,8 +63,8 @@ static grpc_metadata_array metadata_batch_to_md_array(
grpc_slice value = GRPC_MDVALUE(md);
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));
+ result.metadata = (grpc_metadata *)gpr_realloc(
+ result.metadata, result.capacity * sizeof(grpc_metadata));
}
usr_md = &result.metadata[result.count++];
usr_md->key = grpc_slice_ref_internal(key);
@@ -66,8 +76,8 @@ static grpc_metadata_array metadata_batch_to_md_array(
static grpc_filtered_mdelem remove_consumed_md(grpc_exec_ctx *exec_ctx,
void *user_data,
grpc_mdelem md) {
- grpc_call_element *elem = user_data;
- call_data *calld = elem->call_data;
+ grpc_call_element *elem = (grpc_call_element *)user_data;
+ call_data *calld = (call_data *)elem->call_data;
size_t i;
for (i = 0; i < calld->num_consumed_md; i++) {
const grpc_metadata *consumed_md = &calld->consumed_md[i];
@@ -78,54 +88,94 @@ static grpc_filtered_mdelem remove_consumed_md(grpc_exec_ctx *exec_ctx,
return GRPC_FILTERED_MDELEM(md);
}
-/* called from application code */
-static void on_md_processing_done(
- void *user_data, const grpc_metadata *consumed_md, size_t num_consumed_md,
- const grpc_metadata *response_md, size_t num_response_md,
- grpc_status_code status, const char *error_details) {
- grpc_call_element *elem = user_data;
- call_data *calld = elem->call_data;
+static void on_md_processing_done_inner(grpc_exec_ctx *exec_ctx,
+ grpc_call_element *elem,
+ const grpc_metadata *consumed_md,
+ size_t num_consumed_md,
+ const grpc_metadata *response_md,
+ size_t num_response_md,
+ grpc_error *error) {
+ call_data *calld = (call_data *)elem->call_data;
grpc_transport_stream_op_batch *batch = calld->recv_initial_metadata_batch;
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
/* TODO(jboeuf): Implement support for response_md. */
if (response_md != NULL && num_response_md > 0) {
gpr_log(GPR_INFO,
"response_md in auth metadata processing not supported for now. "
"Ignoring...");
}
- grpc_error *error = GRPC_ERROR_NONE;
- if (status == GRPC_STATUS_OK) {
+ if (error == GRPC_ERROR_NONE) {
calld->consumed_md = consumed_md;
calld->num_consumed_md = num_consumed_md;
error = grpc_metadata_batch_filter(
- &exec_ctx, batch->payload->recv_initial_metadata.recv_initial_metadata,
+ exec_ctx, batch->payload->recv_initial_metadata.recv_initial_metadata,
remove_consumed_md, elem, "Response metadata filtering error");
- } else {
- if (error_details == NULL) {
- error_details = "Authentication metadata processing failed.";
+ }
+ GRPC_CLOSURE_SCHED(exec_ctx, calld->original_recv_initial_metadata_ready,
+ error);
+}
+
+// Called from application code.
+static void on_md_processing_done(
+ void *user_data, const grpc_metadata *consumed_md, size_t num_consumed_md,
+ const grpc_metadata *response_md, size_t num_response_md,
+ grpc_status_code status, const char *error_details) {
+ grpc_call_element *elem = (grpc_call_element *)user_data;
+ call_data *calld = (call_data *)elem->call_data;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ // If the call was not cancelled while we were in flight, process the result.
+ if (gpr_atm_full_cas(&calld->state, (gpr_atm)STATE_INIT,
+ (gpr_atm)STATE_DONE)) {
+ grpc_error *error = GRPC_ERROR_NONE;
+ if (status != GRPC_STATUS_OK) {
+ if (error_details == NULL) {
+ error_details = "Authentication metadata processing failed.";
+ }
+ error = grpc_error_set_int(
+ GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_details),
+ GRPC_ERROR_INT_GRPC_STATUS, status);
}
- error =
- grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_details),
- GRPC_ERROR_INT_GRPC_STATUS, status);
+ on_md_processing_done_inner(&exec_ctx, elem, consumed_md, num_consumed_md,
+ response_md, num_response_md, error);
}
+ // Clean up.
for (size_t i = 0; i < calld->md.count; i++) {
grpc_slice_unref_internal(&exec_ctx, calld->md.metadata[i].key);
grpc_slice_unref_internal(&exec_ctx, calld->md.metadata[i].value);
}
grpc_metadata_array_destroy(&calld->md);
- GRPC_CLOSURE_SCHED(&exec_ctx, calld->original_recv_initial_metadata_ready,
- error);
+ GRPC_CALL_STACK_UNREF(&exec_ctx, calld->owning_call, "server_auth_metadata");
grpc_exec_ctx_finish(&exec_ctx);
}
+static void cancel_call(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ grpc_call_element *elem = (grpc_call_element *)arg;
+ call_data *calld = (call_data *)elem->call_data;
+ // If the result was not already processed, invoke the callback now.
+ if (error != GRPC_ERROR_NONE &&
+ gpr_atm_full_cas(&calld->state, (gpr_atm)STATE_INIT,
+ (gpr_atm)STATE_CANCELLED)) {
+ on_md_processing_done_inner(exec_ctx, elem, NULL, 0, NULL, 0,
+ GRPC_ERROR_REF(error));
+ }
+ GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "cancel_call");
+}
+
static void recv_initial_metadata_ready(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
- grpc_call_element *elem = arg;
- channel_data *chand = elem->channel_data;
- call_data *calld = elem->call_data;
+ grpc_call_element *elem = (grpc_call_element *)arg;
+ channel_data *chand = (channel_data *)elem->channel_data;
+ call_data *calld = (call_data *)elem->call_data;
grpc_transport_stream_op_batch *batch = calld->recv_initial_metadata_batch;
if (error == GRPC_ERROR_NONE) {
if (chand->creds != NULL && chand->creds->processor.process != NULL) {
+ // We're calling out to the application, so we need to make sure
+ // to drop the call combiner early if we get cancelled.
+ GRPC_CALL_STACK_REF(calld->owning_call, "cancel_call");
+ GRPC_CLOSURE_INIT(&calld->cancel_closure, cancel_call, elem,
+ grpc_schedule_on_exec_ctx);
+ grpc_call_combiner_set_notify_on_cancel(exec_ctx, calld->call_combiner,
+ &calld->cancel_closure);
+ GRPC_CALL_STACK_REF(calld->owning_call, "server_auth_metadata");
calld->md = metadata_batch_to_md_array(
batch->payload->recv_initial_metadata.recv_initial_metadata);
chand->creds->processor.process(
@@ -141,7 +191,7 @@ static void recv_initial_metadata_ready(grpc_exec_ctx *exec_ctx, void *arg,
static void auth_start_transport_stream_op_batch(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_transport_stream_op_batch *batch) {
- call_data *calld = elem->call_data;
+ call_data *calld = (call_data *)elem->call_data;
if (batch->recv_initial_metadata) {
// Inject our callback.
calld->recv_initial_metadata_batch = batch;
@@ -157,8 +207,10 @@ static void auth_start_transport_stream_op_batch(
static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
const grpc_call_element_args *args) {
- call_data *calld = elem->call_data;
- channel_data *chand = elem->channel_data;
+ call_data *calld = (call_data *)elem->call_data;
+ channel_data *chand = (channel_data *)elem->channel_data;
+ calld->call_combiner = args->call_combiner;
+ calld->owning_call = args->call_stack;
GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready,
recv_initial_metadata_ready, elem,
grpc_schedule_on_exec_ctx);
@@ -188,7 +240,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
GPR_ASSERT(!args->is_last);
- channel_data *chand = elem->channel_data;
+ channel_data *chand = (channel_data *)elem->channel_data;
grpc_auth_context *auth_context =
grpc_find_auth_context_in_args(args->channel_args);
GPR_ASSERT(auth_context != NULL);
@@ -203,7 +255,7 @@ static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
/* Destructor for channel data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
- channel_data *chand = elem->channel_data;
+ channel_data *chand = (channel_data *)elem->channel_data;
GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter");
grpc_server_credentials_unref(exec_ctx, chand->creds);
}
@@ -218,6 +270,5 @@ const grpc_channel_filter grpc_server_auth_filter = {
sizeof(channel_data),
init_channel_elem,
destroy_channel_elem,
- grpc_call_next_get_peer,
grpc_channel_next_get_info,
"server-auth"};
diff --git a/src/core/lib/security/transport/tsi_error.c b/src/core/lib/security/transport/tsi_error.cc
index 72f9600e84..72f9600e84 100644
--- a/src/core/lib/security/transport/tsi_error.c
+++ b/src/core/lib/security/transport/tsi_error.cc
diff --git a/src/core/lib/security/transport/tsi_error.h b/src/core/lib/security/transport/tsi_error.h
index 87a63a8a7c..4e19daf796 100644
--- a/src/core/lib/security/transport/tsi_error.h
+++ b/src/core/lib/security/transport/tsi_error.h
@@ -22,6 +22,14 @@
#include "src/core/lib/iomgr/error.h"
#include "src/core/tsi/transport_security_interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
grpc_error *grpc_set_tsi_error_result(grpc_error *error, tsi_result result);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_TSI_ERROR_H */
diff --git a/src/core/lib/security/util/json_util.c b/src/core/lib/security/util/json_util.cc
index d847addef9..d847addef9 100644
--- a/src/core/lib/security/util/json_util.c
+++ b/src/core/lib/security/util/json_util.cc
diff --git a/src/core/lib/security/util/json_util.h b/src/core/lib/security/util/json_util.h
index 5ea831e27e..cdd8a7198a 100644
--- a/src/core/lib/security/util/json_util.h
+++ b/src/core/lib/security/util/json_util.h
@@ -28,6 +28,10 @@
#define GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT "service_account"
#define GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER "authorized_user"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
// Gets a child property from a json node.
const char *grpc_json_get_string_property(const grpc_json *json,
const char *prop_name);
@@ -37,4 +41,8 @@ const char *grpc_json_get_string_property(const grpc_json *json,
bool grpc_copy_json_string_property(const grpc_json *json,
const char *prop_name, char **copied_value);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_CORE_LIB_SECURITY_UTIL_JSON_UTIL_H */