diff options
Diffstat (limited to 'fnet/src/tests')
-rw-r--r-- | fnet/src/tests/frt/rpc/CMakeLists.txt | 6 | ||||
-rw-r--r-- | fnet/src/tests/frt/rpc/invoke.cpp | 34 | ||||
-rw-r--r-- | fnet/src/tests/frt/rpc/my_crypto_engine.hpp | 9 |
3 files changed, 46 insertions, 3 deletions
diff --git a/fnet/src/tests/frt/rpc/CMakeLists.txt b/fnet/src/tests/frt/rpc/CMakeLists.txt index 64a1d150fce..35150cad7b6 100644 --- a/fnet/src/tests/frt/rpc/CMakeLists.txt +++ b/fnet/src/tests/frt/rpc/CMakeLists.txt @@ -10,6 +10,12 @@ vespa_add_test(NAME fnet_invoke_test_app_xor COMMAND fnet_invoke_test_app ENVIRO vespa_add_test(NAME fnet_invoke_test_app_tls COMMAND fnet_invoke_test_app ENVIRONMENT "CRYPTOENGINE=tls") vespa_add_test(NAME fnet_invoke_test_app_tls_maybe_yes COMMAND fnet_invoke_test_app ENVIRONMENT "CRYPTOENGINE=tls_maybe_yes") vespa_add_test(NAME fnet_invoke_test_app_tls_maybe_no COMMAND fnet_invoke_test_app ENVIRONMENT "CRYPTOENGINE=tls_maybe_no") +vespa_add_test(NAME fnet_invoke_test_app_tls_cap_enforced COMMAND fnet_invoke_test_app + ENVIRONMENT "CRYPTOENGINE=tls" "VESPA_TLS_CAPABILITIES_ENFORCEMENT_MODE=enforce") +vespa_add_test(NAME fnet_invoke_test_app_tls_cap_log_only COMMAND fnet_invoke_test_app + ENVIRONMENT "CRYPTOENGINE=tls" "VESPA_TLS_CAPABILITIES_ENFORCEMENT_MODE=log_only") +vespa_add_test(NAME fnet_invoke_test_app_tls_cap_disable COMMAND fnet_invoke_test_app + ENVIRONMENT "CRYPTOENGINE=tls" "VESPA_TLS_CAPABILITIES_ENFORCEMENT_MODE=disable") vespa_add_executable(fnet_detach_return_invoke_test_app TEST SOURCES detach_return_invoke.cpp diff --git a/fnet/src/tests/frt/rpc/invoke.cpp b/fnet/src/tests/frt/rpc/invoke.cpp index e1912985379..2668d86cae6 100644 --- a/fnet/src/tests/frt/rpc/invoke.cpp +++ b/fnet/src/tests/frt/rpc/invoke.cpp @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/vespalib/net/socket_spec.h> +#include <vespa/vespalib/net/tls/capability_env_config.h> #include <vespa/vespalib/util/benchmark_timer.h> #include <vespa/vespalib/util/latch.h> #include <vespa/fnet/frt/supervisor.h> @@ -8,12 +9,14 @@ #include <vespa/fnet/frt/rpcrequest.h> #include <vespa/fnet/frt/invoker.h> #include <vespa/fnet/frt/request_access_filter.h> +#include <vespa/fnet/frt/require_capabilities.h> #include <mutex> #include <condition_variable> #include <string_view> using vespalib::SocketSpec; using vespalib::BenchmarkTimer; +using namespace vespalib::net::tls; constexpr double timeout = 60.0; constexpr double short_timeout = 0.1; @@ -221,6 +224,13 @@ public: rb.DefineMethod("accessRestricted", "s", "", FRT_METHOD(TestRPC::RPC_AccessRestricted), this); rb.RequestAccessFilter(std::make_unique<MyAccessFilter>()); + // The authz rules used for this test only grant the telemetry capability set + rb.DefineMethod("capabilityRestricted", "", "", + FRT_METHOD(TestRPC::RPC_AccessRestricted), this); + rb.RequestAccessFilter(std::make_unique<FRT_RequireCapabilities>(CapabilitySet::content_node())); + rb.DefineMethod("capabilityAllowed", "", "", + FRT_METHOD(TestRPC::RPC_AccessRestricted), this); + rb.RequestAccessFilter(std::make_unique<FRT_RequireCapabilities>(CapabilitySet::telemetry())); } void RPC_Test(FRT_RPCRequest *req) @@ -470,6 +480,30 @@ TEST_F("request allowed by access filter invokes server method as usual", Fixtur EXPECT_TRUE(f1.server_instance().restricted_method_was_invoked()); } +TEST_F("capability checking filter is enforced under mTLS unless overridden by env var", Fixture()) { + MyReq req("capabilityRestricted"); // Requires content node cap set; disallowed + f1.target().InvokeSync(req.borrow(), timeout); + auto cap_mode = capability_enforcement_mode_from_env(); + fprintf(stderr, "capability enforcement mode: %s\n", to_string(cap_mode)); + if (crypto->use_tls_when_client() && (cap_mode == CapabilityEnforcementMode::Enforce)) { + // Default authz rule does not give required capabilities; must fail. + EXPECT_EQUAL(req.get().GetErrorCode(), FRTE_RPC_PERMISSION_DENIED); + EXPECT_FALSE(f1.server_instance().restricted_method_was_invoked()); + } else { + // Either no mTLS configured (implicit full capability set) or capabilities not enforced. + ASSERT_FALSE(req.get().IsError()); + EXPECT_TRUE(f1.server_instance().restricted_method_was_invoked()); + } +} + +TEST_F("access is allowed by capability filter when peer is granted the required capability", Fixture()) { + MyReq req("capabilityAllowed"); // Requires telemetry cap set; allowed + f1.target().InvokeSync(req.borrow(), timeout); + // Should always be allowed, regardless of mTLS mode or capability enforcement + ASSERT_FALSE(req.get().IsError()); + EXPECT_TRUE(f1.server_instance().restricted_method_was_invoked()); +} + TEST_MAIN() { crypto = my_crypto_engine(); TEST_RUN_ALL(); diff --git a/fnet/src/tests/frt/rpc/my_crypto_engine.hpp b/fnet/src/tests/frt/rpc/my_crypto_engine.hpp index 83934c430b3..219b4dafd05 100644 --- a/fnet/src/tests/frt/rpc/my_crypto_engine.hpp +++ b/fnet/src/tests/frt/rpc/my_crypto_engine.hpp @@ -17,14 +17,17 @@ vespalib::CryptoEngine::SP my_crypto_engine() { return std::make_shared<vespalib::XorCryptoEngine>(); } else if (engine == "tls") { fprintf(stderr, "crypto engine: tls\n"); - return std::make_shared<vespalib::TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing()); + return std::make_shared<vespalib::TlsCryptoEngine>( + vespalib::test::make_telemetry_only_capability_tls_options_for_testing()); } else if (engine == "tls_maybe_yes") { fprintf(stderr, "crypto engine: tls client, mixed server\n"); - auto tls = std::make_shared<vespalib::TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing()); + auto tls = std::make_shared<vespalib::TlsCryptoEngine>( + vespalib::test::make_telemetry_only_capability_tls_options_for_testing()); return std::make_shared<vespalib::MaybeTlsCryptoEngine>(std::move(tls), true); } else if (engine == "tls_maybe_no") { fprintf(stderr, "crypto engine: null client, mixed server\n"); - auto tls = std::make_shared<vespalib::TlsCryptoEngine>(vespalib::test::make_tls_options_for_testing()); + auto tls = std::make_shared<vespalib::TlsCryptoEngine>( + vespalib::test::make_telemetry_only_capability_tls_options_for_testing()); return std::make_shared<vespalib::MaybeTlsCryptoEngine>(std::move(tls), false); } TEST_FATAL(("invalid crypto engine: " + engine).c_str()); |