Experimental API for XdsServerCredentials

pull/24843/head
Yash Tibrewal 4 years ago
parent d6298ed3dc
commit 096b2324e1
  1. 2
      BUILD
  2. 1
      BUILD.gn
  3. 1
      CMakeLists.txt
  4. 2
      Makefile
  5. 1
      build_autogenerated.yaml
  6. 1
      gRPC-C++.podspec
  7. 1
      grpc.def
  8. 1
      grpc.gyp
  9. 27
      include/grpc/grpc_security.h
  10. 26
      include/grpcpp/security/server_credentials.h
  11. 2
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  12. 23
      src/core/lib/security/credentials/insecure/insecure_credentials.cc
  13. 22
      src/core/lib/security/credentials/xds/xds_credentials.cc
  14. 30
      src/core/lib/security/credentials/xds/xds_credentials.h
  15. 59
      src/core/lib/security/security_connector/insecure/insecure_security_connector.cc
  16. 29
      src/core/lib/security/security_connector/insecure/insecure_security_connector.h
  17. 3
      src/cpp/server/insecure_server_credentials.cc
  18. 4
      src/cpp/server/secure_server_credentials.h
  19. 41
      src/cpp/server/xds_server_credentials.cc
  20. 2
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  21. 3
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  22. 18
      test/core/end2end/end2end_tests.h
  23. 2
      test/core/end2end/fixtures/h2_fakesec.cc
  24. 127
      test/core/end2end/fixtures/h2_insecure.cc
  25. 1
      test/core/end2end/generate_tests.bzl
  26. 327
      test/core/end2end/tests/call_creds.cc
  27. 9
      test/core/security/insecure_security_connector_test.cc
  28. 1
      test/core/surface/public_headers_must_be_c89.c
  29. 41
      test/cpp/end2end/xds_credentials_end2end_test.cc
  30. 1
      tools/doxygen/Doxyfile.c++.internal

