]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/ask-password-api: show "(press TAB for no echo)" 14800/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 6 Feb 2020 08:50:35 +0000 (09:50 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 6 Feb 2020 09:51:24 +0000 (10:51 +0100)
For #8495: it is arguably useful to not show the length of the password
in public spaces. It is possible to press TAB or BS to cancel the asterisks,
but this is not very discoverable. Let's make it discoverable by showing
a message (in gray). The message is "erased" after the first character
is entered.

src/shared/ask-password-api.c
src/test/test-ask-password-api.c

index a6c83e181a01f6433895fa1002f94de5c456b4bb..7abe7d17115661082d48364a544ad2a3914379f1 100644 (file)
@@ -394,6 +394,10 @@ finish:
         return r;
 }
 
+#define NO_ECHO "(no echo) "
+#define PRESS_TAB "(press TAB for no echo) "
+#define SKIPPED "(skipped)"
+
 int ask_password_tty(
                 int ttyfd,
                 const char *message,
@@ -409,7 +413,7 @@ int ask_password_tty(
                 _POLL_MAX,
         };
 
-        bool reset_tty = false, dirty = false, use_color = false;
+        bool reset_tty = false, dirty = false, use_color = false, press_tab_visible = false;
         _cleanup_close_ int cttyfd = -1, notify = -1;
         struct termios old_termios, new_termios;
         char passphrase[LINE_MAX + 1] = {}, *x;
@@ -465,6 +469,13 @@ int ask_password_tty(
                 (void) loop_write(ttyfd, message, strlen(message), false);
                 (void) loop_write(ttyfd, " ", 1, false);
 
+                if (!(flags & ASK_PASSWORD_SILENT)) {
+                        if (use_color)
+                                (void) loop_write(ttyfd, ANSI_GREY, STRLEN(ANSI_GREY), false);
+                        (void) loop_write(ttyfd, PRESS_TAB, strlen(PRESS_TAB), false);
+                        press_tab_visible = true;
+                }
+
                 if (use_color)
                         (void) loop_write(ttyfd, ANSI_NORMAL, STRLEN(ANSI_NORMAL), false);
 
@@ -550,13 +561,19 @@ int ask_password_tty(
 
                 }
 
+                if (press_tab_visible) {
+                        assert(ttyfd >= 0);
+                        backspace_chars(ttyfd, strlen(PRESS_TAB));
+                        press_tab_visible = false;
+                }
+
                 /* We treat EOF, newline and NUL byte all as valid end markers */
                 if (n == 0 || c == '\n' || c == 0)
                         break;
 
                 if (c == 4) { /* C-d also known as EOT */
                         if (ttyfd >= 0)
-                                (void) loop_write(ttyfd, "(skipped)", 9, false);
+                                (void) loop_write(ttyfd, SKIPPED, strlen(SKIPPED), false);
 
                         goto skipped;
                 }
@@ -606,7 +623,7 @@ int ask_password_tty(
                                  * first key (and only as first key), or ... */
 
                                 if (ttyfd >= 0)
-                                        (void) loop_write(ttyfd, "(no echo) ", 10, false);
+                                        (void) loop_write(ttyfd, NO_ECHO, strlen(NO_ECHO), false);
 
                         } else if (ttyfd >= 0)
                                 (void) loop_write(ttyfd, "\a", 1, false);
@@ -619,7 +636,7 @@ int ask_password_tty(
                         /* ... or by pressing TAB at any time. */
 
                         if (ttyfd >= 0)
-                                (void) loop_write(ttyfd, "(no echo) ", 10, false);
+                                (void) loop_write(ttyfd, NO_ECHO, strlen(NO_ECHO), false);
 
                 } else if (p >= sizeof(passphrase)-1) {
 
index 13a1064b457898685fa906130df80812da0e2adf..098bb35bce67ebebc8fc43e99d743d21eae4d1f2 100644 (file)
@@ -8,7 +8,7 @@ static void test_ask_password(void) {
         int r;
         _cleanup_strv_free_ char **ret = NULL;
 
-        r = ask_password_tty(-1, "hello?", "da key", 0, 0, NULL, &ret);
+        r = ask_password_tty(-1, "hello?", "da key", 0, ASK_PASSWORD_CONSOLE_COLOR, NULL, &ret);
         if (r == -ECANCELED)
                 assert_se(ret == NULL);
         else {