Chnages to supporta pinnetry notification
authorWerner Koch <wk@gnupg.org>
Thu, 14 Feb 2008 19:51:21 +0000 (19:51 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 14 Feb 2008 19:51:21 +0000 (19:51 +0000)
16 files changed:
assuan/ChangeLog
assuan/assuan-pipe-connect.c
gpgme/ChangeLog
gpgme/engine-gpgconf.c
gpgme/engine-gpgsm.c
gpgme/gpgme.h
gpgme/posix-io.c
gpgme/posix-util.c
gpgme/priv-io.h
gpgme/rungpg.c
gpgme/util.h
gpgme/version.c
gpgme/w32-glib-io.c
gpgme/w32-io.c
gpgme/w32-qt-io.cpp
gpgme/w32-util.c

index 65131625cc94a166b84e1dcea8497b96a0605004..22bc735362715598d7dbddec26d4a27f660c1226 100644 (file)
@@ -1,3 +1,8 @@
+2008-02-14  Werner Koch  <wk@g10code.com>
+
+       * assuan-pipe-connect.c (_gpgme_io_spawn): Adjust prototype.
+       (pipe_connect_gpgme, pipe_connect_gpgme): Adjust call.
+
 2008-01-04  Marcus Brinkmann  <marcus@g10code.de>
 
        * assuan-pipe-connect.c (_gpgme_io_pipe)
index 10f54c4390def4b3d6117de565df091e9094301b..32a62191c00374524b2f3e7b6c341950cf997e15 100644 (file)
@@ -44,7 +44,7 @@
 int _gpgme_io_pipe (int filedes[2], int inherit_idx);
 int _gpgme_io_spawn (const char *path, char **argv,
                     struct spawn_fd_item_s *fd_child_list,
-                    struct spawn_fd_item_s *fd_parent_list);
+                    struct spawn_fd_item_s *fd_parent_list, pid_t *r_pid);
 #endif
 
 /* Hacks for Slowaris.  */
@@ -643,7 +643,7 @@ pipe_connect_gpgme (assuan_context_t *ctx,
   child_fds[2].fd = -1;
 
   /* Start the process.  */
-  res = _gpgme_io_spawn (name, argv, child_fds, child_fds);
+  res = _gpgme_io_spawn (name, argv, child_fds, child_fds, NULL);
   if (res == -1)
     {
       _assuan_log_printf ("CreateProcess failed: %s\n", strerror (errno));
index 5bc5dca6d959a6a3da6827703b5976295d035b03..9ac1f61f3ea56a5e4e8c683fb76dd17b30c9354b 100644 (file)
@@ -1,3 +1,18 @@
+2008-02-14  Werner Koch  <wk@g10code.com>
+
+       * w32-io.c (_gpgme_io_spawn): Add arg R_PID to return the pid.
+       * posix-io.c (_gpgme_io_spawn): Ditto.
+       * w32-glib-io.c (_gpgme_io_spawn): Ditto.
+       * w32-qt-io.cpp (_gpgme_io_spawn): Ditto.
+       * priv-io.h (_gpgme_io_spawn): Adjust prototyp and change all callers.
+       * rungpg.c (start): Call _gpgme_allow_set_foregound_window.
+
+       * w32-util.c (_gpgme_allow_set_foregound_window): New.
+       * posix-util.c (_gpgme_allow_set_foregound_window): New.
+       * engine-gpgsm.c (default_inq_cb): New.
+       (gpgsm_new) [W32]: Enable pinentry notifications.
+       (status_handler): Handle inquiries.
+
 2008-01-30  Marcus Brinkmann  <marcus@g10code.de>
 
        * kdpipeiodevice.cpp: New version by Frank Osterfeld, fixes race
index 584bbea9a0ed46a8e951c38f14e60b5a2e838593..26cd45f41e9e3d4c8e2f221b3201ef592ca0c0b2 100644 (file)
@@ -219,7 +219,7 @@ gpgconf_read (void *engine, char *arg1, char *arg2,
   pfd[0].fd = rp[1];
   cfd[0].fd = rp[1];
 
-  status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, pfd);
+  status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, pfd, NULL);
   if (status < 0)
     {
       _gpgme_io_close (rp[0]);
@@ -630,7 +630,7 @@ gpgconf_write (void *engine, char *arg1, char *arg2, gpgme_data_t conf)
   pfd[0].fd = rp[0];
   cfd[0].fd = rp[0];
 
-  status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, pfd);
+  status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, pfd, NULL);
   if (status < 0)
     {
       _gpgme_io_close (rp[0]);
index 2993f09d427eae35c891539ac19ad3021db012a0..615648b09bba1f03628e20b07a52b0478fe73594 100644 (file)
@@ -285,6 +285,20 @@ map_assuan_error (gpg_error_t err)
 }
 
 
