aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/security
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/security')
-rw-r--r--src/core/security/base64.c99
-rw-r--r--src/core/security/base64.h4
-rw-r--r--src/core/security/client_auth_filter.c30
-rw-r--r--src/core/security/credentials.c2
-rw-r--r--src/core/security/secure_transport_setup.c10
-rw-r--r--src/core/security/security_connector.c60
-rw-r--r--src/core/security/security_connector.h33
-rw-r--r--src/core/security/security_context.c31
-rw-r--r--src/core/security/security_context.h19
-rw-r--r--src/core/security/server_auth_filter.c36
-rw-r--r--src/core/security/server_secure_chttp2.c29
11 files changed, 227 insertions, 126 deletions
diff --git a/src/core/security/base64.c b/src/core/security/base64.c
index 3f28c09611..8dfaef846f 100644
--- a/src/core/security/base64.c
+++ b/src/core/security/base64.c
@@ -120,7 +120,68 @@ char *grpc_base64_encode(const void *vdata, size_t data_size, int url_safe,
}
gpr_slice grpc_base64_decode(const char *b64, int url_safe) {
- size_t b64_len = strlen(b64);
+ return grpc_base64_decode_with_len(b64, strlen(b64), url_safe);
+}
+
+static void decode_one_char(const unsigned char *codes, unsigned char *result,
+ size_t *result_offset) {
+ gpr_uint32 packed = (codes[0] << 2) | (codes[1] >> 4);
+ result[(*result_offset)++] = (unsigned char)packed;
+}
+
+static void decode_two_chars(const unsigned char *codes, unsigned char *result,
+ size_t *result_offset) {
+ gpr_uint32 packed = (codes[0] << 10) | (codes[1] << 4) | (codes[2] >> 2);
+ result[(*result_offset)++] = (unsigned char)(packed >> 8);
+ result[(*result_offset)++] = (unsigned char)(packed);
+}
+
+static int decode_group(const unsigned char *codes, size_t num_codes,
+ unsigned char *result, size_t *result_offset) {
+ GPR_ASSERT(num_codes <= 4);
+
+ /* Short end groups that may not have padding. */
+ if (num_codes == 1) {
+ gpr_log(GPR_ERROR, "Invalid group. Must be at least 2 bytes.");
+ return 0;
+ }
+ if (num_codes == 2) {
+ decode_one_char(codes, result, result_offset);
+ return 1;
+ }
+ if (num_codes == 3) {
+ decode_two_chars(codes, result, result_offset);
+ return 1;
+ }
+
+ /* Regular 4 byte groups with padding or not. */
+ GPR_ASSERT(num_codes == 4);
+ if (codes[0] == GRPC_BASE64_PAD_BYTE || codes[1] == GRPC_BASE64_PAD_BYTE) {
+ gpr_log(GPR_ERROR, "Invalid padding detected.");
+ return 0;
+ }
+ if (codes[2] == GRPC_BASE64_PAD_BYTE) {
+ if (codes[3] == GRPC_BASE64_PAD_BYTE) {
+ decode_one_char(codes, result, result_offset);
+ } else {
+ gpr_log(GPR_ERROR, "Invalid padding detected.");
+ return 0;
+ }
+ } else if (codes[3] == GRPC_BASE64_PAD_BYTE) {
+ decode_two_chars(codes, result, result_offset);
+ } else {
+ /* No padding. */
+ gpr_uint32 packed =
+ (codes[0] << 18) | (codes[1] << 12) | (codes[2] << 6) | codes[3];
+ result[(*result_offset)++] = (unsigned char)(packed >> 16);
+ result[(*result_offset)++] = (unsigned char)(packed >> 8);
+ result[(*result_offset)++] = (unsigned char)(packed);
+ }
+ return 1;
+}
+
+gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
+ int url_safe) {
gpr_slice result = gpr_slice_malloc(b64_len);
unsigned char *current = GPR_SLICE_START_PTR(result);
size_t result_size = 0;
@@ -151,43 +212,15 @@ gpr_slice grpc_base64_decode(const char *b64, int url_safe) {
} else {
codes[num_codes++] = (unsigned char)code;
if (num_codes == 4) {
- if (codes[0] == GRPC_BASE64_PAD_BYTE ||
- codes[1] == GRPC_BASE64_PAD_BYTE) {
- gpr_log(GPR_ERROR, "Invalid padding detected.");
- goto fail;
- }
- if (codes[2] == GRPC_BASE64_PAD_BYTE) {
- if (codes[3] == GRPC_BASE64_PAD_BYTE) {
- /* Double padding. */
- gpr_uint32 packed = (gpr_uint32)((codes[0] << 2) | (codes[1] >> 4));
- current[result_size++] = (unsigned char)packed;
- } else {
- gpr_log(GPR_ERROR, "Invalid padding detected.");
- goto fail;
- }
- } else if (codes[3] == GRPC_BASE64_PAD_BYTE) {
- /* Single padding. */
- gpr_uint32 packed =
- (gpr_uint32)((codes[0] << 10) | (codes[1] << 4) | (codes[2] >> 2));
- current[result_size++] = (unsigned char)(packed >> 8);
- current[result_size++] = (unsigned char)(packed);
- } else {
- /* No padding. */
- gpr_uint32 packed =
- (gpr_uint32)((codes[0] << 18) | (codes[1] << 12) | (codes[2] << 6) | codes[3]);
- current[result_size++] = (unsigned char)(packed >> 16);
- current[result_size++] = (unsigned char)(packed >> 8);
- current[result_size++] = (unsigned char)(packed);
- }
+ if (!decode_group(codes, num_codes, current, &result_size)) goto fail;
num_codes = 0;
}
}
}
- if (num_codes != 0) {
- gpr_log(GPR_ERROR, "Invalid base64.");
- gpr_slice_unref(result);
- return gpr_empty_slice();
+ if (num_codes != 0 &&
+ !decode_group(codes, num_codes, current, &result_size)) {
+ goto fail;
}
GPR_SLICE_SET_LENGTH(result, result_size);
return result;
diff --git a/src/core/security/base64.h b/src/core/security/base64.h
index 6a7cd8e96c..b9abc07b52 100644
--- a/src/core/security/base64.h
+++ b/src/core/security/base64.h
@@ -45,4 +45,8 @@ char *grpc_base64_encode(const void *data, size_t data_size, int url_safe,
slice in case of failure. */
gpr_slice grpc_base64_decode(const char *b64, int url_safe);
+/* Same as above except that the length is provided by the caller. */
+gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
+ int url_safe);
+
#endif /* GRPC_INTERNAL_CORE_SECURITY_BASE64_H */
diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c
index e9bd45db68..f8d18d9b17 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -58,7 +58,7 @@ typedef struct {
so that work can progress when this call wants work to
progress */
grpc_pollset *pollset;
- grpc_transport_op op;
+ grpc_transport_stream_op op;
size_t op_md_idx;
int sent_initial_metadata;
grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
@@ -77,7 +77,7 @@ typedef struct {
static void bubble_up_error(grpc_call_element *elem, const char *error_msg) {
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
- grpc_transport_op_add_cancellation(
+ grpc_transport_stream_op_add_cancellation(
&calld->op, GRPC_STATUS_UNAUTHENTICATED,
grpc_mdstr_from_string(chand->md_ctx, error_msg));
grpc_call_next_op(elem, &calld->op);
@@ -90,7 +90,7 @@ static void on_credentials_metadata(void *user_data,
grpc_call_element *elem = (grpc_call_element *)user_data;
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
- grpc_transport_op *op = &calld->op;
+ grpc_transport_stream_op *op = &calld->op;
grpc_metadata_batch *mdb;
size_t i;
if (status != GRPC_CREDENTIALS_OK) {
@@ -131,7 +131,7 @@ static char *build_service_url(const char *url_scheme, call_data *calld) {
}
static void send_security_metadata(grpc_call_element *elem,
- grpc_transport_op *op) {
+ grpc_transport_stream_op *op) {
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
grpc_client_security_context *ctx =
@@ -193,7 +193,7 @@ static void on_host_checked(void *user_data, grpc_security_status status) {
op contains type and call direction information, in addition to the data
that is being sent or received. */
static void auth_start_transport_op(grpc_call_element *elem,
- grpc_transport_op *op) {
+ grpc_transport_stream_op *op) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
@@ -253,17 +253,10 @@ static void auth_start_transport_op(grpc_call_element *elem,
grpc_call_next_op(elem, op);
}
-/* Called on special channel events, such as disconnection or new incoming
- calls on the server */
-static void channel_op(grpc_channel_element *elem,
- grpc_channel_element *from_elem, grpc_channel_op *op) {
- grpc_channel_next_op(elem, op);
-}
-
/* Constructor for call_data */
static void init_call_elem(grpc_call_element *elem,
const void *server_transport_data,
- grpc_transport_op *initial_op) {
+ grpc_transport_stream_op *initial_op) {
call_data *calld = elem->call_data;
calld->creds = NULL;
calld->host = NULL;
@@ -287,7 +280,7 @@ static void destroy_call_elem(grpc_call_element *elem) {
}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_channel_element *elem,
+static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
const grpc_channel_args *args,
grpc_mdctx *metadata_context, int is_first,
int is_last) {
@@ -298,14 +291,14 @@ static void init_channel_elem(grpc_channel_element *elem,
/* The first and the last filters tend to be implemented differently to
handle the case that there's no 'next' filter to call on the up or down
path */
- GPR_ASSERT(!is_first);
GPR_ASSERT(!is_last);
GPR_ASSERT(sc != NULL);
/* initialize members */
GPR_ASSERT(sc->is_client_side);
chand->security_connector =
- (grpc_channel_security_connector *)grpc_security_connector_ref(sc);
+ (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(
+ sc, "client_auth_filter");
chand->md_ctx = metadata_context;
chand->authority_string = grpc_mdstr_from_string(chand->md_ctx, ":authority");
chand->path_string = grpc_mdstr_from_string(chand->md_ctx, ":path");
@@ -318,7 +311,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */
channel_data *chand = elem->channel_data;
grpc_channel_security_connector *ctx = chand->security_connector;
- if (ctx != NULL) grpc_security_connector_unref(&ctx->base);
+ if (ctx != NULL)
+ GRPC_SECURITY_CONNECTOR_UNREF(&ctx->base, "client_auth_filter");
if (chand->authority_string != NULL) {
grpc_mdstr_unref(chand->authority_string);
}
@@ -334,6 +328,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_client_auth_filter = {
- auth_start_transport_op, channel_op, sizeof(call_data),
+ auth_start_transport_op, grpc_channel_next_op, sizeof(call_data),
init_call_elem, destroy_call_elem, sizeof(channel_data),
init_channel_elem, destroy_channel_elem, "client-auth"};
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index cf663faf2d..e79e9ce351 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -225,7 +225,7 @@ static grpc_security_status ssl_create_security_connector(
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);
+ *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
return status;
}
diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c
index 1b39ab141e..731b382f09 100644
--- a/src/core/security/secure_transport_setup.c
+++ b/src/core/security/secure_transport_setup.c
@@ -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_connector_unref(s->connector);
+ GRPC_SECURITY_CONNECTOR_UNREF(s->connector, "secure_transport_setup");
gpr_free(s);
}
@@ -234,8 +234,9 @@ static void on_handshake_data_received_from_peer(
gpr_slice_split_tail(&slices[i], consumed_slice_size));
gpr_slice_unref(slices[i]); /* split_tail above increments refcount. */
}
- gpr_slice_buffer_addn(&s->left_overs, &slices[i + 1],
- num_left_overs - (size_t)has_left_overs_in_current_slice);
+ gpr_slice_buffer_addn(
+ &s->left_overs, &slices[i + 1],
+ num_left_overs - (size_t)has_left_overs_in_current_slice);
check_peer(s);
}
@@ -275,7 +276,8 @@ void grpc_setup_secure_transport(grpc_security_connector *connector,
secure_transport_setup_done(s, 0);
return;
}
- s->connector = grpc_security_connector_ref(connector);
+ s->connector =
+ GRPC_SECURITY_CONNECTOR_REF(connector, "secure_transport_setup");
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/security_connector.c b/src/core/security/security_connector.c
index 5512bb177a..f6e423eb27 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -84,12 +84,12 @@ static const char *ssl_cipher_suites(void) {
/* -- Common methods. -- */
/* Returns the first property with that name. */
-const tsi_peer_property *tsi_peer_get_property_by_name(
- const tsi_peer *peer, const char *name) {
+const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
+ const char *name) {
size_t i;
if (peer == NULL) return NULL;
for (i = 0; i < peer->property_count; i++) {
- const tsi_peer_property* property = &peer->properties[i];
+ const tsi_peer_property *property = &peer->properties[i];
if (name == NULL && property->name == NULL) {
return property;
}
@@ -124,24 +124,44 @@ grpc_security_status grpc_channel_security_connector_check_call_host(
return sc->check_call_host(sc, host, cb, user_data);
}
-void grpc_security_connector_unref(grpc_security_connector *sc) {
- if (sc == NULL) return;
- if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
-}
-
+#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
+grpc_security_connector *grpc_security_connector_ref(
+ grpc_security_connector *sc, const char *file, int line,
+ const char *reason) {
+ if (sc == NULL) return NULL;
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "SECURITY_CONNECTOR:%p ref %d -> %d %s", sc,
+ (int)sc->refcount.count, (int)sc->refcount.count + 1, reason);
+#else
grpc_security_connector *grpc_security_connector_ref(
grpc_security_connector *sc) {
if (sc == NULL) return NULL;
+#endif
gpr_ref(&sc->refcount);
return sc;
}
+#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
+void grpc_security_connector_unref(grpc_security_connector *sc,
+ const char *file, int line,
+ const char *reason) {
+ if (sc == NULL) return;
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc,
+ (int)sc->refcount.count, (int)sc->refcount.count - 1, reason);
+#else
+void grpc_security_connector_unref(grpc_security_connector *sc) {
+ if (sc == NULL) return;
+#endif
+ if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
+}
+
static void connector_pointer_arg_destroy(void *p) {
- grpc_security_connector_unref(p);
+ GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg");
}
static void *connector_pointer_arg_copy(void *p) {
- return grpc_security_connector_ref(p);
+ return GRPC_SECURITY_CONNECTOR_REF(p, "connector_pointer_arg");
}
grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) {
@@ -196,12 +216,12 @@ typedef struct {
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);
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
static void fake_server_destroy(grpc_security_connector *sc) {
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
@@ -242,7 +262,7 @@ static grpc_security_status fake_check_peer(grpc_security_connector *sc,
status = GRPC_SECURITY_ERROR;
goto end;
}
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
sc->auth_context = grpc_auth_context_create(NULL, 1);
sc->auth_context->properties[0] = grpc_auth_property_init_from_cstring(
GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
@@ -323,7 +343,7 @@ static void ssl_channel_destroy(grpc_security_connector *sc) {
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);
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
@@ -333,7 +353,7 @@ static void ssl_server_destroy(grpc_security_connector *sc) {
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
- grpc_auth_context_unref(sc->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
gpr_free(sc);
}
@@ -437,6 +457,9 @@ static grpc_security_status ssl_check_peer(grpc_security_connector *sc,
gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
return GRPC_SECURITY_ERROR;
}
+ if (sc->auth_context != NULL) {
+ GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
+ }
sc->auth_context = tsi_ssl_peer_to_auth_context(peer);
return GRPC_SECURITY_OK;
}
@@ -577,7 +600,8 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
config->pem_private_key, config->pem_private_key_size,
config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs,
pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings,
- alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, &c->handshaker_factory);
+ alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
+ &c->handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
@@ -630,8 +654,8 @@ grpc_security_status grpc_ssl_server_security_connector_create(
(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, (uint16_t)num_alpn_protocols,
- &c->handshaker_factory);
+ alpn_protocol_strings, alpn_protocol_string_lengths,
+ (uint16_t)num_alpn_protocols, &c->handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
index ee3057b43b..a4c723f026 100644
--- a/src/core/security/security_connector.h
+++ b/src/core/security/security_connector.h
@@ -80,12 +80,25 @@ struct grpc_security_connector {
grpc_auth_context *auth_context; /* Populated after the peer is checked. */
};
-/* Increments the refcount. */
+/* Refcounting. */
+#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG
+#define GRPC_SECURITY_CONNECTOR_REF(p, r) \
+ grpc_security_connector_ref((p), __FILE__, __LINE__, (r))
+#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \
+ grpc_security_connector_unref((p), __FILE__, __LINE__, (r))
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);
+ grpc_security_connector *policy, const char *file, int line,
+ const char *reason);
+void grpc_security_connector_unref(grpc_security_connector *policy,
+ const char *file, int line,
+ const char *reason);
+#else
+#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p))
+#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p))
+grpc_security_connector *grpc_security_connector_ref(
+ grpc_security_connector *policy);
+void grpc_security_connector_unref(grpc_security_connector *policy);
+#endif
/* Handshake creation. */
grpc_security_status grpc_security_connector_create_handshaker(
@@ -172,9 +185,9 @@ typedef struct {
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);
+ 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);
@@ -200,8 +213,8 @@ grpc_security_status grpc_ssl_server_security_connector_create(
const grpc_ssl_server_config *config, grpc_security_connector **sc);
/* Util. */
-const tsi_peer_property *tsi_peer_get_property_by_name(
- const tsi_peer *peer, const char *name);
+const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
+ const char *name);
/* Exposed for testing only. */
grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer);
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 9aba1e7f91..4d56549f9b 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -89,7 +89,7 @@ grpc_client_security_context *grpc_client_security_context_create(void) {
void grpc_client_security_context_destroy(void *ctx) {
grpc_client_security_context *c = (grpc_client_security_context *)ctx;
grpc_credentials_unref(c->creds);
- grpc_auth_context_unref(c->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
gpr_free(ctx);
}
@@ -104,7 +104,7 @@ grpc_server_security_context *grpc_server_security_context_create(void) {
void grpc_server_security_context_destroy(void *ctx) {
grpc_server_security_context *c = (grpc_server_security_context *)ctx;
- grpc_auth_context_unref(c->auth_context);
+ GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context");
gpr_free(ctx);
}
@@ -120,21 +120,40 @@ grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained,
memset(ctx->properties, 0, property_count * sizeof(grpc_auth_property));
ctx->property_count = property_count;
gpr_ref_init(&ctx->refcount, 1);
- if (chained != NULL) ctx->chained = grpc_auth_context_ref(chained);
+ if (chained != NULL) ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained");
return ctx;
}
+#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
+grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx,
+ const char *file, int line,
+ const char *reason) {
+ if (ctx == NULL) return NULL;
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "AUTH_CONTEXT:%p ref %d -> %d %s", ctx, (int)ctx->refcount.count,
+ (int)ctx->refcount.count + 1, reason);
+#else
grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *ctx) {
if (ctx == NULL) return NULL;
+#endif
gpr_ref(&ctx->refcount);
return ctx;
}
+#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
+void grpc_auth_context_unref(grpc_auth_context *ctx, const char *file, int line,
+ const char *reason) {
+ if (ctx == NULL) return;
+ gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
+ "AUTH_CONTEXT:%p unref %d -> %d %s", ctx, (int)ctx->refcount.count,
+ (int)ctx->refcount.count - 1, reason);
+#else
void grpc_auth_context_unref(grpc_auth_context *ctx) {
if (ctx == NULL) return;
+#endif
if (gpr_unref(&ctx->refcount)) {
size_t i;
- grpc_auth_context_unref(ctx->chained);
+ GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained");
if (ctx->properties != NULL) {
for (i = 0; i < ctx->property_count; i++) {
grpc_auth_property_reset(&ctx->properties[i]);
@@ -223,8 +242,8 @@ grpc_auth_property grpc_auth_property_init(const char *name, const char *value,
}
void grpc_auth_property_reset(grpc_auth_property *property) {
- if (property->name != NULL) gpr_free(property->name);
- if (property->value != NULL) gpr_free(property->value);
+ gpr_free(property->name);
+ gpr_free(property->value);
memset(property, 0, sizeof(grpc_auth_property));
}
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index d8909cd6f1..20c4390898 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -55,9 +55,22 @@ grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained,
size_t property_count);
/* Refcounting. */
-grpc_auth_context *grpc_auth_context_ref(
- grpc_auth_context *ctx);
-void grpc_auth_context_unref(grpc_auth_context *ctx);
+#ifdef GRPC_AUTH_CONTEXT_REFCOUNT_DEBUG
+#define GRPC_AUTH_CONTEXT_REF(p, r) \
+ grpc_auth_context_ref((p), __FILE__, __LINE__, (r))
+#define GRPC_AUTH_CONTEXT_UNREF(p, r) \
+ grpc_auth_context_unref((p), __FILE__, __LINE__, (r))
+grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy,
+ const char *file, int line,
+ const char *reason);
+void grpc_auth_context_unref(grpc_auth_context *policy, const char *file,
+ int line, const char *reason);
+#else
+#define GRPC_AUTH_CONTEXT_REF(p, r) grpc_auth_context_ref((p))
+#define GRPC_AUTH_CONTEXT_UNREF(p, r) grpc_auth_context_unref((p))
+grpc_auth_context *grpc_auth_context_ref(grpc_auth_context *policy);
+void grpc_auth_context_unref(grpc_auth_context *policy);
+#endif
grpc_auth_property grpc_auth_property_init_from_cstring(const char *name,
const char *value);
diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c
index b19160b8ed..10eef6d237 100644
--- a/src/core/security/server_auth_filter.c
+++ b/src/core/security/server_auth_filter.c
@@ -51,24 +51,17 @@ typedef struct channel_data {
op contains type and call direction information, in addition to the data
that is being sent or received. */
static void auth_start_transport_op(grpc_call_element *elem,
- grpc_transport_op *op) {
+ grpc_transport_stream_op *op) {
/* TODO(jboeuf): Get the metadata and get a new context from it. */
/* pass control down the stack */
grpc_call_next_op(elem, op);
}
-/* Called on special channel events, such as disconnection or new incoming
- calls on the server */
-static void channel_op(grpc_channel_element *elem,
- grpc_channel_element *from_elem, grpc_channel_op *op) {
- grpc_channel_next_op(elem, op);
-}
-
/* Constructor for call_data */
static void init_call_elem(grpc_call_element *elem,
const void *server_transport_data,
- grpc_transport_op *initial_op) {
+ grpc_transport_stream_op *initial_op) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
@@ -82,20 +75,23 @@ static void init_call_elem(grpc_call_element *elem,
/* Create a security context for the call and reference the auth context from
the channel. */
+ if (initial_op->context[GRPC_CONTEXT_SECURITY].value != NULL) {
+ initial_op->context[GRPC_CONTEXT_SECURITY].destroy(
+ initial_op->context[GRPC_CONTEXT_SECURITY].value);
+ }
server_ctx = grpc_server_security_context_create();
- server_ctx->auth_context =
- grpc_auth_context_ref(chand->security_connector->auth_context);
+ server_ctx->auth_context = GRPC_AUTH_CONTEXT_REF(
+ chand->security_connector->auth_context, "server_security_context");
initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx;
initial_op->context[GRPC_CONTEXT_SECURITY].destroy =
grpc_server_security_context_destroy;
}
/* Destructor for call_data */
-static void destroy_call_elem(grpc_call_element *elem) {
-}
+static void destroy_call_elem(grpc_call_element *elem) {}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_channel_element *elem,
+static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
const grpc_channel_args *args, grpc_mdctx *mdctx,
int is_first, int is_last) {
grpc_security_connector *sc = grpc_find_security_connector_in_args(args);
@@ -111,17 +107,19 @@ static void init_channel_elem(grpc_channel_element *elem,
/* initialize members */
GPR_ASSERT(!sc->is_client_side);
- chand->security_connector = grpc_security_connector_ref(sc);
+ chand->security_connector =
+ GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter");
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */
channel_data *chand = elem->channel_data;
- grpc_security_connector_unref(chand->security_connector);
+ GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector,
+ "server_auth_filter");
}
const grpc_channel_filter grpc_server_auth_filter = {
- auth_start_transport_op, channel_op, sizeof(call_data), init_call_elem,
- destroy_call_elem, sizeof(channel_data), init_channel_elem,
- destroy_channel_elem, "server-auth"};
+ auth_start_transport_op, grpc_channel_next_op, sizeof(call_data),
+ init_call_elem, destroy_call_elem, sizeof(channel_data),
+ init_channel_elem, destroy_channel_elem, "server-auth"};
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 53afa1caad..8a7ada07af 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -70,38 +70,39 @@ static void state_unref(grpc_server_secure_state *state) {
gpr_mu_lock(&state->mu);
gpr_mu_unlock(&state->mu);
/* clean up */
- grpc_security_connector_unref(state->sc);
+ GRPC_SECURITY_CONNECTOR_UNREF(state->sc, "server");
gpr_free(state);
}
}
-static grpc_transport_setup_result setup_transport(void *statep,
- grpc_transport *transport,
- grpc_mdctx *mdctx) {
+static void setup_transport(void *statep, grpc_transport *transport,
+ grpc_mdctx *mdctx) {
static grpc_channel_filter const *extra_filters[] = {
&grpc_server_auth_filter, &grpc_http_server_filter};
grpc_server_secure_state *state = statep;
- grpc_transport_setup_result result;
grpc_arg connector_arg = grpc_security_connector_to_arg(state->sc);
grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
- grpc_server_get_channel_args(state->server), &connector_arg);
- result = grpc_server_setup_transport(state->server, transport, extra_filters,
- GPR_ARRAY_SIZE(extra_filters), mdctx,
- args_copy);
+ grpc_server_get_channel_args(state->server), &connector_arg, 1);
+ grpc_server_setup_transport(state->server, transport, extra_filters,
+ GPR_ARRAY_SIZE(extra_filters), mdctx, args_copy);
grpc_channel_args_destroy(args_copy);
- return result;
}
static void on_secure_transport_setup_done(void *statep,
grpc_security_status status,
grpc_endpoint *secure_endpoint) {
grpc_server_secure_state *state = statep;
+ grpc_transport *transport;
+ grpc_mdctx *mdctx;
if (status == GRPC_SECURITY_OK) {
gpr_mu_lock(&state->mu);
if (!state->is_shutdown) {
- grpc_create_chttp2_transport(
- setup_transport, state, grpc_server_get_channel_args(state->server),
- secure_endpoint, NULL, 0, grpc_mdctx_create(), 0);
+ mdctx = grpc_mdctx_create();
+ transport = grpc_create_chttp2_transport(
+ grpc_server_get_channel_args(state->server), secure_endpoint, mdctx,
+ 0);
+ setup_transport(state, transport, mdctx);
+ grpc_chttp2_transport_start_reading(transport, NULL, 0);
} else {
/* We need to consume this here, because the server may already have gone
* away. */
@@ -220,7 +221,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
/* Error path: cleanup and return */
error:
if (sc) {
- grpc_security_connector_unref(sc);
+ GRPC_SECURITY_CONNECTOR_UNREF(sc, "server");
}
if (resolved) {
grpc_resolved_addresses_destroy(resolved);