Changing the API to use a callback mechanism.

This is the agreed-upon solution.
pull/4934/head
Julien Boeuf 9 years ago
parent 564b915503
commit aaebf7ae74
  1. 27
      include/grpc/grpc_security.h
  2. 20
      src/core/security/security_connector.c
  3. 23
      test/core/security/security_connector_test.c

@ -143,14 +143,29 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void);
#define GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR \
"GRPC_DEFAULT_SSL_ROOTS_FILE_PATH"
/* Overrides the default TLS/SSL roots.
The roots must be encoded as PEM and NULL-terminated.
/* Results for the SSL roots override callback. */
typedef enum {
GRPC_SSL_ROOTS_OVERRIDE_OK,
GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY, /* Do not try fallback options. */
GRPC_SSL_ROOTS_OVERRIDE_FAIL
} grpc_ssl_roots_override_result;
/* Callback for getting the SSL roots override from the application.
In case of success, *pem_roots_certs must be set to a NULL terminated string
containing the list of PEM encoded root certificates. The ownership is passed
to the core and freed (laster by the core) with gpr_free.
If this function fails and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is
set to a valid path, it will override the roots specified this func */
typedef grpc_ssl_roots_override_result (*grpc_ssl_roots_override_callback)(
char **pem_root_certs);
/* Setup a callback to override the default TLS/SSL roots.
This function is not thread-safe and must be called at initialization time
before any ssl credentials are created to have the desired side effect.
It also does not do any checks about the validity of the encoding.
If the GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is set to a valid path,
it will override the roots specified in this function. */
void grpc_override_ssl_default_roots(const char *roots_pem);
If GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is set to a valid path, the
callback will not be called. */
void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb);
/* Object that holds a private key / certificate chain pair in PEM format. */
typedef struct {

@ -63,10 +63,10 @@ static const char *installed_roots_path =
/* -- Overridden default roots. -- */
static gpr_slice overridden_default_roots;
static grpc_ssl_roots_override_callback ssl_roots_override_cb = NULL;
void grpc_override_ssl_default_roots(const char *roots_pem) {
overridden_default_roots = gpr_slice_from_copied_string(roots_pem);
void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
ssl_roots_override_cb = cb;
}
/* -- Cipher suites. -- */
@ -615,13 +615,19 @@ static gpr_slice compute_default_pem_root_certs_once(void) {
}
/* Try overridden roots path if needed. */
if (GPR_SLICE_IS_EMPTY(result) &&
!GPR_SLICE_IS_EMPTY(overridden_default_roots)) {
result = gpr_slice_ref(overridden_default_roots);
grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL;
if (GPR_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != NULL) {
char *pem_root_certs = NULL;
ovrd_res = ssl_roots_override_cb(&pem_root_certs);
if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) {
GPR_ASSERT(pem_root_certs != NULL);
result = gpr_slice_new(pem_root_certs, strlen(pem_root_certs), gpr_free);
}
}
/* Fall back to installed certs if needed. */
if (GPR_SLICE_IS_EMPTY(result)) {
if (GPR_SLICE_IS_EMPTY(result) &&
ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) {
result = gpr_load_file(installed_roots_path, 0, NULL);
}
return result;

@ -47,6 +47,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
static int check_transport_security_type(const grpc_auth_context *ctx) {
@ -300,8 +301,20 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(
GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
}
static const char *roots_for_override_api = "roots for override api";
static grpc_ssl_roots_override_result override_roots_success(
char **pem_root_certs) {
*pem_root_certs = gpr_strdup(roots_for_override_api);
return GRPC_SSL_ROOTS_OVERRIDE_OK;
}
static grpc_ssl_roots_override_result override_roots_permanent_failure(
char **pem_root_certs) {
return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY;
}
static void test_default_ssl_roots(void) {
const char *roots_for_override_api = "roots for override api";
const char *roots_for_env_var = "roots for env var";
char *roots_env_var_file_path;
@ -311,7 +324,7 @@ static void test_default_ssl_roots(void) {
fclose(roots_env_var_file);
/* First let's get the root through the override (no env are set). */
grpc_override_ssl_default_roots(roots_for_override_api);
grpc_set_ssl_roots_override_callback(override_roots_success);
gpr_slice roots = grpc_get_default_ssl_roots_for_testing();
char *roots_contents = gpr_dump_slice(roots, GPR_DUMP_ASCII);
gpr_slice_unref(roots);
@ -336,6 +349,12 @@ static void test_default_ssl_roots(void) {
GPR_ASSERT(strcmp(roots_contents, roots_for_override_api) == 0);
gpr_free(roots_contents);
/* Now setup a permanent failure for the overridden roots and we should get
an empty slice. */
grpc_set_ssl_roots_override_callback(override_roots_permanent_failure);
roots = grpc_get_default_ssl_roots_for_testing();
GPR_ASSERT(GPR_SLICE_IS_EMPTY(roots));
/* Cleanup. */
remove(roots_env_var_file_path);
gpr_free(roots_env_var_file_path);

Loading…
Cancel
Save