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