[PATCH 1/1] gpg-agent: add new option --cancel-card-pinentry

Curt Brune curt at brune.net
Fri Dec 16 02:58:37 CET 2016


This patch adds a new boolean global option to gpg-agent.

The goal is to suppress unneeded pinentry prompting when the inserted
smartcard's serial number does not match the requested serial number.

When the requested smartcard serial number does not match the inserted
card's serial number, automatically skip the card without prompting
the user.  This skips the launching of pinetry and moves on, as if the
user had selected "cancel".

This is convenient when decrypting a file encrypted for multiple
smartcard recipients, but only one smartcard is available.  In this
case only one pinetry will be shown to the user (the one for the
inserted card), while the remaining pinetry prompts for unavailable
smartcards will be suppressed.

Signed-off-by: Curt Brune <curt at brune.net>
---
 agent/agent.h        |  7 +++++++
 agent/divert-scd.c   |  5 +++++
 agent/gpg-agent.c    |  7 +++++++
 doc/gpg-agent.texi   | 16 ++++++++++++++++
 tools/gpgconf-comp.c |  3 +++
 5 files changed, 38 insertions(+)

diff --git a/agent/agent.h b/agent/agent.h
index c2726bb..14d1a3b 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -158,20 +158,27 @@ struct
   /* This global options indicates the use of an extra socket. Note
      that we use a hack for cleanup handling in gpg-agent.c: If the
      value is less than 2 the name has not yet been malloced. */
   int extra_socket;
 
   /* This global options indicates the use of an extra socket for web
      browsers. Note that we use a hack for cleanup handling in
      gpg-agent.c: If the value is less than 2 the name has not yet
      been malloced. */
   int browser_socket;
+
+  /* If this global option is true, then when a smartcard serial
+     number does not match the requested serial number, automatically
+     assume the user wants to skip this card.  This skips the
+     launching of pinetry and moves on, as if the user had selected
+     "cancel". */
+  int cancel_card_pinentry;
 } opt;
 
 
 /* Bit values for the --debug option.  */
 #define DBG_COMMAND_VALUE 1	/* debug commands i/o */
 #define DBG_MPI_VALUE	  2	/* debug mpi details */
 #define DBG_CRYPTO_VALUE  4	/* debug low level crypto */
 #define DBG_MEMORY_VALUE  32	/* debug memory allocation stuff */
 #define DBG_CACHE_VALUE   64	/* debug the caching */
 #define DBG_MEMSTAT_VALUE 128	/* show memory statistics */
diff --git a/agent/divert-scd.c b/agent/divert-scd.c
index 5d3b1ef..7e8c7fb 100644
--- a/agent/divert-scd.c
+++ b/agent/divert-scd.c
@@ -64,20 +64,25 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
           log_debug ("detected card with S/N %s\n", serialno);
           i = strcmp (serialno, want_sn);
           xfree (serialno);
           serialno = NULL;
           if (!i)
             {
               xfree (want_sn);
               *r_kid = want_kid;
               return 0; /* yes, we have the correct card */
             }
+          if (opt.cancel_card_pinentry)
+            {
+              log_debug ("automatically skipping card with mismatched S/N\n");
+              rc = gpg_error (GPG_ERR_CANCELED);
+            }
         }
       else if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT)
         {
           log_debug ("no card present\n");
           rc = 0;
           no_card = 1;
         }
       else
         {
           log_error ("error accessing card: %s\n", gpg_strerror (rc));
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 8aab2b9..54ff4ca 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -117,20 +117,21 @@ enum cmd_and_opt_values
   oBrowserSocket,
   oFakedSystemTime,
 
   oIgnoreCacheForSigning,
   oAllowMarkTrusted,
   oNoAllowMarkTrusted,
   oAllowPresetPassphrase,
   oAllowLoopbackPinentry,
   oNoAllowExternalCache,
   oAllowEmacsPinentry,
+  oCancelCardPinentry,
   oKeepTTY,
   oKeepDISPLAY,
   oSSHSupport,
   oPuttySupport,
   oDisableScdaemon,
   oDisableCheckOwnSocket,
   oWriteEnvFile
 };
 
 
