33e3ec3c6ac4cb945f8fa9cdfd5bf59b417b988b
[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   rc = assuan_transact (entry_ctx,
358                         opt.no_grab? "OPTION no-grab":"OPTION grab",
359                         NULL, NULL, NULL, NULL, NULL, NULL);
360   if (rc)
361     return unlock_pinentry (rc);
362
363   value = session_env_getenv (ctrl->session_env, "GPG_TTY");
364   if (value)
365     {
366       char *optstr;
367       if (asprintf (&optstr, "OPTION ttyname=%s", value) < 0 )
368         return unlock_pinentry (out_of_core ());
369       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
370                             NULL);
371       xfree (optstr);
372       if (rc)
373         return unlock_pinentry (rc);
374     }
375   value = session_env_getenv (ctrl->session_env, "TERM");
376   if (value)
377     {
378       char *optstr;
379       if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 )
380         return unlock_pinentry (out_of_core ());
381       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
382                             NULL);
383       xfree (optstr);
384       if (rc)
385         return unlock_pinentry (rc);
386     }
387   if (ctrl->lc_ctype)
388     {
389       char *optstr;
390       if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 )
391         return unlock_pinentry (out_of_core ());
392       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
393                             NULL);
394       xfree (optstr);
395       if (rc)
396         return unlock_pinentry (rc);
397     }
398   if (ctrl->lc_messages)
399     {
400       char *optstr;
401       if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 )
402         return unlock_pinentry (out_of_core ());
403       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
404                             NULL);
405       xfree (optstr);
406       if (rc)
407         return unlock_pinentry (rc);
408     }
409
410
411   if (opt.allow_external_cache)
412     {
413       /* Indicate to the pinentry that it may read from an external cache.
414
415          It is essential that the pinentry respect this.  If the
416          cached password is not up to date and retry == 1, then, using
417          a version of GPG Agent that doesn't support this, won't issue
418          another pin request and the user won't get a chance to
419          correct the password.  */
420       rc = assuan_transact (entry_ctx, "OPTION allow-external-password-cache",
421                             NULL, NULL, NULL, NULL, NULL, NULL);
422       if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
423         return unlock_pinentry (rc);
424     }
425
426   if (opt.allow_emacs_pinentry)
427     {
428       /* Indicate to the pinentry that it may read passphrase through
429          Emacs minibuffer, if possible.  */
430       rc = assuan_transact (entry_ctx, "OPTION allow-emacs-prompt",
431                             NULL, NULL, NULL, NULL, NULL, NULL);
432       if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
433         return unlock_pinentry (rc);
434     }
435
436
437   {
438     /* Provide a few default strings for use by the pinentries.  This
439        may help a pinentry to avoid implementing localization code.  */
440     static struct { const char *key, *value; int what; } tbl[] = {
441       /* TRANSLATORS: These are labels for buttons etc used in
442          Pinentries.  An underscore indicates that the next letter
443          should be used as an accelerator.  Double the underscore for
444          a literal one.  The actual to be translated text starts after
445          the second vertical bar.  Note that gpg-agent has been set to
446          utf-8 so that the strings are in the expected encoding.  */
447       { "ok",     N_("|pinentry-label|_OK") },
448       { "cancel", N_("|pinentry-label|_Cancel") },
449       { "yes",    N_("|pinentry-label|_Yes") },
450       { "no",     N_("|pinentry-label|_No") },
451       { "prompt", N_("|pinentry-label|PIN:") },
452       { "pwmngr", N_("|pinentry-label|_Save in password manager"), 1 },
453       { "cf-visi",N_("Do you really want to make your "
454                      "passphrase visible on the screen?") },
455       { "tt-visi",N_("|pinentry-tt|Make passphrase visible") },
456       { "tt-hide",N_("|pinentry-tt|Hide passphrase") },
457       { NULL, NULL}
458     };
459     char *optstr;
460     int idx;
461     const char *s, *s2;
462
463     for (idx=0; tbl[idx].key; idx++)
464       {
465         if (!opt.allow_external_cache && tbl[idx].what == 1)
466           continue;  /* No need for it.  */
467         s = L_(tbl[idx].value);
468         if (*s == '|' && (s2=strchr (s+1,'|')))
469           s = s2+1;
470         if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 )
471           return unlock_pinentry (out_of_core ());
472         assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
473                          NULL);
474         xfree (optstr);
475       }
476   }
477
478   /* Tell the pinentry that we would prefer that the given character
479      is used as the invisible character by the entry widget.  */
480   if (opt.pinentry_invisible_char)
481     {
482       char *optstr;
483       if ((optstr = xtryasprintf ("OPTION invisible-char=%s",
484                                   opt.pinentry_invisible_char)))
485         {
486           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
487                            NULL);
488           /* We ignore errors because this is just a fancy thing and
489              older pinentries do not support this feature.  */
490           xfree (optstr);
491         }
492     }
493
494   /* Tell the pinentry the name of a file it shall touch after having
495      messed with the tty.  This is optional and only supported by
496      newer pinentries and thus we do no error checking. */
497   tmpstr = opt.pinentry_touch_file;
498   if (tmpstr && !strcmp (tmpstr, "/dev/null"))
499     tmpstr = NULL;
500   else if (!tmpstr)
501     tmpstr = get_agent_socket_name ();
502   if (tmpstr)
503     {
504       char *optstr;
505
506       if (asprintf (&optstr, "OPTION touch-file=%s", tmpstr ) < 0 )
507         ;
508       else
509         {
510           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
511                            NULL);
512           xfree (optstr);
513         }
514     }
515
516
517   /* Now ask the Pinentry for its PID.  If the Pinentry is new enough
518      it will send the pid back and we will use an inquire to notify
519      our client.  The client may answer the inquiry either with END or
520      with CAN to cancel the pinentry. */
521   rc = assuan_transact (entry_ctx, "GETINFO pid",
522                         getinfo_pid_cb, &pinentry_pid,
523                         NULL, NULL, NULL, NULL);
524   if (rc)
525     {
526       log_info ("You may want to update to a newer pinentry\n");
527       rc = 0;
528     }
529   else if (!rc && (pid_t)pinentry_pid == (pid_t)(-1))
530     log_error ("pinentry did not return a PID\n");
531   else
532     {
533       rc = agent_inq_pinentry_launched (ctrl, pinentry_pid);
534       if (gpg_err_code (rc) == GPG_ERR_CANCELED
535           || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
536         return unlock_pinentry (gpg_err_make (GPG_ERR_SOURCE_DEFAULT,
537                                               gpg_err_code (rc)));
538       rc = 0;
539     }
540
541   return 0;
542 }
543
544
545 /* Returns True if the pinentry is currently active. If WAITSECONDS is
546    greater than zero the function will wait for this many seconds
547    before returning.  */
548 int
549 pinentry_active_p (ctrl_t ctrl, int waitseconds)
550 {
551   int err;
552   (void)ctrl;
553
554   if (waitseconds > 0)
555     {
556       struct timespec abstime;
557       int rc;
558
559       npth_clock_gettime (&abstime);
560       abstime.tv_sec += waitseconds;
561       err = npth_mutex_timedlock (&entry_lock, &abstime);
562       if (err)
563         {
564           if (err == ETIMEDOUT)
565             rc = gpg_error (GPG_ERR_TIMEOUT);
566           else
567             rc = gpg_error (GPG_ERR_INTERNAL);
568           return rc;
569         }
570     }
571   else
572     {
573       err = npth_mutex_trylock (&entry_lock);
574       if (err)
575         return gpg_error (GPG_ERR_LOCKED);
576     }
577
578   err = npth_mutex_unlock (&entry_lock);
579   if (err)
580     log_error ("failed to release the entry lock at %d: %s\n", __LINE__,
581                strerror (errno));
582   return 0;
583 }
584
585
586 static gpg_error_t
587 getpin_cb (void *opaque, const void *buffer, size_t length)
588 {
589   struct entry_parm_s *parm = opaque;
590
591   if (!buffer)
592     return 0;
593
594   /* we expect the pin to fit on one line */
595   if (parm->lines || length >= parm->size)
596     return gpg_error (GPG_ERR_ASS_TOO_MUCH_DATA);
597
598   /* fixme: we should make sure that the assuan buffer is allocated in
599      secure memory or read the response byte by byte */
600   memcpy (parm->buffer, buffer, length);
601   parm->buffer[length] = 0;
602   parm->lines++;
603   return 0;
604 }
605
606
607 static int
608 all_digitsp( const char *s)
609 {
610   for (; *s && *s >= '0' && *s <= '9'; s++)
611     ;
612   return !*s;
613 }
614
615
616 /* Return a new malloced string by unescaping the string S.  Escaping
617    is percent escaping and '+'/space mapping.  A binary Nul will
618    silently be replaced by a 0xFF.  Function returns NULL to indicate
619    an out of memory status.  Parsing stops at the end of the string or
620    a white space character. */
621 static char *
622 unescape_passphrase_string (const unsigned char *s)
623 {
624   char *buffer, *d;
625
626   buffer = d = xtrymalloc_secure (strlen ((const char*)s)+1);
627   if (!buffer)
628     return NULL;
629   while (*s && !spacep (s))
630     {
631       if (*s == '%' && s[1] && s[2])
632         {
633           s++;
634           *d = xtoi_2 (s);
635           if (!*d)
636             *d = '\xff';
637           d++;
638           s += 2;
639         }
640       else if (*s == '+')
641         {
642           *d++ = ' ';
643           s++;
644         }
645       else
646         *d++ = *s++;
647     }
648   *d = 0;
649   return buffer;
650 }
651
652
653 /* Estimate the quality of the passphrase PW and return a value in the
654    range 0..100.  */
655 static int
656 estimate_passphrase_quality (const char *pw)
657 {
658   int goodlength = opt.min_passphrase_len + opt.min_passphrase_len/3;
659   int length;
660   const char *s;
661
662   if (goodlength < 1)
663     return 0;
664
665   for (length = 0, s = pw; *s; s++)
666     if (!spacep (s))
667       length ++;
668
669   if (length > goodlength)
670     return 100;
671   return ((length*10) / goodlength)*10;
672 }
673
674
675 /* Handle the QUALITY inquiry. */
676 static gpg_error_t
677 inq_quality (void *opaque, const char *line)
678 {
679   assuan_context_t ctx = opaque;
680   const char *s;
681   char *pin;
682   int rc;
683   int percent;
684   char numbuf[20];
685
686   if ((s = has_leading_keyword (line, "QUALITY")))
687     {
688       pin = unescape_passphrase_string (s);
689       if (!pin)
690         rc = gpg_error_from_syserror ();
691       else
692         {
693           percent = estimate_passphrase_quality (pin);
694           if (check_passphrase_constraints (NULL, pin, NULL))
695             percent = -percent;
696           snprintf (numbuf, sizeof numbuf, "%d", percent);
697           rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
698           xfree (pin);
699         }
700     }
701   else
702     {
703       log_error ("unsupported inquiry '%s' from pinentry\n", line);
704       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
705     }
706
707   return rc;
708 }
709
710
711 /* Helper for agent_askpin and agent_get_passphrase.  */
712 static gpg_error_t
713 setup_qualitybar (ctrl_t ctrl)
714 {
715   int rc;
716   char line[ASSUAN_LINELENGTH];
717   char *tmpstr, *tmpstr2;
718   const char *tooltip;
719
720   (void)ctrl;
721
722   /* TRANSLATORS: This string is displayed by Pinentry as the label
723      for the quality bar.  */
724   tmpstr = try_percent_escape (L_("Quality:"), "\t\r\n\f\v");
725   snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:"");
726   line[DIM(line)-1] = 0;
727   xfree (tmpstr);
728   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
729   if (rc == 103 /*(Old assuan error code)*/
730       || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
731     ; /* Ignore Unknown Command from old Pinentry versions.  */
732   else if (rc)
733     return rc;
734
735   tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
736   if (tmpstr2)
737     tooltip = tmpstr2;
738   else
739     {
740       /* TRANSLATORS: This string is a tooltip, shown by pinentry when
741          hovering over the quality bar.  Please use an appropriate
742          string to describe what this is about.  The length of the
743          tooltip is limited to about 900 characters.  If you do not
744          translate this entry, a default english text (see source)
745          will be used. */
746       tooltip =  L_("pinentry.qualitybar.tooltip");
747       if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
748         tooltip = ("The quality of the text entered above.\n"
749                    "Please ask your administrator for "
750                    "details about the criteria.");
751     }
752   tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
753   xfree (tmpstr2);
754   snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
755   line[DIM(line)-1] = 0;
756   xfree (tmpstr);
757   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
758   if (rc == 103 /*(Old assuan error code)*/
759           || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
760     ; /* Ignore Unknown Command from old pinentry versions.  */
761   else if (rc)
762     return rc;
763
764   return 0;
765 }
766
767 enum
768   {
769     PINENTRY_STATUS_CLOSE_BUTTON = 1 << 0,
770     PINENTRY_STATUS_PIN_REPEATED = 1 << 8,
771     PINENTRY_STATUS_PASSWORD_FROM_CACHE = 1 << 9
772   };
773
774 /* Check the button_info line for a close action.  Also check for the
775    PIN_REPEATED flag.  */
776 static gpg_error_t
777 pinentry_status_cb (void *opaque, const char *line)
778 {
779   unsigned int *flag = opaque;
780   const char *args;
781
782   if ((args = has_leading_keyword (line, "BUTTON_INFO")))
783     {
784       if (!strcmp (args, "close"))
785         *flag |= PINENTRY_STATUS_CLOSE_BUTTON;
786     }
787   else if (has_leading_keyword (line, "PIN_REPEATED"))
788     {
789       *flag |= PINENTRY_STATUS_PIN_REPEATED;
790     }
791   else if (has_leading_keyword (line, "PASSWORD_FROM_CACHE"))
792     {
793       *flag |= PINENTRY_STATUS_PASSWORD_FROM_CACHE;
794     }
795
796   return 0;
797 }
798
799
800
801 \f
802 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
803    number here and repeat it as long as we have invalid formed
804    numbers.  KEYINFO and CACHE_MODE are used to tell pinentry something
805    about the key. */
806 gpg_error_t
807 agent_askpin (ctrl_t ctrl,
808               const char *desc_text, const char *prompt_text,
809               const char *initial_errtext,
810               struct pin_entry_info_s *pininfo,
811               const char *keyinfo, cache_mode_t cache_mode)
812 {
813   gpg_error_t rc;
814   char line[ASSUAN_LINELENGTH];
815   struct entry_parm_s parm;
816   const char *errtext = NULL;
817   int is_pin = 0;
818   int saveflag;
819   unsigned int pinentry_status;
820
821   if (opt.batch)
822     return 0; /* fixme: we should return BAD PIN */
823
824   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
825     {
826       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
827         return gpg_error (GPG_ERR_CANCELED);
828       if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
829         {
830           unsigned char *passphrase;
831           size_t size;
832
833           *pininfo->pin = 0; /* Reset the PIN. */
834           rc = pinentry_loopback(ctrl, "PASSPHRASE", &passphrase, &size,
835                   pininfo->max_length - 1);
836           if (rc)
837             return rc;
838
839           memcpy(&pininfo->pin, passphrase, size);
840           xfree(passphrase);
841           pininfo->pin[size] = 0;
842           if (pininfo->check_cb)
843             {
844               /* More checks by utilizing the optional callback. */
845               pininfo->cb_errtext = NULL;
846               rc = pininfo->check_cb (pininfo);
847             }
848           return rc;
849         }
850       return gpg_error(GPG_ERR_NO_PIN_ENTRY);
851     }
852
853   if (!pininfo || pininfo->max_length < 1)
854     return gpg_error (GPG_ERR_INV_VALUE);
855   if (!desc_text && pininfo->min_digits)
856     desc_text = L_("Please enter your PIN, so that the secret key "
857                    "can be unlocked for this session");
858   else if (!desc_text)
859     desc_text = L_("Please enter your passphrase, so that the secret key "
860                    "can be unlocked for this session");
861
862   if (prompt_text)
863     is_pin = !!strstr (prompt_text, "PIN");
864   else
865     is_pin = desc_text && strstr (desc_text, "PIN");
866
867   rc = start_pinentry (ctrl);
868   if (rc)
869     return rc;
870
871   /* If we have a KEYINFO string and are normal, user, or ssh cache
872      mode, we tell that the Pinentry so it may use it for own caching
873      purposes.  Most pinentries won't have this implemented and thus
874      we do not error out in this case.  */
875   if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
876                   || cache_mode == CACHE_MODE_USER
877                   || cache_mode == CACHE_MODE_SSH))
878     snprintf (line, DIM(line)-1, "SETKEYINFO %c/%s",
879               cache_mode == CACHE_MODE_USER? 'u' :
880               cache_mode == CACHE_MODE_SSH? 's' : 'n',
881               keyinfo);
882   else
883     snprintf (line, DIM(line)-1, "SETKEYINFO --clear");
884
885   rc = assuan_transact (entry_ctx, line,
886                         NULL, NULL, NULL, NULL, NULL, NULL);
887   if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
888     return unlock_pinentry (rc);
889
890   snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
891   line[DIM(line)-1] = 0;
892   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
893   if (rc)
894     return unlock_pinentry (rc);
895
896   snprintf (line, DIM(line)-1, "SETPROMPT %s",
897             prompt_text? prompt_text : is_pin? L_("PIN:") : L_("Passphrase:"));
898   line[DIM(line)-1] = 0;
899   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
900   if (rc)
901     return unlock_pinentry (rc);
902
903   /* If a passphrase quality indicator has been requested and a
904      minimum passphrase length has not been disabled, send the command
905      to the pinentry.  */
906   if (pininfo->with_qualitybar && opt.min_passphrase_len )
907     {
908       rc = setup_qualitybar (ctrl);
909       if (rc)
910         return unlock_pinentry (rc);
911     }
912
913   if (initial_errtext)
914     {
915       snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext);
916       line[DIM(line)-1] = 0;
917       rc = assuan_transact (entry_ctx, line,
918                             NULL, NULL, NULL, NULL, NULL, NULL);
919       if (rc)
920         return unlock_pinentry (rc);
921     }
922
923   if (pininfo->with_repeat)
924     {
925       snprintf (line, DIM(line)-1, "SETREPEATERROR %s",
926                 L_("does not match - try again"));
927       line[DIM(line)-1] = 0;
928       rc = assuan_transact (entry_ctx, line,
929                             NULL, NULL, NULL, NULL, NULL, NULL);
930       if (rc)
931         pininfo->with_repeat = 0; /* Pinentry does not support it.  */
932     }
933   pininfo->repeat_okay = 0;
934
935   for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
936     {
937       memset (&parm, 0, sizeof parm);
938       parm.size = pininfo->max_length;
939       *pininfo->pin = 0; /* Reset the PIN. */
940       parm.buffer = (unsigned char*)pininfo->pin;
941
942       if (errtext)
943         {
944           /* TRANSLATORS: The string is appended to an error message in
945              the pinentry.  The %s is the actual error message, the
946              two %d give the current and maximum number of tries. */
947           snprintf (line, DIM(line)-1, L_("SETERROR %s (try %d of %d)"),
948                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
949           line[DIM(line)-1] = 0;
950           rc = assuan_transact (entry_ctx, line,
951                                 NULL, NULL, NULL, NULL, NULL, NULL);
952           if (rc)
953             return unlock_pinentry (rc);
954           errtext = NULL;
955         }
956
957       if (pininfo->with_repeat)
958         {
959           snprintf (line, DIM(line)-1, "SETREPEAT %s", L_("Repeat:"));
960           line[DIM(line)-1] = 0;
961           rc = assuan_transact (entry_ctx, line,
962                                 NULL, NULL, NULL, NULL, NULL, NULL);
963           if (rc)
964             return unlock_pinentry (rc);
965         }
966
967       saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
968       assuan_begin_confidential (entry_ctx);
969       pinentry_status = 0;
970       rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
971                             inq_quality, entry_ctx,
972                             pinentry_status_cb, &pinentry_status);
973       assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
974       /* Most pinentries out in the wild return the old Assuan error code
975          for canceled which gets translated to an assuan Cancel error and
976          not to the code for a user cancel.  Fix this here. */
977       if (rc && gpg_err_source (rc)
978           && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
979         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
980
981
982       /* Change error code in case the window close button was clicked
983          to cancel the operation.  */
984       if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON)
985           && gpg_err_code (rc) == GPG_ERR_CANCELED)
986         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
987
988       if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
989         errtext = is_pin? L_("PIN too long")
990                         : L_("Passphrase too long");
991       else if (rc)
992         return unlock_pinentry (rc);
993
994       if (!errtext && pininfo->min_digits)
995         {
996           /* do some basic checks on the entered PIN. */
997           if (!all_digitsp (pininfo->pin))
998             errtext = L_("Invalid characters in PIN");
999           else if (pininfo->max_digits
1000                    && strlen (pininfo->pin) > pininfo->max_digits)
1001             errtext = L_("PIN too long");
1002           else if (strlen (pininfo->pin) < pininfo->min_digits)
1003             errtext = L_("PIN too short");
1004         }
1005
1006       if (!errtext && pininfo->check_cb)
1007         {
1008           /* More checks by utilizing the optional callback. */
1009           pininfo->cb_errtext = NULL;
1010           rc = pininfo->check_cb (pininfo);
1011           if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1012               && pininfo->cb_errtext)
1013             errtext = pininfo->cb_errtext;
1014           else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1015                    || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
1016             errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase"));
1017           else if (rc)
1018             return unlock_pinentry (rc);
1019         }
1020
1021       if (!errtext)
1022         {
1023           if (pininfo->with_repeat
1024               && (pinentry_status & PINENTRY_STATUS_PIN_REPEATED))
1025             pininfo->repeat_okay = 1;
1026           return unlock_pinentry (0); /* okay, got a PIN or passphrase */
1027         }
1028
1029       if ((pinentry_status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1030         /* The password was read from the cache.  Don't count this
1031            against the retry count.  */
1032         pininfo->failed_tries --;
1033     }
1034
1035   return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
1036                           : GPG_ERR_BAD_PASSPHRASE));
1037 }
1038
1039
1040 \f
1041 /* Ask for the passphrase using the supplied arguments.  The returned
1042    passphrase needs to be freed by the caller. */
1043 int
1044 agent_get_passphrase (ctrl_t ctrl,
1045                       char **retpass, const char *desc, const char *prompt,
1046                       const char *errtext, int with_qualitybar,
1047                       const char *keyinfo, cache_mode_t cache_mode)
1048 {
1049
1050   int rc;
1051   char line[ASSUAN_LINELENGTH];
1052   struct entry_parm_s parm;
1053   int saveflag;
1054   unsigned int pinentry_status;
1055
1056   *retpass = NULL;
1057   if (opt.batch)
1058     return gpg_error (GPG_ERR_BAD_PASSPHRASE);
1059
1060   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1061     {
1062       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1063         return gpg_error (GPG_ERR_CANCELED);
1064
1065       if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1066         {
1067           size_t size;
1068           size_t len = ASSUAN_LINELENGTH/2;
1069
1070           return pinentry_loopback (ctrl, "PASSPHRASE",
1071                                     (unsigned char **)retpass, &size, len);
1072         }
1073       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1074     }
1075
1076   rc = start_pinentry (ctrl);
1077   if (rc)
1078     return rc;
1079
1080   if (!prompt)
1081     prompt = desc && strstr (desc, "PIN")? L_("PIN:"): L_("Passphrase:");
1082
1083
1084   /* If we have a KEYINFO string and are normal, user, or ssh cache
1085      mode, we tell that the Pinentry so it may use it for own caching
1086      purposes.  Most pinentries won't have this implemented and thus
1087      we do not error out in this case.  */
1088   if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1089                   || cache_mode == CACHE_MODE_USER
1090                   || cache_mode == CACHE_MODE_SSH))
1091     snprintf (line, DIM(line)-1, "SETKEYINFO %c/%s",
1092               cache_mode == CACHE_MODE_USER? 'u' :
1093               cache_mode == CACHE_MODE_SSH? 's' : 'n',
1094               keyinfo);
1095   else
1096     snprintf (line, DIM(line)-1, "SETKEYINFO --clear");
1097
1098   rc = assuan_transact (entry_ctx, line,
1099                         NULL, NULL, NULL, NULL, NULL, NULL);
1100   if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1101     return unlock_pinentry (rc);
1102
1103
1104   if (desc)
1105     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1106   else
1107     snprintf (line, DIM(line)-1, "RESET");
1108   line[DIM(line)-1] = 0;
1109   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1110   if (rc)
1111     return unlock_pinentry (rc);
1112
1113   snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
1114   line[DIM(line)-1] = 0;
1115   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1116   if (rc)
1117     return unlock_pinentry (rc);
1118
1119   if (with_qualitybar && opt.min_passphrase_len)
1120     {
1121       rc = setup_qualitybar (ctrl);
1122       if (rc)
1123         return unlock_pinentry (rc);
1124     }
1125
1126   if (errtext)
1127     {
1128       snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
1129       line[DIM(line)-1] = 0;
1130       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1131       if (rc)
1132         return unlock_pinentry (rc);
1133     }
1134
1135   memset (&parm, 0, sizeof parm);
1136   parm.size = ASSUAN_LINELENGTH/2 - 5;
1137   parm.buffer = gcry_malloc_secure (parm.size+10);
1138   if (!parm.buffer)
1139     return unlock_pinentry (out_of_core ());
1140
1141   saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
1142   assuan_begin_confidential (entry_ctx);
1143   pinentry_status = 0;
1144   rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
1145                         inq_quality, entry_ctx,
1146                         pinentry_status_cb, &pinentry_status);
1147   assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
1148   /* Most pinentries out in the wild return the old Assuan error code
1149      for canceled which gets translated to an assuan Cancel error and
1150      not to the code for a user cancel.  Fix this here. */
1151   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1152     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1153   /* Change error code in case the window close button was clicked
1154      to cancel the operation.  */
1155   if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON)
1156       && gpg_err_code (rc) == GPG_ERR_CANCELED)
1157     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
1158
1159   if (rc)
1160     xfree (parm.buffer);
1161   else
1162     *retpass = parm.buffer;
1163   return unlock_pinentry (rc);
1164 }
1165
1166
1167 \f
1168 /* Pop up the PIN-entry, display the text and the prompt and ask the
1169    user to confirm this.  We return 0 for success, ie. the user
1170    confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
1171    other error.  If WITH_CANCEL it true an extra cancel button is
1172    displayed to allow the user to easily return a GPG_ERR_CANCELED.
1173    if the Pinentry does not support this, the user can still cancel by
1174    closing the Pinentry window.  */
1175 int
1176 agent_get_confirmation (ctrl_t ctrl,
1177                         const char *desc, const char *ok,
1178                         const char *notok, int with_cancel)
1179 {
1180   int rc;
1181   char line[ASSUAN_LINELENGTH];
1182
1183   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1184     {
1185       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1186         return gpg_error (GPG_ERR_CANCELED);
1187
1188       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1189     }
1190
1191   rc = start_pinentry (ctrl);
1192   if (rc)
1193     return rc;
1194
1195   if (desc)
1196     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1197   else
1198     snprintf (line, DIM(line)-1, "RESET");
1199   line[DIM(line)-1] = 0;
1200   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1201   /* Most pinentries out in the wild return the old Assuan error code
1202      for canceled which gets translated to an assuan Cancel error and
1203      not to the code for a user cancel.  Fix this here. */
1204   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1205     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1206
1207   if (rc)
1208     return unlock_pinentry (rc);
1209
1210   if (ok)
1211     {
1212       snprintf (line, DIM(line)-1, "SETOK %s", ok);
1213       line[DIM(line)-1] = 0;
1214       rc = assuan_transact (entry_ctx,
1215                             line, NULL, NULL, NULL, NULL, NULL, NULL);
1216       if (rc)
1217         return unlock_pinentry (rc);
1218     }
1219   if (notok)
1220     {
1221       /* Try to use the newer NOTOK feature if a cancel button is
1222          requested.  If no cancel button is requested we keep on using
1223          the standard cancel.  */
1224       if (with_cancel)
1225         {
1226           snprintf (line, DIM(line)-1, "SETNOTOK %s", notok);
1227           line[DIM(line)-1] = 0;
1228           rc = assuan_transact (entry_ctx,
1229                                 line, NULL, NULL, NULL, NULL, NULL, NULL);
1230         }
1231       else
1232         rc = GPG_ERR_ASS_UNKNOWN_CMD;
1233
1234       if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1235         {
1236           snprintf (line, DIM(line)-1, "SETCANCEL %s", notok);
1237           line[DIM(line)-1] = 0;
1238           rc = assuan_transact (entry_ctx, line,
1239                                 NULL, NULL, NULL, NULL, NULL, NULL);
1240         }
1241       if (rc)
1242         return unlock_pinentry (rc);
1243     }
1244
1245   rc = assuan_transact (entry_ctx, "CONFIRM",
1246                         NULL, NULL, NULL, NULL, NULL, NULL);
1247   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1248     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1249
1250   return unlock_pinentry (rc);
1251 }
1252
1253
1254 \f
1255 /* Pop up the PINentry, display the text DESC and a button with the
1256    text OK_BTN (which may be NULL to use the default of "OK") and wait
1257    for the user to hit this button.  The return value is not
1258    relevant.  */
1259 int
1260 agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
1261 {
1262   int rc;
1263   char line[ASSUAN_LINELENGTH];
1264
1265   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1266     return gpg_error (GPG_ERR_CANCELED);
1267
1268   rc = start_pinentry (ctrl);
1269   if (rc)
1270     return rc;
1271
1272   if (desc)
1273     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1274   else
1275     snprintf (line, DIM(line)-1, "RESET");
1276   line[DIM(line)-1] = 0;
1277   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1278   /* Most pinentries out in the wild return the old Assuan error code
1279      for canceled which gets translated to an assuan Cancel error and
1280      not to the code for a user cancel.  Fix this here. */
1281   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1282     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1283
1284   if (rc)
1285     return unlock_pinentry (rc);
1286
1287   if (ok_btn)
1288     {
1289       snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
1290       line[DIM(line)-1] = 0;
1291       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL,
1292                             NULL, NULL, NULL);
1293       if (rc)
1294         return unlock_pinentry (rc);
1295     }
1296
1297   rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL,
1298                         NULL, NULL, NULL);
1299   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1300     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1301
1302   return unlock_pinentry (rc);
1303 }
1304
1305
1306 /* The thread running the popup message. */
1307 static void *
1308 popup_message_thread (void *arg)
1309 {
1310   (void)arg;
1311
1312   /* We use the --one-button hack instead of the MESSAGE command to
1313      allow the use of old Pinentries.  Those old Pinentries will then
1314      show an additional Cancel button but that is mostly a visual
1315      annoyance. */
1316   assuan_transact (entry_ctx, "CONFIRM --one-button",
1317                    NULL, NULL, NULL, NULL, NULL, NULL);
1318   popup_finished = 1;
1319   return NULL;
1320 }
1321
1322
1323 /* Pop up a message window similar to the confirm one but keep it open
1324    until agent_popup_message_stop has been called.  It is crucial for
1325    the caller to make sure that the stop function gets called as soon
1326    as the message is not anymore required because the message is
1327    system modal and all other attempts to use the pinentry will fail
1328    (after a timeout). */
1329 int
1330 agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
1331 {
1332   int rc;
1333   char line[ASSUAN_LINELENGTH];
1334   npth_attr_t tattr;
1335   int err;
1336
1337   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1338     return gpg_error (GPG_ERR_CANCELED);
1339
1340   rc = start_pinentry (ctrl);
1341   if (rc)
1342     return rc;
1343
1344   if (desc)
1345     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1346   else
1347     snprintf (line, DIM(line)-1, "RESET");
1348   line[DIM(line)-1] = 0;
1349   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1350   if (rc)
1351     return unlock_pinentry (rc);
1352
1353   if (ok_btn)
1354     {
1355       snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
1356       line[DIM(line)-1] = 0;
1357       rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
1358       if (rc)
1359         return unlock_pinentry (rc);
1360     }
1361
1362   err = npth_attr_init (&tattr);
1363   if (err)
1364     return unlock_pinentry (gpg_error_from_errno (err));
1365   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1366
1367   popup_finished = 0;
1368   err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL);
1369   npth_attr_destroy (&tattr);
1370   if (err)
1371     {
1372       rc = gpg_error_from_errno (err);
1373       log_error ("error spawning popup message handler: %s\n",
1374                  strerror (err) );
1375       return unlock_pinentry (rc);
1376     }
1377   npth_setname_np (popup_tid, "popup-message");
1378
1379   return 0;
1380 }
1381
1382 /* Close a popup window. */
1383 void
1384 agent_popup_message_stop (ctrl_t ctrl)
1385 {
1386   int rc;
1387   pid_t pid;
1388
1389   (void)ctrl;
1390
1391   if (!popup_tid || !entry_ctx)
1392     {
1393       log_debug ("agent_popup_message_stop called with no active popup\n");
1394       return;
1395     }
1396
1397   pid = assuan_get_pid (entry_ctx);
1398   if (pid == (pid_t)(-1))
1399     ; /* No pid available can't send a kill. */
1400   else if (popup_finished)
1401     ; /* Already finished and ready for joining. */
1402 #ifdef HAVE_W32_SYSTEM
1403   /* Older versions of assuan set PID to 0 on Windows to indicate an
1404      invalid value.  */
1405   else if (pid != (pid_t) INVALID_HANDLE_VALUE
1406            && pid != 0)
1407     {
1408       HANDLE process = (HANDLE) pid;
1409
1410       /* Arbitrary error code.  */
1411       TerminateProcess (process, 1);
1412     }
1413 #else
1414   else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
1415     { /* The daemon already died.  No need to send a kill.  However
1416          because we already waited for the process, we need to tell
1417          assuan that it should not wait again (done by
1418          unlock_pinentry). */
1419       if (rc == pid)
1420         assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
1421     }
1422   else if (pid > 0)
1423     kill (pid, SIGINT);
1424 #endif
1425
1426   /* Now wait for the thread to terminate. */
1427   rc = npth_join (popup_tid, NULL);
1428   if (rc)
1429     log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
1430                strerror (rc));
1431   /* Thread IDs are opaque, but we try our best here by resetting it
1432      to the same content that a static global variable has.  */
1433   memset (&popup_tid, '\0', sizeof (popup_tid));
1434   entry_owner = NULL;
1435
1436   /* Now we can close the connection. */
1437   unlock_pinentry (0);
1438 }
1439
1440 int
1441 agent_clear_passphrase (ctrl_t ctrl,
1442                         const char *keyinfo, cache_mode_t cache_mode)
1443 {
1444   int rc;
1445   char line[ASSUAN_LINELENGTH];
1446
1447   if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1448                      || cache_mode == CACHE_MODE_USER
1449                      || cache_mode == CACHE_MODE_SSH)))
1450     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1451
1452   rc = start_pinentry (ctrl);
1453   if (rc)
1454     return rc;
1455
1456   snprintf (line, DIM(line)-1, "CLEARPASSPHRASE %c/%s",
1457             cache_mode == CACHE_MODE_USER? 'u' :
1458             cache_mode == CACHE_MODE_SSH? 's' : 'n',
1459             keyinfo);
1460   rc = assuan_transact (entry_ctx, line,
1461                         NULL, NULL, NULL, NULL, NULL, NULL);
1462
1463   return unlock_pinentry (rc);
1464 }