@ -391,9 +391,11 @@ grpc_cc_library(
name = "grpc++_xds_credentials",
srcs = [
"src/cpp/client/xds_credentials.cc",
"src/cpp/server/xds_server_credentials.cc",
],
hdrs = [
"src/cpp/client/secure_credentials.h",
"src/cpp/server/secure_server_credentials.h",
],
language = "c++",
deps = [

@ -1479,6 +1479,7 @@ config("grpc_config") {
"src/cpp/server/server_credentials.cc",
"src/cpp/server/server_posix.cc",
"src/cpp/server/thread_pool_interface.h",
"src/cpp/server/xds_server_credentials.cc",
"src/cpp/thread_manager/thread_manager.cc",
"src/cpp/thread_manager/thread_manager.h",
"src/cpp/util/byte_buffer_cc.cc",

@ -2715,6 +2715,7 @@ add_library(grpc++
src/cpp/server/server_context.cc
src/cpp/server/server_credentials.cc
src/cpp/server/server_posix.cc
src/cpp/server/xds_server_credentials.cc
src/cpp/thread_manager/thread_manager.cc
src/cpp/util/byte_buffer_cc.cc
src/cpp/util/status.cc

@ -2904,6 +2904,7 @@ LIBGRPC++_SRC = \
src/cpp/server/server_context.cc \
src/cpp/server/server_credentials.cc \
src/cpp/server/server_posix.cc \
src/cpp/server/xds_server_credentials.cc \
src/cpp/thread_manager/thread_manager.cc \
src/cpp/util/byte_buffer_cc.cc \
src/cpp/util/status.cc \
@ -4915,6 +4916,7 @@ src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP)
src/cpp/server/channelz/channelz_service.cc: $(OPENSSL_DEP)
src/cpp/server/channelz/channelz_service_plugin.cc: $(OPENSSL_DEP)
src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
src/cpp/server/xds_server_credentials.cc: $(OPENSSL_DEP)
src/cpp/util/error_details.cc: $(OPENSSL_DEP)
src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP)
endif

@ -2353,6 +2353,7 @@ libs:
- src/cpp/server/server_context.cc
- src/cpp/server/server_credentials.cc
- src/cpp/server/server_posix.cc
- src/cpp/server/xds_server_credentials.cc
- src/cpp/thread_manager/thread_manager.cc
- src/cpp/util/byte_buffer_cc.cc
- src/cpp/util/status.cc

@ -762,6 +762,7 @@ Pod::Spec.new do |s|
'src/cpp/server/server_credentials.cc',
'src/cpp/server/server_posix.cc',
'src/cpp/server/thread_pool_interface.h',
'src/cpp/server/xds_server_credentials.cc',
'src/cpp/thread_manager/thread_manager.cc',
'src/cpp/thread_manager/thread_manager.h',
'src/cpp/util/byte_buffer_cc.cc',

@ -153,6 +153,7 @@ EXPORTS
grpc_tls_server_authorization_check_config_create
grpc_tls_server_authorization_check_config_release
grpc_xds_credentials_create
grpc_xds_server_credentials_create
grpc_raw_byte_buffer_create
grpc_raw_compressed_byte_buffer_create
grpc_byte_buffer_copy

@ -1434,6 +1434,7 @@
'src/cpp/server/server_context.cc',
'src/cpp/server/server_credentials.cc',
'src/cpp/server/server_posix.cc',
'src/cpp/server/xds_server_credentials.cc',
'src/cpp/thread_manager/thread_manager.cc',
'src/cpp/util/byte_buffer_cc.cc',
'src/cpp/util/status.cc',

@ -1034,10 +1034,17 @@ grpc_channel_credentials* grpc_insecure_credentials_create();
/**
* EXPERIMENTAL API - Subject to change
*
* This method creates an XDS channel credentials object.
* This method creates an insecure server credentials object.
*/
grpc_server_credentials* grpc_insecure_server_credentials_create();
/**
* EXPERIMENTAL API - Subject to change
*
* This method creates an xDS channel credentials object.
*
* Creating a channel with credentials of this type indicates that an xDS
* channel should get credentials configuration from the xDS control plane.
* Creating a channel with credentials of this type indicates that the channel
* should get credentials configuration from the xDS control plane.
*
* \a fallback_credentials are used if the channel target does not have the
* 'xds:///' scheme or if the xDS control plane does not provide information on
@ -1047,6 +1054,20 @@ grpc_channel_credentials* grpc_insecure_credentials_create();
GRPCAPI grpc_channel_credentials* grpc_xds_credentials_create(
grpc_channel_credentials* fallback_credentials);
/**
* EXPERIMENTAL API - Subject to change
*
* This method creates an xDS server credentials object.
*
* \a fallback_credentials are used if the xDS control plane does not provide
* information on how to fetch credentials dynamically.
*
* Does NOT take ownership of the \a fallback_credentials. (Internally takes
* a ref to the object.)
*/
GRPCAPI grpc_server_credentials* grpc_xds_server_credentials_create(
grpc_server_credentials* fallback_credentials);
#ifdef __cplusplus
}
#endif

@ -32,6 +32,8 @@ struct grpc_server;
namespace grpc {
class Server;
class ServerCredentials;
class SecureServerCredentials;
/// Options to create ServerCredentials with SSL
struct SslServerCredentialsOptions {
/// \warning Deprecated
@ -58,6 +60,12 @@ struct SslServerCredentialsOptions {
grpc_ssl_client_certificate_request_type client_certificate_request;
};
namespace experimental {
/// Builds Xds ServerCredentials given fallback credentials
std::shared_ptr<ServerCredentials> XdsServerCredentials(
const std::shared_ptr<ServerCredentials>& fallback_credentials);
} // namespace experimental
/// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
class ServerCredentials {
public:
@ -71,12 +79,30 @@ class ServerCredentials {
private:
friend class Server;
// We need this friend declaration for access to Insecure() and
// AsSecureServerCredentials(). When these two functions are no longer
// necessary, this friend declaration can be removed too.
friend std::shared_ptr<ServerCredentials>
grpc::experimental::XdsServerCredentials(
const std::shared_ptr<ServerCredentials>& fallback_credentials);
/// Tries to bind \a server to the given \a addr (eg, localhost:1234,
/// 192.168.1.1:31416, [::1]:27182, etc.)
///
/// \return bound port number on success, 0 on failure.
// TODO(dgq): the "port" part seems to be a misnomer.
virtual int AddPortToServer(const std::string& addr, grpc_server* server) = 0;
// TODO(yashykt): This is a hack since InsecureServerCredentials() cannot use
// grpc_insecure_server_credentials_create() and should be removed after
// insecure builds are removed from gRPC.
virtual bool IsInsecure() const { return false; }
// TODO(yashkt): This is a hack that should be removed once we remove insecure
// builds and the indirect method of adding ports to a server.
virtual SecureServerCredentials* AsSecureServerCredentials() {
return nullptr;
}
};
/// Builds SSL ServerCredentials given SSL specific options

@ -449,7 +449,7 @@ grpc_error* CdsLb::UpdateXdsCertificateProvider(
grpc_channel_credentials* channel_credentials =
grpc_channel_credentials_find_in_args(args_);
if (channel_credentials == nullptr ||
channel_credentials->type() != XdsCredentials::kCredentialsTypeXds) {
channel_credentials->type() != kCredentialsTypeXds) {
xds_certificate_provider_ = nullptr;
return GRPC_ERROR_NONE;
}

@ -30,12 +30,10 @@ constexpr char kCredentialsTypeInsecure[] = "insecure";
class InsecureCredentials final : public grpc_channel_credentials {
public:
explicit InsecureCredentials()
: grpc_channel_credentials(kCredentialsTypeInsecure) {}
InsecureCredentials() : grpc_channel_credentials(kCredentialsTypeInsecure) {}
grpc_core::RefCountedPtr<grpc_channel_security_connector>
create_security_connector(
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
RefCountedPtr<grpc_channel_security_connector> create_security_connector(
RefCountedPtr<grpc_call_credentials> call_creds,
const char* /* target_name */, const grpc_channel_args* /* args */,
grpc_channel_args** /* new_args */) override {
return MakeRefCounted<InsecureChannelSecurityConnector>(
@ -43,9 +41,24 @@ class InsecureCredentials final : public grpc_channel_credentials {
}
};
class InsecureServerCredentials final : public grpc_server_credentials {
public:
InsecureServerCredentials()
: grpc_server_credentials(kCredentialsTypeInsecure) {}
RefCountedPtr<grpc_server_security_connector> create_security_connector()
override {
return MakeRefCounted<InsecureServerSecurityConnector>(Ref());
}
};
} // namespace
} // namespace grpc_core
grpc_channel_credentials* grpc_insecure_credentials_create() {
return new grpc_core::InsecureCredentials();
}
grpc_server_credentials* grpc_insecure_server_credentials_create() {
return new grpc_core::InsecureServerCredentials();
}

@ -27,7 +27,7 @@
namespace grpc_core {
constexpr const char XdsCredentials::kCredentialsTypeXds[];
const char kCredentialsTypeXds[] = "Xds";
namespace {
@ -47,6 +47,10 @@ void ServerAuthCheckDestroy(void* config_user_data) {
} // namespace
//
// XdsCredentials
//
RefCountedPtr<grpc_channel_security_connector>
XdsCredentials::create_security_connector(
RefCountedPtr<grpc_call_credentials> call_creds, const char* target_name,
@ -96,6 +100,16 @@ XdsCredentials::create_security_connector(
return security_connector;
}
//
// XdsServerCredentials
//
RefCountedPtr<grpc_server_security_connector>
XdsServerCredentials::create_security_connector() {
// TODO(yashkt): Fill this
return fallback_credentials_->create_security_connector();
}
} // namespace grpc_core
grpc_channel_credentials* grpc_xds_credentials_create(
@ -103,3 +117,9 @@ grpc_channel_credentials* grpc_xds_credentials_create(
GPR_ASSERT(fallback_credentials != nullptr);
return new grpc_core::XdsCredentials(fallback_credentials->Ref());
}
grpc_server_credentials* grpc_xds_server_credentials_create(
grpc_server_credentials* fallback_credentials) {
GPR_ASSERT(fallback_credentials != nullptr);
return new grpc_core::XdsServerCredentials(fallback_credentials->Ref());
}

@ -27,23 +27,35 @@
namespace grpc_core {
extern const char kCredentialsTypeXds[];
class XdsCredentials final : public grpc_channel_credentials {
public:
static constexpr const char kCredentialsTypeXds[] = "Xds";
explicit XdsCredentials(
grpc_core::RefCountedPtr<grpc_channel_credentials> fallback_credentials)
RefCountedPtr<grpc_channel_credentials> fallback_credentials)
: grpc_channel_credentials(kCredentialsTypeXds),
fallback_credentials_(std::move(fallback_credentials)) {}
grpc_core::RefCountedPtr<grpc_channel_security_connector>
create_security_connector(
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
const char* target_name, const grpc_channel_args* args,
grpc_channel_args** new_args) override;
RefCountedPtr<grpc_channel_security_connector> create_security_connector(
RefCountedPtr<grpc_call_credentials> call_creds, const char* target_name,
const grpc_channel_args* args, grpc_channel_args** new_args) override;
private:
RefCountedPtr<grpc_channel_credentials> fallback_credentials_;
};
class XdsServerCredentials final : public grpc_server_credentials {
public:
explicit XdsServerCredentials(
RefCountedPtr<grpc_server_credentials> fallback_credentials)
: grpc_server_credentials(kCredentialsTypeXds),
fallback_credentials_(std::move(fallback_credentials)) {}
RefCountedPtr<grpc_server_security_connector> create_security_connector()
override;
private:
grpc_core::RefCountedPtr<grpc_channel_credentials> fallback_credentials_;
RefCountedPtr<grpc_server_credentials> fallback_credentials_;
};
} // namespace grpc_core

@ -28,6 +28,26 @@ namespace grpc_core {
const char kInsecureTransportSecurityType[] = "insecure";
namespace {
RefCountedPtr<grpc_auth_context> MakeAuthContext() {
auto ctx = MakeRefCounted<grpc_auth_context>(nullptr);
grpc_auth_context_add_cstring_property(
ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
kInsecureTransportSecurityType);
const char* security_level = tsi_security_level_to_string(TSI_SECURITY_NONE);
grpc_auth_context_add_property(ctx.get(),
GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME,
security_level, strlen(security_level));
return ctx;
}
} // namespace
RefCountedPtr<grpc_auth_context> TestOnlyMakeInsecureAuthContext() {
return MakeAuthContext();
}
// check_call_host and cancel_check_call_host are no-ops since we want to
// provide an insecure channel.
bool InsecureChannelSecurityConnector::check_call_host(
@ -70,19 +90,32 @@ int InsecureChannelSecurityConnector::cmp(
static_cast<const grpc_channel_security_connector*>(other_sc));
}
RefCountedPtr<grpc_auth_context>
InsecureChannelSecurityConnector::MakeAuthContext() {
auto ctx = MakeRefCounted<grpc_auth_context>(nullptr);
grpc_auth_context_add_cstring_property(
ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
kInsecureTransportSecurityType);
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1);
const char* security_level = tsi_security_level_to_string(TSI_SECURITY_NONE);
grpc_auth_context_add_property(ctx.get(),
GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME,
security_level, strlen(security_level));
return ctx;
// add_handshakers should have been a no-op but we need to add a minimalist
// security handshaker so that check_peer is invoked and an auth_context is
// created with the security level of TSI_SECURITY_NONE.
void InsecureServerSecurityConnector::add_handshakers(
const grpc_channel_args* args, grpc_pollset_set* /* interested_parties */,
grpc_core::HandshakeManager* handshake_manager) {
tsi_handshaker* handshaker = nullptr;
// Re-use local_tsi_handshaker_create as a minimalist handshaker.
GPR_ASSERT(tsi_local_handshaker_create(false /* is_client */, &handshaker) ==
TSI_OK);
handshake_manager->Add(SecurityHandshakerCreate(handshaker, this, args));
}
void InsecureServerSecurityConnector::check_peer(
tsi_peer peer, grpc_endpoint* ep,
grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
grpc_closure* on_peer_checked) {
*auth_context = MakeAuthContext();
tsi_peer_destruct(&peer);
ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, GRPC_ERROR_NONE);
}
int InsecureServerSecurityConnector::cmp(
const grpc_security_connector* other) const {
return server_security_connector_cmp(
static_cast<const grpc_server_security_connector*>(other));
}
} // namespace grpc_core

@ -29,6 +29,12 @@ namespace grpc_core {
extern const char kInsecureTransportSecurityType[];
// Exposed for testing purposes only.
// Create an auth context which is necessary to pass the santiy check in
// client_auth_filter that verifies if the peer's auth context is obtained
// during handshakes.
RefCountedPtr<grpc_auth_context> TestOnlyMakeInsecureAuthContext();
class InsecureChannelSecurityConnector
: public grpc_channel_security_connector {
public:
@ -55,13 +61,24 @@ class InsecureChannelSecurityConnector
grpc_closure* on_peer_checked) override;
int cmp(const grpc_security_connector* other_sc) const override;
};
class InsecureServerSecurityConnector : public grpc_server_security_connector {
public:
InsecureServerSecurityConnector(
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
: grpc_server_security_connector(nullptr /* url_scheme */,
std::move(server_creds)) {}
void add_handshakers(const grpc_channel_args* args,
grpc_pollset_set* /* interested_parties */,
grpc_core::HandshakeManager* handshake_manager) override;
void check_peer(tsi_peer peer, grpc_endpoint* ep,
grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
grpc_closure* on_peer_checked) override;
// Exposed for testing purposes only.
// Create an auth context which is necessary to pass the santiy check in
// client_auth_filter that verifies if the peer's auth context is obtained
// during handshakes. The auth context is only checked for its existence and
// not actually used.
static RefCountedPtr<grpc_auth_context> MakeAuthContext();
int cmp(const grpc_security_connector* other) const override;
};
} // namespace grpc_core

@ -33,6 +33,9 @@ class InsecureServerCredentialsImpl final : public ServerCredentials {
(void)processor;
GPR_ASSERT(0); // Should not be called on InsecureServerCredentials.
}
private:
bool IsInsecure() const override { return true; }
};
} // namespace

@ -69,7 +69,11 @@ class SecureServerCredentials final : public ServerCredentials {
void SetAuthMetadataProcessor(
const std::shared_ptr<grpc::AuthMetadataProcessor>& processor) override;
grpc_server_credentials* c_creds() { return creds_; }
private:
SecureServerCredentials* AsSecureServerCredentials() override { return this; }
grpc_server_credentials* creds_;
std::unique_ptr<grpc::AuthMetadataProcessorAyncWrapper> processor_;
};

@ -0,0 +1,41 @@
//
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#include "src/cpp/server/secure_server_credentials.h"
namespace grpc {
namespace experimental {
std::shared_ptr<ServerCredentials> XdsServerCredentials(
const std::shared_ptr<ServerCredentials>& fallback_credentials) {
GPR_ASSERT(fallback_credentials != nullptr);
if (fallback_credentials->IsInsecure()) {
grpc_server_credentials* insecure_creds =
grpc_insecure_server_credentials_create();
auto xds_creds = std::make_shared<SecureServerCredentials>(
grpc_xds_server_credentials_create(insecure_creds));
grpc_server_credentials_release(insecure_creds);
return xds_creds;
}
return std::make_shared<SecureServerCredentials>(
grpc_xds_server_credentials_create(
fallback_credentials->AsSecureServerCredentials()->c_creds()));
}
} // namespace experimental
} // namespace grpc

@ -176,6 +176,7 @@ grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls
grpc_tls_server_authorization_check_config_create_type grpc_tls_server_authorization_check_config_create_import;
grpc_tls_server_authorization_check_config_release_type grpc_tls_server_authorization_check_config_release_import;
grpc_xds_credentials_create_type grpc_xds_credentials_create_import;
grpc_xds_server_credentials_create_type grpc_xds_server_credentials_create_import;
grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
@ -455,6 +456,7 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_tls_server_authorization_check_config_create_import = (grpc_tls_server_authorization_check_config_create_type) GetProcAddress(library, "grpc_tls_server_authorization_check_config_create");
grpc_tls_server_authorization_check_config_release_import = (grpc_tls_server_authorization_check_config_release_type) GetProcAddress(library, "grpc_tls_server_authorization_check_config_release");
grpc_xds_credentials_create_import = (grpc_xds_credentials_create_type) GetProcAddress(library, "grpc_xds_credentials_create");
grpc_xds_server_credentials_create_import = (grpc_xds_server_credentials_create_type) GetProcAddress(library, "grpc_xds_server_credentials_create");
grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");
grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy");

@ -503,6 +503,9 @@ extern grpc_tls_server_authorization_check_config_release_type grpc_tls_server_a
typedef grpc_channel_credentials*(*grpc_xds_credentials_create_type)(grpc_channel_credentials* fallback_credentials);
extern grpc_xds_credentials_create_type grpc_xds_credentials_create_import;
#define grpc_xds_credentials_create grpc_xds_credentials_create_import
typedef grpc_server_credentials*(*grpc_xds_server_credentials_create_type)(grpc_server_credentials* fallback_credentials);
extern grpc_xds_server_credentials_create_type grpc_xds_server_credentials_create_import;
#define grpc_xds_server_credentials_create grpc_xds_server_credentials_create_import
typedef grpc_byte_buffer*(*grpc_raw_byte_buffer_create_type)(grpc_slice* slices, size_t nslices);
extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
#define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import

@ -27,14 +27,18 @@ typedef struct grpc_end2end_test_config grpc_end2end_test_config;
/* Test feature flags. */
#define FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION 1
#define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION 2
// Feature mask supports call credentials with a minimum security level of
// GRPC_PRIVACY_AND_INTEGRITY.
#define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS 4
#define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 8
#define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL 16
#define FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER 32
#define FEATURE_MASK_DOES_NOT_SUPPORT_RESOURCE_QUOTA_SERVER 64
#define FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE 128
#define FEATURE_MASK_SUPPORTS_WORKAROUNDS 256
#define FEATURE_MASK_DOES_NOT_SUPPORT_SEND_CALL_CREDENTIALS 512
// Feature mask supports call credentials with a minimum security level of
// GRPC_SECURTITY_NONE.
#define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE 8
#define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 16
#define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL 32
#define FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER 64
#define FEATURE_MASK_DOES_NOT_SUPPORT_RESOURCE_QUOTA_SERVER 128
#define FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE 256
#define FEATURE_MASK_SUPPORTS_WORKAROUNDS 512
#define FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST 1024
#define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check"

@ -130,7 +130,7 @@ static grpc_end2end_test_config configs[] = {
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
FEATURE_MASK_DOES_NOT_SUPPORT_SEND_CALL_CREDENTIALS,
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE,
nullptr, chttp2_create_fixture_secure_fullstack,
chttp2_init_client_fake_secure_fullstack,
chttp2_init_server_fake_secure_fullstack,

@ -0,0 +1,127 @@
//
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
#include "test/core/end2end/end2end_tests.h"
#include <string.h>
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/host_port.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
namespace {
struct Chttp2InsecureFullstackFixtureData {
std::string localaddr;
};
grpc_end2end_test_fixture Chttp2CreateFixtureInsecureFullstack(
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
grpc_end2end_test_fixture f;
int port = grpc_pick_unused_port_or_die();
Chttp2InsecureFullstackFixtureData* ffd =
new Chttp2InsecureFullstackFixtureData();
memset(&f, 0, sizeof(f));
ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
f.fixture_data = ffd;
f.cq = grpc_completion_queue_create_for_next(nullptr);
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
return f;
}
void Chttp2InitClientInsecureFullstack(grpc_end2end_test_fixture* f,
grpc_channel_args* client_args) {
Chttp2InsecureFullstackFixtureData* ffd =
static_cast<Chttp2InsecureFullstackFixtureData*>(f->fixture_data);
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
f->client = grpc_secure_channel_create(creds, ffd->localaddr.c_str(),
client_args, nullptr);
grpc_channel_credentials_release(creds);
GPR_ASSERT(f->client);
}
void ProcessAuthFailure(void* state, grpc_auth_context* /*ctx*/,
const grpc_metadata* /*md*/, size_t /*md_count*/,
grpc_process_auth_metadata_done_cb cb,
void* user_data) {
GPR_ASSERT(state == nullptr);
cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
}
void Chttp2InitServerInsecureFullstack(grpc_end2end_test_fixture* f,
grpc_channel_args* server_args) {
Chttp2InsecureFullstackFixtureData* ffd =
static_cast<Chttp2InsecureFullstackFixtureData*>(f->fixture_data);
if (f->server) {
grpc_server_destroy(f->server);
}
f->server = grpc_server_create(server_args, nullptr);
grpc_server_register_completion_queue(f->server, f->cq, nullptr);
grpc_server_credentials* server_creds =
grpc_insecure_server_credentials_create();
if (grpc_channel_args_find(server_args, FAIL_AUTH_CHECK_SERVER_ARG_NAME) !=
nullptr) {
grpc_auth_metadata_processor processor = {ProcessAuthFailure, nullptr,
nullptr};
grpc_server_credentials_set_auth_metadata_processor(server_creds,
processor);
}
GPR_ASSERT(grpc_server_add_secure_http2_port(
f->server, ffd->localaddr.c_str(), server_creds));
grpc_server_credentials_release(server_creds);
grpc_server_start(f->server);
}
void Chttp2TearDownInsecureFullstack(grpc_end2end_test_fixture* f) {
Chttp2InsecureFullstackFixtureData* ffd =
static_cast<Chttp2InsecureFullstackFixtureData*>(f->fixture_data);
delete ffd;
}
/* All test configurations */
grpc_end2end_test_config configs[] = {
{"chttp2/insecure_fullstack",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE,
nullptr, Chttp2CreateFixtureInsecureFullstack,
Chttp2InitClientInsecureFullstack, Chttp2InitServerInsecureFullstack,
Chttp2TearDownInsecureFullstack},
};
} // namespace
int main(int argc, char** argv) {
size_t i;
grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
grpc_end2end_tests(argc, argv, configs[i]);
}
grpc_shutdown();
return 0;
}

@ -70,6 +70,7 @@ END2END_FIXTURES = {
"h2_full+trace": _fixture_options(tracing = True),
"h2_full+workarounds": _fixture_options(),
"h2_http_proxy": _fixture_options(supports_proxy_auth = True),
"h2_insecure": _fixture_options(secure = True),
"h2_oauth2": _fixture_options(),
"h2_proxy": _fixture_options(includes_proxy = True),
"h2_sockpair_1byte": _fixture_options(

@ -35,6 +35,10 @@ static const char iam_token[] = "token";
static const char iam_selector[] = "selector";
static const char overridden_iam_token[] = "overridden_token";
static const char overridden_iam_selector[] = "overridden_selector";
static const char fake_md_key[] = "fake_key";
static const char fake_md_value[] = "fake_value";
static const char overridden_fake_md_key[] = "overridden_fake_key";
static const char overridden_fake_md_value[] = "overridden_fake_value";
typedef enum { NONE, OVERRIDE, DESTROY, FAIL } override_mode;
@ -42,9 +46,13 @@ static void* tag(intptr_t t) { return (void*)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char* test_name,
bool use_secure_call_creds,
int fail_server_auth_check) {
grpc_end2end_test_fixture f;
gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
gpr_log(GPR_INFO, "Running test: %s%s/%s", test_name,
use_secure_call_creds ? "_with_secure_call_creds"
: "_with_insecure_call_creds",
config.name);
f = config.create_fixture(nullptr, nullptr);
config.init_client(&f, nullptr);
if (fail_server_auth_check) {
@ -122,10 +130,10 @@ static void print_auth_context(int is_client, const grpc_auth_context* ctx) {
}
static void request_response_with_payload_and_call_creds(
const char* test_name, grpc_end2end_test_config config,
override_mode mode) {
grpc_call* c;
grpc_call* s;
const char* test_name, grpc_end2end_test_config config, override_mode mode,
bool use_secure_call_creds) {
grpc_call* c = nullptr;
grpc_call* s = nullptr;
grpc_slice request_payload_slice =
grpc_slice_from_copied_string("hello world");
grpc_slice response_payload_slice =
@ -152,7 +160,7 @@ static void request_response_with_payload_and_call_creds(
grpc_auth_context* s_auth_context = nullptr;
grpc_auth_context* c_auth_context = nullptr;
f = begin_test(config, test_name, 0);
f = begin_test(config, test_name, use_secure_call_creds, 0);
cqv = cq_verifier_create(f.cq);
gpr_timespec deadline = five_seconds_from_now();
@ -160,7 +168,13 @@ static void request_response_with_payload_and_call_creds(
grpc_slice_from_static_string("/foo"), nullptr,
deadline, nullptr);
GPR_ASSERT(c);
creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
if (use_secure_call_creds) {
creds =
grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
} else {
creds =
grpc_md_only_test_credentials_create(fake_md_key, fake_md_value, false);
}
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
switch (mode) {
@ -168,15 +182,22 @@ static void request_response_with_payload_and_call_creds(
break;
case OVERRIDE:
grpc_call_credentials_release(creds);
creds = grpc_google_iam_credentials_create(
overridden_iam_token, overridden_iam_selector, nullptr);
if (use_secure_call_creds) {
creds = grpc_google_iam_credentials_create(
overridden_iam_token, overridden_iam_selector, nullptr);
} else {
creds = grpc_md_only_test_credentials_create(
overridden_fake_md_key, overridden_fake_md_value, false);
}
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
break;
case DESTROY:
case FAIL:
GPR_ASSERT(grpc_call_set_credentials(c, nullptr) == GRPC_CALL_OK);
break;
case FAIL:
// Do nothing
break;
}
grpc_call_credentials_release(creds);
@ -222,111 +243,137 @@ static void request_response_with_payload_and_call_creds(
nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
error =
grpc_server_request_call(f.server, &s, &call_details,
&request_metadata_recv, f.cq, f.cq, tag(101));
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
cq_verify(cqv);
s_auth_context = grpc_call_auth_context(s);
GPR_ASSERT(s_auth_context != nullptr);
print_auth_context(0, s_auth_context);
grpc_auth_context_release(s_auth_context);
c_auth_context = grpc_call_auth_context(c);
GPR_ASSERT(c_auth_context != nullptr);
print_auth_context(1, c_auth_context);
grpc_auth_context_release(c_auth_context);
/* Cannot set creds on the server call object. */
GPR_ASSERT(grpc_call_set_credentials(s, nullptr) != GRPC_CALL_OK);
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message.recv_message = &request_payload_recv;
op->flags = 0;
op->reserved = nullptr;
op++;
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
cq_verify(cqv);
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message.send_message = response_payload;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
grpc_slice status_details = grpc_slice_from_static_string("xyz");
op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = nullptr;
op++;
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
switch (mode) {
case NONE:
GPR_ASSERT(contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
iam_token));
GPR_ASSERT(contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
iam_selector));
break;
case OVERRIDE:
GPR_ASSERT(contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
overridden_iam_token));
GPR_ASSERT(contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
overridden_iam_selector));
break;
case DESTROY:
case FAIL:
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
iam_token));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
iam_selector));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
overridden_iam_token));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
overridden_iam_selector));
break;
if (mode == FAIL) {
// Expect the call to fail since the channel credentials did not satisfy the
// minimum security level requirements.
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_UNAUTHENTICATED);
} else {
error =
grpc_server_request_call(f.server, &s, &call_details,
&request_metadata_recv, f.cq, f.cq, tag(101));
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
cq_verify(cqv);
s_auth_context = grpc_call_auth_context(s);
GPR_ASSERT(s_auth_context != nullptr);
print_auth_context(0, s_auth_context);
grpc_auth_context_release(s_auth_context);
c_auth_context = grpc_call_auth_context(c);
GPR_ASSERT(c_auth_context != nullptr);
print_auth_context(1, c_auth_context);
grpc_auth_context_release(c_auth_context);
/* Cannot set creds on the server call object. */
GPR_ASSERT(grpc_call_set_credentials(s, nullptr) != GRPC_CALL_OK);
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message.recv_message = &request_payload_recv;
op->flags = 0;
op->reserved = nullptr;
op++;
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
tag(102), nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
cq_verify(cqv);
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message.send_message = response_payload;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
grpc_slice status_details = grpc_slice_from_static_string("xyz");
op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = nullptr;
op++;
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
tag(103), nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
GPR_ASSERT(status == GRPC_STATUS_OK);
GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
GPR_ASSERT(was_cancelled == 0);
GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
switch (mode) {
case NONE:
if (use_secure_call_creds) {
GPR_ASSERT(contains_metadata(
&request_metadata_recv, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
iam_token));
GPR_ASSERT(contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
iam_selector));
} else {
GPR_ASSERT(contains_metadata(&request_metadata_recv, fake_md_key,
fake_md_value));
}
break;
case OVERRIDE:
if (use_secure_call_creds) {
GPR_ASSERT(contains_metadata(
&request_metadata_recv, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
overridden_iam_token));
GPR_ASSERT(contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
overridden_iam_selector));
} else {
GPR_ASSERT(contains_metadata(&request_metadata_recv,
overridden_fake_md_key,
overridden_fake_md_value));
}
break;
case DESTROY:
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
iam_token));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
iam_selector));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
overridden_iam_token));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
overridden_iam_selector));
GPR_ASSERT(!contains_metadata(&request_metadata_recv, fake_md_key,
fake_md_value));
GPR_ASSERT(!contains_metadata(&request_metadata_recv,
overridden_fake_md_key,
overridden_fake_md_value));
break;
case FAIL:
GPR_ASSERT(0);
}
grpc_call_unref(s);
}
grpc_slice_unref(details);
@ -336,7 +383,6 @@ static void request_response_with_payload_and_call_creds(
grpc_call_details_destroy(&call_details);
grpc_call_unref(c);
grpc_call_unref(s);
cq_verifier_destroy(cqv);
@ -350,30 +396,31 @@ static void request_response_with_payload_and_call_creds(
}
static void test_request_response_with_payload_and_call_creds(
grpc_end2end_test_config config) {
grpc_end2end_test_config config, bool use_secure_call_creds) {
request_response_with_payload_and_call_creds(
"test_request_response_with_payload_and_call_creds", config, NONE);
"test_request_response_with_payload_and_call_creds", config, NONE,
use_secure_call_creds);
}
static void test_request_response_with_payload_and_overridden_call_creds(
grpc_end2end_test_config config) {
grpc_end2end_test_config config, bool use_secure_call_creds) {
request_response_with_payload_and_call_creds(
"test_request_response_with_payload_and_overridden_call_creds", config,
OVERRIDE);
OVERRIDE, use_secure_call_creds);
}
static void test_request_response_with_payload_and_deleted_call_creds(
grpc_end2end_test_config config) {
grpc_end2end_test_config config, bool use_secure_call_creds) {
request_response_with_payload_and_call_creds(
"test_request_response_with_payload_and_deleted_call_creds", config,
DESTROY);
DESTROY, use_secure_call_creds);
}
static void test_request_response_with_payload_fail_to_send_call_creds(
grpc_end2end_test_config config) {
grpc_end2end_test_config config, bool use_secure_call_creds) {
request_response_with_payload_and_call_creds(
"test_request_response_with_payload_fail_to_send_call_creds", config,
FAIL);
FAIL, use_secure_call_creds);
}
static void test_request_with_server_rejecting_client_creds(
@ -398,7 +445,8 @@ static void test_request_with_server_rejecting_client_creds(
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_call_credentials* creds;
f = begin_test(config, "test_request_with_server_rejecting_client_creds", 1);
f = begin_test(config, "test_request_with_server_rejecting_client_creds",
false, 1);
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
@ -406,7 +454,8 @@ static void test_request_with_server_rejecting_client_creds(
deadline, nullptr);
GPR_ASSERT(c);
creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
creds =
grpc_md_only_test_credentials_create(fake_md_key, fake_md_value, false);
GPR_ASSERT(creds != nullptr);
GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
grpc_call_credentials_release(creds);
@ -475,15 +524,29 @@ static void test_request_with_server_rejecting_client_creds(
}
void call_creds(grpc_end2end_test_config config) {
// Test fixtures that support call credentials with a minimum security level
// of GRPC_PRIVACY_AND_INTEGRITY
if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS) {
test_request_response_with_payload_and_call_creds(config);
test_request_response_with_payload_and_overridden_call_creds(config);
test_request_response_with_payload_and_deleted_call_creds(config);
test_request_with_server_rejecting_client_creds(config);
test_request_response_with_payload_and_call_creds(config, true);
test_request_response_with_payload_and_overridden_call_creds(config, true);
test_request_response_with_payload_and_deleted_call_creds(config, true);
}
// Test that fixtures that support call credentials with a minimum security
// level of GRPC_SECURITY_NONE cannot send call credentials that require
// higher security level
if (config.feature_mask &
FEATURE_MASK_DOES_NOT_SUPPORT_SEND_CALL_CREDENTIALS) {
test_request_response_with_payload_fail_to_send_call_creds(config);
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE) {
test_request_response_with_payload_fail_to_send_call_creds(config, true);
}
// Fixtures that support sending call credentials should be able to send call
// credentials of security level GRPC_SECURITY_NONE.
if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS ||
config.feature_mask &
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE) {
test_request_response_with_payload_and_call_creds(config, false);
test_request_response_with_payload_and_overridden_call_creds(config, false);
test_request_response_with_payload_and_deleted_call_creds(config, false);
test_request_with_server_rejecting_client_creds(config);
}
}

