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