diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml index f241064d8b..a92e45058c 100644 --- a/man/systemd-ask-password.xml +++ b/man/systemd-ask-password.xml @@ -165,6 +165,15 @@ usernames. + + + + Controls whether or not to prefix the query with a + lock and key emoji (🔐), if the TTY settings permit this. The default + is auto, which defaults to yes, + unless is given. + + diff --git a/src/ask-password/ask-password.c b/src/ask-password/ask-password.c index 09bcefbe66..26cf012f01 100644 --- a/src/ask-password/ask-password.c +++ b/src/ask-password/ask-password.c @@ -10,6 +10,7 @@ #include "log.h" #include "macro.h" #include "main-func.h" +#include "parse-argument.h" #include "pretty-print.h" #include "strv.h" #include "terminal-util.h" @@ -45,6 +46,8 @@ static int help(void) { " credentials\n" " --timeout=SEC Timeout in seconds\n" " --echo Do not mask input (useful for usernames)\n" + " --emoji=yes|no|auto\n" + " Show a lock and key emoji\n" " --no-tty Ask question via agent even on TTY\n" " --accept-cached Accept cached passwords\n" " --multiple List multiple passwords if available\n" @@ -64,6 +67,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_ICON = 0x100, ARG_TIMEOUT, ARG_ECHO, + ARG_EMOJI, ARG_NO_TTY, ARG_ACCEPT_CACHED, ARG_MULTIPLE, @@ -80,6 +84,7 @@ static int parse_argv(int argc, char *argv[]) { { "icon", required_argument, NULL, ARG_ICON }, { "timeout", required_argument, NULL, ARG_TIMEOUT }, { "echo", no_argument, NULL, ARG_ECHO }, + { "emoji", required_argument, NULL, ARG_EMOJI }, { "no-tty", no_argument, NULL, ARG_NO_TTY }, { "accept-cached", no_argument, NULL, ARG_ACCEPT_CACHED }, { "multiple", no_argument, NULL, ARG_MULTIPLE }, @@ -90,6 +95,7 @@ static int parse_argv(int argc, char *argv[]) { {} }; + const char *emoji = NULL; int c; assert(argc >= 0); @@ -120,6 +126,10 @@ static int parse_argv(int argc, char *argv[]) { arg_flags |= ASK_PASSWORD_ECHO; break; + case ARG_EMOJI: + emoji = optarg; + break; + case ARG_NO_TTY: arg_flags |= ASK_PASSWORD_NO_TTY; break; @@ -155,6 +165,18 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached("Unhandled option"); } + if (isempty(emoji) || streq(emoji, "auto")) + SET_FLAG(arg_flags, ASK_PASSWORD_HIDE_EMOJI, FLAGS_SET(arg_flags, ASK_PASSWORD_ECHO)); + else { + int r; + bool b; + + r = parse_boolean_argument("--emoji=", emoji, &b); + if (r < 0) + return r; + SET_FLAG(arg_flags, ASK_PASSWORD_HIDE_EMOJI, !b); + } + if (argc > optind) { arg_message = strv_join(argv + optind, " "); if (!arg_message) diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index 0895a24c7f..8b840ac84c 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -107,7 +107,7 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa assert(keyname); - if (!(flags & ASK_PASSWORD_PUSH_CACHE)) + if (!FLAGS_SET(flags, ASK_PASSWORD_PUSH_CACHE)) return 0; if (strv_isempty(passwords)) return 0; @@ -165,7 +165,7 @@ static int ask_password_keyring(const char *keyname, AskPasswordFlags flags, cha assert(keyname); assert(ret); - if (!(flags & ASK_PASSWORD_ACCEPT_CACHED)) + if (!FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED)) return -EUNATCH; r = lookup_key(keyname, &serial); @@ -258,7 +258,7 @@ int ask_password_plymouth( if (r < 0) return -errno; - if (flags & ASK_PASSWORD_ACCEPT_CACHED) { + if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED)) { packet = strdup("c"); n = 1; } else if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) @@ -320,7 +320,7 @@ int ask_password_plymouth( if (buffer[0] == 5) { - if (flags & ASK_PASSWORD_ACCEPT_CACHED) { + if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED)) { /* Hmm, first try with cached * passwords failed, so let's retry * with a normal password request */ @@ -415,16 +415,16 @@ int ask_password_tty( assert(ret); - if (flags & ASK_PASSWORD_NO_TTY) + if (FLAGS_SET(flags, ASK_PASSWORD_NO_TTY)) return -EUNATCH; if (!message) message = "Password:"; - if (emoji_enabled()) + if (!FLAGS_SET(flags, ASK_PASSWORD_HIDE_EMOJI) && emoji_enabled()) message = strjoina(special_glyph(SPECIAL_GLYPH_LOCK_AND_KEY), " ", message); - if (flag_file || ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname)) { + if (flag_file || (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname)) { notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK); if (notify < 0) return -errno; @@ -433,7 +433,7 @@ int ask_password_tty( if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) return -errno; } - if ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname) { + if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname) { r = ask_password_keyring(keyname, flags, ret); if (r >= 0) return 0; @@ -452,7 +452,7 @@ int ask_password_tty( if (tcgetattr(ttyfd, &old_termios) < 0) return -errno; - if (flags & ASK_PASSWORD_CONSOLE_COLOR) + if (FLAGS_SET(flags, ASK_PASSWORD_CONSOLE_COLOR)) use_color = dev_console_colors_enabled(); else use_color = colors_enabled(); @@ -463,7 +463,7 @@ int ask_password_tty( (void) loop_write(ttyfd, message, strlen(message), false); (void) loop_write(ttyfd, " ", 1, false); - if (!(flags & ASK_PASSWORD_SILENT) && !(flags & ASK_PASSWORD_ECHO)) { + if (!FLAGS_SET(flags, ASK_PASSWORD_SILENT) && !FLAGS_SET(flags, ASK_PASSWORD_ECHO)) { if (use_color) (void) loop_write(ttyfd, ansi_grey(), strlen(ansi_grey()), false); (void) loop_write(ttyfd, PRESS_TAB, strlen(PRESS_TAB), false); @@ -564,7 +564,7 @@ int ask_password_tty( if (c == 21) { /* C-u */ - if (!(flags & ASK_PASSWORD_SILENT)) + if (!FLAGS_SET(flags, ASK_PASSWORD_SILENT)) (void) backspace_string(ttyfd, passphrase); explicit_bzero_safe(passphrase, sizeof(passphrase)); @@ -575,7 +575,7 @@ int ask_password_tty( if (p > 0) { size_t q; - if (!(flags & ASK_PASSWORD_SILENT)) + if (!FLAGS_SET(flags, ASK_PASSWORD_SILENT)) (void) backspace_chars(ttyfd, 1); /* Remove a full UTF-8 codepoint from the end. For that, figure out where the @@ -599,7 +599,7 @@ int ask_password_tty( p = codepoint = q == SIZE_MAX ? p - 1 : q; explicit_bzero_safe(passphrase + p, sizeof(passphrase) - p); - } else if (!dirty && !(flags & ASK_PASSWORD_SILENT)) { + } else if (!dirty && !FLAGS_SET(flags, ASK_PASSWORD_SILENT)) { flags |= ASK_PASSWORD_SILENT; @@ -612,7 +612,7 @@ int ask_password_tty( } else if (ttyfd >= 0) (void) loop_write(ttyfd, "\a", 1, false); - } else if (c == '\t' && !(flags & ASK_PASSWORD_SILENT)) { + } else if (c == '\t' && !FLAGS_SET(flags, ASK_PASSWORD_SILENT)) { (void) backspace_string(ttyfd, passphrase); flags |= ASK_PASSWORD_SILENT; @@ -631,11 +631,11 @@ int ask_password_tty( } else { passphrase[p++] = c; - if (!(flags & ASK_PASSWORD_SILENT) && ttyfd >= 0) { + if (!FLAGS_SET(flags, ASK_PASSWORD_SILENT) && ttyfd >= 0) { /* Check if we got a complete UTF-8 character now. If so, let's output one '*'. */ n = utf8_encoded_valid_unichar(passphrase + codepoint, SIZE_MAX); if (n >= 0) { - if (flags & ASK_PASSWORD_ECHO) + if (FLAGS_SET(flags, ASK_PASSWORD_ECHO)) (void) loop_write(ttyfd, passphrase + codepoint, n, false); else (void) loop_write(ttyfd, "*", 1, false); @@ -739,7 +739,7 @@ int ask_password_agent( assert(ret); - if (flags & ASK_PASSWORD_NO_AGENT) + if (FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT)) return -EUNATCH; assert_se(sigemptyset(&mask) >= 0); @@ -748,7 +748,7 @@ int ask_password_agent( (void) mkdir_p_label("/run/systemd/ask-password", 0755); - if ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname) { + if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname) { r = ask_password_keyring(keyname, flags, ret); if (r >= 0) { r = 0; @@ -803,10 +803,10 @@ int ask_password_agent( "Silent=%i\n", getpid_cached(), socket_name, - (flags & ASK_PASSWORD_ACCEPT_CACHED) ? 1 : 0, - (flags & ASK_PASSWORD_ECHO) ? 1 : 0, + FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED), + FLAGS_SET(flags, ASK_PASSWORD_ECHO), until, - (flags & ASK_PASSWORD_SILENT) ? 1 : 0); + FLAGS_SET(flags, ASK_PASSWORD_SILENT)); if (message) fprintf(f, "Message=%s\n", message); @@ -1009,25 +1009,25 @@ int ask_password_auto( assert(ret); - if (!(flags & ASK_PASSWORD_NO_CREDENTIAL) && credential_name) { + if (!FLAGS_SET(flags, ASK_PASSWORD_NO_CREDENTIAL) && credential_name) { r = ask_password_credential(credential_name, flags, ret); if (r != -ENOKEY) return r; } - if ((flags & ASK_PASSWORD_ACCEPT_CACHED) && + if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && key_name && - ((flags & ASK_PASSWORD_NO_TTY) || !isatty(STDIN_FILENO)) && - (flags & ASK_PASSWORD_NO_AGENT)) { + (FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) || !isatty(STDIN_FILENO)) && + FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT)) { r = ask_password_keyring(key_name, flags, ret); if (r != -ENOKEY) return r; } - if (!(flags & ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO)) + if (!FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO)) return ask_password_tty(-1, message, key_name, until, flags, NULL, ret); - if (!(flags & ASK_PASSWORD_NO_AGENT)) + if (!FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT)) return ask_password_agent(message, icon, id, key_name, until, flags, ret); return -EUNATCH; diff --git a/src/shared/ask-password-api.h b/src/shared/ask-password-api.h index bb507b2e8d..7464e7f6de 100644 --- a/src/shared/ask-password-api.h +++ b/src/shared/ask-password-api.h @@ -14,6 +14,7 @@ typedef enum AskPasswordFlags { ASK_PASSWORD_NO_AGENT = 1 << 5, /* never ask for password via agent */ ASK_PASSWORD_CONSOLE_COLOR = 1 << 6, /* Use color if /dev/console points to a console that supports color */ ASK_PASSWORD_NO_CREDENTIAL = 1 << 7, /* never use $CREDENTIALS_DIRECTORY data */ + ASK_PASSWORD_HIDE_EMOJI = 1 << 8, /* hide the lock and key emoji */ } AskPasswordFlags; int ask_password_tty(int tty_fd, const char *message, const char *key_name, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);