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