From 054a49c5514f0defdf6e44eaf9265c71f88b677e Mon Sep 17 00:00:00 2001 From: Frank Ueberschar Date: Thu, 22 Nov 2018 13:23:39 +0100 Subject: [PATCH] tls handshake: refactored the way a server finds out the handshake mode - introduced ConnectionHandshakeType - special case for R_CLIENT for compatibility with old clients --- core/src/lib/parse_conf.cc | 36 +++++---- core/src/lib/parse_conf.h | 4 +- core/src/lib/try_tls_handshake_as_a_server.cc | 73 ++++++++++++------- 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/core/src/lib/parse_conf.cc b/core/src/lib/parse_conf.cc index 607c8793413..53b6c15b58e 100644 --- a/core/src/lib/parse_conf.cc +++ b/core/src/lib/parse_conf.cc @@ -1013,29 +1013,27 @@ bool ConfigurationParser::GetPathOfNewResource(PoolMem &path, PoolMem &extramsg, return true; } -bool ConfigurationParser::GetCleartextConfigured(const std::string &r_code_str, +bool ConfigurationParser::GetConfiguredTlsPolicy(const std::string &r_code_str, const std::string &name, - bool &cleartext) const + TlsPolicy &tls_policy) const { - TlsResource *own_tls_resource = reinterpret_cast(GetNextRes(r_own_, nullptr)); - if (!own_tls_resource) { - Dmsg1(100, "Could not find own tls resource: %d\n", r_own_); - return false; - } - - uint32_t r_code = qualified_resource_name_type_converter_->StringToResourceType(r_code_str); - if (r_code < 0) { return false; } - - TlsResource *foreign_tls_resource = reinterpret_cast(GetResWithName(r_code, name.c_str())); - if (!foreign_tls_resource) { - Dmsg2(100, "Could not find foreign tls resource: %d-%s\n", r_code, name.c_str()); - return false; - } - if (name == std::string("*UserAgent*")) { - cleartext = !own_tls_resource->IsTlsConfigured(); + TlsResource *own_tls_resource = reinterpret_cast(GetNextRes(r_own_, nullptr)); + if (!own_tls_resource) { + Dmsg1(100, "Could not find own tls resource: %d\n", r_own_); + return false; + } + tls_policy = own_tls_resource->GetPolicy(); } else { - cleartext = !own_tls_resource->IsTlsConfigured() && !foreign_tls_resource->IsTlsConfigured(); + uint32_t r_code = qualified_resource_name_type_converter_->StringToResourceType(r_code_str); + if (r_code < 0) { return false; } + + TlsResource *foreign_tls_resource = reinterpret_cast(GetResWithName(r_code, name.c_str())); + if (!foreign_tls_resource) { + Dmsg2(100, "Could not find foreign tls resource: %d-%s\n", r_code, name.c_str()); + return false; + } + tls_policy = foreign_tls_resource->GetPolicy(); } return true; } diff --git a/core/src/lib/parse_conf.h b/core/src/lib/parse_conf.h index 4acfcddb623..0017a1981c3 100644 --- a/core/src/lib/parse_conf.h +++ b/core/src/lib/parse_conf.h @@ -508,7 +508,9 @@ class ConfigurationParser { static bool GetTlsPskByFullyQualifiedResourceName(ConfigurationParser *config, const char *fully_qualified_name, std::string &psk); - bool GetCleartextConfigured(const std::string &r_code, const std::string &name, bool &cleartext) const; + bool GetConfiguredTlsPolicy(const std::string &r_code, + const std::string &name, + TlsPolicy &tls_policy) const; private: ConfigurationParser(const ConfigurationParser&) = delete; diff --git a/core/src/lib/try_tls_handshake_as_a_server.cc b/core/src/lib/try_tls_handshake_as_a_server.cc index ffa27407fd1..77ef74fbf71 100644 --- a/core/src/lib/try_tls_handshake_as_a_server.cc +++ b/core/src/lib/try_tls_handshake_as_a_server.cc @@ -24,7 +24,14 @@ #include "lib/bsock_tcp.h" -static bool CheckForCleartextConnection(BareosSocket *bs, ConfigurationParser *config, bool &do_cleartext) +enum class ConnectionHandshakeMode { + PerformTlsHandshake, + PerformCleartextHandshake, + CloseConnection +}; + +static ConnectionHandshakeMode GetHandshakeMode(BareosSocket *bs, + ConfigurationParser *config) { bool cleartext_hello; std::string client_name; @@ -34,42 +41,54 @@ static bool CheckForCleartextConnection(BareosSocket *bs, ConfigurationParser *c client_name, r_code_str)) { Dmsg0(100, "Could not read out cleartext hello\n"); - return false; + return ConnectionHandshakeMode::CloseConnection; } if (cleartext_hello) { - bool cleartext_configured; - if (!config->GetCleartextConfigured(r_code_str, client_name, cleartext_configured)) { + TlsPolicy tls_policy; + if (!config->GetConfiguredTlsPolicy(r_code_str, client_name, tls_policy)) { Dmsg0(100, "Could not read out cleartext configuration\n"); - return false; + return ConnectionHandshakeMode::CloseConnection; } - - if (!cleartext_configured) { - Dmsg0(100, "Client wants cleartext connection but tls is configured\n"); - return false; + if (r_code_str == std::string("R_CLIENT")) { + if (tls_policy == kBnetTlsRequired) { + return ConnectionHandshakeMode::CloseConnection; + } else { /* kBnetTlsNone or kBnetTlsEnabled */ + return ConnectionHandshakeMode::PerformCleartextHandshake; + } + } else { /* not R_CLIENT */ + if (tls_policy == kBnetTlsNone) { + return ConnectionHandshakeMode::PerformCleartextHandshake; + } else { + return ConnectionHandshakeMode::CloseConnection; + } } - do_cleartext = true; - } else { - /* client is unknown, yet; try tls */ - do_cleartext = false; - } - - Dmsg1(100, "Try %s connection\n", do_cleartext ? "cleartext" : "tls"); - return true; + } else { /* !cleartext_hello */ + return ConnectionHandshakeMode::PerformTlsHandshake; + } /* if (cleartext_hello) */ } bool TryTlsHandshakeAsAServer(BareosSocket *bs, ConfigurationParser *config) { - bool cleartext; - if (!CheckForCleartextConnection(bs, config, cleartext)) { - return false; - } + ConnectionHandshakeMode type = GetHandshakeMode(bs, config); + + bool success = false; - if (!cleartext) { - if (!bs->DoTlsHandshakeAsAServer(config)) { - return false; - } + switch(type) { + case ConnectionHandshakeMode::PerformTlsHandshake: + if (bs->DoTlsHandshakeAsAServer(config)) { + success = true; + } + break; + case ConnectionHandshakeMode::PerformCleartextHandshake: + /* do tls handshake later */ + success = true; + break; + default: + case ConnectionHandshakeMode::CloseConnection: + success = false; + break; } - /* cleartext - no Tls Handshake */ - return true; + + return success; }