1 //
2 // Copyright 2017 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include <gmock/gmock.h>
18 #include <grpc/grpc.h>
19 #include <grpc/grpc_security.h>
20 #include <grpc/support/alloc.h>
21 #include <grpc/support/time.h>
22 #include <grpcpp/channel.h>
23 #include <grpcpp/client_context.h>
24 #include <grpcpp/create_channel.h>
25 #include <grpcpp/security/audit_logging.h>
26 #include <grpcpp/security/tls_certificate_provider.h>
27 #include <grpcpp/server.h>
28 #include <grpcpp/server_builder.h>
29 #include <grpcpp/xds_server_builder.h>
30 #include <gtest/gtest.h>
31
32 #include <map>
33 #include <memory>
34 #include <string>
35 #include <utility>
36 #include <vector>
37
38 #include "absl/functional/function_ref.h"
39 #include "absl/log/check.h"
40 #include "absl/log/log.h"
41 #include "absl/strings/str_cat.h"
42 #include "absl/strings/str_format.h"
43 #include "absl/strings/str_join.h"
44 #include "absl/time/time.h"
45 #include "absl/types/optional.h"
46 #include "envoy/config/cluster/v3/cluster.pb.h"
47 #include "envoy/config/endpoint/v3/endpoint.pb.h"
48 #include "envoy/config/listener/v3/listener.pb.h"
49 #include "envoy/config/route/v3/route.pb.h"
50 #include "envoy/extensions/clusters/aggregate/v3/cluster.pb.h"
51 #include "envoy/extensions/filters/http/rbac/v3/rbac.pb.h"
52 #include "envoy/extensions/filters/http/router/v3/router.pb.h"
53 #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h"
54 #include "envoy/extensions/transport_sockets/tls/v3/tls.pb.h"
55 #include "src/core/config/config_vars.h"
56 #include "src/core/config/core_configuration.h"
57 #include "src/core/ext/filters/http/client/http_client_filter.h"
58 #include "src/core/lib/security/authorization/audit_logging.h"
59 #include "src/core/lib/security/certificate_provider/certificate_provider_registry.h"
60 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
61 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
62 #include "src/core/util/env.h"
63 #include "src/core/util/ref_counted_ptr.h"
64 #include "src/core/util/string.h"
65 #include "src/core/util/sync.h"
66 #include "src/cpp/client/secure_credentials.h"
67 #include "src/cpp/server/secure_server_credentials.h"
68 #include "src/proto/grpc/testing/echo.grpc.pb.h"
69 #include "src/proto/grpc/testing/echo_messages.pb.h"
70 #include "test/core/test_util/audit_logging_utils.h"
71 #include "test/core/test_util/port.h"
72 #include "test/core/test_util/resolve_localhost_ip46.h"
73 #include "test/core/test_util/scoped_env_var.h"
74 #include "test/core/test_util/test_config.h"
75 #include "test/core/test_util/tls_utils.h"
76 #include "test/cpp/end2end/xds/xds_end2end_test_lib.h"
77 #include "test/cpp/util/test_config.h"
78 #include "test/cpp/util/tls_test_utils.h"
79 #include "xds/type/v3/typed_struct.pb.h"
80
81 namespace grpc {
82 namespace testing {
83 namespace {
84
85 using ::envoy::config::rbac::v3::Policy;
86 using ::envoy::config::rbac::v3::RBAC_Action_ALLOW;
87 using ::envoy::config::rbac::v3::RBAC_Action_DENY;
88 using ::envoy::config::rbac::v3::RBAC_Action_LOG;
89 using ::envoy::config::rbac::v3::
90 RBAC_AuditLoggingOptions_AuditCondition_ON_ALLOW;
91 using ::envoy::config::rbac::v3::
92 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY;
93 using ::envoy::config::rbac::v3::
94 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY_AND_ALLOW;
95 using ::envoy::extensions::filters::http::rbac::v3::RBAC;
96 using ::envoy::extensions::filters::http::rbac::v3::RBACPerRoute;
97 using ::envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext;
98 using ::envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext;
99 using ::envoy::type::matcher::v3::StringMatcher;
100 using ::xds::type::v3::TypedStruct;
101
102 using ::grpc::experimental::ExternalCertificateVerifier;
103 using ::grpc::experimental::IdentityKeyCertPair;
104 using ::grpc::experimental::RegisterAuditLoggerFactory;
105 using ::grpc::experimental::StaticDataCertificateProvider;
106 using ::grpc_core::experimental::AuditLoggerRegistry;
107 using ::grpc_core::testing::ScopedExperimentalEnvVar;
108 using ::grpc_core::testing::TestAuditLoggerFactory;
109
110 constexpr char kClientCertPath[] = "src/core/tsi/test_creds/client.pem";
111 constexpr char kClientKeyPath[] = "src/core/tsi/test_creds/client.key";
112 constexpr char kBadClientCertPath[] = "src/core/tsi/test_creds/badclient.pem";
113 constexpr char kBadClientKeyPath[] = "src/core/tsi/test_creds/badclient.key";
114
115 // Based on StaticDataCertificateProvider, but provides alternate certificates
116 // if the certificate name is not empty.
117 class FakeCertificateProvider final : public grpc_tls_certificate_provider {
118 public:
119 struct CertData {
120 std::string root_certificate;
121 grpc_core::PemKeyCertPairList identity_key_cert_pairs;
122 };
123
124 using CertDataMap = std::map<std::string /*cert_name */, CertData>;
125 class CertDataMapWrapper {
126 public:
Get()127 CertDataMap Get() {
128 grpc_core::MutexLock lock(&mu_);
129 return cert_data_map_;
130 }
131
Set(CertDataMap data)132 void Set(CertDataMap data) {
133 grpc_core::MutexLock lock(&mu_);
134 cert_data_map_ = std::move(data);
135 }
136
137 private:
138 grpc_core::Mutex mu_;
139 CertDataMap cert_data_map_ ABSL_GUARDED_BY(mu_);
140 };
141
FakeCertificateProvider(CertDataMap cert_data_map)142 explicit FakeCertificateProvider(CertDataMap cert_data_map)
143 : distributor_(
144 grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>()),
145 cert_data_map_(std::move(cert_data_map)) {
146 distributor_->SetWatchStatusCallback([this](std::string cert_name,
147 bool root_being_watched,
148 bool identity_being_watched) {
149 if (!root_being_watched && !identity_being_watched) return;
150 auto it = cert_data_map_.find(cert_name);
151 if (it == cert_data_map_.end()) {
152 grpc_error_handle error = GRPC_ERROR_CREATE(absl::StrCat(
153 "No certificates available for cert_name \"", cert_name, "\""));
154 distributor_->SetErrorForCert(cert_name, error, error);
155 } else {
156 absl::optional<std::string> root_certificate;
157 absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs;
158 if (root_being_watched) {
159 root_certificate = it->second.root_certificate;
160 }
161 if (identity_being_watched) {
162 pem_key_cert_pairs = it->second.identity_key_cert_pairs;
163 }
164 distributor_->SetKeyMaterials(cert_name, std::move(root_certificate),
165 std::move(pem_key_cert_pairs));
166 }
167 });
168 }
169
~FakeCertificateProvider()170 ~FakeCertificateProvider() override {
171 distributor_->SetWatchStatusCallback(nullptr);
172 }
173
distributor() const174 grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor()
175 const override {
176 return distributor_;
177 }
178
type() const179 grpc_core::UniqueTypeName type() const override {
180 static grpc_core::UniqueTypeName::Factory kFactory("fake");
181 return kFactory.Create();
182 }
183
184 private:
CompareImpl(const grpc_tls_certificate_provider * other) const185 int CompareImpl(const grpc_tls_certificate_provider* other) const override {
186 // TODO(yashykt): Maybe do something better here.
187 return grpc_core::QsortCompare(
188 static_cast<const grpc_tls_certificate_provider*>(this), other);
189 }
190
191 grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
192 CertDataMap cert_data_map_;
193 };
194
195 class FakeCertificateProviderFactory
196 : public grpc_core::CertificateProviderFactory {
197 public:
198 class Config : public grpc_core::CertificateProviderFactory::Config {
199 public:
Config(absl::string_view name)200 explicit Config(absl::string_view name) : name_(name) {}
201
name() const202 absl::string_view name() const override { return name_; }
203
ToString() const204 std::string ToString() const override { return "{}"; }
205
206 private:
207 absl::string_view name_;
208 };
209
FakeCertificateProviderFactory(absl::string_view name,FakeCertificateProvider::CertDataMapWrapper * cert_data_map)210 FakeCertificateProviderFactory(
211 absl::string_view name,
212 FakeCertificateProvider::CertDataMapWrapper* cert_data_map)
213 : name_(name), cert_data_map_(cert_data_map) {
214 CHECK_NE(cert_data_map, nullptr);
215 }
216
name() const217 absl::string_view name() const override { return name_; }
218
219 grpc_core::RefCountedPtr<grpc_core::CertificateProviderFactory::Config>
CreateCertificateProviderConfig(const grpc_core::Json &,const grpc_core::JsonArgs &,grpc_core::ValidationErrors *)220 CreateCertificateProviderConfig(
221 const grpc_core::Json& /*config_json*/,
222 const grpc_core::JsonArgs& /*args*/,
223 grpc_core::ValidationErrors* /*errors*/) override {
224 return grpc_core::MakeRefCounted<Config>(name_);
225 }
226
227 grpc_core::RefCountedPtr<grpc_tls_certificate_provider>
CreateCertificateProvider(grpc_core::RefCountedPtr<grpc_core::CertificateProviderFactory::Config>)228 CreateCertificateProvider(
229 grpc_core::RefCountedPtr<grpc_core::CertificateProviderFactory::Config>
230 /*config*/) override {
231 CHECK_NE(cert_data_map_, nullptr);
232 return grpc_core::MakeRefCounted<FakeCertificateProvider>(
233 cert_data_map_->Get());
234 }
235
236 private:
237 absl::string_view name_;
238 FakeCertificateProvider::CertDataMapWrapper* cert_data_map_;
239 };
240
241 // Global variables for each provider.
242 FakeCertificateProvider::CertDataMapWrapper* g_fake1_cert_data_map = nullptr;
243 FakeCertificateProvider::CertDataMapWrapper* g_fake2_cert_data_map = nullptr;
244
245 //
246 // Client-side mTLS tests
247 //
248
249 class XdsSecurityTest : public XdsEnd2endTest {
250 protected:
SetUp()251 void SetUp() override {
252 XdsBootstrapBuilder builder = MakeBootstrapBuilder();
253 builder.AddCertificateProviderPlugin("fake_plugin1", "fake1");
254 builder.AddCertificateProviderPlugin("fake_plugin2", "fake2");
255 std::vector<std::string> fields;
256 fields.push_back(absl::StrFormat(" \"certificate_file\": \"%s\"",
257 kClientCertPath));
258 fields.push_back(absl::StrFormat(" \"private_key_file\": \"%s\"",
259 kClientKeyPath));
260 fields.push_back(absl::StrFormat(" \"ca_certificate_file\": \"%s\"",
261 kCaCertPath));
262 builder.AddCertificateProviderPlugin("file_plugin", "file_watcher",
263 absl::StrJoin(fields, ",\n"));
264 InitClient(builder, /*lb_expected_authority=*/"",
265 /*xds_resource_does_not_exist_timeout_ms=*/0,
266 /*balancer_authority_override=*/"", /*args=*/nullptr,
267 CreateXdsChannelCredentials());
268 CreateAndStartBackends(2, /*xds_enabled=*/false,
269 CreateMtlsServerCredentials());
270 root_cert_ = grpc_core::testing::GetFileContents(kCaCertPath);
271 bad_root_cert_ = grpc_core::testing::GetFileContents(kBadClientCertPath);
272 identity_pair_ = ReadTlsIdentityPair(kClientKeyPath, kClientCertPath);
273 // TODO(yashykt): Use different client certs here instead of reusing
274 // server certs after https://github.com/grpc/grpc/pull/24876 is merged
275 fallback_identity_pair_ =
276 ReadTlsIdentityPair(kServerKeyPath, kServerCertPath);
277 bad_identity_pair_ =
278 ReadTlsIdentityPair(kBadClientKeyPath, kBadClientCertPath);
279 server_san_exact_.set_exact("*.test.google.fr");
280 server_san_prefix_.set_prefix("waterzooi.test.google");
281 server_san_suffix_.set_suffix("google.fr");
282 server_san_contains_.set_contains("google");
283 server_san_regex_.mutable_safe_regex()->mutable_google_re2();
284 server_san_regex_.mutable_safe_regex()->set_regex(
285 "(foo|waterzooi).test.google.(fr|be)");
286 bad_san_1_.set_exact("192.168.1.4");
287 bad_san_2_.set_exact("foo.test.google.in");
288 authenticated_identity_ = {"testclient"};
289 fallback_authenticated_identity_ = {"*.test.google.fr",
290 "waterzooi.test.google.be",
291 "*.test.youtube.com", "192.168.1.3"};
292 EdsResourceArgs args({
293 {"locality0", CreateEndpointsForBackends(0, 1)},
294 });
295 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
296 }
297
MaybeSetUpstreamTlsContextOnCluster(absl::string_view root_instance_name,absl::string_view root_certificate_name,absl::string_view identity_instance_name,absl::string_view identity_certificate_name,const std::vector<StringMatcher> & san_matchers,Cluster * cluster)298 void MaybeSetUpstreamTlsContextOnCluster(
299 absl::string_view root_instance_name,
300 absl::string_view root_certificate_name,
301 absl::string_view identity_instance_name,
302 absl::string_view identity_certificate_name,
303 const std::vector<StringMatcher>& san_matchers, Cluster* cluster) {
304 if (!identity_instance_name.empty() || !root_instance_name.empty()) {
305 auto* transport_socket = cluster->mutable_transport_socket();
306 transport_socket->set_name("envoy.transport_sockets.tls");
307 UpstreamTlsContext upstream_tls_context;
308 if (!identity_instance_name.empty()) {
309 upstream_tls_context.mutable_common_tls_context()
310 ->mutable_tls_certificate_provider_instance()
311 ->set_instance_name(std::string(identity_instance_name));
312 upstream_tls_context.mutable_common_tls_context()
313 ->mutable_tls_certificate_provider_instance()
314 ->set_certificate_name(std::string(identity_certificate_name));
315 }
316 if (!root_instance_name.empty()) {
317 upstream_tls_context.mutable_common_tls_context()
318 ->mutable_validation_context()
319 ->mutable_ca_certificate_provider_instance()
320 ->set_instance_name(std::string(root_instance_name));
321 upstream_tls_context.mutable_common_tls_context()
322 ->mutable_validation_context()
323 ->mutable_ca_certificate_provider_instance()
324 ->set_certificate_name(std::string(root_certificate_name));
325 }
326 if (!san_matchers.empty()) {
327 auto* validation_context =
328 upstream_tls_context.mutable_common_tls_context()
329 ->mutable_validation_context();
330 for (const auto& san_matcher : san_matchers) {
331 *validation_context->add_match_subject_alt_names() = san_matcher;
332 }
333 }
334 transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
335 }
336 }
337
338 // Sends CDS updates with the new security configuration and verifies that
339 // after propagation, this new configuration is used for connections. If \a
340 // identity_instance_name and \a root_instance_name are both empty,
341 // connections are expected to use fallback credentials.
342 // TODO(yashykt): The core of this logic should be inlined into the
343 // individual tests instead of being in this helper function.
UpdateAndVerifyXdsSecurityConfiguration(absl::string_view root_instance_name,absl::string_view root_certificate_name,absl::string_view identity_instance_name,absl::string_view identity_certificate_name,const std::vector<StringMatcher> & san_matchers,const std::vector<std::string> & expected_authenticated_identity,bool test_expects_failure=false)344 void UpdateAndVerifyXdsSecurityConfiguration(
345 absl::string_view root_instance_name,
346 absl::string_view root_certificate_name,
347 absl::string_view identity_instance_name,
348 absl::string_view identity_certificate_name,
349 const std::vector<StringMatcher>& san_matchers,
350 const std::vector<std::string>& expected_authenticated_identity,
351 bool test_expects_failure = false) {
352 // Change the backend and use a unique service name to use so that we know
353 // that the CDS update was applied.
354 std::string service_name = absl::StrCat(
355 "eds_service_name",
356 absl::FormatTime("%H%M%E3S", absl::Now(), absl::LocalTimeZone()));
357 backend_index_ = (backend_index_ + 1) % 2;
358 EdsResourceArgs args({
359 {"locality0",
360 CreateEndpointsForBackends(backend_index_, backend_index_ + 1)},
361 });
362 balancer_->ads_service()->SetEdsResource(
363 BuildEdsResource(args, service_name.c_str()));
364 auto cluster = default_cluster_;
365 cluster.mutable_eds_cluster_config()->set_service_name(service_name);
366 MaybeSetUpstreamTlsContextOnCluster(
367 root_instance_name, root_certificate_name, identity_instance_name,
368 identity_certificate_name, san_matchers, &cluster);
369 balancer_->ads_service()->SetCdsResource(cluster);
370 // The updates might take time to have an effect, so use a retry loop.
371 if (test_expects_failure) {
372 SendRpcsUntilFailure(DEBUG_LOCATION, StatusCode::UNAVAILABLE,
373 // TODO(yashkt): Change individual test cases to
374 // expect the exact error message here.
375 ".*", /*timeout_ms=*/20 * 1000,
376 RpcOptions().set_timeout_ms(5000));
377 } else {
378 backends_[backend_index_]->backend_service()->ResetCounters();
379 SendRpcsUntil(
380 DEBUG_LOCATION,
381 [&](const RpcResult& result) {
382 // Make sure that we are hitting the correct backend.
383 // TODO(yashykt): Even if we haven't moved to the correct backend
384 // and are still using the previous update, we should still check
385 // for the status and make sure that it fits our expectations.
386 if (backends_[backend_index_]->backend_service()->request_count() ==
387 0) {
388 return true;
389 }
390 EXPECT_TRUE(result.status.ok())
391 << "code=" << result.status.error_code()
392 << " message=" << result.status.error_message();
393 // Check that the identity is as expected.
394 EXPECT_EQ(backends_[backend_index_]
395 ->backend_service()
396 ->last_peer_identity(),
397 expected_authenticated_identity);
398 return false;
399 },
400 /* timeout_ms= */ 20 * 1000, RpcOptions().set_timeout_ms(5000));
401 }
402 }
403
404 std::string root_cert_;
405 std::string bad_root_cert_;
406 grpc_core::PemKeyCertPairList identity_pair_;
407 grpc_core::PemKeyCertPairList fallback_identity_pair_;
408 grpc_core::PemKeyCertPairList bad_identity_pair_;
409 StringMatcher server_san_exact_;
410 StringMatcher server_san_prefix_;
411 StringMatcher server_san_suffix_;
412 StringMatcher server_san_contains_;
413 StringMatcher server_san_regex_;
414 StringMatcher bad_san_1_;
415 StringMatcher bad_san_2_;
416 std::vector<std::string> authenticated_identity_;
417 std::vector<std::string> fallback_authenticated_identity_;
418 int backend_index_ = 0;
419 };
420
421 INSTANTIATE_TEST_SUITE_P(XdsTest, XdsSecurityTest,
422 ::testing::Values(XdsTestType()), &XdsTestType::Name);
423
TEST_P(XdsSecurityTest,TestTlsConfigurationInCombinedValidationContext)424 TEST_P(XdsSecurityTest, TestTlsConfigurationInCombinedValidationContext) {
425 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
426 auto cluster = default_cluster_;
427 auto* transport_socket = cluster.mutable_transport_socket();
428 transport_socket->set_name("envoy.transport_sockets.tls");
429 UpstreamTlsContext upstream_tls_context;
430 upstream_tls_context.mutable_common_tls_context()
431 ->mutable_combined_validation_context()
432 ->mutable_default_validation_context()
433 ->mutable_ca_certificate_provider_instance()
434 ->set_instance_name("fake_plugin1");
435 transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
436 balancer_->ads_service()->SetCdsResource(cluster);
437 CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(5000));
438 }
439
440 // TODO(yashykt): Remove this test once we stop supporting old fields
TEST_P(XdsSecurityTest,TestTlsConfigurationInValidationContextCertificateProviderInstance)441 TEST_P(XdsSecurityTest,
442 TestTlsConfigurationInValidationContextCertificateProviderInstance) {
443 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
444 auto cluster = default_cluster_;
445 auto* transport_socket = cluster.mutable_transport_socket();
446 transport_socket->set_name("envoy.transport_sockets.tls");
447 UpstreamTlsContext upstream_tls_context;
448 upstream_tls_context.mutable_common_tls_context()
449 ->mutable_combined_validation_context()
450 ->mutable_validation_context_certificate_provider_instance()
451 ->set_instance_name("fake_plugin1");
452 transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
453 balancer_->ads_service()->SetCdsResource(cluster);
454 CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(5000));
455 }
456
TEST_P(XdsSecurityTest,UseSystemRootCerts)457 TEST_P(XdsSecurityTest, UseSystemRootCerts) {
458 grpc_core::testing::ScopedExperimentalEnvVar env1(
459 "GRPC_EXPERIMENTAL_XDS_SYSTEM_ROOT_CERTS");
460 grpc_core::testing::ScopedEnvVar env2("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH",
461 kCaCertPath);
462 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
463 auto cluster = default_cluster_;
464 auto* transport_socket = cluster.mutable_transport_socket();
465 transport_socket->set_name("envoy.transport_sockets.tls");
466 UpstreamTlsContext upstream_tls_context;
467 upstream_tls_context.mutable_common_tls_context()
468 ->mutable_validation_context()
469 ->mutable_system_root_certs();
470 transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
471 balancer_->ads_service()->SetCdsResource(cluster);
472 CheckRpcSendOk(DEBUG_LOCATION, 1, RpcOptions().set_timeout_ms(5000));
473 }
474
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithNoSanMatchers)475 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithNoSanMatchers) {
476 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
477 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
478 "", {}, authenticated_identity_);
479 }
480
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithExactSanMatcher)481 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithExactSanMatcher) {
482 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
483 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
484 "", {server_san_exact_},
485 authenticated_identity_);
486 }
487
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithPrefixSanMatcher)488 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithPrefixSanMatcher) {
489 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
490 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
491 "", {server_san_prefix_},
492 authenticated_identity_);
493 }
494
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithSuffixSanMatcher)495 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithSuffixSanMatcher) {
496 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
497 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
498 "", {server_san_suffix_},
499 authenticated_identity_);
500 }
501
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithContainsSanMatcher)502 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithContainsSanMatcher) {
503 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
504 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
505 "", {server_san_contains_},
506 authenticated_identity_);
507 }
508
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithRegexSanMatcher)509 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRegexSanMatcher) {
510 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
511 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
512 "", {server_san_regex_},
513 authenticated_identity_);
514 }
515
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithSanMatchersUpdate)516 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithSanMatchersUpdate) {
517 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
518 UpdateAndVerifyXdsSecurityConfiguration(
519 "fake_plugin1", "", "fake_plugin1", "",
520 {server_san_exact_, server_san_prefix_}, authenticated_identity_);
521 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
522 "", {bad_san_1_, bad_san_2_}, {},
523 true /* failure */);
524 UpdateAndVerifyXdsSecurityConfiguration(
525 "fake_plugin1", "", "fake_plugin1", "",
526 {server_san_prefix_, server_san_regex_}, authenticated_identity_);
527 }
528
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithRootPluginUpdate)529 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRootPluginUpdate) {
530 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
531 g_fake2_cert_data_map->Set({{"", {bad_root_cert_, bad_identity_pair_}}});
532 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
533 "", {server_san_exact_},
534 authenticated_identity_);
535 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin2" /* bad root */, "",
536 "fake_plugin1", "", {}, {},
537 true /* failure */);
538 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
539 "", {server_san_exact_},
540 authenticated_identity_);
541 }
542
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithIdentityPluginUpdate)543 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithIdentityPluginUpdate) {
544 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
545 g_fake2_cert_data_map->Set({{"", {root_cert_, fallback_identity_pair_}}});
546 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
547 "", {server_san_exact_},
548 authenticated_identity_);
549 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin2",
550 "", {server_san_exact_},
551 fallback_authenticated_identity_);
552 }
553
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithBothPluginsUpdated)554 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithBothPluginsUpdated) {
555 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
556 g_fake2_cert_data_map->Set({{"", {bad_root_cert_, bad_identity_pair_}},
557 {"good", {root_cert_, fallback_identity_pair_}}});
558 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin2", "", "fake_plugin2",
559 "", {}, {}, true /* failure */);
560 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
561 "", {server_san_prefix_},
562 authenticated_identity_);
563 UpdateAndVerifyXdsSecurityConfiguration(
564 "fake_plugin2", "good", "fake_plugin2", "good", {server_san_prefix_},
565 fallback_authenticated_identity_);
566 }
567
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithRootCertificateNameUpdate)568 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRootCertificateNameUpdate) {
569 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
570 {"bad", {bad_root_cert_, bad_identity_pair_}}});
571 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
572 "", {server_san_regex_},
573 authenticated_identity_);
574 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "fake_plugin1",
575 "", {server_san_regex_}, {},
576 true /* failure */);
577 }
578
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithIdentityCertificateNameUpdate)579 TEST_P(XdsSecurityTest,
580 TestMtlsConfigurationWithIdentityCertificateNameUpdate) {
581 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
582 {"bad", {bad_root_cert_, bad_identity_pair_}}});
583 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
584 "", {server_san_exact_},
585 authenticated_identity_);
586 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
587 "bad", {server_san_exact_}, {},
588 true /* failure */);
589 }
590
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithIdentityCertificateNameUpdateGoodCerts)591 TEST_P(XdsSecurityTest,
592 TestMtlsConfigurationWithIdentityCertificateNameUpdateGoodCerts) {
593 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
594 {"good", {root_cert_, fallback_identity_pair_}}});
595 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
596 "", {server_san_exact_},
597 authenticated_identity_);
598 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
599 "good", {server_san_exact_},
600 fallback_authenticated_identity_);
601 }
602
TEST_P(XdsSecurityTest,TestMtlsConfigurationWithBothCertificateNamesUpdated)603 TEST_P(XdsSecurityTest, TestMtlsConfigurationWithBothCertificateNamesUpdated) {
604 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
605 {"bad", {bad_root_cert_, bad_identity_pair_}}});
606 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "fake_plugin1",
607 "bad", {server_san_prefix_}, {},
608 true /* failure */);
609 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
610 "", {server_san_prefix_},
611 authenticated_identity_);
612 }
613
TEST_P(XdsSecurityTest,TestTlsConfigurationWithNoSanMatchers)614 TEST_P(XdsSecurityTest, TestTlsConfigurationWithNoSanMatchers) {
615 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
616 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "", {},
617 {} /* unauthenticated */);
618 }
619
TEST_P(XdsSecurityTest,TestTlsConfigurationWithSanMatchers)620 TEST_P(XdsSecurityTest, TestTlsConfigurationWithSanMatchers) {
621 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
622 UpdateAndVerifyXdsSecurityConfiguration(
623 "fake_plugin1", "", "", "",
624 {server_san_exact_, server_san_prefix_, server_san_regex_},
625 {} /* unauthenticated */);
626 }
627
TEST_P(XdsSecurityTest,TestTlsConfigurationWithSanMatchersUpdate)628 TEST_P(XdsSecurityTest, TestTlsConfigurationWithSanMatchersUpdate) {
629 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
630 UpdateAndVerifyXdsSecurityConfiguration(
631 "fake_plugin1", "", "", "", {server_san_exact_, server_san_prefix_},
632 {} /* unauthenticated */);
633 UpdateAndVerifyXdsSecurityConfiguration(
634 "fake_plugin1", "", "", "", {bad_san_1_, bad_san_2_},
635 {} /* unauthenticated */, true /* failure */);
636 UpdateAndVerifyXdsSecurityConfiguration(
637 "fake_plugin1", "", "", "", {server_san_prefix_, server_san_regex_},
638 {} /* unauthenticated */);
639 }
640
TEST_P(XdsSecurityTest,TestTlsConfigurationWithRootCertificateNameUpdate)641 TEST_P(XdsSecurityTest, TestTlsConfigurationWithRootCertificateNameUpdate) {
642 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
643 {"bad", {bad_root_cert_, bad_identity_pair_}}});
644 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
645 {server_san_exact_},
646 {} /* unauthenticated */);
647 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "", "",
648 {server_san_exact_}, {},
649 true /* failure */);
650 }
651
TEST_P(XdsSecurityTest,TestTlsConfigurationWithRootPluginUpdate)652 TEST_P(XdsSecurityTest, TestTlsConfigurationWithRootPluginUpdate) {
653 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
654 g_fake2_cert_data_map->Set({{"", {bad_root_cert_, bad_identity_pair_}}});
655 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
656 {server_san_exact_},
657 {} /* unauthenticated */);
658 UpdateAndVerifyXdsSecurityConfiguration(
659 "fake_plugin2", "", "", "", {server_san_exact_}, {}, true /* failure */);
660 }
661
TEST_P(XdsSecurityTest,TestFallbackConfiguration)662 TEST_P(XdsSecurityTest, TestFallbackConfiguration) {
663 UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
664 fallback_authenticated_identity_);
665 }
666
TEST_P(XdsSecurityTest,TestMtlsToTls)667 TEST_P(XdsSecurityTest, TestMtlsToTls) {
668 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
669 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
670 "", {server_san_exact_},
671 authenticated_identity_);
672 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
673 {server_san_exact_},
674 {} /* unauthenticated */);
675 }
676
TEST_P(XdsSecurityTest,TestMtlsToFallback)677 TEST_P(XdsSecurityTest, TestMtlsToFallback) {
678 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
679 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
680 "", {server_san_exact_},
681 authenticated_identity_);
682 UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
683 fallback_authenticated_identity_);
684 }
685
TEST_P(XdsSecurityTest,TestTlsToMtls)686 TEST_P(XdsSecurityTest, TestTlsToMtls) {
687 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
688 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
689 {server_san_exact_},
690 {} /* unauthenticated */);
691 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
692 "", {server_san_exact_},
693 authenticated_identity_);
694 }
695
TEST_P(XdsSecurityTest,TestTlsToFallback)696 TEST_P(XdsSecurityTest, TestTlsToFallback) {
697 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
698 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
699 {server_san_exact_},
700 {} /* unauthenticated */);
701 UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
702 fallback_authenticated_identity_);
703 }
704
TEST_P(XdsSecurityTest,TestFallbackToMtls)705 TEST_P(XdsSecurityTest, TestFallbackToMtls) {
706 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
707 UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
708 fallback_authenticated_identity_);
709 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
710 "", {server_san_exact_},
711 authenticated_identity_);
712 }
713
TEST_P(XdsSecurityTest,TestFallbackToTls)714 TEST_P(XdsSecurityTest, TestFallbackToTls) {
715 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
716 UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
717 fallback_authenticated_identity_);
718 UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
719 {server_san_exact_},
720 {} /* unauthenticated */);
721 }
722
TEST_P(XdsSecurityTest,TestFileWatcherCertificateProvider)723 TEST_P(XdsSecurityTest, TestFileWatcherCertificateProvider) {
724 UpdateAndVerifyXdsSecurityConfiguration("file_plugin", "", "file_plugin", "",
725 {server_san_exact_},
726 authenticated_identity_);
727 }
728
TEST_P(XdsSecurityTest,MtlsWithAggregateCluster)729 TEST_P(XdsSecurityTest, MtlsWithAggregateCluster) {
730 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
731 g_fake2_cert_data_map->Set({{"", {root_cert_, fallback_identity_pair_}}});
732 // Set up aggregate cluster.
733 const char* kNewCluster1Name = "new_cluster_1";
734 const char* kNewEdsService1Name = "new_eds_service_name_1";
735 const char* kNewCluster2Name = "new_cluster_2";
736 const char* kNewEdsService2Name = "new_eds_service_name_2";
737 // Populate new EDS resources.
738 EdsResourceArgs args1({
739 {"locality0", CreateEndpointsForBackends(0, 1)},
740 });
741 EdsResourceArgs args2({
742 {"locality0", CreateEndpointsForBackends(1, 2)},
743 });
744 balancer_->ads_service()->SetEdsResource(
745 BuildEdsResource(args1, kNewEdsService1Name));
746 balancer_->ads_service()->SetEdsResource(
747 BuildEdsResource(args2, kNewEdsService2Name));
748 // Populate new CDS resources.
749 Cluster new_cluster1 = default_cluster_;
750 new_cluster1.set_name(kNewCluster1Name);
751 new_cluster1.mutable_eds_cluster_config()->set_service_name(
752 kNewEdsService1Name);
753 MaybeSetUpstreamTlsContextOnCluster("fake_plugin1", "", "fake_plugin1", "",
754 {}, &new_cluster1);
755 balancer_->ads_service()->SetCdsResource(new_cluster1);
756 Cluster new_cluster2 = default_cluster_;
757 new_cluster2.set_name(kNewCluster2Name);
758 new_cluster2.mutable_eds_cluster_config()->set_service_name(
759 kNewEdsService2Name);
760 MaybeSetUpstreamTlsContextOnCluster("fake_plugin1", "", "fake_plugin2", "",
761 {}, &new_cluster2);
762 balancer_->ads_service()->SetCdsResource(new_cluster2);
763 // Create Aggregate Cluster
764 auto cluster = default_cluster_;
765 auto* custom_cluster = cluster.mutable_cluster_type();
766 custom_cluster->set_name("envoy.clusters.aggregate");
767 envoy::extensions::clusters::aggregate::v3::ClusterConfig cluster_config;
768 cluster_config.add_clusters(kNewCluster1Name);
769 cluster_config.add_clusters(kNewCluster2Name);
770 custom_cluster->mutable_typed_config()->PackFrom(cluster_config);
771 balancer_->ads_service()->SetCdsResource(cluster);
772 // RPC should go to backend 0.
773 CheckRpcSendOk(DEBUG_LOCATION);
774 EXPECT_EQ(backends_[0]->backend_service()->request_count(), 1);
775 // Make sure the backend saw the right client identity.
776 EXPECT_EQ(backends_[0]->backend_service()->last_peer_identity(),
777 authenticated_identity_);
778 // Now stop backend 0 and wait for backend 1.
779 backends_[0]->StopListeningAndSendGoaways();
780 WaitForBackend(DEBUG_LOCATION, 1);
781 // Make sure the backend saw the right client identity.
782 EXPECT_EQ(backends_[1]->backend_service()->last_peer_identity(),
783 fallback_authenticated_identity_);
784 }
785
786 //
787 // Server-side mTLS tests
788 //
789
790 class XdsServerSecurityTest : public XdsEnd2endTest {
791 protected:
SetUp()792 void SetUp() override {
793 XdsBootstrapBuilder builder = MakeBootstrapBuilder();
794 builder.AddCertificateProviderPlugin("fake_plugin1", "fake1");
795 builder.AddCertificateProviderPlugin("fake_plugin2", "fake2");
796 std::vector<std::string> fields;
797 fields.push_back(absl::StrFormat(" \"certificate_file\": \"%s\"",
798 kClientCertPath));
799 fields.push_back(absl::StrFormat(" \"private_key_file\": \"%s\"",
800 kClientKeyPath));
801 fields.push_back(absl::StrFormat(" \"ca_certificate_file\": \"%s\"",
802 kCaCertPath));
803 builder.AddCertificateProviderPlugin("file_plugin", "file_watcher",
804 absl::StrJoin(fields, ",\n"));
805 InitClient(builder, /*lb_expected_authority=*/"",
806 /*xds_resource_does_not_exist_timeout_ms=*/
807 500, // using a low timeout to quickly end negative tests.
808 // Prefer using WaitOnServingStatusChange() or a similar
809 // loop on the client side to wait on status changes
810 // instead of increasing this timeout.
811 /*balancer_authority_override=*/"", /*args=*/nullptr,
812 CreateXdsChannelCredentials());
813 CreateBackends(1, /*xds_enabled=*/true,
814 XdsServerCredentials(InsecureServerCredentials()));
815 root_cert_ = grpc_core::testing::GetFileContents(kCaCertPath);
816 bad_root_cert_ = grpc_core::testing::GetFileContents(kBadClientCertPath);
817 identity_pair_ = ReadTlsIdentityPair(kServerKeyPath, kServerCertPath);
818 bad_identity_pair_ =
819 ReadTlsIdentityPair(kBadClientKeyPath, kBadClientCertPath);
820 identity_pair_2_ = ReadTlsIdentityPair(kClientKeyPath, kClientCertPath);
821 server_authenticated_identity_ = {"*.test.google.fr",
822 "waterzooi.test.google.be",
823 "*.test.youtube.com", "192.168.1.3"};
824 server_authenticated_identity_2_ = {"testclient"};
825 client_authenticated_identity_ = {"*.test.google.fr",
826 "waterzooi.test.google.be",
827 "*.test.youtube.com", "192.168.1.3"};
828 EdsResourceArgs args({
829 {"locality0", CreateEndpointsForBackends(0, 1)},
830 });
831 balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
832 }
833
SetLdsUpdate(absl::string_view root_instance_name,absl::string_view root_certificate_name,absl::string_view identity_instance_name,absl::string_view identity_certificate_name,bool require_client_certificates)834 void SetLdsUpdate(absl::string_view root_instance_name,
835 absl::string_view root_certificate_name,
836 absl::string_view identity_instance_name,
837 absl::string_view identity_certificate_name,
838 bool require_client_certificates) {
839 Listener listener = default_server_listener_;
840 auto* filter_chain = listener.mutable_default_filter_chain();
841 if (!identity_instance_name.empty()) {
842 auto* transport_socket = filter_chain->mutable_transport_socket();
843 transport_socket->set_name("envoy.transport_sockets.tls");
844 DownstreamTlsContext downstream_tls_context;
845 downstream_tls_context.mutable_common_tls_context()
846 ->mutable_tls_certificate_provider_instance()
847 ->set_instance_name(std::string(identity_instance_name));
848 downstream_tls_context.mutable_common_tls_context()
849 ->mutable_tls_certificate_provider_instance()
850 ->set_certificate_name(std::string(identity_certificate_name));
851 if (!root_instance_name.empty()) {
852 downstream_tls_context.mutable_common_tls_context()
853 ->mutable_validation_context()
854 ->mutable_ca_certificate_provider_instance()
855 ->set_instance_name(std::string(root_instance_name));
856 downstream_tls_context.mutable_common_tls_context()
857 ->mutable_validation_context()
858 ->mutable_ca_certificate_provider_instance()
859 ->set_certificate_name(std::string(root_certificate_name));
860 downstream_tls_context.mutable_require_client_certificate()->set_value(
861 require_client_certificates);
862 }
863 transport_socket->mutable_typed_config()->PackFrom(
864 downstream_tls_context);
865 }
866 SetServerListenerNameAndRouteConfiguration(balancer_.get(), listener,
867 backends_[0]->port(),
868 default_server_route_config_);
869 }
870
871 // TODO(yashykt): These methods to create channels should be
872 // integrated into the framework, probably by just constructing the
873 // credentials and then passing them to XdsEnd2endTest::CreateChannel().
874 // It may also be helpful to add methods to the framework to construct
875 // these creds types, similar to
876 // XdsEnd2endTest::CreateTlsChannelCredentials().
877
CreateMtlsChannel()878 std::shared_ptr<grpc::Channel> CreateMtlsChannel() {
879 ChannelArguments args;
880 // Override target name for host name check
881 args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
882 std::string(grpc_core::LocalIp()));
883 args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1);
884 std::string uri = grpc_core::LocalIpUri(backends_[0]->port());
885 IdentityKeyCertPair key_cert_pair;
886 key_cert_pair.private_key =
887 grpc_core::testing::GetFileContents(kServerKeyPath);
888 key_cert_pair.certificate_chain =
889 grpc_core::testing::GetFileContents(kServerCertPath);
890 std::vector<IdentityKeyCertPair> identity_key_cert_pairs;
891 identity_key_cert_pairs.emplace_back(key_cert_pair);
892 auto certificate_provider = std::make_shared<StaticDataCertificateProvider>(
893 grpc_core::testing::GetFileContents(kCaCertPath),
894 identity_key_cert_pairs);
895 grpc::experimental::TlsChannelCredentialsOptions options;
896 options.set_certificate_provider(std::move(certificate_provider));
897 options.watch_root_certs();
898 options.watch_identity_key_cert_pairs();
899 auto verifier =
900 ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
901 options.set_verify_server_certs(true);
902 options.set_certificate_verifier(std::move(verifier));
903 auto channel_creds = grpc::experimental::TlsCredentials(options);
904 CHECK_NE(channel_creds.get(), nullptr);
905 return CreateCustomChannel(uri, channel_creds, args);
906 }
907
CreateTlsChannel()908 std::shared_ptr<grpc::Channel> CreateTlsChannel() {
909 ChannelArguments args;
910 // Override target name for host name check
911 args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
912 std::string(grpc_core::LocalIp()));
913 args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1);
914 std::string uri = grpc_core::LocalIpUri(backends_[0]->port());
915 auto certificate_provider = std::make_shared<StaticDataCertificateProvider>(
916 grpc_core::testing::GetFileContents(kCaCertPath));
917 grpc::experimental::TlsChannelCredentialsOptions options;
918 options.set_certificate_provider(std::move(certificate_provider));
919 options.watch_root_certs();
920 auto verifier =
921 ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true);
922 options.set_verify_server_certs(true);
923 options.set_certificate_verifier(std::move(verifier));
924 auto channel_creds = grpc::experimental::TlsCredentials(options);
925 CHECK_NE(channel_creds.get(), nullptr);
926 return CreateCustomChannel(uri, channel_creds, args);
927 }
928
CreateInsecureChannel(bool use_put_requests=false)929 std::shared_ptr<grpc::Channel> CreateInsecureChannel(
930 bool use_put_requests = false) {
931 ChannelArguments args;
932 // Override target name for host name check
933 args.SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
934 std::string(grpc_core::LocalIp()));
935 args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1);
936 if (use_put_requests) {
937 args.SetInt(GRPC_ARG_TEST_ONLY_USE_PUT_REQUESTS, 1);
938 }
939 std::string uri = grpc_core::LocalIpUri(backends_[0]->port());
940 return CreateCustomChannel(uri, InsecureChannelCredentials(), args);
941 }
942
943 // TODO(yashykt): The core of this logic should be inlined into the
944 // individual tests instead of being in this helper function. This
945 // can probably be replaced with something like
946 // XdsEnd2endTest::SendRpcsUntil().
SendRpc(absl::FunctionRef<std::shared_ptr<grpc::Channel> ()> channel_creator,const RpcOptions & rpc_options,const std::vector<std::string> & expected_server_identity,const std::vector<std::string> & expected_client_identity,bool test_expects_failure=false,absl::optional<grpc::StatusCode> expected_status=absl::nullopt,absl::string_view expected_error_message_regex="")947 void SendRpc(
948 absl::FunctionRef<std::shared_ptr<grpc::Channel>()> channel_creator,
949 const RpcOptions& rpc_options,
950 const std::vector<std::string>& expected_server_identity,
951 const std::vector<std::string>& expected_client_identity,
952 bool test_expects_failure = false,
953 absl::optional<grpc::StatusCode> expected_status = absl::nullopt,
954 absl::string_view expected_error_message_regex = "") {
955 LOG(INFO) << "Sending RPC";
956 int num_tries = 0;
957 constexpr int kRetryCount = 100;
958 auto overall_deadline =
959 absl::Now() + absl::Seconds(20) * grpc_test_slowdown_factor();
960 auto channel = channel_creator();
961 auto stub = grpc::testing::EchoTestService::NewStub(channel);
962 for (; num_tries < kRetryCount || absl::Now() < overall_deadline;
963 num_tries++) {
964 ClientContext context;
965 EchoRequest request;
966 rpc_options.SetupRpc(&context, &request);
967 // TODO(yashykt): Skipping the cancelled check on the server since the
968 // server's graceful shutdown isn't as per spec and the check isn't
969 // necessary for what we want to test here anyway.
970 // https://github.com/grpc/grpc/issues/24237
971 request.mutable_param()->set_skip_cancelled_check(true);
972 request.set_message(kRequestMessage);
973 EchoResponse response;
974 Status status = stub->Echo(&context, request, &response);
975 if (test_expects_failure) {
976 if (status.ok()) {
977 LOG(ERROR) << "RPC succeeded. Failure expected. Trying again.";
978 continue;
979 }
980 if (expected_status.has_value() &&
981 *expected_status != status.error_code()) {
982 LOG(ERROR) << "Expected status does not match Actual("
983 << status.error_code() << ") vs Expected("
984 << *expected_status << ")";
985 continue;
986 }
987 EXPECT_THAT(status.error_message(),
988 ::testing::MatchesRegex(expected_error_message_regex));
989 } else {
990 if (!status.ok()) {
991 LOG(ERROR) << "RPC failed. code=" << status.error_code()
992 << " message=" << status.error_message()
993 << " Trying again.";
994 continue;
995 }
996 EXPECT_EQ(response.message(), kRequestMessage);
997 std::vector<std::string> peer_identity;
998 for (const auto& entry : context.auth_context()->GetPeerIdentity()) {
999 peer_identity.emplace_back(
1000 std::string(entry.data(), entry.size()).c_str());
1001 }
1002 if (peer_identity != expected_server_identity) {
1003 LOG(ERROR) << "Expected server identity does not match. (actual) "
1004 << absl::StrJoin(peer_identity, ",") << " vs (expected) "
1005 << absl::StrJoin(expected_server_identity, ",")
1006 << " Trying again.";
1007 continue;
1008 }
1009 if (backends_[0]->backend_service()->last_peer_identity() !=
1010 expected_client_identity) {
1011 LOG(ERROR)
1012 << "Expected client identity does not match. (actual) "
1013 << absl::StrJoin(
1014 backends_[0]->backend_service()->last_peer_identity(), ",")
1015 << " vs (expected) "
1016 << absl::StrJoin(expected_client_identity, ",")
1017 << " Trying again.";
1018 continue;
1019 }
1020 }
1021 break;
1022 }
1023 EXPECT_TRUE(absl::Now() <= overall_deadline || num_tries < kRetryCount);
1024 }
1025
1026 std::string root_cert_;
1027 std::string bad_root_cert_;
1028 grpc_core::PemKeyCertPairList identity_pair_;
1029 grpc_core::PemKeyCertPairList bad_identity_pair_;
1030 grpc_core::PemKeyCertPairList identity_pair_2_;
1031 std::vector<std::string> server_authenticated_identity_;
1032 std::vector<std::string> server_authenticated_identity_2_;
1033 std::vector<std::string> client_authenticated_identity_;
1034 };
1035
1036 // We are only testing the server here.
1037 // Run with bootstrap from env var so that we use one XdsClient.
1038 INSTANTIATE_TEST_SUITE_P(XdsTest, XdsServerSecurityTest,
1039 ::testing::Values(XdsTestType().set_bootstrap_source(
1040 XdsTestType::kBootstrapFromEnvVar)),
1041 &XdsTestType::Name);
1042
TEST_P(XdsServerSecurityTest,TestDeprecateTlsCertificateCertificateProviderInstanceField)1043 TEST_P(XdsServerSecurityTest,
1044 TestDeprecateTlsCertificateCertificateProviderInstanceField) {
1045 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1046 Listener listener = default_server_listener_;
1047 auto* filter_chain = listener.mutable_default_filter_chain();
1048 filter_chain->mutable_filters()->at(0).mutable_typed_config()->PackFrom(
1049 ServerHcmAccessor().Unpack(listener));
1050 auto* transport_socket = filter_chain->mutable_transport_socket();
1051 transport_socket->set_name("envoy.transport_sockets.tls");
1052 DownstreamTlsContext downstream_tls_context;
1053 downstream_tls_context.mutable_common_tls_context()
1054 ->mutable_tls_certificate_certificate_provider_instance()
1055 ->set_instance_name("fake_plugin1");
1056 transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context);
1057 SetServerListenerNameAndRouteConfiguration(balancer_.get(), listener,
1058 backends_[0]->port(),
1059 default_server_route_config_);
1060 StartBackend(0);
1061 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1062 SendRpc([this]() { return CreateTlsChannel(); },
1063 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1064 {});
1065 }
1066
TEST_P(XdsServerSecurityTest,CertificatesNotAvailable)1067 TEST_P(XdsServerSecurityTest, CertificatesNotAvailable) {
1068 g_fake1_cert_data_map->Set({});
1069 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1070 StartBackend(0);
1071 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1072 SendRpc([this]() { return CreateMtlsChannel(); }, RpcOptions(), {}, {},
1073 true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
1074 MakeConnectionFailureRegex(
1075 "failed to connect to all addresses; last error: ",
1076 /*has_resolution_note=*/false));
1077 }
1078
TEST_P(XdsServerSecurityTest,TestMtls)1079 TEST_P(XdsServerSecurityTest, TestMtls) {
1080 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1081 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1082 StartBackend(0);
1083 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1084 SendRpc([this]() { return CreateMtlsChannel(); },
1085 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1086 client_authenticated_identity_);
1087 }
1088
TEST_P(XdsServerSecurityTest,TestMtlsWithRootPluginUpdate)1089 TEST_P(XdsServerSecurityTest, TestMtlsWithRootPluginUpdate) {
1090 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1091 g_fake2_cert_data_map->Set({{"", {bad_root_cert_, bad_identity_pair_}}});
1092 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1093 StartBackend(0);
1094 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1095 SendRpc([this]() { return CreateMtlsChannel(); },
1096 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1097 client_authenticated_identity_);
1098 SetLdsUpdate("fake_plugin2", "", "fake_plugin1", "", true);
1099 SendRpc([this]() { return CreateMtlsChannel(); }, RpcOptions(), {}, {},
1100 true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
1101 MakeConnectionFailureRegex(
1102 "failed to connect to all addresses; last error: ",
1103 /*has_resolution_note=*/false));
1104 }
1105
TEST_P(XdsServerSecurityTest,TestMtlsWithIdentityPluginUpdate)1106 TEST_P(XdsServerSecurityTest, TestMtlsWithIdentityPluginUpdate) {
1107 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1108 g_fake2_cert_data_map->Set({{"", {root_cert_, identity_pair_2_}}});
1109 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1110 StartBackend(0);
1111 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1112 SendRpc([this]() { return CreateMtlsChannel(); },
1113 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1114 client_authenticated_identity_);
1115 SetLdsUpdate("fake_plugin1", "", "fake_plugin2", "", true);
1116 SendRpc([this]() { return CreateMtlsChannel(); },
1117 RpcOptions().set_wait_for_ready(true),
1118 server_authenticated_identity_2_, client_authenticated_identity_);
1119 }
1120
TEST_P(XdsServerSecurityTest,TestMtlsWithBothPluginsUpdated)1121 TEST_P(XdsServerSecurityTest, TestMtlsWithBothPluginsUpdated) {
1122 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1123 g_fake2_cert_data_map->Set({{"good", {root_cert_, identity_pair_2_}},
1124 {"", {bad_root_cert_, bad_identity_pair_}}});
1125 SetLdsUpdate("fake_plugin2", "", "fake_plugin2", "", true);
1126 StartBackend(0);
1127 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1128 SendRpc([this]() { return CreateMtlsChannel(); }, RpcOptions(), {}, {},
1129 true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
1130 MakeTlsHandshakeFailureRegex(
1131 "failed to connect to all addresses; last error: "));
1132 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1133 SendRpc([this]() { return CreateMtlsChannel(); },
1134 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1135 client_authenticated_identity_);
1136 SetLdsUpdate("fake_plugin2", "good", "fake_plugin2", "good", true);
1137 SendRpc([this]() { return CreateMtlsChannel(); },
1138 RpcOptions().set_wait_for_ready(true),
1139 server_authenticated_identity_2_, client_authenticated_identity_);
1140 }
1141
TEST_P(XdsServerSecurityTest,TestMtlsWithRootCertificateNameUpdate)1142 TEST_P(XdsServerSecurityTest, TestMtlsWithRootCertificateNameUpdate) {
1143 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
1144 {"bad", {bad_root_cert_, bad_identity_pair_}}});
1145 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1146 StartBackend(0);
1147 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1148 SendRpc([this]() { return CreateMtlsChannel(); },
1149 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1150 client_authenticated_identity_);
1151 SetLdsUpdate("fake_plugin1", "bad", "fake_plugin1", "", true);
1152 SendRpc([this]() { return CreateMtlsChannel(); }, RpcOptions(), {}, {},
1153 true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
1154 MakeConnectionFailureRegex(
1155 "failed to connect to all addresses; last error: ",
1156 /*has_resolution_note=*/false));
1157 }
1158
TEST_P(XdsServerSecurityTest,TestMtlsWithIdentityCertificateNameUpdate)1159 TEST_P(XdsServerSecurityTest, TestMtlsWithIdentityCertificateNameUpdate) {
1160 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
1161 {"good", {root_cert_, identity_pair_2_}}});
1162 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1163 StartBackend(0);
1164 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1165 SendRpc([this]() { return CreateMtlsChannel(); },
1166 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1167 client_authenticated_identity_);
1168 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "good", true);
1169 SendRpc([this]() { return CreateMtlsChannel(); },
1170 RpcOptions().set_wait_for_ready(true),
1171 server_authenticated_identity_2_, client_authenticated_identity_);
1172 }
1173
TEST_P(XdsServerSecurityTest,TestMtlsWithBothCertificateNamesUpdated)1174 TEST_P(XdsServerSecurityTest, TestMtlsWithBothCertificateNamesUpdated) {
1175 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
1176 {"good", {root_cert_, identity_pair_2_}}});
1177 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1178 StartBackend(0);
1179 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1180 SendRpc([this]() { return CreateMtlsChannel(); },
1181 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1182 client_authenticated_identity_);
1183 SetLdsUpdate("fake_plugin1", "good", "fake_plugin1", "good", true);
1184 SendRpc([this]() { return CreateMtlsChannel(); },
1185 RpcOptions().set_wait_for_ready(true),
1186 server_authenticated_identity_2_, client_authenticated_identity_);
1187 }
1188
TEST_P(XdsServerSecurityTest,TestMtlsNotRequiringButProvidingClientCerts)1189 TEST_P(XdsServerSecurityTest, TestMtlsNotRequiringButProvidingClientCerts) {
1190 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1191 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", false);
1192 StartBackend(0);
1193 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1194 SendRpc([this]() { return CreateMtlsChannel(); },
1195 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1196 client_authenticated_identity_);
1197 }
1198
TEST_P(XdsServerSecurityTest,TestMtlsNotRequiringAndNotProvidingClientCerts)1199 TEST_P(XdsServerSecurityTest, TestMtlsNotRequiringAndNotProvidingClientCerts) {
1200 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1201 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", false);
1202 StartBackend(0);
1203 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1204 SendRpc([this]() { return CreateTlsChannel(); },
1205 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1206 {});
1207 }
1208
TEST_P(XdsServerSecurityTest,TestTls)1209 TEST_P(XdsServerSecurityTest, TestTls) {
1210 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1211 SetLdsUpdate("", "", "fake_plugin1", "", false);
1212 StartBackend(0);
1213 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1214 SendRpc([this]() { return CreateTlsChannel(); },
1215 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1216 {});
1217 }
1218
TEST_P(XdsServerSecurityTest,TestTlsWithIdentityPluginUpdate)1219 TEST_P(XdsServerSecurityTest, TestTlsWithIdentityPluginUpdate) {
1220 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1221 g_fake2_cert_data_map->Set({{"", {root_cert_, identity_pair_2_}}});
1222 SetLdsUpdate("", "", "fake_plugin1", "", false);
1223 StartBackend(0);
1224 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1225 SendRpc([this]() { return CreateTlsChannel(); },
1226 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1227 {});
1228 SetLdsUpdate("", "", "fake_plugin2", "", false);
1229 SendRpc([this]() { return CreateTlsChannel(); },
1230 RpcOptions().set_wait_for_ready(true),
1231 server_authenticated_identity_2_, {});
1232 }
1233
TEST_P(XdsServerSecurityTest,TestTlsWithIdentityCertificateNameUpdate)1234 TEST_P(XdsServerSecurityTest, TestTlsWithIdentityCertificateNameUpdate) {
1235 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}},
1236 {"good", {root_cert_, identity_pair_2_}}});
1237 SetLdsUpdate("", "", "fake_plugin1", "", false);
1238 StartBackend(0);
1239 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1240 SendRpc([this]() { return CreateTlsChannel(); },
1241 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1242 {});
1243 SetLdsUpdate("", "", "fake_plugin1", "good", false);
1244 SendRpc([this]() { return CreateTlsChannel(); },
1245 RpcOptions().set_wait_for_ready(true),
1246 server_authenticated_identity_2_, {});
1247 }
1248
TEST_P(XdsServerSecurityTest,TestFallback)1249 TEST_P(XdsServerSecurityTest, TestFallback) {
1250 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1251 SetLdsUpdate("", "", "", "", false);
1252 StartBackend(0);
1253 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1254 SendRpc([this]() { return CreateInsecureChannel(); },
1255 RpcOptions().set_wait_for_ready(true), {}, {});
1256 }
1257
TEST_P(XdsServerSecurityTest,TestMtlsToTls)1258 TEST_P(XdsServerSecurityTest, TestMtlsToTls) {
1259 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1260 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1261 StartBackend(0);
1262 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1263 SendRpc([this]() { return CreateTlsChannel(); }, RpcOptions(), {}, {},
1264 true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
1265 MakeConnectionFailureRegex(
1266 "failed to connect to all addresses; last error: ",
1267 /*has_resolution_note=*/false));
1268 SetLdsUpdate("", "", "fake_plugin1", "", false);
1269 SendRpc([this]() { return CreateTlsChannel(); },
1270 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1271 {});
1272 }
1273
TEST_P(XdsServerSecurityTest,TestTlsToMtls)1274 TEST_P(XdsServerSecurityTest, TestTlsToMtls) {
1275 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1276 SetLdsUpdate("", "", "fake_plugin1", "", false);
1277 StartBackend(0);
1278 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1279 SendRpc([this]() { return CreateTlsChannel(); },
1280 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1281 {});
1282 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1283 SendRpc([this]() { return CreateTlsChannel(); }, RpcOptions(), {}, {},
1284 true /* test_expects_failure */, grpc::StatusCode::UNAVAILABLE,
1285 MakeConnectionFailureRegex(
1286 "failed to connect to all addresses; last error: ",
1287 /*has_resolution_note=*/false));
1288 }
1289
TEST_P(XdsServerSecurityTest,TestMtlsToFallback)1290 TEST_P(XdsServerSecurityTest, TestMtlsToFallback) {
1291 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1292 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", false);
1293 StartBackend(0);
1294 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1295 SendRpc([this]() { return CreateMtlsChannel(); },
1296 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1297 client_authenticated_identity_);
1298 SetLdsUpdate("", "", "", "", false);
1299 SendRpc([this]() { return CreateInsecureChannel(); },
1300 RpcOptions().set_wait_for_ready(true), {}, {});
1301 }
1302
TEST_P(XdsServerSecurityTest,TestFallbackToMtls)1303 TEST_P(XdsServerSecurityTest, TestFallbackToMtls) {
1304 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1305 SetLdsUpdate("", "", "", "", false);
1306 StartBackend(0);
1307 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1308 SendRpc([this]() { return CreateInsecureChannel(); },
1309 RpcOptions().set_wait_for_ready(true), {}, {});
1310 SetLdsUpdate("fake_plugin1", "", "fake_plugin1", "", true);
1311 SendRpc([this]() { return CreateMtlsChannel(); },
1312 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1313 client_authenticated_identity_);
1314 }
1315
TEST_P(XdsServerSecurityTest,TestTlsToFallback)1316 TEST_P(XdsServerSecurityTest, TestTlsToFallback) {
1317 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1318 SetLdsUpdate("", "", "fake_plugin1", "", false);
1319 StartBackend(0);
1320 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1321 SendRpc([this]() { return CreateTlsChannel(); },
1322 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1323 {});
1324 SetLdsUpdate("", "", "", "", false);
1325 SendRpc([this]() { return CreateInsecureChannel(); },
1326 RpcOptions().set_wait_for_ready(true), {}, {});
1327 }
1328
TEST_P(XdsServerSecurityTest,TestFallbackToTls)1329 TEST_P(XdsServerSecurityTest, TestFallbackToTls) {
1330 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
1331 SetLdsUpdate("", "", "", "", false);
1332 StartBackend(0);
1333 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1334 SendRpc([this]() { return CreateInsecureChannel(); },
1335 RpcOptions().set_wait_for_ready(true), {}, {});
1336 SetLdsUpdate("", "", "fake_plugin1", "", false);
1337 SendRpc([this]() { return CreateTlsChannel(); },
1338 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
1339 {});
1340 }
1341
1342 //
1343 // Basic RBAC tests
1344 //
1345
1346 class XdsRbacTest : public XdsServerSecurityTest {
1347 protected:
XdsRbacTest()1348 XdsRbacTest() {
1349 RegisterAuditLoggerFactory(
1350 std::make_unique<TestAuditLoggerFactory>(&audit_logs_));
1351 }
1352
~XdsRbacTest()1353 ~XdsRbacTest() override { AuditLoggerRegistry::TestOnlyResetRegistry(); }
1354
SetServerRbacPolicies(Listener listener,const std::vector<RBAC> & rbac_policies)1355 void SetServerRbacPolicies(Listener listener,
1356 const std::vector<RBAC>& rbac_policies) {
1357 HttpConnectionManager http_connection_manager =
1358 ServerHcmAccessor().Unpack(listener);
1359 http_connection_manager.clear_http_filters();
1360 RouteConfiguration route_config = default_server_route_config_;
1361 int count = 0;
1362 for (auto& rbac : rbac_policies) {
1363 auto* filter = http_connection_manager.add_http_filters();
1364 std::string filter_name = absl::StrFormat("rbac%d", ++count);
1365 filter->set_name(filter_name);
1366 switch (GetParam().filter_config_setup()) {
1367 case XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInListener:
1368 filter->mutable_typed_config()->PackFrom(rbac);
1369 break;
1370 case XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute:
1371 filter->mutable_typed_config()->PackFrom(RBAC());
1372 google::protobuf::Any filter_config;
1373 RBACPerRoute rbac_per_route;
1374 *rbac_per_route.mutable_rbac() = rbac;
1375 filter_config.PackFrom(rbac_per_route);
1376 auto* config_map = route_config.mutable_virtual_hosts(0)
1377 ->mutable_routes(0)
1378 ->mutable_typed_per_filter_config();
1379 (*config_map)[filter_name] = std::move(filter_config);
1380 }
1381 }
1382 auto* filter = http_connection_manager.add_http_filters();
1383 filter->set_name("router");
1384 filter->mutable_typed_config()->PackFrom(
1385 envoy::extensions::filters::http::router::v3::Router());
1386 ServerHcmAccessor().Pack(http_connection_manager, &listener);
1387 SetServerListenerNameAndRouteConfiguration(
1388 balancer_.get(), listener, backends_[0]->port(), route_config);
1389 }
1390
SetServerRbacPolicy(Listener listener,const RBAC & rbac)1391 void SetServerRbacPolicy(Listener listener, const RBAC& rbac) {
1392 SetServerRbacPolicies(std::move(listener), {rbac});
1393 }
1394
SetServerRbacPolicy(const RBAC & rbac)1395 void SetServerRbacPolicy(const RBAC& rbac) {
1396 SetServerRbacPolicy(default_server_listener_, rbac);
1397 }
1398
1399 std::vector<std::string> audit_logs_;
1400 };
1401
1402 // We test with and without RDS, and with the filter config both at the
1403 // top level and in the route.
1404 // Run with bootstrap from env var, so that we use a global XdsClient
1405 // instance. Otherwise, we would need to use a separate fake resolver
1406 // result generator on the client and server sides.
1407 INSTANTIATE_TEST_SUITE_P(
1408 XdsTest, XdsRbacTest,
1409 ::testing::Values(
1410 XdsTestType().set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1411 XdsTestType().set_enable_rds_testing().set_bootstrap_source(
1412 XdsTestType::kBootstrapFromEnvVar),
1413 XdsTestType()
1414 .set_filter_config_setup(
1415 XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute)
1416 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1417 XdsTestType()
1418 .set_enable_rds_testing()
1419 .set_filter_config_setup(
1420 XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute)
1421 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar)),
1422 &XdsTestType::Name);
1423
TEST_P(XdsRbacTest,AbsentRbacPolicy)1424 TEST_P(XdsRbacTest, AbsentRbacPolicy) {
1425 SetServerRbacPolicy(RBAC());
1426 StartBackend(0);
1427 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1428 // An absent RBAC policy leads to all RPCs being accepted.
1429 SendRpc([this]() { return CreateInsecureChannel(); },
1430 RpcOptions().set_wait_for_ready(true), {}, {});
1431 }
1432
TEST_P(XdsRbacTest,LogAction)1433 TEST_P(XdsRbacTest, LogAction) {
1434 RBAC rbac;
1435 auto* rules = rbac.mutable_rules();
1436 rules->set_action(RBAC_Action_LOG);
1437 SetServerRbacPolicy(rbac);
1438 StartBackend(0);
1439 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1440 // A Log action is identical to no rbac policy being configured.
1441 SendRpc([this]() { return CreateInsecureChannel(); },
1442 RpcOptions().set_wait_for_ready(true), {}, {});
1443 }
1444
1445 //
1446 // RBAC tests with route config override always present
1447 //
1448
1449 using XdsRbacTestWithRouteOverrideAlwaysPresent = XdsRbacTest;
1450
1451 // Run both with and without RDS.
1452 // Run with bootstrap from env var, so that we use a global XdsClient
1453 // instance. Otherwise, we would need to use a separate fake resolver
1454 // result generator on the client and server sides.
1455 INSTANTIATE_TEST_SUITE_P(
1456 XdsTest, XdsRbacTestWithRouteOverrideAlwaysPresent,
1457 ::testing::Values(
1458 XdsTestType()
1459 .set_filter_config_setup(
1460 XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute)
1461 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1462 XdsTestType()
1463 .set_enable_rds_testing()
1464 .set_filter_config_setup(
1465 XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute)
1466 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar)),
1467 &XdsTestType::Name);
1468
TEST_P(XdsRbacTestWithRouteOverrideAlwaysPresent,EmptyRBACPerRouteOverride)1469 TEST_P(XdsRbacTestWithRouteOverrideAlwaysPresent, EmptyRBACPerRouteOverride) {
1470 HttpConnectionManager http_connection_manager;
1471 Listener listener = default_server_listener_;
1472 RouteConfiguration route_config = default_server_route_config_;
1473 auto* filter = http_connection_manager.add_http_filters();
1474 filter->set_name("rbac");
1475 // Create a top-level RBAC policy with a DENY action for all RPCs
1476 RBAC rbac;
1477 auto* rules = rbac.mutable_rules();
1478 rules->set_action(RBAC_Action_DENY);
1479 Policy policy;
1480 policy.add_permissions()->set_any(true);
1481 policy.add_principals()->set_any(true);
1482 (*rules->mutable_policies())["policy"] = policy;
1483 filter->mutable_typed_config()->PackFrom(rbac);
1484 // Override with an Empty RBACPerRoute policy which should result in RBAC
1485 // being disabled and RPCs being allowed.
1486 google::protobuf::Any filter_config;
1487 filter_config.PackFrom(RBACPerRoute());
1488 auto* config_map = route_config.mutable_virtual_hosts(0)
1489 ->mutable_routes(0)
1490 ->mutable_typed_per_filter_config();
1491 (*config_map)["rbac"] = std::move(filter_config);
1492 filter = http_connection_manager.add_http_filters();
1493 filter->set_name("router");
1494 filter->mutable_typed_config()->PackFrom(
1495 envoy::extensions::filters::http::router::v3::Router());
1496 ServerHcmAccessor().Pack(http_connection_manager, &listener);
1497 SetServerListenerNameAndRouteConfiguration(
1498 balancer_.get(), listener, backends_[0]->port(), route_config);
1499 StartBackend(0);
1500 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1501 SendRpc([this]() { return CreateInsecureChannel(); },
1502 RpcOptions().set_wait_for_ready(true), {}, {});
1503 }
1504
1505 // Test a non-empty top level RBAC with a non-empty RBACPerRouteOverride
TEST_P(XdsRbacTestWithRouteOverrideAlwaysPresent,NonEmptyTopLevelRBACNonEmptyPerRouteOverride)1506 TEST_P(XdsRbacTestWithRouteOverrideAlwaysPresent,
1507 NonEmptyTopLevelRBACNonEmptyPerRouteOverride) {
1508 HttpConnectionManager http_connection_manager;
1509 Listener listener = default_server_listener_;
1510 RouteConfiguration route_config = default_server_route_config_;
1511 auto* filter = http_connection_manager.add_http_filters();
1512 filter->set_name("rbac");
1513 // Create a top-level RBAC policy with a DENY action for all RPCs
1514 RBAC rbac;
1515 auto* rules = rbac.mutable_rules();
1516 rules->set_action(RBAC_Action_DENY);
1517 Policy policy;
1518 policy.add_permissions()->set_any(true);
1519 policy.add_principals()->set_any(true);
1520 (*rules->mutable_policies())["policy"] = policy;
1521 filter->mutable_typed_config()->PackFrom(rbac);
1522 // Override with a non-empty RBACPerRoute policy which allows all RPCs.
1523 google::protobuf::Any filter_config;
1524 RBACPerRoute rbac_per_route;
1525 rules = rbac_per_route.mutable_rbac()->mutable_rules();
1526 rules->set_action(RBAC_Action_ALLOW);
1527 (*rules->mutable_policies())["policy"] = policy;
1528 filter_config.PackFrom(RBACPerRoute());
1529 auto* config_map = route_config.mutable_virtual_hosts(0)
1530 ->mutable_routes(0)
1531 ->mutable_typed_per_filter_config();
1532 (*config_map)["rbac"] = std::move(filter_config);
1533 filter = http_connection_manager.add_http_filters();
1534 filter->set_name("router");
1535 filter->mutable_typed_config()->PackFrom(
1536 envoy::extensions::filters::http::router::v3::Router());
1537 ServerHcmAccessor().Pack(http_connection_manager, &listener);
1538 SetServerListenerNameAndRouteConfiguration(
1539 balancer_.get(), listener, backends_[0]->port(), route_config);
1540 StartBackend(0);
1541 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1542 SendRpc([this]() { return CreateInsecureChannel(); },
1543 RpcOptions().set_wait_for_ready(true), {}, {});
1544 }
1545
1546 //
1547 // RBAC tests with action permutations
1548 //
1549
1550 using XdsRbacTestWithActionPermutations = XdsRbacTest;
1551
1552 // Run with and without RDS, with the filter config both at the top
1553 // level and in the route, and without various actions.
1554 // Run with bootstrap from env var, so that we use a global XdsClient
1555 // instance. Otherwise, we would need to use a separate fake resolver
1556 // result generator on the client and server sides.
1557 INSTANTIATE_TEST_SUITE_P(
1558 XdsTest, XdsRbacTestWithActionPermutations,
1559 ::testing::Values(
1560 XdsTestType()
1561 .set_rbac_action(RBAC_Action_ALLOW)
1562 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1563 XdsTestType()
1564 .set_rbac_action(RBAC_Action_DENY)
1565 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1566 XdsTestType()
1567 .set_enable_rds_testing()
1568 .set_rbac_action(RBAC_Action_ALLOW)
1569 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1570 XdsTestType()
1571 .set_enable_rds_testing()
1572 .set_rbac_action(RBAC_Action_DENY)
1573 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1574 XdsTestType()
1575 .set_filter_config_setup(
1576 XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute)
1577 .set_rbac_action(RBAC_Action_ALLOW)
1578 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1579 XdsTestType()
1580 .set_filter_config_setup(
1581 XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute)
1582 .set_rbac_action(RBAC_Action_DENY)
1583 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1584 XdsTestType()
1585 .set_enable_rds_testing()
1586 .set_filter_config_setup(
1587 XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute)
1588 .set_rbac_action(RBAC_Action_ALLOW)
1589 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
1590 XdsTestType()
1591 .set_enable_rds_testing()
1592 .set_filter_config_setup(
1593 XdsTestType::HttpFilterConfigLocation::kHttpFilterConfigInRoute)
1594 .set_rbac_action(RBAC_Action_DENY)
1595 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar)),
1596 &XdsTestType::Name);
1597
TEST_P(XdsRbacTestWithActionPermutations,EmptyRbacPolicy)1598 TEST_P(XdsRbacTestWithActionPermutations, EmptyRbacPolicy) {
1599 RBAC rbac;
1600 rbac.mutable_rules()->set_action(GetParam().rbac_action());
1601 SetServerRbacPolicy(rbac);
1602 StartBackend(0);
1603 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1604 // An empty RBAC policy leads to all RPCs being rejected.
1605 SendRpc(
1606 [this]() { return CreateInsecureChannel(); },
1607 RpcOptions().set_wait_for_ready(true), {}, {},
1608 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1609 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1610 }
1611
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionAnyPrincipal)1612 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAnyPrincipal) {
1613 RBAC rbac;
1614 auto* rules = rbac.mutable_rules();
1615 rules->set_action(GetParam().rbac_action());
1616 Policy policy;
1617 policy.add_permissions()->set_any(true);
1618 policy.add_principals()->set_any(true);
1619 (*rules->mutable_policies())["policy"] = policy;
1620 SetServerRbacPolicy(rbac);
1621 StartBackend(0);
1622 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1623 SendRpc([this]() { return CreateInsecureChannel(); },
1624 RpcOptions().set_wait_for_ready(true), {}, {},
1625 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1626 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1627 }
1628
TEST_P(XdsRbacTestWithActionPermutations,MultipleRbacPolicies)1629 TEST_P(XdsRbacTestWithActionPermutations, MultipleRbacPolicies) {
1630 RBAC always_allow;
1631 auto* rules = always_allow.mutable_rules();
1632 rules->set_action(RBAC_Action_ALLOW);
1633 Policy policy;
1634 policy.add_permissions()->set_any(true);
1635 policy.add_principals()->set_any(true);
1636 (*rules->mutable_policies())["policy"] = policy;
1637 RBAC rbac;
1638 rules = rbac.mutable_rules();
1639 rules->set_action(GetParam().rbac_action());
1640 (*rules->mutable_policies())["policy"] = policy;
1641 SetServerRbacPolicies(default_server_listener_,
1642 {always_allow, rbac, always_allow});
1643 StartBackend(0);
1644 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1645 SendRpc([this]() { return CreateInsecureChannel(); },
1646 RpcOptions().set_wait_for_ready(true), {}, {},
1647 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1648 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1649 }
1650
TEST_P(XdsRbacTestWithActionPermutations,MethodPostPermissionAnyPrincipal)1651 TEST_P(XdsRbacTestWithActionPermutations, MethodPostPermissionAnyPrincipal) {
1652 RBAC rbac;
1653 auto* rules = rbac.mutable_rules();
1654 rules->set_action(GetParam().rbac_action());
1655 Policy policy;
1656 auto* header = policy.add_permissions()->mutable_header();
1657 header->set_name(":method");
1658 header->set_exact_match("POST");
1659 policy.add_principals()->set_any(true);
1660 (*rules->mutable_policies())["policy"] = policy;
1661 SetServerRbacPolicy(rbac);
1662 backends_[0]->set_allow_put_requests(true);
1663 StartBackend(0);
1664 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1665 // All RPCs use POST method by default
1666 SendRpc([this]() { return CreateInsecureChannel(); },
1667 RpcOptions().set_wait_for_ready(true), {}, {},
1668 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1669 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1670 // Test that an RPC with PUT method is handled properly.
1671 SendRpc([this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
1672 RpcOptions().set_wait_for_ready(true), {}, {},
1673 /*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_DENY,
1674 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1675 }
1676
TEST_P(XdsRbacTestWithActionPermutations,MethodPostPermissionWithStringMatcherAnyPrincipal)1677 TEST_P(XdsRbacTestWithActionPermutations,
1678 MethodPostPermissionWithStringMatcherAnyPrincipal) {
1679 RBAC rbac;
1680 auto* rules = rbac.mutable_rules();
1681 rules->set_action(GetParam().rbac_action());
1682 Policy policy;
1683 auto* header = policy.add_permissions()->mutable_header();
1684 header->set_name(":method");
1685 auto* string_match = header->mutable_string_match();
1686 string_match->set_exact("post");
1687 string_match->set_ignore_case(true);
1688 policy.add_principals()->set_any(true);
1689 (*rules->mutable_policies())["policy"] = policy;
1690 SetServerRbacPolicy(rbac);
1691 backends_[0]->set_allow_put_requests(true);
1692 StartBackend(0);
1693 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1694 // All RPCs use POST method by default
1695 SendRpc([this]() { return CreateInsecureChannel(); },
1696 RpcOptions().set_wait_for_ready(true), {}, {},
1697 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1698 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1699 // Test that an RPC with PUT method is handled properly.
1700 SendRpc([this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
1701 RpcOptions().set_wait_for_ready(true), {}, {},
1702 /*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_DENY,
1703 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1704 }
1705
TEST_P(XdsRbacTestWithActionPermutations,MethodGetPermissionAnyPrincipal)1706 TEST_P(XdsRbacTestWithActionPermutations, MethodGetPermissionAnyPrincipal) {
1707 RBAC rbac;
1708 auto* rules = rbac.mutable_rules();
1709 rules->set_action(GetParam().rbac_action());
1710 Policy policy;
1711 auto* header = policy.add_permissions()->mutable_header();
1712 header->set_name(":method");
1713 header->set_exact_match("GET");
1714 policy.add_principals()->set_any(true);
1715 (*rules->mutable_policies())["policy"] = policy;
1716 SetServerRbacPolicy(rbac);
1717 StartBackend(0);
1718 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1719 // Test that an RPC with a POST method gets rejected
1720 SendRpc(
1721 [this]() { return CreateInsecureChannel(); },
1722 RpcOptions().set_wait_for_ready(true), {}, {},
1723 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1724 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1725 // TODO(yashykt): When we start supporting GET requests in the future, this
1726 // should be modified to test that they are accepted with this rule.
1727 }
1728
TEST_P(XdsRbacTestWithActionPermutations,MethodPutPermissionAnyPrincipal)1729 TEST_P(XdsRbacTestWithActionPermutations, MethodPutPermissionAnyPrincipal) {
1730 RBAC rbac;
1731 auto* rules = rbac.mutable_rules();
1732 rules->set_action(GetParam().rbac_action());
1733 Policy policy;
1734 auto* header = policy.add_permissions()->mutable_header();
1735 header->set_name(":method");
1736 header->set_exact_match("PUT");
1737 policy.add_principals()->set_any(true);
1738 (*rules->mutable_policies())["policy"] = policy;
1739 SetServerRbacPolicy(rbac);
1740 backends_[0]->set_allow_put_requests(true);
1741 StartBackend(0);
1742 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1743 // Test that an RPC with a POST method gets rejected
1744 SendRpc(
1745 [this]() { return CreateInsecureChannel(); },
1746 RpcOptions().set_wait_for_ready(true), {}, {},
1747 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1748 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1749 // Test that an RPC with a PUT method gets accepted
1750 SendRpc(
1751 [this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
1752 RpcOptions().set_wait_for_ready(true), {}, {},
1753 /*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_ALLOW,
1754 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1755 }
1756
TEST_P(XdsRbacTestWithActionPermutations,UrlPathPermissionAnyPrincipal)1757 TEST_P(XdsRbacTestWithActionPermutations, UrlPathPermissionAnyPrincipal) {
1758 RBAC rbac;
1759 auto* rules = rbac.mutable_rules();
1760 rules->set_action(GetParam().rbac_action());
1761 Policy policy;
1762 policy.add_permissions()->mutable_url_path()->mutable_path()->set_exact(
1763 "/grpc.testing.EchoTestService/Echo");
1764 policy.add_principals()->set_any(true);
1765 (*rules->mutable_policies())["policy"] = policy;
1766 SetServerRbacPolicy(rbac);
1767 StartBackend(0);
1768 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1769 SendRpc([this]() { return CreateInsecureChannel(); },
1770 RpcOptions().set_wait_for_ready(true), {}, {},
1771 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1772 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1773 // Test an RPC with a different URL path
1774 auto stub = grpc::testing::EchoTestService::NewStub(CreateInsecureChannel());
1775 ClientContext context;
1776 context.set_wait_for_ready(true);
1777 context.set_deadline(grpc_timeout_milliseconds_to_deadline(2000));
1778 EchoRequest request;
1779 request.set_message(kRequestMessage);
1780 EchoResponse response;
1781 Status status = stub->Echo1(&context, request, &response);
1782 EXPECT_TRUE(GetParam().rbac_action() == RBAC_Action_DENY ? status.ok()
1783 : !status.ok())
1784 << status.error_code() << ", " << status.error_message() << ", "
1785 << status.error_details() << ", " << context.debug_error_string();
1786 }
1787
TEST_P(XdsRbacTestWithActionPermutations,DestinationIpPermissionAnyPrincipal)1788 TEST_P(XdsRbacTestWithActionPermutations, DestinationIpPermissionAnyPrincipal) {
1789 RBAC rbac;
1790 auto* rules = rbac.mutable_rules();
1791 rules->set_action(GetParam().rbac_action());
1792 Policy policy;
1793 auto* range = policy.add_permissions()->mutable_destination_ip();
1794 range->set_address_prefix(grpc_core::LocalIp());
1795 range->mutable_prefix_len()->set_value(grpc_core::RunningWithIPv6Only() ? 128
1796 : 32);
1797 policy.add_principals()->set_any(true);
1798 (*rules->mutable_policies())["policy"] = policy;
1799 SetServerRbacPolicy(rbac);
1800 StartBackend(0);
1801 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1802 SendRpc([this]() { return CreateInsecureChannel(); },
1803 RpcOptions().set_wait_for_ready(true), {}, {},
1804 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1805 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1806 // Change the policy itself for a negative test where there is no match.
1807 policy.clear_permissions();
1808 range = policy.add_permissions()->mutable_destination_ip();
1809 range->set_address_prefix(grpc_core::RunningWithIPv6Only() ? "::2"
1810 : "127.0.0.2");
1811 range->mutable_prefix_len()->set_value(grpc_core::RunningWithIPv6Only() ? 128
1812 : 32);
1813 (*rules->mutable_policies())["policy"] = policy;
1814 SetServerRbacPolicy(rbac);
1815 SendRpc(
1816 [this]() { return CreateInsecureChannel(); },
1817 RpcOptions().set_wait_for_ready(true), {}, {},
1818 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1819 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1820 }
1821
TEST_P(XdsRbacTestWithActionPermutations,DestinationPortPermissionAnyPrincipal)1822 TEST_P(XdsRbacTestWithActionPermutations,
1823 DestinationPortPermissionAnyPrincipal) {
1824 RBAC rbac;
1825 auto* rules = rbac.mutable_rules();
1826 rules->set_action(GetParam().rbac_action());
1827 Policy policy;
1828 policy.add_permissions()->set_destination_port(backends_[0]->port());
1829 policy.add_principals()->set_any(true);
1830 (*rules->mutable_policies())["policy"] = policy;
1831 SetServerRbacPolicy(rbac);
1832 StartBackend(0);
1833 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1834 SendRpc([this]() { return CreateInsecureChannel(); },
1835 RpcOptions().set_wait_for_ready(true), {}, {},
1836 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1837 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1838 // Change the policy itself for a negative test where there is no match.
1839 policy.clear_permissions();
1840 policy.add_permissions()->set_destination_port(1);
1841 (*rules->mutable_policies())["policy"] = policy;
1842 SetServerRbacPolicy(rbac);
1843 SendRpc(
1844 [this]() { return CreateInsecureChannel(); },
1845 RpcOptions().set_wait_for_ready(true), {}, {},
1846 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1847 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1848 }
1849
TEST_P(XdsRbacTestWithActionPermutations,MetadataPermissionAnyPrincipal)1850 TEST_P(XdsRbacTestWithActionPermutations, MetadataPermissionAnyPrincipal) {
1851 RBAC rbac;
1852 auto* rules = rbac.mutable_rules();
1853 rules->set_action(GetParam().rbac_action());
1854 Policy policy;
1855 policy.add_permissions()->mutable_metadata();
1856 policy.add_principals()->set_any(true);
1857 (*rules->mutable_policies())["policy"] = policy;
1858 SetServerRbacPolicy(rbac);
1859 StartBackend(0);
1860 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1861 SendRpc(
1862 [this]() { return CreateInsecureChannel(); },
1863 RpcOptions().set_wait_for_ready(true), {}, {},
1864 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1865 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1866 // Test metadata with inverted match
1867 policy.clear_permissions();
1868 policy.add_permissions()->mutable_metadata()->set_invert(true);
1869 (*rules->mutable_policies())["policy"] = policy;
1870 SetServerRbacPolicy(rbac);
1871 SendRpc([this]() { return CreateInsecureChannel(); },
1872 RpcOptions().set_wait_for_ready(true), {}, {},
1873 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1874 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1875 }
1876
TEST_P(XdsRbacTestWithActionPermutations,ReqServerNamePermissionAnyPrincipal)1877 TEST_P(XdsRbacTestWithActionPermutations, ReqServerNamePermissionAnyPrincipal) {
1878 RBAC rbac;
1879 auto* rules = rbac.mutable_rules();
1880 rules->set_action(GetParam().rbac_action());
1881 Policy policy;
1882 policy.add_principals()->set_any(true);
1883 policy.add_permissions()->mutable_requested_server_name()->set_exact(
1884 "server_name");
1885 (*rules->mutable_policies())["policy"] = policy;
1886 SetServerRbacPolicy(rbac);
1887 StartBackend(0);
1888 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1889 SendRpc(
1890 [this]() { return CreateInsecureChannel(); },
1891 RpcOptions().set_wait_for_ready(true), {}, {},
1892 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1893 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1894 policy.clear_permissions();
1895 policy.add_permissions()->mutable_requested_server_name()->set_exact("");
1896 (*rules->mutable_policies())["policy"] = policy;
1897 SetServerRbacPolicy(rbac);
1898 SendRpc([this]() { return CreateInsecureChannel(); },
1899 RpcOptions().set_wait_for_ready(true), {}, {},
1900 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1901 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1902 }
1903
TEST_P(XdsRbacTestWithActionPermutations,NotRulePermissionAnyPrincipal)1904 TEST_P(XdsRbacTestWithActionPermutations, NotRulePermissionAnyPrincipal) {
1905 RBAC rbac;
1906 auto* rules = rbac.mutable_rules();
1907 rules->set_action(GetParam().rbac_action());
1908 Policy policy;
1909 policy.add_permissions()
1910 ->mutable_not_rule()
1911 ->mutable_requested_server_name()
1912 ->set_exact("server_name");
1913 policy.add_principals()->set_any(true);
1914 (*rules->mutable_policies())["policy"] = policy;
1915 SetServerRbacPolicy(rbac);
1916 StartBackend(0);
1917 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1918 SendRpc([this]() { return CreateInsecureChannel(); },
1919 RpcOptions().set_wait_for_ready(true), {}, {},
1920 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1921 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1922 // Change the policy itself for a negative test where there is no match.
1923 policy.clear_permissions();
1924 policy.add_permissions()->mutable_not_rule()->set_any(true);
1925 (*rules->mutable_policies())["policy"] = policy;
1926 SetServerRbacPolicy(rbac);
1927 SendRpc(
1928 [this]() { return CreateInsecureChannel(); },
1929 RpcOptions().set_wait_for_ready(true), {}, {},
1930 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1931 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1932 }
1933
TEST_P(XdsRbacTestWithActionPermutations,AndRulePermissionAnyPrincipal)1934 TEST_P(XdsRbacTestWithActionPermutations, AndRulePermissionAnyPrincipal) {
1935 RBAC rbac;
1936 auto* rules = rbac.mutable_rules();
1937 rules->set_action(GetParam().rbac_action());
1938 Policy policy;
1939 auto* and_rules = policy.add_permissions()->mutable_and_rules();
1940 and_rules->add_rules()->set_any(true);
1941 and_rules->add_rules()->set_destination_port(backends_[0]->port());
1942 policy.add_principals()->set_any(true);
1943 (*rules->mutable_policies())["policy"] = policy;
1944 SetServerRbacPolicy(rbac);
1945 StartBackend(0);
1946 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1947 SendRpc([this]() { return CreateInsecureChannel(); },
1948 RpcOptions().set_wait_for_ready(true), {}, {},
1949 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1950 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1951 // Change the policy itself for a negative test where there is no match.
1952 and_rules = (*policy.mutable_permissions())[0].mutable_and_rules();
1953 (*and_rules->mutable_rules())[1].set_destination_port(1);
1954 (*rules->mutable_policies())["policy"] = policy;
1955 SetServerRbacPolicy(rbac);
1956 SendRpc(
1957 [this]() { return CreateInsecureChannel(); },
1958 RpcOptions().set_wait_for_ready(true), {}, {},
1959 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1960 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1961 }
1962
TEST_P(XdsRbacTestWithActionPermutations,OrRulePermissionAnyPrincipal)1963 TEST_P(XdsRbacTestWithActionPermutations, OrRulePermissionAnyPrincipal) {
1964 RBAC rbac;
1965 auto* rules = rbac.mutable_rules();
1966 rules->set_action(GetParam().rbac_action());
1967 Policy policy;
1968 auto* or_rules = policy.add_permissions()->mutable_or_rules();
1969 or_rules->add_rules()->mutable_not_rule()->set_any(true);
1970 or_rules->add_rules()->set_destination_port(backends_[0]->port());
1971 policy.add_principals()->set_any(true);
1972 (*rules->mutable_policies())["policy"] = policy;
1973 SetServerRbacPolicy(rbac);
1974 StartBackend(0);
1975 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
1976 SendRpc([this]() { return CreateInsecureChannel(); },
1977 RpcOptions().set_wait_for_ready(true), {}, {},
1978 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
1979 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1980 // Change the policy itself for a negative test where there is no match.
1981 or_rules = (*policy.mutable_permissions())[0].mutable_or_rules();
1982 (*or_rules->mutable_rules())[1].set_destination_port(1);
1983 (*rules->mutable_policies())["policy"] = policy;
1984 SetServerRbacPolicy(rbac);
1985 SendRpc(
1986 [this]() { return CreateInsecureChannel(); },
1987 RpcOptions().set_wait_for_ready(true), {}, {},
1988 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
1989 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
1990 }
1991
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionMethodPostPrincipal)1992 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMethodPostPrincipal) {
1993 RBAC rbac;
1994 auto* rules = rbac.mutable_rules();
1995 rules->set_action(GetParam().rbac_action());
1996 Policy policy;
1997 auto* header = policy.add_principals()->mutable_header();
1998 header->set_name(":method");
1999 header->set_exact_match("POST");
2000 policy.add_permissions()->set_any(true);
2001 (*rules->mutable_policies())["policy"] = policy;
2002 SetServerRbacPolicy(rbac);
2003 backends_[0]->set_allow_put_requests(true);
2004 StartBackend(0);
2005 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2006 // All RPCs use POST method by default
2007 SendRpc([this]() { return CreateInsecureChannel(); },
2008 RpcOptions().set_wait_for_ready(true), {}, {},
2009 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2010 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2011 // Test that an RPC with PUT method is handled properly.
2012 SendRpc([this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
2013 RpcOptions().set_wait_for_ready(true), {}, {},
2014 /*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_DENY,
2015 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2016 }
2017
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionMethodGetPrincipal)2018 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMethodGetPrincipal) {
2019 RBAC rbac;
2020 auto* rules = rbac.mutable_rules();
2021 rules->set_action(GetParam().rbac_action());
2022 Policy policy;
2023 auto* header = policy.add_principals()->mutable_header();
2024 header->set_name(":method");
2025 header->set_exact_match("GET");
2026 policy.add_permissions()->set_any(true);
2027 (*rules->mutable_policies())["policy"] = policy;
2028 SetServerRbacPolicy(rbac);
2029 StartBackend(0);
2030 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2031 // Test that an RPC with a POST method gets rejected
2032 SendRpc(
2033 [this]() { return CreateInsecureChannel(); },
2034 RpcOptions().set_wait_for_ready(true), {}, {},
2035 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2036 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2037 // TODO(yashykt): When we start supporting GET requests in the future, this
2038 // should be modified to test that they are accepted with this rule.
2039 }
2040
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionMethodPutPrincipal)2041 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMethodPutPrincipal) {
2042 RBAC rbac;
2043 auto* rules = rbac.mutable_rules();
2044 rules->set_action(GetParam().rbac_action());
2045 Policy policy;
2046 auto* header = policy.add_principals()->mutable_header();
2047 header->set_name(":method");
2048 header->set_exact_match("PUT");
2049 policy.add_permissions()->set_any(true);
2050 (*rules->mutable_policies())["policy"] = policy;
2051 SetServerRbacPolicy(rbac);
2052 backends_[0]->set_allow_put_requests(true);
2053 StartBackend(0);
2054 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2055 // Test that an RPC with a PUT method gets accepted
2056 SendRpc(
2057 [this]() { return CreateInsecureChannel(/*use_put_requests=*/true); },
2058 RpcOptions().set_wait_for_ready(true), {}, {},
2059 /*test_expects_failure=*/GetParam().rbac_action() != RBAC_Action_ALLOW,
2060 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2061 // Test that an RPC with a POST method gets rejected
2062 SendRpc(
2063 [this]() { return CreateInsecureChannel(); },
2064 RpcOptions().set_wait_for_ready(true), {}, {},
2065 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2066 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2067 }
2068
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionUrlPathPrincipal)2069 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionUrlPathPrincipal) {
2070 RBAC rbac;
2071 auto* rules = rbac.mutable_rules();
2072 rules->set_action(GetParam().rbac_action());
2073 Policy policy;
2074 policy.add_principals()->mutable_url_path()->mutable_path()->set_exact(
2075 "/grpc.testing.EchoTestService/Echo");
2076 policy.add_permissions()->set_any(true);
2077 (*rules->mutable_policies())["policy"] = policy;
2078 SetServerRbacPolicy(rbac);
2079 StartBackend(0);
2080 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2081 SendRpc([this]() { return CreateInsecureChannel(); },
2082 RpcOptions().set_wait_for_ready(true), {}, {},
2083 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2084 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2085 // Test an RPC with a different URL path
2086 auto stub = grpc::testing::EchoTestService::NewStub(CreateInsecureChannel());
2087 ClientContext context;
2088 context.set_wait_for_ready(true);
2089 context.set_deadline(grpc_timeout_milliseconds_to_deadline(2000));
2090 EchoRequest request;
2091 request.set_message(kRequestMessage);
2092 EchoResponse response;
2093 Status status = stub->Echo1(&context, request, &response);
2094 EXPECT_TRUE(GetParam().rbac_action() == RBAC_Action_DENY ? status.ok()
2095 : !status.ok())
2096 << status.error_code() << ", " << status.error_message() << ", "
2097 << status.error_details() << ", " << context.debug_error_string();
2098 }
2099
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionDirectRemoteIpPrincipal)2100 TEST_P(XdsRbacTestWithActionPermutations,
2101 AnyPermissionDirectRemoteIpPrincipal) {
2102 RBAC rbac;
2103 auto* rules = rbac.mutable_rules();
2104 rules->set_action(GetParam().rbac_action());
2105 Policy policy;
2106 auto* range = policy.add_principals()->mutable_direct_remote_ip();
2107 range->set_address_prefix(grpc_core::LocalIp());
2108 range->mutable_prefix_len()->set_value(grpc_core::RunningWithIPv6Only() ? 128
2109 : 32);
2110 policy.add_permissions()->set_any(true);
2111 (*rules->mutable_policies())["policy"] = policy;
2112 SetServerRbacPolicy(rbac);
2113 StartBackend(0);
2114 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2115 SendRpc([this]() { return CreateInsecureChannel(); },
2116 RpcOptions().set_wait_for_ready(true), {}, {},
2117 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2118 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2119 // Change the policy itself for a negative test where there is no match.
2120 policy.clear_principals();
2121 range = policy.add_principals()->mutable_direct_remote_ip();
2122 range->set_address_prefix(grpc_core::RunningWithIPv6Only() ? "::2"
2123 : "127.0.0.2");
2124 range->mutable_prefix_len()->set_value(grpc_core::RunningWithIPv6Only() ? 128
2125 : 32);
2126 (*rules->mutable_policies())["policy"] = policy;
2127 SetServerRbacPolicy(rbac);
2128 SendRpc(
2129 [this]() { return CreateInsecureChannel(); },
2130 RpcOptions().set_wait_for_ready(true), {}, {},
2131 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2132 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2133 }
2134
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionRemoteIpPrincipal)2135 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionRemoteIpPrincipal) {
2136 RBAC rbac;
2137 auto* rules = rbac.mutable_rules();
2138 rules->set_action(GetParam().rbac_action());
2139 Policy policy;
2140 auto* range = policy.add_principals()->mutable_remote_ip();
2141 range->set_address_prefix(grpc_core::LocalIp());
2142 range->mutable_prefix_len()->set_value(grpc_core::RunningWithIPv6Only() ? 128
2143 : 32);
2144 policy.add_permissions()->set_any(true);
2145 (*rules->mutable_policies())["policy"] = policy;
2146 SetServerRbacPolicy(rbac);
2147 StartBackend(0);
2148 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2149 SendRpc([this]() { return CreateInsecureChannel(); },
2150 RpcOptions().set_wait_for_ready(true), {}, {},
2151 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2152 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2153 // Change the policy itself for a negative test where there is no match.
2154 policy.clear_principals();
2155 range = policy.add_principals()->mutable_remote_ip();
2156 range->set_address_prefix(grpc_core::RunningWithIPv6Only() ? "::2"
2157 : "127.0.0.2");
2158 range->mutable_prefix_len()->set_value(grpc_core::RunningWithIPv6Only() ? 128
2159 : 32);
2160 (*rules->mutable_policies())["policy"] = policy;
2161 SetServerRbacPolicy(rbac);
2162 SendRpc(
2163 [this]() { return CreateInsecureChannel(); },
2164 RpcOptions().set_wait_for_ready(true), {}, {},
2165 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2166 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2167 }
2168
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionAuthenticatedPrincipal)2169 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAuthenticatedPrincipal) {
2170 g_fake1_cert_data_map->Set({{"", {root_cert_, identity_pair_}}});
2171 Listener listener = default_server_listener_;
2172 auto* filter_chain = listener.mutable_default_filter_chain();
2173 auto* transport_socket = filter_chain->mutable_transport_socket();
2174 transport_socket->set_name("envoy.transport_sockets.tls");
2175 DownstreamTlsContext downstream_tls_context;
2176 downstream_tls_context.mutable_common_tls_context()
2177 ->mutable_tls_certificate_provider_instance()
2178 ->set_instance_name("fake_plugin1");
2179 downstream_tls_context.mutable_common_tls_context()
2180 ->mutable_validation_context()
2181 ->mutable_ca_certificate_provider_instance()
2182 ->set_instance_name("fake_plugin1");
2183 downstream_tls_context.mutable_require_client_certificate()->set_value(true);
2184 transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context);
2185 RBAC rbac;
2186 auto* rules = rbac.mutable_rules();
2187 rules->set_action(GetParam().rbac_action());
2188 Policy policy;
2189 policy.add_principals()
2190 ->mutable_authenticated()
2191 ->mutable_principal_name()
2192 ->set_exact("*.test.google.fr");
2193 policy.add_permissions()->set_any(true);
2194 (*rules->mutable_policies())["policy"] = policy;
2195 SetServerRbacPolicy(listener, rbac);
2196 StartBackend(0);
2197 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2198 SendRpc([this]() { return CreateMtlsChannel(); },
2199 RpcOptions().set_wait_for_ready(true), server_authenticated_identity_,
2200 client_authenticated_identity_,
2201 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2202 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2203 }
2204
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionMetadataPrincipal)2205 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionMetadataPrincipal) {
2206 RBAC rbac;
2207 auto* rules = rbac.mutable_rules();
2208 rules->set_action(GetParam().rbac_action());
2209 Policy policy;
2210 policy.add_principals()->mutable_metadata();
2211 policy.add_permissions()->set_any(true);
2212 (*rules->mutable_policies())["policy"] = policy;
2213 SetServerRbacPolicy(rbac);
2214 StartBackend(0);
2215 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2216 SendRpc(
2217 [this]() { return CreateInsecureChannel(); },
2218 RpcOptions().set_wait_for_ready(true), {}, {},
2219 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2220 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2221 // Test metadata with inverted match
2222 policy.clear_principals();
2223 policy.add_principals()->mutable_metadata()->set_invert(true);
2224 (*rules->mutable_policies())["policy"] = policy;
2225 SetServerRbacPolicy(rbac);
2226 SendRpc([this]() { return CreateInsecureChannel(); },
2227 RpcOptions().set_wait_for_ready(true), {}, {},
2228 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2229 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2230 }
2231
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionNotIdPrincipal)2232 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionNotIdPrincipal) {
2233 RBAC rbac;
2234 auto* rules = rbac.mutable_rules();
2235 rules->set_action(GetParam().rbac_action());
2236 Policy policy;
2237 policy.add_principals()
2238 ->mutable_not_id()
2239 ->mutable_url_path()
2240 ->mutable_path()
2241 ->set_exact("/grpc.testing.EchoTestService/Echo1");
2242 policy.add_permissions()->set_any(true);
2243 (*rules->mutable_policies())["policy"] = policy;
2244 SetServerRbacPolicy(rbac);
2245 StartBackend(0);
2246 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2247 SendRpc([this]() { return CreateInsecureChannel(); },
2248 RpcOptions().set_wait_for_ready(true), {}, {},
2249 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2250 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2251 // Change the policy itself for a negative test where there is no match.
2252 policy.clear_principals();
2253 policy.add_principals()->mutable_not_id()->set_any(true);
2254 (*rules->mutable_policies())["policy"] = policy;
2255 SetServerRbacPolicy(rbac);
2256 SendRpc(
2257 [this]() { return CreateInsecureChannel(); },
2258 RpcOptions().set_wait_for_ready(true), {}, {},
2259 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2260 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2261 }
2262
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionAndIdPrincipal)2263 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionAndIdPrincipal) {
2264 RBAC rbac;
2265 auto* rules = rbac.mutable_rules();
2266 rules->set_action(GetParam().rbac_action());
2267 Policy policy;
2268 auto* and_ids = policy.add_principals()->mutable_and_ids();
2269 and_ids->add_ids()->set_any(true);
2270 and_ids->add_ids()->mutable_url_path()->mutable_path()->set_exact(
2271 "/grpc.testing.EchoTestService/Echo");
2272 policy.add_permissions()->set_any(true);
2273 (*rules->mutable_policies())["policy"] = policy;
2274 SetServerRbacPolicy(rbac);
2275 StartBackend(0);
2276 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2277 SendRpc([this]() { return CreateInsecureChannel(); },
2278 RpcOptions().set_wait_for_ready(true), {}, {},
2279 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2280 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2281 // Change the policy itself for a negative test where there is no match.
2282 and_ids = (*policy.mutable_principals())[0].mutable_and_ids();
2283 (*and_ids->mutable_ids())[1].mutable_url_path()->mutable_path()->set_exact(
2284 "/grpc.testing.EchoTestService/Echo1");
2285 (*rules->mutable_policies())["policy"] = policy;
2286 SetServerRbacPolicy(rbac);
2287 SendRpc(
2288 [this]() { return CreateInsecureChannel(); },
2289 RpcOptions().set_wait_for_ready(true), {}, {},
2290 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2291 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2292 }
2293
TEST_P(XdsRbacTestWithActionPermutations,AnyPermissionOrIdPrincipal)2294 TEST_P(XdsRbacTestWithActionPermutations, AnyPermissionOrIdPrincipal) {
2295 RBAC rbac;
2296 auto* rules = rbac.mutable_rules();
2297 rules->set_action(GetParam().rbac_action());
2298 Policy policy;
2299 auto* or_ids = policy.add_principals()->mutable_or_ids();
2300 or_ids->add_ids()->mutable_not_id()->set_any(true);
2301 or_ids->add_ids()->mutable_url_path()->mutable_path()->set_exact(
2302 "/grpc.testing.EchoTestService/Echo");
2303 policy.add_permissions()->set_any(true);
2304 (*rules->mutable_policies())["policy"] = policy;
2305 SetServerRbacPolicy(rbac);
2306 StartBackend(0);
2307 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2308 SendRpc([this]() { return CreateInsecureChannel(); },
2309 RpcOptions().set_wait_for_ready(true), {}, {},
2310 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2311 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2312 // Change the policy itself for a negative test where there is no match.
2313 or_ids = (*policy.mutable_principals())[0].mutable_or_ids();
2314 (*or_ids->mutable_ids())[1].mutable_url_path()->mutable_path()->set_exact(
2315 "/grpc.testing.EchoTestService/Echo1");
2316 (*rules->mutable_policies())["policy"] = policy;
2317 SetServerRbacPolicy(rbac);
2318 SendRpc(
2319 [this]() { return CreateInsecureChannel(); },
2320 RpcOptions().set_wait_for_ready(true), {}, {},
2321 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2322 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2323 }
2324
TEST_P(XdsRbacTestWithActionPermutations,AuditLoggerNotInvokedOnAuditConditionNone)2325 TEST_P(XdsRbacTestWithActionPermutations,
2326 AuditLoggerNotInvokedOnAuditConditionNone) {
2327 ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RBAC_AUDIT_LOGGING");
2328 RBAC rbac;
2329 rbac.mutable_rules()->set_action(GetParam().rbac_action());
2330 auto* logging_options = rbac.mutable_rules()->mutable_audit_logging_options();
2331 auto* audit_logger =
2332 logging_options->add_logger_configs()->mutable_audit_logger();
2333 audit_logger->mutable_typed_config()->set_type_url("/test_logger");
2334 TypedStruct typed_struct;
2335 typed_struct.set_type_url("/test_logger");
2336 typed_struct.mutable_value()->mutable_fields();
2337 audit_logger->mutable_typed_config()->PackFrom(typed_struct);
2338 SetServerRbacPolicy(rbac);
2339 StartBackend(0);
2340 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2341 // An empty RBAC policy leads to all RPCs being rejected.
2342 SendRpc(
2343 [this]() { return CreateInsecureChannel(); },
2344 RpcOptions().set_wait_for_ready(true), {}, {},
2345 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_ALLOW,
2346 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2347 EXPECT_THAT(audit_logs_, ::testing::ElementsAre());
2348 }
2349
TEST_P(XdsRbacTestWithActionPermutations,MultipleRbacPoliciesWithAuditOnAllow)2350 TEST_P(XdsRbacTestWithActionPermutations,
2351 MultipleRbacPoliciesWithAuditOnAllow) {
2352 ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RBAC_AUDIT_LOGGING");
2353 RBAC always_allow;
2354 auto* rules = always_allow.mutable_rules();
2355 rules->set_action(RBAC_Action_ALLOW);
2356 Policy policy;
2357 policy.add_permissions()->set_any(true);
2358 policy.add_principals()->set_any(true);
2359 (*rules->mutable_policies())["policy"] = policy;
2360 auto* logging_options = rules->mutable_audit_logging_options();
2361 logging_options->set_audit_condition(
2362 RBAC_AuditLoggingOptions_AuditCondition_ON_ALLOW);
2363 auto* audit_logger =
2364 logging_options->add_logger_configs()->mutable_audit_logger();
2365 audit_logger->mutable_typed_config()->set_type_url("/test_logger");
2366 TypedStruct typed_struct;
2367 typed_struct.set_type_url("/test_logger");
2368 typed_struct.mutable_value()->mutable_fields();
2369 audit_logger->mutable_typed_config()->PackFrom(typed_struct);
2370 RBAC rbac;
2371 rules = rbac.mutable_rules();
2372 rules->set_action(GetParam().rbac_action());
2373 (*rules->mutable_policies())["policy"] = policy;
2374 logging_options = rules->mutable_audit_logging_options();
2375 logging_options->set_audit_condition(
2376 RBAC_AuditLoggingOptions_AuditCondition_ON_ALLOW);
2377 audit_logger = logging_options->add_logger_configs()->mutable_audit_logger();
2378 audit_logger->mutable_typed_config()->PackFrom(typed_struct);
2379 SetServerRbacPolicies(default_server_listener_,
2380 {always_allow, rbac, always_allow});
2381 StartBackend(0);
2382 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2383 SendRpc([this]() { return CreateInsecureChannel(); },
2384 RpcOptions().set_wait_for_ready(true), {}, {},
2385 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2386 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2387 // If the second rbac denies the rpc, only one log from the first rbac.
2388 // Otherwise, all three rbacs log.
2389 std::vector<absl::string_view> expected(
2390 GetParam().rbac_action() != RBAC_Action_DENY ? 3 : 1,
2391 "{\"authorized\":true,\"matched_rule\":\"policy\","
2392 "\"policy_name\":\"\",\"principal\":\"\",\"rpc_"
2393 "method\":\"/grpc.testing.EchoTestService/Echo\"}");
2394 EXPECT_THAT(audit_logs_, ::testing::ElementsAreArray(expected));
2395 }
2396
TEST_P(XdsRbacTestWithActionPermutations,MultipleRbacPoliciesWithAuditOnDeny)2397 TEST_P(XdsRbacTestWithActionPermutations, MultipleRbacPoliciesWithAuditOnDeny) {
2398 ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RBAC_AUDIT_LOGGING");
2399 RBAC always_allow;
2400 auto* rules = always_allow.mutable_rules();
2401 rules->set_action(RBAC_Action_ALLOW);
2402 Policy policy;
2403 policy.add_permissions()->set_any(true);
2404 policy.add_principals()->set_any(true);
2405 (*rules->mutable_policies())["policy"] = policy;
2406 auto* logging_options = rules->mutable_audit_logging_options();
2407 logging_options->set_audit_condition(
2408 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY);
2409 auto* audit_logger =
2410 logging_options->add_logger_configs()->mutable_audit_logger();
2411 audit_logger->mutable_typed_config()->set_type_url("/test_logger");
2412 TypedStruct typed_struct;
2413 typed_struct.set_type_url("/test_logger");
2414 typed_struct.mutable_value()->mutable_fields();
2415 audit_logger->mutable_typed_config()->PackFrom(typed_struct);
2416 RBAC rbac;
2417 rules = rbac.mutable_rules();
2418 rules->set_action(GetParam().rbac_action());
2419 (*rules->mutable_policies())["policy"] = policy;
2420 logging_options = rules->mutable_audit_logging_options();
2421 logging_options->set_audit_condition(
2422 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY);
2423 audit_logger = logging_options->add_logger_configs()->mutable_audit_logger();
2424 audit_logger->mutable_typed_config()->PackFrom(typed_struct);
2425 SetServerRbacPolicies(default_server_listener_,
2426 {always_allow, rbac, always_allow});
2427 StartBackend(0);
2428 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2429 SendRpc([this]() { return CreateInsecureChannel(); },
2430 RpcOptions().set_wait_for_ready(true), {}, {},
2431 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2432 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2433 // Only the second rbac logs if it denies the rpc.
2434 std::vector<absl::string_view> expected;
2435 if (GetParam().rbac_action() == RBAC_Action_DENY) {
2436 expected.push_back(
2437 "{\"authorized\":false,\"matched_rule\":\"policy\",\"policy_name\":"
2438 "\"\",\"principal\":\"\",\"rpc_method\":\"/"
2439 "grpc.testing.EchoTestService/Echo\"}");
2440 }
2441 EXPECT_THAT(audit_logs_, ::testing::ElementsAreArray(expected));
2442 }
2443
TEST_P(XdsRbacTestWithActionPermutations,MultipleRbacPoliciesWithAuditOnDenyAndAllow)2444 TEST_P(XdsRbacTestWithActionPermutations,
2445 MultipleRbacPoliciesWithAuditOnDenyAndAllow) {
2446 ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RBAC_AUDIT_LOGGING");
2447 RBAC always_allow;
2448 auto* rules = always_allow.mutable_rules();
2449 rules->set_action(RBAC_Action_ALLOW);
2450 Policy policy;
2451 policy.add_permissions()->set_any(true);
2452 policy.add_principals()->set_any(true);
2453 (*rules->mutable_policies())["policy"] = policy;
2454 auto* logging_options = rules->mutable_audit_logging_options();
2455 logging_options->set_audit_condition(
2456 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY_AND_ALLOW);
2457 auto* audit_logger =
2458 logging_options->add_logger_configs()->mutable_audit_logger();
2459 audit_logger->mutable_typed_config()->set_type_url("/test_logger");
2460 TypedStruct typed_struct;
2461 typed_struct.set_type_url("/test_logger");
2462 typed_struct.mutable_value()->mutable_fields();
2463 audit_logger->mutable_typed_config()->PackFrom(typed_struct);
2464 RBAC rbac;
2465 rules = rbac.mutable_rules();
2466 rules->set_action(GetParam().rbac_action());
2467 (*rules->mutable_policies())["policy"] = policy;
2468 logging_options = rules->mutable_audit_logging_options();
2469 logging_options->set_audit_condition(
2470 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY_AND_ALLOW);
2471 audit_logger = logging_options->add_logger_configs()->mutable_audit_logger();
2472 audit_logger->mutable_typed_config()->PackFrom(typed_struct);
2473 SetServerRbacPolicies(default_server_listener_,
2474 {always_allow, rbac, always_allow});
2475 StartBackend(0);
2476 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2477 SendRpc([this]() { return CreateInsecureChannel(); },
2478 RpcOptions().set_wait_for_ready(true), {}, {},
2479 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2480 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2481 // If the second rbac denies the request, the last rbac won't log. Otherwise
2482 // all rbacs log.
2483 std::vector<absl::string_view> expected = {
2484 "{\"authorized\":true,\"matched_rule\":\"policy\",\"policy_name\":"
2485 "\"\",\"principal\":\"\",\"rpc_method\":\"/"
2486 "grpc.testing.EchoTestService/Echo\"}"};
2487 if (GetParam().rbac_action() == RBAC_Action_DENY) {
2488 expected.push_back(
2489 "{\"authorized\":false,\"matched_rule\":\"policy\",\"policy_name\":"
2490 "\"\",\"principal\":\"\",\"rpc_method\":\"/"
2491 "grpc.testing.EchoTestService/Echo\"}");
2492 } else {
2493 expected = std::vector<absl::string_view>(
2494 3,
2495 "{\"authorized\":true,\"matched_rule\":\"policy\",\"policy_name\":"
2496 "\"\",\"principal\":\"\",\"rpc_method\":\"/"
2497 "grpc.testing.EchoTestService/Echo\"}");
2498 }
2499 EXPECT_THAT(audit_logs_, ::testing::ElementsAreArray(expected));
2500 }
2501
2502 //
2503 // RBAC tests with audit conditions
2504 //
2505
2506 using XdsRbacTestWithActionAndAuditConditionPermutations = XdsRbacTest;
2507
2508 INSTANTIATE_TEST_SUITE_P(
2509 XdsTest, XdsRbacTestWithActionAndAuditConditionPermutations,
2510 ::testing::Values(
2511 XdsTestType()
2512 .set_rbac_action(RBAC_Action_ALLOW)
2513 .set_rbac_audit_condition(
2514 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY)
2515 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
2516 XdsTestType()
2517 .set_rbac_action(RBAC_Action_ALLOW)
2518 .set_rbac_audit_condition(
2519 RBAC_AuditLoggingOptions_AuditCondition_ON_ALLOW)
2520 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
2521 XdsTestType()
2522 .set_rbac_action(RBAC_Action_ALLOW)
2523 .set_rbac_audit_condition(
2524 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY_AND_ALLOW)
2525 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
2526 XdsTestType()
2527 .set_rbac_action(RBAC_Action_DENY)
2528 .set_rbac_audit_condition(
2529 RBAC_AuditLoggingOptions_AuditCondition_ON_ALLOW)
2530 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
2531 XdsTestType()
2532 .set_rbac_action(RBAC_Action_DENY)
2533 .set_rbac_audit_condition(
2534 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY)
2535 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar),
2536 XdsTestType()
2537 .set_enable_rds_testing()
2538 .set_rbac_action(RBAC_Action_DENY)
2539 .set_rbac_audit_condition(
2540 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY_AND_ALLOW)
2541 .set_bootstrap_source(XdsTestType::kBootstrapFromEnvVar)),
2542 &XdsTestType::Name);
2543
TEST_P(XdsRbacTestWithActionAndAuditConditionPermutations,AuditLoggingDisabled)2544 TEST_P(XdsRbacTestWithActionAndAuditConditionPermutations,
2545 AuditLoggingDisabled) {
2546 RBAC rbac;
2547 auto* rules = rbac.mutable_rules();
2548 rules->set_action(GetParam().rbac_action());
2549 Policy policy;
2550 policy.add_permissions()->set_any(true);
2551 policy.add_principals()->set_any(true);
2552 (*rules->mutable_policies())["policy"] = policy;
2553 auto* logging_options = rules->mutable_audit_logging_options();
2554 logging_options->set_audit_condition(GetParam().rbac_audit_condition());
2555 auto* audit_logger =
2556 logging_options->add_logger_configs()->mutable_audit_logger();
2557 audit_logger->mutable_typed_config()->set_type_url("/test_logger");
2558 TypedStruct typed_struct;
2559 typed_struct.set_type_url("/test_logger");
2560 typed_struct.mutable_value()->mutable_fields();
2561 audit_logger->mutable_typed_config()->PackFrom(typed_struct);
2562 SetServerRbacPolicy(rbac);
2563 StartBackend(0);
2564 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2565 SendRpc([this]() { return CreateInsecureChannel(); },
2566 RpcOptions().set_wait_for_ready(true), {}, {},
2567 /*test_expects_failure=*/GetParam().rbac_action() == RBAC_Action_DENY,
2568 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2569 EXPECT_THAT(audit_logs_, ::testing::ElementsAre());
2570 }
2571
TEST_P(XdsRbacTestWithActionAndAuditConditionPermutations,MultipleLoggers)2572 TEST_P(XdsRbacTestWithActionAndAuditConditionPermutations, MultipleLoggers) {
2573 ScopedExperimentalEnvVar env_var("GRPC_EXPERIMENTAL_XDS_RBAC_AUDIT_LOGGING");
2574 RBAC rbac;
2575 auto* rules = rbac.mutable_rules();
2576 rules->set_action(GetParam().rbac_action());
2577 Policy policy;
2578 policy.add_permissions()->set_any(true);
2579 policy.add_principals()->set_any(true);
2580 (*rules->mutable_policies())["policy"] = policy;
2581 auto* logging_options = rules->mutable_audit_logging_options();
2582 logging_options->set_audit_condition(GetParam().rbac_audit_condition());
2583 auto* stdout_logger =
2584 logging_options->add_logger_configs()->mutable_audit_logger();
2585 stdout_logger->mutable_typed_config()->set_type_url(
2586 "/envoy.extensions.rbac.audit_loggers.stream.v3.StdoutAuditLog");
2587 auto* test_logger =
2588 logging_options->add_logger_configs()->mutable_audit_logger();
2589 test_logger->mutable_typed_config()->set_type_url("/test_logger");
2590 TypedStruct typed_struct;
2591 typed_struct.set_type_url("/test_logger");
2592 typed_struct.mutable_value()->mutable_fields();
2593 test_logger->mutable_typed_config()->PackFrom(typed_struct);
2594 SetServerRbacPolicy(rbac);
2595 StartBackend(0);
2596 ASSERT_TRUE(backends_[0]->WaitOnServingStatusChange(grpc::StatusCode::OK));
2597 auto action = GetParam().rbac_action();
2598 SendRpc([this]() { return CreateInsecureChannel(); },
2599 RpcOptions().set_wait_for_ready(true), {}, {},
2600 /*test_expects_failure=*/action == RBAC_Action_DENY,
2601 grpc::StatusCode::PERMISSION_DENIED, "Unauthorized RPC rejected");
2602 auto audit_condition = GetParam().rbac_audit_condition();
2603 bool should_log =
2604 (audit_condition ==
2605 RBAC_AuditLoggingOptions_AuditCondition_ON_DENY_AND_ALLOW) ||
2606 (action != RBAC_Action_DENY &&
2607 audit_condition == RBAC_AuditLoggingOptions_AuditCondition_ON_ALLOW) ||
2608 (action == RBAC_Action_DENY &&
2609 audit_condition == RBAC_AuditLoggingOptions_AuditCondition_ON_DENY);
2610 if (should_log) {
2611 EXPECT_THAT(audit_logs_,
2612 ::testing::ElementsAre(absl::StrFormat(
2613 "{\"authorized\":%s,\"matched_rule\":\"policy\","
2614 "\"policy_name\":\"\",\"principal\":\"\","
2615 "\"rpc_"
2616 "method\":\"/grpc.testing.EchoTestService/Echo\"}",
2617 action == RBAC_Action_DENY ? "false" : "true")));
2618 } else {
2619 EXPECT_THAT(audit_logs_, ::testing::ElementsAre());
2620 }
2621 }
2622
2623 } // namespace
2624 } // namespace testing
2625 } // namespace grpc
2626
main(int argc,char ** argv)2627 int main(int argc, char** argv) {
2628 grpc::testing::TestEnvironment env(&argc, argv);
2629 ::testing::InitGoogleTest(&argc, argv);
2630 // Make the backup poller poll very frequently in order to pick up
2631 // updates from all the subchannels's FDs.
2632 grpc_core::ConfigVars::Overrides overrides;
2633 overrides.client_channel_backup_poll_interval_ms = 1;
2634 overrides.trace =
2635 "call,channel,client_channel,client_channel_call,client_channel_lb_call,"
2636 "handshaker";
2637 grpc_core::ConfigVars::SetOverrides(overrides);
2638 #if TARGET_OS_IPHONE
2639 // Workaround Apple CFStream bug
2640 grpc_core::SetEnv("grpc_cfstream", "0");
2641 #endif
2642 grpc::testing::FakeCertificateProvider::CertDataMapWrapper cert_data_map_1;
2643 grpc::testing::g_fake1_cert_data_map = &cert_data_map_1;
2644 grpc::testing::FakeCertificateProvider::CertDataMapWrapper cert_data_map_2;
2645 grpc::testing::g_fake2_cert_data_map = &cert_data_map_2;
2646 grpc_core::CoreConfiguration::RegisterBuilder(
2647 [](grpc_core::CoreConfiguration::Builder* builder) {
2648 builder->certificate_provider_registry()
2649 ->RegisterCertificateProviderFactory(
2650 std::make_unique<grpc::testing::FakeCertificateProviderFactory>(
2651 "fake1", grpc::testing::g_fake1_cert_data_map));
2652 builder->certificate_provider_registry()
2653 ->RegisterCertificateProviderFactory(
2654 std::make_unique<grpc::testing::FakeCertificateProviderFactory>(
2655 "fake2", grpc::testing::g_fake2_cert_data_map));
2656 });
2657 grpc_init();
2658 const auto result = RUN_ALL_TESTS();
2659 grpc_shutdown();
2660 return result;
2661 }
2662