Skip to content

Commit

Permalink
bsock: added an extra unique pointer for tls initialization
Browse files Browse the repository at this point in the history
- added unique_ptr tls_conn_init that is used during tls initialization and handshake
  to hold the pointer to the Tls implementation
- upen successful initialization this pointer will be moved to the shared_ptr tls_conn
- tls_conn is used from the send and receive routines
- BareosSocket::mutex_ is used for thread safeness
  • Loading branch information
franku committed Sep 18, 2018
1 parent 988bcfa commit d7acc84
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 45 deletions.
20 changes: 14 additions & 6 deletions core/src/lib/bnet.cc
Expand Up @@ -122,24 +122,28 @@ bool BnetTlsServer(BareosSocket *bsock, const std::vector<std::string> &verify_l
{
JobControlRecord *jcr = bsock->jcr();

if (!bsock->tls_conn) {
if (!bsock->tls_conn_init) {
Dmsg0(100, "No Tsl Connection: Cannot call TlsBsockAccept\n");
}

if (!bsock->tls_conn->TlsBsockAccept(bsock)) {
if (!bsock->tls_conn_init->TlsBsockAccept(bsock)) {
Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
goto err;
}

if (!verify_list.empty()) {
if (!bsock->tls_conn->TlsPostconnectVerifyCn(jcr, verify_list)) {
if (!bsock->tls_conn_init->TlsPostconnectVerifyCn(jcr, verify_list)) {
Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
" Peer certificate did not match a required commonName\n"),
bsock->host());
goto err;
}
}

bsock->LockMutex();
bsock->tls_conn = std::move(bsock->tls_conn_init);
bsock->UnlockMutex();

Dmsg0(50, "TLS server negotiation established.\n");
return true;

Expand All @@ -157,7 +161,7 @@ bool BnetTlsClient(BareosSocket *bsock, bool VerifyPeer, const std::vector<std::
{
JobControlRecord *jcr = bsock->jcr();

if (!bsock->tls_conn->TlsBsockConnect(bsock)) {
if (!bsock->tls_conn_init->TlsBsockConnect(bsock)) {
goto err;
}

Expand All @@ -167,21 +171,25 @@ bool BnetTlsClient(BareosSocket *bsock, bool VerifyPeer, const std::vector<std::
* certificate's CN. Otherwise, we use standard host/CN matching.
*/
if (!verify_list.empty()) {
if (!bsock->tls_conn->TlsPostconnectVerifyCn(jcr, verify_list)) {
if (!bsock->tls_conn_init->TlsPostconnectVerifyCn(jcr, verify_list)) {
Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
" Peer certificate did not match a required commonName\n"),
bsock->host());
goto err;
}
} else {
if (!bsock->tls_conn->TlsPostconnectVerifyHost(jcr, bsock->host())) {
if (!bsock->tls_conn_init->TlsPostconnectVerifyHost(jcr, bsock->host())) {
Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host name \"%s\" did not match presented certificate\n"),
bsock->host());
goto err;
}
}
}

bsock->LockMutex();
bsock->tls_conn = std::move(bsock->tls_conn_init);
bsock->UnlockMutex();

Dmsg0(50, "TLS client negotiation established.\n");
return true;

Expand Down
83 changes: 51 additions & 32 deletions core/src/lib/bsock.cc
Expand Up @@ -125,10 +125,15 @@ BareosSocket::~BareosSocket() { Dmsg0(100, "Destruct BareosSocket\n"); }

void BareosSocket::CloseTlsConnectionAndFreeMemory()
{
if (tls_conn) {
LockMutex();
if (tls_conn && !tls_conn_init) {
tls_conn->TlsBsockShutdown(this);
tls_conn.reset();
} else if (tls_conn_init) {
tls_conn_init->TlsBsockShutdown(this);
tls_conn_init.reset();
}
UnlockMutex();
}

/**
Expand Down Expand Up @@ -167,6 +172,20 @@ void BareosSocket::ClearLocking()
if (mutex_) { mutex_.reset(); }
}

void BareosSocket::LockMutex()
{
if (mutex_) {
mutex_->lock();
}
}

void BareosSocket::UnlockMutex()
{
if (mutex_) {
mutex_->unlock();
}
}

/**
* Send a signal
*/
Expand Down Expand Up @@ -400,28 +419,28 @@ bool BareosSocket::DoTlsHandshakeAsAServer(ConfigurationParser *config, JobContr
if (!DoTlsHandshakeWithClient(&tls_resource->tls_cert, jcr)) { return false; }

if (tls_resource->tls_cert.GetAuthenticate()) { /* tls authentication only? */
tls_conn->TlsBsockShutdown(this);
tls_conn_init->TlsBsockShutdown(this);
CloseTlsConnectionAndFreeMemory(); /* yes, shutdown tls */
}

return true;
}

void BareosSocket::ParameterizeTlsCert(Tls *tls_conn, TlsResource *tls_resource)
void BareosSocket::ParameterizeTlsCert(Tls *tls_conn_init, TlsResource *tls_resource)
{
if (tls_resource->tls_cert.enabled) {
const std::string empty;
tls_conn->SetCaCertfile(tls_resource->tls_cert.CaCertfile ? *tls_resource->tls_cert.CaCertfile : empty);
tls_conn->SetCaCertdir(tls_resource->tls_cert.CaCertdir ? *tls_resource->tls_cert.CaCertdir : empty);
tls_conn->SetCrlfile(tls_resource->tls_cert.crlfile ? *tls_resource->tls_cert.crlfile : empty);
tls_conn->SetCertfile(tls_resource->tls_cert.certfile ? *tls_resource->tls_cert.certfile : empty);
tls_conn->SetKeyfile(tls_resource->tls_cert.keyfile ? *tls_resource->tls_cert.keyfile : empty);
// tls_conn->SetPemCallback(TlsPemCallback); Ueb: --> Console Callback
tls_conn->SetPemUserdata(tls_resource->tls_cert.pem_message);
tls_conn->SetDhFile(tls_resource->tls_cert.dhfile ? *tls_resource->tls_cert.dhfile
tls_conn_init->SetCaCertfile(tls_resource->tls_cert.CaCertfile ? *tls_resource->tls_cert.CaCertfile : empty);
tls_conn_init->SetCaCertdir(tls_resource->tls_cert.CaCertdir ? *tls_resource->tls_cert.CaCertdir : empty);
tls_conn_init->SetCrlfile(tls_resource->tls_cert.crlfile ? *tls_resource->tls_cert.crlfile : empty);
tls_conn_init->SetCertfile(tls_resource->tls_cert.certfile ? *tls_resource->tls_cert.certfile : empty);
tls_conn_init->SetKeyfile(tls_resource->tls_cert.keyfile ? *tls_resource->tls_cert.keyfile : empty);
// tls_conn_init->SetPemCallback(TlsPemCallback); Ueb: --> Console Callback
tls_conn_init->SetPemUserdata(tls_resource->tls_cert.pem_message);
tls_conn_init->SetDhFile(tls_resource->tls_cert.dhfile ? *tls_resource->tls_cert.dhfile
: empty); /* Ueb: was never used before */
tls_conn->SetCipherList(tls_resource->tls_cert.cipherlist ? *tls_resource->tls_cert.cipherlist : empty);
tls_conn->SetVerifyPeer(tls_resource->tls_cert.VerifyPeer);
tls_conn_init->SetCipherList(tls_resource->tls_cert.cipherlist ? *tls_resource->tls_cert.cipherlist : empty);
tls_conn_init->SetVerifyPeer(tls_resource->tls_cert.VerifyPeer);
}
}

Expand All @@ -432,22 +451,22 @@ bool BareosSocket::ParameterizeAndInitTlsConnectionAsAServer(ConfigurationParser
if (!tls_resource->tls_cert.enabled && !tls_resource->tls_psk.enabled) {
return true; /* cleartext connection */
}
tls_conn.reset(Tls::CreateNewTlsContext(Tls::TlsImplementationType::kTlsOpenSsl));
if (!tls_conn) {
tls_conn_init.reset(Tls::CreateNewTlsContext(Tls::TlsImplementationType::kTlsOpenSsl));
if (!tls_conn_init) {
Qmsg0(BareosSocket::jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
return false;
}

tls_conn->SetTcpFileDescriptor(fd_);
tls_conn_init->SetTcpFileDescriptor(fd_);

ParameterizeTlsCert(tls_conn.get(), tls_resource);
ParameterizeTlsCert(tls_conn_init.get(), tls_resource);

if (tls_resource->tls_psk.enabled) {
tls_conn->SetTlsPskServerContext(config, config->GetTlsPskByFullyQualifiedResourceName);
tls_conn_init->SetTlsPskServerContext(config, config->GetTlsPskByFullyQualifiedResourceName);
}

if (!tls_conn->init()) {
tls_conn.reset();
if (!tls_conn_init->init()) {
tls_conn_init.reset();
return false;
}
return true;
Expand Down Expand Up @@ -480,13 +499,13 @@ bool BareosSocket::DoTlsHandshake(uint32_t remote_tls_policy,
}

if (selected_local_tls->GetAuthenticate()) { /* tls authentication only? */
tls_conn->TlsBsockShutdown(this);
tls_conn_init->TlsBsockShutdown(this);
CloseTlsConnectionAndFreeMemory(); /* yes, shutdown tls */
}
}
if (!initiated_by_remote) {
if (tls_conn) {
tls_conn->TlsLogConninfo(jcr, host(), port(), who());
if (tls_conn_init) {
tls_conn_init->TlsLogConninfo(jcr, host(), port(), who());
} else {
Qmsg(jcr, M_INFO, 0, _("Cleartext connection to %s at %s:%d established\n"), who(), host(), port());
}
Expand All @@ -501,25 +520,25 @@ bool BareosSocket::ParameterizeAndInitTlsConnection(TlsResource *tls_resource,
{
if (!tls_resource->tls_cert.enabled && !tls_resource->tls_psk.enabled) { return true; }

tls_conn.reset(Tls::CreateNewTlsContext(Tls::TlsImplementationType::kTlsOpenSsl));
if (!tls_conn) {
tls_conn_init.reset(Tls::CreateNewTlsContext(Tls::TlsImplementationType::kTlsOpenSsl));
if (!tls_conn_init) {
Qmsg0(BareosSocket::jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
return false;
}

tls_conn->SetTcpFileDescriptor(fd_);
tls_conn_init->SetTcpFileDescriptor(fd_);

ParameterizeTlsCert(tls_conn.get(), tls_resource);
ParameterizeTlsCert(tls_conn_init.get(), tls_resource);

if (tls_resource->tls_psk.enabled) {
if (!initiated_by_remote) {
const PskCredentials psk_cred(identity, password);
tls_conn->SetTlsPskClientContext(psk_cred);
tls_conn_init->SetTlsPskClientContext(psk_cred);
}
}

if (!tls_conn->init()) {
tls_conn.reset();
if (!tls_conn_init->init()) {
tls_conn_init.reset();
return false;
}
return true;
Expand All @@ -535,7 +554,7 @@ bool BareosSocket::DoTlsHandshakeWithClient(TlsConfigBase *selected_local_tls, J
if (BnetTlsServer(this, verify_list)) {
return true;
}
tls_conn.reset();
tls_conn_init.reset();
Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
Dmsg0(debuglevel, "TLS negotiation failed.\n");
return false;
Expand All @@ -550,7 +569,7 @@ bool BareosSocket::DoTlsHandshakeWithServer(TlsConfigBase *selected_local_tls,
selected_local_tls->AllowedCertificateCommonNames())) {
return true;
}
tls_conn.reset();
tls_conn_init.reset();
Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
Dmsg0(debuglevel, "TLS negotiation failed.\n");
return false;
Expand Down
3 changes: 3 additions & 0 deletions core/src/lib/bsock.h
Expand Up @@ -75,6 +75,7 @@ class BareosSocket : public SmartAlloc {
void SetTlsEstablished() { tls_established_ = true; }
bool TlsEstablished() const { return tls_established_; }
std::shared_ptr<Tls> tls_conn; /* Associated tls connection */
std::unique_ptr<Tls> tls_conn_init; /* during initialization */

protected:
JobControlRecord *jcr_; /* JobControlRecord or NULL for error msgs */
Expand Down Expand Up @@ -242,6 +243,8 @@ class BareosSocket : public SmartAlloc {
void SetTerminated() { terminated_ = true; }
void StartTimer(int sec) { tid_ = StartBsockTimer(this, sec); }
void StopTimer() { StopBsockTimer(tid_); }
void LockMutex();
void UnlockMutex();
};

/**
Expand Down
10 changes: 3 additions & 7 deletions core/src/lib/bsock_tcp.cc
Expand Up @@ -467,9 +467,7 @@ bool BareosSocketTCP::send()
return false;
}

if (mutex_) {
mutex_->lock();
}
LockMutex();

/*
* Compute total packet length
Expand Down Expand Up @@ -506,9 +504,7 @@ bool BareosSocketTCP::send()
}
}

if (mutex_) {
mutex_->unlock();
}
UnlockMutex();

return ok;
}
Expand Down Expand Up @@ -913,7 +909,7 @@ void BareosSocketTCP::close()
if (!cloned_) {
ClearLocking();

if (tls_conn) {
if (tls_conn || tls_conn_init) {
CloseTlsConnectionAndFreeMemory();
}
}
Expand Down

0 comments on commit d7acc84

Please sign in to comment.