]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ask-password: Add $SYSTEMD_ASK_PASSWORD_KEYRING_TYPE
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 30 Oct 2024 22:45:38 +0000 (23:45 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 2 Nov 2024 22:20:57 +0000 (23:20 +0100)
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.

docs/ENVIRONMENT.md
src/shared/ask-password-api.c

index b0b30949fbbc8becf663102c8d302df45253016e..30c987f83411fcd2703ec870942b7becef3a4db7 100644 (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`.
index eba647aaef83a6b24619b1c81bcc65018081cf49..2e49096f820fccb049ac4f3e0c25205185adde9b 100644 (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"
 
 #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;