agent,tests,w32: Fix relaying pinentry user data, fix fake-pinentry.
[gnupg.git] / agent / call-pinentry.c
index 5092375..813df9a 100644 (file)
@@ -226,7 +226,7 @@ getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
 }
 
 /* Fork off the pin entry if this has not already been done.  Note,
-   that this function must always be used to aquire the lock for the
+   that this function must always be used to acquire the lock for the
    pinentry - we will serialize _all_ pinentry calls.
  */
 static gpg_error_t
@@ -354,6 +354,19 @@ start_pinentry (ctrl_t ctrl)
   if (DBG_IPC)
     log_debug ("connection to PIN entry established\n");
 
+  value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA");
+  if (value != NULL)
+    {
+      char *optstr;
+      if (asprintf (&optstr, "OPTION pinentry-user-data=%s", value) < 0 )
+       return unlock_pinentry (out_of_core ());
+      rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
+                           NULL);
+      xfree (optstr);
+      if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
+        return unlock_pinentry (rc);
+    }
+
   rc = assuan_transact (entry_ctx,
                         opt.no_grab? "OPTION no-grab":"OPTION grab",
                         NULL, NULL, NULL, NULL, NULL, NULL);
@@ -491,6 +504,18 @@ start_pinentry (ctrl_t ctrl)
         }
     }
 
+  if (opt.pinentry_timeout)
+    {
+      char *optstr;
+      if ((optstr = xtryasprintf ("SETTIMEOUT %lu", opt.pinentry_timeout)))
+        {
+          assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
+                           NULL);
+          /* We ignore errors because this is just a fancy thing.  */
+          xfree (optstr);
+        }
+    }
+
   /* Tell the pinentry the name of a file it shall touch after having
      messed with the tty.  This is optional and only supported by
      newer pinentries and thus we do no error checking. */
@@ -717,11 +742,12 @@ setup_qualitybar (ctrl_t ctrl)
   char *tmpstr, *tmpstr2;
   const char *tooltip;
 
+  (void)ctrl;
+
   /* TRANSLATORS: This string is displayed by Pinentry as the label
      for the quality bar.  */
   tmpstr = try_percent_escape (L_("Quality:"), "\t\r\n\f\v");
-  snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:"");
-  line[DIM(line)-1] = 0;
+  snprintf (line, DIM(line), "SETQUALITYBAR %s", tmpstr? tmpstr:"");
   xfree (tmpstr);
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   if (rc == 103 /*(Old assuan error code)*/
@@ -749,8 +775,7 @@ setup_qualitybar (ctrl_t ctrl)
     }
   tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
   xfree (tmpstr2);
