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

Sam Overton via Gnupg-devel <[email protected]>
Newsgroups gmane.comp.encryption.gpg.devel
Message-ID <[email protected]>
* 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 <[email protected]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.