agent,tests,w32: Fix relaying pinentry user data, fix fake-pinentry.
authorJustus Winter <justus@g10code.com>
Tue, 25 Oct 2016 15:07:08 +0000 (17:07 +0200)
committerJustus Winter <justus@g10code.com>
Tue, 25 Oct 2016 15:07:08 +0000 (17:07 +0200)
* agent/call-pinentry.c (start_pinentry): Also send the user data
using an Assuan 'OPTION' command.
* tests/openpgp/fake-pinentry.c (get_passphrase): Fix updating
passphrase file.
(spacep): Include newline characters.
(rstrip): New function.
(main): Handle Windows line endings.  Handle the userdata option, and
restart with the new options.

Signed-off-by: Justus Winter <justus@g10code.com>
agent/call-pinentry.c
tests/openpgp/fake-pinentry.c

index 46db9e8..813df9a 100644 (file)
@@ -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);
index ce89765..90e086c 100644 (file)
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
+#include <unistd.h>
 
 FILE *log_stream;
 
@@ -109,12 +111,39 @@ get_passphrase (const char *fname)
 
   fclose (source);
   fclose (sink);
-  rename (fname_new, fname);
+  if (unlink (fname))
+    {
+      fprintf (stderr, "Failed to remove %s: %s",
+               fname, strerror (errno));
+      exit (1);
+    }
+
+  if (rename (fname_new, fname))
+    {
+      fprintf (stderr, "Failed to rename %s to %s: %s",
+               fname, fname_new, strerror (errno));
+      exit (1);
+    }
   return passphrase;
 }
 
 \f
-#define spacep(p)   (*(p) == ' ' || *(p) == '\t')
+#define spacep(p)   (*(p) == ' ' || *(p) == '\t' \
+                     || *(p) == '\r' || *(p) == '\n')
+
+/* rstrip line.  */
+void
+rstrip (char *buffer)
+{
+  char *p;
+  for (p = buffer + strlen (buffer) - 1; p >= buffer; p--)
+    {
+      if (! spacep (p))
+        break;
+      *p = 0;
+    }
+}
+
 
 /* Skip over options in LINE.
 
@@ -165,6 +194,8 @@ int
 main (int argc, char **argv)
 {
   char *args;
+  char *option_user_data = NULL;
+  int got_environment_user_data;
   char *logfile;
   char *passphrasefile;
   char *passphrase;
@@ -176,9 +207,11 @@ main (int argc, char **argv)
   setvbuf (stdout, NULL, _IOLBF, BUFSIZ);
 
   args = getenv ("PINENTRY_USER_DATA");
+  got_environment_user_data = args != NULL;
   if (! args)
     args = "";
 
+ restart:
   logfile = option_value (args, "--logfile");
   if (logfile)
     {
@@ -215,9 +248,7 @@ main (int argc, char **argv)
           return 1;
         }
 
-      p = passphrase + strlen (passphrase) - 1;
-      if (*p == '\n')
-        *p = 0;
+      rstrip (passphrase);
     }
   else
     {
@@ -226,12 +257,13 @@ main (int argc, char **argv)
         passphrase = "no PINENTRY_USER_DATA -- using default passphrase";
     }
 
-  reply ("# fake-pinentry started.  Passphrase='%s'.\n", passphrase);
+  reply ("# fake-pinentry(%d) started.  Passphrase='%s'.\n",
+         getpid (), passphrase);
   reply ("OK - what's up?\n");
 
   while (! feof (stdin))
     {
-      char buffer[1024];
+      char buffer[1024], *p;
 
       if (fgets (buffer, sizeof buffer, stdin) == NULL)
        break;
@@ -239,6 +271,8 @@ main (int argc, char **argv)
       if (log_stream)
         fprintf (log_stream, "< %s", buffer);
 
+      rstrip (buffer);
+
       if (strncmp (buffer, "GETPIN", 6) == 0)
         reply ("D %s\n", passphrase);
       else if (strncmp (buffer, "BYE", 3) == 0)
@@ -246,6 +280,22 @@ main (int argc, char **argv)
          reply ("OK\n");
          break;
        }
+#define OPT_USER_DATA  "OPTION pinentry-user-data="
+      else if (strncmp (buffer, OPT_USER_DATA, strlen (OPT_USER_DATA)) == 0)
+        {
+          if (got_environment_user_data)
+            {
+              reply ("OK - I already got the data from the environment.\n");
+              continue;
+            }
+
+          if (log_stream)
+            fclose (log_stream);
+          log_stream = NULL;
+          free (option_user_data);
+          option_user_data = args = strdup (buffer + strlen (OPT_USER_DATA));
+          goto restart;
+        }
 
       reply ("OK\n");
     }
@@ -254,5 +304,6 @@ main (int argc, char **argv)
   if (log_stream)
     fclose (log_stream);
 
+  free (option_user_data);
   return 0;
 }