@ -31,9 +31,12 @@ namespace testing {
namespace {
TEST(InsecureSecurityConnector, MakeAuthContextTest) {
auto auth_context = InsecureChannelSecurityConnector::MakeAuthContext();
// Verify that peer identity is set
auto it = grpc_auth_context_peer_identity(auth_context.get());
auto auth_context = TestOnlyMakeInsecureAuthContext();
// Verify that peer is not authenticated
EXPECT_EQ(auth_context->is_authenticated(), false);
// Verify that GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME is set
auto it = grpc_auth_context_find_properties_by_name(
auth_context.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it);
ASSERT_NE(prop, nullptr);
EXPECT_STREQ(prop->name, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);

@ -220,6 +220,7 @@ int main(int argc, char **argv) {
printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_create);
printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_release);
printf("%lx", (unsigned long) grpc_xds_credentials_create);
printf("%lx", (unsigned long) grpc_xds_server_credentials_create);
printf("%lx", (unsigned long) grpc_raw_byte_buffer_create);
printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create);
printf("%lx", (unsigned long) grpc_byte_buffer_copy);

@ -69,11 +69,52 @@ TEST_P(XdsCredentialsEnd2EndFallbackTest, NoXdsSchemeInTarget) {
EXPECT_EQ(resp.message(), "Hello");
}
class XdsServerCredentialsEnd2EndFallbackTest
: public ::testing::TestWithParam<const char*> {
protected:
XdsServerCredentialsEnd2EndFallbackTest() {
int port = grpc_pick_unused_port_or_die();
// Build a server that is not xDS enabled but uses XdsServerCredentials.
ServerBuilder builder;
server_address_ = "localhost:" + std::to_string(port);
builder.AddListeningPort(
server_address_,
grpc::experimental::XdsServerCredentials(
GetCredentialsProvider()->GetServerCredentials(GetParam())));
builder.RegisterService(&service_);
server_ = builder.BuildAndStart();
}
std::string server_address_;
TestServiceImpl service_;
std::unique_ptr<Server> server_;
};
TEST_P(XdsServerCredentialsEnd2EndFallbackTest, Basic) {
ChannelArguments args;
auto channel = grpc::CreateCustomChannel(
server_address_,
GetCredentialsProvider()->GetChannelCredentials(GetParam(), &args), args);
auto stub = grpc::testing::EchoTestService::NewStub(channel);
ClientContext ctx;
EchoRequest req;
req.set_message("Hello");
EchoResponse resp;
Status s = stub->Echo(&ctx, req, &resp);
EXPECT_EQ(s.ok(), true);
EXPECT_EQ(resp.message(), "Hello");
}
INSTANTIATE_TEST_SUITE_P(XdsCredentialsEnd2EndFallback,
XdsCredentialsEnd2EndFallbackTest,
::testing::ValuesIn(std::vector<const char*>(
{kInsecureCredentialsType, kTlsCredentialsType})));
INSTANTIATE_TEST_SUITE_P(XdsServerCredentialsEnd2EndFallback,
XdsServerCredentialsEnd2EndFallbackTest,
::testing::ValuesIn(std::vector<const char*>(
{kInsecureCredentialsType, kTlsCredentialsType})));
} // namespace
} // namespace testing
} // namespace grpc

@ -2172,6 +2172,7 @@ src/cpp/server/server_context.cc \
src/cpp/server/server_credentials.cc \
src/cpp/server/server_posix.cc \
src/cpp/server/thread_pool_interface.h \
src/cpp/server/xds_server_credentials.cc \
src/cpp/thread_manager/thread_manager.cc \
src/cpp/thread_manager/thread_manager.h \
src/cpp/util/byte_buffer_cc.cc \

Loading…
Cancel
Save