agent: Send pinentry the uid of connecting process where possible.
[gnupg.git] / agent / call-pinentry.c
1 /* call-pinentry.c - Spawn the pinentry to query stuff from the user
2  * Copyright (C) 2001, 2002, 2004, 2007, 2008,
3  *               2010  Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <assert.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #ifndef HAVE_W32_SYSTEM
31 # include <sys/wait.h>
32 # include <sys/types.h>
33 # include <signal.h>
34 # include <sys/utsname.h>
35 #endif
36 #include <npth.h>
37
38 #include "agent.h"
39 #include <assuan.h>
40 #include "../common/sysutils.h"
41 #include "../common/i18n.h"
42
43 #ifdef _POSIX_OPEN_MAX
44 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
45 #else
46 #define MAX_OPEN_FDS 20
47 #endif
48
49
50 /* Because access to the pinentry must be serialized (it is and shall
51    be a global mutually exclusive dialog) we better timeout pending
52    requests after some time.  1 minute seem to be a reasonable
53    time. */
54 #define LOCK_TIMEOUT  (1*60)
55
56 /* The assuan context of the current pinentry. */
57 static assuan_context_t entry_ctx;
58
59 /* A list of features of the current pinentry.  */
60 static struct
61 {
62   /* The Pinentry support RS+US tabbing.  This means that a RS (0x1e)
63    * starts a new tabbing block in which a US (0x1f) followed by a
64    * colon marks a colon.  A pinentry can use this to pretty print
65    * name value pairs.  */
66   unsigned int tabbing:1;
67 } entry_features;
68
69
70 /* The control variable of the connection owning the current pinentry.
71    This is only valid if ENTRY_CTX is not NULL.  Note, that we care
72    only about the value of the pointer and that it should never be
73    dereferenced.  */
74 static ctrl_t entry_owner;
75
76 /* A mutex used to serialize access to the pinentry. */
77 static npth_mutex_t entry_lock;
78
79 /* The thread ID of the popup working thread. */
80 static npth_t  popup_tid;
81
82 /* A flag used in communication between the popup working thread and
83    its stop function. */
84 static int popup_finished;
85
86
87
88 /* Data to be passed to our callbacks, */
89 struct entry_parm_s
90 {
91   int lines;
92   size_t size;
93   unsigned char *buffer;
94 };
95
96
97
98 \f
99 /* This function must be called once to initialize this module.  This
100    has to be done before a second thread is spawned.  We can't do the
101    static initialization because Pth emulation code might not be able
102    to do a static init; in particular, it is not possible for W32. */
103 void
104 initialize_module_call_pinentry (void)
105 {
106   static int initialized;
107
108   if (!initialized)
109     {
110       if (npth_mutex_init (&entry_lock, NULL))
111         initialized = 1;
112     }
113 }
114
115
116
117 /* This function may be called to print information pertaining to the
118    current state of this module to the log. */
119 void
120 agent_query_dump_state (void)
121 {
122   log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
123             entry_ctx, (long)assuan_get_pid (entry_ctx), (void*)popup_tid);
124 }
125
126 /* Called to make sure that a popup window owned by the current
127    connection gets closed. */
128 void
129 agent_reset_query (ctrl_t ctrl)
130 {
131   if (entry_ctx && popup_tid && entry_owner == ctrl)
132     {
133       agent_popup_message_stop (ctrl);
134     }
135 }
136
137
138 /* Unlock the pinentry so that another thread can start one and
139    disconnect that pinentry - we do this after the unlock so that a
140    stalled pinentry does not block other threads.  Fixme: We should
141    have a timeout in Assuan for the disconnect operation. */
142 static gpg_error_t
143 unlock_pinentry (gpg_error_t rc)
144 {
145   assuan_context_t ctx = entry_ctx;
146   int err;
147
148   if (rc)
149     {
150       if (DBG_IPC)
151         log_debug ("error calling pinentry: %s <%s>\n",
152                    gpg_strerror (rc), gpg_strsource (rc));
153
154       /* Change the source of the error to pinentry so that the final
155          consumer of the error code knows that the problem is with
156          pinentry.  For backward compatibility we do not do that for
157          some common error codes.  */
158       switch (gpg_err_code (rc))
159         {
160         case GPG_ERR_NO_PIN_ENTRY:
161         case GPG_ERR_CANCELED:
162         case GPG_ERR_FULLY_CANCELED:
163         case GPG_ERR_ASS_UNKNOWN_INQUIRE:
164         case GPG_ERR_ASS_TOO_MUCH_DATA:
165         case GPG_ERR_NO_PASSPHRASE:
166         case GPG_ERR_BAD_PASSPHRASE:
167         case GPG_ERR_BAD_PIN:
168           break;
169
170         case GPG_ERR_CORRUPTED_PROTECTION:
171           /* This comes from gpg-agent.  */
172           break;
173
174         default:
175           rc = gpg_err_make (GPG_ERR_SOURCE_PINENTRY, gpg_err_code (rc));
176           break;
177         }
178     }
179
180   entry_ctx = NULL;
181   err = npth_mutex_unlock (&entry_lock);
182   if (err)
183     {
184       log_error ("failed to release the entry lock: %s\n", strerror (err));
185       if (!rc)
186         rc = gpg_error_from_errno (err);
187     }
188   assuan_release (ctx);
189   return rc;
190 }
191
192
193 /* To make sure we leave no secrets in our image after forking of the
194    pinentry, we use this callback. */
195 static void
196 atfork_cb (void *opaque, int where)
197 {
198   ctrl_t ctrl = opaque;
199
200   if (!where)
201     {
202       int iterator = 0;
203       const char *name, *assname, *value;
204
205       gcry_control (GCRYCTL_TERM_SECMEM);
206
207       while ((name = session_env_list_stdenvnames (&iterator, &assname)))
208         {
209           /* For all new envvars (!ASSNAME) and the two medium old
210              ones which do have an assuan name but are conveyed using
211              environment variables, update the environment of the
212              forked process.  */
213           if (!assname
214               || !strcmp (name, "XAUTHORITY")
215               || !strcmp (name, "PINENTRY_USER_DATA"))
216             {
217               value = session_env_getenv (ctrl->session_env, name);
218               if (value)
219                 gnupg_setenv (name, value, 1);
220             }
221         }
222     }
223 }
224
225
226 /* Status line callback for the FEATURES status.  */
227 static gpg_error_t
228 getinfo_features_cb (void *opaque, const char *line)
229 {
230   const char *args;
231   char **tokens;
232   int i;
233
234   (void)opaque;
235
236   if ((args = has_leading_keyword (line, "FEATURES")))
237     {
238       tokens = strtokenize (args, " ");
239       if (!tokens)
240         return gpg_error_from_syserror ();
241       for (i=0; tokens[i]; i++)
242         if (!strcmp (tokens[i], "tabbing"))
243           entry_features.tabbing = 1;
244       xfree (tokens);
245     }
246
247   return 0;
248 }
249
250
251 static gpg_error_t
252 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
253 {
254   unsigned long *pid = opaque;
255   char pidbuf[50];
256
257   /* There is only the pid in the server's response.  */
258   if (length >= sizeof pidbuf)
259     length = sizeof pidbuf -1;
260   if (length)
261     {
262       strncpy (pidbuf, buffer, length);
263       pidbuf[length] = 0;
264       *pid = strtoul (pidbuf, NULL, 10);
265     }
266   return 0;
267 }
268
269
270 /* Fork off the pin entry if this has not already been done.  Note,
271    that this function must always be used to acquire the lock for the
272    pinentry - we will serialize _all_ pinentry calls.
273  */
274 static gpg_error_t
275 start_pinentry (ctrl_t ctrl)
276 {
277   int rc = 0;
278   const char *full_pgmname;
279   const char *pgmname;
280   assuan_context_t ctx;
281   const char *argv[5];
282   assuan_fd_t no_close_list[3];
283   int i;
284   const char *tmpstr;
285   unsigned long pinentry_pid;
286   const char *value;
287   struct timespec abstime;
288   char *flavor_version;
289   int err;
290
291   npth_clock_gettime (&abstime);
292   abstime.tv_sec += LOCK_TIMEOUT;
293   err = npth_mutex_timedlock (&entry_lock, &abstime);
294   if (err)
295     {
296       if (err == ETIMEDOUT)
297         rc = gpg_error (GPG_ERR_TIMEOUT);
298       else
299         rc = gpg_error_from_errno (rc);
300       log_error (_("failed to acquire the pinentry lock: %s\n"),
301                  gpg_strerror (rc));
302       return rc;
303     }
304
305   entry_owner = ctrl;
306
307   if (entry_ctx)
308     return 0;
309
310   if (opt.verbose)
311     log_info ("starting a new PIN Entry\n");
312
313 #ifdef HAVE_W32_SYSTEM
314   fflush (stdout);
315   fflush (stderr);
316 #endif
317   if (fflush (NULL))
318     {
319 #ifndef HAVE_W32_SYSTEM
320       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
321 #endif
322       log_error ("error flushing pending output: %s\n", strerror (errno));
323       /* At least Windows XP fails here with EBADF.  According to docs
324          and Wine an fflush(NULL) is the same as _flushall.  However
325          the Wine implementation does not flush stdin,stdout and stderr
326          - see above.  Let's try to ignore the error. */
327 #ifndef HAVE_W32_SYSTEM
328       return unlock_pinentry (tmperr);
329 #endif
330     }
331
332   full_pgmname = opt.pinentry_program;
333   if (!full_pgmname || !*full_pgmname)
334     full_pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY);
335   if ( !(pgmname = strrchr (full_pgmname, '/')))
336     pgmname = full_pgmname;
337   else
338     pgmname++;
339
340   /* OS X needs the entire file name in argv[0], so that it can locate
341      the resource bundle.  For other systems we stick to the usual
342      convention of supplying only the name of the program.  */
343 #ifdef __APPLE__
344   argv[0] = full_pgmname;
345 #else /*!__APPLE__*/
346   argv[0] = pgmname;
347 #endif /*__APPLE__*/
348
349   if (!opt.keep_display
350       && (value = session_env_getenv (ctrl->session_env, "DISPLAY")))
351     {
352       argv[1] = "--display";
353       argv[2] = value;
354       argv[3] = NULL;
355     }
356   else
357     argv[1] = NULL;
358
359   i=0;
360   if (!opt.running_detached)
361     {
362       if (log_get_fd () != -1)
363         no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
364       no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
365     }
366   no_close_list[i] = ASSUAN_INVALID_FD;
367
368   rc = assuan_new (&ctx);
369   if (rc)
370     {
371       log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
372       return rc;
373     }
374   /* We don't want to log the pinentry communication to make the logs
375      easier to read.  We might want to add a new debug option to enable
376      pinentry logging.  */
377 #ifdef ASSUAN_NO_LOGGING
378   assuan_set_flag (ctx, ASSUAN_NO_LOGGING, !opt.debug_pinentry);
379 #endif
380
381   /* Connect to the pinentry and perform initial handshaking.  Note
382      that atfork is used to change the environment for pinentry.  We
383      start the server in detached mode to suppress the console window
384      under Windows.  */
385   rc = assuan_pipe_connect (ctx, full_pgmname, argv,
386                             no_close_list, atfork_cb, ctrl,
387                             ASSUAN_PIPE_CONNECT_DETACHED);
388   if (rc)
389     {
390       log_error ("can't connect to the PIN entry module '%s': %s\n",
391                  full_pgmname, gpg_strerror (rc));
392       assuan_release (ctx);
393       return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY));
394     }
395   entry_ctx = ctx;
396
397   if (DBG_IPC)
398     log_debug ("connection to PIN entry established\n");
399
400   value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA");
401   if (value != NULL)
402     {
403       char *optstr;
404       if (asprintf (&optstr, "OPTION pinentry-user-data=%s", value) < 0 )
405         return unlock_pinentry (out_of_core ());
406       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
407                             NULL);
408       xfree (optstr);
409       if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
410         return unlock_pinentry (rc);
411     }
412
413   rc = assuan_transact (entry_ctx,
414                         opt.no_grab? "OPTION no-grab":"OPTION grab",
415                         NULL, NULL, NULL, NULL, NULL, NULL);
416   if (rc)
417     return unlock_pinentry (rc);
418
419   value = session_env_getenv (ctrl->session_env, "GPG_TTY");
420   if (value)
421     {
422       char *optstr;
423       if (asprintf (&optstr, "OPTION ttyname=%s", value) < 0 )
424         return unlock_pinentry (out_of_core ());
425       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
426                             NULL);
427       xfree (optstr);
428       if (rc)
429         return unlock_pinentry (rc);
430     }
431   value = session_env_getenv (ctrl->session_env, "TERM");
432   if (value)
433     {
434       char *optstr;
435       if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 )
436         return unlock_pinentry (out_of_core ());
437       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
438                             NULL);
439       xfree (optstr);
440       if (rc)
441         return unlock_pinentry (rc);
442     }
443   if (ctrl->lc_ctype)
444     {
445       char *optstr;
446       if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 )
447         return unlock_pinentry (out_of_core ());
448       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
449                             NULL);
450       xfree (optstr);
451       if (rc)
452         return unlock_pinentry (rc);
453     }
454   if (ctrl->lc_messages)
455     {
456       char *optstr;
457       if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 )
458         return unlock_pinentry (out_of_core ());
459       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
460                             NULL);
461       xfree (optstr);
462       if (rc)
463         return unlock_pinentry (rc);
464     }
465
466
467   if (opt.allow_external_cache)
468     {
469       /* Indicate to the pinentry that it may read from an external cache.
470
471          It is essential that the pinentry respect this.  If the
472          cached password is not up to date and retry == 1, then, using
473          a version of GPG Agent that doesn't support this, won't issue
474          another pin request and the user won't get a chance to
475          correct the password.  */
476       rc = assuan_transact (entry_ctx, "OPTION allow-external-password-cache",
477                             NULL, NULL, NULL, NULL, NULL, NULL);
478       if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
479         return unlock_pinentry (rc);
480     }
481
482   if (opt.allow_emacs_pinentry)
483     {
484       /* Indicate to the pinentry that it may read passphrase through
485          Emacs minibuffer, if possible.  */
486       rc = assuan_transact (entry_ctx, "OPTION allow-emacs-prompt",
487                             NULL, NULL, NULL, NULL, NULL, NULL);
488       if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
489         return unlock_pinentry (rc);
490     }
491
492
493   {
494     /* Provide a few default strings for use by the pinentries.  This
495        may help a pinentry to avoid implementing localization code.  */
496     static const struct { const char *key, *value; int what; } tbl[] = {
497       /* TRANSLATORS: These are labels for buttons etc used in
498          Pinentries.  An underscore indicates that the next letter
499          should be used as an accelerator.  Double the underscore for
500          a literal one.  The actual to be translated text starts after
501          the second vertical bar.  Note that gpg-agent has been set to
502          utf-8 so that the strings are in the expected encoding.  */
503       { "ok",     N_("|pinentry-label|_OK") },
504       { "cancel", N_("|pinentry-label|_Cancel") },
505       { "yes",    N_("|pinentry-label|_Yes") },
506       { "no",     N_("|pinentry-label|_No") },
507       { "prompt", N_("|pinentry-label|PIN:") },
508       { "pwmngr", N_("|pinentry-label|_Save in password manager"), 1 },
509       { "cf-visi",N_("Do you really want to make your "
510                      "passphrase visible on the screen?") },
511       { "tt-visi",N_("|pinentry-tt|Make passphrase visible") },
512       { "tt-hide",N_("|pinentry-tt|Hide passphrase") },
513       { NULL, NULL}
514     };
515     char *optstr;
516     int idx;
517     const char *s, *s2;
518
519     for (idx=0; tbl[idx].key; idx++)
520       {
521         if (!opt.allow_external_cache && tbl[idx].what == 1)
522           continue;  /* No need for it.  */
523         s = L_(tbl[idx].value);
524         if (*s == '|' && (s2=strchr (s+1,'|')))
525           s = s2+1;
526         if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 )
527           return unlock_pinentry (out_of_core ());
528         assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
529                          NULL);
530         xfree (optstr);
531       }
532   }
533
534   /* Tell the pinentry that we would prefer that the given character
535      is used as the invisible character by the entry widget.  */
536   if (opt.pinentry_invisible_char)
537     {
538       char *optstr;
539       if ((optstr = xtryasprintf ("OPTION invisible-char=%s",
540                                   opt.pinentry_invisible_char)))
541         {
542           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
543                            NULL);
544           /* We ignore errors because this is just a fancy thing and
545              older pinentries do not support this feature.  */
546           xfree (optstr);
547         }
548     }
549
550   if (opt.pinentry_timeout)
551     {
552       char *optstr;
553       if ((optstr = xtryasprintf ("SETTIMEOUT %lu", opt.pinentry_timeout)))
554         {
555           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
556                            NULL);
557           /* We ignore errors because this is just a fancy thing.  */
558           xfree (optstr);
559         }
560     }
561
562   /* Tell the pinentry the name of a file it shall touch after having
563      messed with the tty.  This is optional and only supported by
564      newer pinentries and thus we do no error checking. */
565   tmpstr = opt.pinentry_touch_file;
566   if (tmpstr && !strcmp (tmpstr, "/dev/null"))
567     tmpstr = NULL;
568   else if (!tmpstr)
569     tmpstr = get_agent_socket_name ();
570   if (tmpstr)
571     {
572       char *optstr;
573
574       if (asprintf (&optstr, "OPTION touch-file=%s", tmpstr ) < 0 )
575         ;
576       else
577         {
578           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
579                            NULL);
580           xfree (optstr);
581         }
582     }
583
584   /* Tell Pinentry about our client.  */
585   if (ctrl->client_pid)
586     {
587       char *optstr;
588       const char *nodename = "";
589
590 #ifndef HAVE_W32_SYSTEM
591       struct utsname utsbuf;
592       if (!uname (&utsbuf))
593         nodename = utsbuf.nodename;
594 #endif /*!HAVE_W32_SYSTEM*/
595
596       if ((optstr = xtryasprintf ("OPTION owner=%lu/%d %s",
597                                   ctrl->client_pid, ctrl->client_uid,
598                                   nodename)))
599         {
600           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
601                            NULL);
602           /* We ignore errors because this is just a fancy thing and
603              older pinentries do not support this feature.  */
604           xfree (optstr);
605         }
606     }
607
608
609   /* Ask the pinentry for its version and flavor and store that as a
610    * string in MB.  This information is useful for helping users to
611    * figure out Pinentry problems.  Noet that "flavor" may also return
612    * a status line with the features; we use a dedicated handler for
613    * that.  */
614   {
615     membuf_t mb;
616
617     init_membuf (&mb, 256);
618     if (assuan_transact (entry_ctx, "GETINFO flavor",
619                          put_membuf_cb, &mb,
620                          NULL, NULL,
621                          getinfo_features_cb, NULL))
622       put_membuf_str (&mb, "unknown");
623     put_membuf_str (&mb, " ");
624     if (assuan_transact (entry_ctx, "GETINFO version",
625                          put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
626       put_membuf_str (&mb, "unknown");
627     put_membuf_str (&mb, " ");
628     if (assuan_transact (entry_ctx, "GETINFO ttyinfo",
629                          put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
630       put_membuf_str (&mb, "? ? ?");
631     put_membuf (&mb, "", 1);
632     flavor_version = get_membuf (&mb, NULL);
633   }
634
635
636   /* Now ask the Pinentry for its PID.  If the Pinentry is new enough
637      it will send the pid back and we will use an inquire to notify
638      our client.  The client may answer the inquiry either with END or
639      with CAN to cancel the pinentry. */
640   rc = assuan_transact (entry_ctx, "GETINFO pid",
641                         getinfo_pid_cb, &pinentry_pid,
642                         NULL, NULL, NULL, NULL);
643   if (rc)
644     {
645       log_info ("You may want to update to a newer pinentry\n");
646       rc = 0;
647     }
648   else if (!rc && (pid_t)pinentry_pid == (pid_t)(-1))
649     log_error ("pinentry did not return a PID\n");
650   else
651     {
652       rc = agent_inq_pinentry_launched (ctrl, pinentry_pid, flavor_version);
653       if (gpg_err_code (rc) == GPG_ERR_CANCELED
654           || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
655         return unlock_pinentry (gpg_err_make (GPG_ERR_SOURCE_DEFAULT,
656                                               gpg_err_code (rc)));
657       rc = 0;
658     }
659
660   xfree (flavor_version);
661
662   return rc;
663 }
664
665
666 /* Returns True if the pinentry is currently active. If WAITSECONDS is
667    greater than zero the function will wait for this many seconds
668    before returning.  */
669 int
670 pinentry_active_p (ctrl_t ctrl, int waitseconds)
671 {
672   int err;
673   (void)ctrl;
674
675   if (waitseconds > 0)
676     {
677       struct timespec abstime;
678       int rc;
679
680       npth_clock_gettime (&abstime);
681       abstime.tv_sec += waitseconds;
682       err = npth_mutex_timedlock (&entry_lock, &abstime);
683       if (err)
684         {
685           if (err == ETIMEDOUT)
686             rc = gpg_error (GPG_ERR_TIMEOUT);
687           else
688             rc = gpg_error (GPG_ERR_INTERNAL);
689           return rc;
690         }
691     }
692   else
693     {
694       err = npth_mutex_trylock (&entry_lock);
695       if (err)
696         return gpg_error (GPG_ERR_LOCKED);
697     }
698
699   err = npth_mutex_unlock (&entry_lock);
700   if (err)
701     log_error ("failed to release the entry lock at %d: %s\n", __LINE__,
702                strerror (errno));
703   return 0;
704 }
705
706
707 static gpg_error_t
708 getpin_cb (void *opaque, const void *buffer, size_t length)
709 {
710   struct entry_parm_s *parm = opaque;
711
712   if (!buffer)
713     return 0;
714
715   /* we expect the pin to fit on one line */
716   if (parm->lines || length >= parm->size)
717     return gpg_error (GPG_ERR_ASS_TOO_MUCH_DATA);
718
719   /* fixme: we should make sure that the assuan buffer is allocated in
720      secure memory or read the response byte by byte */
721   memcpy (parm->buffer, buffer, length);
722   parm->buffer[length] = 0;
723   parm->lines++;
724   return 0;
725 }
726
727
728 static int
729 all_digitsp( const char *s)
730 {
731   for (; *s && *s >= '0' && *s <= '9'; s++)
732     ;
733   return !*s;
734 }
735
736
737 /* Return a new malloced string by unescaping the string S.  Escaping
738    is percent escaping and '+'/space mapping.  A binary Nul will
739    silently be replaced by a 0xFF.  Function returns NULL to indicate
740    an out of memory status.  Parsing stops at the end of the string or
741    a white space character. */
742 static char *
743 unescape_passphrase_string (const unsigned char *s)
744 {
745   char *buffer, *d;
746
747   buffer = d = xtrymalloc_secure (strlen ((const char*)s)+1);
748   if (!buffer)
749     return NULL;
750   while (*s && !spacep (s))
751     {
752       if (*s == '%' && s[1] && s[2])
753         {
754           s++;
755           *d = xtoi_2 (s);
756           if (!*d)
757             *d = '\xff';
758           d++;
759           s += 2;
760         }
761       else if (*s == '+')
762         {
763           *d++ = ' ';
764           s++;
765         }
766       else
767         *d++ = *s++;
768     }
769   *d = 0;
770   return buffer;
771 }
772
773
774 /* Estimate the quality of the passphrase PW and return a value in the
775    range 0..100.  */
776 static int
777 estimate_passphrase_quality (const char *pw)
778 {
779   int goodlength = opt.min_passphrase_len + opt.min_passphrase_len/3;
780   int length;
781   const char *s;
782
783   if (goodlength < 1)
784     return 0;
785
786   for (length = 0, s = pw; *s; s++)
787     if (!spacep (s))
788       length ++;
789
790   if (length > goodlength)
791     return 100;
792   return ((length*10) / goodlength)*10;
793 }
794
795
796 /* Handle the QUALITY inquiry. */
797 static gpg_error_t
798 inq_quality (void *opaque, const char *line)
799 {
800   assuan_context_t ctx = opaque;
801   const char *s;
802   char *pin;
803   int rc;
804   int percent;
805   char numbuf[20];
806
807   if ((s = has_leading_keyword (line, "QUALITY")))
808     {
809       pin = unescape_passphrase_string (s);
810       if (!pin)
811         rc = gpg_error_from_syserror ();
812       else
813         {
814           percent = estimate_passphrase_quality (pin);
815           if (check_passphrase_constraints (NULL, pin, NULL))
816             percent = -percent;
817           snprintf (numbuf, sizeof numbuf, "%d", percent);
818           rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
819           xfree (pin);
820         }
821     }
822   else
823     {
824       log_error ("unsupported inquiry '%s' from pinentry\n", line);
825       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
826     }
827
828   return rc;
829 }
830
831
832 /* Helper for agent_askpin and agent_get_passphrase.  */
833 static gpg_error_t
834 setup_qualitybar (ctrl_t ctrl)
835 {
836   int rc;
837   char line[ASSUAN_LINELENGTH];
838   char *tmpstr, *tmpstr2;
839   const char *tooltip;
840
841   (void)ctrl;
842
843   /* TRANSLATORS: This string is displayed by Pinentry as the label
844      for the quality bar.  */
845   tmpstr = try_percent_escape (L_("Quality:"), "\t\r\n\f\v");
846   snprintf (line, DIM(line), "SETQUALITYBAR %s", tmpstr? tmpstr:"");
847   xfree (tmpstr);
848   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
849   if (rc == 103 /*(Old assuan error code)*/
850       || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
851     ; /* Ignore Unknown Command from old Pinentry versions.  */
852   else if (rc)
853     return rc;
854
855   tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
856   if (tmpstr2)
857     tooltip = tmpstr2;
858   else
859     {
860       /* TRANSLATORS: This string is a tooltip, shown by pinentry when
861          hovering over the quality bar.  Please use an appropriate
862          string to describe what this is about.  The length of the
863          tooltip is limited to about 900 characters.  If you do not
864          translate this entry, a default english text (see source)
865          will be used. */
866       tooltip =  L_("pinentry.qualitybar.tooltip");
867       if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
868         tooltip = ("The quality of the text entered above.\n"
869                    "Please ask your administrator for "
870                    "details about the criteria.");
871     }
872   tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
873   xfree (tmpstr2);
874   snprintf (line, DIM(line), "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
875   xfree (tmpstr);
876   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
877   if (rc == 103 /*(Old assuan error code)*/
878           || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
879     ; /* Ignore Unknown Command from old pinentry versions.  */
880   else if (rc)
881     return rc;
882
883   return 0;
884 }
885
886 enum
887   {
888     PINENTRY_STATUS_CLOSE_BUTTON = 1 << 0,
889     PINENTRY_STATUS_PIN_REPEATED = 1 << 8,
890     PINENTRY_STATUS_PASSWORD_FROM_CACHE = 1 << 9
891   };
892
893 /* Check the button_info line for a close action.  Also check for the
894    PIN_REPEATED flag.  */
895 static gpg_error_t
896 pinentry_status_cb (void *opaque, const char *line)
897 {
898   unsigned int *flag = opaque;
899   const char *args;
900
901   if ((args = has_leading_keyword (line, "BUTTON_INFO")))
902     {
903       if (!strcmp (args, "close"))
904         *flag |= PINENTRY_STATUS_CLOSE_BUTTON;
905     }
906   else if (has_leading_keyword (line, "PIN_REPEATED"))
907     {
908       *flag |= PINENTRY_STATUS_PIN_REPEATED;
909     }
910   else if (has_leading_keyword (line, "PASSWORD_FROM_CACHE"))
911     {
912       *flag |= PINENTRY_STATUS_PASSWORD_FROM_CACHE;
913     }
914
915   return 0;
916 }
917
918
919 /* Build a SETDESC command line.  This is a dedicated function so that
920  * it can remove control characters which are not supported by the
921  * current Pinentry.  */
922 static void
923 build_cmd_setdesc (char *line, size_t linelen, const char *desc)
924 {
925   char *src, *dst;
926
927   snprintf (line, linelen, "SETDESC %s", desc);
928   if (!entry_features.tabbing)
929     {
930       /* Remove RS and US.  */
931       for (src=dst=line; *src; src++)
932         if (!strchr ("\x1e\x1f", *src))
933           *dst++ = *src;
934       *dst = 0;
935     }
936 }
937
938
939 \f
940 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
941    number here and repeat it as long as we have invalid formed
942    numbers.  KEYINFO and CACHE_MODE are used to tell pinentry something
943    about the key. */
944 gpg_error_t
945 agent_askpin (ctrl_t ctrl,
946               const char *desc_text, const char *prompt_text,
947               const char *initial_errtext,
948               struct pin_entry_info_s *pininfo,
949               const char *keyinfo, cache_mode_t cache_mode)
950 {
951   gpg_error_t rc;
952   char line[ASSUAN_LINELENGTH];
953   struct entry_parm_s parm;
954   const char *errtext = NULL;
955   int is_pin = 0;
956   int saveflag;
957   unsigned int pinentry_status;
958
959   if (opt.batch)
960     return 0; /* fixme: we should return BAD PIN */
961
962   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
963     {
964       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
965         return gpg_error (GPG_ERR_CANCELED);
966       if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
967         {
968           unsigned char *passphrase;
969           size_t size;
970
971           *pininfo->pin = 0; /* Reset the PIN. */
972           rc = pinentry_loopback (ctrl, "PASSPHRASE", &passphrase, &size,
973                                   pininfo->max_length - 1);
974           if (rc)
975             return rc;
976
977           memcpy(&pininfo->pin, passphrase, size);
978           xfree(passphrase);
979           pininfo->pin[size] = 0;
980           if (pininfo->check_cb)
981             {
982               /* More checks by utilizing the optional callback. */
983               pininfo->cb_errtext = NULL;
984               rc = pininfo->check_cb (pininfo);
985             }
986           return rc;
987         }
988       return gpg_error(GPG_ERR_NO_PIN_ENTRY);
989     }
990
991   if (!pininfo || pininfo->max_length < 1)
992     return gpg_error (GPG_ERR_INV_VALUE);
993   if (!desc_text && pininfo->min_digits)
994     desc_text = L_("Please enter your PIN, so that the secret key "
995                    "can be unlocked for this session");
996   else if (!desc_text)
997     desc_text = L_("Please enter your passphrase, so that the secret key "
998                    "can be unlocked for this session");
999
1000   if (prompt_text)
1001     is_pin = !!strstr (prompt_text, "PIN");
1002   else
1003     is_pin = desc_text && strstr (desc_text, "PIN");
1004
1005   rc = start_pinentry (ctrl);
1006   if (rc)
1007     return rc;
1008
1009   /* If we have a KEYINFO string and are normal, user, or ssh cache
1010      mode, we tell that the Pinentry so it may use it for own caching
1011      purposes.  Most pinentries won't have this implemented and thus
1012      we do not error out in this case.  */
1013   if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1014                   || cache_mode == CACHE_MODE_USER
1015                   || cache_mode == CACHE_MODE_SSH))
1016     snprintf (line, DIM(line), "SETKEYINFO %c/%s",
1017               cache_mode == CACHE_MODE_USER? 'u' :
1018               cache_mode == CACHE_MODE_SSH? 's' : 'n',
1019               keyinfo);
1020   else
1021     snprintf (line, DIM(line), "SETKEYINFO --clear");
1022
1023   rc = assuan_transact (entry_ctx, line,
1024                         NULL, NULL, NULL, NULL, NULL, NULL);
1025   if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1026     return unlock_pinentry (rc);
1027
1028   build_cmd_setdesc (line, DIM(line), desc_text);
1029   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1030   if (rc)
1031     return unlock_pinentry (rc);
1032
1033   snprintf (line, DIM(line), "SETPROMPT %s",
1034             prompt_text? prompt_text : is_pin? L_("PIN:") : L_("Passphrase:"));
1035   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1036   if (rc)
1037     return unlock_pinentry (rc);
1038
1039   /* If a passphrase quality indicator has been requested and a
1040      minimum passphrase length has not been disabled, send the command
1041      to the pinentry.  */
1042   if (pininfo->with_qualitybar && opt.min_passphrase_len )
1043     {
1044       rc = setup_qualitybar (ctrl);
1045       if (rc)
1046         return unlock_pinentry (rc);
1047     }
1048
1049   if (initial_errtext)
1050     {
1051       snprintf (line, DIM(line), "SETERROR %s", initial_errtext);
1052       rc = assuan_transact (entry_ctx, line,
1053                             NULL, NULL, NULL, NULL, NULL, NULL);
1054       if (rc)
1055         return unlock_pinentry (rc);
1056     }
1057
1058   if (pininfo->with_repeat)
1059     {
1060       snprintf (line, DIM(line), "SETREPEATERROR %s",
1061                 L_("does not match - try again"));
1062       rc = assuan_transact (entry_ctx, line,
1063                             NULL, NULL, NULL, NULL, NULL, NULL);
1064       if (rc)
1065         pininfo->with_repeat = 0; /* Pinentry does not support it.  */
1066     }
1067   pininfo->repeat_okay = 0;
1068
1069   for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
1070     {
1071       memset (&parm, 0, sizeof parm);
1072       parm.size = pininfo->max_length;
1073       *pininfo->pin = 0; /* Reset the PIN. */
1074       parm.buffer = (unsigned char*)pininfo->pin;
1075
1076       if (errtext)
1077         {
1078           /* TRANSLATORS: The string is appended to an error message in
1079              the pinentry.  The %s is the actual error message, the
1080              two %d give the current and maximum number of tries. */
1081           snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"),
1082                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
1083           rc = assuan_transact (entry_ctx, line,
1084                                 NULL, NULL, NULL, NULL, NULL, NULL);
1085           if (rc)
1086             return unlock_pinentry (rc);
1087           errtext = NULL;
1088         }
1089
1090       if (pininfo->with_repeat)
1091         {
1092           snprintf (line, DIM(line), "SETREPEAT %s", L_("Repeat:"));
1093           rc = assuan_transact (entry_ctx, line,
1094                                 NULL, NULL, NULL, NULL, NULL, NULL);
1095           if (rc)
1096             return unlock_pinentry (rc);
1097         }
1098
1099       saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
1100       assuan_begin_confidential (entry_ctx);
1101       pinentry_status = 0;
1102       rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
1103                             inq_quality, entry_ctx,
1104                             pinentry_status_cb, &pinentry_status);
1105       assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
1106       /* Most pinentries out in the wild return the old Assuan error code
1107          for canceled which gets translated to an assuan Cancel error and
1108          not to the code for a user cancel.  Fix this here. */
1109       if (rc && gpg_err_source (rc)
1110           && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1111         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1112
1113
1114       /* Change error code in case the window close button was clicked
1115          to cancel the operation.  */
1116       if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON)
1117           && gpg_err_code (rc) == GPG_ERR_CANCELED)
1118         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
1119
1120       if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
1121         errtext = is_pin? L_("PIN too long")
1122                         : L_("Passphrase too long");
1123       else if (rc)
1124         return unlock_pinentry (rc);
1125
1126       if (!errtext && pininfo->min_digits)
1127         {
1128           /* do some basic checks on the entered PIN. */
1129           if (!all_digitsp (pininfo->pin))
1130             errtext = L_("Invalid characters in PIN");
1131           else if (pininfo->max_digits
1132                    && strlen (pininfo->pin) > pininfo->max_digits)
1133             errtext = L_("PIN too long");
1134           else if (strlen (pininfo->pin) < pininfo->min_digits)
1135             errtext = L_("PIN too short");
1136         }
1137
1138       if (!errtext && pininfo->check_cb)
1139         {
1140           /* More checks by utilizing the optional callback. */
1141           pininfo->cb_errtext = NULL;
1142           rc = pininfo->check_cb (pininfo);
1143           if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1144               && pininfo->cb_errtext)
1145             errtext = pininfo->cb_errtext;
1146           else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1147                    || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
1148             errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase"));
1149           else if (rc)
1150             return unlock_pinentry (rc);
1151         }
1152
1153       if (!errtext)
1154         {
1155           if (pininfo->with_repeat
1156               && (pinentry_status & PINENTRY_STATUS_PIN_REPEATED))
1157             pininfo->repeat_okay = 1;
1158           return unlock_pinentry (0); /* okay, got a PIN or passphrase */
1159         }
1160
1161       if ((pinentry_status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1162         /* The password was read from the cache.  Don't count this
1163            against the retry count.  */
1164         pininfo->failed_tries --;
1165     }
1166
1167   return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
1168                           : GPG_ERR_BAD_PASSPHRASE));
1169 }
1170
1171
1172 \f
1173 /* Ask for the passphrase using the supplied arguments.  The returned
1174    passphrase needs to be freed by the caller. */
1175 int
1176 agent_get_passphrase (ctrl_t ctrl,
1177                       char **retpass, const char *desc, const char *prompt,
1178                       const char *errtext, int with_qualitybar,
1179                       const char *keyinfo, cache_mode_t cache_mode)
1180 {
1181
1182   int rc;
1183   char line[ASSUAN_LINELENGTH];
1184   struct entry_parm_s parm;
1185   int saveflag;
1186   unsigned int pinentry_status;
1187
1188   *retpass = NULL;
1189   if (opt.batch)
1190     return gpg_error (GPG_ERR_BAD_PASSPHRASE);
1191
1192   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1193     {
1194       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1195         return gpg_error (GPG_ERR_CANCELED);
1196
1197       if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1198         {
1199           size_t size;
1200
1201           return pinentry_loopback (ctrl, "PASSPHRASE",
1202                                     (unsigned char **)retpass, &size,
1203                                     MAX_PASSPHRASE_LEN);
1204         }
1205       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1206     }
1207
1208   rc = start_pinentry (ctrl);
1209   if (rc)
1210     return rc;
1211
1212   if (!prompt)
1213     prompt = desc && strstr (desc, "PIN")? L_("PIN:"): L_("Passphrase:");
1214
1215
1216   /* If we have a KEYINFO string and are normal, user, or ssh cache
1217      mode, we tell that the Pinentry so it may use it for own caching
1218      purposes.  Most pinentries won't have this implemented and thus
1219      we do not error out in this case.  */
1220   if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1221                   || cache_mode == CACHE_MODE_USER
1222                   || cache_mode == CACHE_MODE_SSH))
1223     snprintf (line, DIM(line), "SETKEYINFO %c/%s",
1224               cache_mode == CACHE_MODE_USER? 'u' :
1225               cache_mode == CACHE_MODE_SSH? 's' : 'n',
1226               keyinfo);
1227   else
1228     snprintf (line, DIM(line), "SETKEYINFO --clear");
1229
1230   rc = assuan_transact (entry_ctx, line,
1231                         NULL, NULL, NULL, NULL, NULL, NULL);
1232   if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1233     return unlock_pinentry (rc);
1234
1235
1236   if (desc)
1237     build_cmd_setdesc (line, DIM(line), desc);
1238   else
1239     snprintf (line, DIM(line), "RESET");
1240   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1241   if (rc)
1242     return unlock_pinentry (rc);
1243
1244   snprintf (line, DIM(line), "SETPROMPT %s", prompt);
1245   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1246   if (rc)
1247     return unlock_pinentry (rc);
1248
1249   if (with_qualitybar && opt.min_passphrase_len)
1250     {
1251       rc = setup_qualitybar (ctrl);
1252       if (rc)
1253         return unlock_pinentry (rc);
1254     }
1255
1256   if (errtext)
1257     {
1258       snprintf (line, DIM(line), "SETERROR %s", errtext);
1259       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1260       if (rc)
1261         return unlock_pinentry (rc);
1262     }
1263
1264   memset (&parm, 0, sizeof parm);
1265   parm.size = ASSUAN_LINELENGTH/2 - 5;
1266   parm.buffer = gcry_malloc_secure (parm.size+10);
1267   if (!parm.buffer)
1268     return unlock_pinentry (out_of_core ());
1269
1270   saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
1271   assuan_begin_confidential (entry_ctx);
1272   pinentry_status = 0;
1273   rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
1274                         inq_quality, entry_ctx,
1275                         pinentry_status_cb, &pinentry_status);
1276   assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
1277   /* Most pinentries out in the wild return the old Assuan error code
1278      for canceled which gets translated to an assuan Cancel error and
1279      not to the code for a user cancel.  Fix this here. */
1280   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1281     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1282   /* Change error code in case the window close button was clicked
1283      to cancel the operation.  */
1284   if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON)
1285       && gpg_err_code (rc) == GPG_ERR_CANCELED)
1286     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
1287
1288   if (rc)
1289     xfree (parm.buffer);
1290   else
1291     *retpass = parm.buffer;
1292   return unlock_pinentry (rc);
1293 }
1294
1295
1296 \f
1297 /* Pop up the PIN-entry, display the text and the prompt and ask the
1298    user to confirm this.  We return 0 for success, ie. the user
1299    confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
1300    other error.  If WITH_CANCEL it true an extra cancel button is
1301    displayed to allow the user to easily return a GPG_ERR_CANCELED.
1302    if the Pinentry does not support this, the user can still cancel by
1303    closing the Pinentry window.  */
1304 int
1305 agent_get_confirmation (ctrl_t ctrl,
1306                         const char *desc, const char *ok,
1307                         const char *notok, int with_cancel)
1308 {
1309   int rc;
1310   char line[ASSUAN_LINELENGTH];
1311
1312   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1313     {
1314       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1315         return gpg_error (GPG_ERR_CANCELED);
1316
1317       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1318     }
1319
1320   rc = start_pinentry (ctrl);
1321   if (rc)
1322     return rc;
1323
1324   if (desc)
1325     build_cmd_setdesc (line, DIM(line), desc);
1326   else
1327     snprintf (line, DIM(line), "RESET");
1328   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1329   /* Most pinentries out in the wild return the old Assuan error code
1330      for canceled which gets translated to an assuan Cancel error and
1331      not to the code for a user cancel.  Fix this here. */
1332   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1333     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1334
1335   if (rc)
1336     return unlock_pinentry (rc);
1337
1338   if (ok)
1339     {
1340       snprintf (line, DIM(line), "SETOK %s", ok);
1341       rc = assuan_transact (entry_ctx,
1342                             line, NULL, NULL, NULL, NULL, NULL, NULL);
1343       if (rc)
1344         return unlock_pinentry (rc);
1345     }
1346   if (notok)
1347     {
1348       /* Try to use the newer NOTOK feature if a cancel button is
1349          requested.  If no cancel button is requested we keep on using
1350          the standard cancel.  */
1351       if (with_cancel)
1352         {
1353           snprintf (line, DIM(line), "SETNOTOK %s", notok);
1354           rc = assuan_transact (entry_ctx,
1355                                 line, NULL, NULL, NULL, NULL, NULL, NULL);
1356         }
1357       else
1358         rc = GPG_ERR_ASS_UNKNOWN_CMD;
1359
1360       if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1361         {
1362           snprintf (line, DIM(line), "SETCANCEL %s", notok);
1363           rc = assuan_transact (entry_ctx, line,
1364                                 NULL, NULL, NULL, NULL, NULL, NULL);
1365         }
1366       if (rc)
1367         return unlock_pinentry (rc);
1368     }
1369
1370   rc = assuan_transact (entry_ctx, "CONFIRM",
1371                         NULL, NULL, NULL, NULL, NULL, NULL);
1372   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1373     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1374
1375   return unlock_pinentry (rc);
1376 }
1377
1378
1379 \f
1380 /* Pop up the PINentry, display the text DESC and a button with the
1381    text OK_BTN (which may be NULL to use the default of "OK") and wait
1382    for the user to hit this button.  The return value is not
1383    relevant.  */
1384 int
1385 agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
1386 {
1387   int rc;
1388   char line[ASSUAN_LINELENGTH];
1389
1390   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1391     return gpg_error (GPG_ERR_CANCELED);
1392
1393   rc = start_pinentry (ctrl);
1394   if (rc)
1395     return rc;
1396
1397   if (desc)
1398     build_cmd_setdesc (line, DIM(line), desc);
1399   else
1400     snprintf (line, DIM(line), "RESET");
1401   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1402   /* Most pinentries out in the wild return the old Assuan error code
1403      for canceled which gets translated to an assuan Cancel error and
1404      not to the code for a user cancel.  Fix this here. */
1405   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1406     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1407
1408   if (rc)
1409     return unlock_pinentry (rc);
1410
1411   if (ok_btn)
1412     {
1413       snprintf (line, DIM(line), "SETOK %s", ok_btn);
1414       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL,
1415                             NULL, NULL, NULL);
1416       if (rc)
1417         return unlock_pinentry (rc);
1418     }
1419
1420   rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL,
1421                         NULL, NULL, NULL);
1422   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1423     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1424
1425   return unlock_pinentry (rc);
1426 }
1427
1428
1429 /* The thread running the popup message. */
1430 static void *
1431 popup_message_thread (void *arg)
1432 {
1433   (void)arg;
1434
1435   /* We use the --one-button hack instead of the MESSAGE command to
1436      allow the use of old Pinentries.  Those old Pinentries will then
1437      show an additional Cancel button but that is mostly a visual
1438      annoyance. */
1439   assuan_transact (entry_ctx, "CONFIRM --one-button",
1440                    NULL, NULL, NULL, NULL, NULL, NULL);
1441   popup_finished = 1;
1442   return NULL;
1443 }
1444
1445
1446 /* Pop up a message window similar to the confirm one but keep it open
1447    until agent_popup_message_stop has been called.  It is crucial for
1448    the caller to make sure that the stop function gets called as soon
1449    as the message is not anymore required because the message is
1450    system modal and all other attempts to use the pinentry will fail
1451    (after a timeout). */
1452 int
1453 agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
1454 {
1455   int rc;
1456   char line[ASSUAN_LINELENGTH];
1457   npth_attr_t tattr;
1458   int err;
1459
1460   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1461     return gpg_error (GPG_ERR_CANCELED);
1462
1463   rc = start_pinentry (ctrl);
1464   if (rc)
1465     return rc;
1466
1467   if (desc)
1468     build_cmd_setdesc (line, DIM(line), desc);
1469   else
1470     snprintf (line, DIM(line), "RESET");
1471   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1472   if (rc)
1473     return unlock_pinentry (rc);
1474
1475   if (ok_btn)
1476     {
1477       snprintf (line, DIM(line), "SETOK %s", ok_btn);
1478       rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
1479       if (rc)
1480         return unlock_pinentry (rc);
1481     }
1482
1483   err = npth_attr_init (&tattr);
1484   if (err)
1485     return unlock_pinentry (gpg_error_from_errno (err));
1486   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1487
1488   popup_finished = 0;
1489   err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL);
1490   npth_attr_destroy (&tattr);
1491   if (err)
1492     {
1493       rc = gpg_error_from_errno (err);
1494       log_error ("error spawning popup message handler: %s\n",
1495                  strerror (err) );
1496       return unlock_pinentry (rc);
1497     }
1498   npth_setname_np (popup_tid, "popup-message");
1499
1500   return 0;
1501 }
1502
1503 /* Close a popup window. */
1504 void
1505 agent_popup_message_stop (ctrl_t ctrl)
1506 {
1507   int rc;
1508   pid_t pid;
1509
1510   (void)ctrl;
1511
1512   if (!popup_tid || !entry_ctx)
1513     {
1514       log_debug ("agent_popup_message_stop called with no active popup\n");
1515       return;
1516     }
1517
1518   pid = assuan_get_pid (entry_ctx);
1519   if (pid == (pid_t)(-1))
1520     ; /* No pid available can't send a kill. */
1521   else if (popup_finished)
1522     ; /* Already finished and ready for joining. */
1523 #ifdef HAVE_W32_SYSTEM
1524   /* Older versions of assuan set PID to 0 on Windows to indicate an
1525      invalid value.  */
1526   else if (pid != (pid_t) INVALID_HANDLE_VALUE
1527            && pid != 0)
1528     {
1529       HANDLE process = (HANDLE) pid;
1530
1531       /* Arbitrary error code.  */
1532       TerminateProcess (process, 1);
1533     }
1534 #else
1535   else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
1536     { /* The daemon already died.  No need to send a kill.  However
1537          because we already waited for the process, we need to tell
1538          assuan that it should not wait again (done by
1539          unlock_pinentry). */
1540       if (rc == pid)
1541         assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
1542     }
1543   else if (pid > 0)
1544     kill (pid, SIGINT);
1545 #endif
1546
1547   /* Now wait for the thread to terminate. */
1548   rc = npth_join (popup_tid, NULL);
1549   if (rc)
1550     log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
1551                strerror (rc));
1552   /* Thread IDs are opaque, but we try our best here by resetting it
1553      to the same content that a static global variable has.  */
1554   memset (&popup_tid, '\0', sizeof (popup_tid));
1555   entry_owner = NULL;
1556
1557   /* Now we can close the connection. */
1558   unlock_pinentry (0);
1559 }
1560
1561 int
1562 agent_clear_passphrase (ctrl_t ctrl,
1563                         const char *keyinfo, cache_mode_t cache_mode)
1564 {
1565   int rc;
1566   char line[ASSUAN_LINELENGTH];
1567
1568   if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1569                      || cache_mode == CACHE_MODE_USER
1570                      || cache_mode == CACHE_MODE_SSH)))
1571     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1572
1573   rc = start_pinentry (ctrl);
1574   if (rc)
1575     return rc;
1576
1577   snprintf (line, DIM(line), "CLEARPASSPHRASE %c/%s",
1578             cache_mode == CACHE_MODE_USER? 'u' :
1579             cache_mode == CACHE_MODE_SSH? 's' : 'n',
1580             keyinfo);
1581   rc = assuan_transact (entry_ctx, line,
1582                         NULL, NULL, NULL, NULL, NULL, NULL);
1583
1584   return unlock_pinentry (rc);
1585 }