1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-18 10:04:04 +03:00

ask-password: Add $SYSTEMD_ASK_PASSWORD_KEYRING_TYPE

Currently ask_password_auto() will always try to store the password into
the user keyring. Let's make this configurable so that we can configure
ask_password_auto() into the session keyring. This is required when working
with user namespaces, as the user keyring is namespaced by user namespaces
which makes it impossible to share cached keys across user namespaces by using
the user namespace while this is possible with the session keyring.
This commit is contained in:
Daan De Meyer 2024-10-30 23:45:38 +01:00
parent 01d138b990
commit 36c6c696a7
2 changed files with 50 additions and 1 deletions

View File

@ -743,3 +743,8 @@ Tools using the Varlink protocol (such as `varlinkctl`) or sd-bus (such as
If unset, 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.
* `SYSTEMD_ASK_PASSWORD_KEYRING_TYPE` - takes a keyring ID or one of `thread`,
`process`, `session`, `user`, `user-session`, or `group`. Controls the kernel
keyring in which `systemd-ask-password` caches the queried password. Defaults
to `user`.

View File

@ -44,6 +44,7 @@
#include "random-util.h"
#include "signal-util.h"
#include "socket-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
@ -54,6 +55,17 @@
#define KEYRING_TIMEOUT_USEC ((5 * USEC_PER_MINUTE) / 2)
static const char* keyring_table[] = {
[-KEY_SPEC_THREAD_KEYRING] = "thread",
[-KEY_SPEC_PROCESS_KEYRING] = "process",
[-KEY_SPEC_SESSION_KEYRING] = "session",
[-KEY_SPEC_USER_KEYRING] = "user",
[-KEY_SPEC_USER_SESSION_KEYRING] = "user-session",
[-KEY_SPEC_GROUP_KEYRING] = "group",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(keyring, int);
static int lookup_key(const char *keyname, key_serial_t *ret) {
key_serial_t serial;
@ -134,6 +146,38 @@ static usec_t keyring_cache_timeout(void) {
return saved_timeout;
}
static key_serial_t keyring_cache_type(void) {
static key_serial_t saved_keyring = KEY_SPEC_USER_KEYRING;
static bool saved_keyring_set = false;
int r;
if (saved_keyring_set)
return saved_keyring;
const char *e = secure_getenv("SYSTEMD_ASK_PASSWORD_KEYRING_TYPE");
if (e) {
key_serial_t keyring;
r = safe_atoi32(e, &keyring);
if (r >= 0)
if (keyring < 0)
log_debug_errno(keyring, "Invalid value in $SYSTEMD_ASK_PASSWORD_KEYRING_TYPE, ignoring: %s", e);
else
saved_keyring = keyring;
else {
keyring = keyring_from_string(e);
if (keyring < 0)
log_debug_errno(keyring, "Invalid value in $SYSTEMD_ASK_PASSWORD_KEYRING_TYPE, ignoring: %s", e);
else
saved_keyring = -keyring;
}
}
saved_keyring_set = true;
return saved_keyring;
}
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;
@ -168,7 +212,7 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
* have multiple passwords. */
n = LESS_BY(n, (size_t) 1);
serial = add_key("user", keyname, p, n, KEY_SPEC_USER_KEYRING);
serial = add_key("user", keyname, p, n, keyring_cache_type());
if (serial == -1)
return -errno;