+/* This is the default inquiry callback.  We use it to handle the
+   Pinentry notifications.  */
+static gpgme_error_t
+default_inq_cb (engine_gpgsm_t gpgsm, const char *line)
+{
+  if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
+    {
+      _gpgme_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
+    }
+
+  return 0;
+}
+
+
 static gpgme_error_t
 gpgsm_cancel (void *engine)
 {
@@ -528,6 +542,19 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
         err = 0; /* This is an optional feature of gpgsm.  */
     }
 
+
+#ifdef HAVE_W32_SYSTEM
+  /* Under Windows we need to use AllowSetForegroundWindow.  Tell
+     gpgsm to tell us when it needs it.  */
+  if (!err)
+    {
+      err = assuan_transact (gpgsm->assuan_ctx, "OPTION allow-pinentry-notify",
+                             NULL, NULL, NULL, NULL, NULL, NULL);
+      if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
+        err = 0; /* This is a new feature of gpgsm.  */
+    }
+#endif /*HAVE_W32_SYSTEM*/
+
 #if !USE_DESCRIPTOR_PASSING
   if (!err
       && (_gpgme_io_set_close_notify (gpgsm->input_cb.fd,
@@ -861,7 +888,7 @@ status_handler (void *opaque, int fd)
                  "fd 0x%x: ERR line - mapped to: %s",
                   fd, err ? gpg_strerror (err) : "ok");
          /* Try our best to terminate the connection friendly.  */
-         //      assuan_write_line (gpgsm->assuan_ctx, "BYE");
+         /*      assuan_write_line (gpgsm->assuan_ctx, "BYE"); */
        }
       else if (linelen >= 2
               && line[0] == 'O' && line[1] == 'K'
@@ -1028,6 +1055,20 @@ status_handler (void *opaque, int fd)
                  "fd 0x%x: S line (%s) - final status: %s",
                   fd, line+2, err? gpg_strerror (err):"ok");
        }
+      else if (linelen >= 7
+               && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
+               && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
+               && line[6] == 'E' 
+               && (line[7] == '\0' || line[7] == ' '))
+        {
+          char *keyword = line+7;
+
+          while (*keyword == ' ')
+            keyword++;;
+          default_inq_cb (gpgsm, keyword);
+          assuan_write_line (gpgsm->assuan_ctx, "END");
+        }
+
     }
   while (!err && assuan_pending_line (gpgsm->assuan_ctx));
          
index 12ddee8a019d1110c0fd9929cba558f6de81cdb3..8ae4daff1698686dbe45ef6648f95bbdbd35d75c 100644 (file)
@@ -72,7 +72,7 @@ extern "C" {
    AM_PATH_GPGME macro) check that this header matches the installed
    library.  Warning: Do not edit the next line.  configure will do
    that for you!  */
-#define GPGME_VERSION "1.1.7-svn1300"
+#define GPGME_VERSION "1.1.7-svn1301"
 
 
 \f
