aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Julien Boeuf <jboeuf@google.com>2015-04-17 14:38:48 -0700
committerGravatar Julien Boeuf <jboeuf@google.com>2015-04-17 23:41:46 -0700
commit7d1d9ca7faf6e5cd37df572ab98ff500c07297b9 (patch)
treebdeaa9100ae91aeb9a8ec4a83f7a25b7348ad043 /src
parent4f558f536c1bfe523e0dd0250420785d54dcc326 (diff)
Refactoring of core security to remove the factories.
- Renamed security_context -> security_connector. - Credentials are now responsible for creating their own connectors.
Diffstat (limited to 'src')
-rw-r--r--src/core/httpcli/httpcli.c13
-rw-r--r--src/core/httpcli/httpcli_security_connector.c (renamed from src/core/httpcli/httpcli_security_context.c)42
-rw-r--r--src/core/httpcli/httpcli_security_connector.h (renamed from src/core/httpcli/httpcli_security_context.h)12
-rw-r--r--src/core/security/auth.c30
-rw-r--r--src/core/security/credentials.c189
-rw-r--r--src/core/security/credentials.h46
-rw-r--r--src/core/security/factories.c68
-rw-r--r--src/core/security/secure_transport_setup.c14
-rw-r--r--src/core/security/secure_transport_setup.h4
-rw-r--r--src/core/security/security_connector.c (renamed from src/core/security/security_context.c)300
-rw-r--r--src/core/security/security_connector.h201
-rw-r--r--src/core/security/security_context.h214
-rw-r--r--src/core/security/server_secure_chttp2.c19
-rw-r--r--src/core/surface/secure_channel_create.c43
14 files changed, 576 insertions, 619 deletions
diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c
index d2cf09a8df..fe7ea6a86b 100644
--- a/src/core/httpcli/httpcli.c
+++ b/src/core/httpcli/httpcli.c
@@ -40,9 +40,8 @@
#include "src/core/iomgr/resolve_address.h"
#include "src/core/iomgr/tcp_client.h"
#include "src/core/httpcli/format_request.h"
-#include "src/core/httpcli/httpcli_security_context.h"
+#include "src/core/httpcli/httpcli_security_connector.h"
#include "src/core/httpcli/parser.h"
-#include "src/core/security/security_context.h"
#include "src/core/security/secure_transport_setup.h"
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
@@ -180,7 +179,7 @@ static void on_connected(void *arg, grpc_endpoint *tcp) {
}
req->ep = tcp;
if (req->use_ssl) {
- grpc_channel_security_context *ctx = NULL;
+ grpc_channel_security_connector *sc = NULL;
const unsigned char *pem_root_certs = NULL;
size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
if (pem_root_certs == NULL || pem_root_certs_size == 0) {
@@ -188,12 +187,12 @@ static void on_connected(void *arg, grpc_endpoint *tcp) {
finish(req, 0);
return;
}
- GPR_ASSERT(grpc_httpcli_ssl_channel_security_context_create(
- pem_root_certs, pem_root_certs_size, req->host, &ctx) ==
+ GPR_ASSERT(grpc_httpcli_ssl_channel_security_connector_create(
+ pem_root_certs, pem_root_certs_size, req->host, &sc) ==
GRPC_SECURITY_OK);
- grpc_setup_secure_transport(&ctx->base, tcp, on_secure_transport_setup_done,
+ grpc_setup_secure_transport(&sc->base, tcp, on_secure_transport_setup_done,
req);
- grpc_security_context_unref(&ctx->base);
+ grpc_security_connector_unref(&sc->base);
} else {
start_write(req);
}
diff --git a/src/core/httpcli/httpcli_security_context.c b/src/core/httpcli/httpcli_security_connector.c
index e97752bbe1..6eed5eaf12 100644
--- a/src/core/httpcli/httpcli_security_context.c
+++ b/src/core/httpcli/httpcli_security_connector.c
@@ -31,7 +31,7 @@
*
*/
-#include "src/core/httpcli/httpcli_security_context.h"
+#include "src/core/httpcli/httpcli_security_connector.h"
#include <string.h>
@@ -42,25 +42,25 @@
#include "src/core/tsi/ssl_transport_security.h"
typedef struct {
- grpc_channel_security_context base;
+ grpc_channel_security_connector base;
tsi_ssl_handshaker_factory *handshaker_factory;
char *secure_peer_name;
-} grpc_httpcli_ssl_channel_security_context;
+} grpc_httpcli_ssl_channel_security_connector;
-static void httpcli_ssl_destroy(grpc_security_context *ctx) {
- grpc_httpcli_ssl_channel_security_context *c =
- (grpc_httpcli_ssl_channel_security_context *)ctx;
+static void httpcli_ssl_destroy(grpc_security_connector *sc) {
+ grpc_httpcli_ssl_channel_security_connector *c =
+ (grpc_httpcli_ssl_channel_security_connector *)sc;
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
- gpr_free(ctx);
+ gpr_free(sc);
}
static grpc_security_status httpcli_ssl_create_handshaker(
- grpc_security_context *ctx, tsi_handshaker **handshaker) {
- grpc_httpcli_ssl_channel_security_context *c =
- (grpc_httpcli_ssl_channel_security_context *)ctx;
+ grpc_security_connector *sc, tsi_handshaker **handshaker) {
+ grpc_httpcli_ssl_channel_security_connector *c =
+ (grpc_httpcli_ssl_channel_security_connector *)sc;
tsi_result result = TSI_OK;
if (c->handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
result = tsi_ssl_handshaker_factory_create_handshaker(
@@ -73,12 +73,12 @@ static grpc_security_status httpcli_ssl_create_handshaker(
return GRPC_SECURITY_OK;
}
-static grpc_security_status httpcli_ssl_check_peer(grpc_security_context *ctx,
+static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc,
tsi_peer peer,
grpc_security_check_cb cb,
void *user_data) {
- grpc_httpcli_ssl_channel_security_context *c =
- (grpc_httpcli_ssl_channel_security_context *)ctx;
+ grpc_httpcli_ssl_channel_security_connector *c =
+ (grpc_httpcli_ssl_channel_security_connector *)sc;
grpc_security_status status = GRPC_SECURITY_OK;
/* Check the peer name. */
@@ -92,14 +92,14 @@ static grpc_security_status httpcli_ssl_check_peer(grpc_security_context *ctx,
return status;
}
-static grpc_security_context_vtable httpcli_ssl_vtable = {
+static grpc_security_connector_vtable httpcli_ssl_vtable = {
httpcli_ssl_destroy, httpcli_ssl_create_handshaker, httpcli_ssl_check_peer};
-grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
+grpc_security_status grpc_httpcli_ssl_channel_security_connector_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
- const char *secure_peer_name, grpc_channel_security_context **ctx) {
+ const char *secure_peer_name, grpc_channel_security_connector **sc) {
tsi_result result = TSI_OK;
- grpc_httpcli_ssl_channel_security_context *c;
+ grpc_httpcli_ssl_channel_security_connector *c;
if (secure_peer_name != NULL && pem_root_certs == NULL) {
gpr_log(GPR_ERROR,
@@ -107,8 +107,8 @@ grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
return GRPC_SECURITY_ERROR;
}
- c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_context));
- memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_context));
+ c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_connector));
+ memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_connector));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.is_client_side = 1;
@@ -123,9 +123,9 @@ grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
httpcli_ssl_destroy(&c->base.base);
- *ctx = NULL;
+ *sc = NULL;
return GRPC_SECURITY_ERROR;
}
- *ctx = &c->base;
+ *sc = &c->base;
return GRPC_SECURITY_OK;
}
diff --git a/src/core/httpcli/httpcli_security_context.h b/src/core/httpcli/httpcli_security_connector.h
index a776828a69..c50f25905e 100644
--- a/src/core/httpcli/httpcli_security_context.h
+++ b/src/core/httpcli/httpcli_security_connector.h
@@ -31,13 +31,13 @@
*
*/
-#ifndef GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H
-#define GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H
+#ifndef GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONNECTOR_H
+#define GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONNECTOR_H
-#include "src/core/security/security_context.h"
+#include "src/core/security/security_connector.h"
-grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
+grpc_security_status grpc_httpcli_ssl_channel_security_connector_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size,
- const char *secure_peer_name, grpc_channel_security_context **ctx);
+ const char *secure_peer_name, grpc_channel_security_connector **sc);
-#endif /* GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H */
+#endif /* GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONNECTOR_H */
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
index 5fc6d2717f..130698c11b 100644
--- a/src/core/security/auth.c
+++ b/src/core/security/auth.c
@@ -40,7 +40,7 @@
#include "src/core/support/string.h"
#include "src/core/channel/channel_stack.h"
-#include "src/core/security/security_context.h"
+#include "src/core/security/security_connector.h"
#include "src/core/security/credentials.h"
#include "src/core/surface/call.h"
@@ -54,7 +54,7 @@ typedef struct {
/* We can have a per-channel credentials. */
typedef struct {
- grpc_channel_security_context *security_context;
+ grpc_channel_security_connector *security_connector;
grpc_mdctx *md_ctx;
grpc_mdstr *authority_string;
grpc_mdstr *path_string;
@@ -126,7 +126,7 @@ static void send_security_metadata(grpc_call_element *elem, grpc_call_op *op) {
channel_data *channeld = elem->channel_data;
grpc_credentials *channel_creds =
- channeld->security_context->request_metadata_creds;
+ channeld->security_connector->request_metadata_creds;
/* TODO(jboeuf):
Decide on the policy in this case:
- populate both channel and call?
@@ -138,7 +138,7 @@ static void send_security_metadata(grpc_call_element *elem, grpc_call_op *op) {
if (channel_creds != NULL &&
grpc_credentials_has_request_metadata(channel_creds)) {
char *service_url =
- build_service_url(channeld->security_context->base.url_scheme, calld);
+ build_service_url(channeld->security_connector->base.url_scheme, calld);
calld->op = *op; /* Copy op (originates from the caller's stack). */
grpc_credentials_get_request_metadata(channel_creds, service_url,
on_credentials_metadata, elem);
@@ -193,8 +193,8 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
grpc_security_status status;
const char *call_host = grpc_mdstr_as_c_string(calld->host);
calld->op = *op; /* Copy op (originates from the caller's stack). */
- status = grpc_channel_security_context_check_call_host(
- channeld->security_context, call_host, on_host_checked, elem);
+ status = grpc_channel_security_connector_check_call_host(
+ channeld->security_connector, call_host, on_host_checked, elem);
if (status != GRPC_SECURITY_OK) {
if (status == GRPC_SECURITY_ERROR) {
char *error_msg;
@@ -255,7 +255,7 @@ static void init_channel_elem(grpc_channel_element *elem,
const grpc_channel_args *args,
grpc_mdctx *metadata_context, int is_first,
int is_last) {
- grpc_security_context *ctx = grpc_find_security_context_in_args(args);
+ grpc_security_connector *ctx = grpc_find_security_connector_in_args(args);
/* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data;
@@ -268,23 +268,24 @@ static void init_channel_elem(grpc_channel_element *elem,
/* initialize members */
GPR_ASSERT(ctx->is_client_side);
- channeld->security_context =
- (grpc_channel_security_context *)grpc_security_context_ref(ctx);
+ channeld->security_connector =
+ (grpc_channel_security_connector *)grpc_security_connector_ref(ctx);
channeld->md_ctx = metadata_context;
channeld->authority_string =
grpc_mdstr_from_string(channeld->md_ctx, ":authority");
channeld->path_string = grpc_mdstr_from_string(channeld->md_ctx, ":path");
channeld->error_msg_key =
grpc_mdstr_from_string(channeld->md_ctx, "grpc-message");
- channeld->status_key = grpc_mdstr_from_string(channeld->md_ctx, "grpc-status");
+ channeld->status_key =
+ grpc_mdstr_from_string(channeld->md_ctx, "grpc-status");
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */
channel_data *channeld = elem->channel_data;
- grpc_channel_security_context *ctx = channeld->security_context;
- if (ctx != NULL) grpc_security_context_unref(&ctx->base);
+ grpc_channel_security_connector *ctx = channeld->security_connector;
+ if (ctx != NULL) grpc_security_connector_unref(&ctx->base);
if (channeld->authority_string != NULL) {
grpc_mdstr_unref(channeld->authority_string);
}
@@ -300,6 +301,5 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_client_auth_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "auth"};
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem, "auth"};
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index e6d2e9e332..f6366f0750 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -36,11 +36,14 @@
#include <string.h>
#include <stdio.h>
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/http_client_filter.h"
#include "src/core/json/json.h"
#include "src/core/httpcli/httpcli.h"
#include "src/core/iomgr/iomgr.h"
#include "src/core/security/json_token.h"
#include "src/core/support/string.h"
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
@@ -111,9 +114,33 @@ void grpc_credentials_get_request_metadata(grpc_credentials *creds,
creds->vtable->get_request_metadata(creds, service_url, cb, user_data);
}
-grpc_mdctx *grpc_credentials_get_metadata_context(grpc_credentials *creds) {
- if (creds == NULL) return NULL;
- return creds->vtable->get_metadata_context(creds);
+grpc_mdctx *grpc_credentials_get_or_create_metadata_context(
+ grpc_credentials *creds) {
+ grpc_mdctx *mdctx = NULL;
+ if (creds != NULL && creds->vtable->get_metadata_context != NULL) {
+ mdctx = creds->vtable->get_metadata_context(creds);
+ }
+ if (mdctx == NULL) {
+ return grpc_mdctx_create();
+ } else {
+ grpc_mdctx_ref(mdctx);
+ return mdctx;
+ }
+}
+
+grpc_security_status grpc_credentials_create_security_connector(
+ grpc_credentials *creds, const char *target, const grpc_channel_args *args,
+ grpc_credentials *request_metadata_creds,
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+ *new_args = NULL;
+ if (creds == NULL || creds->vtable->create_security_connector == NULL ||
+ grpc_credentials_has_request_metadata_only(creds)) {
+ gpr_log(GPR_ERROR,
+ "Invalid credentials for creating a security connector.");
+ return GRPC_SECURITY_ERROR;
+ }
+ return creds->vtable->create_security_connector(
+ creds, target, args, request_metadata_creds, sc, new_args);
}
void grpc_server_credentials_release(grpc_server_credentials *creds) {
@@ -121,6 +148,15 @@ void grpc_server_credentials_release(grpc_server_credentials *creds) {
creds->vtable->destroy(creds);
}
+grpc_security_status grpc_server_credentials_create_security_connector(
+ grpc_server_credentials *creds, grpc_security_connector **sc) {
+ if (creds == NULL || creds->vtable->create_security_connector == NULL) {
+ gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
+ return GRPC_SECURITY_ERROR;
+ }
+ return creds->vtable->create_security_connector(creds, sc);
+}
+
/* -- Ssl credentials. -- */
typedef struct {
@@ -176,32 +212,49 @@ static grpc_mdctx *ssl_get_metadata_context(grpc_credentials *creds) {
return NULL;
}
-static grpc_credentials_vtable ssl_vtable = {
- ssl_destroy, ssl_has_request_metadata, ssl_has_request_metadata_only,
- ssl_get_metadata_context, NULL};
-
-static grpc_server_credentials_vtable ssl_server_vtable = {ssl_server_destroy};
-
-const grpc_ssl_config *grpc_ssl_credentials_get_config(
- const grpc_credentials *creds) {
- if (creds == NULL || strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
- return NULL;
- } else {
- grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
- return &c->config;
+static grpc_security_status ssl_create_security_connector(
+ grpc_credentials *creds, const char *target, const grpc_channel_args *args,
+ grpc_credentials *request_metadata_creds,
+ 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;
+ size_t i = 0;
+ const char *overridden_target_name = NULL;
+ grpc_arg arg;
+
+ for (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(
+ request_metadata_creds, &c->config, target, overridden_target_name, sc);
+ if (status != GRPC_SECURITY_OK) {
+ return status;
}
+ arg.type = GRPC_ARG_STRING;
+ arg.key = GRPC_ARG_HTTP2_SCHEME;
+ arg.value.string = "https";
+ *new_args = grpc_channel_args_copy_and_add(args, &arg);
+ return status;
}
-const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config(
- const grpc_server_credentials *creds) {
- if (creds == NULL || strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
- return NULL;
- } else {
- grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
- return &c->config;
- }
+static grpc_security_status ssl_server_create_security_connector(
+ grpc_server_credentials *creds, grpc_security_connector **sc) {
+ grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
+ return grpc_ssl_server_security_connector_create(&c->config, sc);
}
+static grpc_credentials_vtable ssl_vtable = {
+ ssl_destroy, ssl_has_request_metadata, ssl_has_request_metadata_only,
+ ssl_get_metadata_context, NULL, ssl_create_security_connector};
+
+static grpc_server_credentials_vtable ssl_server_vtable = {
+ ssl_server_destroy, ssl_server_create_security_connector};
+
static void ssl_copy_key_material(const char *input, unsigned char **output,
size_t *output_size) {
*output_size = strlen(input);
@@ -388,7 +441,7 @@ static grpc_mdctx *jwt_get_metadata_context(grpc_credentials *creds) {
static grpc_credentials_vtable jwt_vtable = {
jwt_destroy, jwt_has_request_metadata, jwt_has_request_metadata_only,
- jwt_get_metadata_context, jwt_get_request_metadata};
+ jwt_get_metadata_context, jwt_get_request_metadata, NULL};
grpc_credentials *grpc_jwt_credentials_create(const char *json_key,
gpr_timespec token_lifetime) {
@@ -613,7 +666,7 @@ static grpc_credentials_vtable compute_engine_vtable = {
oauth2_token_fetcher_destroy, oauth2_token_fetcher_has_request_metadata,
oauth2_token_fetcher_has_request_metadata_only,
oauth2_token_fetcher_get_metadata_context,
- oauth2_token_fetcher_get_request_metadata};
+ oauth2_token_fetcher_get_request_metadata, NULL};
static void compute_engine_fetch_oauth2(
grpc_credentials_metadata_request *metadata_req,
@@ -657,7 +710,7 @@ static grpc_credentials_vtable service_account_vtable = {
service_account_destroy, oauth2_token_fetcher_has_request_metadata,
oauth2_token_fetcher_has_request_metadata_only,
oauth2_token_fetcher_get_metadata_context,
- oauth2_token_fetcher_get_request_metadata};
+ oauth2_token_fetcher_get_request_metadata, NULL};
static void service_account_fetch_oauth2(
grpc_credentials_metadata_request *metadata_req,
@@ -731,7 +784,7 @@ static grpc_credentials_vtable refresh_token_vtable = {
refresh_token_destroy, oauth2_token_fetcher_has_request_metadata,
oauth2_token_fetcher_has_request_metadata_only,
oauth2_token_fetcher_get_metadata_context,
- oauth2_token_fetcher_get_request_metadata};
+ oauth2_token_fetcher_get_request_metadata, NULL};
static void refresh_token_fetch_oauth2(
grpc_credentials_metadata_request *metadata_req,
@@ -834,7 +887,7 @@ static grpc_mdctx *fake_oauth2_get_metadata_context(grpc_credentials *creds) {
static grpc_credentials_vtable fake_oauth2_vtable = {
fake_oauth2_destroy, fake_oauth2_has_request_metadata,
fake_oauth2_has_request_metadata_only, fake_oauth2_get_metadata_context,
- fake_oauth2_get_request_metadata};
+ fake_oauth2_get_request_metadata, NULL};
grpc_credentials *grpc_fake_oauth2_credentials_create(
const char *token_md_value, int is_async) {
@@ -878,15 +931,33 @@ static grpc_mdctx *fake_transport_security_get_metadata_context(
return NULL;
}
+static grpc_security_status
+fake_transport_security_create_security_connector(
+ grpc_credentials *c, const char *target, const grpc_channel_args *args,
+ grpc_credentials *request_metadata_creds,
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+ *sc = grpc_fake_channel_security_connector_create(request_metadata_creds, 1);
+ return GRPC_SECURITY_OK;
+}
+
+static grpc_security_status
+fake_transport_security_server_create_security_connector(
+ grpc_server_credentials *c, grpc_security_connector **sc) {
+ *sc = grpc_fake_server_security_connector_create();
+ return GRPC_SECURITY_OK;
+}
+
static grpc_credentials_vtable fake_transport_security_credentials_vtable = {
fake_transport_security_credentials_destroy,
fake_transport_security_has_request_metadata,
fake_transport_security_has_request_metadata_only,
- fake_transport_security_get_metadata_context, NULL};
+ fake_transport_security_get_metadata_context, NULL,
+ fake_transport_security_create_security_connector};
static grpc_server_credentials_vtable
fake_transport_security_server_credentials_vtable = {
- fake_transport_security_server_credentials_destroy};
+ fake_transport_security_server_credentials_destroy,
+ fake_transport_security_server_create_security_connector};
grpc_credentials *grpc_fake_transport_security_credentials_create(void) {
grpc_credentials *c = gpr_malloc(sizeof(grpc_credentials));
@@ -911,6 +982,7 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
typedef struct {
grpc_credentials base;
grpc_credentials_array inner;
+ grpc_credentials *connector_creds;
} grpc_composite_credentials;
typedef struct {
@@ -1038,7 +1110,10 @@ static grpc_mdctx *composite_get_metadata_context(grpc_credentials *creds) {
size_t i;
for (i = 0; i < c->inner.num_creds; i++) {
grpc_credentials *inner_creds = c->inner.creds_array[i];
- grpc_mdctx *inner_ctx = grpc_credentials_get_metadata_context(inner_creds);
+ grpc_mdctx *inner_ctx = NULL;
+ if (inner_creds->vtable->get_metadata_context != NULL) {
+ inner_ctx = inner_creds->vtable->get_metadata_context(inner_creds);
+ }
if (inner_ctx) {
GPR_ASSERT(ctx == NULL &&
"can only have one metadata context per composite credential");
@@ -1048,10 +1123,24 @@ static grpc_mdctx *composite_get_metadata_context(grpc_credentials *creds) {
return ctx;
}
+static grpc_security_status composite_create_security_connector(
+ grpc_credentials *creds, const char *target, const grpc_channel_args *args,
+ grpc_credentials *request_metadata_creds,
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+ grpc_composite_credentials *c = (grpc_composite_credentials *)creds;
+ if (c->connector_creds == NULL) {
+ gpr_log(GPR_ERROR,
+ "Cannot create security connector, missing connector credentials.");
+ return GRPC_SECURITY_ERROR;
+ }
+ return grpc_credentials_create_security_connector(c->connector_creds, target,
+ args, creds, sc, new_args);
+}
+
static grpc_credentials_vtable composite_credentials_vtable = {
composite_destroy, composite_has_request_metadata,
composite_has_request_metadata_only, composite_get_metadata_context,
- composite_get_request_metadata};
+ composite_get_request_metadata, composite_create_security_connector};
static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) {
grpc_credentials_array result;
@@ -1067,6 +1156,7 @@ static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) {
grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
grpc_credentials *creds2) {
size_t i;
+ size_t creds_array_byte_size;
grpc_credentials_array creds1_array;
grpc_credentials_array creds2_array;
grpc_composite_credentials *c;
@@ -1080,16 +1170,39 @@ grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
creds1_array = get_creds_array(&creds1);
creds2_array = get_creds_array(&creds2);
c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds;
- c->inner.creds_array =
- gpr_malloc(c->inner.num_creds * sizeof(grpc_credentials *));
+ creds_array_byte_size = c->inner.num_creds * sizeof(grpc_credentials *);
+ c->inner.creds_array = gpr_malloc(creds_array_byte_size);
+ memset(c->inner.creds_array, 0, creds_array_byte_size);
for (i = 0; i < creds1_array.num_creds; i++) {
- c->inner.creds_array[i] = grpc_credentials_ref(creds1_array.creds_array[i]);
+ grpc_credentials *cur_creds = creds1_array.creds_array[i];
+ if (!grpc_credentials_has_request_metadata_only(cur_creds)) {
+ if (c->connector_creds == NULL) {
+ c->connector_creds = cur_creds;
+ } else {
+ gpr_log(GPR_ERROR, "Cannot compose multiple connector credentials.");
+ goto fail;
+ }
+ }
+ c->inner.creds_array[i] = grpc_credentials_ref(cur_creds);
}
for (i = 0; i < creds2_array.num_creds; i++) {
+ grpc_credentials *cur_creds = creds2_array.creds_array[i];
+ if (!grpc_credentials_has_request_metadata_only(cur_creds)) {
+ if (c->connector_creds == NULL) {
+ c->connector_creds = cur_creds;
+ } else {
+ gpr_log(GPR_ERROR, "Cannot compose multiple connector credentials.");
+ goto fail;
+ }
+ }
c->inner.creds_array[i + creds1_array.num_creds] =
- grpc_credentials_ref(creds2_array.creds_array[i]);
+ grpc_credentials_ref(cur_creds);
}
return &c->base;
+
+fail:
+ grpc_credentials_unref(&c->base);
+ return NULL;
}
const grpc_credentials_array *grpc_composite_credentials_get_credentials(
@@ -1163,7 +1276,7 @@ static grpc_mdctx *iam_get_metadata_context(grpc_credentials *creds) {
static grpc_credentials_vtable iam_vtable = {
iam_destroy, iam_has_request_metadata, iam_has_request_metadata_only,
- iam_get_metadata_context, iam_get_request_metadata};
+ iam_get_metadata_context, iam_get_request_metadata, NULL};
grpc_credentials *grpc_iam_credentials_create(const char *token,
const char *authority_selector) {
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 562b3faa33..87c773e49a 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -39,6 +39,8 @@
#include <grpc/grpc_security.h>
#include <grpc/support/sync.h>
+#include "src/core/security/security_connector.h"
+
struct grpc_httpcli_response;
/* --- Constants. --- */
@@ -99,6 +101,11 @@ typedef struct {
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data);
+ grpc_security_status (*create_security_connector)(
+ grpc_credentials *c, const char *target, const grpc_channel_args *args,
+ grpc_credentials *request_metadata_creds,
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args);
+
} grpc_credentials_vtable;
struct grpc_credentials {
@@ -115,19 +122,20 @@ void grpc_credentials_get_request_metadata(grpc_credentials *creds,
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data);
-grpc_mdctx *grpc_credentials_get_metadata_context(grpc_credentials *creds);
-typedef struct {
- unsigned char *pem_private_key;
- size_t pem_private_key_size;
- unsigned char *pem_cert_chain;
- size_t pem_cert_chain_size;
- unsigned char *pem_root_certs;
- size_t pem_root_certs_size;
-} grpc_ssl_config;
+/* Gets the mdctx from the credentials and increase the refcount if it exists,
+ otherwise, create a new one. */
+grpc_mdctx *grpc_credentials_get_or_create_metadata_context(
+ grpc_credentials *creds);
-const grpc_ssl_config *grpc_ssl_credentials_get_config(
- const grpc_credentials *ssl_creds);
+/* Creates a security connector for the channel. May also create new channel
+ args for the channel to be used in place of the passed in const args if
+ returned non NULL. In that case the caller is responsible for destroying
+ new_args after channel creation. */
+grpc_security_status grpc_credentials_create_security_connector(
+ grpc_credentials *creds, const char *target, const grpc_channel_args *args,
+ grpc_credentials *request_metadata_creds,
+ grpc_channel_security_connector **sc, grpc_channel_args **new_args);
typedef struct {
grpc_credentials **creds_array;
@@ -159,6 +167,8 @@ grpc_credentials *grpc_fake_oauth2_credentials_create(
typedef struct {
void (*destroy)(grpc_server_credentials *c);
+ grpc_security_status (*create_security_connector)(
+ grpc_server_credentials *c, grpc_security_connector **sc);
} grpc_server_credentials_vtable;
struct grpc_server_credentials {
@@ -166,17 +176,7 @@ struct grpc_server_credentials {
const char *type;
};
-typedef struct {
- unsigned char **pem_private_keys;
- size_t *pem_private_keys_sizes;
- unsigned char **pem_cert_chains;
- size_t *pem_cert_chains_sizes;
- size_t num_key_cert_pairs;
- unsigned char *pem_root_certs;
- size_t pem_root_certs_size;
-} grpc_ssl_server_config;
-
-const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config(
- const grpc_server_credentials *ssl_creds);
+grpc_security_status grpc_server_credentials_create_security_connector(
+ grpc_server_credentials *creds, grpc_security_connector **sc);
#endif /* GRPC_INTERNAL_CORE_SECURITY_CREDENTIALS_H */
diff --git a/src/core/security/factories.c b/src/core/security/factories.c
deleted file mode 100644
index 3d9216aac4..0000000000
--- a/src/core/security/factories.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <string.h>
-
-#include <grpc/grpc.h>
-#include "src/core/security/credentials.h"
-#include "src/core/security/security_context.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/useful.h>
-
-grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
- const char *target,
- const grpc_channel_args *args) {
- grpc_secure_channel_factory factories[] = {
- {GRPC_CREDENTIALS_TYPE_SSL, grpc_ssl_channel_create},
- {GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY,
- grpc_fake_transport_security_channel_create}};
- return grpc_secure_channel_create_with_factories(
- factories, GPR_ARRAY_SIZE(factories), creds, target, args);
-}
-
-grpc_security_status grpc_server_security_context_create(
- grpc_server_credentials *creds, grpc_security_context **ctx) {
- grpc_security_status status = GRPC_SECURITY_ERROR;
-
- *ctx = NULL;
- if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL) == 0) {
- status = grpc_ssl_server_security_context_create(
- grpc_ssl_server_credentials_get_config(creds), ctx);
- } else if (strcmp(creds->type,
- GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) == 0) {
- *ctx = grpc_fake_server_security_context_create();
- status = GRPC_SECURITY_OK;
- }
- return status;
-}
diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c
index f57d22109c..3e1db9a12d 100644
--- a/src/core/security/secure_transport_setup.c
+++ b/src/core/security/secure_transport_setup.c
@@ -43,7 +43,7 @@
#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
typedef struct {
- grpc_security_context *ctx;
+ grpc_security_connector *connector;
tsi_handshaker *handshaker;
unsigned char *handshake_buffer;
size_t handshake_buffer_size;
@@ -74,7 +74,7 @@ static void secure_transport_setup_done(grpc_secure_transport_setup *s,
if (s->handshaker != NULL) tsi_handshaker_destroy(s->handshaker);
if (s->handshake_buffer != NULL) gpr_free(s->handshake_buffer);
gpr_slice_buffer_destroy(&s->left_overs);
- grpc_security_context_unref(s->ctx);
+ grpc_security_connector_unref(s->connector);
gpr_free(s);
}
@@ -112,8 +112,8 @@ static void check_peer(grpc_secure_transport_setup *s) {
secure_transport_setup_done(s, 0);
return;
}
- peer_status =
- grpc_security_context_check_peer(s->ctx, peer, on_peer_checked, s);
+ peer_status = grpc_security_connector_check_peer(s->connector, peer,
+ on_peer_checked, s);
if (peer_status == GRPC_SECURITY_ERROR) {
gpr_log(GPR_ERROR, "Peer check failed.");
secure_transport_setup_done(s, 0);
@@ -262,7 +262,7 @@ static void on_handshake_data_sent_to_peer(void *setup,
}
}
-void grpc_setup_secure_transport(grpc_security_context *ctx,
+void grpc_setup_secure_transport(grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_secure_transport_setup_done_cb cb,
void *user_data) {
@@ -270,12 +270,12 @@ void grpc_setup_secure_transport(grpc_security_context *ctx,
grpc_secure_transport_setup *s =
gpr_malloc(sizeof(grpc_secure_transport_setup));
memset(s, 0, sizeof(grpc_secure_transport_setup));
- result = grpc_security_context_create_handshaker(ctx, &s->handshaker);
+ result = grpc_security_connector_create_handshaker(connector, &s->handshaker);
if (result != GRPC_SECURITY_OK) {
secure_transport_setup_done(s, 0);
return;
}
- s->ctx = grpc_security_context_ref(ctx);
+ s->connector = grpc_security_connector_ref(connector);
s->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
s->handshake_buffer = gpr_malloc(s->handshake_buffer_size);
s->endpoint = nonsecure_endpoint;
diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/secure_transport_setup.h
index e1f8ed7830..58701c461d 100644
--- a/src/core/security/secure_transport_setup.h
+++ b/src/core/security/secure_transport_setup.h
@@ -35,7 +35,7 @@
#define GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H
#include "src/core/iomgr/endpoint.h"
-#include "src/core/security/security_context.h"
+#include "src/core/security/security_connector.h"
/* --- Secure transport setup --- */
@@ -45,7 +45,7 @@ typedef void (*grpc_secure_transport_setup_done_cb)(
grpc_endpoint *secure_endpoint);
/* Calls the callback upon completion. */
-void grpc_setup_secure_transport(grpc_security_context *ctx,
+void grpc_setup_secure_transport(grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_secure_transport_setup_done_cb cb,
void *user_data);
diff --git a/src/core/security/security_context.c b/src/core/security/security_connector.c
index dbfcf55655..dbd79c5b22 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_connector.c
@@ -31,12 +31,10 @@
*
*/
-#include "src/core/security/security_context.h"
+#include "src/core/security/security_connector.h"
#include <string.h>
-#include "src/core/channel/channel_args.h"
-#include "src/core/channel/http_client_filter.h"
#include "src/core/security/credentials.h"
#include "src/core/security/secure_endpoint.h"
#include "src/core/support/env.h"
@@ -56,7 +54,8 @@
#ifndef INSTALL_PREFIX
static const char *installed_roots_path = "/usr/share/grpc/roots.pem";
#else
-static const char *installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem";
+static const char *installed_roots_path =
+ INSTALL_PREFIX "/share/grpc/roots.pem";
#endif
/* -- Cipher suites. -- */
@@ -82,75 +81,77 @@ static const char *ssl_cipher_suites(void) {
/* -- Common methods. -- */
-grpc_security_status grpc_security_context_create_handshaker(
- grpc_security_context *ctx, tsi_handshaker **handshaker) {
- if (ctx == NULL || handshaker == NULL) return GRPC_SECURITY_ERROR;
- return ctx->vtable->create_handshaker(ctx, handshaker);
+grpc_security_status grpc_security_connector_create_handshaker(
+ grpc_security_connector *sc, tsi_handshaker **handshaker) {
+ if (sc == NULL || handshaker == NULL) return GRPC_SECURITY_ERROR;
+ return sc->vtable->create_handshaker(sc, handshaker);
}
-grpc_security_status grpc_security_context_check_peer(
- grpc_security_context *ctx, tsi_peer peer, grpc_security_check_cb cb,
+grpc_security_status grpc_security_connector_check_peer(
+ grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb,
void *user_data) {
- if (ctx == NULL) {
+ if (sc == NULL) {
tsi_peer_destruct(&peer);
return GRPC_SECURITY_ERROR;
}
- return ctx->vtable->check_peer(ctx, peer, cb, user_data);
+ return sc->vtable->check_peer(sc, peer, cb, user_data);
}
-grpc_security_status grpc_channel_security_context_check_call_host(
- grpc_channel_security_context *ctx, const char *host,
+grpc_security_status grpc_channel_security_connector_check_call_host(
+ grpc_channel_security_connector *sc, const char *host,
grpc_security_check_cb cb, void *user_data) {
- if (ctx == NULL || ctx->check_call_host == NULL) return GRPC_SECURITY_ERROR;
- return ctx->check_call_host(ctx, host, cb, user_data);
+ if (sc == NULL || sc->check_call_host == NULL) return GRPC_SECURITY_ERROR;
+ return sc->check_call_host(sc, host, cb, user_data);
}
-void grpc_security_context_unref(grpc_security_context *ctx) {
- if (ctx == NULL) return;
- if (gpr_unref(&ctx->refcount)) ctx->vtable->destroy(ctx);
+void grpc_security_connector_unref(grpc_security_connector *sc) {
+ if (sc == NULL) return;
+ if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
}
-grpc_security_context *grpc_security_context_ref(grpc_security_context *ctx) {
- if (ctx == NULL) return NULL;
- gpr_ref(&ctx->refcount);
- return ctx;
+grpc_security_connector *grpc_security_connector_ref(
+ grpc_security_connector *sc) {
+ if (sc == NULL) return NULL;
+ gpr_ref(&sc->refcount);
+ return sc;
}
-static void context_pointer_arg_destroy(void *p) {
- grpc_security_context_unref(p);
+static void connector_pointer_arg_destroy(void *p) {
+ grpc_security_connector_unref(p);
}
-static void *context_pointer_arg_copy(void *p) {
- return grpc_security_context_ref(p);
+static void *connector_pointer_arg_copy(void *p) {
+ return grpc_security_connector_ref(p);
}
-grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx) {
+grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) {
grpc_arg result;
result.type = GRPC_ARG_POINTER;
- result.key = GRPC_SECURITY_CONTEXT_ARG;
- result.value.pointer.destroy = context_pointer_arg_destroy;
- result.value.pointer.copy = context_pointer_arg_copy;
- result.value.pointer.p = ctx;
+ result.key = GRPC_SECURITY_CONNECTOR_ARG;
+ result.value.pointer.destroy = connector_pointer_arg_destroy;
+ result.value.pointer.copy = connector_pointer_arg_copy;
+ result.value.pointer.p = sc;
return result;
}
-grpc_security_context *grpc_security_context_from_arg(const grpc_arg *arg) {
- if (strcmp(arg->key, GRPC_SECURITY_CONTEXT_ARG)) return NULL;
+grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) {
+ if (strcmp(arg->key, GRPC_SECURITY_CONNECTOR_ARG)) return NULL;
if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
- GRPC_SECURITY_CONTEXT_ARG);
+ GRPC_SECURITY_CONNECTOR_ARG);
return NULL;
}
return arg->value.pointer.p;
}
-grpc_security_context *grpc_find_security_context_in_args(
+grpc_security_connector *grpc_find_security_connector_in_args(
const grpc_channel_args *args) {
size_t i;
if (args == NULL) return NULL;
for (i = 0; i < args->num_args; i++) {
- grpc_security_context *ctx = grpc_security_context_from_arg(&args->args[i]);
- if (ctx != NULL) return ctx;
+ grpc_security_connector *sc =
+ grpc_security_connector_from_arg(&args->args[i]);
+ if (sc != NULL) return sc;
}
return NULL;
}
@@ -158,51 +159,41 @@ grpc_security_context *grpc_find_security_context_in_args(
static int check_request_metadata_creds(grpc_credentials *creds) {
if (creds != NULL && !grpc_credentials_has_request_metadata(creds)) {
gpr_log(GPR_ERROR,
- "Incompatible credentials for channel security context: needs to "
+ "Incompatible credentials for channel security connector: needs to "
"set request metadata.");
return 0;
}
return 1;
}
-static grpc_mdctx *get_or_create_mdctx(grpc_credentials *creds) {
- grpc_mdctx *mdctx = grpc_credentials_get_metadata_context(creds);
- if (mdctx == NULL) {
- mdctx = grpc_mdctx_create();
- } else {
- grpc_mdctx_ref(mdctx);
- }
- return mdctx;
-}
-
/* -- Fake implementation. -- */
typedef struct {
- grpc_channel_security_context base;
+ grpc_channel_security_connector base;
int call_host_check_is_async;
-} grpc_fake_channel_security_context;
+} grpc_fake_channel_security_connector;
-static void fake_channel_destroy(grpc_security_context *ctx) {
- grpc_channel_security_context *c = (grpc_channel_security_context *)ctx;
+static void fake_channel_destroy(grpc_security_connector *sc) {
+ grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
grpc_credentials_unref(c->request_metadata_creds);
- gpr_free(ctx);
+ gpr_free(sc);
}
-static void fake_server_destroy(grpc_security_context *ctx) { gpr_free(ctx); }
+static void fake_server_destroy(grpc_security_connector *sc) { gpr_free(sc); }
static grpc_security_status fake_channel_create_handshaker(
- grpc_security_context *ctx, tsi_handshaker **handshaker) {
+ grpc_security_connector *sc, tsi_handshaker **handshaker) {
*handshaker = tsi_create_fake_handshaker(1);
return GRPC_SECURITY_OK;
}
static grpc_security_status fake_server_create_handshaker(
- grpc_security_context *ctx, tsi_handshaker **handshaker) {
+ grpc_security_connector *sc, tsi_handshaker **handshaker) {
*handshaker = tsi_create_fake_handshaker(0);
return GRPC_SECURITY_OK;
}
-static grpc_security_status fake_check_peer(grpc_security_context *ctx,
+static grpc_security_status fake_check_peer(grpc_security_connector *sc,
tsi_peer peer,
grpc_security_check_cb cb,
void *user_data) {
@@ -238,10 +229,10 @@ end:
}
static grpc_security_status fake_channel_check_call_host(
- grpc_channel_security_context *ctx, const char *host,
+ grpc_channel_security_connector *sc, const char *host,
grpc_security_check_cb cb, void *user_data) {
- grpc_fake_channel_security_context *c =
- (grpc_fake_channel_security_context *)ctx;
+ grpc_fake_channel_security_connector *c =
+ (grpc_fake_channel_security_connector *)sc;
if (c->call_host_check_is_async) {
cb(user_data, GRPC_SECURITY_OK);
return GRPC_SECURITY_PENDING;
@@ -250,16 +241,16 @@ static grpc_security_status fake_channel_check_call_host(
}
}
-static grpc_security_context_vtable fake_channel_vtable = {
+static grpc_security_connector_vtable fake_channel_vtable = {
fake_channel_destroy, fake_channel_create_handshaker, fake_check_peer};
-static grpc_security_context_vtable fake_server_vtable = {
+static grpc_security_connector_vtable fake_server_vtable = {
fake_server_destroy, fake_server_create_handshaker, fake_check_peer};
-grpc_channel_security_context *grpc_fake_channel_security_context_create(
+grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
grpc_credentials *request_metadata_creds, int call_host_check_is_async) {
- grpc_fake_channel_security_context *c =
- gpr_malloc(sizeof(grpc_fake_channel_security_context));
+ grpc_fake_channel_security_connector *c =
+ gpr_malloc(sizeof(grpc_fake_channel_security_connector));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.is_client_side = 1;
c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
@@ -271,8 +262,8 @@ grpc_channel_security_context *grpc_fake_channel_security_context_create(
return &c->base;
}
-grpc_security_context *grpc_fake_server_security_context_create(void) {
- grpc_security_context *c = gpr_malloc(sizeof(grpc_security_context));
+grpc_security_connector *grpc_fake_server_security_connector_create(void) {
+ grpc_security_connector *c = gpr_malloc(sizeof(grpc_security_connector));
gpr_ref_init(&c->refcount, 1);
c->vtable = &fake_server_vtable;
c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
@@ -282,21 +273,21 @@ grpc_security_context *grpc_fake_server_security_context_create(void) {
/* --- Ssl implementation. --- */
typedef struct {
- grpc_channel_security_context base;
+ grpc_channel_security_connector base;
tsi_ssl_handshaker_factory *handshaker_factory;
char *target_name;
char *overridden_target_name;
tsi_peer peer;
-} grpc_ssl_channel_security_context;
+} grpc_ssl_channel_security_connector;
typedef struct {
- grpc_security_context base;
+ grpc_security_connector base;
tsi_ssl_handshaker_factory *handshaker_factory;
-} grpc_ssl_server_security_context;
+} grpc_ssl_server_security_connector;
-static void ssl_channel_destroy(grpc_security_context *ctx) {
- grpc_ssl_channel_security_context *c =
- (grpc_ssl_channel_security_context *)ctx;
+static void ssl_channel_destroy(grpc_security_connector *sc) {
+ grpc_ssl_channel_security_connector *c =
+ (grpc_ssl_channel_security_connector *)sc;
grpc_credentials_unref(c->base.request_metadata_creds);
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
@@ -304,15 +295,16 @@ static void ssl_channel_destroy(grpc_security_context *ctx) {
if (c->target_name != NULL) gpr_free(c->target_name);
if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
tsi_peer_destruct(&c->peer);
- gpr_free(ctx);
+ gpr_free(sc);
}
-static void ssl_server_destroy(grpc_security_context *ctx) {
- grpc_ssl_server_security_context *c = (grpc_ssl_server_security_context *)ctx;
+static void ssl_server_destroy(grpc_security_connector *sc) {
+ grpc_ssl_server_security_connector *c =
+ (grpc_ssl_server_security_connector *)sc;
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
- gpr_free(ctx);
+ gpr_free(sc);
}
static grpc_security_status ssl_create_handshaker(
@@ -331,9 +323,9 @@ static grpc_security_status ssl_create_handshaker(
}
static grpc_security_status ssl_channel_create_handshaker(
- grpc_security_context *ctx, tsi_handshaker **handshaker) {
- grpc_ssl_channel_security_context *c =
- (grpc_ssl_channel_security_context *)ctx;
+ grpc_security_connector *sc, tsi_handshaker **handshaker) {
+ grpc_ssl_channel_security_connector *c =
+ (grpc_ssl_channel_security_connector *)sc;
return ssl_create_handshaker(c->handshaker_factory, 1,
c->overridden_target_name != NULL
? c->overridden_target_name
@@ -342,13 +334,13 @@ static grpc_security_status ssl_channel_create_handshaker(
}
static grpc_security_status ssl_server_create_handshaker(
- grpc_security_context *ctx, tsi_handshaker **handshaker) {
- grpc_ssl_server_security_context *c = (grpc_ssl_server_security_context *)ctx;
+ grpc_security_connector *sc, tsi_handshaker **handshaker) {
+ grpc_ssl_server_security_connector *c =
+ (grpc_ssl_server_security_connector *)sc;
return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker);
}
-static int ssl_host_matches_name(const tsi_peer *peer,
- const char *peer_name) {
+static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) {
char *allocated_name = NULL;
int r;
@@ -384,8 +376,7 @@ static grpc_security_status ssl_check_peer(const char *peer_name,
}
/* Check the peer name if specified. */
- if (peer_name != NULL &&
- !ssl_host_matches_name(peer, peer_name)) {
+ if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) {
gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
return GRPC_SECURITY_ERROR;
}
@@ -393,12 +384,12 @@ static grpc_security_status ssl_check_peer(const char *peer_name,
return GRPC_SECURITY_OK;
}
-static grpc_security_status ssl_channel_check_peer(grpc_security_context *ctx,
+static grpc_security_status ssl_channel_check_peer(grpc_security_connector *sc,
tsi_peer peer,
grpc_security_check_cb cb,
void *user_data) {
- grpc_ssl_channel_security_context *c =
- (grpc_ssl_channel_security_context *)ctx;
+ grpc_ssl_channel_security_connector *c =
+ (grpc_ssl_channel_security_connector *)sc;
grpc_security_status status;
tsi_peer_destruct(&c->peer);
c->peer = peer;
@@ -409,7 +400,7 @@ static grpc_security_status ssl_channel_check_peer(grpc_security_context *ctx,
return status;
}
-static grpc_security_status ssl_server_check_peer(grpc_security_context *ctx,
+static grpc_security_status ssl_server_check_peer(grpc_security_connector *sc,
tsi_peer peer,
grpc_security_check_cb cb,
void *user_data) {
@@ -420,10 +411,10 @@ static grpc_security_status ssl_server_check_peer(grpc_security_context *ctx,
}
static grpc_security_status ssl_channel_check_call_host(
- grpc_channel_security_context *ctx, const char *host,
+ grpc_channel_security_connector *sc, const char *host,
grpc_security_check_cb cb, void *user_data) {
- grpc_ssl_channel_security_context *c =
- (grpc_ssl_channel_security_context *)ctx;
+ grpc_ssl_channel_security_connector *c =
+ (grpc_ssl_channel_security_connector *)sc;
if (ssl_host_matches_name(&c->peer, host)) return GRPC_SECURITY_OK;
@@ -437,10 +428,10 @@ static grpc_security_status ssl_channel_check_call_host(
}
}
-static grpc_security_context_vtable ssl_channel_vtable = {
+static grpc_security_connector_vtable ssl_channel_vtable = {
ssl_channel_destroy, ssl_channel_create_handshaker, ssl_channel_check_peer};
-static grpc_security_context_vtable ssl_server_vtable = {
+static grpc_security_connector_vtable ssl_server_vtable = {
ssl_server_destroy, ssl_server_create_handshaker, ssl_server_check_peer};
static gpr_slice default_pem_root_certs;
@@ -471,17 +462,17 @@ size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs) {
return GPR_SLICE_LENGTH(default_pem_root_certs);
}
-grpc_security_status grpc_ssl_channel_security_context_create(
+grpc_security_status grpc_ssl_channel_security_connector_create(
grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
const char *target_name, const char *overridden_target_name,
- grpc_channel_security_context **ctx) {
+ grpc_channel_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
const unsigned char **alpn_protocol_strings =
gpr_malloc(sizeof(const char *) * num_alpn_protocols);
unsigned char *alpn_protocol_string_lengths =
gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
tsi_result result = TSI_OK;
- grpc_ssl_channel_security_context *c;
+ grpc_ssl_channel_security_connector *c;
size_t i;
const unsigned char *pem_root_certs;
size_t pem_root_certs_size;
@@ -502,8 +493,8 @@ grpc_security_status grpc_ssl_channel_security_context_create(
goto error;
}
- c = gpr_malloc(sizeof(grpc_ssl_channel_security_context));
- memset(c, 0, sizeof(grpc_ssl_channel_security_context));
+ c = gpr_malloc(sizeof(grpc_ssl_channel_security_connector));
+ memset(c, 0, sizeof(grpc_ssl_channel_security_connector));
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.vtable = &ssl_channel_vtable;
@@ -535,10 +526,10 @@ grpc_security_status grpc_ssl_channel_security_context_create(
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
ssl_channel_destroy(&c->base.base);
- *ctx = NULL;
+ *sc = NULL;
goto error;
}
- *ctx = &c->base;
+ *sc = &c->base;
gpr_free(alpn_protocol_strings);
gpr_free(alpn_protocol_string_lengths);
return GRPC_SECURITY_OK;
@@ -549,15 +540,15 @@ error:
return GRPC_SECURITY_ERROR;
}
-grpc_security_status grpc_ssl_server_security_context_create(
- const grpc_ssl_server_config *config, grpc_security_context **ctx) {
+grpc_security_status grpc_ssl_server_security_connector_create(
+ const grpc_ssl_server_config *config, grpc_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
const unsigned char **alpn_protocol_strings =
gpr_malloc(sizeof(const char *) * num_alpn_protocols);
unsigned char *alpn_protocol_string_lengths =
gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
tsi_result result = TSI_OK;
- grpc_ssl_server_security_context *c;
+ grpc_ssl_server_security_connector *c;
size_t i;
for (i = 0; i < num_alpn_protocols; i++) {
@@ -571,8 +562,8 @@ grpc_security_status grpc_ssl_server_security_context_create(
gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
goto error;
}
- c = gpr_malloc(sizeof(grpc_ssl_server_security_context));
- memset(c, 0, sizeof(grpc_ssl_server_security_context));
+ c = gpr_malloc(sizeof(grpc_ssl_server_security_connector));
+ memset(c, 0, sizeof(grpc_ssl_server_security_connector));
gpr_ref_init(&c->base.refcount, 1);
c->base.url_scheme = GRPC_SSL_URL_SCHEME;
@@ -582,17 +573,17 @@ grpc_security_status grpc_ssl_server_security_context_create(
config->pem_private_keys_sizes,
(const unsigned char **)config->pem_cert_chains,
config->pem_cert_chains_sizes, config->num_key_cert_pairs,
- config->pem_root_certs, config->pem_root_certs_size,
- ssl_cipher_suites(), alpn_protocol_strings,
- alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory);
+ config->pem_root_certs, config->pem_root_certs_size, ssl_cipher_suites(),
+ alpn_protocol_strings, alpn_protocol_string_lengths, 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(&c->base);
- *ctx = NULL;
+ *sc = NULL;
goto error;
}
- *ctx = &c->base;
+ *sc = &c->base;
gpr_free(alpn_protocol_strings);
gpr_free(alpn_protocol_string_lengths);
return GRPC_SECURITY_OK;
@@ -603,84 +594,3 @@ error:
return GRPC_SECURITY_ERROR;
}
-/* -- High level objects. -- */
-
-grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
- grpc_credentials *request_metadata_creds,
- const char *target,
- const grpc_channel_args *args) {
- grpc_channel_security_context *ctx = NULL;
- grpc_channel *channel = NULL;
- grpc_security_status status = GRPC_SECURITY_OK;
- size_t i = 0;
- const char *overridden_target_name = NULL;
- grpc_arg arg;
- grpc_channel_args *new_args;
-
- for (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_context_create(
- request_metadata_creds, grpc_ssl_credentials_get_config(ssl_creds),
- target, overridden_target_name, &ctx);
- if (status != GRPC_SECURITY_OK) {
- return grpc_lame_client_channel_create();
- }
- arg.type = GRPC_ARG_STRING;
- arg.key = GRPC_ARG_HTTP2_SCHEME;
- arg.value.string = "https";
- new_args = grpc_channel_args_copy_and_add(args, &arg);
- channel = grpc_secure_channel_create_internal(
- target, new_args, ctx, get_or_create_mdctx(request_metadata_creds));
- grpc_security_context_unref(&ctx->base);
- grpc_channel_args_destroy(new_args);
- return channel;
-}
-
-grpc_channel *grpc_fake_transport_security_channel_create(
- grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
- const char *target, const grpc_channel_args *args) {
- grpc_channel_security_context *ctx =
- grpc_fake_channel_security_context_create(request_metadata_creds, 1);
- grpc_channel *channel = grpc_secure_channel_create_internal(
- target, args, ctx, get_or_create_mdctx(request_metadata_creds));
- grpc_security_context_unref(&ctx->base);
- return channel;
-}
-
-grpc_channel *grpc_secure_channel_create_with_factories(
- const grpc_secure_channel_factory *factories, size_t num_factories,
- grpc_credentials *creds, const char *target,
- const grpc_channel_args *args) {
- size_t i;
- if (creds == NULL) {
- gpr_log(GPR_ERROR, "No credentials to create a secure channel.");
- return grpc_lame_client_channel_create();
- }
- if (grpc_credentials_has_request_metadata_only(creds)) {
- gpr_log(GPR_ERROR,
- "Credentials is insufficient to create a secure channel.");
- return grpc_lame_client_channel_create();
- }
-
- for (i = 0; i < num_factories; i++) {
- grpc_credentials *composite_creds = NULL;
- grpc_credentials *transport_security_creds = NULL;
- transport_security_creds = grpc_credentials_contains_type(
- creds, factories[i].creds_type, &composite_creds);
- if (transport_security_creds != NULL) {
- return factories[i].factory(transport_security_creds, composite_creds,
- target, args);
- }
- }
-
- gpr_log(GPR_ERROR,
- "Unknown credentials type %s for creating a secure channel.",
- creds->type);
- return grpc_lame_client_channel_create();
-}
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
new file mode 100644
index 0000000000..47abe05cff
--- /dev/null
+++ b/src/core/security/security_connector.h
@@ -0,0 +1,201 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H
+#define GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H
+
+#include <grpc/grpc_security.h>
+#include "src/core/iomgr/endpoint.h"
+#include "src/core/tsi/transport_security_interface.h"
+
+/* --- status enum. --- */
+
+typedef enum {
+ GRPC_SECURITY_OK = 0,
+ GRPC_SECURITY_PENDING,
+ GRPC_SECURITY_ERROR
+} grpc_security_status;
+
+/* --- URL schemes. --- */
+
+#define GRPC_SSL_URL_SCHEME "https"
+#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security"
+
+/* --- security_connector object. ---
+
+ A security connector object represents away to configure the underlying
+ transport security mechanism and check the resulting trusted peer. */
+
+typedef struct grpc_security_connector grpc_security_connector;
+
+#define GRPC_SECURITY_CONNECTOR_ARG "grpc.security_connector"
+
+typedef void (*grpc_security_check_cb)(void *user_data,
+ grpc_security_status status);
+
+typedef struct {
+ void (*destroy)(grpc_security_connector *sc);
+ grpc_security_status (*create_handshaker)(grpc_security_connector *sc,
+ tsi_handshaker **handshaker);
+ grpc_security_status (*check_peer)(grpc_security_connector *sc, tsi_peer peer,
+ grpc_security_check_cb cb,
+ void *user_data);
+} grpc_security_connector_vtable;
+
+struct grpc_security_connector {
+ const grpc_security_connector_vtable *vtable;
+ gpr_refcount refcount;
+ int is_client_side;
+ const char *url_scheme;
+};
+
+/* Increments the refcount. */
+grpc_security_connector *grpc_security_connector_ref(
+ grpc_security_connector *sc);
+
+/* Decrements the refcount and destroys the object if it reaches 0. */
+void grpc_security_connector_unref(grpc_security_connector *sc);
+
+/* Handshake creation. */
+grpc_security_status grpc_security_connector_create_handshaker(
+ grpc_security_connector *sc, tsi_handshaker **handshaker);
+
+/* Check the peer.
+ Implementations can choose to check the peer either synchronously or
+ asynchronously. In the first case, a successful call will return
+ GRPC_SECURITY_OK. In the asynchronous case, the call will return
+ GRPC_SECURITY_PENDING unless an error is detected early on.
+ Ownership of the peer is transfered.
+*/
+grpc_security_status grpc_security_connector_check_peer(
+ grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb,
+ void *user_data);
+
+/* Util to encapsulate the connector in a channel arg. */
+grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);
+
+/* Util to get the connector from a channel arg. */
+grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg);
+
+/* Util to find the connector from channel args. */
+grpc_security_connector *grpc_find_security_connector_in_args(
+ const grpc_channel_args *args);
+
+/* --- channel_security_connector object. ---
+
+ A channel security connector object represents away 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; /* requires is_client_side to be non 0. */
+ grpc_credentials *request_metadata_creds;
+ grpc_security_status (*check_call_host)(grpc_channel_security_connector *sc,
+ const char *host,
+ grpc_security_check_cb cb,
+ void *user_data);
+};
+
+/* Checks that the host that will be set for a call is acceptable.
+ Implementations can choose do the check either synchronously or
+ asynchronously. In the first case, a successful call will return
+ GRPC_SECURITY_OK. In the asynchronous case, the call will return
+ GRPC_SECURITY_PENDING unless an error is detected early on. */
+grpc_security_status grpc_channel_security_connector_check_call_host(
+ grpc_channel_security_connector *sc, const char *host,
+ grpc_security_check_cb cb, void *user_data);
+
+/* --- Creation security connectors. --- */
+
+/* For TESTING ONLY!
+ Creates a fake connector that emulates real channel security. */
+grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
+ grpc_credentials *request_metadata_creds, int call_host_check_is_async);
+
+/* For TESTING ONLY!
+ Creates a fake connector that emulates real server security. */
+grpc_security_connector *grpc_fake_server_security_connector_create(void);
+
+/* Config for ssl clients. */
+typedef struct {
+ unsigned char *pem_private_key;
+ size_t pem_private_key_size;
+ unsigned char *pem_cert_chain;
+ size_t pem_cert_chain_size;
+ unsigned char *pem_root_certs;
+ size_t pem_root_certs_size;
+} grpc_ssl_config;
+
+/* Creates an SSL channel_security_connector.
+ - request_metadata_creds is the credentials object which metadata
+ will be sent with each request. This parameter can be NULL.
+ - config is the SSL config to be used for the SSL channel establishment.
+ - is_client should be 0 for a server or a non-0 value for a client.
+ - secure_peer_name is the secure peer name that should be checked in
+ grpc_channel_security_connector_check_peer. This parameter may be NULL in
+ which case the peer name will not be checked. Note that if this parameter
+ is not NULL, then, pem_root_certs should not be NULL either.
+ - sc is a pointer on the connector to be created.
+ This function returns GRPC_SECURITY_OK in case of success or a
+ specific error code otherwise.
+*/
+grpc_security_status grpc_ssl_channel_security_connector_create(
+ grpc_credentials *request_metadata_creds,
+ const grpc_ssl_config *config, const char *target_name,
+ const char *overridden_target_name, grpc_channel_security_connector **sc);
+
+/* Gets the default ssl roots. */
+size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs);
+
+/* Config for ssl servers. */
+typedef struct {
+ unsigned char **pem_private_keys;
+ size_t *pem_private_keys_sizes;
+ unsigned char **pem_cert_chains;
+ size_t *pem_cert_chains_sizes;
+ size_t num_key_cert_pairs;
+ unsigned char *pem_root_certs;
+ size_t pem_root_certs_size;
+} grpc_ssl_server_config;
+
+/* Creates an SSL server_security_connector.
+ - config is the SSL config to be used for the SSL channel establishment.
+ - sc is a pointer on the connector to be created.
+ This function returns GRPC_SECURITY_OK in case of success or a
+ specific error code otherwise.
+*/
+grpc_security_status grpc_ssl_server_security_connector_create(
+ const grpc_ssl_server_config *config, grpc_security_connector **sc);
+
+#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H */
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
deleted file mode 100644
index 8e7ba34cac..0000000000
--- a/src/core/security/security_context.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
-#define GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
-
-#include <grpc/grpc_security.h>
-#include "src/core/iomgr/endpoint.h"
-#include "src/core/security/credentials.h"
-#include "src/core/tsi/transport_security_interface.h"
-
-/* --- status enum. --- */
-
-typedef enum {
- GRPC_SECURITY_OK = 0,
- GRPC_SECURITY_PENDING,
- GRPC_SECURITY_ERROR
-} grpc_security_status;
-
-/* --- URL schemes. --- */
-
-#define GRPC_SSL_URL_SCHEME "https"
-#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security"
-
-/* --- security_context object. ---
-
- A security context object represents away to configure the underlying
- transport security mechanism and check the resulting trusted peer. */
-
-typedef struct grpc_security_context grpc_security_context;
-
-#define GRPC_SECURITY_CONTEXT_ARG "grpc.security_context"
-
-typedef void (*grpc_security_check_cb)(void *user_data,
- grpc_security_status status);
-
-typedef struct {
- void (*destroy)(grpc_security_context *ctx);
- grpc_security_status (*create_handshaker)(grpc_security_context *ctx,
- tsi_handshaker **handshaker);
- grpc_security_status (*check_peer)(grpc_security_context *ctx, tsi_peer peer,
- grpc_security_check_cb cb,
- void *user_data);
-} grpc_security_context_vtable;
-
-struct grpc_security_context {
- const grpc_security_context_vtable *vtable;
- gpr_refcount refcount;
- int is_client_side;
- const char *url_scheme;
-};
-
-/* Increments the refcount. */
-grpc_security_context *grpc_security_context_ref(grpc_security_context *ctx);
-
-/* Decrements the refcount and destroys the object if it reaches 0. */
-void grpc_security_context_unref(grpc_security_context *ctx);
-
-/* Handshake creation. */
-grpc_security_status grpc_security_context_create_handshaker(
- grpc_security_context *ctx, tsi_handshaker **handshaker);
-
-/* Check the peer.
- Implementations can choose to check the peer either synchronously or
- asynchronously. In the first case, a successful call will return
- GRPC_SECURITY_OK. In the asynchronous case, the call will return
- GRPC_SECURITY_PENDING unless an error is detected early on.
- Ownership of the peer is transfered.
-*/
-grpc_security_status grpc_security_context_check_peer(
- grpc_security_context *ctx, tsi_peer peer,
- grpc_security_check_cb cb, void *user_data);
-
-/* Util to encapsulate the context in a channel arg. */
-grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx);
-
-/* Util to get the context from a channel arg. */
-grpc_security_context *grpc_security_context_from_arg(const grpc_arg *arg);
-
-/* Util to find the context from channel args. */
-grpc_security_context *grpc_find_security_context_in_args(
- const grpc_channel_args *args);
-
-/* --- channel_security_context object. ---
-
- A channel security context object represents away to configure the
- underlying transport security mechanism on the client side. */
-
-typedef struct grpc_channel_security_context grpc_channel_security_context;
-
-struct grpc_channel_security_context {
- grpc_security_context base; /* requires is_client_side to be non 0. */
- grpc_credentials *request_metadata_creds;
- grpc_security_status (*check_call_host)(
- grpc_channel_security_context *ctx, const char *host,
- grpc_security_check_cb cb, void *user_data);
-};
-
-/* Checks that the host that will be set for a call is acceptable.
- Implementations can choose do the check either synchronously or
- asynchronously. In the first case, a successful call will return
- GRPC_SECURITY_OK. In the asynchronous case, the call will return
- GRPC_SECURITY_PENDING unless an error is detected early on. */
-grpc_security_status grpc_channel_security_context_check_call_host(
- grpc_channel_security_context *ctx, const char *host,
- grpc_security_check_cb cb, void *user_data);
-
-/* --- Creation security contexts. --- */
-
-/* For TESTING ONLY!
- Creates a fake context that emulates real channel security. */
-grpc_channel_security_context *grpc_fake_channel_security_context_create(
- grpc_credentials *request_metadata_creds, int call_host_check_is_async);
-
-/* For TESTING ONLY!
- Creates a fake context that emulates real server security. */
-grpc_security_context *grpc_fake_server_security_context_create(void);
-
-/* Creates an SSL channel_security_context.
- - request_metadata_creds is the credentials object which metadata
- will be sent with each request. This parameter can be NULL.
- - config is the SSL config to be used for the SSL channel establishment.
- - is_client should be 0 for a server or a non-0 value for a client.
- - secure_peer_name is the secure peer name that should be checked in
- grpc_channel_security_context_check_peer. This parameter may be NULL in
- which case the peer name will not be checked. Note that if this parameter
- is not NULL, then, pem_root_certs should not be NULL either.
- - ctx is a pointer on the context to be created.
- This function returns GRPC_SECURITY_OK in case of success or a
- specific error code otherwise.
-*/
-grpc_security_status grpc_ssl_channel_security_context_create(
- grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
- const char *target_name, const char *overridden_target_name,
- grpc_channel_security_context **ctx);
-
-/* Creates an SSL server_security_context.
- - config is the SSL config to be used for the SSL channel establishment.
- - ctx is a pointer on the context to be created.
- This function returns GRPC_SECURITY_OK in case of success or a
- specific error code otherwise.
-*/
-grpc_security_status grpc_ssl_server_security_context_create(
- const grpc_ssl_server_config *config, grpc_security_context **ctx);
-
-/* --- Creation of high level objects. --- */
-
-/* Secure client channel creation. */
-
-size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs);
-
-grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
- grpc_credentials *request_metadata_creds,
- const char *target,
- const grpc_channel_args *args);
-
-grpc_channel *grpc_fake_transport_security_channel_create(
- grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
- const char *target, const grpc_channel_args *args);
-
-grpc_channel *grpc_secure_channel_create_internal(
- const char *target, const grpc_channel_args *args,
- grpc_channel_security_context *ctx, grpc_mdctx *mdctx);
-
-typedef grpc_channel *(*grpc_secure_channel_factory_func)(
- grpc_credentials *transport_security_creds,
- grpc_credentials *request_metadata_creds, const char *target,
- const grpc_channel_args *args);
-
-typedef struct {
- const char *creds_type;
- grpc_secure_channel_factory_func factory;
-} grpc_secure_channel_factory;
-
-grpc_channel *grpc_secure_channel_create_with_factories(
- const grpc_secure_channel_factory *factories, size_t num_factories,
- grpc_credentials *creds, const char *target, const grpc_channel_args *args);
-
-/* Secure server context creation. */
-
-grpc_security_status grpc_server_security_context_create(
- grpc_server_credentials *creds, grpc_security_context **ctx);
-
-#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 165ed5474f..5b7d99ce40 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -40,7 +40,8 @@
#include "src/core/iomgr/endpoint.h"
#include "src/core/iomgr/resolve_address.h"
#include "src/core/iomgr/tcp_server.h"
-#include "src/core/security/security_context.h"
+#include "src/core/security/credentials.h"
+#include "src/core/security/security_connector.h"
#include "src/core/security/secure_transport_setup.h"
#include "src/core/surface/server.h"
#include "src/core/transport/chttp2_transport.h"
@@ -52,7 +53,7 @@
typedef struct grpc_server_secure_state {
grpc_server *server;
grpc_tcp_server *tcp;
- grpc_security_context *ctx;
+ grpc_security_connector *sc;
int is_shutdown;
gpr_mu mu;
gpr_refcount refcount;
@@ -64,7 +65,7 @@ static void state_ref(grpc_server_secure_state *state) {
static void state_unref(grpc_server_secure_state *state) {
if (gpr_unref(&state->refcount)) {
- grpc_security_context_unref(state->ctx);
+ grpc_security_connector_unref(state->sc);
gpr_free(state);
}
}
@@ -104,7 +105,7 @@ static void on_secure_transport_setup_done(void *statep,
static void on_accept(void *statep, grpc_endpoint *tcp) {
grpc_server_secure_state *state = statep;
state_ref(state);
- grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done,
+ grpc_setup_secure_transport(state->sc, tcp, on_secure_transport_setup_done,
state);
}
@@ -137,11 +138,11 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
int port_num = -1;
int port_temp;
grpc_security_status status = GRPC_SECURITY_ERROR;
- grpc_security_context *ctx = NULL;
+ grpc_security_connector *sc = NULL;
/* create security context */
if (creds == NULL) goto error;
- status = grpc_server_security_context_create(creds, &ctx);
+ status = grpc_server_credentials_create_security_connector(creds, &sc);
if (status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Unable to create secure server with credentials of type %s.",
@@ -188,7 +189,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
state = gpr_malloc(sizeof(*state));
state->server = server;
state->tcp = tcp;
- state->ctx = ctx;
+ state->sc = sc;
state->is_shutdown = 0;
gpr_mu_init(&state->mu);
gpr_ref_init(&state->refcount, 1);
@@ -200,8 +201,8 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
/* Error path: cleanup and return */
error:
- if (ctx) {
- grpc_security_context_unref(ctx);
+ if (sc) {
+ grpc_security_connector_unref(sc);
}
if (resolved) {
grpc_resolved_addresses_destroy(resolved);
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index 96b2fe04fa..e7d223bfda 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -48,7 +48,7 @@
#include "src/core/iomgr/resolve_address.h"
#include "src/core/iomgr/tcp_client.h"
#include "src/core/security/auth.h"
-#include "src/core/security/security_context.h"
+#include "src/core/security/credentials.h"
#include "src/core/security/secure_transport_setup.h"
#include "src/core/support/string.h"
#include "src/core/surface/channel.h"
@@ -74,7 +74,7 @@ typedef struct {
} request;
struct setup {
- grpc_channel_security_context *security_context;
+ grpc_channel_security_connector *security_connector;
const char *target;
grpc_transport_setup_callback setup_callback;
void *setup_user_data;
@@ -130,7 +130,7 @@ static void on_connect(void *rp, grpc_endpoint *tcp) {
return;
}
} else {
- grpc_setup_secure_transport(&r->setup->security_context->base, tcp,
+ grpc_setup_secure_transport(&r->setup->security_connector->base, tcp,
on_secure_transport_setup_done, r);
}
}
@@ -185,7 +185,7 @@ static void initiate_setup(void *sp, grpc_client_setup_request *cs_request) {
static void done_setup(void *sp) {
setup *s = sp;
gpr_free((void *)s->target);
- grpc_security_context_unref(&s->security_context->base);
+ grpc_security_connector_unref(&s->security_connector->base);
gpr_free(s);
}
@@ -203,23 +203,37 @@ static grpc_transport_setup_result complete_setup(void *channel_stack,
Asynchronously: - resolve target
- connect to it (trying alternatives as presented)
- perform handshakes */
-grpc_channel *grpc_secure_channel_create_internal(
- const char *target, const grpc_channel_args *args,
- grpc_channel_security_context *context, grpc_mdctx *mdctx) {
+grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
+ const char *target,
+ const grpc_channel_args *args) {
setup *s;
grpc_channel *channel;
- grpc_arg context_arg;
+ grpc_arg connector_arg;
grpc_channel_args *args_copy;
+ grpc_channel_args *new_args_from_connector;
+ grpc_channel_security_connector* connector;
+ grpc_mdctx *mdctx;
#define MAX_FILTERS 3
const grpc_channel_filter *filters[MAX_FILTERS];
int n = 0;
- if (grpc_find_security_context_in_args(args) != NULL) {
+
+ if (grpc_find_security_connector_in_args(args) != NULL) {
gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
+ return grpc_lame_client_channel_create();
+ }
+
+ if (grpc_credentials_create_security_connector(
+ creds, target, args, NULL, &connector, &new_args_from_connector) !=
+ GRPC_SECURITY_OK) {
+ return grpc_lame_client_channel_create();
}
+ mdctx = grpc_credentials_get_or_create_metadata_context(creds);
s = gpr_malloc(sizeof(setup));
- context_arg = grpc_security_context_to_arg(&context->base);
- args_copy = grpc_channel_args_copy_and_add(args, &context_arg);
+ connector_arg = grpc_security_connector_to_arg(&connector->base);
+ args_copy = grpc_channel_args_copy_and_add(
+ new_args_from_connector != NULL ? new_args_from_connector : args,
+ &connector_arg);
filters[n++] = &grpc_client_surface_filter;
if (grpc_channel_args_is_census_enabled(args)) {
filters[n++] = &grpc_client_census_filter;
@@ -228,13 +242,14 @@ grpc_channel *grpc_secure_channel_create_internal(
GPR_ASSERT(n <= MAX_FILTERS);
channel = grpc_channel_create_from_filters(filters, n, args_copy, mdctx, 1);
grpc_channel_args_destroy(args_copy);
+ if (new_args_from_connector != NULL) {
+ grpc_channel_args_destroy(new_args_from_connector);
+ }
s->target = gpr_strdup(target);
s->setup_callback = complete_setup;
s->setup_user_data = grpc_channel_get_channel_stack(channel);
- s->security_context =
- (grpc_channel_security_context *)grpc_security_context_ref(
- &context->base);
+ s->security_connector = connector;
grpc_client_setup_create_and_attach(grpc_channel_get_channel_stack(channel),
args, mdctx, initiate_setup, done_setup,
s);