@@ -217,20 +218,22 @@ static ARGPARSE_OPTS opts[] = {
                 /* */    N_("disallow the use of an external password cache")),
   ARGPARSE_s_n (oNoAllowMarkTrusted, "no-allow-mark-trusted",
                 /* */    N_("disallow clients to mark keys as \"trusted\"")),
   ARGPARSE_s_n (oAllowMarkTrusted,   "allow-mark-trusted", "@"),
   ARGPARSE_s_n (oAllowPresetPassphrase, "allow-preset-passphrase",
                 /* */                    N_("allow presetting passphrase")),
   ARGPARSE_s_n (oAllowLoopbackPinentry, "allow-loopback-pinentry",
                                    N_("allow caller to override the pinentry")),
   ARGPARSE_s_n (oAllowEmacsPinentry,  "allow-emacs-pinentry",
                 /* */    N_("allow passphrase to be prompted through Emacs")),
+  ARGPARSE_s_n (oCancelCardPinentry,  "cancel-card-pinentry",
+                /* */    N_("cancel pinentry display for card with mismatched S/N")),
 
   ARGPARSE_s_n (oSSHSupport,   "enable-ssh-support", N_("enable ssh support")),
   ARGPARSE_s_n (oPuttySupport, "enable-putty-support",
 #ifdef HAVE_W32_SYSTEM
                 /* */           N_("enable putty support")
 #else
                 /* */           "@"
 #endif
                 ),
 
@@ -967,20 +970,24 @@ main (int argc, char **argv )
             time_t faked_time = isotime2epoch (pargs.r.ret_str);
             if (faked_time == (time_t)(-1))
               faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
             gnupg_set_time (faked_time, 0);
           }
           break;
 
         case oKeepTTY: opt.keep_tty = 1; break;
         case oKeepDISPLAY: opt.keep_display = 1; break;
 
+	case oCancelCardPinentry:
+          opt.cancel_card_pinentry = 1;
+          break;
+
 	case oSSHSupport:
           ssh_support = 1;
           break;
         case oPuttySupport:
 #        ifdef HAVE_W32_SYSTEM
           putty_support = 1;
 #        endif
           break;
 
         case oExtraSocket:
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index f4da9cf..bb22464 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -497,20 +497,36 @@ pinentry to pop up at the @code{tty} or display you started the agent.
 @opindex extra-socket
 Also listen on native gpg-agent connections on the given socket.  The
 intended use for this extra socket is to setup a Unix domain socket
 forwarding from a remote machine to this socket on the local machine.
 A @command{gpg} running on the remote machine may then connect to the
 local gpg-agent and use its private keys.  This allows to decrypt or
 sign data on a remote machine without exposing the private keys to the
 remote machine.
 
 
+ at anchor{option --cancel-card-pinentry}
+ at item --cancel-card-pinentry
+ at opindex cancel-card-pinentry
+
+When the requested smartcard serial number does not match the inserted
+card's serial number, automatically skip the card without prompting
+the user.  This skips the launching of pinetry and moves on, as if the
+user had selected "cancel".
+
+This is convenient when decrypting a file encrypted for multiple
+smartcard recipients, but only one smartcard is available.  In this
+case only one pinetry will be shown to the user (the one for the
+inserted card), while the remaining pinetry prompts for unavailable
+smartcards will be suppressed.
+
+
 @anchor{option --enable-ssh-support}
 @item --enable-ssh-support
 @itemx --enable-putty-support
 @opindex enable-ssh-support
 @opindex enable-putty-support
 
 Enable the OpenSSH Agent protocol.
 
 In this mode of operation, the agent does not only implement the
 gpg-agent protocol, but also the agent protocol used by OpenSSH
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index 45e5c90..441f46a 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -489,20 +489,23 @@ static gc_option_t gc_options_gpg_agent[] =
 
    { "Configuration",
      GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
      "gnupg", N_("Options controlling the configuration") },
    { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
      "gnupg", "|FILE|read options from FILE",
      GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
    { "disable-scdaemon", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
      "gnupg", "do not use the SCdaemon",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
+   { "cancel-card-pinentry", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
+     "gnupg", "cancel card pinentry on mismatched serial number",
+     GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
    { "enable-ssh-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
      "gnupg", "enable ssh support",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
    { "enable-putty-support", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
      "gnupg", "enable putty support",
      GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
 
    { "Debug",
      GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
      "gnupg", N_("Options useful for debugging") },
-- 
2.7.4




More information about the Gnupg-devel mailing list