mirror of
https://github.com/systemd/systemd.git
synced 2025-03-28 02:50:16 +03:00
Merge pull request #17096 from eworm-de/ask-password
ask-password: allow to control emoji
This commit is contained in:
commit
7dba77a67e
@ -165,6 +165,15 @@
|
||||
usernames. </para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--emoji=yes|no|auto</option></term>
|
||||
|
||||
<listitem><para>Controls whether or not to prefix the query with a
|
||||
lock and key emoji (🔐), if the TTY settings permit this. The default
|
||||
is <literal>auto</literal>, which defaults to <literal>yes</literal>,
|
||||
unless <option>--echo</option> is given.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--no-tty</option></term>
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user