This is an automated email from the ASF dual-hosted git repository. abukor pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/kudu.git
commit 592ba3c5f7abfba43ee5ef1b339a4743006b6e3b Author: Attila Bukor <[email protected]> AuthorDate: Tue Jul 27 15:00:26 2021 +0200 KUDU-1921 Add ability to require auth/encryption to C++ client Kudu servers support requiring authentication and encryption to be enabled, and clients prefer connecting in a secure way, but if a server doesn't support authentication and/or encryption, the client will silently connect insecurely, which can lead to a downgrade attack. With this patch, clients can require authentication and encryption to be set using the client API, where if such an attack is attempted, the client will fail to connect to the cluster. Change-Id: Ia3e800eb7c4e2f8787f0adf1f040d47358d29320 Reviewed-on: http://gerrit.cloudera.org:8080/17731 Tested-by: Kudu Jenkins Reviewed-by: Alexey Serbin <[email protected]> --- src/kudu/client/client.cc | 19 +++++++ src/kudu/client/client.h | 42 ++++++++++++++++ src/kudu/client/client_builder-internal.cc | 11 ++-- src/kudu/client/client_builder-internal.h | 2 + src/kudu/integration-tests/security-itest.cc | 75 +++++++++++++++++++++++++++- src/kudu/rpc/client_negotiation.cc | 4 +- src/kudu/rpc/client_negotiation.h | 2 + src/kudu/rpc/messenger.cc | 2 + src/kudu/rpc/messenger.h | 8 +++ src/kudu/rpc/negotiation-test.cc | 20 +++++--- src/kudu/rpc/negotiation.cc | 10 +++- src/kudu/rpc/negotiation.h | 1 + src/kudu/rpc/reactor.cc | 7 ++- src/kudu/rpc/server_negotiation.cc | 6 ++- src/kudu/rpc/server_negotiation.h | 2 + 15 files changed, 192 insertions(+), 19 deletions(-) diff --git a/src/kudu/client/client.cc b/src/kudu/client/client.cc index 8c57302..d05aaa8 100644 --- a/src/kudu/client/client.cc +++ b/src/kudu/client/client.cc @@ -325,6 +325,16 @@ KuduClientBuilder& KuduClientBuilder::sasl_protocol_name(const string& sasl_prot return *this; } +KuduClientBuilder& KuduClientBuilder::encryption_policy(EncryptionPolicy encryption_policy) { + data_->encryption_policy_ = encryption_policy; + return *this; +} + +KuduClientBuilder& KuduClientBuilder::require_authentication(bool require_authentication) { + data_->require_authentication_ = require_authentication; + return *this; +} + namespace { Status ImportAuthnCreds(const string& authn_creds, Messenger* messenger, @@ -371,6 +381,15 @@ Status KuduClientBuilder::Build(shared_ptr<KuduClient>* client) { if (!data_->sasl_protocol_name_.empty()) { builder.set_sasl_proto_name(data_->sasl_protocol_name_); } + if (data_->require_authentication_) { + builder.set_rpc_authentication("required"); + } + if (data_->encryption_policy_ != OPTIONAL) { + builder.set_rpc_encryption("required"); + if (data_->encryption_policy_ == REQUIRED) { + builder.set_rpc_loopback_encryption(true); + } + } std::shared_ptr<Messenger> messenger; RETURN_NOT_OK(builder.Build(&messenger)); UserCredentials user_credentials; diff --git a/src/kudu/client/client.h b/src/kudu/client/client.h index 3ff9141..853d0a1 100644 --- a/src/kudu/client/client.h +++ b/src/kudu/client/client.h @@ -230,6 +230,18 @@ class KUDU_EXPORT KuduClientBuilder { KuduClientBuilder(); ~KuduClientBuilder(); + /// Policy for on-the-wire encryption + enum EncryptionPolicy { + OPTIONAL, ///< Optional, it uses encrypted connection if the server supports + ///< it, but it can connect to insecure servers too. + + REQUIRED_REMOTE, ///< Only connects to remote servers that support encryption, fails + ///< otherwise. It can connect to insecure servers only locally. + + REQUIRED ///< Only connects to any server, including on the loopback interface, + ///< that support encryption, fails otherwise. + }; + /// Clear the set of master addresses. /// /// @return Reference to the updated object. @@ -319,6 +331,36 @@ class KUDU_EXPORT KuduClientBuilder { /// @return Reference to the updated object. KuduClientBuilder& sasl_protocol_name(const std::string& sasl_protocol_name); + /// Require authentication for the connection to a remote server. + /// + /// If it's set to true, the client will require mutual authentication between + /// the server and the client. If the server doesn't support authentication, + /// or it's disabled, the client will fail to connect. + /// + /// @param [in] require_authentication + /// Whether to require authentication. + /// @return Reference to the updated object. + KuduClientBuilder& require_authentication(bool require_authentication); + + /// Require encryption for the connection to a remote server. + /// + /// If it's set to REQUIRED_REMOTE or REQUIRED, the client will + /// require encrypting the traffic between the server and the client. + /// If the server doesn't support encryption, or if it's disabled, the + /// client will fail to connect. + /// + /// Loopback connections are encrypted only if 'encryption_policy' is + /// set to REQUIRED, or if it's required by the server. + /// + /// The default value is OPTIONAL, which allows connecting to servers without + /// encryption as well, but it will still attempt to use it if the server + /// supports it. + /// + /// @param [in] encryption_policy + /// Which encryption policy to use. + /// @return Reference to the updated object. + KuduClientBuilder& encryption_policy(EncryptionPolicy encryption_policy); + /// Create a client object. /// /// @note KuduClients objects are shared amongst multiple threads and, diff --git a/src/kudu/client/client_builder-internal.cc b/src/kudu/client/client_builder-internal.cc index 7d0d496..b3c027c 100644 --- a/src/kudu/client/client_builder-internal.cc +++ b/src/kudu/client/client_builder-internal.cc @@ -25,11 +25,12 @@ namespace client { KuduClientBuilder::Data::Data() : default_admin_operation_timeout_(MonoDelta::FromSeconds(30)), default_rpc_timeout_(MonoDelta::FromSeconds(10)), - replica_visibility_(internal::ReplicaController::Visibility::VOTERS) { -} + replica_visibility_(internal::ReplicaController::Visibility::VOTERS), + require_authentication_(false), + encryption_policy_(EncryptionPolicy::OPTIONAL) { + } -KuduClientBuilder::Data::~Data() { -} + KuduClientBuilder::Data::~Data() {} -} // namespace client +} // namespace client } // namespace kudu diff --git a/src/kudu/client/client_builder-internal.h b/src/kudu/client/client_builder-internal.h index f097b3e..8da30b4 100644 --- a/src/kudu/client/client_builder-internal.h +++ b/src/kudu/client/client_builder-internal.h @@ -43,6 +43,8 @@ class KuduClientBuilder::Data { internal::ReplicaController::Visibility replica_visibility_; boost::optional<int> num_reactors_; std::string sasl_protocol_name_; + bool require_authentication_; + EncryptionPolicy encryption_policy_; DISALLOW_COPY_AND_ASSIGN(Data); }; diff --git a/src/kudu/integration-tests/security-itest.cc b/src/kudu/integration-tests/security-itest.cc index c2d6bd2..60646aa 100644 --- a/src/kudu/integration-tests/security-itest.cc +++ b/src/kudu/integration-tests/security-itest.cc @@ -25,6 +25,7 @@ #include <memory> #include <ostream> #include <string> +#include <tuple> #include <vector> #include <gflags/gflags_declare.h> @@ -87,7 +88,9 @@ using kudu::client::sp::shared_ptr; using kudu::cluster::ExternalMiniCluster; using kudu::cluster::ExternalMiniClusterOptions; using kudu::rpc::Messenger; +using std::get; using std::string; +using std::tuple; using std::unique_ptr; using std::vector; using strings::Substitute; @@ -639,6 +642,76 @@ TEST_F(SecurityITest, TestMismatchingPrincipals) { ASSERT_TRUE(s.IsTimedOut()); } +TEST_F(SecurityITest, TestRequireAuthenticationInsecureCluster) { + cluster_opts_.enable_kerberos = false; + ASSERT_OK(StartCluster()); + + shared_ptr<KuduClient> client; + KuduClientBuilder b; + b.require_authentication(true); + Status s = cluster_->CreateClient(&b, &client); + ASSERT_TRUE(s.IsNotAuthorized()); + ASSERT_STR_CONTAINS(s.ToString(), + "client requires authentication, but server does not have Kerberos enabled"); +} + +TEST_F(SecurityITest, TestRequireEncryptionInsecureCluster) { + cluster_opts_.enable_kerberos = false; + cluster_opts_.extra_master_flags.emplace_back("--rpc_encryption=disabled"); + cluster_opts_.extra_tserver_flags.emplace_back("--rpc_encryption=disabled"); + cluster_opts_.extra_master_flags.emplace_back("--rpc_authentication=disabled"); + cluster_opts_.extra_tserver_flags.emplace_back("--rpc_authentication=disabled"); + ASSERT_OK(StartCluster()); + + shared_ptr<KuduClient> client; + KuduClientBuilder b; + b.encryption_policy(client::KuduClientBuilder::REQUIRED); + Status s = cluster_->CreateClient(&b, &client); + ASSERT_TRUE(s.IsNotAuthorized()); + ASSERT_STR_CONTAINS(s.ToString(), "server does not support required TLS encryption"); +} + +TEST_F(SecurityITest, TestRequireAuthenticationSecureCluster) { + ASSERT_OK(StartCluster()); + + shared_ptr<KuduClient> client; + KuduClientBuilder b; + b.require_authentication(true); + ASSERT_OK(cluster_->CreateClient(&b, &client)); + SmokeTestCluster(client, /* transactional */ false); +} + +class EncryptionPolicyTest : + public SecurityITest, + public ::testing::WithParamInterface<tuple< + KuduClientBuilder::EncryptionPolicy, bool>> { +}; + +INSTANTIATE_TEST_SUITE_P(, + EncryptionPolicyTest, + ::testing::Combine( + ::testing::Values( + KuduClientBuilder::EncryptionPolicy::OPTIONAL, + KuduClientBuilder::EncryptionPolicy::REQUIRED, + KuduClientBuilder::EncryptionPolicy::REQUIRED_REMOTE), + ::testing::Values(true, false))); + +TEST_P(EncryptionPolicyTest, TestEncryptionPolicy) { + const auto& params = GetParam(); + if (!get<1>(params)) { + cluster_opts_.enable_kerberos = false; + cluster_opts_.extra_master_flags.emplace_back("--rpc_authentication=disabled"); + cluster_opts_.extra_tserver_flags.emplace_back("--rpc_authentication=disabled"); + } + ASSERT_OK(StartCluster()); + + shared_ptr<KuduClient> client; + KuduClientBuilder b; + b.encryption_policy(get<0>(params)); + ASSERT_OK(cluster_->CreateClient(&b, &client)); + SmokeTestCluster(client, /* transactional */ false); +} + Status AssignIPToClient(bool external) { // If the test does not require an external IP address // assign loopback IP to FLAGS_local_ip_for_outbound_sockets. @@ -924,4 +997,4 @@ TEST_P(ConnectToFollowerMasterTest, AuthnTokenVerifierHaveKeys) { } } -} // namespace kudu +} // namespace kudu diff --git a/src/kudu/rpc/client_negotiation.cc b/src/kudu/rpc/client_negotiation.cc index 7c3992b..9557ff3 100644 --- a/src/kudu/rpc/client_negotiation.cc +++ b/src/kudu/rpc/client_negotiation.cc @@ -119,6 +119,7 @@ ClientNegotiation::ClientNegotiation(unique_ptr<Socket> socket, const security::TlsContext* tls_context, boost::optional<security::SignedTokenPB> authn_token, RpcEncryption encryption, + bool encrypt_loopback, std::string sasl_proto_name) : socket_(std::move(socket)), helper_(SaslHelper::CLIENT), @@ -126,6 +127,7 @@ ClientNegotiation::ClientNegotiation(unique_ptr<Socket> socket, tls_handshake_(security::TlsHandshakeType::CLIENT), encryption_(encryption), tls_negotiated_(false), + encrypt_loopback_(encrypt_loopback), authn_token_(std::move(authn_token)), psecret_(nullptr, std::free), negotiated_authn_(AuthenticationType::INVALID), @@ -324,7 +326,7 @@ Status ClientNegotiation::SendNegotiate() { client_features_.insert(TLS); // If the remote peer is local, then we allow using TLS for authentication // without encryption or integrity. - if (socket_->IsLoopbackConnection() && !FLAGS_rpc_encrypt_loopback_connections) { + if (socket_->IsLoopbackConnection() && !encrypt_loopback_) { client_features_.insert(TLS_AUTHENTICATION_ONLY); } } diff --git a/src/kudu/rpc/client_negotiation.h b/src/kudu/rpc/client_negotiation.h index e9f0c7d..4d3e6d5 100644 --- a/src/kudu/rpc/client_negotiation.h +++ b/src/kudu/rpc/client_negotiation.h @@ -66,6 +66,7 @@ class ClientNegotiation { const security::TlsContext* tls_context, boost::optional<security::SignedTokenPB> authn_token, security::RpcEncryption encryption, + bool encrypt_loopback, std::string sasl_proto_name); // Enable PLAIN authentication. @@ -229,6 +230,7 @@ class ClientNegotiation { security::TlsHandshake tls_handshake_; const security::RpcEncryption encryption_; bool tls_negotiated_; + bool encrypt_loopback_; // TSK state. boost::optional<security::SignedTokenPB> authn_token_; diff --git a/src/kudu/rpc/messenger.cc b/src/kudu/rpc/messenger.cc index 87a7bae..a517a6f 100644 --- a/src/kudu/rpc/messenger.cc +++ b/src/kudu/rpc/messenger.cc @@ -76,6 +76,7 @@ MessengerBuilder::MessengerBuilder(string name) sasl_proto_name_("kudu"), rpc_authentication_("optional"), rpc_encryption_("optional"), + rpc_loopback_encryption_(false), rpc_tls_ciphers_(kudu::security::SecurityDefaults::kDefaultTlsCiphers), rpc_tls_ciphersuites_(kudu::security::SecurityDefaults::kDefaultTlsCipherSuites), rpc_tls_min_protocol_(kudu::security::SecurityDefaults::kDefaultTlsMinVersion), @@ -98,6 +99,7 @@ Status MessengerBuilder::Build(shared_ptr<Messenger>* msgr) { RETURN_NOT_OK(ParseTriState("--rpc_encryption", rpc_encryption_, &new_msgr->encryption_)); + new_msgr->loopback_encryption_ = rpc_loopback_encryption_; RETURN_NOT_OK(new_msgr->Init()); if (new_msgr->encryption_ != RpcEncryption::DISABLED && enable_inbound_tls_) { auto* tls_context = new_msgr->mutable_tls_context(); diff --git a/src/kudu/rpc/messenger.h b/src/kudu/rpc/messenger.h index 983d959..4c99f6f 100644 --- a/src/kudu/rpc/messenger.h +++ b/src/kudu/rpc/messenger.h @@ -160,6 +160,11 @@ class MessengerBuilder { return *this; } + MessengerBuilder& set_rpc_loopback_encryption(bool rpc_loopback_encryption) { + rpc_loopback_encryption_ = rpc_loopback_encryption; + return *this; + } + // Set TLSv1.2 and earlier cipher suite preferences to use for TLS-secured RPC // connections. Uses the OpenSSL cipher preference list format. Under the // hood, SSL_CTX_set_cipher_list() is eventually being called with @@ -261,6 +266,7 @@ class MessengerBuilder { std::string sasl_proto_name_; std::string rpc_authentication_; std::string rpc_encryption_; + bool rpc_loopback_encryption_; std::string rpc_tls_ciphers_; // pre-TLSv1.3 cipher suites std::string rpc_tls_ciphersuites_; // TLSv1.3-related cipher suites std::string rpc_tls_min_protocol_; @@ -381,6 +387,7 @@ class Messenger { security::RpcAuthentication authentication() const { return authentication_; } security::RpcEncryption encryption() const { return encryption_; } + bool loopback_encryption() const { return loopback_encryption_; } ThreadPool* negotiation_pool(Connection::Direction dir); @@ -473,6 +480,7 @@ class Messenger { // reused by different clients. security::RpcAuthentication authentication_; security::RpcEncryption encryption_; + bool loopback_encryption_; // Pools which are listening on behalf of this messenger. // Note that the user may have called Shutdown() on one of these diff --git a/src/kudu/rpc/negotiation-test.cc b/src/kudu/rpc/negotiation-test.cc index 3983ff0..e0a8321 100644 --- a/src/kudu/rpc/negotiation-test.cc +++ b/src/kudu/rpc/negotiation-test.cc @@ -252,11 +252,13 @@ TEST_P(TestNegotiation, TestNegotiation) { &client_tls_context, authn_token, desc.client.encryption, + desc.rpc_encrypt_loopback, "kudu"); ServerNegotiation server_negotiation(std::move(server_socket), &server_tls_context, &token_verifier, desc.server.encryption, + desc.rpc_encrypt_loopback, "kudu"); // Set client and server SASL mechanisms. @@ -1034,7 +1036,8 @@ static void RunGSSAPINegotiationServer(unique_ptr<Socket> socket, CHECK_OK(tls_context.Init()); TokenVerifier token_verifier; ServerNegotiation server_negotiation(std::move(socket), &tls_context, - &token_verifier, RpcEncryption::OPTIONAL, "kudu"); + &token_verifier, RpcEncryption::OPTIONAL, + /* encrypt_loopback */ false, "kudu"); server_negotiation.set_server_fqdn("127.0.0.1"); CHECK_OK(server_negotiation.EnableGSSAPI()); post_check(server_negotiation.Negotiate()); @@ -1047,7 +1050,8 @@ static void RunGSSAPINegotiationClient(unique_ptr<Socket> conn, TlsContext tls_context; CHECK_OK(tls_context.Init()); ClientNegotiation client_negotiation(std::move(conn), &tls_context, - boost::none, RpcEncryption::OPTIONAL, "kudu"); + boost::none, RpcEncryption::OPTIONAL, + /* encrypt_loopback */ false, "kudu"); client_negotiation.set_server_fqdn("127.0.0.1"); CHECK_OK(client_negotiation.EnableGSSAPI()); post_check(client_negotiation.Negotiate()); @@ -1210,7 +1214,8 @@ static void RunTimeoutExpectingServer(unique_ptr<Socket> socket) { CHECK_OK(tls_context.Init()); TokenVerifier token_verifier; ServerNegotiation server_negotiation(std::move(socket), &tls_context, - &token_verifier, RpcEncryption::OPTIONAL, "kudu"); + &token_verifier, RpcEncryption::OPTIONAL, + /* encrypt_loopback */ false, "kudu"); CHECK_OK(server_negotiation.EnablePlain()); Status s = server_negotiation.Negotiate(); ASSERT_TRUE(s.IsNetworkError()) << "Expected client to time out and close the connection. Got: " @@ -1221,7 +1226,8 @@ static void RunTimeoutNegotiationClient(unique_ptr<Socket> sock) { TlsContext tls_context; CHECK_OK(tls_context.Init()); ClientNegotiation client_negotiation(std::move(sock), &tls_context, - boost::none, RpcEncryption::OPTIONAL, "kudu"); + boost::none, RpcEncryption::OPTIONAL, + /* encrypt_loopback */ false, "kudu"); CHECK_OK(client_negotiation.EnablePlain("test", "test")); MonoTime deadline = MonoTime::Now() - MonoDelta::FromMilliseconds(100L); client_negotiation.set_deadline(deadline); @@ -1242,7 +1248,8 @@ static void RunTimeoutNegotiationServer(unique_ptr<Socket> socket) { CHECK_OK(tls_context.Init()); TokenVerifier token_verifier; ServerNegotiation server_negotiation(std::move(socket), &tls_context, - &token_verifier, RpcEncryption::OPTIONAL, "kudu"); + &token_verifier, RpcEncryption::OPTIONAL, + /* encrypt_loopback */ false, "kudu"); CHECK_OK(server_negotiation.EnablePlain()); MonoTime deadline = MonoTime::Now() - MonoDelta::FromMilliseconds(100L); server_negotiation.set_deadline(deadline); @@ -1255,7 +1262,8 @@ static void RunTimeoutExpectingClient(unique_ptr<Socket> socket) { TlsContext tls_context; CHECK_OK(tls_context.Init()); ClientNegotiation client_negotiation(std::move(socket), &tls_context, - boost::none, RpcEncryption::OPTIONAL, "kudu"); + boost::none, RpcEncryption::OPTIONAL, + /* encrypt_loopback */ false, "kudu"); CHECK_OK(client_negotiation.EnablePlain("test", "test")); Status s = client_negotiation.Negotiate(); ASSERT_TRUE(s.IsNetworkError()) << "Expected server to time out and close the connection. Got: " diff --git a/src/kudu/rpc/negotiation.cc b/src/kudu/rpc/negotiation.cc index 71c23f7..e429b4c 100644 --- a/src/kudu/rpc/negotiation.cc +++ b/src/kudu/rpc/negotiation.cc @@ -166,6 +166,7 @@ static Status DisableSocketTimeouts(Socket* socket) { static Status DoClientNegotiation(Connection* conn, RpcAuthentication authentication, RpcEncryption encryption, + bool encrypt_loopback, MonoTime deadline, unique_ptr<ErrorStatusPB>* rpc_error) { const auto* messenger = conn->reactor_thread()->reactor()->messenger(); @@ -176,6 +177,7 @@ static Status DoClientNegotiation(Connection* conn, &messenger->tls_context(), authn_token, encryption, + encrypt_loopback, messenger->sasl_proto_name()); client_negotiation.set_server_fqdn(conn->outbound_connection_id().hostname()); @@ -236,6 +238,7 @@ static Status DoClientNegotiation(Connection* conn, static Status DoServerNegotiation(Connection* conn, RpcAuthentication authentication, RpcEncryption encryption, + bool encrypt_loopback, const MonoTime& deadline) { const auto* messenger = conn->reactor_thread()->reactor()->messenger(); if (authentication == RpcAuthentication::REQUIRED && @@ -257,6 +260,7 @@ static Status DoServerNegotiation(Connection* conn, &messenger->tls_context(), &messenger->token_verifier(), encryption, + encrypt_loopback, messenger->sasl_proto_name()); if (authentication != RpcAuthentication::DISABLED && !messenger->keytab_file().empty()) { @@ -286,13 +290,15 @@ static Status DoServerNegotiation(Connection* conn, void Negotiation::RunNegotiation(const scoped_refptr<Connection>& conn, RpcAuthentication authentication, RpcEncryption encryption, + bool loopback_encryption, MonoTime deadline) { Status s; unique_ptr<ErrorStatusPB> rpc_error; + bool encrypt_loopback = FLAGS_rpc_encrypt_loopback_connections || loopback_encryption; if (conn->direction() == Connection::SERVER) { - s = DoServerNegotiation(conn.get(), authentication, encryption, deadline); + s = DoServerNegotiation(conn.get(), authentication, encryption, encrypt_loopback, deadline); } else { - s = DoClientNegotiation(conn.get(), authentication, encryption, deadline, + s = DoClientNegotiation(conn.get(), authentication, encryption, encrypt_loopback, deadline, &rpc_error); } diff --git a/src/kudu/rpc/negotiation.h b/src/kudu/rpc/negotiation.h index 9f06c64..8f48e71 100644 --- a/src/kudu/rpc/negotiation.h +++ b/src/kudu/rpc/negotiation.h @@ -47,6 +47,7 @@ class Negotiation { static void RunNegotiation(const scoped_refptr<Connection>& conn, security::RpcAuthentication authentication, security::RpcEncryption encryption, + bool loopback_encryption, MonoTime deadline); private: DISALLOW_IMPLICIT_CONSTRUCTORS(Negotiation); diff --git a/src/kudu/rpc/reactor.cc b/src/kudu/rpc/reactor.cc index 771b9f8..4f276ea 100644 --- a/src/kudu/rpc/reactor.cc +++ b/src/kudu/rpc/reactor.cc @@ -609,10 +609,13 @@ Status ReactorThread::StartConnectionNegotiation(const scoped_refptr<Connection> TRACE("Submitting negotiation task for $0", conn->ToString()); auto authentication = reactor()->messenger()->authentication(); auto encryption = reactor()->messenger()->encryption(); + auto loopback_encryption = reactor()->messenger()->loopback_encryption(); ThreadPool* negotiation_pool = reactor()->messenger()->negotiation_pool(conn->direction()); - RETURN_NOT_OK(negotiation_pool->Submit([conn, authentication, encryption, deadline]() { - Negotiation::RunNegotiation(conn, authentication, encryption, deadline); + RETURN_NOT_OK(negotiation_pool->Submit([conn, authentication, encryption, loopback_encryption, + deadline]() { + Negotiation::RunNegotiation(conn, authentication, encryption, loopback_encryption, + deadline); })); return Status::OK(); } diff --git a/src/kudu/rpc/server_negotiation.cc b/src/kudu/rpc/server_negotiation.cc index 5cf8c42..0f373e5 100644 --- a/src/kudu/rpc/server_negotiation.cc +++ b/src/kudu/rpc/server_negotiation.cc @@ -156,6 +156,7 @@ ServerNegotiation::ServerNegotiation(unique_ptr<Socket> socket, const security::TlsContext* tls_context, const security::TokenVerifier* token_verifier, RpcEncryption encryption, + bool encrypt_loopback, std::string sasl_proto_name) : socket_(std::move(socket)), helper_(SaslHelper::SERVER), @@ -163,6 +164,7 @@ ServerNegotiation::ServerNegotiation(unique_ptr<Socket> socket, tls_handshake_(security::TlsHandshakeType::SERVER), encryption_(encryption), tls_negotiated_(false), + encrypt_loopback_(encrypt_loopback), token_verifier_(token_verifier), negotiated_authn_(AuthenticationType::INVALID), negotiated_mech_(SaslMechanism::INVALID), @@ -304,7 +306,7 @@ Status ServerNegotiation::PreflightCheckGSSAPI(const std::string& sasl_proto_nam // We aren't going to actually send/receive any messages, but // this makes it easier to reuse the initialization code. ServerNegotiation server( - nullptr, nullptr, nullptr, RpcEncryption::OPTIONAL, sasl_proto_name); + nullptr, nullptr, nullptr, RpcEncryption::OPTIONAL, false, sasl_proto_name); Status s = server.EnableGSSAPI(); if (!s.ok()) { return Status::RuntimeError(s.message()); @@ -542,7 +544,7 @@ Status ServerNegotiation::HandleNegotiate(const NegotiatePB& request) { server_features_.insert(TLS); // If the remote peer is local, then we allow using TLS for authentication // without encryption or integrity. - if (socket_->IsLoopbackConnection() && !FLAGS_rpc_encrypt_loopback_connections) { + if (socket_->IsLoopbackConnection() && !encrypt_loopback_) { server_features_.insert(TLS_AUTHENTICATION_ONLY); } } diff --git a/src/kudu/rpc/server_negotiation.h b/src/kudu/rpc/server_negotiation.h index 021f55d..6f22798 100644 --- a/src/kudu/rpc/server_negotiation.h +++ b/src/kudu/rpc/server_negotiation.h @@ -66,6 +66,7 @@ class ServerNegotiation { const security::TlsContext* tls_context, const security::TokenVerifier* token_verifier, security::RpcEncryption encryption, + bool encrypt_loopback, std::string sasl_proto_name); // Enable PLAIN authentication. @@ -229,6 +230,7 @@ class ServerNegotiation { security::TlsHandshake tls_handshake_; const security::RpcEncryption encryption_; bool tls_negotiated_; + bool encrypt_loopback_; // TSK state. const security::TokenVerifier* token_verifier_;
