tty-ask-password-agent: reenable color for boot-time password prompt
authorLennart Poettering <lennart@poettering.net>
Wed, 14 Feb 2018 13:30:30 +0000 (14:30 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 14 Feb 2018 13:30:30 +0000 (14:30 +0100)
The password prompt used to be highlighted, and that was a good thing.
Let's fix things to make the prompt highlighted again.

Fixes: #3853

src/basic/terminal-util.c
src/basic/terminal-util.h
src/shared/ask-password-api.c
src/shared/ask-password-api.h
src/tty-ask-password-agent/tty-ask-password-agent.c

index 26c35eb..ee540bb 100644 (file)
@@ -48,6 +48,8 @@
 #include "log.h"
 #include "macro.h"
 #include "parse-util.h"
+#include "path-util.h"
+#include "proc-cmdline.h"
 #include "process-util.h"
 #include "socket-util.h"
 #include "stat-util.h"
@@ -56,7 +58,6 @@
 #include "terminal-util.h"
 #include "time-util.h"
 #include "util.h"
-#include "path-util.h"
 
 static volatile unsigned cached_columns = 0;
 static volatile unsigned cached_lines = 0;
@@ -1230,6 +1231,27 @@ bool colors_enabled(void) {
         return cached_colors_enabled;
 }
 
+bool dev_console_colors_enabled(void) {
+        _cleanup_free_ char *s = NULL;
+        int b;
+
+        /* Returns true if we assume that color is supported on /dev/console.
+         *
+         * For that we first check if we explicitly got told to use colors or not, by checking $SYSTEMD_COLORS. If that
+         * didn't tell us anything we check whether PID 1 has $TERM set, and if not whether $TERM is set on the kernel
+         * command line. If we find $TERM set we assume color if it's not set to "dumb", similar to regular
+         * colors_enabled() operates. */
+
+        b = getenv_bool("SYSTEMD_COLORS");
+        if (b >= 0)
+                return b;
+
+        if (getenv_for_pid(1, "TERM", &s) <= 0)
+                (void) proc_cmdline_get_key("TERM", 0, &s);
+
+        return !streq_ptr(s, "dumb");
+}
+
 bool underline_enabled(void) {
 
         if (cached_underline_enabled < 0) {
index 9a060f5..470892d 100644 (file)
@@ -106,6 +106,7 @@ bool on_tty(void);
 bool terminal_is_dumb(void);
 bool colors_enabled(void);
 bool underline_enabled(void);
+bool dev_console_colors_enabled(void);
 
 #define DEFINE_ANSI_FUNC(name, NAME)                            \
         static inline const char *ansi_##name(void) {           \
index c37920b..845fd9d 100644 (file)
@@ -216,13 +216,12 @@ int ask_password_tty(
                 _POLL_MAX,
         };
 
+        bool reset_tty = false, dirty = false, use_color = false;
         _cleanup_close_ int cttyfd = -1, notify = -1;
         struct termios old_termios, new_termios;
         char passphrase[LINE_MAX + 1] = {}, *x;
         struct pollfd pollfd[_POLL_MAX];
         size_t p = 0, codepoint = 0;
-        bool reset_tty = false;
-        bool dirty = false;
         int r;
 
         assert(ret);
@@ -250,13 +249,18 @@ int ask_password_tty(
                 if (tcgetattr(ttyfd, &old_termios) < 0)
                         return -errno;
 
-                if (colors_enabled())
+                if (flags & ASK_PASSWORD_CONSOLE_COLOR)
+                        use_color = dev_console_colors_enabled();
+                else
+                        use_color = colors_enabled();
+
+                if (use_color)
                         (void) loop_write(ttyfd, ANSI_HIGHLIGHT, STRLEN(ANSI_HIGHLIGHT), false);
 
                 (void) loop_write(ttyfd, message, strlen(message), false);
                 (void) loop_write(ttyfd, " ", 1, false);
 
-                if (colors_enabled())
+                if (use_color)
                         (void) loop_write(ttyfd, ANSI_NORMAL, STRLEN(ANSI_NORMAL), false);
 
                 new_termios = old_termios;
index 7a01029..4b2eb3f 100644 (file)
@@ -31,6 +31,7 @@ typedef enum AskPasswordFlags {
         ASK_PASSWORD_SILENT        = 1U << 3, /* do no show any password at all while reading */
         ASK_PASSWORD_NO_TTY        = 1U << 4,
         ASK_PASSWORD_NO_AGENT      = 1U << 5,
+        ASK_PASSWORD_CONSOLE_COLOR = 1U << 6, /* Use color if /dev/console points to a console that supports color */
 } AskPasswordFlags;
 
 int ask_password_tty(int tty_fd, const char *message, const char *keyname, usec_t until, AskPasswordFlags flags, const char *flag_file, char **ret);
index be78892..c52a19d 100644 (file)
@@ -377,10 +377,12 @@ static int parse_password(const char *filename, char **wall) {
                                 r = reset_terminal_fd(tty_fd, true);
                                 if (r < 0)
                                         log_warning_errno(r, "Failed to reset terminal, ignoring: %m");
-
                         }
 
-                        r = ask_password_tty(tty_fd, message, NULL, not_after, echo ? ASK_PASSWORD_ECHO : 0, filename, &password);
+                        r = ask_password_tty(tty_fd, message, NULL, not_after,
+                                             (echo ? ASK_PASSWORD_ECHO : 0) |
+                                             (arg_console ? ASK_PASSWORD_CONSOLE_COLOR : 0),
+                                             filename, &password);
 
                         if (arg_console) {
                                 tty_fd = safe_close(tty_fd);