Merge pull request #710 from jboeuf/default_google_creds

Added support for default credentials.
changes/54/217554/1^2
Craig Tiller 10 years ago
commit 74ae8f61d9
  1. 43
      Makefile
  2. 17
      build.json
  3. 20
      include/grpc++/credentials.h
  4. 17
      include/grpc/grpc_security.h
  5. 1
      src/core/httpcli/httpcli.c
  6. 4
      src/core/security/credentials.c
  7. 7
      src/core/security/credentials.h
  8. 60
      src/core/security/credentials_posix.c
  9. 60
      src/core/security/credentials_win32.c
  10. 185
      src/core/security/google_default_credentials.c
  11. 6
      src/core/security/security_context.c
  12. 18
      src/cpp/client/credentials.cc
  13. 107
      test/core/security/print_google_default_creds_token.c
  14. 2
      test/cpp/util/create_test_channel.cc
  15. 8
      vsprojects/vs2013/Grpc.mak
  16. 6
      vsprojects/vs2013/grpc.vcxproj
  17. 9
      vsprojects/vs2013/grpc.vcxproj.filters
  18. 6
      vsprojects/vs2013/grpc_shared.vcxproj
  19. 9
      vsprojects/vs2013/grpc_shared.vcxproj.filters

@ -481,6 +481,7 @@ grpc_create_jwt: $(BINDIR)/$(CONFIG)/grpc_create_jwt
grpc_credentials_test: $(BINDIR)/$(CONFIG)/grpc_credentials_test
grpc_fetch_oauth2: $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2
grpc_json_token_test: $(BINDIR)/$(CONFIG)/grpc_json_token_test
grpc_print_google_default_creds_token: $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token
grpc_stream_op_test: $(BINDIR)/$(CONFIG)/grpc_stream_op_test
hpack_parser_test: $(BINDIR)/$(CONFIG)/hpack_parser_test
hpack_table_test: $(BINDIR)/$(CONFIG)/hpack_table_test
@ -1763,7 +1764,7 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/thread_pool_test || ( echo test thread_pool_test failed ; exit 1 )
tools: privatelibs $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2
tools: privatelibs $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token
buildbenchmarks: privatelibs $(BINDIR)/$(CONFIG)/grpc_completion_queue_benchmark $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark
@ -2288,7 +2289,10 @@ LIBGRPC_SRC = \
src/core/security/auth.c \
src/core/security/base64.c \
src/core/security/credentials.c \
src/core/security/credentials_posix.c \
src/core/security/credentials_win32.c \
src/core/security/factories.c \
src/core/security/google_default_credentials.c \
src/core/security/json_token.c \
src/core/security/secure_endpoint.c \
src/core/security/secure_transport_setup.c \
@ -2429,7 +2433,10 @@ src/core/httpcli/parser.c: $(OPENSSL_DEP)
src/core/security/auth.c: $(OPENSSL_DEP)
src/core/security/base64.c: $(OPENSSL_DEP)
src/core/security/credentials.c: $(OPENSSL_DEP)
src/core/security/credentials_posix.c: $(OPENSSL_DEP)
src/core/security/credentials_win32.c: $(OPENSSL_DEP)
src/core/security/factories.c: $(OPENSSL_DEP)
src/core/security/google_default_credentials.c: $(OPENSSL_DEP)
src/core/security/json_token.c: $(OPENSSL_DEP)
src/core/security/secure_endpoint.c: $(OPENSSL_DEP)
src/core/security/secure_transport_setup.c: $(OPENSSL_DEP)
@ -2587,7 +2594,10 @@ $(OBJDIR)/$(CONFIG)/src/core/httpcli/parser.o:
$(OBJDIR)/$(CONFIG)/src/core/security/auth.o:
$(OBJDIR)/$(CONFIG)/src/core/security/base64.o:
$(OBJDIR)/$(CONFIG)/src/core/security/credentials.o:
$(OBJDIR)/$(CONFIG)/src/core/security/credentials_posix.o:
$(OBJDIR)/$(CONFIG)/src/core/security/credentials_win32.o:
$(OBJDIR)/$(CONFIG)/src/core/security/factories.o:
$(OBJDIR)/$(CONFIG)/src/core/security/google_default_credentials.o:
$(OBJDIR)/$(CONFIG)/src/core/security/json_token.o:
$(OBJDIR)/$(CONFIG)/src/core/security/secure_endpoint.o:
$(OBJDIR)/$(CONFIG)/src/core/security/secure_transport_setup.o:
@ -6551,6 +6561,37 @@ endif
endif
GRPC_PRINT_GOOGLE_DEFAULT_CREDS_TOKEN_SRC = \
test/core/security/print_google_default_creds_token.c \
GRPC_PRINT_GOOGLE_DEFAULT_CREDS_TOKEN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_PRINT_GOOGLE_DEFAULT_CREDS_TOKEN_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL with ALPN.
$(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token: $(GRPC_PRINT_GOOGLE_DEFAULT_CREDS_TOKEN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GRPC_PRINT_GOOGLE_DEFAULT_CREDS_TOKEN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token
endif
$(OBJDIR)/$(CONFIG)/test/core/security/print_google_default_creds_token.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_grpc_print_google_default_creds_token: $(GRPC_PRINT_GOOGLE_DEFAULT_CREDS_TOKEN_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GRPC_PRINT_GOOGLE_DEFAULT_CREDS_TOKEN_OBJS:.o=.dep)
endif
endif
GRPC_STREAM_OP_TEST_SRC = \
test/core/transport/stream_op_test.c \

@ -320,7 +320,10 @@
"src/core/security/auth.c",
"src/core/security/base64.c",
"src/core/security/credentials.c",
"src/core/security/credentials_posix.c",
"src/core/security/credentials_win32.c",
"src/core/security/factories.c",
"src/core/security/google_default_credentials.c",
"src/core/security/json_token.c",
"src/core/security/secure_endpoint.c",
"src/core/security/secure_transport_setup.c",
@ -1186,6 +1189,20 @@
"gpr"
]
},
{
"name": "grpc_print_google_default_creds_token",
"build": "tool",
"language": "c",
"src": [
"test/core/security/print_google_default_creds_token.c"
],
"deps": [
"grpc_test_util",
"grpc",
"gpr_test_util",
"gpr"
]
},
{
"name": "grpc_stream_op_test",
"build": "test",

@ -86,17 +86,23 @@ struct SslCredentialsOptions {
// fail on it.
class CredentialsFactory {
public:
// Builds credentials with reasonable defaults.
static std::unique_ptr<Credentials> DefaultCredentials();
// Builds google credentials with reasonable defaults.
// WARNING: Do NOT use this credentials to connect to a non-google service as
// this could result in an oauth2 token leak.
static std::unique_ptr<Credentials> GoogleDefaultCredentials();
// Builds SSL Credentials given SSL specific options
static std::unique_ptr<Credentials> SslCredentials(
const SslCredentialsOptions& options);
// Builds credentials for use when running in GCE
// WARNING: Do NOT use this credentials to connect to a non-google service as
// this could result in an oauth2 token leak.
static std::unique_ptr<Credentials> ComputeEngineCredentials();
// Builds service account credentials.
// WARNING: Do NOT use this credentials to connect to a non-google service as
// this could result in an oauth2 token leak.
// json_key is the JSON key string containing the client's private key.
// scope is a space-delimited list of the requested permissions.
// token_lifetime is the lifetime of each token acquired through this service
@ -106,13 +112,21 @@ class CredentialsFactory {
const grpc::string& json_key, const grpc::string& scope,
std::chrono::seconds token_lifetime);
// Builds JWT credentials.
// json_key is the JSON key string containing the client's private key.
// token_lifetime is the lifetime of each Json Web Token (JWT) created with
// this credentials. It should not exceed grpc_max_auth_token_lifetime or
// will be cropped to this value.
static std::unique_ptr<Credentials> JWTCredentials(
const grpc::string& json_key, std::chrono::seconds token_lifetime);
// Builds IAM credentials.
static std::unique_ptr<Credentials> IAMCredentials(
const grpc::string& authorization_token,
const grpc::string& authority_selector);
// Combines two credentials objects into a composite credentials
static std::unique_ptr<Credentials> ComposeCredentials(
static std::unique_ptr<Credentials> CompositeCredentials(
const std::unique_ptr<Credentials>& creds1,
const std::unique_ptr<Credentials>& creds2);
};

@ -51,8 +51,10 @@ typedef struct grpc_credentials grpc_credentials;
The creator of the credentials object is responsible for its release. */
void grpc_credentials_release(grpc_credentials *creds);
/* Creates default credentials. */
grpc_credentials *grpc_default_credentials_create(void);
/* Creates default credentials to connect to a google gRPC service.
WARNING: Do NOT use this credentials to connect to a non-google service as
this could result in an oauth2 token leak. */
grpc_credentials *grpc_google_default_credentials_create(void);
/* Environment variable that points to the default SSL roots file. This file
must be a PEM encoded file with all the roots such as the one that can be
@ -88,13 +90,17 @@ grpc_credentials *grpc_ssl_credentials_create(
grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
grpc_credentials *creds2);
/* Creates a compute engine credentials object. */
/* Creates a compute engine credentials object.
WARNING: Do NOT use this credentials to connect to a non-google service as
this could result in an oauth2 token leak. */
grpc_credentials *grpc_compute_engine_credentials_create(void);
extern const gpr_timespec grpc_max_auth_token_lifetime;
/* Creates a service account credentials object. May return NULL if the input is
invalid.
WARNING: Do NOT use this credentials to connect to a non-google service as
this could result in an oauth2 token leak.
- json_key is the JSON key string containing the client's private key.
- scope is a space-delimited list of the requested permissions.
- token_lifetime is the lifetime of each token acquired through this service
@ -129,11 +135,6 @@ grpc_credentials *grpc_iam_credentials_create(const char *authorization_token,
channel, it will just be ignored. */
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
/* Creates a default secure channel using the default credentials object using
the environment. */
grpc_channel *grpc_default_secure_channel_create(const char *target,
const grpc_channel_args *args);
/* Creates a secure channel using the passed-in credentials. */
grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
const char *target,

@ -216,6 +216,7 @@ static void on_resolved(void *arg, grpc_resolved_addresses *addresses) {
gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
if (!addresses) {
finish(req, 0);
return;
}
req->addresses = addresses;
req->next_address = 0;

@ -1076,7 +1076,3 @@ grpc_credentials *grpc_iam_credentials_create(const char *token,
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; }

@ -60,8 +60,15 @@ typedef enum {
"x-goog-iam-authorization-token"
#define GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY "x-goog-iam-authority-selector"
#define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud"
#define GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE \
"application_default_credentials.json"
/* --- grpc_credentials. --- */
/* It is the caller's responsibility to gpr_free the result if not NULL. */
char *grpc_get_well_known_google_credentials_file_path(void);
typedef void (*grpc_credentials_metadata_cb)(void *user_data,
grpc_mdelem **md_elems,
size_t num_md,

@ -0,0 +1,60 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/port_platform.h>
#ifdef GPR_POSIX_FILE
#include "src/core/security/credentials.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/support/env.h"
#include "src/core/support/string.h"
char *grpc_get_well_known_google_credentials_file_path(void) {
char *result = NULL;
char *home = gpr_getenv("HOME");
if (home == NULL) {
gpr_log(GPR_ERROR, "Could not get HOME environment variable.");
return NULL;
}
gpr_asprintf(&result, "%s/.config/%s/%s", home,
GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY,
GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE);
gpr_free(home);
return result;
}
#endif /* GPR_POSIX_FILE */

@ -0,0 +1,60 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/support/port_platform.h>
#ifdef GPR_WIN32
#include "src/core/security/credentials.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/support/env.h"
#include "src/core/support/string.h"
char *grpc_get_well_known_google_credentials_file_path(void) {
char *result = NULL;
char *appdata_path = gpr_getenv("APPDATA");
if (appdata_path == NULL) {
gpr_log(GPR_ERROR, "Could not get APPDATA environment variable.");
return NULL;
}
gpr_asprintf(&result, "%s/%s/%s", appdata_path,
GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY,
GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE);
gpr_free(appdata_path);
return result;
}
#endif /* GPR_WIN32 */

@ -0,0 +1,185 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/security/credentials.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include "src/core/httpcli/httpcli.h"
#include "src/core/support/env.h"
#include "src/core/support/file.h"
/* -- Constants. -- */
#define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal"
#define GRPC_GOOGLE_CREDENTIALS_ENV_VAR "GOOGLE_APPLICATION_CREDENTIALS"
/* -- Default credentials. -- */
static grpc_credentials *default_credentials = NULL;
static int compute_engine_detection_done = 0;
static gpr_mu g_mu;
static gpr_once g_once = GPR_ONCE_INIT;
static void init_default_credentials(void) {
gpr_mu_init(&g_mu);
}
typedef struct {
gpr_cv cv;
gpr_mu mu;
int is_done;
int success;
} compute_engine_detector;
static void on_compute_engine_detection_http_response(
void *user_data, const grpc_httpcli_response *response) {
compute_engine_detector *detector = (compute_engine_detector *)user_data;
if (response != NULL && response->status == 200 && response->hdr_count > 0) {
/* Internet providers can return a generic response to all requests, so
it is necessary to check that metadata header is present also. */
size_t i;
for (i = 0; i < response->hdr_count; i++) {
grpc_httpcli_header *header = &response->hdrs[i];
if (!strcmp(header->key, "Metadata-Flavor") &&
!strcmp(header->value, "Google")) {
detector->success = 1;
break;
}
}
}
gpr_mu_lock(&detector->mu);
detector->is_done = 1;
gpr_mu_unlock(&detector->mu);
gpr_cv_signal(&detector->cv);
}
static int is_stack_running_on_compute_engine(void) {
compute_engine_detector detector;
grpc_httpcli_request request;
/* The http call is local. If it takes more than one sec, it is for sure not
on compute engine. */
gpr_timespec max_detection_delay = {1, 0};
gpr_mu_init(&detector.mu);
gpr_cv_init(&detector.cv);
detector.is_done = 0;
detector.success = 0;
memset(&request, 0, sizeof(grpc_httpcli_request));
request.host = GRPC_COMPUTE_ENGINE_DETECTION_HOST;
request.path = "/";
grpc_httpcli_get(&request, gpr_time_add(gpr_now(), max_detection_delay),
on_compute_engine_detection_http_response, &detector);
/* Block until we get the response. This is not ideal but this should only be
called once for the lifetime of the process by the default credentials. */
gpr_mu_lock(&detector.mu);
while (!detector.is_done) {
gpr_cv_wait(&detector.cv, &detector.mu, gpr_inf_future);
}
gpr_mu_unlock(&detector.mu);
gpr_mu_destroy(&detector.mu);
gpr_cv_destroy(&detector.cv);
return detector.success;
}
/* Takes ownership of creds_path if not NULL. */
static grpc_credentials *create_jwt_creds_from_path(char *creds_path) {
grpc_credentials *result = NULL;
gpr_slice creds_data;
int file_ok = 0;
if (creds_path == NULL) return NULL;
creds_data = gpr_load_file(creds_path, &file_ok);
gpr_free(creds_path);
if (file_ok) {
result = grpc_jwt_credentials_create(
(const char *)GPR_SLICE_START_PTR(creds_data),
grpc_max_auth_token_lifetime);
gpr_slice_unref(creds_data);
}
return result;
}
grpc_credentials *grpc_google_default_credentials_create(void) {
grpc_credentials *result = NULL;
int serving_cached_credentials = 0;
gpr_once_init(&g_once, init_default_credentials);
gpr_mu_lock(&g_mu);
if (default_credentials != NULL) {
result = default_credentials;
serving_cached_credentials = 1;
goto end;
}
/* First, try the environment variable. */
result =
create_jwt_creds_from_path(gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR));
if (result != NULL) goto end;
/* Then the well-known file. */
result = create_jwt_creds_from_path(
grpc_get_well_known_google_credentials_file_path());
if (result != NULL) goto end;
/* At last try to see if we're on compute engine (do the detection only once
since it requires a network test). */
if (!compute_engine_detection_done) {
int need_compute_engine_creds = is_stack_running_on_compute_engine();
compute_engine_detection_done = 1;
if (need_compute_engine_creds) {
result = grpc_compute_engine_credentials_create();
}
}
end:
if (!serving_cached_credentials && result != NULL) {
/* Blend with default ssl credentials and add a global reference so that it
can be cached and re-served. */
result = grpc_composite_credentials_create(
grpc_ssl_credentials_create(NULL, NULL), result);
GPR_ASSERT(result != NULL);
default_credentials = grpc_credentials_ref(result);
}
gpr_mu_unlock(&g_mu);
return result;
}

@ -641,9 +641,3 @@ grpc_channel *grpc_secure_channel_create_with_factories(
creds->type);
return grpc_lame_client_channel_create();
}
grpc_channel *grpc_default_secure_channel_create(
const char *target, const grpc_channel_args *args) {
return grpc_secure_channel_create(grpc_default_credentials_create(), target,
args);
}

@ -45,8 +45,8 @@ Credentials::Credentials(grpc_credentials *c_creds) : creds_(c_creds) {}
Credentials::~Credentials() { grpc_credentials_release(creds_); }
grpc_credentials *Credentials::GetRawCreds() { return creds_; }
std::unique_ptr<Credentials> CredentialsFactory::DefaultCredentials() {
grpc_credentials *c_creds = grpc_default_credentials_create();
std::unique_ptr<Credentials> CredentialsFactory::GoogleDefaultCredentials() {
grpc_credentials *c_creds = grpc_google_default_credentials_create();
std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
return cpp_creds;
}
@ -86,6 +86,18 @@ std::unique_ptr<Credentials> CredentialsFactory::ServiceAccountCredentials(
return cpp_creds;
}
// Builds JWT credentials.
std::unique_ptr<Credentials> CredentialsFactory::JWTCredentials(
const grpc::string &json_key, std::chrono::seconds token_lifetime) {
gpr_timespec lifetime = gpr_time_from_seconds(
token_lifetime.count() > 0 ? token_lifetime.count() : 0);
grpc_credentials *c_creds =
grpc_jwt_credentials_create(json_key.c_str(), lifetime);
std::unique_ptr<Credentials> cpp_creds(
c_creds == nullptr ? nullptr : new Credentials(c_creds));
return cpp_creds;
}
// Builds IAM credentials.
std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials(
const grpc::string &authorization_token,
@ -98,7 +110,7 @@ std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials(
}
// Combines two credentials objects into a composite credentials.
std::unique_ptr<Credentials> CredentialsFactory::ComposeCredentials(
std::unique_ptr<Credentials> CredentialsFactory::CompositeCredentials(
const std::unique_ptr<Credentials> &creds1,
const std::unique_ptr<Credentials> &creds2) {
// Note that we are not saving unique_ptrs to the two credentials

@ -0,0 +1,107 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdio.h>
#include <string.h>
#include "src/core/security/credentials.h"
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpc/support/cmdline.h>
#include <grpc/support/log.h>
#include <grpc/support/slice.h>
#include <grpc/support/sync.h>
typedef struct {
gpr_cv cv;
gpr_mu mu;
int is_done;
} synchronizer;
static void on_metadata_response(void *user_data, grpc_mdelem **md_elems,
size_t num_md,
grpc_credentials_status status) {
synchronizer *sync = user_data;
if (status == GRPC_CREDENTIALS_ERROR) {
fprintf(stderr, "Fetching token failed.\n");
} else {
GPR_ASSERT(num_md == 1);
printf("\nGot token: %s\n\n",
(const char *)GPR_SLICE_START_PTR(md_elems[0]->value->slice));
}
gpr_mu_lock(&sync->mu);
sync->is_done = 1;
gpr_mu_unlock(&sync->mu);
gpr_cv_signal(&sync->cv);
}
int main(int argc, char **argv) {
int result = 0;
synchronizer sync;
grpc_credentials *creds = NULL;
char *service_url = "https://test.foo.google.com/Foo";
gpr_cmdline *cl = gpr_cmdline_create("print_google_default_creds_token");
gpr_cmdline_add_string(cl, "service_url",
"Service URL for the token request.",
&service_url);
gpr_cmdline_parse(cl, argc, argv);
grpc_init();
creds = grpc_google_default_credentials_create();
if (creds == NULL) {
fprintf(stderr, "\nCould not find default credentials.\n\n");
result = 1;
goto end;
}
gpr_mu_init(&sync.mu);
gpr_cv_init(&sync.cv);
sync.is_done = 0;
grpc_credentials_get_request_metadata(creds, "", on_metadata_response, &sync);
gpr_mu_lock(&sync.mu);
while (!sync.is_done) gpr_cv_wait(&sync.cv, &sync.mu, gpr_inf_future);
gpr_mu_unlock(&sync.mu);
gpr_mu_destroy(&sync.mu);
gpr_cv_destroy(&sync.cv);
grpc_credentials_release(creds);
end:
gpr_cmdline_destroy(cl);
grpc_shutdown();
return result;
}

@ -75,7 +75,7 @@ std::shared_ptr<ChannelInterface> CreateTestChannel(
server.empty() ? override_hostname : server;
if (creds.get()) {
channel_creds =
CredentialsFactory::ComposeCredentials(creds, channel_creds);
CredentialsFactory::CompositeCredentials(creds, channel_creds);
}
return CreateChannel(connect_to, channel_creds, channel_args);
} else {

@ -478,6 +478,14 @@ grpc_json_token_test: grpc_json_token_test.exe
echo Running grpc_json_token_test
$(OUT_DIR)\grpc_json_token_test.exe
grpc_print_google_default_creds_token.exe: grpc_test_util
echo Building grpc_print_google_default_creds_token
$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\print_google_default_creds_token.c
$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_print_google_default_creds_token.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\print_google_default_creds_token.obj
grpc_print_google_default_creds_token: grpc_print_google_default_creds_token.exe
echo Running grpc_print_google_default_creds_token
$(OUT_DIR)\grpc_print_google_default_creds_token.exe
grpc_stream_op_test.exe: grpc_test_util
echo Building grpc_stream_op_test
$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\stream_op_test.c

@ -201,8 +201,14 @@
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials_posix.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials_win32.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\factories.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\google_default_credentials.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\json_token.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\secure_endpoint.c">

@ -22,9 +22,18 @@
<ClCompile Include="..\..\src\core\security\credentials.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials_posix.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials_win32.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\factories.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\google_default_credentials.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\json_token.c">
<Filter>src\core\security</Filter>
</ClCompile>

@ -205,8 +205,14 @@
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials_posix.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials_win32.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\factories.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\google_default_credentials.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\json_token.c">
</ClCompile>
<ClCompile Include="..\..\src\core\security\secure_endpoint.c">

@ -22,9 +22,18 @@
<ClCompile Include="..\..\src\core\security\credentials.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials_posix.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\credentials_win32.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\factories.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\google_default_credentials.c">
<Filter>src\core\security</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\security\json_token.c">
<Filter>src\core\security</Filter>
</ClCompile>

Loading…
Cancel
Save