Navigation Menu

Skip to content

Commit

Permalink
Merge branch 'bareos-18.2' after release
Browse files Browse the repository at this point in the history
  • Loading branch information
franku committed Sep 25, 2018
2 parents 7b2dd36 + 2c8ea1e commit ae06364
Show file tree
Hide file tree
Showing 29 changed files with 244 additions and 145 deletions.
22 changes: 14 additions & 8 deletions core/src/console/console.cc
Expand Up @@ -889,22 +889,26 @@ BareosSocket *ConnectToDirector(JobControlRecord &jcr, utime_t heart_beat, char
ConsoleOutput("Could not generate qualified resource name\n");
TerminateConsole(0);
return nullptr;
}
}

if (!UA_sock->DoTlsHandshake(TlsConfigBase::BNET_TLS_AUTO, local_tls_resource, false,
int tls_policy = local_tls_resource->tls_psk.IsActivated() || local_tls_resource->tls_cert.IsActivated()
? TlsConfigBase::BNET_TLS_AUTO : TlsConfigBase::BNET_TLS_NONE;

if (!UA_sock->DoTlsHandshake(tls_policy, local_tls_resource, false,
qualified_resource_name.c_str(), password->value, &jcr)) {
ConsoleOutput(errmsg);
TerminateConsole(0);
return nullptr;
}
}

if (!UA_sock->AuthenticateWithDirector(&jcr, name, *password, errmsg, errmsg_len, director_resource)) {
ConsoleOutput(errmsg);
TerminateConsole(0);
return nullptr;
}
}
return UA_sock;
}
}

} /* namespace console */
/*
* Main Bareos Console -- User Interface Program
Expand Down Expand Up @@ -1085,13 +1089,15 @@ int main(int argc, char *argv[])

ConsoleOutput(errmsg);

UA_sock->OutputCipherMessageString(ConsoleOutput);

#if defined(HAVE_PAM)
if (console_resource) { /* not for root console */
if (director_resource && director_resource->UsePamAuthentication_) {
if (!ConsolePamAuthenticate(stdin, UA_sock)) {
TerminateConsole(0);
return 1;
}
TerminateConsole(0);
return 1;
}
}
}
#endif /* HAVE_PAM */
Expand Down
3 changes: 2 additions & 1 deletion core/src/dird/authenticate.cc
Expand Up @@ -33,6 +33,7 @@
#include "include/bareos.h"
#include "dird.h"
#include "dird/fd_cmds.h"
#include "dird/client_connection_handshake_mode.h"
#include "dird/dird_globals.h"
#include "lib/bnet.h"
#include "lib/qualified_resource_name_type_converter.h"
Expand Down Expand Up @@ -131,7 +132,7 @@ bool AuthenticateWithFileDaemon(JobControlRecord *jcr)
BareosSocket *fd = jcr->file_bsock;
ClientResource *client = jcr->res.client;

