aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2022-08-22 13:55:17 +0000
committerTor Brede Vekterli <vekterli@yahooinc.com>2022-08-22 14:11:59 +0000
commit55e0f93a74214caf22c4fd79d60e1b0b6836a99c (patch)
tree0a59f93c8c46f98007057ab9e49a789867e2018d /vespalib
parentb4117991e6d98dbc9a93625f6dc7170cdd1484dc (diff)
Support capability enforcement environment variable in C++
Mirrors Java enforce/log-only/disable semantics, defaulting to enforce. Also fixes an issue where connection auth context and capabilities would not be set if a server socket was running in mixed-mode. This is not a problem in practice since mixed-mode is inherently completely insecure since it must accept plain-text clients, which implicitly have all capabilities granted.
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/CMakeLists.txt1
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/capability_env_config.cpp46
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/capability_env_config.h16
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp5
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.h1
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/transport_security_options.cpp13
-rw-r--r--vespalib/src/vespa/vespalib/net/tls/transport_security_options.h4
-rw-r--r--vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp23
-rw-r--r--vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h8
9 files changed, 109 insertions, 8 deletions
diff --git a/vespalib/src/vespa/vespalib/net/tls/CMakeLists.txt b/vespalib/src/vespa/vespalib/net/tls/CMakeLists.txt
index 5be2e0d4387..5e91f682f36 100644
--- a/vespalib/src/vespa/vespalib/net/tls/CMakeLists.txt
+++ b/vespalib/src/vespa/vespalib/net/tls/CMakeLists.txt
@@ -4,6 +4,7 @@ vespa_add_library(vespalib_vespalib_net_tls OBJECT
authorization_mode.cpp
auto_reloading_tls_crypto_engine.cpp
capability.cpp
+ capability_env_config.cpp
capability_set.cpp
crypto_codec.cpp
crypto_codec_adapter.cpp
diff --git a/vespalib/src/vespa/vespalib/net/tls/capability_env_config.cpp b/vespalib/src/vespa/vespalib/net/tls/capability_env_config.cpp
new file mode 100644
index 00000000000..ec97882ca64
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/net/tls/capability_env_config.cpp
@@ -0,0 +1,46 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "capability_env_config.h"
+#include <vespa/vespalib/stllike/string.h>
+#include <cstdlib>
+
+#include <vespa/log/log.h>
+LOG_SETUP(".vespalib.net.tls.capability_env_config");
+
+namespace vespalib::net::tls {
+
+namespace {
+
+CapabilityEnforcementMode parse_enforcement_mode_from_env() noexcept {
+ const char* env = getenv("VESPA_TLS_CAPABILITIES_ENFORCEMENT_MODE");
+ vespalib::string mode = env ? env : "";
+ if (mode == "enforce") {
+ return CapabilityEnforcementMode::Enforce;
+ } else if (mode == "log_only") {
+ return CapabilityEnforcementMode::LogOnly;
+ } else if (mode == "disable") {
+ return CapabilityEnforcementMode::Disable;
+ } else if (!mode.empty()) {
+ LOG(warning, "VESPA_TLS_CAPABILITIES_ENFORCEMENT_MODE environment variable has "
+ "an unsupported value (%s). Falling back to 'enforce'", mode.c_str());
+ }
+ return CapabilityEnforcementMode::Enforce;
+}
+
+}
+
+const char* to_string(CapabilityEnforcementMode mode) noexcept {
+ switch (mode) {
+ case CapabilityEnforcementMode::Enforce: return "Enforce";
+ case CapabilityEnforcementMode::LogOnly: return "LogOnly";
+ case CapabilityEnforcementMode::Disable: return "Disable";
+ default: abort();
+ }
+}
+
+CapabilityEnforcementMode capability_enforcement_mode_from_env() noexcept {
+ static const CapabilityEnforcementMode mode = parse_enforcement_mode_from_env();
+ return mode;
+}
+
+}
diff --git a/vespalib/src/vespa/vespalib/net/tls/capability_env_config.h b/vespalib/src/vespa/vespalib/net/tls/capability_env_config.h
new file mode 100644
index 00000000000..e66fca9656b
--- /dev/null
+++ b/vespalib/src/vespa/vespalib/net/tls/capability_env_config.h
@@ -0,0 +1,16 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+namespace vespalib::net::tls {
+
+enum class CapabilityEnforcementMode {
+ Disable,
+ LogOnly,
+ Enforce
+};
+
+const char* to_string(CapabilityEnforcementMode mode) noexcept;
+
+CapabilityEnforcementMode capability_enforcement_mode_from_env() noexcept;
+
+}
diff --git a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp
index be692e8df35..04613cb3a65 100644
--- a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp
+++ b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.cpp
@@ -5,6 +5,7 @@
#include "tls_crypto_socket.h"
#include "protocol_snooping.h"
#include <vespa/vespalib/data/smart_buffer.h>
+#include <vespa/vespalib/net/connection_auth_context.h>
#include <vespa/vespalib/util/size_literals.h>
namespace vespalib {
@@ -94,4 +95,8 @@ MaybeTlsCryptoSocket::MaybeTlsCryptoSocket(SocketHandle socket, std::shared_ptr<
{
}
+std::unique_ptr<net::ConnectionAuthContext> MaybeTlsCryptoSocket::make_auth_context() {
+ return _socket->make_auth_context();
+}
+
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.h b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.h
index ba706cb3cd7..1928307e5ad 100644
--- a/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.h
+++ b/vespalib/src/vespa/vespalib/net/tls/maybe_tls_crypto_socket.h
@@ -33,6 +33,7 @@ public:
ssize_t flush() override { return _socket->flush(); }
ssize_t half_close() override { return _socket->half_close(); }
void drop_empty_buffers() override { _socket->drop_empty_buffers(); }
+ std::unique_ptr<net::ConnectionAuthContext> make_auth_context() override;
};
} // namespace vespalib
diff --git a/vespalib/src/vespa/vespalib/net/tls/transport_security_options.cpp b/vespalib/src/vespa/vespalib/net/tls/transport_security_options.cpp
index 3b3fdd579d1..f3ae1a05919 100644
--- a/vespalib/src/vespa/vespalib/net/tls/transport_security_options.cpp
+++ b/vespalib/src/vespa/vespalib/net/tls/transport_security_options.cpp
@@ -29,6 +29,15 @@ TransportSecurityOptions::TransportSecurityOptions(vespalib::string ca_certs_pem
{
}
+TransportSecurityOptions::TransportSecurityOptions(const TransportSecurityOptions&) = default;
+TransportSecurityOptions& TransportSecurityOptions::operator=(const TransportSecurityOptions&) = default;
+TransportSecurityOptions::TransportSecurityOptions(TransportSecurityOptions&&) noexcept = default;
+TransportSecurityOptions& TransportSecurityOptions::operator=(TransportSecurityOptions&&) noexcept = default;
+
+TransportSecurityOptions::~TransportSecurityOptions() {
+ secure_memzero(&_private_key_pem[0], _private_key_pem.size());
+}
+
TransportSecurityOptions TransportSecurityOptions::copy_without_private_key() const {
return TransportSecurityOptions(_ca_certs_pem, _cert_chain_pem, "",
_authorized_peers, _disable_hostname_validation);
@@ -62,8 +71,4 @@ TransportSecurityOptions::Params::Params(Params&&) noexcept = default;
TransportSecurityOptions::Params&
TransportSecurityOptions::Params::operator=(TransportSecurityOptions::Params&&) noexcept = default;
-TransportSecurityOptions::~TransportSecurityOptions() {
- secure_memzero(&_private_key_pem[0], _private_key_pem.size());
-}
-
} // vespalib::net::tls
diff --git a/vespalib/src/vespa/vespalib/net/tls/transport_security_options.h b/vespalib/src/vespa/vespalib/net/tls/transport_security_options.h
index 84fc9c1cbbe..4694373671b 100644
--- a/vespalib/src/vespa/vespalib/net/tls/transport_security_options.h
+++ b/vespalib/src/vespa/vespalib/net/tls/transport_security_options.h
@@ -46,6 +46,10 @@ public:
};
explicit TransportSecurityOptions(Params params);
+ TransportSecurityOptions(const TransportSecurityOptions&);
+ TransportSecurityOptions& operator=(const TransportSecurityOptions&);
+ TransportSecurityOptions(TransportSecurityOptions&&) noexcept;
+ TransportSecurityOptions& operator=(TransportSecurityOptions&&) noexcept;
~TransportSecurityOptions();
diff --git a/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp b/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp
index 29043dc42a5..1210b1d7c87 100644
--- a/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp
+++ b/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.cpp
@@ -1,17 +1,20 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "make_tls_options_for_testing.h"
+#include "peer_policy_utils.h"
#include <vespa/vespalib/crypto/private_key.h>
#include <vespa/vespalib/crypto/x509_certificate.h>
namespace {
using namespace vespalib::crypto;
+using namespace vespalib::net::tls;
struct TransientCryptoCredentials {
CertKeyWrapper root_ca;
CertKeyWrapper host_creds;
vespalib::net::tls::TransportSecurityOptions cached_transport_options;
+ vespalib::net::tls::TransportSecurityOptions cached_constrained_transport_options;
TransientCryptoCredentials();
~TransientCryptoCredentials();
@@ -29,14 +32,16 @@ struct TransientCryptoCredentials {
return {std::move(cert), std::move(key)};
}
- static CertKeyWrapper make_host_creds(const CertKeyWrapper& root_ca_creds) {
+ static CertKeyWrapper make_host_creds(const CertKeyWrapper& root_ca_creds,
+ const vespalib::string& extra_san_entry) {
auto dn = X509Certificate::DistinguishedName()
.country("US").state("CA").locality("Sunnyvale")
.organization("Wile E. Coyote, Ltd.")
.organizational_unit("Unit Testing and Anvil Dropping Division")
.add_common_name("localhost"); // Should technically not be needed, but including it anyway.
auto subject = X509Certificate::SubjectInfo(std::move(dn));
- subject.add_subject_alt_name("DNS:localhost");
+ subject.add_subject_alt_name("DNS:localhost")
+ .add_subject_alt_name(extra_san_entry);
auto key = PrivateKey::generate_p256_ec_key();
auto params = X509Certificate::Params::issued_by(std::move(subject), key, root_ca_creds.cert, root_ca_creds.key);
params.valid_for = std::chrono::hours(1);
@@ -49,12 +54,18 @@ struct TransientCryptoCredentials {
TransientCryptoCredentials::TransientCryptoCredentials()
: root_ca(make_root_ca()),
- host_creds(make_host_creds(root_ca)),
+ host_creds(make_host_creds(root_ca, "DNS:anvils.example")),
cached_transport_options(vespalib::net::tls::TransportSecurityOptions::Params().
ca_certs_pem(root_ca.cert->to_pem()).
cert_chain_pem(host_creds.cert->to_pem()).
private_key_pem(host_creds.key->private_to_pem()).
- authorized_peers(vespalib::net::tls::AuthorizedPeers::allow_all_authenticated()))
+ authorized_peers(vespalib::net::tls::AuthorizedPeers::allow_all_authenticated())),
+ cached_constrained_transport_options(vespalib::net::tls::TransportSecurityOptions::Params().
+ ca_certs_pem(root_ca.cert->to_pem()).
+ cert_chain_pem(host_creds.cert->to_pem()).
+ private_key_pem(host_creds.key->private_to_pem()).
+ authorized_peers(authorized_peers({policy_with({required_san_dns("anvils.example")},
+ CapabilitySet::telemetry())})))
{}
TransientCryptoCredentials::~TransientCryptoCredentials() = default;
@@ -74,4 +85,8 @@ vespalib::net::tls::TransportSecurityOptions make_tls_options_for_testing() {
return TransientCryptoCredentials::instance().cached_transport_options;
}
+vespalib::net::tls::TransportSecurityOptions make_telemetry_only_capability_tls_options_for_testing() {
+ return TransientCryptoCredentials::instance().cached_constrained_transport_options;
+}
+
} // namespace vespalib::test
diff --git a/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h b/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h
index 055d9cbdfa6..5a07f796991 100644
--- a/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h
+++ b/vespalib/src/vespa/vespalib/test/make_tls_options_for_testing.h
@@ -20,4 +20,12 @@ extern SocketSpec local_spec;
**/
vespalib::net::tls::TransportSecurityOptions make_tls_options_for_testing();
+/**
+ * Make security options whose authz rules only grant the telemetry capability
+ * set to the included certificate.
+ *
+ * Only useful for testing capability propagation and filtering.
+ */
+vespalib::net::tls::TransportSecurityOptions make_telemetry_only_capability_tls_options_for_testing();
+
} // namespace vespalib::test