aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/security
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/security')
-rw-r--r--src/core/security/auth.c2
-rw-r--r--src/core/security/credentials.c235
-rw-r--r--src/core/security/credentials.h14
-rw-r--r--src/core/security/security_context.c71
-rw-r--r--src/core/security/security_context.h11
-rw-r--r--src/core/security/server_secure_chttp2.c2
6 files changed, 298 insertions, 37 deletions
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
index 6480dd2239..9ce0c69d96 100644
--- a/src/core/security/auth.c
+++ b/src/core/security/auth.c
@@ -75,7 +75,7 @@ static void call_op(grpc_call_element *elem, grpc_call_op *op) {
switch (op->type) {
case GRPC_SEND_START: {
grpc_credentials *channel_creds =
- channeld->security_context->request_metadata_only_creds;
+ channeld->security_context->request_metadata_creds;
/* TODO(jboeuf):
Decide on the policy in this case:
- populate both channel and call?
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 969a97369c..7ff48f9123 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -47,12 +47,10 @@
#include <stdio.h>
/* -- Constants. -- */
-
#define GRPC_COMPUTE_ENGINE_TOKEN_REFRESH_THRESHOLD_SECS 60
#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata"
#define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \
"computeMetadata/v1/instance/service-accounts/default/token"
-#define GRPC_AUTHORIZATION_METADATA_KEY "Authorization"
/* -- Common. -- */
@@ -108,7 +106,13 @@ int grpc_credentials_has_request_metadata_only(grpc_credentials *creds) {
void grpc_credentials_get_request_metadata(grpc_credentials *creds,
grpc_credentials_metadata_cb cb,
void *user_data) {
- if (creds == NULL || !grpc_credentials_has_request_metadata(creds)) return;
+ if (creds == NULL || !grpc_credentials_has_request_metadata(creds) ||
+ creds->vtable->get_request_metadata == NULL) {
+ if (cb != NULL) {
+ cb(user_data, NULL, 0, GRPC_CREDENTIALS_OK);
+ }
+ return;
+ }
creds->vtable->get_request_metadata(creds, cb, user_data);
}
@@ -521,14 +525,235 @@ grpc_fake_transport_security_server_credentials_create() {
return c;
}
+/* -- Composite credentials. -- */
+
+typedef struct {
+ grpc_credentials base;
+ grpc_credentials_array inner;
+} grpc_composite_credentials;
+
+typedef struct {
+ grpc_composite_credentials *composite_creds;
+ size_t creds_index;
+ grpc_mdelem **md_elems;
+ size_t num_md;
+ void *user_data;
+ grpc_credentials_metadata_cb cb;
+} grpc_composite_credentials_metadata_context;
+
+static void composite_destroy(grpc_credentials *creds) {
+ grpc_composite_credentials *c = (grpc_composite_credentials *)creds;
+ size_t i;
+ for (i = 0; i < c->inner.num_creds; i++) {
+ grpc_credentials_unref(c->inner.creds_array[i]);
+ }
+ gpr_free(c->inner.creds_array);
+ gpr_free(creds);
+}
+
+static int composite_has_request_metadata(const grpc_credentials *creds) {
+ const grpc_composite_credentials *c =
+ (const grpc_composite_credentials *)creds;
+ size_t i;
+ for (i = 0; i < c->inner.num_creds; i++) {
+ if (grpc_credentials_has_request_metadata(c->inner.creds_array[i])) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int composite_has_request_metadata_only(const grpc_credentials *creds) {
+ const grpc_composite_credentials *c =
+ (const grpc_composite_credentials *)creds;
+ size_t i;
+ for (i = 0; i < c->inner.num_creds; i++) {
+ if (!grpc_credentials_has_request_metadata_only(c->inner.creds_array[i])) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void composite_md_context_destroy(
+ grpc_composite_credentials_metadata_context *ctx) {
+ size_t i;
+ for (i = 0; i < ctx->num_md; i++) {
+ grpc_mdelem_unref(ctx->md_elems[i]);
+ }
+ gpr_free(ctx->md_elems);
+ gpr_free(ctx);
+}
+
+static void composite_metadata_cb(void *user_data, grpc_mdelem **md_elems,
+ size_t num_md,
+ grpc_credentials_status status) {
+ grpc_composite_credentials_metadata_context *ctx =
+ (grpc_composite_credentials_metadata_context *)user_data;
+ size_t i;
+ if (status != GRPC_CREDENTIALS_OK) {
+ ctx->cb(ctx->user_data, NULL, 0, status);
+ return;
+ }
+
+ /* Copy the metadata in the context. */
+ if (num_md > 0) {
+ ctx->md_elems = gpr_realloc(ctx->md_elems,
+ (ctx->num_md + num_md) * sizeof(grpc_mdelem *));
+ for (i = 0; i < num_md; i++) {
+ ctx->md_elems[i + ctx->num_md] = grpc_mdelem_ref(md_elems[i]);
+ }
+ ctx->num_md += num_md;
+ }
+
+ /* See if we need to get some more metadata. */
+ while (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
+ grpc_credentials *inner_creds =
+ ctx->composite_creds->inner.creds_array[ctx->creds_index++];
+ if (grpc_credentials_has_request_metadata(inner_creds)) {
+ grpc_credentials_get_request_metadata(inner_creds, composite_metadata_cb,
+ ctx);
+ return;
+ }
+ }
+
+ /* We're done!. */
+ ctx->cb(ctx->user_data, ctx->md_elems, ctx->num_md, GRPC_CREDENTIALS_OK);
+ composite_md_context_destroy(ctx);
+}
+
+static void composite_get_request_metadata(grpc_credentials *creds,
+ grpc_credentials_metadata_cb cb,
+ void *user_data) {
+ grpc_composite_credentials *c = (grpc_composite_credentials *)creds;
+ grpc_composite_credentials_metadata_context *ctx;
+ if (!grpc_credentials_has_request_metadata(creds)) {
+ cb(user_data, NULL, 0, GRPC_CREDENTIALS_OK);
+ return;
+ }
+ ctx = gpr_malloc(sizeof(grpc_composite_credentials_metadata_context));
+ memset(ctx, 0, sizeof(grpc_composite_credentials_metadata_context));
+ ctx->user_data = user_data;
+ ctx->cb = cb;
+ ctx->composite_creds = c;
+ while (ctx->creds_index < c->inner.num_creds) {
+ grpc_credentials *inner_creds = c->inner.creds_array[ctx->creds_index++];
+ if (grpc_credentials_has_request_metadata(inner_creds)) {
+ grpc_credentials_get_request_metadata(inner_creds, composite_metadata_cb,
+ ctx);
+ return;
+ }
+ }
+ GPR_ASSERT(0); /* Should have exited before. */
+}
-/* -- Composite credentials TODO(jboeuf). -- */
+static grpc_credentials_vtable composite_credentials_vtable = {
+ composite_destroy, composite_has_request_metadata,
+ composite_has_request_metadata_only, composite_get_request_metadata};
+
+static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) {
+ grpc_credentials_array result;
+ grpc_credentials *creds = *creds_addr;
+ result.creds_array = creds_addr;
+ result.num_creds = 1;
+ if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
+ result = *grpc_composite_credentials_get_credentials(creds);
+ }
+ return result;
+}
grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
grpc_credentials *creds2) {
- return NULL;
+ size_t i;
+ grpc_credentials_array creds1_array;
+ grpc_credentials_array creds2_array;
+ grpc_composite_credentials *c;
+ GPR_ASSERT(creds1 != NULL);
+ GPR_ASSERT(creds2 != NULL);
+ c = gpr_malloc(sizeof(grpc_composite_credentials));
+ memset(c, 0, sizeof(grpc_composite_credentials));
+ c->base.type = GRPC_CREDENTIALS_TYPE_COMPOSITE;
+ c->base.vtable = &composite_credentials_vtable;
+ gpr_ref_init(&c->base.refcount, 1);
+ 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 *));
+ for (i = 0; i < creds1_array.num_creds; i++) {
+ c->inner.creds_array[i] = grpc_credentials_ref(creds1_array.creds_array[i]);
+ }
+ for (i = 0; i < creds2_array.num_creds; i++) {
+ c->inner.creds_array[i + creds1_array.num_creds] =
+ grpc_credentials_ref(creds2_array.creds_array[i]);
+ }
+ return &c->base;
+}
+
+const grpc_credentials_array *grpc_composite_credentials_get_credentials(
+ grpc_credentials *creds) {
+ const grpc_composite_credentials *c =
+ (const grpc_composite_credentials *)creds;
+ GPR_ASSERT(!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE));
+ return &c->inner;
+}
+
+/* -- IAM credentials. -- */
+
+typedef struct {
+ grpc_credentials base;
+ grpc_mdctx *md_ctx;
+ grpc_mdelem *token_md;
+ grpc_mdelem *authority_selector_md;
+} grpc_iam_credentials;
+
+static void iam_destroy(grpc_credentials *creds) {
+ grpc_iam_credentials *c = (grpc_iam_credentials *)creds;
+ grpc_mdelem_unref(c->token_md);
+ grpc_mdelem_unref(c->authority_selector_md);
+ grpc_mdctx_orphan(c->md_ctx);
+ gpr_free(c);
+}
+
+static int iam_has_request_metadata(const grpc_credentials *creds) { return 1; }
+
+static int iam_has_request_metadata_only(const grpc_credentials *creds) {
+ return 1;
+}
+
+static void iam_get_request_metadata(grpc_credentials *creds,
+ grpc_credentials_metadata_cb cb,
+ void *user_data) {
+ grpc_iam_credentials *c = (grpc_iam_credentials *)creds;
+ grpc_mdelem *md_array[2];
+ md_array[0] = c->token_md;
+ md_array[1] = c->authority_selector_md;
+ cb(user_data, md_array, 2, GRPC_CREDENTIALS_OK);
+}
+
+static grpc_credentials_vtable iam_vtable = {
+ iam_destroy, iam_has_request_metadata, iam_has_request_metadata_only,
+ iam_get_request_metadata};
+
+grpc_credentials *grpc_iam_credentials_create(const char *token,
+ const char *authority_selector) {
+ grpc_iam_credentials *c;
+ GPR_ASSERT(token != NULL);
+ GPR_ASSERT(authority_selector != NULL);
+ c = gpr_malloc(sizeof(grpc_iam_credentials));
+ memset(c, 0, sizeof(grpc_iam_credentials));
+ c->base.type = GRPC_CREDENTIALS_TYPE_IAM;
+ c->base.vtable = &iam_vtable;
+ gpr_ref_init(&c->base.refcount, 1);
+ c->md_ctx = grpc_mdctx_create();
+ c->token_md = grpc_mdelem_from_strings(
+ c->md_ctx, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY, token);
+ c->authority_selector_md = grpc_mdelem_from_strings(
+ c->md_ctx, GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY, authority_selector);
+ return &c->base;
}
/* -- Default credentials TODO(jboeuf). -- */
grpc_credentials *grpc_default_credentials_create(void) { return NULL; }
+
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 1432611ec6..9fb82e1ecd 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -50,9 +50,15 @@ typedef enum {
#define GRPC_CREDENTIALS_TYPE_SSL "Ssl"
#define GRPC_CREDENTIALS_TYPE_OAUTH2 "Oauth2"
+#define GRPC_CREDENTIALS_TYPE_IAM "Iam"
#define GRPC_CREDENTIALS_TYPE_COMPOSITE "Composite"
#define GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY "FakeTransportSecurity"
+#define GRPC_AUTHORIZATION_METADATA_KEY "Authorization"
+#define GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY \
+ "x-goog-iam-authorization-token"
+#define GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY "x-goog-iam-authority-selector"
+
/* --- grpc_credentials. --- */
typedef void (*grpc_credentials_metadata_cb)(void *user_data,
@@ -94,6 +100,14 @@ typedef struct {
const grpc_ssl_config *grpc_ssl_credentials_get_config(
const grpc_credentials *ssl_creds);
+typedef struct {
+ grpc_credentials **creds_array;
+ size_t num_creds;
+} grpc_credentials_array;
+
+const grpc_credentials_array *grpc_composite_credentials_get_credentials(
+ grpc_credentials *composite_creds);
+
/* Exposed for testing only. */
grpc_credentials_status grpc_compute_engine_credentials_parse_server_response(
const struct grpc_httpcli_response *response, grpc_mdctx *ctx,
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index beda64cba2..c56692ae83 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -37,6 +37,8 @@
#include "src/core/endpoint/secure_endpoint.h"
#include "src/core/security/credentials.h"
+#include "src/core/surface/lame_client.h"
+#include "src/core/transport/chttp2/alpn.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/slice_buffer.h>
@@ -47,7 +49,6 @@
/* -- Constants. -- */
-#define GRPC_ALPN_PROTOCOL_STRING "h2-15"
/* Defines the cipher suites that we accept. All these cipher suites are
compliant with TLS 1.2 and use an RSA public key. We prefer GCM over CBC
and ECDHE-RSA over just RSA. */
@@ -122,11 +123,11 @@ grpc_security_context *grpc_find_security_context_in_args(
return NULL;
}
-static int check_request_metadata_only_creds(grpc_credentials *creds) {
- if (creds != NULL && !grpc_credentials_has_request_metadata_only(creds)) {
+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 "
- "only set request metadata.");
+ "set request metadata.");
return 0;
}
return 1;
@@ -136,7 +137,7 @@ static int check_request_metadata_only_creds(grpc_credentials *creds) {
static void fake_channel_destroy(grpc_security_context *ctx) {
grpc_channel_security_context *c = (grpc_channel_security_context *)ctx;
- grpc_credentials_unref(c->request_metadata_only_creds);
+ grpc_credentials_unref(c->request_metadata_creds);
gpr_free(ctx);
}
@@ -191,15 +192,14 @@ static grpc_security_context_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_credentials *request_metadata_only_creds) {
+ grpc_credentials *request_metadata_creds) {
grpc_channel_security_context *c =
gpr_malloc(sizeof(grpc_channel_security_context));
gpr_ref_init(&c->base.refcount, 1);
c->base.is_client_side = 1;
c->base.vtable = &fake_channel_vtable;
- GPR_ASSERT(check_request_metadata_only_creds(request_metadata_only_creds));
- c->request_metadata_only_creds =
- grpc_credentials_ref(request_metadata_only_creds);
+ GPR_ASSERT(check_request_metadata_creds(request_metadata_creds));
+ c->request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
return c;
}
@@ -226,7 +226,7 @@ typedef struct {
static void ssl_channel_destroy(grpc_security_context *ctx) {
grpc_ssl_channel_security_context *c =
(grpc_ssl_channel_security_context *)ctx;
- grpc_credentials_unref(c->base.request_metadata_only_creds);
+ grpc_credentials_unref(c->base.request_metadata_creds);
if (c->handshaker_factory != NULL) {
tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
}
@@ -282,8 +282,8 @@ static grpc_security_status ssl_check_peer(const char *secure_peer_name,
gpr_log(GPR_ERROR, "Invalid or missing selected ALPN property.");
return GRPC_SECURITY_ERROR;
}
- if (strncmp(GRPC_ALPN_PROTOCOL_STRING, p->value.string.data,
- p->value.string.length)) {
+ if (!grpc_chttp2_is_alpn_version_supported(p->value.string.data,
+ p->value.string.length)) {
gpr_log(GPR_ERROR, "Invalid ALPN value.");
return GRPC_SECURITY_ERROR;
}
@@ -320,10 +320,9 @@ static grpc_security_context_vtable ssl_server_vtable = {
ssl_server_destroy, ssl_server_create_handshaker, ssl_server_check_peer};
grpc_security_status grpc_ssl_channel_security_context_create(
- grpc_credentials *request_metadata_only_creds,
- const grpc_ssl_config *config, const char *secure_peer_name,
- grpc_channel_security_context **ctx) {
- const char *alpn_protocol_string = GRPC_ALPN_PROTOCOL_STRING;
+ grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
+ const char *secure_peer_name, grpc_channel_security_context **ctx) {
+ const char *alpn_protocol_string = GRPC_CHTTP2_ALPN_VERSION;
unsigned char alpn_protocol_string_len =
(unsigned char)strlen(alpn_protocol_string);
tsi_result result = TSI_OK;
@@ -334,7 +333,7 @@ grpc_security_status grpc_ssl_channel_security_context_create(
gpr_log(GPR_ERROR, "An ssl channel needs a secure name and root certs.");
return GRPC_SECURITY_ERROR;
}
- if (!check_request_metadata_only_creds(request_metadata_only_creds)) {
+ if (!check_request_metadata_creds(request_metadata_creds)) {
return GRPC_SECURITY_ERROR;
}
@@ -344,8 +343,7 @@ grpc_security_status grpc_ssl_channel_security_context_create(
gpr_ref_init(&c->base.base.refcount, 1);
c->base.base.vtable = &ssl_channel_vtable;
c->base.base.is_client_side = 1;
- c->base.request_metadata_only_creds =
- grpc_credentials_ref(request_metadata_only_creds);
+ c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
if (secure_peer_name != NULL) {
c->secure_peer_name = gpr_strdup(secure_peer_name);
}
@@ -368,7 +366,7 @@ grpc_security_status grpc_ssl_channel_security_context_create(
grpc_security_status grpc_ssl_server_security_context_create(
const grpc_ssl_config *config, grpc_security_context **ctx) {
- const char *alpn_protocol_string = GRPC_ALPN_PROTOCOL_STRING;
+ const char *alpn_protocol_string = GRPC_CHTTP2_ALPN_VERSION;
unsigned char alpn_protocol_string_len =
(unsigned char)strlen(alpn_protocol_string);
tsi_result result = TSI_OK;
@@ -427,7 +425,7 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
status = grpc_ssl_channel_security_context_create(creds, config,
secure_peer_name, &ctx);
if (status != GRPC_SECURITY_OK) {
- return NULL; /* TODO(ctiller): return lame channel. */
+ return grpc_lame_client_channel_create();
}
channel = grpc_secure_channel_create_internal(target, args, ctx);
grpc_security_context_unref(&ctx->base);
@@ -435,13 +433,38 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
}
+static grpc_credentials *get_creds_from_composite(
+ grpc_credentials *composite_creds, const char *type) {
+ size_t i;
+ const grpc_credentials_array *inner_creds_array =
+ grpc_composite_credentials_get_credentials(composite_creds);
+ for (i = 0; i < inner_creds_array->num_creds; i++) {
+ if (!strcmp(type, inner_creds_array->creds_array[i]->type)) {
+ return inner_creds_array->creds_array[i];
+ }
+ }
+ return NULL;
+}
+
+static grpc_channel *grpc_channel_create_from_composite_creds(
+ grpc_credentials *composite_creds, const char *target,
+ const grpc_channel_args *args) {
+ grpc_credentials *creds =
+ get_creds_from_composite(composite_creds, GRPC_CREDENTIALS_TYPE_SSL);
+ if (creds != NULL) {
+ return grpc_ssl_channel_create(
+ composite_creds, grpc_ssl_credentials_get_config(creds), target, args);
+ }
+ return NULL; /* TODO(ctiller): return lame channel. */
+}
+
grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
const char *target,
const grpc_channel_args *args) {
if (grpc_credentials_has_request_metadata_only(creds)) {
gpr_log(GPR_ERROR,
"Credentials is insufficient to create a secure channel.");
- return NULL; /* TODO(ctiller): return lame channel. */
+ return grpc_lame_client_channel_create();
}
if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
return grpc_ssl_channel_create(NULL, grpc_ssl_credentials_get_config(creds),
@@ -455,11 +478,11 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
grpc_security_context_unref(&ctx->base);
return channel;
} else if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE)) {
- return NULL; /* TODO(jboeuf) Implement. */
+ return grpc_channel_create_from_composite_creds(creds, target, args);
} else {
gpr_log(GPR_ERROR,
"Unknown credentials type %s for creating a secure channel.");
- return NULL; /* TODO(ctiller): return lame channel. */
+ return grpc_lame_client_channel_create();
}
}
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index 59c9bbdf34..0c6025643a 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -119,7 +119,7 @@ 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_only_creds;
+ grpc_credentials *request_metadata_creds;
};
/* --- Creation security contexts. --- */
@@ -127,14 +127,14 @@ struct grpc_channel_security_context {
/* 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_only_creds);
+ grpc_credentials *request_metadata_creds);
/* 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_only_creds is the credentials object which metadata
+ - 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.
@@ -147,9 +147,8 @@ grpc_security_context *grpc_fake_server_security_context_create(void);
specific error code otherwise.
*/
grpc_security_status grpc_ssl_channel_security_context_create(
- grpc_credentials *request_metadata_only_creds,
- const grpc_ssl_config *config, const char *secure_peer_name,
- grpc_channel_security_context **ctx);
+ grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
+ const char *secure_peer_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.
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index bce27ec3ab..335d502217 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -109,7 +109,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) {
for (i = 0; i < resolved->naddrs; i++) {
if (grpc_tcp_server_add_port(tcp,
(struct sockaddr *)&resolved->addrs[i].addr,
- resolved->addrs[i].len) >= 0) {
+ resolved->addrs[i].len)) {
count++;
}
}