[PATCH GnuPG] agent: add pinentry-ignored-env configuration parameter

Sam Overton gpg at samoverton.dev
Sun Feb 9 03:09:16 CET 2025


* The pinentry-ignored-env parameter takes a CSV of environment
  variables that should not be passed from the client to the pinentry
  environment.

* This allows users running Flatpak applications to resolve the issue
  where an invalid DBUS_SESSION_BUS_ADDRESS is unavoidably passed from
  gpg (running inside the Flatpak) to pinentry (running on the host
  system).

  Addresses T7522

Signed-off-by: Sam Overton <gpg at samoverton.dev>
---
 agent/agent.h         |  4 ++++
 agent/call-pinentry.c | 39 +++++++++++++++++++++++++++++++++++++--
 agent/gpg-agent.c     |  8 ++++++++
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/agent/agent.h b/agent/agent.h
index 42b167726..ff9a79269 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -175,6 +175,10 @@ struct
      allow-emacs-prompt is allowed.  */
   int allow_emacs_pinentry;
 
+  /* Comma separated list of environment variables which must not be
+     passed from the client to pinentry */
+  const char *pinentry_ignored_env;
+
   int keep_tty;      /* Don't switch the TTY (for pinentry) on request */
   int keep_display;  /* Don't switch the DISPLAY (for pinentry) on request */
 
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index ba37a775e..86897ce29 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -203,6 +203,40 @@ unlock_pinentry (ctrl_t ctrl, gpg_error_t rc)
   return rc;
 }
 
+/* Allow configuration of which environment variables from the client to ignore
+ * when passing to pinentry. This helps to solve problems where the client has
+ * incorrect settings relative to the environment that the agent is running in,
+ * in particular DBUS_SESSION_BUS_ADDRESS passed from inside a container. */
+static int
+is_ignored_env_var(const char* name)
+{
+    const char* p = opt.pinentry_ignored_env;
+    const char* q = NULL;
+    size_t csv_len = 0;
+    size_t name_len = 0;
+
+    if (!name || !*name)
+        return 1;
+
+    if (!opt.pinentry_ignored_env || !*opt.pinentry_ignored_env)
+        return 0;
+
+    csv_len = strlen(opt.pinentry_ignored_env);
+    name_len = strlen(name);
+
+    while (p - opt.pinentry_ignored_env < csv_len)
+    {
+        /* q points at the NULL terminator if the separator is not found */
+        q = strchrnul(p, ',');
+
+        if ((q - p) == name_len && (0 == strncmp(name, p, q - p)))
+            return 1;
+
+        p = q + 1;
+    }
+
+    return 0;
+}
 
 /* Helper for at_fork_cb which can also be called by the parent to
  * show which envvars will be set.  */
@@ -224,10 +258,11 @@ atfork_core (ctrl_t ctrl, int debug_mode)
        * envvar like "QT_QPA_PLATFORMTHEME=qt5ct" which for example is
        * useful when using the Qt pinentry under GNOME or XFCE.
        */
-      if (!assname
+      if ( !is_ignored_env_var(name) &&
+             (!assname
           || (!opt.keep_display && !strcmp (name, "DISPLAY"))
           || !strcmp (name, "XAUTHORITY")
-          || !strcmp (name, "PINENTRY_USER_DATA"))
+          || !strcmp (name, "PINENTRY_USER_DATA")))
         {
           value = session_env_getenv (ctrl->session_env, name);
           if (value)
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 758824144..58b2b452b 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -133,6 +133,7 @@ enum cmd_and_opt_values
   oNoAllowLoopbackPinentry,
   oNoAllowExternalCache,
   oAllowEmacsPinentry,
+  oPinentryIgnoredEnv,
   oKeepTTY,
   oKeepDISPLAY,
   oSSHSupport,
@@ -303,6 +304,8 @@ static gpgrt_opt_t opts[] = {
                 "@"),
   ARGPARSE_s_n (oAllowEmacsPinentry,  "allow-emacs-pinentry",
                 N_("allow passphrase to be prompted through Emacs")),
+  ARGPARSE_s_s (oPinentryIgnoredEnv, "pinentry-ignored-env",
+                N_("Comma-separated list of environment variables to ignore")),
 
 
   /* Dummy options for backward compatibility.  */
@@ -904,6 +907,7 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
       opt.allow_external_cache = 1;
       opt.allow_loopback_pinentry = 1;
       opt.allow_emacs_pinentry = 0;
+      opt.pinentry_ignored_env = NULL;
       memset (opt.disable_daemon, 0, sizeof opt.disable_daemon);
       disable_check_own_socket = 0;
       /* Note: When changing the next line, change also gpgconf_list.  */
@@ -1007,6 +1011,10 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
     case oAllowEmacsPinentry: opt.allow_emacs_pinentry = 1;
       break;
 
+    case oPinentryIgnoredEnv:
+      opt.pinentry_ignored_env = pargs->r.ret_str;
+      break;
+
     case oSSHFingerprintDigest:
       i = gcry_md_map_name (pargs->r.ret_str);
       if (!i)
-- 
2.47.2




More information about the Gnupg-devel mailing list