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