diff options
Diffstat (limited to 'src/shared/ask-password-api.c')
-rw-r--r-- | src/shared/ask-password-api.c | 114 |
1 files changed, 58 insertions, 56 deletions
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index 0e323f4..bf79dc2 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -147,18 +147,17 @@ static int add_to_keyring_and_log(const char *keyname, AskPasswordFlags flags, c return 0; } -static int ask_password_keyring(const char *keyname, AskPasswordFlags flags, char ***ret) { - +static int ask_password_keyring(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret) { key_serial_t serial; int r; - assert(keyname); + assert(req); assert(ret); if (!FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED)) return -EUNATCH; - r = lookup_key(keyname, &serial); + r = lookup_key(req->keyring, &serial); if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EPERM) /* When retrieving, the distinction between "kernel or container manager don't support or * allow this" and "no matching key known" doesn't matter. Note that we propagate EACCESS @@ -205,7 +204,7 @@ static int backspace_string(int ttyfd, const char *str) { } int ask_password_plymouth( - const char *message, + const AskPasswordRequest *req, usec_t until, AskPasswordFlags flags, const char *flag_file, @@ -225,8 +224,10 @@ int ask_password_plymouth( assert(ret); - if (!message) - message = "Password:"; + if (FLAGS_SET(flags, ASK_PASSWORD_HEADLESS)) + return -ENOEXEC; + + const char *message = req && req->message ? req->message : "Password:"; if (flag_file) { notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK); @@ -357,8 +358,7 @@ int ask_password_plymouth( int ask_password_tty( int ttyfd, - const char *message, - const char *keyname, + const AskPasswordRequest *req, usec_t until, AskPasswordFlags flags, const char *flag_file, @@ -381,16 +381,19 @@ int ask_password_tty( assert(ret); + if (FLAGS_SET(flags, ASK_PASSWORD_HEADLESS)) + return -ENOEXEC; + if (FLAGS_SET(flags, ASK_PASSWORD_NO_TTY)) return -EUNATCH; - if (!message) - message = "Password:"; + const char *message = req && req->message ? req->message : "Password:"; + const char *keyring = req ? req->keyring : NULL; if (!FLAGS_SET(flags, ASK_PASSWORD_HIDE_EMOJI) && emoji_enabled()) message = strjoina(special_glyph(SPECIAL_GLYPH_LOCK_AND_KEY), " ", message); - if (flag_file || (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname)) { + if (flag_file || (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyring)) { notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK); if (notify < 0) return -errno; @@ -399,8 +402,8 @@ int ask_password_tty( if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) return -errno; } - if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname) { - r = ask_password_keyring(keyname, flags, ret); + if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && req && keyring) { + r = ask_password_keyring(req, flags, ret); if (r >= 0) return 0; else if (r != -ENOKEY) @@ -443,9 +446,7 @@ int ask_password_tty( (void) loop_write(ttyfd, ANSI_NORMAL, SIZE_MAX); new_termios = old_termios; - new_termios.c_lflag &= ~(ICANON|ECHO); - new_termios.c_cc[VMIN] = 1; - new_termios.c_cc[VTIME] = 0; + termios_disable_echo(&new_termios); r = RET_NERRNO(tcsetattr(ttyfd, TCSADRAIN, &new_termios)); if (r < 0) @@ -489,10 +490,10 @@ int ask_password_tty( goto finish; } - if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0 && keyname) { + if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0 && keyring) { (void) flush_fd(notify); - r = ask_password_keyring(keyname, flags, ret); + r = ask_password_keyring(req, flags, ret); if (r >= 0) { r = 0; goto finish; @@ -631,8 +632,8 @@ skipped: if (strv_isempty(l)) r = log_debug_errno(SYNTHETIC_ERRNO(ECANCELED), "Password query was cancelled."); else { - if (keyname) - (void) add_to_keyring_and_log(keyname, flags, l); + if (keyring) + (void) add_to_keyring_and_log(keyring, flags, l); *ret = TAKE_PTR(l); r = 0; @@ -681,10 +682,7 @@ static int create_socket(char **ret) { } int ask_password_agent( - const char *message, - const char *icon, - const char *id, - const char *keyname, + const AskPasswordRequest *req, usec_t until, AskPasswordFlags flags, char ***ret) { @@ -708,17 +706,20 @@ int ask_password_agent( assert(ret); + if (FLAGS_SET(flags, ASK_PASSWORD_HEADLESS)) + return -ENOEXEC; + if (FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT)) return -EUNATCH; assert_se(sigemptyset(&mask) >= 0); - assert_se(sigset_add_many(&mask, SIGINT, SIGTERM, -1) >= 0); + assert_se(sigset_add_many(&mask, SIGINT, SIGTERM) >= 0); assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) >= 0); (void) mkdir_p_label("/run/systemd/ask-password", 0755); - if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && keyname) { - r = ask_password_keyring(keyname, flags, ret); + if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && req && req->keyring) { + r = ask_password_keyring(req, flags, ret); if (r >= 0) { r = 0; goto finish; @@ -777,14 +778,16 @@ int ask_password_agent( until, FLAGS_SET(flags, ASK_PASSWORD_SILENT)); - if (message) - fprintf(f, "Message=%s\n", message); + if (req) { + if (req->message) + fprintf(f, "Message=%s\n", req->message); - if (icon) - fprintf(f, "Icon=%s\n", icon); + if (req->icon) + fprintf(f, "Icon=%s\n", req->icon); - if (id) - fprintf(f, "Id=%s\n", id); + if (req->id) + fprintf(f, "Id=%s\n", req->id); + } r = fflush_and_check(f); if (r < 0) @@ -839,12 +842,14 @@ int ask_password_agent( if (notify >= 0 && pollfd[FD_INOTIFY].revents != 0) { (void) flush_fd(notify); - r = ask_password_keyring(keyname, flags, ret); - if (r >= 0) { - r = 0; - goto finish; - } else if (r != -ENOKEY) - goto finish; + if (req && req->keyring) { + r = ask_password_keyring(req, flags, ret); + if (r >= 0) { + r = 0; + goto finish; + } else if (r != -ENOKEY) + goto finish; + } } if (pollfd[FD_SOCKET].revents == 0) @@ -923,8 +928,8 @@ int ask_password_agent( log_debug("Invalid packet"); } - if (keyname) - (void) add_to_keyring_and_log(keyname, flags, l); + if (req && req->keyring) + (void) add_to_keyring_and_log(req->keyring, flags, l); *ret = TAKE_PTR(l); r = 0; @@ -942,16 +947,17 @@ finish: return r; } -static int ask_password_credential(const char *credential_name, AskPasswordFlags flags, char ***ret) { +static int ask_password_credential(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret) { _cleanup_(erase_and_freep) char *buffer = NULL; size_t size; char **l; int r; - assert(credential_name); + assert(req); + assert(req->credential); assert(ret); - r = read_credential(credential_name, (void**) &buffer, &size); + r = read_credential(req->credential, (void**) &buffer, &size); if (IN_SET(r, -ENXIO, -ENOENT)) /* No credentials passed or this credential not defined? */ return -ENOKEY; @@ -964,11 +970,7 @@ static int ask_password_credential(const char *credential_name, AskPasswordFlags } int ask_password_auto( - const char *message, - const char *icon, - const char *id, /* id in "ask-password" protocol */ - const char *key_name, /* name in kernel keyring */ - const char *credential_name, /* name in $CREDENTIALS_DIRECTORY directory */ + const AskPasswordRequest *req, usec_t until, AskPasswordFlags flags, char ***ret) { @@ -977,26 +979,26 @@ int ask_password_auto( assert(ret); - if (!FLAGS_SET(flags, ASK_PASSWORD_NO_CREDENTIAL) && credential_name) { - r = ask_password_credential(credential_name, flags, ret); + if (!FLAGS_SET(flags, ASK_PASSWORD_NO_CREDENTIAL) && req && req->credential) { + r = ask_password_credential(req, flags, ret); if (r != -ENOKEY) return r; } if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) && - key_name && + req && req->keyring && (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); + r = ask_password_keyring(req, flags, ret); if (r != -ENOKEY) return r; } if (!FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO)) - return ask_password_tty(-1, message, key_name, until, flags, NULL, ret); + return ask_password_tty(-EBADF, req, until, flags, NULL, ret); if (!FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT)) - return ask_password_agent(message, icon, id, key_name, until, flags, ret); + return ask_password_agent(req, until, flags, ret); return -EUNATCH; } |