]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
import: Support env var to override gpg keyring
authorKai Lüke <kai@amutable.com>
Wed, 29 Apr 2026 06:06:32 +0000 (15:06 +0900)
committerKai Lüke <kai@amutable.com>
Wed, 1 Jul 2026 13:00:48 +0000 (22:00 +0900)
By default there is a fixed keyring in /usr or /etc. But when running
systemd-pull unprivileged in the user context or with a custom transfer
definition as in systemd-sysupdate --definitions=./... (e.g., for local
ParticleOS updates) it is limiting to require that all keys have to be
part of the OS keyring or otherwise no verification can be used. Also,
for testing it is valuable to point it at a different keyring.
Add a SYSTEMD_OPENPGP_KEYRING env var where the omission or empty
assignment sticks to the current behavior of the global OS keyrings but
a keyring path given will take precedence. While an env var can leak
down the process tree and is more difficult to secure for being the
trust anchor the advantage is that one can directly specify it in the
service unit as drop-in instead of having to patch the command
invocation. Anyway it's a niche use case and thus not part of the man
page.

docs/ENVIRONMENT.md
src/import/pull-common.c

index 31f180beea973823f61c88f9ec61e29c8c96388e..1d2498e206f6d75d3137b0127bebd09d323cd402 100644 (file)
@@ -508,6 +508,16 @@ is suppressed by default.
   operation. If not set, defaults to true. If disabled installation of images
   will be quicker, but not as safe.
 
+`systemd-importd`/`systemd-pull` and `systemd-sysupdate`:
+
+* `$SYSTEMD_OPENPGP_KEYRING` — takes an absolute path to an OpenPGP keyring
+  file. If set and non-empty, signature verification on download uses this
+  keyring instead of the default `/etc/systemd/import-pubring.pgp` and
+  `/usr/lib/systemd/import-pubring.pgp` keyrings.
+  Useful when running unprivileged in the user context, with custom transfer
+  definitions (e.g. `systemd-sysupdate --definitions=…`), or for testing.
+  Has no effect when signature verification is disabled.
+
 `systemd-dissect`, `systemd-nspawn` and all other tools that may operate on
 disk images with `--image=` or similar:
 
index 2d36bf6e4ad02af3b0c8516df431bed46bf62d15..a2629392d0806dfac27a558757b4d988320d5f0b 100644 (file)
@@ -409,11 +409,19 @@ static int verify_gpg(
         _cleanup_(rm_rf_physical_and_freep) char *gpg_home = NULL;
         char sig_file_path[] = "/tmp/sigXXXXXX";
         _cleanup_(pidref_done_sigkill_wait) PidRef pidref = PIDREF_NULL;
+        const char *keyring_override;
         int r;
 
         assert(iovec_is_valid(payload));
         assert(iovec_is_valid(signature));
 
+        /* Support using a custom keyring, see docs/ENVIRONMENT.md. */
+        keyring_override = empty_to_null(secure_getenv("SYSTEMD_OPENPGP_KEYRING"));
+        if (keyring_override && !(path_is_absolute(keyring_override) && path_is_normalized(keyring_override)))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "$SYSTEMD_OPENPGP_KEYRING must be an absolute, normalized path, got '%s'.",
+                                       keyring_override);
+
         r = pipe2(gpg_pipe, O_CLOEXEC);
         if (r < 0)
                 return log_error_errno(errno, "Failed to create pipe for gpg: %m");
@@ -468,9 +476,11 @@ static int verify_gpg(
 
                 cmd[k++] = strjoina("--homedir=", gpg_home);
 
-                /* We add the user keyring only to the command line arguments, if it's around since gpg fails
-                 * otherwise. */
-                if (access(USER_KEYRING_PATH, F_OK) >= 0)
+                if (keyring_override)
+                        cmd[k++] = strjoina("--keyring=", keyring_override);
+                else if (access(USER_KEYRING_PATH, F_OK) >= 0) /* We add the user keyring only to the
+                                                                * command line arguments, if it's around
+                                                                * since gpg fails otherwise. */
                         cmd[k++] = "--keyring=" USER_KEYRING_PATH;
                 else if (access(USER_KEYRING_PATH_LEGACY, F_OK) >= 0)
                         cmd[k++] = "--keyring=" USER_KEYRING_PATH_LEGACY;