From: Radosław Korzeniewski Date: Thu, 15 Oct 2020 10:41:38 +0000 (+0200) Subject: BConsole add '-p' to avoid getpass for authenticate. X-Git-Tag: Release-11.3.2~922 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27e24f4f32290a32b1b6b3a62d4373d542f8ca7a;p=thirdparty%2Fbacula.git BConsole add '-p' to avoid getpass for authenticate. When compiled with DEVELOPER mode (regression tests) then bconsole can handle '-p' command line parameter which tells bconsole BPAM API to avoid getpass() during authentication chatting. This allows to batch and test BPAM framework API with regression testing scripts. --- diff --git a/bacula/src/console/authenticate.c b/bacula/src/console/authenticate.c index 0e2cb7700..e0b0a96ff 100644 --- a/bacula/src/console/authenticate.c +++ b/bacula/src/console/authenticate.c @@ -64,7 +64,8 @@ class ConsoleAuthenticate: public AuthenticateBase { public: ConsoleAuthenticate(BSOCK *dir): - AuthenticateBase(NULL, dir, dtCli, dcCON, dcDIR) + AuthenticateBase(NULL, dir, dtCli, dcCON, dcDIR), + avoid_getpass(false) { } virtual ~ConsoleAuthenticate() {}; @@ -73,11 +74,14 @@ public: int authenticate_director(DIRRES *director, CONRES *cons); bool ClientAuthenticate(CONRES *cons, const char *password); + + bool avoid_getpass; // this is for regress testing }; -int authenticate_director(BSOCK *dir, DIRRES *director, CONRES *cons) +int authenticate_director(BSOCK *dir, DIRRES *director, CONRES *cons, bool avoid_getpass = false) { ConsoleAuthenticate auth(dir); + auth.avoid_getpass = avoid_getpass; return auth.authenticate_director(director, cons); } @@ -158,8 +162,8 @@ bool ConsoleAuthenticate::ClientAuthenticate(CONRES *cons, const char *password) char *data = msg.c_str(); POOL_MEM buf(PM_MESSAGE); - char *passwd; char *input; + char *passwd; // the command is encoded as a first char of the message switch (dir->msg[0]){ @@ -177,17 +181,29 @@ bool ConsoleAuthenticate::ClientAuthenticate(CONRES *cons, const char *password) break; case UA_AUTH_INTERACTIVE_HIDDEN: +#if defined(DEVELOPER) + if (!avoid_getpass){ + // normal pass handling +#endif #if defined(HAVE_WIN32) - sendit(data); - if (win32_cgets(buf.c_str(), buf.size()) == NULL) { - buf[0] = 0; - return 0; + sendit(data); + if (win32_cgets(buf.c_str(), buf.size()) == NULL) { + pm_strcpy(buf, NULL); + } +#else + passwd = getpass(data); + bstrncpy(buf.c_str(), passwd, buf.size()); +#endif +#if defined(DEVELOPER) } else { - return strlen(buf); + sendit(data); + input = fgets(buf.c_str(), buf.size(), stdin); + if (!input){ + Dmsg0(1, "Error reading user input!\n"); + return false; + } + strip_trailing_junk(buf.c_str()); } -#else - passwd = getpass(data); - bstrncpy(buf.c_str(), passwd, buf.size()); #endif // now we should get a hidden response at `buf` class, return it to director dir->fsend("%c%s", UA_AUTH_INTERACTIVE_RESPONSE, buf.c_str()); diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index c3b7ebf7e..24f4b110a 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -54,7 +54,7 @@ static int require_fips = 0; //extern int rl_catch_signals; /* Imported functions */ -int authenticate_director(BSOCK *dir, DIRRES *director, CONRES *cons); +int authenticate_director(BSOCK *dir, DIRRES *director, CONRES *cons, bool avoid_getpass); /* Forward referenced functions */ static void terminate_console(int sig); @@ -135,6 +135,9 @@ PROG_COPYRIGHT " -s no signals\n" " -u set command execution timeout to seconds\n" " -t test - read configuration and exit\n" +#if defined(DEVELOPER) +" -p regress test - avoid getpass()\n" +#endif " -? print this message.\n" "\n"), 2000, BDEMO, HOST_OS, DISTNAME, DISTVER); } @@ -794,7 +797,7 @@ get_cmd(FILE *input, const char *prompt, BSOCK *sock, int sec) if (!next) { if (do_history) { add_history(line); - /* Count the number of lines added, we use it to truncate the history + /* Count the number of lines added, we use it to truncate the history * file correctly */ history_lines_added++; @@ -1118,6 +1121,7 @@ int main(int argc, char *argv[]) bool no_signals = false; bool test_config = false; utime_t heart_beat; + bool avoid_getpass = false; setlocale(LC_ALL, ""); bindtextdomain("bacula", LOCALEDIR); @@ -1130,7 +1134,7 @@ int main(int argc, char *argv[]) working_directory = "/tmp"; args = get_pool_memory(PM_FNAME); - while ((ch = getopt(argc, argv, "D:lc:d:nstu:?C:L")) != -1) { + while ((ch = getopt(argc, argv, "D:lc:d:npstu:?C:L")) != -1) { switch (ch) { case 'D': /* Director */ if (director) { @@ -1190,6 +1194,12 @@ int main(int argc, char *argv[]) timeout = atoi(optarg); break; +#if defined(DEVELOPER) + case 'p': + avoid_getpass = true; + break; +#endif + case '?': default: usage(); @@ -1339,7 +1349,7 @@ int main(int argc, char *argv[]) terminate_console(0); return 1; } - + if (dir->heartbeat_interval) { heart_beat = dir->heartbeat_interval; } else if (cons) { @@ -1359,7 +1369,7 @@ int main(int argc, char *argv[]) } /* If cons==NULL, default console will be used */ - if (!authenticate_director(UA_sock, dir, cons)) { + if (!authenticate_director(UA_sock, dir, cons, avoid_getpass)) { terminate_console(0); return 1; }