Cleanup error handling for google_default_credentials

pull/6897/head
Craig Tiller 9 years ago
parent e451225f70
commit 4727b9be84
  1. 2
      src/core/lib/iomgr/error.c
  2. 1
      src/core/lib/iomgr/error.h
  3. 64
      src/core/lib/security/credentials/google_default/google_default_credentials.c
  4. 6
      src/core/lib/security/transport/security_connector.c
  5. 30
      src/core/lib/support/load_file.c
  6. 9
      src/core/lib/support/load_file.h
  7. 8
      test/core/security/credentials_test.c

@ -134,6 +134,8 @@ static const char *error_str_name(grpc_error_strs key) {
return "raw_bytes"; return "raw_bytes";
case GRPC_ERROR_STR_TSI_ERROR: case GRPC_ERROR_STR_TSI_ERROR:
return "tsi_error"; return "tsi_error";
case GRPC_ERROR_STR_FILENAME:
return "filename";
} }
GPR_UNREACHABLE_CODE(return "unknown"); GPR_UNREACHABLE_CODE(return "unknown");
} }

@ -78,6 +78,7 @@ typedef enum {
GRPC_ERROR_STR_GRPC_MESSAGE, GRPC_ERROR_STR_GRPC_MESSAGE,
GRPC_ERROR_STR_RAW_BYTES, GRPC_ERROR_STR_RAW_BYTES,
GRPC_ERROR_STR_TSI_ERROR, GRPC_ERROR_STR_TSI_ERROR,
GRPC_ERROR_STR_FILENAME,
} grpc_error_strs; } grpc_error_strs;
typedef enum { typedef enum {

@ -45,6 +45,7 @@
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h" #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
#include "src/core/lib/support/env.h" #include "src/core/lib/support/env.h"
#include "src/core/lib/support/load_file.h" #include "src/core/lib/support/load_file.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/api_trace.h"
/* -- Constants. -- */ /* -- Constants. -- */
@ -154,19 +155,31 @@ static int is_stack_running_on_compute_engine(void) {
} }
/* Takes ownership of creds_path if not NULL. */ /* Takes ownership of creds_path if not NULL. */
static grpc_call_credentials *create_default_creds_from_path(char *creds_path) { static grpc_error *create_default_creds_from_path(
char *creds_path, grpc_call_credentials **creds) {
grpc_json *json = NULL; grpc_json *json = NULL;
grpc_auth_json_key key; grpc_auth_json_key key;
grpc_auth_refresh_token token; grpc_auth_refresh_token token;
grpc_call_credentials *result = NULL; grpc_call_credentials *result = NULL;
gpr_slice creds_data = gpr_empty_slice(); gpr_slice creds_data = gpr_empty_slice();
int file_ok = 0; grpc_error *error = GRPC_ERROR_NONE;
if (creds_path == NULL) goto end; if (creds_path == NULL) {
creds_data = gpr_load_file(creds_path, 0, &file_ok); error = GRPC_ERROR_CREATE("creds_path unset");
if (!file_ok) goto end; goto end;
}
error = gpr_load_file(creds_path, 0, &creds_data);
if (error != GRPC_ERROR_NONE) {
goto end;
}
json = grpc_json_parse_string_with_len( json = grpc_json_parse_string_with_len(
(char *)GPR_SLICE_START_PTR(creds_data), GPR_SLICE_LENGTH(creds_data)); (char *)GPR_SLICE_START_PTR(creds_data), GPR_SLICE_LENGTH(creds_data));
if (json == NULL) goto end; if (json == NULL) {
char *dump = gpr_dump_slice(creds_data, GPR_DUMP_HEX | GPR_DUMP_ASCII);
error = grpc_error_set_str(GRPC_ERROR_CREATE("Failed to parse JSON"),
GRPC_ERROR_STR_RAW_BYTES, dump);
gpr_free(dump);
goto end;
}
/* First, try an auth json key. */ /* First, try an auth json key. */
key = grpc_auth_json_key_create_from_json(json); key = grpc_auth_json_key_create_from_json(json);
@ -174,6 +187,11 @@ static grpc_call_credentials *create_default_creds_from_path(char *creds_path) {
result = result =
grpc_service_account_jwt_access_credentials_create_from_auth_json_key( grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
key, grpc_max_auth_token_lifetime()); key, grpc_max_auth_token_lifetime());
if (result == NULL) {
error = GRPC_ERROR_CREATE(
"grpc_service_account_jwt_access_credentials_create_from_auth_json_"
"key failed");
}
goto end; goto end;
} }
@ -182,19 +200,28 @@ static grpc_call_credentials *create_default_creds_from_path(char *creds_path) {
if (grpc_auth_refresh_token_is_valid(&token)) { if (grpc_auth_refresh_token_is_valid(&token)) {
result = result =
grpc_refresh_token_credentials_create_from_auth_refresh_token(token); grpc_refresh_token_credentials_create_from_auth_refresh_token(token);
if (result == NULL) {
error = GRPC_ERROR_CREATE(
"grpc_refresh_token_credentials_create_from_auth_refresh_token "
"failed");
}
goto end; goto end;
} }
end: end:
GPR_ASSERT((result == NULL) + (error == GRPC_ERROR_NONE) == 1);
if (creds_path != NULL) gpr_free(creds_path); if (creds_path != NULL) gpr_free(creds_path);
gpr_slice_unref(creds_data); gpr_slice_unref(creds_data);
if (json != NULL) grpc_json_destroy(json); if (json != NULL) grpc_json_destroy(json);
return result; *creds = result;
return error;
} }
grpc_channel_credentials *grpc_google_default_credentials_create(void) { grpc_channel_credentials *grpc_google_default_credentials_create(void) {
grpc_channel_credentials *result = NULL; grpc_channel_credentials *result = NULL;
grpc_call_credentials *call_creds = NULL; grpc_call_credentials *call_creds = NULL;
grpc_error *error = GRPC_ERROR_CREATE("Failed to create Google credentials");
grpc_error *err;
GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ()); GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ());
@ -208,14 +235,16 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void) {
} }
/* First, try the environment variable. */ /* First, try the environment variable. */
call_creds = create_default_creds_from_path( err = create_default_creds_from_path(
gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR)); gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR), &call_creds);
if (call_creds != NULL) goto end; if (err == GRPC_ERROR_NONE) goto end;
error = grpc_error_add_child(error, err);
/* Then the well-known file. */ /* Then the well-known file. */
call_creds = create_default_creds_from_path( err = create_default_creds_from_path(
grpc_get_well_known_google_credentials_file_path()); grpc_get_well_known_google_credentials_file_path(), &call_creds);
if (call_creds != NULL) goto end; if (err == GRPC_ERROR_NONE) goto end;
error = grpc_error_add_child(error, err);
/* At last try to see if we're on compute engine (do the detection only once /* At last try to see if we're on compute engine (do the detection only once
since it requires a network test). */ since it requires a network test). */
@ -224,6 +253,10 @@ grpc_channel_credentials *grpc_google_default_credentials_create(void) {
compute_engine_detection_done = 1; compute_engine_detection_done = 1;
if (need_compute_engine_creds) { if (need_compute_engine_creds) {
call_creds = grpc_google_compute_engine_credentials_create(NULL); call_creds = grpc_google_compute_engine_credentials_create(NULL);
if (call_creds == NULL) {
error = grpc_error_add_child(
error, GRPC_ERROR_CREATE("Failed to get credentials from network"));
}
} }
} }
@ -247,6 +280,11 @@ end:
} }
} }
gpr_mu_unlock(&g_state_mu); gpr_mu_unlock(&g_state_mu);
if (result == NULL) {
GRPC_LOG_IF_ERROR("grpc_google_default_credentials_create", error);
} else {
GRPC_ERROR_UNREF(error);
}
return result; return result;
} }

