Skip to content

Commit

Permalink
tls: refactored EvaluateCleartextBareosHello
Browse files Browse the repository at this point in the history
- read out the client name and resource type
  • Loading branch information
franku committed Nov 15, 2018
1 parent f58de90 commit 2467bad
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 16 deletions.
21 changes: 16 additions & 5 deletions core/src/lib/bsock.cc
Expand Up @@ -596,15 +596,26 @@ bool BareosSocket::AuthenticateInboundConnection(JobControlRecord *jcr,
return TwoWayAuthenticate(jcr, what, identity, password, tls_resource, true);
}

bool BareosSocket::EvaluateCleartextBareosHello(bool &cleartext) const
bool BareosSocket::EvaluateCleartextBareosHello(const QualifiedResourceNameTypeConverter &converter,
bool &cleartext,
std::string &client_name,
uint32_t &r_code) const
{
char buffer[12];
char buffer[256];
memset(buffer, 0, sizeof(buffer));
int ret = ::recv(fd_, buffer, 10, MSG_PEEK);
if (ret == 10) {
int ret = ::recv(fd_, buffer, 255, MSG_PEEK);
if (ret >= 10) {
std::string hello("Hello ");
std::string received(&buffer[4]);
cleartext = hello == received ? true : false;
cleartext = received.compare(0, hello.size(), hello) == 0;
if (cleartext) {
std::string name;
uint32_t code;
if (GetNameAndResourceTypeFromHello(buffer, converter, name, code)) {
client_name = name;
r_code = code;
}
}
return true;
}
return false;
Expand Down
6 changes: 5 additions & 1 deletion core/src/lib/bsock.h
Expand Up @@ -48,6 +48,7 @@ struct btimer_t; /* forward reference */
class BareosSocket;
class Tls;
class BStringList;
class QualifiedResourceNameTypeConverter;
btimer_t *StartBsockTimer(BareosSocket *bs, uint32_t wait);
void StopBsockTimer(btimer_t *wid);

Expand Down Expand Up @@ -185,7 +186,10 @@ class BareosSocket : public SmartAlloc {
void ClearLocking(); /* in bsock.c */
void SetSourceAddress(dlist *src_addr_list);
void ControlBwlimit(int bytes); /* in bsock.c */
bool EvaluateCleartextBareosHello(bool &cleartext) const;
bool EvaluateCleartextBareosHello(const QualifiedResourceNameTypeConverter &converter,
bool &cleartext,
std::string &client_name,
uint32_t &r_code) const;
void OutputCipherMessageString(std::function<void(const char *)>);
void GetCipherMessageString(std::string &str);
bool ReceiveAndEvaluateResponseMessage(uint32_t &id_out, BStringList &args_out);
Expand Down
10 changes: 9 additions & 1 deletion core/src/lib/try_tls_handshake_as_a_server.cc
Expand Up @@ -27,7 +27,15 @@
static bool CheckForCleartextConnection(BareosSocket *bs, ConfigurationParser *config, bool &do_cleartext)
{
bool cleartext_requested;
if (!bs->EvaluateCleartextBareosHello(cleartext_requested)) {
std::string client_name;
uint32_t r_code;

QualifiedResourceNameTypeConverter *converter = config->GetQualifiedResourceNameTypeConverter();
if (!converter) { return false; }
if (!bs->EvaluateCleartextBareosHello(*converter,
cleartext_requested,
client_name,
r_code)) {
Dmsg0(100, "Could not read out cleartext hello\n");
return false;
}
Expand Down
65 changes: 57 additions & 8 deletions core/src/lib/util.cc
Expand Up @@ -29,6 +29,10 @@
#include "include/jcr.h"
#include "lib/edit.h"
#include "lib/ascii_control_characters.h"
#include "lib/bstringlist.h"
#include "lib/qualified_resource_name_type_converter.h"

#include <algorithm>

/*
* Various BAREOS Utility subroutines
Expand Down Expand Up @@ -179,17 +183,62 @@ void UnbashSpaces(PoolMem &pm)
}
}

void SwapSeparatorsInString(std::string &str,
char separator,
char new_separator)
struct HelloInformation {
std::string hello_string;
std::string resource_type_string;
uint32_t position_of_name;
};

static std::list<HelloInformation> hello_list {
/* this order is important */
{ "Hello Storage calling start Job", "R_JOB", 5 },
{ "Hello Start Storage Job", "R_JOB", 4 },
{ "Hello Start Job", "R_JOB", 3 },
{ "Hello Director", "R_DIRECTOR", 2 },
{ "Hello Storage", "R_STORAGE", 2 },
{ "Hello Client", "R_CLIENT", 2 },
{ "Hello", "R_CONSOLE", 1 }
};

bool GetNameAndResourceTypeFromHello(const char *input,
const QualifiedResourceNameTypeConverter &converter,
std::string &name,
uint32_t &r_type)
{
std::string::iterator it = str.begin();
while( it != str.end() ) {
if (*it == separator) {
*it = new_separator;
bool ok = false;

std::string s(input);

std::list<HelloInformation>::const_iterator hello = hello_list.cbegin();

bool found = false;
while (hello != hello_list.cend()) {
uint32_t size = hello->hello_string.size();
if (s.size() >= size ) {
if (!s.compare(0, size, hello->hello_string)) {
found = true;
break;
}
}
it++;
hello++;
}

if (!found) {
Dmsg1(100, "Client information not found: %s", s.c_str());
return false;
}

BStringList args(s, ' '); /* split at blanks */

if (args.size() >= hello->position_of_name) {
name = args[hello->position_of_name];
std::replace(name.begin(),name.end(), (char)0x1, ' ');
int r = converter.StringToResourceType(hello->resource_type_string);
if (r < 0) { return false; }
r_type = r;
ok = true;
}
return ok;
}

/*
Expand Down
7 changes: 6 additions & 1 deletion core/src/lib/util.h
Expand Up @@ -23,14 +23,19 @@

#include "lib/ascii_control_characters.h"

class QualifiedResourceNameTypeConverter;

void EscapeString(PoolMem &snew, char *old, int len);
bool IsBufZero(char *buf, int len);
void lcase(char *str);
void BashSpaces(char *str);
void BashSpaces(PoolMem &pm);
void UnbashSpaces(char *str);
void UnbashSpaces(PoolMem &pm);
void SwapSeparatorsInString(std::string &str, char separator = AsciiControlCharacters::RecordSeparator(), char new_separator = ' ');
bool GetNameAndResourceTypeFromHello(const char *input,
const QualifiedResourceNameTypeConverter &converter,
std::string &name,
uint32_t &r_type);
const char* IndentMultilineString(PoolMem &resultbuffer, const char *multilinestring, const char *separator);
char *encode_time(utime_t time, char *buf);
bool ConvertTimeoutToTimespec(timespec &timeout, int timeout_in_seconds);
Expand Down
39 changes: 39 additions & 0 deletions core/src/tests/lib_tests.cc
Expand Up @@ -152,3 +152,42 @@ TEST(BNet, EvaluateResponseMessage_Correct_Id)
const char *m3 {"1001 OK: <director-name> Version: <version>"};
EXPECT_STREQ(args.JoinReadable().c_str(), m3);
}

enum {
R_DIRECTOR = 1, R_CLIENT, R_JOB, R_STORAGE, R_CONSOLE
};

#include "lib/qualified_resource_name_type_converter.h"

static void do_get_name_from_hello_test(const char *client_string_fmt, uint32_t r_type_test)
{
std::map<int, std::string> map{
{R_DIRECTOR, "R_DIRECTOR"}, {R_CLIENT, "R_CLIENT"}, {R_JOB, "R_JOB"}, { R_CONSOLE, "R_CONSOLE" }
};

QualifiedResourceNameTypeConverter converter(map);

char bashed_client_name[20];
const char *t = "Test Client";
sprintf(bashed_client_name, t);
BashSpaces(bashed_client_name);

char output_text[64];
sprintf(output_text, client_string_fmt, bashed_client_name);

std::string name;
uint32_t r_type;

bool ok = GetNameAndResourceTypeFromHello(output_text, converter, name, r_type);

EXPECT_TRUE(ok);
EXPECT_STREQ(name.c_str(), t);
EXPECT_EQ(r_type, r_type_test);
}

TEST(Util, get_name_from_hello_test)
{
do_get_name_from_hello_test("Hello Client %s calling", R_CLIENT);
do_get_name_from_hello_test("Hello Storage calling start Job %s", R_JOB);
do_get_name_from_hello_test("Hello %s", R_CONSOLE);
}

0 comments on commit 2467bad

Please sign in to comment.