1
0
mirror of https://github.com/systemd/systemd.git synced 2025-02-03 17:47:28 +03:00

ask-password: Allow configuring the keyring timeout via an environment variable

In mkosi, we want an easy way to set the keyring timeout for every
tool we invoke that might use systemd-ask-password to query for a
password which is then stored in the kernel keyring. Let's make this
possible via a new $SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC environment
variable.

Using an environment variable means we don't have to modify every separate
tool to add a CLI option allowing to specify the timeout. In mkosi specifically,
we'll set up a new session keyring for the mkosi process linked to the user keyring
so that any pins in the user keyring are used if available, and otherwise we'll query
for and store password in mkosi's session keyring with a zero timeout so that they stay
in the keyring until the mkosi process exits at which point they're removed from the
keyring.
This commit is contained in:
Daan De Meyer 2024-10-30 13:53:31 +01:00 committed by Lennart Poettering
parent 14b0fcdf6d
commit d9f4dad986
2 changed files with 37 additions and 4 deletions

View File

@ -735,3 +735,12 @@ Tools using the Varlink protocol (such as `varlinkctl`) or sd-bus (such as
* `SYSTEMD_EXIT_ON_IDLE` Takes a boolean. When false, the exit-on-idle logic
of these services is disabled, making it easier to debug them.
`systemd-ask-password`:
* `$SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC` - takes a timespan or `default`,
which controls the expiration time of keys stored in the kernel keyring by
`systemd-ask-password`. If unset or set to `default`, the default expiration
of 150 seconds is used. If set to `0`, keys are not cached in the kernel
keyring. If set to `infinity`, keys are cached without an expiration time in
the kernel keyring.

View File

@ -22,6 +22,7 @@
#include "ansi-color.h"
#include "ask-password-api.h"
#include "creds-util.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
@ -113,6 +114,28 @@ static int touch_ask_password_directory(AskPasswordFlags flags) {
return 1; /* did something */
}
static usec_t keyring_cache_timeout(void) {
static usec_t saved_timeout = USEC_INFINITY;
static bool saved_timeout_set = false;
int r;
if (saved_timeout_set)
return saved_timeout;
const char *e = secure_getenv("SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC");
if (streq_ptr(e, "default"))
saved_timeout = KEYRING_TIMEOUT_USEC;
else if (e) {
r = parse_sec(e, &saved_timeout);
if (r < 0)
log_debug_errno(r, "Invalid value in $SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC, ignoring: %s", e);
}
saved_timeout_set = true;
return saved_timeout;
}
static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **passwords) {
_cleanup_strv_free_erase_ char **l = NULL;
_cleanup_(erase_and_freep) char *p = NULL;
@ -122,7 +145,7 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
assert(keyname);
if (!FLAGS_SET(flags, ASK_PASSWORD_PUSH_CACHE))
if (!FLAGS_SET(flags, ASK_PASSWORD_PUSH_CACHE) || keyring_cache_timeout() == 0)
return 0;
if (strv_isempty(passwords))
return 0;
@ -151,9 +174,10 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
if (serial == -1)
return -errno;
if (keyctl(KEYCTL_SET_TIMEOUT,
(unsigned long) serial,
(unsigned long) DIV_ROUND_UP(KEYRING_TIMEOUT_USEC, USEC_PER_SEC), 0, 0) < 0)
if (keyring_cache_timeout() != USEC_INFINITY &&
keyctl(KEYCTL_SET_TIMEOUT,
(unsigned long) serial,
(unsigned long) DIV_ROUND_UP(keyring_cache_timeout(), USEC_PER_SEC), 0, 0) < 0)
log_debug_errno(errno, "Failed to adjust kernel keyring key timeout: %m");
/* Tell everyone to check the keyring */