Skip to content

Commit

Permalink
tls handshake: refactored the way a server finds out the handshake mode
Browse files Browse the repository at this point in the history
- introduced ConnectionHandshakeType
- special case for R_CLIENT for compatibility with old clients
  • Loading branch information
franku committed Nov 22, 2018
1 parent 250c11d commit c854af3
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 47 deletions.
36 changes: 17 additions & 19 deletions core/src/lib/parse_conf.cc
Expand Up @@ -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<TlsResource *>(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<TlsResource *>(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<TlsResource *>(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<TlsResource *>(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;
}
4 changes: 3 additions & 1 deletion core/src/lib/parse_conf.h
Expand Up @@ -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;
Expand Down
73 changes: 46 additions & 27 deletions core/src/lib/try_tls_handshake_as_a_server.cc
Expand Up @@ -24,7 +24,14 @@

#include "lib/bsock_tcp.h"

static bool CheckForCleartextConnection(BareosSocket *bs, ConfigurationParser *config, bool &do_cleartext)
enum class ConnectionHandshakeType {
PerformTlsHandshake,
PerformCleartextHandshake,
CloseConnection
};

static ConnectionHandshakeType GetHandshakeMode(BareosSocket *bs,
ConfigurationParser *config)
{
bool cleartext_hello;
std::string client_name;
Expand All @@ -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 ConnectionHandshakeType::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 ConnectionHandshakeType::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 ConnectionHandshakeType::CloseConnection;
} else { /* kBnetTlsNone or kBnetTlsEnabled */
return ConnectionHandshakeType::PerformCleartextHandshake;
}
} else { /* not R_CLIENT */
if (tls_policy == kBnetTlsNone) {
return ConnectionHandshakeType::PerformCleartextHandshake;
} else {
return ConnectionHandshakeType::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 ConnectionHandshakeType::PerformTlsHandshake;
} /* if (cleartext_hello) */
}

bool TryTlsHandshakeAsAServer(BareosSocket *bs, ConfigurationParser *config)
{
bool cleartext;
if (!CheckForCleartextConnection(bs, config, cleartext)) {
return false;
}
ConnectionHandshakeType type = GetHandshakeMode(bs, config);

bool success = false;

if (!cleartext) {
if (!bs->DoTlsHandshakeAsAServer(config)) {
return false;
}
switch(type) {
case ConnectionHandshakeType::PerformTlsHandshake:
if (bs->DoTlsHandshakeAsAServer(config)) {
success = true;
}
break;
case ConnectionHandshakeType::PerformCleartextHandshake:
/* do tls handshake later */
success = true;
break;
default:
case ConnectionHandshakeType::CloseConnection:
success = false;
break;
}
/* cleartext - no Tls Handshake */
return true;

return success;
}

0 comments on commit c854af3

Please sign in to comment.