agent: Send the new SETKEYINFO command to the Pinentry.
authorWerner Koch <wk@gnupg.org>
Tue, 14 Apr 2015 16:41:05 +0000 (18:41 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 14 Apr 2015 16:41:05 +0000 (18:41 +0200)
* agent/call-pinentry.c (agent_askpin): Add args keyinfo and
cache_mode.  Change all callers to pass (NULL,0) for them.  Send
SETKEYINFO command.
* agent/findkey.c (unprotect): Pass the keygrip and the cache_mode for
the new args.

Signed-off-by: Werner Koch <wk@gnupg.org>
agent/agent.h
agent/call-pinentry.c
agent/command-ssh.c
agent/cvt-openpgp.c
agent/divert-scd.c
agent/findkey.c
agent/genkey.c

index 30d0ffb..2a2658d 100644 (file)
@@ -354,7 +354,8 @@ int pinentry_active_p (ctrl_t ctrl, int waitseconds);
 int agent_askpin (ctrl_t ctrl,
                   const char *desc_text, const char *prompt_text,
                   const char *inital_errtext,
-                  struct pin_entry_info_s *pininfo);
+                  struct pin_entry_info_s *pininfo,
+                  const char *keyinfo, cache_mode_t cache_mode);
 int agent_get_passphrase (ctrl_t ctrl, char **retpass,
                           const char *desc, const char *prompt,
                           const char *errtext, int with_qualitybar);
index 6db429c..d3a0547 100644 (file)
@@ -737,12 +737,14 @@ close_button_status_cb (void *opaque, const char *line)
 \f
 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
    number here and repeat it as long as we have invalid formed
-   numbers. */
+   numbers.  KEYINFO and CACHEMODE are used to tell pinentry something
+   about the key. */
 int
 agent_askpin (ctrl_t ctrl,
               const char *desc_text, const char *prompt_text,
               const char *initial_errtext,
-              struct pin_entry_info_s *pininfo)
+              struct pin_entry_info_s *pininfo,
+              const char *keyinfo, cache_mode_t cache_mode)
 {
   int rc;
   char line[ASSUAN_LINELENGTH];
@@ -802,6 +804,24 @@ agent_askpin (ctrl_t ctrl,
   if (rc)
     return rc;
 
+  /* If we have a KYEINFO string and are normal, user, or ssh cache
+     mode, we tell that the Pinentry so it may use it for own caching
+     purposes.  Most pinentries won't have this implemented and thus
+     we do not error out in this case.  */
+  if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
+                  || cache_mode == CACHE_MODE_USER
+                  || cache_mode == CACHE_MODE_SSH))
+    {
+      snprintf (line, DIM(line)-1, "SETKEYINFO %c/%s",
+                cache_mode == CACHE_MODE_USER? 'u' :
+                cache_mode == CACHE_MODE_SSH? 's' : 'n',
+                keyinfo);
+      rc = assuan_transact (entry_ctx, line,
+                            NULL, NULL, NULL, NULL, NULL, NULL);
+      if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
+        return unlock_pinentry (rc);
+    }
+
   snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
   line[DIM(line)-1] = 0;
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
index fffdb00..a517827 100644 (file)
@@ -3110,7 +3110,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
   pi2->check_cb_arg = pi->pin;
 
  next_try:
-  err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
+  err = agent_askpin (ctrl, description, NULL, initial_errtext, pi, NULL, 0);
   initial_errtext = NULL;
   if (err)
     goto out;
@@ -3119,7 +3119,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
      it already did the repetition check, ask to confirm it.  */
   if (*pi->pin && !pi->repeat_okay)
     {
-      err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
+      err = agent_askpin (ctrl, description2, NULL, NULL, pi2, NULL, 0);
       if (err == -1)
        { /* The re-entered one did not match and the user did not
             hit cancel. */
index b00f032..562179b 100644 (file)
@@ -961,7 +961,7 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp,
           err = try_do_unprotect_cb (pi);
         }
       if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE && !from_native)
-        err = agent_askpin (ctrl, prompt, NULL, NULL, pi);
+        err = agent_askpin (ctrl, prompt, NULL, NULL, pi, NULL, 0);
       skeyidx = pi_arg.skeyidx;
       if (!err && r_passphrase && is_protected)
         {
index 1408d65..0c287b4 100644 (file)
@@ -270,7 +270,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
 
   if (any_flags)
     {
-      rc = agent_askpin (ctrl, info, prompt, again_text, pi);
+      rc = agent_askpin (ctrl, info, prompt, again_text, pi, NULL, 0);
       again_text = NULL;
       if (!rc && newpin)
         {
@@ -292,7 +292,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
                               is_puk?
                               _("Repeat this PUK"):
                               _("Repeat this PIN")),
-                             prompt, NULL, pi2);
+                             prompt, NULL, pi2, NULL, 0);
           if (!rc && strcmp (pi->pin, pi2->pin))
             {
               again_text = (resetcode?
@@ -316,7 +316,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
                      info? info:"",
                      info? ")":"") < 0)
         desc = NULL;
-      rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi);
+      rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi, NULL, 0);
       xfree (desc);
     }
 
index 6f01789..80771c5 100644 (file)
@@ -463,7 +463,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
   arg.change_required = 0;
   pi->check_cb_arg = &arg;
 
-  rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
+  rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi, hexgrip, cache_mode);
   if (!rc)
     {
       assert (arg.unprotected_key);
index ecf676e..30fc44d 100644 (file)
@@ -370,7 +370,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
   pi2->check_cb_arg = pi->pin;
 
  next_try:
-  err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi);
+  err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi, NULL, 0);
   initial_errtext = NULL;
   if (!err)
     {
@@ -384,7 +384,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
          it already did the repetition check, ask to confirm it.  */
       if (*pi->pin && !pi->repeat_okay)
         {
-          err = agent_askpin (ctrl, text2, NULL, NULL, pi2);
+          err = agent_askpin (ctrl, text2, NULL, NULL, pi2, NULL, 0);
           if (err == -1)
             { /* The re-entered one did not match and the user did not
                  hit cancel. */