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