Skip to content

Commit

Permalink
dir: moved console-authenticate code into separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
franku committed Nov 5, 2018
1 parent 9b39d9f commit 6c827b5
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 186 deletions.
3 changes: 2 additions & 1 deletion core/src/dird/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
set(DIRDSRCS dird.cc)

#DIRD_OBJECTS_SRCS also used in a separate library for unittests
set(DIRD_OBJECTS_SRCS admin.cc archive.cc authenticate.cc autoprune.cc backup.cc bsr.cc catreq.cc
set(DIRD_OBJECTS_SRCS admin.cc archive.cc authenticate.cc authenticate_console.cc
autoprune.cc backup.cc bsr.cc catreq.cc
consolidate.cc dird_globals.cc dir_plugins.cc dird_conf.cc expand.cc fd_cmds.cc
getmsg.cc inc_conf.cc job.cc jobq.cc migrate.cc mountreq.cc msgchan.cc
ndmp_dma_storage.cc
Expand Down
185 changes: 0 additions & 185 deletions core/src/dird/authenticate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,189 +216,4 @@ bool AuthenticateFileDaemon(BareosSocket *fd, char *client_name)

return true;
}

static bool NumberOfConsoleConnectionsExceeded()
{
JobControlRecord *jcr;
unsigned int cnt = 0;

foreach_jcr(jcr)
{
if (jcr->is_JobType(JT_CONSOLE)) { cnt++; }
}
endeach_jcr(jcr);

return (cnt >= me->MaxConsoleConnections) ? true : false;
}

static bool GetConsoleName(BareosSocket *ua_sock, std::string &name)
{
char buffer[MAX_NAME_LENGTH]; /* zero terminated C-string */

if (sscanf(ua_sock->msg, "Hello %127s calling\n", buffer) != 1) {
Emsg4(M_ERROR, 0, _("UA Hello from %s:%s:%d is invalid. Got: %s\n"), ua_sock->who(), ua_sock->host(), ua_sock->port(),
ua_sock->msg);
return false;
}
UnbashSpaces(buffer);
name = buffer;
return true;
}

static void LogErrorMessage(std::string console_name, UaContext *ua)
{
Emsg4(M_ERROR, 0, _("Unable to authenticate console \"%s\" at %s:%s:%d.\n"), console_name.c_str(),
ua->UA_sock->who(), ua->UA_sock->host(), ua->UA_sock->port());
}

static void SendOkMessage(UaContext *ua, bool final_state)
{
if (final_state) {
char buffer[128];
::snprintf(buffer, 100, "OK: %s Version: %s (%s)", my_name, VERSION, BDATE);
ua->UA_sock->FormatAndSendResponseMessage(kMessageIdOk, std::string(buffer));
} else if (ua->cons && ua->cons->use_pam_authentication_) {
ua->UA_sock->FormatAndSendResponseMessage(kMessageIdPamRequired, std::string());
}
}

static bool OptionalAuthenticateRootConsole(std::string console_name, UaContext *ua, bool &auth_success)
{
const std::string root_console_name { "*UserAgent*" };
if (console_name != root_console_name) {
return false; /* no need to evaluate auth_success */
}
auth_success = ua->UA_sock->AuthenticateInboundConnection(NULL, "Console", root_console_name.c_str(), me->password, me);
return true;
}

static void AuthenticateNamedConsole(std::string console_name, UaContext *ua, bool &auth_success)
{
ConsoleResource *cons;
cons = (ConsoleResource *)my_config->GetResWithName(R_CONSOLE, console_name.c_str());
if (!cons) { /* if console resource cannot be obtained is treated as an error */
auth_success = false;
return;
}
if (!ua->UA_sock->AuthenticateInboundConnection(NULL, "Console", console_name.c_str(), cons->password, cons)) {
ua->cons = nullptr;
auth_success = false;
} else {
ua->cons = cons;
auth_success = true;
}
}

static bool OptionalAuthenticatePamUser(std::string console_name, UaContext *ua, bool &auth_success)
{
ConsoleResource *cons = (ConsoleResource *)my_config->GetResWithName(R_CONSOLE, console_name.c_str());

#if !defined(HAVE_PAM)
{
if (cons && cons->use_pam_authentication_) {
Emsg0(M_ERROR, 0, _("PAM is not available on this director\n"));
auth_success = false;
return true;
} else {
return false; /* auth_success can be ignored */
}
}
#else /* HAVE_PAM */
{
if (!cons) { /* if console resource cannot be obtained is treated as an error */
auth_success = false;
return true;
}

/* no need to evaluate auth_success if no pam is required */
if (!cons->use_pam_authentication_) { return false; }

uint32_t response_id;
BStringList message_arguments;

if (!ua->UA_sock->ReceiveAndEvaluateResponseMessage(response_id, message_arguments)) {
Dmsg2(100, "Could not evaluate response_id: %d - %d", response_id,
message_arguments.JoinReadable().c_str());
auth_success = false;
return true;
}

std::string pam_username;
std::string pam_password;

if (response_id == kMessageIdPamUserCredentials) {
Dmsg0(200, "Console chooses Pam direct credentials\n");
if (message_arguments.size() < 3) {
Dmsg0(200, "Console sent wrong number of credentials\n");
auth_success = false;
return true;
} else {
pam_username = message_arguments.at(1);
pam_password = message_arguments.at(2);
}
} else if (response_id == kMessageIdPamInteractive) {
Dmsg0(200, "Console chooses Pam interactive\n");
}

std::string authenticated_username;
if (!PamAuthenticateUser(ua->UA_sock, pam_username, pam_password, authenticated_username)) {
ua->cons = nullptr;
auth_success = false;
} else {
ConsoleResource *user = (ConsoleResource *)my_config->GetResWithName(R_CONSOLE,
authenticated_username.c_str());
if (!user) {
Dmsg1(200, "No user config found for user %s\n", authenticated_username.c_str());
ua->cons = nullptr;
auth_success = false;
} else {
ua->cons = user;
auth_success = true;
}
}
return true;
} /* HAVE PAM */
#endif /* !HAVE_PAM */
}

bool AuthenticateUserAgent(UaContext *ua)
{
std::string console_name;
if (!GetConsoleName(ua->UA_sock, console_name)) {
return false;
}

if (NumberOfConsoleConnectionsExceeded()) {
Emsg0(M_ERROR, 0, _("Number of console connections exceeded MaximumConsoleConnections\n"));
return false;
}

bool auth_success = false;

if (OptionalAuthenticateRootConsole(console_name, ua, auth_success)) {
if (!auth_success) {
LogErrorMessage(console_name, ua);
return false;
} else {
SendOkMessage(ua, true);
}
} else {
AuthenticateNamedConsole(console_name, ua, auth_success);
if (!auth_success) {
LogErrorMessage(console_name, ua);
return false;
} else {
SendOkMessage(ua, false);
}
if (OptionalAuthenticatePamUser(console_name, ua, auth_success)) {
if (!auth_success) {
LogErrorMessage(console_name, ua);
return false;
} else {
SendOkMessage(ua, true);
}
}
}
return true;
}
} /* namespace directordaemon */
3 changes: 3 additions & 0 deletions core/src/dird/authenticate.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@

namespace directordaemon {

class StorageResource;
class UaContext;

bool AuthenticateWithStorageDaemon(BareosSocket *sd, JobControlRecord *jcr, StorageResource *store);
bool AuthenticateWithFileDaemon(JobControlRecord *jcr);
bool AuthenticateFileDaemon(BareosSocket *fd, char *client_name);
Expand Down
Loading

0 comments on commit 6c827b5

Please sign in to comment.