mirror of
https://github.com/systemd/systemd.git
synced 2025-01-03 05:18:09 +03:00
ask-password-api: add new "hup_fd" field to AskPasswordReq
This new field allows specification of an fd on which the password prompt logic will look for POLLHUP events for, and if seen will abort the query. The usecase for this is that when we query for a pw on behalf of a Varlink client we can abort the query automatically if the client dies.
This commit is contained in:
parent
4770eb1016
commit
921054a53e
@ -259,6 +259,7 @@ static int run(int argc, char *argv[]) {
|
||||
.keyring = arg_key_name,
|
||||
.credential = arg_credential_name ?: "password",
|
||||
.until = timeout,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, arg_flags, &l);
|
||||
|
@ -989,6 +989,7 @@ int verb_install(int argc, char *argv[], void *userdata) {
|
||||
.keyring = arg_private_key,
|
||||
.credential = "bootctl.private-key-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
},
|
||||
&private_key,
|
||||
&ui);
|
||||
|
@ -62,6 +62,7 @@ int load_volume_key_password(
|
||||
.keyring = "cryptenroll",
|
||||
.credential = "cryptenroll.passphrase",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
for (;;) {
|
||||
@ -138,6 +139,7 @@ int enroll_password(
|
||||
.keyring = "cryptenroll",
|
||||
.credential = "cryptenroll.new-passphrase",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
for (;;) {
|
||||
|
@ -125,6 +125,7 @@ static int get_pin(char **ret_pin_str, TPM2Flags *ret_flags) {
|
||||
.keyring = "tpm2-pin",
|
||||
.credential = "cryptenroll.new-tpm2-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
pin = strv_free_erase(pin);
|
||||
|
@ -913,6 +913,7 @@ static int get_password(
|
||||
.keyring = "cryptsetup",
|
||||
.credential = "cryptsetup.passphrase",
|
||||
.until = until,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
if (ignore_cached)
|
||||
@ -1430,6 +1431,7 @@ static int crypt_activate_by_token_pin_ask_password(
|
||||
.keyring = keyring,
|
||||
.credential = credential,
|
||||
.until = until,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, flags, &pins);
|
||||
|
@ -738,6 +738,7 @@ static int prompt_root_password(int rfd) {
|
||||
.tty_fd = -EBADF,
|
||||
.message = msg1,
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_tty(&req, /* flags= */ 0, &a);
|
||||
|
@ -269,6 +269,7 @@ static int acquire_existing_password(
|
||||
.keyring = "home-password",
|
||||
.credential = "home.password",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, flags, &password);
|
||||
@ -329,6 +330,7 @@ static int acquire_recovery_key(
|
||||
.keyring = "home-recovery-key",
|
||||
.credential = "home.recovery-key",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, flags, &recovery_key);
|
||||
@ -385,6 +387,7 @@ static int acquire_token_pin(
|
||||
.keyring = "token-pin",
|
||||
.credential = "home.token-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, flags, &pin);
|
||||
@ -1241,6 +1244,7 @@ static int acquire_new_password(
|
||||
.keyring = "home-password",
|
||||
.credential = "home.new-password",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(
|
||||
|
@ -187,6 +187,7 @@ static int verb_validate(int argc, char *argv[], void *userdata) {
|
||||
.keyring = arg_private_key,
|
||||
.credential = "keyutil.private-key-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
},
|
||||
&private_key,
|
||||
&ui);
|
||||
@ -245,6 +246,7 @@ static int verb_public(int argc, char *argv[], void *userdata) {
|
||||
.keyring = arg_private_key,
|
||||
.credential = "keyutil.private-key-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
},
|
||||
&private_key,
|
||||
&ui);
|
||||
|
@ -893,6 +893,7 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
|
||||
.keyring = arg_private_key,
|
||||
.credential = "measure.private-key-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
},
|
||||
&privkey,
|
||||
&ui);
|
||||
|
@ -4555,6 +4555,7 @@ static int make_policy(bool force, RecoveryPinMode recovery_pin_mode) {
|
||||
.id = "pcrlock-recovery-pin",
|
||||
.credential = "pcrlock.recovery-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(
|
||||
|
@ -8577,6 +8577,7 @@ static int parse_argv(int argc, char *argv[], X509 **ret_certificate, EVP_PKEY *
|
||||
.keyring = arg_private_key,
|
||||
.credential = "repart.private-key-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
},
|
||||
&private_key,
|
||||
&ui);
|
||||
|
@ -208,6 +208,7 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
|
||||
.keyring = arg_private_key,
|
||||
.credential = "sbsign.private-key-pin",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
},
|
||||
&private_key,
|
||||
&ui);
|
||||
|
@ -355,15 +355,30 @@ int ask_password_plymouth(
|
||||
|
||||
enum {
|
||||
POLL_SOCKET,
|
||||
POLL_INOTIFY, /* Must be last, because optional */
|
||||
POLL_TWO,
|
||||
POLL_THREE,
|
||||
_POLL_MAX,
|
||||
};
|
||||
|
||||
struct pollfd pollfd[_POLL_MAX] = {
|
||||
[POLL_SOCKET] = { .fd = fd, .events = POLLIN },
|
||||
[POLL_INOTIFY] = { .fd = inotify_fd, .events = POLLIN },
|
||||
[POLL_SOCKET] = {
|
||||
.fd = fd,
|
||||
.events = POLLIN,
|
||||
},
|
||||
};
|
||||
size_t n_pollfd = inotify_fd >= 0 ? _POLL_MAX : _POLL_MAX-1;
|
||||
size_t n_pollfd = POLL_SOCKET + 1, inotify_idx = SIZE_MAX, hup_fd_idx = SIZE_MAX;
|
||||
if (inotify_fd >= 0)
|
||||
pollfd[inotify_idx = n_pollfd++] = (struct pollfd) {
|
||||
.fd = inotify_fd,
|
||||
.events = POLLIN,
|
||||
};
|
||||
if (req->hup_fd >= 0)
|
||||
pollfd[hup_fd_idx = n_pollfd++] = (struct pollfd) {
|
||||
.fd = req->hup_fd,
|
||||
.events = POLLHUP,
|
||||
};
|
||||
|
||||
assert(n_pollfd <= _POLL_MAX);
|
||||
|
||||
for (;;) {
|
||||
usec_t timeout;
|
||||
@ -384,7 +399,10 @@ int ask_password_plymouth(
|
||||
if (r == 0)
|
||||
return -ETIME;
|
||||
|
||||
if (inotify_fd >= 0 && pollfd[POLL_INOTIFY].revents != 0)
|
||||
if (req->hup_fd >= 0 && pollfd[hup_fd_idx].revents & POLLHUP)
|
||||
return -ECONNRESET;
|
||||
|
||||
if (inotify_fd >= 0 && pollfd[inotify_idx].revents != 0)
|
||||
(void) flush_fd(inotify_fd);
|
||||
|
||||
if (pollfd[POLL_SOCKET].revents == 0)
|
||||
@ -567,15 +585,31 @@ int ask_password_tty(
|
||||
|
||||
enum {
|
||||
POLL_TTY,
|
||||
POLL_INOTIFY, /* Must be last, because optional */
|
||||
POLL_TWO,
|
||||
POLL_THREE,
|
||||
_POLL_MAX,
|
||||
};
|
||||
|
||||
struct pollfd pollfd[_POLL_MAX] = {
|
||||
[POLL_TTY] = { .fd = ttyfd >= 0 ? ttyfd : STDIN_FILENO, .events = POLLIN },
|
||||
[POLL_INOTIFY] = { .fd = inotify_fd, .events = POLLIN },
|
||||
[POLL_TTY] = {
|
||||
.fd = ttyfd >= 0 ? ttyfd : STDIN_FILENO,
|
||||
.events = POLLIN,
|
||||
},
|
||||
};
|
||||
size_t n_pollfd = inotify_fd >= 0 ? _POLL_MAX : _POLL_MAX-1;
|
||||
size_t n_pollfd = POLL_TTY + 1, inotify_idx = SIZE_MAX, hup_fd_idx = SIZE_MAX;
|
||||
|
||||
if (inotify_fd >= 0)
|
||||
pollfd[inotify_idx = n_pollfd++] = (struct pollfd) {
|
||||
.fd = inotify_fd,
|
||||
.events = POLLIN,
|
||||
};
|
||||
if (req->hup_fd >= 0)
|
||||
pollfd[hup_fd_idx = n_pollfd++] = (struct pollfd) {
|
||||
.fd = req->hup_fd,
|
||||
.events = POLLHUP,
|
||||
};
|
||||
|
||||
assert(n_pollfd <= _POLL_MAX);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_(erase_char) char c;
|
||||
@ -603,7 +637,12 @@ int ask_password_tty(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (inotify_fd >= 0 && pollfd[POLL_INOTIFY].revents != 0 && keyring) {
|
||||
if (req->hup_fd >= 0 && pollfd[hup_fd_idx].revents & POLLHUP) {
|
||||
r = -ECONNRESET;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (inotify_fd >= 0 && pollfd[inotify_idx].revents != 0 && keyring) {
|
||||
(void) flush_fd(inotify_fd);
|
||||
|
||||
r = ask_password_keyring(req, flags, ret);
|
||||
@ -924,16 +963,29 @@ int ask_password_agent(
|
||||
enum {
|
||||
POLL_SOCKET,
|
||||
POLL_SIGNAL,
|
||||
POLL_INOTIFY, /* Must be last, because optional */
|
||||
POLL_THREE,
|
||||
POLL_FOUR,
|
||||
_POLL_MAX
|
||||
};
|
||||
|
||||
struct pollfd pollfd[_POLL_MAX] = {
|
||||
[POLL_SOCKET] = { .fd = socket_fd, .events = POLLIN },
|
||||
[POLL_SIGNAL] = { .fd = signal_fd, .events = POLLIN },
|
||||
[POLL_INOTIFY] = { .fd = inotify_fd, .events = POLLIN },
|
||||
};
|
||||
size_t n_pollfd = inotify_fd >= 0 ? _POLL_MAX : _POLL_MAX - 1;
|
||||
size_t n_pollfd = POLL_SIGNAL + 1, inotify_idx = SIZE_MAX, hup_fd_idx = SIZE_MAX;
|
||||
|
||||
if (inotify_fd >= 0)
|
||||
pollfd[inotify_idx = n_pollfd++] = (struct pollfd) {
|
||||
.fd = inotify_fd,
|
||||
.events = POLLIN,
|
||||
};
|
||||
if (req->hup_fd >= 0)
|
||||
pollfd[hup_fd_idx = n_pollfd ++] = (struct pollfd) {
|
||||
.fd = req->hup_fd,
|
||||
.events = POLLHUP,
|
||||
};
|
||||
|
||||
assert(n_pollfd <= _POLL_MAX);
|
||||
|
||||
for (;;) {
|
||||
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
|
||||
@ -963,7 +1015,10 @@ int ask_password_agent(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (inotify_fd >= 0 && pollfd[POLL_INOTIFY].revents != 0) {
|
||||
if (req->hup_fd >= 0 && pollfd[hup_fd_idx].revents & POLLHUP)
|
||||
return -ECONNRESET;
|
||||
|
||||
if (inotify_fd >= 0 && pollfd[inotify_idx].revents != 0) {
|
||||
(void) flush_fd(inotify_fd);
|
||||
|
||||
if (req && req->keyring) {
|
||||
|
@ -29,6 +29,7 @@ typedef struct AskPasswordRequest {
|
||||
const char *flag_file; /* Once this flag file disappears abort the query */
|
||||
int tty_fd; /* If querying on a TTY, the TTY to query on (or -EBADF) */
|
||||
usec_t until; /* CLOCK_MONOTONIC time until which to show the prompt */
|
||||
int hup_fd; /* An extra fd to watch for POLLHUP, in which case to abort the query */
|
||||
} AskPasswordRequest;
|
||||
|
||||
int ask_password_tty(const AskPasswordRequest *req, AskPasswordFlags flags, char ***ret);
|
||||
|
@ -118,6 +118,7 @@ int acquire_fido2_key(
|
||||
.keyring = "fido2-pin",
|
||||
.credential = "cryptsetup.fido2-pin",
|
||||
.until = until,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
pins = strv_free_erase(pins);
|
||||
|
@ -41,6 +41,7 @@ static int get_pin(
|
||||
.keyring = "tpm2-pin",
|
||||
.credential = askpw_credential,
|
||||
.until = until,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
pin = strv_free_erase(pin);
|
||||
|
@ -3083,6 +3083,7 @@ int dissected_image_decrypt_interactively(
|
||||
.keyring = "dissect",
|
||||
.credential = "dissect.passphrase",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, /* flags= */ 0, &z);
|
||||
|
@ -863,6 +863,7 @@ int fido2_generate_hmac_hash(
|
||||
.keyring = "fido2-pin",
|
||||
.credential = askpw_credential,
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, /* flags= */ 0, &pin);
|
||||
|
@ -387,6 +387,7 @@ int pkcs11_token_login(
|
||||
.keyring = askpw_keyring,
|
||||
.credential = askpw_credential,
|
||||
.until = until,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
/* We never cache PINs, simply because it's fatal if we use wrong PINs, since usually there are only 3 tries */
|
||||
|
@ -13,6 +13,7 @@ TEST(ask_password) {
|
||||
.message = "hello?",
|
||||
.keyring = "da key",
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_tty(&req, /* flags= */ ASK_PASSWORD_CONSOLE_COLOR, &ret);
|
||||
|
@ -152,6 +152,7 @@ static int agent_ask_password_tty(
|
||||
.message = message,
|
||||
.flag_file = flag_file,
|
||||
.until = until,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_tty(&req, flags, ret);
|
||||
@ -260,6 +261,7 @@ static int process_one_password_file(const char *filename, FILE *f) {
|
||||
.message = message,
|
||||
.flag_file = filename,
|
||||
.until = not_after,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_plymouth(&req, flags, &passwords);
|
||||
|
Loading…
Reference in New Issue
Block a user