msg2 = strjoina(special_glyph(TRIANGULAR_BULLET), " Please enter new root password again: ");
for (;;) {
- _cleanup_string_free_erase_ char *a = NULL, *b = NULL;
+ _cleanup_strv_free_erase_ char **a = NULL, **b = NULL;
r = ask_password_tty(-1, msg1, NULL, 0, 0, NULL, &a);
if (r < 0)
return log_error_errno(r, "Failed to query root password: %m");
+ if (strv_length(a) != 1) {
+ log_warning("Received multiple passwords, where we expected one.");
+ return -EINVAL;
+ }
- if (isempty(a)) {
+ if (isempty(*a)) {
log_warning("No password entered, skipping.");
break;
}
if (r < 0)
return log_error_errno(r, "Failed to query root password: %m");
- if (!streq(a, b)) {
+ if (!streq(*a, *b)) {
log_error("Entered passwords did not match, please try again.");
continue;
}
- arg_root_password = TAKE_PTR(a);
+ arg_root_password = TAKE_PTR(*a);
break;
}
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
+#include "fs-util.h"
#include "io-util.h"
#include "log.h"
#include "macro.h"
(unsigned long) DIV_ROUND_UP(KEYRING_TIMEOUT_USEC, USEC_PER_SEC), 0, 0) < 0)
log_debug_errno(errno, "Failed to adjust timeout: %m");
+ /* Tell everyone to check the keyring */
+ (void) touch("/run/systemd/ask-password");
+
log_debug("Added key to keyring as %" PRIi32 ".", serial);
return 1;
usec_t until,
AskPasswordFlags flags,
const char *flag_file,
- char **ret) {
+ char ***ret) {
enum {
POLL_TTY,
_cleanup_close_ int cttyfd = -1, notify = -1;
struct termios old_termios, new_termios;
char passphrase[LINE_MAX + 1] = {}, *x;
+ _cleanup_strv_free_erase_ char **l = NULL;
struct pollfd pollfd[_POLL_MAX];
size_t p = 0, codepoint = 0;
int r;
if (!message)
message = "Password:";
- if (flag_file) {
+ if (flag_file || ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname)) {
notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
if (notify < 0)
return -errno;
-
+ }
+ if (flag_file) {
if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0)
return -errno;
}
+ if ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname) {
+ r = ask_password_keyring(keyname, flags, ret);
+ if (r >= 0)
+ return 0;
+ else if (r != -ENOKEY)
+ return r;
+
+ if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_ATTRIB /* for mtime */) < 0)
+ return -errno;
+ }
/* If the caller didn't specify a TTY, then use the controlling tty, if we can. */
if (ttyfd < 0)
goto finish;
}
- if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
+ if (notify >= 0 && pollfd[POLL_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 (pollfd[POLL_TTY].revents == 0)
continue;
goto finish;
}
+ l = strv_new(x, NULL);
+ if (!l) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
if (keyname)
- (void) add_to_keyring_and_log(keyname, flags, STRV_MAKE(x));
+ (void) add_to_keyring_and_log(keyname, flags, l);
- *ret = x;
+ *ret = TAKE_PTR(l);
r = 0;
finish:
enum {
FD_SOCKET,
FD_SIGNAL,
+ FD_INOTIFY,
_FD_MAX
};
- _cleanup_close_ int socket_fd = -1, signal_fd = -1, fd = -1;
+ _cleanup_close_ int socket_fd = -1, signal_fd = -1, notify = -1, fd = -1;
char temp[] = "/run/systemd/ask-password/tmp.XXXXXX";
char final[sizeof(temp)] = "";
_cleanup_free_ char *socket_name = NULL;
- _cleanup_strv_free_ char **l = NULL;
+ _cleanup_strv_free_erase_ char **l = NULL;
_cleanup_fclose_ FILE *f = NULL;
struct pollfd pollfd[_FD_MAX];
sigset_t mask, oldmask;
(void) mkdir_p_label("/run/systemd/ask-password", 0755);
+ if ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname) {
+ r = ask_password_keyring(keyname, flags, ret);
+ if (r >= 0) {
+ r = 0;
+ goto finish;
+ } else if (r != -ENOKEY)
+ goto finish;
+
+ notify = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
+ if (notify < 0) {
+ r = -errno;
+ goto finish;
+ }
+ if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_ATTRIB /* for mtime */) < 0) {
+ r = -errno;
+ goto finish;
+ }
+ }
+
fd = mkostemp_safe(temp);
if (fd < 0) {
r = fd;
pollfd[FD_SOCKET].events = POLLIN;
pollfd[FD_SIGNAL].fd = signal_fd;
pollfd[FD_SIGNAL].events = POLLIN;
+ pollfd[FD_INOTIFY].fd = notify;
+ pollfd[FD_INOTIFY].events = POLLIN;
for (;;) {
char passphrase[LINE_MAX+1];
goto finish;
}
- k = poll(pollfd, _FD_MAX, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1);
+ k = poll(pollfd, notify >= 0 ? _FD_MAX : _FD_MAX - 1, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1);
if (k < 0) {
if (errno == EINTR)
continue;
goto finish;
}
+ 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 (pollfd[FD_SOCKET].revents == 0)
+ continue;
+
if (pollfd[FD_SOCKET].revents != POLLIN) {
r = -EIO;
goto finish;
assert(ret);
- if ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname) {
+ if ((flags & ASK_PASSWORD_ACCEPT_CACHED) &&
+ keyname &&
+ ((flags & ASK_PASSWORD_NO_TTY) || !isatty(STDIN_FILENO)) &&
+ (flags & ASK_PASSWORD_NO_AGENT)) {
r = ask_password_keyring(keyname, flags, ret);
if (r != -ENOKEY)
return r;
}
- if (!(flags & ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO)) {
- char *s = NULL, **l = NULL;
-
- r = ask_password_tty(-1, message, keyname, until, flags, NULL, &s);
- if (r < 0)
- return r;
-
- r = strv_push(&l, s);
- if (r < 0) {
- string_erase(s);
- free(s);
- return -ENOMEM;
- }
-
- *ret = l;
- return 0;
- }
+ if (!(flags & ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO))
+ return ask_password_tty(-1, message, keyname, until, flags, NULL, ret);
if (!(flags & ASK_PASSWORD_NO_AGENT))
return ask_password_agent(message, icon, id, keyname, until, flags, ret);
ASK_PASSWORD_CONSOLE_COLOR = 1 << 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);
+int ask_password_tty(int tty_fd, const char *message, const char *keyname, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
int ask_password_agent(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, char ***ret);
int ask_password_keyring(const char *keyname, AskPasswordFlags flags, char ***ret);
int ask_password_auto(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, char ***ret);