index 6b793f1e2fdebfa12be6eeb2c19124265a00ea27..f2a616d293e7ed391a3fa31397a83b9e79d9c019 100644 (file)
@@ -235,7 +235,7 @@ _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal)
 int
 _gpgme_io_spawn (const char *path, char **argv,
                 struct spawn_fd_item_s *fd_child_list,
-                struct spawn_fd_item_s *fd_parent_list)
+                struct spawn_fd_item_s *fd_parent_list, pid_t *r_pid)
 {
   pid_t pid;
   int i;
@@ -358,6 +358,9 @@ _gpgme_io_spawn (const char *path, char **argv,
   for (i = 0; fd_parent_list[i].fd != -1; i++)
     _gpgme_io_close (fd_parent_list[i].fd);
 
+  if (r_pid)
+    *r_pid = pid;
+
   return TRACE_SYSRES (0);
 }
 
index 168dad6e42e68e10aa2654b0b7dbd9d53b313904..9e6694910ff3929ab3ae9937b27ed320d359ddf5 100644 (file)
@@ -65,3 +65,10 @@ _gpgme_get_conf_int (const char *key, int *value)
 {
   return 0;
 }
+
+void 
+_gpgme_allow_set_foregound_window (pid_t pid)
+{
+  (void)pid;
+  /* Not needed.  */
+}
index 5841dc9228a31e576e7f844f6bb53c2a36775553..b0bc367dc478ff4445465c5cccb6b555164a9828 100644 (file)
@@ -56,7 +56,7 @@ int _gpgme_io_set_nonblocking (int fd);
    fds in FD_CHILD_LIST in the child.  */
 int _gpgme_io_spawn (const char *path, char **argv,
                     struct spawn_fd_item_s *fd_child_list,
-                    struct spawn_fd_item_s *fd_parent_list);
+                    struct spawn_fd_item_s *fd_parent_list, pid_t *r_pid);
 int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock);
 
 /* Write the printable version of FD to the buffer BUF of length
index 0ffdc7c7a3e82d09420e24353a06489731f6a9ed..64a8ee2001d9c574e2f78173f02f947f25d2897c 100644 (file)
@@ -1226,6 +1226,7 @@ start (engine_gpg_t gpg)
   int i, n;
   int status;
   struct spawn_fd_item_s *fd_child_list, *fd_parent_list;
+  pid_t pid;
 
   if (!gpg)
     return gpg_error (GPG_ERR_INV_VALUE);
@@ -1309,7 +1310,7 @@ start (engine_gpg_t gpg)
 
   status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name :
                            _gpgme_get_gpg_path (),
-                           gpg->argv, fd_child_list, fd_parent_list);
+                           gpg->argv, fd_child_list, fd_parent_list, &pid);
   saved_errno = errno;
   free (fd_child_list);
   if (status == -1)
@@ -1356,6 +1357,8 @@ start (engine_gpg_t gpg)
        }
     }
 
+  _gpgme_allow_set_foregound_window (pid);
+
   gpg_io_event (gpg, GPGME_EVENT_START, NULL);
   
   /* fixme: check what data we can release here */
index 0cd6ab5c74139c78c7576f12a5eed14da91b9990..64e63c700be6d6476a1d8911d64a07318ce6784d 100644 (file)
@@ -33,6 +33,7 @@ const char *_gpgme_get_gpg_path (void);
 const char *_gpgme_get_gpgsm_path (void);
 const char *_gpgme_get_gpgconf_path (void);
 int _gpgme_get_conf_int (const char *key, int *value);
+void _gpgme_allow_set_foregound_window (pid_t pid);
 
 \f
 /*-- replacement functions in <funcname>.c --*/
index 03d7aa013b50c7c300f8a1d7a943c4164ab0c5db..f010249d187af0dd6cacbd3bc70b514af0c14048 100644 (file)
@@ -212,7 +212,7 @@ _gpgme_get_program_version (const char *const file_name)
   pfd[0].fd = rp[1];
   cfd[0].fd = rp[1];
 
-  status = _gpgme_io_spawn (file_name, argv, cfd, pfd);
+  status = _gpgme_io_spawn (file_name, argv, cfd, pfd, NULL);
   if (status < 0)
     {
       _gpgme_io_close (rp[0]);
index 3204b5785bbcb3de89a299b800f9744e2f1dace6..8b284304e576fc1b586f5e813e712247b14bc653 100644 (file)
@@ -450,7 +450,7 @@ build_commandline (char **argv)
 int
 _gpgme_io_spawn (const char *path, char **argv,
                 struct spawn_fd_item_s *fd_child_list,
-                struct spawn_fd_item_s *fd_parent_list)
+                struct spawn_fd_item_s *fd_parent_list, pid_t *r_pid)
 {
   SECURITY_ATTRIBUTES sec_attr;
   PROCESS_INFORMATION pi =
@@ -458,7 +458,7 @@ _gpgme_io_spawn (const char *path, char **argv,
       NULL,      /* returns process handle */
       0,         /* returns primary thread handle */
       0,         /* returns pid */
-      0         /* returns tid */
+      0          /* returns tid */
     };
   STARTUPINFO si;
   char *envblock = NULL;
@@ -593,7 +593,9 @@ _gpgme_io_spawn (const char *path, char **argv,
              "dwProcessID=%d, dwThreadId=%d",
              pi.hProcess, pi.hThread, 
              (int) pi.dwProcessId, (int) pi.dwThreadId);
-  
+  if (r_pid)
+    *r_pid = (pid_t)pi.dwProcessId;
+
   if (ResumeThread (pi.hThread) < 0)
     TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ());
   
