diff --git a/Makefile b/Makefile index c8387a436af..278824a59aa 100644 --- a/Makefile +++ b/Makefile @@ -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 \ diff --git a/build.json b/build.json index f6ef33b25fc..3e9d2a7584c 100644 --- a/build.json +++ b/build.json @@ -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", diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h index ac6f394847d..5cbcca3aa5e 100644 --- a/include/grpc++/credentials.h +++ b/include/grpc++/credentials.h @@ -86,17 +86,23 @@ struct SslCredentialsOptions { // fail on it. class CredentialsFactory { public: - // Builds credentials with reasonable defaults. - static std::unique_ptr 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 GoogleDefaultCredentials(); // Builds SSL Credentials given SSL specific options static std::unique_ptr 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 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 JWTCredentials( + const grpc::string& json_key, std::chrono::seconds token_lifetime); + // Builds IAM credentials. static std::unique_ptr IAMCredentials( const grpc::string& authorization_token, const grpc::string& authority_selector); // Combines two credentials objects into a composite credentials - static std::unique_ptr ComposeCredentials( + static std::unique_ptr CompositeCredentials( const std::unique_ptr& creds1, const std::unique_ptr& creds2); }; diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 0eae444a9b7..4ba4ffc1188 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -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, diff --git a/include/grpc/support/atm.h b/include/grpc/support/atm.h index 0cac9bf5865..f1e30d31e80 100644 --- a/include/grpc/support/atm.h +++ b/include/grpc/support/atm.h @@ -51,12 +51,12 @@ The routines may be implemented as macros. - // Atomic operations acton an intergral_type gpr_atm that is guaranteed to + // Atomic operations act on an intergral_type gpr_atm that is guaranteed to // be the same size as a pointer. typedef gpr_intptr gpr_atm; // A memory barrier, providing both acquire and release semantics, but not - // otherwise acting no memory. + // otherwise acting on memory. void gpr_atm_full_barrier(void); // Atomically return *p, with acquire semantics. diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h index 4437375db72..bc99317f3c9 100644 --- a/include/grpc/support/sync.h +++ b/include/grpc/support/sync.h @@ -206,7 +206,7 @@ void *gpr_event_cancellable_wait(gpr_event *ev, gpr_timespec abs_deadline, /* --- Reference counting --- - These calls act on the type gpr_refcount. It requires no desctruction. */ + These calls act on the type gpr_refcount. It requires no destruction. */ /* Initialize *r to value n. */ void gpr_ref_init(gpr_refcount *r, int n); diff --git a/include/grpc/support/sync_posix.h b/include/grpc/support/sync_posix.h index 413226a9e8f..8ba2c5b8920 100644 --- a/include/grpc/support/sync_posix.h +++ b/include/grpc/support/sync_posix.h @@ -36,7 +36,6 @@ #include -/* Posix variant of gpr_sync_platform.h */ #include typedef pthread_mutex_t gpr_mu; diff --git a/include/grpc/support/sync_win32.h b/include/grpc/support/sync_win32.h index 5a48b52a2dc..13823b8ee3d 100644 --- a/include/grpc/support/sync_win32.h +++ b/include/grpc/support/sync_win32.h @@ -36,7 +36,6 @@ #include -/* Win32 variant of gpr_sync_platform.h */ #include typedef struct { diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h index ebc18c91e94..150b7ac8c53 100644 --- a/include/grpc/support/time.h +++ b/include/grpc/support/time.h @@ -76,7 +76,7 @@ gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b); gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b); gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b); -/* Return a timespec representing a given number of microseconds. LONG_MIN is +/* Return a timespec representing a given number of time units. LONG_MIN is interpreted as gpr_inf_past, and LONG_MAX as gpr_inf_future. */ gpr_timespec gpr_time_from_micros(long x); gpr_timespec gpr_time_from_nanos(long x); diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c index d372e694e96..d2cf09a8df4 100644 --- a/src/core/httpcli/httpcli.c +++ b/src/core/httpcli/httpcli.c @@ -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; diff --git a/src/core/json/json.c b/src/core/json/json.c index df7108a94de..96e11eebb11 100644 --- a/src/core/json/json.c +++ b/src/core/json/json.c @@ -38,8 +38,8 @@ #include "src/core/json/json.h" grpc_json *grpc_json_create(grpc_json_type type) { - grpc_json *json = gpr_malloc(sizeof(grpc_json)); - memset(json, 0, sizeof(grpc_json)); + grpc_json *json = gpr_malloc(sizeof(*json)); + memset(json, 0, sizeof(*json)); json->type = type; return json; diff --git a/src/core/json/json_reader.c b/src/core/json/json_reader.c index 774faa5f239..5ea4e9569c0 100644 --- a/src/core/json/json_reader.c +++ b/src/core/json/json_reader.c @@ -93,7 +93,7 @@ static void json_reader_set_null(grpc_json_reader* reader) { /* Call this function to initialize the reader structure. */ void grpc_json_reader_init(grpc_json_reader* reader, grpc_json_reader_vtable* vtable, void* userdata) { - memset(reader, 0, sizeof(grpc_json_reader)); + memset(reader, 0, sizeof(*reader)); reader->vtable = vtable; reader->userdata = userdata; json_reader_string_clear(reader); diff --git a/src/core/json/json_writer.c b/src/core/json/json_writer.c index 4c0bf30780d..a40bf1733e6 100644 --- a/src/core/json/json_writer.c +++ b/src/core/json/json_writer.c @@ -51,7 +51,7 @@ static void json_writer_output_string_with_len(grpc_json_writer* writer, const c void grpc_json_writer_init(grpc_json_writer* writer, int indent, grpc_json_writer_vtable* vtable, void* userdata) { - memset(writer, 0, sizeof(grpc_json_writer)); + memset(writer, 0, sizeof(*writer)); writer->container_empty = 1; writer->indent = indent; writer->vtable = vtable; @@ -77,7 +77,7 @@ static void json_writer_output_indent( while (spaces >= (sizeof(spacesstr) - 1)) { json_writer_output_string_with_len(writer, spacesstr, - sizeof(spacesstr) - 1); + sizeof(spacesstr) - 1); spaces -= (sizeof(spacesstr) - 1); } @@ -117,10 +117,10 @@ static void json_writer_escape_string(grpc_json_writer* writer, gpr_uint8 c = (gpr_uint8)*string++; if (c == 0) { break; - } else if ((c >= 32) && (c <= 127)) { + } else if ((c >= 32) && (c <= 126)) { if ((c == '\\') || (c == '"')) json_writer_output_char(writer, '\\'); json_writer_output_char(writer, c); - } else if (c < 32) { + } else if ((c < 32) || (c == 127)) { switch (c) { case '\b': json_writer_output_string_with_len(writer, "\\b", 2); @@ -161,6 +161,7 @@ static void json_writer_escape_string(grpc_json_writer* writer, for (i = 0; i < extra; i++) { utf32 <<= 6; c = *string++; + /* Breaks out and bail on any invalid UTF-8 sequence, including \0. */ if ((c & 0xc0) != 0x80) { valid = 0; break; diff --git a/src/core/security/auth.c b/src/core/security/auth.c index 92878e3b7e3..9b67d59cb8e 100644 --- a/src/core/security/auth.c +++ b/src/core/security/auth.c @@ -234,6 +234,9 @@ static void destroy_call_elem(grpc_call_element *elem) { if (calld->host != NULL) { grpc_mdstr_unref(calld->host); } + if (calld->method != NULL) { + grpc_mdstr_unref(calld->method); + } } /* Constructor for channel_data */ @@ -276,6 +279,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) { if (channeld->error_msg_key != NULL) { grpc_mdstr_unref(channeld->error_msg_key); } + if (channeld->path_string != NULL) { + grpc_mdstr_unref(channeld->path_string); + } } const grpc_channel_filter grpc_client_auth_filter = { diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 42d1a900fc5..7e72b238c80 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -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; } diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index 7b8929492b2..0a0074c1d53 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -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, diff --git a/src/core/security/credentials_posix.c b/src/core/security/credentials_posix.c new file mode 100644 index 00000000000..79622cb0246 --- /dev/null +++ b/src/core/security/credentials_posix.c @@ -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 + +#ifdef GPR_POSIX_FILE + +#include "src/core/security/credentials.h" + +#include +#include + +#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 */ diff --git a/src/core/security/credentials_win32.c b/src/core/security/credentials_win32.c new file mode 100644 index 00000000000..ddb310468bb --- /dev/null +++ b/src/core/security/credentials_win32.c @@ -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 + +#ifdef GPR_WIN32 + +#include "src/core/security/credentials.h" + +#include +#include + +#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 */ diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c new file mode 100644 index 00000000000..dc0e453b878 --- /dev/null +++ b/src/core/security/google_default_credentials.c @@ -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 + +#include +#include +#include + +#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; +} diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index fd8baff539d..9dce5af7400 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -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); -} diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c index cff130ae18d..720dc141f51 100644 --- a/src/core/support/log_win32.c +++ b/src/core/support/log_win32.c @@ -90,7 +90,7 @@ void gpr_default_log(gpr_log_func_args *args) { strcpy(time_buffer, "error:strftime"); } - fprintf(stderr, "%s%s.%09u %5u %s:%d: %s\n", + fprintf(stderr, "%s%s.%09u %5u %s:%d] %s\n", gpr_log_severity_string(args->severity), time_buffer, (int)(now.tv_nsec), GetCurrentThreadId(), args->file, args->line, args->message); diff --git a/src/core/support/string_posix.c b/src/core/support/string_posix.c index 8a678b3103d..25c333db4ed 100644 --- a/src/core/support/string_posix.c +++ b/src/core/support/string_posix.c @@ -51,7 +51,7 @@ int gpr_asprintf(char **strp, const char *format, ...) { va_start(args, format); ret = vsnprintf(buf, sizeof(buf), format, args); va_end(args); - if (!(0 <= ret)) { + if (ret < 0) { *strp = NULL; return -1; } diff --git a/src/core/support/sync.c b/src/core/support/sync.c index 1a5cf57c4f2..ccfe1e25f45 100644 --- a/src/core/support/sync.c +++ b/src/core/support/sync.c @@ -41,7 +41,7 @@ Should be a prime. */ enum { event_sync_partitions = 31 }; -/* Event are partitioned by address to avoid lock contention. */ +/* Events are partitioned by address to avoid lock contention. */ static struct sync_array_s { gpr_mu mu; gpr_cv cv; @@ -71,10 +71,10 @@ void gpr_event_set(gpr_event *ev, void *value) { struct sync_array_s *s = hash(ev); gpr_mu_lock(&s->mu); GPR_ASSERT(gpr_atm_acq_load(&ev->state) == 0); - GPR_ASSERT(value != NULL); gpr_atm_rel_store(&ev->state, (gpr_atm)value); gpr_cv_broadcast(&s->cv); gpr_mu_unlock(&s->mu); + GPR_ASSERT(value != NULL); } void *gpr_event_get(gpr_event *ev) { diff --git a/src/core/support/time.c b/src/core/support/time.c index 67f76656502..7dbf95059f5 100644 --- a/src/core/support/time.c +++ b/src/core/support/time.c @@ -85,12 +85,12 @@ gpr_timespec gpr_time_from_nanos(long ns) { } else if (ns == LONG_MIN) { result = gpr_inf_past; } else if (ns >= 0) { - result.tv_sec = ns / 1000000000; - result.tv_nsec = ns - result.tv_sec * 1000000000; + result.tv_sec = ns / GPR_NS_PER_SEC; + result.tv_nsec = ns - result.tv_sec * GPR_NS_PER_SEC; } else { /* Calculation carefully formulated to avoid any possible under/overflow. */ - result.tv_sec = (-(999999999 - (ns + 1000000000)) / 1000000000) - 1; - result.tv_nsec = ns - result.tv_sec * 1000000000; + result.tv_sec = (-(999999999 - (ns + GPR_NS_PER_SEC)) / GPR_NS_PER_SEC) - 1; + result.tv_nsec = ns - result.tv_sec * GPR_NS_PER_SEC; } return result; } @@ -172,8 +172,8 @@ gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) { gpr_timespec sum; int inc = 0; sum.tv_nsec = a.tv_nsec + b.tv_nsec; - if (sum.tv_nsec >= 1000000000) { - sum.tv_nsec -= 1000000000; + if (sum.tv_nsec >= GPR_NS_PER_SEC) { + sum.tv_nsec -= GPR_NS_PER_SEC; inc++; } if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) { @@ -200,7 +200,7 @@ gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) { int dec = 0; diff.tv_nsec = a.tv_nsec - b.tv_nsec; if (diff.tv_nsec < 0) { - diff.tv_nsec += 1000000000; + diff.tv_nsec += GPR_NS_PER_SEC; dec++; } if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) { diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc index 66571cad73d..a140f551e0d 100644 --- a/src/cpp/client/credentials.cc +++ b/src/cpp/client/credentials.cc @@ -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 CredentialsFactory::DefaultCredentials() { - grpc_credentials *c_creds = grpc_default_credentials_create(); +std::unique_ptr CredentialsFactory::GoogleDefaultCredentials() { + grpc_credentials *c_creds = grpc_google_default_credentials_create(); std::unique_ptr cpp_creds(new Credentials(c_creds)); return cpp_creds; } @@ -86,6 +86,18 @@ std::unique_ptr CredentialsFactory::ServiceAccountCredentials( return cpp_creds; } +// Builds JWT credentials. +std::unique_ptr 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 cpp_creds( + c_creds == nullptr ? nullptr : new Credentials(c_creds)); + return cpp_creds; +} + // Builds IAM credentials. std::unique_ptr CredentialsFactory::IAMCredentials( const grpc::string &authorization_token, @@ -98,7 +110,7 @@ std::unique_ptr CredentialsFactory::IAMCredentials( } // Combines two credentials objects into a composite credentials. -std::unique_ptr CredentialsFactory::ComposeCredentials( +std::unique_ptr CredentialsFactory::CompositeCredentials( const std::unique_ptr &creds1, const std::unique_ptr &creds2) { // Note that we are not saving unique_ptrs to the two credentials diff --git a/src/cpp/server/thread_pool.cc b/src/cpp/server/thread_pool.cc index 1ca98129d3e..fa11ddd04c7 100644 --- a/src/cpp/server/thread_pool.cc +++ b/src/cpp/server/thread_pool.cc @@ -37,11 +37,11 @@ namespace grpc { ThreadPool::ThreadPool(int num_threads) { for (int i = 0; i < num_threads; i++) { - threads_.push_back(std::thread([=]() { + threads_.push_back(std::thread([this]() { for (;;) { - std::unique_lock lock(mu_); // Wait until work is available or we are shutting down. - auto have_work = [=]() { return shutdown_ || !callbacks_.empty(); }; + auto have_work = [this]() { return shutdown_ || !callbacks_.empty(); }; + std::unique_lock lock(mu_); if (!have_work()) { cv_.wait(lock, have_work); } diff --git a/src/python/src/grpc/framework/assembly/implementations.py b/src/python/src/grpc/framework/assembly/implementations.py index 461aa9c8554..b9d314844c8 100644 --- a/src/python/src/grpc/framework/assembly/implementations.py +++ b/src/python/src/grpc/framework/assembly/implementations.py @@ -195,7 +195,7 @@ def _servicer(implementations, pool): event_stream_in_stream_out_methods=event_stream_in_stream_out_methods) -class _ServiceAssembly(activated.Activated): +class _ServiceAssembly(interfaces.Server): def __init__(self, implementations, fore_link): self._implementations = implementations @@ -237,6 +237,10 @@ class _ServiceAssembly(activated.Activated): def stop(self): self._stop() + def port(self): + with self._lock: + return self._fore_link.port() + def assemble_face_stub(activated_rear_link): """Assembles a face_interfaces.Stub. @@ -300,6 +304,6 @@ def assemble_service(implementations, activated_fore_link): when passed to this method. Returns: - An activated.Activated value encapsulating RPC service. + An interfaces.Server encapsulating RPC service. """ return _ServiceAssembly(implementations, activated_fore_link) diff --git a/src/python/src/grpc/framework/assembly/interfaces.py b/src/python/src/grpc/framework/assembly/interfaces.py index e5d750b2bc2..d1a6aad29e7 100644 --- a/src/python/src/grpc/framework/assembly/interfaces.py +++ b/src/python/src/grpc/framework/assembly/interfaces.py @@ -37,6 +37,7 @@ import abc # module. from grpc.framework.common import cardinality # pylint: disable=unused-import from grpc.framework.common import style # pylint: disable=unused-import +from grpc.framework.foundation import activated from grpc.framework.foundation import stream # pylint: disable=unused-import @@ -89,3 +90,25 @@ class MethodImplementation(object): style.Service.EVENT. """ __metaclass__ = abc.ABCMeta + + +class Server(activated.Activated): + """The server interface. + + Aside from being able to be activated and deactivated, objects of this type + are able to report the port on which they are servicing RPCs. + """ + __metaclass__ = abc.ABCMeta + + # TODO(issue 726): This is an abstraction violation; not every Server is + # necessarily serving over a network at all. + @abc.abstractmethod + def port(self): + """Identifies the port on which this Server is servicing RPCs. + + This method may only be called while the server is active. + + Returns: + The number of the port on which this Server is servicing RPCs. + """ + raise NotImplementedError() diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c index 0e315e51eee..bc3c7a3da84 100644 --- a/test/core/json/json_test.c +++ b/test/core/json/json_test.c @@ -65,7 +65,7 @@ static testing_pair testing_pairs[] = { /* Testing nested empty containers. */ { " [ [ ] , { } , [ ] ] ", "[[],{},[]]", }, /* Testing escapes and control chars in key strings. */ - { " { \"\\n\\\\a , b\": 1, \"\": 0 } ", "{\"\\n\\\\a , b\":1,\"\":0}" }, + { " { \"\x7f\\n\\\\a , b\": 1, \"\": 0 } ", "{\"\\u007f\\n\\\\a , b\":1,\"\":0}" }, /* Testing the writer's ability to cut off invalid UTF-8 sequences. */ { "\"abc\xf0\x9d\x24\"", "\"abc\"" }, { "\"\xff\"", "\"\"" }, diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c new file mode 100644 index 00000000000..cfd62cf6ccb --- /dev/null +++ b/test/core/security/print_google_default_creds_token.c @@ -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 +#include + +#include "src/core/security/credentials.h" +#include +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/test/core/support/time_test.c b/test/core/support/time_test.c index 2741e17f95f..c1dce777b09 100644 --- a/test/core/support/time_test.c +++ b/test/core/support/time_test.c @@ -81,7 +81,7 @@ static void ts_to_s(gpr_timespec t, void *arg) { if (t.tv_sec < 0 && t.tv_nsec != 0) { t.tv_sec++; - t.tv_nsec = 1000000000 - t.tv_nsec; + t.tv_nsec = GPR_NS_PER_SEC - t.tv_nsec; } i_to_s(t.tv_sec, 10, 0, writer, arg); (*writer)(arg, ".", 1); @@ -127,15 +127,15 @@ static void test_values(void) { /* Test possible overflow in conversion of -ve values. */ x = gpr_time_from_micros(-(LONG_MAX - 999997)); GPR_ASSERT(x.tv_sec < 0); - GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < 1000000000); + GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC); x = gpr_time_from_nanos(-(LONG_MAX - 999999997)); GPR_ASSERT(x.tv_sec < 0); - GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < 1000000000); + GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC); x = gpr_time_from_millis(-(LONG_MAX - 997)); GPR_ASSERT(x.tv_sec < 0); - GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < 1000000000); + GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC); /* Test general -ve values. */ for (i = -1; i > -1000 * 1000 * 1000; i *= 7) { diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index b0472d32a99..66a9a7b7c40 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -75,7 +75,7 @@ std::shared_ptr 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 { diff --git a/tools/dockerfile/grpc_go/Dockerfile b/tools/dockerfile/grpc_go/Dockerfile index 94d962b4482..e1671eaee14 100644 --- a/tools/dockerfile/grpc_go/Dockerfile +++ b/tools/dockerfile/grpc_go/Dockerfile @@ -48,6 +48,9 @@ RUN git config --global url."git@github.com:".insteadOf "https://github.com/" # Get the source from GitHub RUN go get google.golang.org/grpc +# Add a service_account directory containing the auth creds file +ADD service_account service_account + # Build the interop client and server RUN cd src/google.golang.org/grpc/interop/client && go install RUN cd src/google.golang.org/grpc/interop/server && go install diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 41a1d200e60..bbc138c6beb 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -935,6 +935,36 @@ grpc_cloud_prod_gen_ruby_cmd() { echo $the_cmd } +# constructs the full dockerized Go interop test cmd. +# +# call-seq: +# flags= .... # generic flags to include the command +# cmd=$($grpc_gen_test_cmd $flags) +grpc_cloud_prod_auth_service_account_creds_gen_go_cmd() { + local cmd_prefix="sudo docker run grpc/go /bin/bash -c" + local test_script="cd src/google.golang.org/grpc/interop/client" + local test_script+=" && go run client.go --use_tls=true" + local gfe_flags=" --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com" + local added_gfe_flags=$(_grpc_svc_acc_test_flags) + local the_cmd="$cmd_prefix '$test_script $gfe_flags $added_gfe_flags $@'" + echo $the_cmd +} + +# constructs the full dockerized Go interop test cmd. +# +# call-seq: +# flags= .... # generic flags to include the command +# cmd=$($grpc_gen_test_cmd $flags) +grpc_cloud_prod_auth_compute_engine_creds_gen_go_cmd() { + local cmd_prefix="sudo docker run grpc/go /bin/bash -c" + local test_script="cd src/google.golang.org/grpc/interop/client" + local test_script+=" && go run client.go --use_tls=true" + local gfe_flags=" --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com" + local added_gfe_flags=$(_grpc_gce_test_flags) + local the_cmd="$cmd_prefix '$test_script $gfe_flags $added_gfe_flags $@'" + echo $the_cmd +} + # constructs the full dockerized ruby service_account auth interop test cmd. # # call-seq: diff --git a/tools/gce_setup/shared_startup_funcs.sh b/tools/gce_setup/shared_startup_funcs.sh index 242c7921013..195f8f28a88 100755 --- a/tools/gce_setup/shared_startup_funcs.sh +++ b/tools/gce_setup/shared_startup_funcs.sh @@ -364,7 +364,7 @@ grpc_docker_launch_registry() { grpc_docker_pull_known() { local addr=$1 [[ -n $addr ]] || addr="0.0.0.0:5000" - local known="base cxx php_base php ruby_base ruby java_base java go node_base node" + local known="base cxx php_base php ruby_base ruby java_base java go node_base node python_base python" echo "... pulling docker images for '$known'" for i in $known do @@ -408,6 +408,7 @@ grpc_dockerfile_install() { } [[ $image_label == "grpc/go" ]] && { grpc_docker_sync_github_key $dockerfile_dir/.ssh 'go_ssh_key' || return 1; + grpc_docker_sync_service_account $dockerfile_dir/service_account || return 1; } [[ $image_label == "grpc/java_base" ]] && { grpc_docker_sync_github_key $dockerfile_dir/.ssh 'java_base_ssh_key' || return 1; diff --git a/vsprojects/vs2013/Grpc.mak b/vsprojects/vs2013/Grpc.mak index 9abbe8b8847..9272d07cb93 100644 --- a/vsprojects/vs2013/Grpc.mak +++ b/vsprojects/vs2013/Grpc.mak @@ -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 diff --git a/vsprojects/vs2013/grpc.vcxproj b/vsprojects/vs2013/grpc.vcxproj index 89c0de333c9..48f975f99bb 100644 --- a/vsprojects/vs2013/grpc.vcxproj +++ b/vsprojects/vs2013/grpc.vcxproj @@ -201,8 +201,14 @@ + + + + + + diff --git a/vsprojects/vs2013/grpc.vcxproj.filters b/vsprojects/vs2013/grpc.vcxproj.filters index a2d9f30eda7..867e54516c5 100644 --- a/vsprojects/vs2013/grpc.vcxproj.filters +++ b/vsprojects/vs2013/grpc.vcxproj.filters @@ -22,9 +22,18 @@ src\core\security + + src\core\security + + + src\core\security + src\core\security + + src\core\security + src\core\security diff --git a/vsprojects/vs2013/grpc_shared.vcxproj b/vsprojects/vs2013/grpc_shared.vcxproj index 81a280d912a..4b2f1e725e2 100644 --- a/vsprojects/vs2013/grpc_shared.vcxproj +++ b/vsprojects/vs2013/grpc_shared.vcxproj @@ -205,8 +205,14 @@ + + + + + + diff --git a/vsprojects/vs2013/grpc_shared.vcxproj.filters b/vsprojects/vs2013/grpc_shared.vcxproj.filters index a2d9f30eda7..867e54516c5 100644 --- a/vsprojects/vs2013/grpc_shared.vcxproj.filters +++ b/vsprojects/vs2013/grpc_shared.vcxproj.filters @@ -22,9 +22,18 @@ src\core\security + + src\core\security + + + src\core\security + src\core\security + + src\core\security + src\core\security