if (jcr->connection_handshake_try_ == JobControlRecord::ConnectionHandshakeMode::kTlsFirst) {
if (jcr->connection_handshake_try_ == ClientConnectionHandshakeMode::kTlsFirst) {
std::string qualified_resource_name;
if (!my_config->GetQualifiedResourceNameTypeConverter()->ResourceToString(me->hdr.name, my_config->r_own_,
qualified_resource_name)) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/dird/backup.cc
Expand Up @@ -567,7 +567,7 @@ bool DoNativeBackup(JobControlRecord *jcr)
}
} else {

if (jcr->connection_successful_handshake_ != JobControlRecord::ConnectionHandshakeMode::kTlsFirst) {
if (jcr->res.client->connection_successful_handshake_ != ClientConnectionHandshakeMode::kTlsFirst) {
tls_need = GetLocalTlsPolicyFromConfiguration(client);
} else {
tls_need = TlsConfigBase::BNET_TLS_AUTO;
Expand Down
Expand Up @@ -18,14 +18,12 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef BAREOS_DIR_CLIENT_CONNECTION_HANDSHAKE_MODE_H_
#define BAREOS_DIR_CLIENT_CONNECTION_HANDSHAKE_MODE_H_

#ifndef BAREOS_LIB_TLS_CONF_AUTO_H_
#define BAREOS_LIB_TLS_CONF_AUTO_H_
namespace directordaemon {

class TlsConfigAuto : public TlsConfigBase {
public:
TlsConfigAuto() : TlsConfigBase() {}
virtual uint32_t GetPolicy() const override { return BNET_TLS_AUTO; }
};
enum class ClientConnectionHandshakeMode { kUndefined, kTlsFirst, kCleartextFirst, kFailed };

#endif /* BAREOS_LIB_TLS_CONF_AUTO_H_ */
} /* namespace directordaemon */
#endif /* BAREOS_DIR_CLIENT_CONNECTION_HANDSHAKE_MODE_H_ */
30 changes: 12 additions & 18 deletions core/src/dird/dird.cc
Expand Up @@ -742,17 +742,15 @@ static bool CheckResources()
/*
* tls_require implies tls_enable
*/
if (me->tls_cert.require || me->tls_psk.require) {
if (have_tls) {
// me->tls.enable = true;
} else {
Jmsg(NULL, M_FATAL, 0, _("TLS required but not compiled in in BAREOS.\n"));
if (me->tls_cert.IsActivated() || me->tls_psk.IsActivated()) {
if (!have_tls) {
Jmsg(NULL, M_FATAL, 0, _("TLS required but not compiled into BAREOS.\n"));
OK = false;
goto bail_out;
}
}

need_tls = me->tls_cert.enable || me->tls_cert.authenticate;
need_tls = me->tls_cert.IsActivated() || me->tls_cert.authenticate;

if ((me->tls_cert.certfile == nullptr || me->tls_cert.certfile->empty()) && need_tls) {
Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Director \"%s\" in %s.\n"), me->name(),configfile.c_str());
Expand Down Expand Up @@ -819,17 +817,15 @@ static bool CheckResources()
/*
* tls_require implies tls_enable
*/
if (cons->tls_cert.require) {
if (have_tls) {
// cons->tls_cert.enable = true;
} else {
if (cons->tls_cert.IsActivated()) {
if (!have_tls) {
Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in BAREOS.\n"));
OK = false;
goto bail_out;
}
}

need_tls = cons->tls_cert.enable || cons->tls_cert.authenticate;
need_tls = cons->tls_cert.IsActivated() || cons->tls_cert.authenticate;

if ((cons->tls_cert.certfile == nullptr || cons->tls_cert.certfile->empty()) && need_tls) {
Jmsg(NULL, M_FATAL, 0, _("\"TLS Certificate\" file not defined for Console \"%s\" in %s.\n"),
Expand Down Expand Up @@ -874,16 +870,14 @@ static bool CheckResources()
/*
* tls_require implies tls_enable
*/
if (client->tls_cert.require) {
if (have_tls) {
// client->tls_cert.enable = true;
} else {
if (client->tls_cert.IsActivated()) {
if (!have_tls) {
Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured.\n"));
OK = false;
goto bail_out;
}
}
need_tls = client->tls_cert.enable || client->tls_cert.authenticate;
need_tls = client->tls_cert.IsActivated() || client->tls_cert.authenticate;
if ((client->tls_cert.CaCertfile == nullptr || client->tls_cert.CaCertfile->empty()) &&
(client->tls_cert.CaCertdir == nullptr || client->tls_cert.CaCertdir->empty()) && need_tls) {
Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
Expand All @@ -902,7 +896,7 @@ static bool CheckResources()
/*
* tls_require implies tls_enable
*/
if (store->tls_cert.require) {
if (store->tls_cert.IsActivated()) {
if (have_tls) {
// store->tls.enable = true;
} else {
Expand All @@ -912,7 +906,7 @@ static bool CheckResources()
}
}

need_tls = store->tls_cert.enable || store->tls_cert.authenticate;
need_tls = store->tls_cert.IsActivated() || store->tls_cert.authenticate;

if ((store->tls_cert.CaCertfile == nullptr || store->tls_cert.CaCertfile->empty()) &&
(store->tls_cert.CaCertdir == nullptr || store->tls_cert.CaCertdir->empty()) && need_tls) {
Expand Down
16 changes: 15 additions & 1 deletion core/src/dird/dird_conf.cc
Expand Up @@ -3794,6 +3794,18 @@ static void PrintConfigCb(ResourceItem *items, int i, PoolMem &cfg_str, bool hid
}
}

static void ResetAllClientConnectionHandshakeModes(ConfigurationParser &my_config)
{
CommonResourceHeader *header = nullptr;
do {
header = my_config.GetNextRes(R_CLIENT, header);
ClientResource *client = reinterpret_cast<ClientResource*>(header);
if (client) {
client->connection_successful_handshake_ = ClientConnectionHandshakeMode::kUndefined;
}
} while (header);
}

static void ConfigReadyCallback(ConfigurationParser &my_config)
{
CreateAndAddUserAgentConsoleResource(my_config);
Expand All @@ -3805,6 +3817,8 @@ static void ConfigReadyCallback(ConfigurationParser &my_config)
{R_MSGS, "R_MSGS"}, {R_COUNTER, "R_COUNTER"}, {R_PROFILE, "R_PROFILE"},
{R_CONSOLE, "R_CONSOLE"}, {R_DEVICE, "R_DEVICE"}};
my_config.InitializeQualifiedResourceNameTypeConverter(map);

ResetAllClientConnectionHandshakeModes(my_config);
}

static bool AddResourceCopyToEndOfChain(UnionOfResources *res_to_add, int type)
Expand Down Expand Up @@ -3852,7 +3866,7 @@ static void CreateAndAddUserAgentConsoleResource(ConfigurationParser &my_config)
memset(&console, 0, sizeof(console));
console.password.encoding = dir_resource->password.encoding;
console.password.value = bstrdup(dir_resource->password.value);
console.tls_psk.enable = true;
console.tls_psk.enable_ = true;
console.hdr.name = bstrdup("*UserAgent*");
console.hdr.desc = bstrdup("root console definition");
console.hdr.rcode = 1013;
Expand Down
4 changes: 4 additions & 0 deletions core/src/dird/dird_conf.h
Expand Up @@ -31,6 +31,8 @@
#define BAREOS_DIRD_DIRD_CONF_H_
/* NOTE: #includes at the end of this file */

#include "dird/client_connection_handshake_mode.h"

namespace directordaemon {

static std::string default_config_filename("bareos-dir.conf");
Expand Down Expand Up @@ -279,6 +281,8 @@ class ClientResource: public TlsResource {
bool ndmp_use_lmdb; /* NDMP Protocol specific use LMDB for the FHDB or not */
int64_t max_bandwidth; /* Limit speed on this client */
runtime_client_status_t *rcs; /* Runtime Client Status */
ClientConnectionHandshakeMode connection_successful_handshake_;

ClientResource() : TlsResource() {}
};

Expand Down
91 changes: 74 additions & 17 deletions core/src/dird/fd_cmds.cc
Expand Up @@ -159,16 +159,70 @@ static bool connect_outbound_to_file_daemon(JobControlRecord *jcr, int retry_int
return result;
}

bool ConnectToFileDaemon(JobControlRecord *jcr, int retry_interval, int max_retry_time, bool verbose)
static void OutputMessageForConnectionTry(JobControlRecord *jcr, UaContext *ua)
{
std::string m;

if (jcr->res.client->connection_successful_handshake_ == ClientConnectionHandshakeMode::kUndefined
|| jcr->res.client->connection_successful_handshake_ == ClientConnectionHandshakeMode::kFailed) {
m = "\nTry to establish a secure connection by ";
} else {
m = "\nUsing previously recognized ";
}

switch (jcr->connection_handshake_try_) {
case ClientConnectionHandshakeMode::kTlsFirst:
m += "immediate TLS handshake: ";
break;
case ClientConnectionHandshakeMode::kCleartextFirst:
m += "cleartext handshake: ";
break;
default:
m += "unknown mode\n";
break;
}

Jmsg(jcr, M_INFO, 0, m.c_str());
if (ua) {
ua->SendMsg(m.c_str());
}
}

static void SendInfoChosenCipher(JobControlRecord *jcr, UaContext *ua)
{
std::string str;
jcr->file_bsock->GetCipherMessageString(str);
Jmsg(jcr, M_INFO, 0, str.c_str());
if (ua) { /* only whith console connection */
ua->SendRawMsg(str.c_str());
}
}

static void SendInfoFailed(JobControlRecord *jcr, UaContext *ua)
{
Jmsg(jcr, M_INFO, 0, "Failed");
if (ua) { /* only whith console connection */
ua->SendRawMsg("Failed");
}
}

bool ConnectToFileDaemon(JobControlRecord *jcr, int retry_interval, int max_retry_time, bool verbose,
UaContext *ua)
{
bool success = false;
bool tcp_connect_failed = false;
int connect_tries = 3; /* as a finish-hook for the UseWaitingClient mechanism */

/* try the connection mode in case a client that cannot do Tls
* immediately without cleartext md5-handshake first */
jcr->connection_handshake_try_ = JobControlRecord::ConnectionHandshakeMode::kTlsFirst;
jcr->connection_successful_handshake_ = JobControlRecord::ConnectionHandshakeMode::kUndefined;
/* try the connection modes starting with tls directly,
* in case there is a client that cannot do Tls immediately then
* fall back to cleartext md5-handshake */
if (jcr->res.client->connection_successful_handshake_ == ClientConnectionHandshakeMode::kUndefined
|| jcr->res.client->connection_successful_handshake_ == ClientConnectionHandshakeMode::kFailed) {
jcr->connection_handshake_try_ = ClientConnectionHandshakeMode::kTlsFirst;
} else {
/* if there is a stored mode from a previous connection then use this */
jcr->connection_handshake_try_ = jcr->res.client->connection_successful_handshake_;
}

do { /* while (tcp_connect_failed ...) */
/* connect the tcp socket */
Expand All @@ -182,32 +236,35 @@ bool ConnectToFileDaemon(JobControlRecord *jcr, int retry_interval, int max_retr
}
}

/* try to establish tls and authenticate the daemon */
OutputMessageForConnectionTry(jcr, ua);

if (jcr->file_bsock) {
jcr->setJobStatus(JS_Running);
if (AuthenticateWithFileDaemon(jcr)) {
success = true;
jcr->connection_successful_handshake_ = jcr->connection_handshake_try_;
SendInfoChosenCipher(jcr, ua);
jcr->res.client->connection_successful_handshake_ = jcr->connection_handshake_try_;
} else {
/* authentication failed due to
* - tls mismatch or
* - if an old client cannot do tls- before md5-handshake
* */
switch(jcr->connection_handshake_try_) {
case JobControlRecord::ConnectionHandshakeMode::kTlsFirst:
case ClientConnectionHandshakeMode::kTlsFirst:
if (jcr->file_bsock) {
jcr->file_bsock->close();
delete jcr->file_bsock;
jcr->file_bsock = nullptr;
}
SendInfoFailed(jcr, ua);
jcr->resetJobStatus(JS_Running);
jcr->connection_handshake_try_ = JobControlRecord::ConnectionHandshakeMode::kCleartextFirst;
jcr->connection_handshake_try_ = ClientConnectionHandshakeMode::kCleartextFirst;
break;
case JobControlRecord::ConnectionHandshakeMode::kCleartextFirst:
jcr->connection_handshake_try_ = JobControlRecord::ConnectionHandshakeMode::kFailed;
case ClientConnectionHandshakeMode::kCleartextFirst:
jcr->connection_handshake_try_ = ClientConnectionHandshakeMode::kFailed;
break;
case JobControlRecord::ConnectionHandshakeMode::kFailed:
default: /* should bei one of class ConnectionHandshakeMode */
case ClientConnectionHandshakeMode::kFailed:
default: /* should bei one of class ClientConnectionHandshakeMode */
ASSERT(false);
break;
}
Expand All @@ -218,7 +275,7 @@ bool ConnectToFileDaemon(JobControlRecord *jcr, int retry_interval, int max_retr
connect_tries--;
} while (!tcp_connect_failed && connect_tries
&& !success
&& jcr->connection_handshake_try_ != JobControlRecord::ConnectionHandshakeMode::kFailed);
&& jcr->connection_handshake_try_ != ClientConnectionHandshakeMode::kFailed);

if (!success) {
jcr->setJobStatus(JS_ErrorTerminated);
Expand Down Expand Up @@ -1095,7 +1152,7 @@ bool CancelFileDaemonJob(UaContext *ua, JobControlRecord *jcr)
BareosSocket *fd;

ua->jcr->res.client = jcr->res.client;
if (!ConnectToFileDaemon(ua->jcr, 10, me->FDConnectTimeout, true)) {
if (!ConnectToFileDaemon(ua->jcr, 10, me->FDConnectTimeout, true, ua)) {
ua->ErrorMsg(_("Failed to connect to File daemon.\n"));
return false;
}
Expand Down Expand Up @@ -1134,7 +1191,7 @@ void DoNativeClientStatus(UaContext *ua, ClientResource *client, char *cmd)
client->name(), client->address, client->FDport);
}

if (!ConnectToFileDaemon(ua->jcr, 1, 15, false)) {
if (!ConnectToFileDaemon(ua->jcr, 1, 15, false, ua)) {
ua->SendMsg(_("Failed to connect to Client %s.\n====\n"),
client->name());
if (ua->jcr->file_bsock) {
Expand Down Expand Up @@ -1185,7 +1242,7 @@ void DoClientResolve(UaContext *ua, ClientResource *client)
client->name(), client->address, client->FDport);
}

if (!ConnectToFileDaemon(ua->jcr, 1, 15, false)) {
if (!ConnectToFileDaemon(ua->jcr, 1, 15, false, ua)) {
ua->SendMsg(_("Failed to connect to Client %s.\n====\n"),
client->name());
if (ua->jcr->file_bsock) {
Expand Down
3 changes: 2 additions & 1 deletion core/src/dird/fd_cmds.h
Expand Up @@ -24,7 +24,8 @@

namespace directordaemon {

bool ConnectToFileDaemon(JobControlRecord *jcr, int retry_interval, int max_retry_time, bool verbose);
bool ConnectToFileDaemon(JobControlRecord *jcr, int retry_interval, int max_retry_time, bool verbose,
UaContext *ua = nullptr);
int SendJobInfo(JobControlRecord *jcr);
bool SendIncludeList(JobControlRecord *jcr);
bool SendExcludeList(JobControlRecord *jcr);
Expand Down

0 comments on commit ae06364

Please sign in to comment.