]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
BConsole add '-p' to avoid getpass for authenticate.
authorRadosław Korzeniewski <radoslaw@korzeniewski.net>
Thu, 15 Oct 2020 10:41:38 +0000 (12:41 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:02:58 +0000 (09:02 +0100)
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.

bacula/src/console/authenticate.c
bacula/src/console/console.c

index 0e2cb7700ad01a1de454c2733bd41d6eb72c7b44..e0b0a96fffc319e5fbbdaf30f4162d566756ded1 100644 (file)
@@ -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());
index c3b7ebf7e4dbd1fb55bb3e1102c05d40c68a054e..24f4b110a6835cc3d7b9f60c4e647c2b479e115b 100644 (file)
@@ -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 <nn>     set command execution timeout to <nn> 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;
    }