@ -635,7 +635,8 @@ static gpr_slice compute_default_pem_root_certs_once(void) {
char *default_root_certs_path = char *default_root_certs_path =
gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR);
if (default_root_certs_path != NULL) { if (default_root_certs_path != NULL) {
result = gpr_load_file(default_root_certs_path, 0, NULL); GRPC_LOG_IF_ERROR("load_file",
gpr_load_file(default_root_certs_path, 0, &result));
gpr_free(default_root_certs_path); gpr_free(default_root_certs_path);
} }
@ -653,7 +654,8 @@ static gpr_slice compute_default_pem_root_certs_once(void) {
/* Fall back to installed certs if needed. */ /* 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) { ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) {
result = gpr_load_file(installed_roots_path, 0, NULL); GRPC_LOG_IF_ERROR("load_file",
gpr_load_file(installed_roots_path, 0, &result));
} }
return result; return result;
} }

@ -43,21 +43,19 @@
#include "src/core/lib/support/block_annotate.h" #include "src/core/lib/support/block_annotate.h"
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
gpr_slice gpr_load_file(const char *filename, int add_null_terminator, grpc_error *gpr_load_file(const char *filename, int add_null_terminator,
int *success) { gpr_slice *output) {
unsigned char *contents = NULL; unsigned char *contents = NULL;
size_t contents_size = 0; size_t contents_size = 0;
char *error_msg = NULL;
gpr_slice result = gpr_empty_slice(); gpr_slice result = gpr_empty_slice();
FILE *file; FILE *file;
size_t bytes_read = 0; size_t bytes_read = 0;
grpc_error *error = GRPC_ERROR_NONE;
GRPC_SCHEDULING_START_BLOCKING_REGION; GRPC_SCHEDULING_START_BLOCKING_REGION;
file = fopen(filename, "rb"); file = fopen(filename, "rb");
if (file == NULL) { if (file == NULL) {
gpr_asprintf(&error_msg, "Could not open file %s (error = %s).", filename, error = GRPC_OS_ERROR(errno, "fopen");
strerror(errno));
GPR_ASSERT(error_msg != NULL);
goto end; goto end;
} }
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
@ -67,25 +65,25 @@ gpr_slice gpr_load_file(const char *filename, int add_null_terminator,
contents = gpr_malloc(contents_size + (add_null_terminator ? 1 : 0)); contents = gpr_malloc(contents_size + (add_null_terminator ? 1 : 0));
bytes_read = fread(contents, 1, contents_size, file); bytes_read = fread(contents, 1, contents_size, file);
if (bytes_read < contents_size) { if (bytes_read < contents_size) {
error = GRPC_OS_ERROR(errno, "fread");
GPR_ASSERT(ferror(file)); GPR_ASSERT(ferror(file));
gpr_asprintf(&error_msg, "Error %s occured while reading file %s.",
strerror(errno), filename);
GPR_ASSERT(error_msg != NULL);
goto end; goto end;
} }
if (success != NULL) *success = 1;
if (add_null_terminator) { if (add_null_terminator) {
contents[contents_size++] = 0; contents[contents_size++] = 0;
} }
result = gpr_slice_new(contents, contents_size, gpr_free); result = gpr_slice_new(contents, contents_size, gpr_free);
end: end:
if (error_msg != NULL) { *output = result;
gpr_log(GPR_ERROR, "%s", error_msg);
gpr_free(error_msg);
if (success != NULL) *success = 0;
}
if (file != NULL) fclose(file); if (file != NULL) fclose(file);
if (error != GRPC_ERROR_NONE) {
grpc_error *error_out = grpc_error_set_str(
GRPC_ERROR_CREATE_REFERENCING("Failed to load file", &error, 1),
GRPC_ERROR_STR_FILENAME, filename);
GRPC_ERROR_UNREF(error);
error = error_out;
}
GRPC_SCHEDULING_END_BLOCKING_REGION; GRPC_SCHEDULING_END_BLOCKING_REGION;
return result; return error;
} }

@ -38,15 +38,16 @@
#include <grpc/support/slice.h> #include <grpc/support/slice.h>
#include "src/core/lib/iomgr/error.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* Loads the content of a file into a slice. add_null_terminator will add /* Loads the content of a file into a slice. add_null_terminator will add
a NULL terminator if non-zero. The success parameter, if not NULL, a NULL terminator if non-zero. */
will be set to 1 in case of success and 0 in case of failure. */ grpc_error *gpr_load_file(const char *filename, int add_null_terminator,
gpr_slice gpr_load_file(const char *filename, int add_null_terminator, gpr_slice *slice);
int *success);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -901,11 +901,11 @@ static int default_creds_gce_detection_httpcli_get_success_override(
gpr_timespec deadline, grpc_closure *on_done, gpr_timespec deadline, grpc_closure *on_done,
grpc_httpcli_response *response) { grpc_httpcli_response *response) {
*response = http_response(200, ""); *response = http_response(200, "");
grpc_http_header header; grpc_http_header *headers = gpr_malloc(sizeof(*headers) * 1);
header.key = "Metadata-Flavor"; headers[0].key = "Metadata-Flavor";
header.value = "Google"; headers[0].value = "Google";
response->hdr_count = 1; response->hdr_count = 1;
response->hdrs = &header; response->hdrs = headers;
GPR_ASSERT(strcmp(request->http.path, "/") == 0); GPR_ASSERT(strcmp(request->http.path, "/") == 0);
GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
grpc_exec_ctx_push(exec_ctx, on_done, GRPC_ERROR_NONE, NULL); grpc_exec_ctx_push(exec_ctx, on_done, GRPC_ERROR_NONE, NULL);

Loading…
Cancel
Save