Merge pull request #5408 from jboeuf/server_security_connector

Have a dedicated server security connector.
pull/5427/head
Yang Gao 9 years ago
commit d67b5f7313
  1. 4
      package.xml
  2. 14
      src/core/httpcli/httpcli_security_connector.c
  3. 1
      src/core/security/client_auth_filter.c
  4. 6
      src/core/security/credentials.c
  5. 6
      src/core/security/credentials.h
  6. 22
      src/core/security/handshake.c
  7. 3
      src/core/security/handshake.h
  8. 125
      src/core/security/security_connector.c
  9. 64
      src/core/security/security_connector.h
  10. 14
      src/core/security/server_secure_chttp2.c
  11. 11
      src/core/surface/secure_channel_create.c

@ -10,7 +10,7 @@
<email>grpc-packages@google.com</email> <email>grpc-packages@google.com</email>
<active>yes</active> <active>yes</active>
</lead> </lead>
<date>2016-02-25</date> <date>2016-02-24</date>
<time>16:06:07</time> <time>16:06:07</time>
<version> <version>
<release>0.8.0</release> <release>0.8.0</release>
@ -963,7 +963,7 @@ Update to wrap gRPC C Core version 0.10.0
<release>beta</release> <release>beta</release>
<api>beta</api> <api>beta</api>
</stability> </stability>
<date>2016-02-25</date> <date>2016-02-24</date>
<license>BSD</license> <license>BSD</license>
<notes> <notes>
- Simplify gRPC PHP installation #4517 - Simplify gRPC PHP installation #4517

@ -59,7 +59,7 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) {
} }
static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
@ -78,8 +78,8 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
tsi_result_to_string(result)); tsi_result_to_string(result));
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
} else { } else {
grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
user_data); nonsecure_endpoint, cb, user_data);
} }
} }
@ -103,7 +103,7 @@ static void httpcli_ssl_check_peer(grpc_exec_ctx *exec_ctx,
} }
static grpc_security_connector_vtable httpcli_ssl_vtable = { static grpc_security_connector_vtable httpcli_ssl_vtable = {
httpcli_ssl_destroy, httpcli_ssl_do_handshake, httpcli_ssl_check_peer}; httpcli_ssl_destroy, httpcli_ssl_check_peer};
static grpc_security_status httpcli_ssl_channel_security_connector_create( static grpc_security_status httpcli_ssl_channel_security_connector_create(
const unsigned char *pem_root_certs, size_t pem_root_certs_size, const unsigned char *pem_root_certs, size_t pem_root_certs_size,
@ -121,7 +121,6 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
memset(c, 0, 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); gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.is_client_side = 1;
c->base.base.vtable = &httpcli_ssl_vtable; c->base.base.vtable = &httpcli_ssl_vtable;
if (secure_peer_name != NULL) { if (secure_peer_name != NULL) {
c->secure_peer_name = gpr_strdup(secure_peer_name); c->secure_peer_name = gpr_strdup(secure_peer_name);
@ -136,6 +135,7 @@ static grpc_security_status httpcli_ssl_channel_security_connector_create(
*sc = NULL; *sc = NULL;
return GRPC_SECURITY_ERROR; return GRPC_SECURITY_ERROR;
} }
c->base.do_handshake = httpcli_ssl_do_handshake;
*sc = &c->base; *sc = &c->base;
return GRPC_SECURITY_OK; return GRPC_SECURITY_OK;
} }
@ -180,8 +180,8 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
GPR_ASSERT(httpcli_ssl_channel_security_connector_create( GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
pem_root_certs, pem_root_certs_size, host, &sc) == pem_root_certs, pem_root_certs_size, host, &sc) ==
GRPC_SECURITY_OK); GRPC_SECURITY_OK);
grpc_security_connector_do_handshake(exec_ctx, &sc->base, tcp, grpc_channel_security_connector_do_handshake(
on_secure_transport_setup_done, c); exec_ctx, sc, tcp, on_secure_transport_setup_done, c);
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
} }

