gpg: Add status line PINENTRY_LAUNCHED.
authorWerner Koch <wk@gnupg.org>
Wed, 30 Jan 2013 11:00:29 +0000 (12:00 +0100)
committerWerner Koch <wk@gnupg.org>
Wed, 30 Jan 2013 11:00:29 +0000 (12:00 +0100)
* common/status.h (STATUS_PINENTRY_LAUNCHED): New.
* g10/server.c (server_local_s): Add field allow_pinentry_notify.
(option_handler): Add option "allow-pinentry-notify".
(gpg_proxy_pinentry_notify): New.
* g10/call-agent.c (default_inq_cb): Factor code out to the new
function.

common/status.h
doc/DETAILS
g10/call-agent.c
g10/main.h
g10/server.c

index b6ac779..c0e9d1a 100644 (file)
@@ -125,6 +125,8 @@ enum
     STATUS_TRUNCATED,
     STATUS_MOUNTPOINT,
 
+    STATUS_PINENTRY_LAUNCHED,
+
     STATUS_ERROR,
     STATUS_SUCCESS
 };
index 4e87394..8b20c21 100644 (file)
@@ -704,6 +704,15 @@ more arguments in future versions.
         may either be the specified mountpoint or one randomly choosen
         by g13.
 
+    PINENTRY_LAUNCHED <pid>
+
+        This status line is emitted by gpg to notify a client that a
+        Pinentry has been launched.  <pid> is the PID of the Pinentry.
+        It may be used to display a hint to the user but can't be used
+        to synchronize with Pinentry.  Note that there is also an
+        Assuan inquiry line with the same name used internally or, if
+        enabled, send to the client instead of this status line.  Such
+        an inquiry may be used to sync with Pinentry
 
 Status lines which are not anymore used:
 
index 55637e4..a4d1dbb 100644 (file)
@@ -307,14 +307,15 @@ get_serialno_cb (void *opaque, const char *line)
 static gpg_error_t
 default_inq_cb (void *opaque, const char *line)
 {
-  (void)opaque;
+  gpg_error_t err;
+  ctrl_t ctrl = opaque;
 
   if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
     {
-      /* There is no working server mode yet thus we use
-         AllowSetForegroundWindow window right here.  We might want to
-         do this anyway in case gpg is called on the console. */
-      gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
+      err = gpg_proxy_pinentry_notify (ctrl, line);
+      if (err)
+        log_error (_("failed to proxy %s inquiry to client\n"),
+                   "PINENTRY_LAUNCHED");
       /* We do not pass errors to avoid breaking other code.  */
     }
   else
index d25265a..15d3b76 100644 (file)
@@ -353,6 +353,8 @@ void unblock_all_signals(void);
 
 /*-- server.c --*/
 int gpg_server (ctrl_t);
+gpg_error_t gpg_proxy_pinentry_notify (ctrl_t ctrl,
+                                       const unsigned char *line);
 
 #ifdef ENABLE_CARD_SUPPORT
 /*-- card-util.c --*/
index d8871d0..da9c28d 100644 (file)
@@ -50,6 +50,9 @@ struct server_local_s
   /* List of prepared recipients.  */
   pk_list_t recplist;
 
+  /* Set if pinentry notifications should be passed back to the
+     client. */
+  int allow_pinentry_notify;
 };
 
 
@@ -105,9 +108,8 @@ has_option (const char *line, const char *name)
 static gpg_error_t
 option_handler (assuan_context_t ctx, const char *key, const char *value)
 {
-/*   ctrl_t ctrl = assuan_get_pointer (ctx); */
+  ctrl_t ctrl = assuan_get_pointer (ctx);
 
-  (void)ctx;
   (void)value;
 
   /* Fixme: Implement the tty and locale args. */
@@ -136,6 +138,10 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
     {
       /* This is for now a dummy option. */
     }
+  else if (!strcmp (key, "allow-pinentry-notify"))
+    {
+      ctrl->server_local->allow_pinentry_notify = 1;
+    }
   else
     return gpg_error (GPG_ERR_UNKNOWN_OPTION);
 
@@ -768,3 +774,29 @@ gpg_server (ctrl_t ctrl)
   assuan_release (ctx);
   return rc;
 }
+
+
+/* Helper to notify the client about Pinentry events.  Because that
+   might disturb some older clients, this is only done when enabled
+   via an option.  If it is not enabled we tell Windows to allow
+   setting the foreground window right here.  Returns an gpg error
+   code. */
+gpg_error_t
+gpg_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
+{
+  if (!ctrl || !ctrl->server_local
+      || !ctrl->server_local->allow_pinentry_notify)
+    {
+      gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
+      /* Client might be interested in that event - send as status line.  */
+      if (!strncmp (line, "PINENTRY_LAUNCHED", 17)
+          && (line[17]==' '||!line[17]))
+        {
+          for (line += 17; *line && spacep (line); line++)
+            ;
+          write_status_text (STATUS_PINENTRY_LAUNCHED, line);
+        }
+      return 0;
+    }
+  return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
+}