-  snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
-  line[DIM(line)-1] = 0;
+  snprintf (line, DIM(line), "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
   xfree (tmpstr);
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   if (rc == 103 /*(Old assuan error code)*/
@@ -873,27 +898,25 @@ agent_askpin (ctrl_t ctrl,
   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",
+    snprintf (line, DIM(line), "SETKEYINFO %c/%s",
              cache_mode == CACHE_MODE_USER? 'u' :
              cache_mode == CACHE_MODE_SSH? 's' : 'n',
              keyinfo);
   else
-    snprintf (line, DIM(line)-1, "SETKEYINFO --clear");
+    snprintf (line, DIM(line), "SETKEYINFO --clear");
 
   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;
+  snprintf (line, DIM(line), "SETDESC %s", desc_text);
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   if (rc)
     return unlock_pinentry (rc);
 
-  snprintf (line, DIM(line)-1, "SETPROMPT %s",
+  snprintf (line, DIM(line), "SETPROMPT %s",
             prompt_text? prompt_text : is_pin? L_("PIN:") : L_("Passphrase:"));
-  line[DIM(line)-1] = 0;
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   if (rc)
     return unlock_pinentry (rc);
@@ -910,8 +933,7 @@ agent_askpin (ctrl_t ctrl,
 
   if (initial_errtext)
     {
-      snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext);
-      line[DIM(line)-1] = 0;
+      snprintf (line, DIM(line), "SETERROR %s", initial_errtext);
       rc = assuan_transact (entry_ctx, line,
                             NULL, NULL, NULL, NULL, NULL, NULL);
       if (rc)
@@ -920,9 +942,8 @@ agent_askpin (ctrl_t ctrl,
 
   if (pininfo->with_repeat)
     {
-      snprintf (line, DIM(line)-1, "SETREPEATERROR %s",
+      snprintf (line, DIM(line), "SETREPEATERROR %s",
                 L_("does not match - try again"));
-      line[DIM(line)-1] = 0;
       rc = assuan_transact (entry_ctx, line,
                             NULL, NULL, NULL, NULL, NULL, NULL);
       if (rc)
@@ -942,9 +963,8 @@ agent_askpin (ctrl_t ctrl,
           /* TRANSLATORS: The string is appended to an error message in
              the pinentry.  The %s is the actual error message, the
              two %d give the current and maximum number of tries. */
-          snprintf (line, DIM(line)-1, L_("SETERROR %s (try %d of %d)"),
+          snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"),
                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
-          line[DIM(line)-1] = 0;
           rc = assuan_transact (entry_ctx, line,
                                 NULL, NULL, NULL, NULL, NULL, NULL);
           if (rc)
@@ -954,8 +974,7 @@ agent_askpin (ctrl_t ctrl,
 
       if (pininfo->with_repeat)
         {
-          snprintf (line, DIM(line)-1, "SETREPEAT %s", L_("Repeat:"));
-          line[DIM(line)-1] = 0;
+          snprintf (line, DIM(line), "SETREPEAT %s", L_("Repeat:"));
           rc = assuan_transact (entry_ctx, line,
                                 NULL, NULL, NULL, NULL, NULL, NULL);
           if (rc)
@@ -1064,15 +1083,9 @@ agent_get_passphrase (ctrl_t ctrl,
         {
          size_t size;
          size_t len = ASSUAN_LINELENGTH/2;
-         unsigned char *buffer;
 
-         rc = pinentry_loopback(ctrl, "PASSPHRASE", &buffer, &size, len);
-         if (!rc)
-           {
-             buffer[size] = 0;
-             *retpass = buffer;
-           }
-         return rc;
+         return pinentry_loopback (ctrl, "PASSPHRASE",
+                                   (unsigned char **)retpass, &size, len);
         }
       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
     }
@@ -1092,12 +1105,12 @@ agent_get_passphrase (ctrl_t ctrl,
   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",
+    snprintf (line, DIM(line), "SETKEYINFO %c/%s",
              cache_mode == CACHE_MODE_USER? 'u' :
              cache_mode == CACHE_MODE_SSH? 's' : 'n',
              keyinfo);
   else
-    snprintf (line, DIM(line)-1, "SETKEYINFO --clear");
+    snprintf (line, DIM(line), "SETKEYINFO --clear");
 
   rc = assuan_transact (entry_ctx, line,
                        NULL, NULL, NULL, NULL, NULL, NULL);
@@ -1106,16 +1119,14 @@ agent_get_passphrase (ctrl_t ctrl,
 
 
   if (desc)
-    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
+    snprintf (line, DIM(line), "SETDESC %s", desc);
   else
-    snprintf (line, DIM(line)-1, "RESET");
-  line[DIM(line)-1] = 0;
+    snprintf (line, DIM(line), "RESET");
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   if (rc)
     return unlock_pinentry (rc);
 
-  snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
-  line[DIM(line)-1] = 0;
+  snprintf (line, DIM(line), "SETPROMPT %s", prompt);
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   if (rc)
     return unlock_pinentry (rc);
@@ -1129,8 +1140,7 @@ agent_get_passphrase (ctrl_t ctrl,
 
   if (errtext)
     {
-      snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
-      line[DIM(line)-1] = 0;
+      snprintf (line, DIM(line), "SETERROR %s", errtext);
       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
       if (rc)
         return unlock_pinentry (rc);
@@ -1197,10 +1207,9 @@ agent_get_confirmation (ctrl_t ctrl,
     return rc;
 
   if (desc)
-    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
+    snprintf (line, DIM(line), "SETDESC %s", desc);
   else
-    snprintf (line, DIM(line)-1, "RESET");
-  line[DIM(line)-1] = 0;
+    snprintf (line, DIM(line), "RESET");
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   /* Most pinentries out in the wild return the old Assuan error code
      for canceled which gets translated to an assuan Cancel error and
@@ -1213,8 +1222,7 @@ agent_get_confirmation (ctrl_t ctrl,
 
   if (ok)
     {
-      snprintf (line, DIM(line)-1, "SETOK %s", ok);
-      line[DIM(line)-1] = 0;
+      snprintf (line, DIM(line), "SETOK %s", ok);
       rc = assuan_transact (entry_ctx,
                             line, NULL, NULL, NULL, NULL, NULL, NULL);
       if (rc)
@@ -1227,8 +1235,7 @@ agent_get_confirmation (ctrl_t ctrl,
          the standard cancel.  */
       if (with_cancel)
         {
-          snprintf (line, DIM(line)-1, "SETNOTOK %s", notok);
-          line[DIM(line)-1] = 0;
+          snprintf (line, DIM(line), "SETNOTOK %s", notok);
           rc = assuan_transact (entry_ctx,
                                 line, NULL, NULL, NULL, NULL, NULL, NULL);
         }
@@ -1237,8 +1244,7 @@ agent_get_confirmation (ctrl_t ctrl,
 
       if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
        {
-         snprintf (line, DIM(line)-1, "SETCANCEL %s", notok);
-         line[DIM(line)-1] = 0;
+         snprintf (line, DIM(line), "SETCANCEL %s", notok);
          rc = assuan_transact (entry_ctx, line,
                                 NULL, NULL, NULL, NULL, NULL, NULL);
        }
@@ -1274,10 +1280,9 @@ agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
     return rc;
 
   if (desc)
-    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
+    snprintf (line, DIM(line), "SETDESC %s", desc);
   else
-    snprintf (line, DIM(line)-1, "RESET");
-  line[DIM(line)-1] = 0;
+    snprintf (line, DIM(line), "RESET");
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   /* Most pinentries out in the wild return the old Assuan error code
      for canceled which gets translated to an assuan Cancel error and
@@ -1290,8 +1295,7 @@ agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
 
   if (ok_btn)
     {
-      snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
-      line[DIM(line)-1] = 0;
+      snprintf (line, DIM(line), "SETOK %s", ok_btn);
       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL,
                             NULL, NULL, NULL);
       if (rc)
@@ -1346,18 +1350,16 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
     return rc;
 
   if (desc)
-    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
+    snprintf (line, DIM(line), "SETDESC %s", desc);
   else
-    snprintf (line, DIM(line)-1, "RESET");
-  line[DIM(line)-1] = 0;
+    snprintf (line, DIM(line), "RESET");
   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
   if (rc)
     return unlock_pinentry (rc);
 
   if (ok_btn)
     {
-      snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
-      line[DIM(line)-1] = 0;
+      snprintf (line, DIM(line), "SETOK %s", ok_btn);
       rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
       if (rc)
         return unlock_pinentry (rc);
@@ -1457,7 +1459,7 @@ agent_clear_passphrase (ctrl_t ctrl,
   if (rc)
     return rc;
 
-  snprintf (line, DIM(line)-1, "CLEARPASSPHRASE %c/%s",
+  snprintf (line, DIM(line), "CLEARPASSPHRASE %c/%s",
            cache_mode == CACHE_MODE_USER? 'u' :
            cache_mode == CACHE_MODE_SSH? 's' : 'n',
            keyinfo);