@ -310,7 +310,6 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(auth_context != NULL); GPR_ASSERT(auth_context != NULL);
/* initialize members */ /* initialize members */
GPR_ASSERT(sc->is_client_side);
chand->security_connector = chand->security_connector =
(grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF( (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(
sc, "client_auth_filter"); sc, "client_auth_filter");

@ -166,7 +166,7 @@ void grpc_server_credentials_release(grpc_server_credentials *creds) {
} }
grpc_security_status grpc_server_credentials_create_security_connector( grpc_security_status grpc_server_credentials_create_security_connector(
grpc_server_credentials *creds, grpc_security_connector **sc) { grpc_server_credentials *creds, grpc_server_security_connector **sc) {
if (creds == NULL || creds->vtable->create_security_connector == NULL) { if (creds == NULL || creds->vtable->create_security_connector == NULL) {
gpr_log(GPR_ERROR, "Server credentials cannot create security context."); gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
return GRPC_SECURITY_ERROR; return GRPC_SECURITY_ERROR;
@ -298,7 +298,7 @@ static grpc_security_status ssl_create_security_connector(
} }
static grpc_security_status ssl_server_create_security_connector( static grpc_security_status ssl_server_create_security_connector(
grpc_server_credentials *creds, grpc_security_connector **sc) { grpc_server_credentials *creds, grpc_server_security_connector **sc) {
grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds; grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
return grpc_ssl_server_security_connector_create(&c->config, sc); return grpc_ssl_server_security_connector_create(&c->config, sc);
} }
@ -894,7 +894,7 @@ static grpc_security_status fake_transport_security_create_security_connector(
static grpc_security_status static grpc_security_status
fake_transport_security_server_create_security_connector( fake_transport_security_server_create_security_connector(
grpc_server_credentials *c, grpc_security_connector **sc) { grpc_server_credentials *c, grpc_server_security_connector **sc) {
*sc = grpc_fake_server_security_connector_create(); *sc = grpc_fake_server_security_connector_create();
return GRPC_SECURITY_OK; return GRPC_SECURITY_OK;
} }

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -234,7 +234,7 @@ grpc_refresh_token_credentials_create_from_auth_refresh_token(
typedef struct { typedef struct {
void (*destruct)(grpc_server_credentials *c); void (*destruct)(grpc_server_credentials *c);
grpc_security_status (*create_security_connector)( grpc_security_status (*create_security_connector)(
grpc_server_credentials *c, grpc_security_connector **sc); grpc_server_credentials *c, grpc_server_security_connector **sc);
} grpc_server_credentials_vtable; } grpc_server_credentials_vtable;
struct grpc_server_credentials { struct grpc_server_credentials {
@ -245,7 +245,7 @@ struct grpc_server_credentials {
}; };
grpc_security_status grpc_server_credentials_create_security_connector( grpc_security_status grpc_server_credentials_create_security_connector(
grpc_server_credentials *creds, grpc_security_connector **sc); grpc_server_credentials *creds, grpc_server_security_connector **sc);
grpc_server_credentials *grpc_server_credentials_ref( grpc_server_credentials *grpc_server_credentials_ref(
grpc_server_credentials *creds); grpc_server_credentials *creds);

@ -33,6 +33,7 @@
#include "src/core/security/handshake.h" #include "src/core/security/handshake.h"
#include <stdbool.h>
#include <string.h> #include <string.h>
#include "src/core/security/security_context.h" #include "src/core/security/security_context.h"
@ -46,6 +47,7 @@
typedef struct { typedef struct {
grpc_security_connector *connector; grpc_security_connector *connector;
tsi_handshaker *handshaker; tsi_handshaker *handshaker;
bool is_client_side;
unsigned char *handshake_buffer; unsigned char *handshake_buffer;
size_t handshake_buffer_size; size_t handshake_buffer_size;
grpc_endpoint *wrapped_endpoint; grpc_endpoint *wrapped_endpoint;
@ -67,9 +69,11 @@ static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx, void *setup,
bool success); bool success);
static void security_connector_remove_handshake(grpc_security_handshake *h) { static void security_connector_remove_handshake(grpc_security_handshake *h) {
GPR_ASSERT(!h->is_client_side);
grpc_security_connector_handshake_list *node; grpc_security_connector_handshake_list *node;
grpc_security_connector_handshake_list *tmp; grpc_security_connector_handshake_list *tmp;
grpc_security_connector *sc = h->connector; grpc_server_security_connector *sc =
(grpc_server_security_connector *)h->connector;
gpr_mu_lock(&sc->mu); gpr_mu_lock(&sc->mu);
node = sc->handshaking_handshakes; node = sc->handshaking_handshakes;
if (node && node->handshake == h) { if (node && node->handshake == h) {
@ -94,7 +98,7 @@ static void security_connector_remove_handshake(grpc_security_handshake *h) {
static void security_handshake_done(grpc_exec_ctx *exec_ctx, static void security_handshake_done(grpc_exec_ctx *exec_ctx,
grpc_security_handshake *h, grpc_security_handshake *h,
int is_success) { int is_success) {
if (!h->connector->is_client_side) { if (!h->is_client_side) {
security_connector_remove_handshake(h); security_connector_remove_handshake(h);
} }
if (is_success) { if (is_success) {
@ -290,6 +294,7 @@ static void on_handshake_data_sent_to_peer(grpc_exec_ctx *exec_ctx,
void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
tsi_handshaker *handshaker, tsi_handshaker *handshaker,
grpc_security_connector *connector, grpc_security_connector *connector,
bool is_client_side,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
@ -298,6 +303,7 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
memset(h, 0, sizeof(grpc_security_handshake)); memset(h, 0, sizeof(grpc_security_handshake));
h->handshaker = handshaker; h->handshaker = handshaker;
h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake"); h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
h->is_client_side = is_client_side;
h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
h->handshake_buffer = gpr_malloc(h->handshake_buffer_size); h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
h->wrapped_endpoint = nonsecure_endpoint; h->wrapped_endpoint = nonsecure_endpoint;
@ -310,13 +316,15 @@ void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
gpr_slice_buffer_init(&h->left_overs); gpr_slice_buffer_init(&h->left_overs);
gpr_slice_buffer_init(&h->outgoing); gpr_slice_buffer_init(&h->outgoing);
gpr_slice_buffer_init(&h->incoming); gpr_slice_buffer_init(&h->incoming);
if (!connector->is_client_side) { if (!is_client_side) {
grpc_server_security_connector *server_connector =
(grpc_server_security_connector *)connector;
handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list)); handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list));
handshake_node->handshake = h; handshake_node->handshake = h;
gpr_mu_lock(&connector->mu); gpr_mu_lock(&server_connector->mu);
handshake_node->next = connector->handshaking_handshakes; handshake_node->next = server_connector->handshaking_handshakes;
connector->handshaking_handshakes = handshake_node; server_connector->handshaking_handshakes = handshake_node;
gpr_mu_unlock(&connector->mu); gpr_mu_unlock(&server_connector->mu);
} }
send_handshake_bytes_to_peer(exec_ctx, h); send_handshake_bytes_to_peer(exec_ctx, h);
} }

@ -1,6 +1,6 @@
/* /*
* *
* Copyright 2015, Google Inc. * Copyright 2015-2016, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -41,6 +41,7 @@
void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx, void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
tsi_handshaker *handshaker, tsi_handshaker *handshaker,
grpc_security_connector *connector, grpc_security_connector *connector,
bool is_client_side,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data); void *user_data);

@ -33,6 +33,7 @@
#include "src/core/security/security_connector.h" #include "src/core/security/security_connector.h"
#include <stdbool.h>
#include <string.h> #include <string.h>
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
@ -110,31 +111,39 @@ const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
return NULL; return NULL;
} }
void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx, void grpc_server_security_connector_shutdown(
grpc_security_connector *connector) { grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector) {
grpc_security_connector_handshake_list *tmp; grpc_security_connector_handshake_list *tmp;
if (!connector->is_client_side) { gpr_mu_lock(&connector->mu);
gpr_mu_lock(&connector->mu); while (connector->handshaking_handshakes) {
while (connector->handshaking_handshakes) { tmp = connector->handshaking_handshakes;
tmp = connector->handshaking_handshakes; grpc_security_handshake_shutdown(
grpc_security_handshake_shutdown( exec_ctx, connector->handshaking_handshakes->handshake);
exec_ctx, connector->handshaking_handshakes->handshake); connector->handshaking_handshakes = tmp->next;
connector->handshaking_handshakes = tmp->next; gpr_free(tmp);
gpr_free(tmp); }
} gpr_mu_unlock(&connector->mu);
gpr_mu_unlock(&connector->mu); }
void grpc_channel_security_connector_do_handshake(
grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb,
void *user_data) {
if (sc == NULL || nonsecure_endpoint == NULL) {
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
} else {
sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data);
} }
} }
void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx, void grpc_server_security_connector_do_handshake(
grpc_security_connector *sc, grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb, void *user_data) {
void *user_data) {
if (sc == NULL || nonsecure_endpoint == NULL) { if (sc == NULL || nonsecure_endpoint == NULL) {
cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
} else { } else {
sc->vtable->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data); sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, cb, user_data);
} }
} }
@ -248,7 +257,8 @@ static void fake_channel_destroy(grpc_security_connector *sc) {
} }
static void fake_server_destroy(grpc_security_connector *sc) { static void fake_server_destroy(grpc_security_connector *sc) {
gpr_mu_destroy(&sc->mu); grpc_server_security_connector *c = (grpc_server_security_connector *)sc;
gpr_mu_destroy(&c->mu);
gpr_free(sc); gpr_free(sc);
} }
@ -298,49 +308,52 @@ static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx,
} }
static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx, static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), sc, grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base,
nonsecure_endpoint, cb, user_data); true, nonsecure_endpoint, cb, user_data);
} }
static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx, static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), sc, grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base,
nonsecure_endpoint, cb, user_data); false, nonsecure_endpoint, cb, user_data);
} }
static grpc_security_connector_vtable fake_channel_vtable = { static grpc_security_connector_vtable fake_channel_vtable = {
fake_channel_destroy, fake_channel_do_handshake, fake_check_peer}; fake_channel_destroy, fake_check_peer};
static grpc_security_connector_vtable fake_server_vtable = { static grpc_security_connector_vtable fake_server_vtable = {fake_server_destroy,
fake_server_destroy, fake_server_do_handshake, fake_check_peer}; fake_check_peer};
grpc_channel_security_connector *grpc_fake_channel_security_connector_create( grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
grpc_call_credentials *request_metadata_creds) { grpc_call_credentials *request_metadata_creds) {
grpc_channel_security_connector *c = gpr_malloc(sizeof(*c)); grpc_channel_security_connector *c = gpr_malloc(sizeof(*c));
memset(c, 0, sizeof(*c)); memset(c, 0, sizeof(*c));
gpr_ref_init(&c->base.refcount, 1); gpr_ref_init(&c->base.refcount, 1);
c->base.is_client_side = 1;
c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
c->base.vtable = &fake_channel_vtable; c->base.vtable = &fake_channel_vtable;
c->request_metadata_creds = grpc_call_credentials_ref(request_metadata_creds); c->request_metadata_creds = grpc_call_credentials_ref(request_metadata_creds);
c->check_call_host = fake_channel_check_call_host; c->check_call_host = fake_channel_check_call_host;
c->do_handshake = fake_channel_do_handshake;
return c; return c;
} }
grpc_security_connector *grpc_fake_server_security_connector_create(void) { grpc_server_security_connector *grpc_fake_server_security_connector_create(
grpc_security_connector *c = gpr_malloc(sizeof(grpc_security_connector)); void) {
memset(c, 0, sizeof(grpc_security_connector)); grpc_server_security_connector *c =
gpr_ref_init(&c->refcount, 1); gpr_malloc(sizeof(grpc_server_security_connector));
c->is_client_side = 0; memset(c, 0, sizeof(*c));
c->vtable = &fake_server_vtable; gpr_ref_init(&c->base.refcount, 1);
c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; c->base.vtable = &fake_server_vtable;
c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
c->do_handshake = fake_server_do_handshake;
gpr_mu_init(&c->mu); gpr_mu_init(&c->mu);
return c; return c;
} }
@ -355,7 +368,7 @@ typedef struct {
} grpc_ssl_channel_security_connector; } grpc_ssl_channel_security_connector;
typedef struct { typedef struct {
grpc_security_connector base; grpc_server_security_connector base;
tsi_ssl_handshaker_factory *handshaker_factory; tsi_ssl_handshaker_factory *handshaker_factory;
} grpc_ssl_server_security_connector; } grpc_ssl_server_security_connector;
@ -378,12 +391,12 @@ static void ssl_server_destroy(grpc_security_connector *sc) {
if (c->handshaker_factory != NULL) { if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory); tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
} }
gpr_mu_destroy(&sc->mu); gpr_mu_destroy(&c->base.mu);
gpr_free(sc); gpr_free(sc);
} }
static grpc_security_status ssl_create_handshaker( static grpc_security_status ssl_create_handshaker(
tsi_ssl_handshaker_factory *handshaker_factory, int is_client, tsi_ssl_handshaker_factory *handshaker_factory, bool is_client,
const char *peer_name, tsi_handshaker **handshaker) { const char *peer_name, tsi_handshaker **handshaker) {
tsi_result result = TSI_OK; tsi_result result = TSI_OK;
if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR; if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
@ -398,7 +411,7 @@ static grpc_security_status ssl_create_handshaker(
} }
static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
@ -406,20 +419,21 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
(grpc_ssl_channel_security_connector *)sc; (grpc_ssl_channel_security_connector *)sc;
tsi_handshaker *handshaker; tsi_handshaker *handshaker;
grpc_security_status status = ssl_create_handshaker( grpc_security_status status = ssl_create_handshaker(
c->handshaker_factory, 1, c->handshaker_factory, true,
c->overridden_target_name != NULL ? c->overridden_target_name c->overridden_target_name != NULL ? c->overridden_target_name
: c->target_name, : c->target_name,
&handshaker); &handshaker);
if (status != GRPC_SECURITY_OK) { if (status != GRPC_SECURITY_OK) {
cb(exec_ctx, user_data, status, NULL, NULL); cb(exec_ctx, user_data, status, NULL, NULL);
} else { } else {
grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
user_data); nonsecure_endpoint, cb, user_data);
} }
} }
static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc, grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor,
grpc_endpoint *nonsecure_endpoint, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, grpc_security_handshake_done_cb cb,
void *user_data) { void *user_data) {
@ -427,12 +441,12 @@ static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
(grpc_ssl_server_security_connector *)sc; (grpc_ssl_server_security_connector *)sc;
tsi_handshaker *handshaker; tsi_handshaker *handshaker;
grpc_security_status status = grpc_security_status status =
ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker); ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker);
if (status != GRPC_SECURITY_OK) { if (status != GRPC_SECURITY_OK) {
cb(exec_ctx, user_data, status, NULL, NULL); cb(exec_ctx, user_data, status, NULL, NULL);
} else { } else {
grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb, grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false,
user_data); nonsecure_endpoint, cb, user_data);
} }
} }
@ -603,10 +617,10 @@ static void ssl_channel_check_call_host(grpc_exec_ctx *exec_ctx,
} }
static grpc_security_connector_vtable ssl_channel_vtable = { static grpc_security_connector_vtable ssl_channel_vtable = {
ssl_channel_destroy, ssl_channel_do_handshake, ssl_channel_check_peer}; ssl_channel_destroy, ssl_channel_check_peer};
static grpc_security_connector_vtable ssl_server_vtable = { static grpc_security_connector_vtable ssl_server_vtable = {
ssl_server_destroy, ssl_server_do_handshake, ssl_server_check_peer}; ssl_server_destroy, ssl_server_check_peer};
static gpr_slice compute_default_pem_root_certs_once(void) { static gpr_slice compute_default_pem_root_certs_once(void) {
gpr_slice result = gpr_empty_slice(); gpr_slice result = gpr_empty_slice();
@ -700,11 +714,11 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
gpr_ref_init(&c->base.base.refcount, 1); gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.vtable = &ssl_channel_vtable; c->base.base.vtable = &ssl_channel_vtable;
c->base.base.is_client_side = 1;
c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
c->base.request_metadata_creds = c->base.request_metadata_creds =
grpc_call_credentials_ref(request_metadata_creds); grpc_call_credentials_ref(request_metadata_creds);
c->base.check_call_host = ssl_channel_check_call_host; c->base.check_call_host = ssl_channel_check_call_host;
c->base.do_handshake = ssl_channel_do_handshake;
gpr_split_host_port(target_name, &c->target_name, &port); gpr_split_host_port(target_name, &c->target_name, &port);
gpr_free(port); gpr_free(port);
if (overridden_target_name != NULL) { if (overridden_target_name != NULL) {
@ -735,7 +749,7 @@ error:
} }
grpc_security_status grpc_ssl_server_security_connector_create( grpc_security_status grpc_ssl_server_security_connector_create(
const grpc_ssl_server_config *config, grpc_security_connector **sc) { const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions(); size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
const unsigned char **alpn_protocol_strings = const unsigned char **alpn_protocol_strings =
gpr_malloc(sizeof(const char *) * num_alpn_protocols); gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@ -759,9 +773,9 @@ grpc_security_status grpc_ssl_server_security_connector_create(
c = gpr_malloc(sizeof(grpc_ssl_server_security_connector)); c = gpr_malloc(sizeof(grpc_ssl_server_security_connector));
memset(c, 0, sizeof(grpc_ssl_server_security_connector)); memset(c, 0, sizeof(grpc_ssl_server_security_connector));
gpr_ref_init(&c->base.refcount, 1); gpr_ref_init(&c->base.base.refcount, 1);
c->base.url_scheme = GRPC_SSL_URL_SCHEME; c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
c->base.vtable = &ssl_server_vtable; c->base.base.vtable = &ssl_server_vtable;
result = tsi_create_ssl_server_handshaker_factory( result = tsi_create_ssl_server_handshaker_factory(
(const unsigned char **)config->pem_private_keys, (const unsigned char **)config->pem_private_keys,
config->pem_private_keys_sizes, config->pem_private_keys_sizes,
@ -774,11 +788,12 @@ grpc_security_status grpc_ssl_server_security_connector_create(
if (result != TSI_OK) { if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result)); tsi_result_to_string(result));
ssl_server_destroy(&c->base); ssl_server_destroy(&c->base.base);
*sc = NULL; *sc = NULL;
goto error; goto error;
} }
gpr_mu_init(&c->base.mu); gpr_mu_init(&c->base.mu);
c->base.do_handshake = ssl_server_do_handshake;
*sc = &c->base; *sc = &c->base;
gpr_free((void *)alpn_protocol_strings); gpr_free((void *)alpn_protocol_strings);
gpr_free(alpn_protocol_string_lengths); gpr_free(alpn_protocol_string_lengths);

@ -36,6 +36,7 @@
#include <grpc/grpc_security.h> #include <grpc/grpc_security.h>
#include "src/core/iomgr/endpoint.h" #include "src/core/iomgr/endpoint.h"
#include "src/core/iomgr/tcp_server.h"
#include "src/core/tsi/transport_security_interface.h" #include "src/core/tsi/transport_security_interface.h"
/* --- status enum. --- */ /* --- status enum. --- */
@ -68,9 +69,6 @@ typedef void (*grpc_security_handshake_done_cb)(
typedef struct { typedef struct {
void (*destroy)(grpc_security_connector *sc); void (*destroy)(grpc_security_connector *sc);
void (*do_handshake)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, void *user_data);
void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc, void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
tsi_peer peer, grpc_security_peer_check_cb cb, tsi_peer peer, grpc_security_peer_check_cb cb,
void *user_data); void *user_data);
@ -84,13 +82,7 @@ typedef struct grpc_security_connector_handshake_list {
struct grpc_security_connector { struct grpc_security_connector {
const grpc_security_connector_vtable *vtable; const grpc_security_connector_vtable *vtable;
gpr_refcount refcount; gpr_refcount refcount;
int is_client_side;
const char *url_scheme; const char *url_scheme;
/* Used on server side only. */
/* TODO(yangg): Create a grpc_server_security_connector with these. */
gpr_mu mu;
grpc_security_connector_handshake_list *handshaking_handshakes;
const grpc_channel_args *channel_args;
}; };
/* Refcounting. */ /* Refcounting. */
@ -113,13 +105,6 @@ grpc_security_connector *grpc_security_connector_ref(
void grpc_security_connector_unref(grpc_security_connector *policy); void grpc_security_connector_unref(grpc_security_connector *policy);
#endif #endif
/* Handshake. */
void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx,
grpc_security_connector *connector,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb,
void *user_data);
/* Check the peer. Callee takes ownership of the peer object. /* Check the peer. Callee takes ownership of the peer object.
The callback will include the resulting auth_context. */ The callback will include the resulting auth_context. */
void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx, void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
@ -128,9 +113,6 @@ void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
grpc_security_peer_check_cb cb, grpc_security_peer_check_cb cb,
void *user_data); void *user_data);
void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx,
grpc_security_connector *connector);
/* Util to encapsulate the connector in a channel arg. */ /* Util to encapsulate the connector in a channel arg. */
grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc); grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);
@ -153,12 +135,16 @@ typedef void (*grpc_security_call_host_check_cb)(grpc_exec_ctx *exec_ctx,
grpc_security_status status); grpc_security_status status);
struct grpc_channel_security_connector { struct grpc_channel_security_connector {
grpc_security_connector base; /* requires is_client_side to be non 0. */ grpc_security_connector base;
grpc_call_credentials *request_metadata_creds; grpc_call_credentials *request_metadata_creds;
void (*check_call_host)(grpc_exec_ctx *exec_ctx, void (*check_call_host)(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc, const char *host, grpc_channel_security_connector *sc, const char *host,
grpc_auth_context *auth_context, grpc_auth_context *auth_context,
grpc_security_call_host_check_cb cb, void *user_data); grpc_security_call_host_check_cb cb, void *user_data);
void (*do_handshake)(grpc_exec_ctx *exec_ctx,
grpc_channel_security_connector *sc,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, void *user_data);
}; };
/* Checks that the host that will be set for a call is acceptable. */ /* Checks that the host that will be set for a call is acceptable. */
@ -167,6 +153,39 @@ void grpc_channel_security_connector_check_call_host(
const char *host, grpc_auth_context *auth_context, const char *host, grpc_auth_context *auth_context,
grpc_security_call_host_check_cb cb, void *user_data); grpc_security_call_host_check_cb cb, void *user_data);
/* Handshake. */
void grpc_channel_security_connector_do_handshake(
grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector,
grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb,
void *user_data);
/* --- server_security_connector object. ---
A server security connector object represents away 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;
gpr_mu mu;
grpc_security_connector_handshake_list *handshaking_handshakes;
const grpc_channel_args *channel_args;
void (*do_handshake)(grpc_exec_ctx *exec_ctx,
grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor,
grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, void *user_data);
};
void grpc_server_security_connector_do_handshake(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
grpc_security_handshake_done_cb cb, void *user_data);
void grpc_server_security_connector_shutdown(
grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector);
/* --- Creation security connectors. --- */ /* --- Creation security connectors. --- */
/* For TESTING ONLY! /* For TESTING ONLY!
@ -176,7 +195,8 @@ grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
/* For TESTING ONLY! /* For TESTING ONLY!
Creates a fake connector that emulates real server security. */ Creates a fake connector that emulates real server security. */
grpc_security_connector *grpc_fake_server_security_connector_create(void); grpc_server_security_connector *grpc_fake_server_security_connector_create(
void);
/* Config for ssl clients. */ /* Config for ssl clients. */
typedef struct { typedef struct {
@ -231,7 +251,7 @@ typedef struct {
specific error code otherwise. specific error code otherwise.
*/ */
grpc_security_status grpc_ssl_server_security_connector_create( grpc_security_status grpc_ssl_server_security_connector_create(
const grpc_ssl_server_config *config, grpc_security_connector **sc); const grpc_ssl_server_config *config, grpc_server_security_connector **sc);
/* Util. */ /* Util. */
const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,

@ -55,7 +55,7 @@
typedef struct grpc_server_secure_state { typedef struct grpc_server_secure_state {
grpc_server *server; grpc_server *server;
grpc_tcp_server *tcp; grpc_tcp_server *tcp;
grpc_security_connector *sc; grpc_server_security_connector *sc;
grpc_server_credentials *creds; grpc_server_credentials *creds;
int is_shutdown; int is_shutdown;
gpr_mu mu; gpr_mu mu;
@ -74,7 +74,7 @@ static void state_unref(grpc_server_secure_state *state) {
gpr_mu_lock(&state->mu); gpr_mu_lock(&state->mu);
gpr_mu_unlock(&state->mu); gpr_mu_unlock(&state->mu);
/* clean up */ /* clean up */
GRPC_SECURITY_CONNECTOR_UNREF(state->sc, "server"); GRPC_SECURITY_CONNECTOR_UNREF(&state->sc->base, "server");
grpc_server_credentials_unref(state->creds); grpc_server_credentials_unref(state->creds);
gpr_free(state); gpr_free(state);
} }
@ -130,8 +130,8 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,
grpc_tcp_server_acceptor *acceptor) { grpc_tcp_server_acceptor *acceptor) {
grpc_server_secure_state *state = statep; grpc_server_secure_state *state = statep;
state_ref(state); state_ref(state);
grpc_security_connector_do_handshake(exec_ctx, state->sc, tcp, grpc_server_security_connector_do_handshake(
on_secure_handshake_done, state); exec_ctx, state->sc, acceptor, tcp, on_secure_handshake_done, state);
} }
/* Server callback: start listening on our ports */ /* Server callback: start listening on our ports */
@ -148,7 +148,7 @@ static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep, bool success) {
state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg, state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
success); success);
} }
grpc_security_connector_shutdown(exec_ctx, state->sc); grpc_server_security_connector_shutdown(exec_ctx, state->sc);
state_unref(state); state_unref(state);
} }
@ -176,7 +176,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
int port_num = -1; int port_num = -1;
int port_temp; int port_temp;
grpc_security_status status = GRPC_SECURITY_ERROR; grpc_security_status status = GRPC_SECURITY_ERROR;
grpc_security_connector *sc = NULL; grpc_server_security_connector *sc = NULL;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
GRPC_API_TRACE( GRPC_API_TRACE(
@ -256,7 +256,7 @@ error:
grpc_tcp_server_unref(&exec_ctx, tcp); grpc_tcp_server_unref(&exec_ctx, tcp);
} else { } else {
if (sc) { if (sc) {
GRPC_SECURITY_CONNECTOR_UNREF(sc, "server"); GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
} }
if (state) { if (state) {
gpr_free(state); gpr_free(state);

@ -130,9 +130,9 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg,
static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
bool success) { bool success) {
connector *c = arg; connector *c = arg;
grpc_security_connector_do_handshake(exec_ctx, &c->security_connector->base, grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector,
c->connecting_endpoint, c->connecting_endpoint,
on_secure_handshake_done, c); on_secure_handshake_done, c);
} }
static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) { static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
@ -153,9 +153,8 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
&c->initial_string_sent); &c->initial_string_sent);
} else { } else {
grpc_security_connector_do_handshake(exec_ctx, grpc_channel_security_connector_do_handshake(
&c->security_connector->base, tcp, exec_ctx, c->security_connector, tcp, on_secure_handshake_done, c);
on_secure_handshake_done, c);
} }
} else { } else {
memset(c->result, 0, sizeof(*c->result)); memset(c->result, 0, sizeof(*c->result));

Loading…
Cancel
Save