index c4d2a1bf8b55dc293b738c214e4cdb1ec4136e8e..e7dad2c3d80cacc8712586628ffe7ae2058657f4 100644 (file)
@@ -1007,7 +1007,7 @@ build_commandline (char **argv)
 int
 _gpgme_io_spawn (const char *path, char **argv,
                 struct spawn_fd_item_s *fd_child_list,
-                struct spawn_fd_item_s *fd_parent_list)
+                struct spawn_fd_item_s *fd_parent_list, pid_t *r_pid)
 {
   SECURITY_ATTRIBUTES sec_attr;
   PROCESS_INFORMATION pi =
@@ -1015,7 +1015,7 @@ _gpgme_io_spawn (const char *path, char **argv,
       NULL,      /* returns process handle */
       0,         /* returns primary thread handle */
       0,         /* returns pid */
-      0         /* returns tid */
+      0          /* returns tid */
     };
   STARTUPINFO si;
   char *envblock = NULL;
@@ -1147,6 +1147,8 @@ _gpgme_io_spawn (const char *path, char **argv,
              "dwProcessID=%d, dwThreadId=%d",
              pi.hProcess, pi.hThread, 
              (int) pi.dwProcessId, (int) pi.dwThreadId);
+  if (r_pid)
+    *r_pid = (pid_t)pi.dwProcessId;
   
   if (ResumeThread (pi.hThread) < 0)
     TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ());
index ba43913c2467abcc950a94b35cff3f28c02e2d7a..9ccdff9af812cfeb8deeae1be9334ee10d0dc144 100644 (file)
@@ -399,7 +399,7 @@ build_commandline (char **argv)
 int
 _gpgme_io_spawn (const char *path, char **argv,
                 struct spawn_fd_item_s *fd_child_list,
-                struct spawn_fd_item_s *fd_parent_list)
+                struct spawn_fd_item_s *fd_parent_list, pid_t *r_pid)
 {
   SECURITY_ATTRIBUTES sec_attr;
   PROCESS_INFORMATION pi =
@@ -543,6 +543,8 @@ _gpgme_io_spawn (const char *path, char **argv,
              "dwProcessID=%d, dwThreadId=%d",
              pi.hProcess, pi.hThread, 
              (int) pi.dwProcessId, (int) pi.dwThreadId);
+  if (r_pid)
+    *r_pid = (pid_t)pi.dwProcessId;
   
   if (ResumeThread (pi.hThread) < 0)
     TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ());
index b0f6df2df4439d11e7e0bf5d7d4c3f0d62a99d75..a4763dec25a03c47cf5a518d84084122abcb02c7 100644 (file)
@@ -363,3 +363,35 @@ _gpgme_get_conf_int (const char *key, int *value)
   free (tmp);
   return 1;
 }
+
+
+void 
+_gpgme_allow_set_foregound_window (pid_t pid)
+{
+  static int initialized;
+  static BOOL (WINAPI * func)(DWORD);
+  void *handle;
+
+  if (!initialized)
+    {
+      /* Available since W2000; thus we dynload it.  */
+      initialized = 1;
+      handle = dlopen ("user32.dll", RTLD_LAZY);
+      if (handle)
+        {
+          func = dlsym (handle, "AllowSetForegroundWindow");
+          if (!func)
+            {
+              dlclose (handle);
+              handle = NULL;
+            }
+        }
+    }
+
+  if (!pid || pid == (pid_t)(-1))
+    ;
+  else if (func)
+    func (pid);
+
+}
+