Use passphrase caching for import and genkey.
[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\n",
336                  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         return unlock_pinentry (gpg_error (GPG_ERR_CANCELED));
472       rc = 0;
473     }
474
475   return 0;
476 }
477
478
479 /* Returns True is the pinentry is currently active. If WAITSECONDS is
480    greater than zero the function will wait for this many seconds
481    before returning.  */
482 int
483 pinentry_active_p (ctrl_t ctrl, int waitseconds)
484 {
485   (void)ctrl;
486
487   if (waitseconds > 0)
488     {
489       pth_event_t evt;
490       int rc;
491
492       evt = pth_event (PTH_EVENT_TIME, pth_timeout (waitseconds, 0));
493       if (!pth_mutex_acquire (&entry_lock, 0, evt))
494         {
495           if (pth_event_occurred (evt))
496             rc = gpg_error (GPG_ERR_TIMEOUT);
497           else
498             rc = gpg_error (GPG_ERR_INTERNAL);
499           pth_event_free (evt, PTH_FREE_THIS);
500           return rc;
501         }
502       pth_event_free (evt, PTH_FREE_THIS);
503     }
504   else
505     {
506       if (!pth_mutex_acquire (&entry_lock, 1, NULL))
507         return gpg_error (GPG_ERR_LOCKED);
508     }
509
510   if (!pth_mutex_release (&entry_lock))
511     log_error ("failed to release the entry lock at %d\n", __LINE__);
512   return 0;
513 }
514
515
516 static gpg_error_t
517 getpin_cb (void *opaque, const void *buffer, size_t length)
518 {
519   struct entry_parm_s *parm = opaque;
520
521   if (!buffer)
522     return 0;
523
524   /* we expect the pin to fit on one line */
525   if (parm->lines || length >= parm->size)
526     return gpg_error (GPG_ERR_ASS_TOO_MUCH_DATA);
527
528   /* fixme: we should make sure that the assuan buffer is allocated in
529      secure memory or read the response byte by byte */
530   memcpy (parm->buffer, buffer, length);
531   parm->buffer[length] = 0;
532   parm->lines++;
533   return 0;
534 }
535
536
537 static int
538 all_digitsp( const char *s)
539 {
540   for (; *s && *s >= '0' && *s <= '9'; s++)
541     ;
542   return !*s;
543 }  
544
545
546 /* Return a new malloced string by unescaping the string S.  Escaping
547    is percent escaping and '+'/space mapping.  A binary Nul will
548    silently be replaced by a 0xFF.  Function returns NULL to indicate
549    an out of memory status.  PArsing stops at the end of the string or
550    a white space character. */
551 static char *
552 unescape_passphrase_string (const unsigned char *s)
553 {
554   char *buffer, *d;
555
556   buffer = d = xtrymalloc_secure (strlen ((const char*)s)+1);
557   if (!buffer)
558     return NULL;
559   while (*s && !spacep (s))
560     {
561       if (*s == '%' && s[1] && s[2])
562         { 
563           s++;
564           *d = xtoi_2 (s);
565           if (!*d)
566             *d = '\xff';
567           d++;
568           s += 2;
569         }
570       else if (*s == '+')
571         {
572           *d++ = ' ';
573           s++;
574         }
575       else
576         *d++ = *s++;
577     }
578   *d = 0; 
579   return buffer;
580 }
581
582
583 /* Estimate the quality of the passphrase PW and return a value in the
584    range 0..100.  */
585 static int
586 estimate_passphrase_quality (const char *pw)
587 {
588   int goodlength = opt.min_passphrase_len + opt.min_passphrase_len/3;
589   int length;
590   const char *s;
591
592   if (goodlength < 1)
593     return 0;
594
595   for (length = 0, s = pw; *s; s++)
596     if (!spacep (s))
597       length ++;
598
599   if (length > goodlength)
600     return 100;
601   return ((length*10) / goodlength)*10;
602 }
603
604
605 /* Handle the QUALITY inquiry. */
606 static gpg_error_t
607 inq_quality (void *opaque, const char *line)
608 {
609   assuan_context_t ctx = opaque;
610   char *pin;
611   int rc;
612   int percent;
613   char numbuf[20];
614
615   if (!strncmp (line, "QUALITY", 7) && (line[7] == ' ' || !line[7]))
616     {
617       line += 7;
618       while (*line == ' ')
619         line++;
620       
621       pin = unescape_passphrase_string (line);
622       if (!pin)
623         rc = gpg_error_from_syserror ();
624       else
625         {
626           percent = estimate_passphrase_quality (pin);
627           if (check_passphrase_constraints (NULL, pin, 1))
628             percent = -percent;
629           snprintf (numbuf, sizeof numbuf, "%d", percent);
630           rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
631           xfree (pin);
632         }
633     }
634   else
635     {
636       log_error ("unsupported inquiry `%s' from pinentry\n", line);
637       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
638     }
639
640   return rc;
641 }
642
643
644 /* Helper for agent_askpin and agent_get_passphrase.  */
645 static int
646 setup_qualitybar (void)
647 {
648   int rc;
649   char line[ASSUAN_LINELENGTH];
650   char *tmpstr, *tmpstr2;
651   const char *tooltip;
652   
653   /* TRANSLATORS: This string is displayed by Pinentry as the label
654      for the quality bar.  */
655   tmpstr = try_percent_escape (_("Quality:"), "\t\r\n\f\v");
656   snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:"");
657   line[DIM(line)-1] = 0;
658   xfree (tmpstr);
659   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
660   if (rc == 103 /*(Old assuan error code)*/
661       || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
662     ; /* Ignore Unknown Command from old Pinentry versions.  */
663   else if (rc)
664     return rc;
665   
666   tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
667   if (tmpstr2)
668     tooltip = tmpstr2;
669   else
670     {
671       /* TRANSLATORS: This string is a tooltip, shown by pinentry when
672          hovering over the quality bar.  Please use an appropriate
673          string to describe what this is about.  The length of the
674          tooltip is limited to about 900 characters.  If you do not
675          translate this entry, a default english text (see source)
676          will be used. */
677       tooltip =  _("pinentry.qualitybar.tooltip");
678       if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
679         tooltip = ("The quality of the text entered above.\n"
680                    "Please ask your administrator for "
681                    "details about the criteria.");
682     }
683   tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
684   xfree (tmpstr2);
685   snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
686   line[DIM(line)-1] = 0;
687   xfree (tmpstr);
688   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
689   if (rc == 103 /*(Old assuan error code)*/
690           || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
691     ; /* Ignore Unknown Command from old pinentry versions.  */
692   else if (rc)
693     return rc;
694
695   return 0;
696 }
697
698
699 \f
700 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
701    number here and repeat it as long as we have invalid formed
702    numbers. */
703 int
704 agent_askpin (ctrl_t ctrl,
705               const char *desc_text, const char *prompt_text,
706               const char *initial_errtext,
707               struct pin_entry_info_s *pininfo)
708 {
709   int rc;
710   char line[ASSUAN_LINELENGTH];
711   struct entry_parm_s parm;
712   const char *errtext = NULL;
713   int is_pin = 0;
714   int saveflag;
715
716   if (opt.batch)
717     return 0; /* fixme: we should return BAD PIN */
718
719   if (!pininfo || pininfo->max_length < 1)
720     return gpg_error (GPG_ERR_INV_VALUE);
721   if (!desc_text && pininfo->min_digits)
722     desc_text = _("Please enter your PIN, so that the secret key "
723                   "can be unlocked for this session");
724   else if (!desc_text)
725     desc_text = _("Please enter your passphrase, so that the secret key "
726                   "can be unlocked for this session");
727
728   if (prompt_text)
729     is_pin = !!strstr (prompt_text, "PIN");
730   else
731     is_pin = desc_text && strstr (desc_text, "PIN");
732
733   rc = start_pinentry (ctrl);
734   if (rc)
735     return rc;
736
737   snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
738   line[DIM(line)-1] = 0;
739   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
740   if (rc)
741     return unlock_pinentry (rc);
742
743   snprintf (line, DIM(line)-1, "SETPROMPT %s",
744             prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:");
745   line[DIM(line)-1] = 0;
746   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
747   if (rc)
748     return unlock_pinentry (rc);
749
750   /* If a passphrase quality indicator has been requested and a
751      minimum passphrase length has not been disabled, send the command
752      to the pinentry.  */
753   if (pininfo->with_qualitybar && opt.min_passphrase_len )
754     {
755       rc = setup_qualitybar ();
756       if (rc)
757         return unlock_pinentry (rc);
758     }
759
760   if (initial_errtext)
761     { 
762       snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext);
763       line[DIM(line)-1] = 0;
764       rc = assuan_transact (entry_ctx, line,
765                             NULL, NULL, NULL, NULL, NULL, NULL);
766       if (rc)
767         return unlock_pinentry (rc);
768     }
769
770   for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
771     {
772       memset (&parm, 0, sizeof parm);
773       parm.size = pininfo->max_length;
774       *pininfo->pin = 0; /* Reset the PIN. */
775       parm.buffer = (unsigned char*)pininfo->pin;
776
777       if (errtext)
778         { 
779           /* TRANLATORS: The string is appended to an error message in
780              the pinentry.  The %s is the actual error message, the
781              two %d give the current and maximum number of tries. */
782           snprintf (line, DIM(line)-1, _("SETERROR %s (try %d of %d)"),
783                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
784           line[DIM(line)-1] = 0;
785           rc = assuan_transact (entry_ctx, line,
786                                 NULL, NULL, NULL, NULL, NULL, NULL);
787           if (rc)
788             return unlock_pinentry (rc);
789           errtext = NULL;
790         }
791       
792       saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
793       assuan_begin_confidential (entry_ctx);
794       rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
795                             inq_quality, entry_ctx, NULL, NULL);
796       assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
797       /* Most pinentries out in the wild return the old Assuan error code
798          for canceled which gets translated to an assuan Cancel error and
799          not to the code for a user cancel.  Fix this here. */
800       if (rc && gpg_err_source (rc)
801           && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
802         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
803
804       if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
805         errtext = is_pin? _("PIN too long")
806                         : _("Passphrase too long");
807       else if (rc)
808         return unlock_pinentry (rc);
809
810       if (!errtext && pininfo->min_digits)
811         {
812           /* do some basic checks on the entered PIN. */
813           if (!all_digitsp (pininfo->pin))
814             errtext = _("Invalid characters in PIN");
815           else if (pininfo->max_digits
816                    && strlen (pininfo->pin) > pininfo->max_digits)
817             errtext = _("PIN too long");
818           else if (strlen (pininfo->pin) < pininfo->min_digits)
819             errtext = _("PIN too short");
820         }
821
822       if (!errtext && pininfo->check_cb)
823         {
824           /* More checks by utilizing the optional callback. */
825           pininfo->cb_errtext = NULL;
826           rc = pininfo->check_cb (pininfo);
827           if (rc == -1 && pininfo->cb_errtext)
828             errtext = pininfo->cb_errtext;
829           else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
830                    || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
831             errtext = (is_pin? _("Bad PIN")
832                        : _("Bad Passphrase"));
833           else if (rc)
834             return unlock_pinentry (rc);
835         }
836
837       if (!errtext)
838         return unlock_pinentry (0); /* okay, got a PIN or passphrase */
839     }
840
841   return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
842                           : GPG_ERR_BAD_PASSPHRASE));
843 }
844
845
846 \f
847 /* Ask for the passphrase using the supplied arguments.  The returned
848    passphrase needs to be freed by the caller. */
849 int 
850 agent_get_passphrase (ctrl_t ctrl,
851                       char **retpass, const char *desc, const char *prompt,
852                       const char *errtext, int with_qualitybar)
853 {
854
855   int rc;
856   char line[ASSUAN_LINELENGTH];
857   struct entry_parm_s parm;
858   int saveflag;
859
860   *retpass = NULL;
861   if (opt.batch)
862     return gpg_error (GPG_ERR_BAD_PASSPHRASE); 
863
864   rc = start_pinentry (ctrl);
865   if (rc)
866     return rc;
867
868   if (!prompt)
869     prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");
870
871
872   if (desc)
873     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
874   else
875     snprintf (line, DIM(line)-1, "RESET");
876   line[DIM(line)-1] = 0;
877   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
878   if (rc)
879     return unlock_pinentry (rc);
880
881   snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
882   line[DIM(line)-1] = 0;
883   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
884   if (rc)
885     return unlock_pinentry (rc);
886
887   if (with_qualitybar && opt.min_passphrase_len)
888     {
889       rc = setup_qualitybar ();
890       if (rc)
891         return unlock_pinentry (rc);
892     }
893
894   if (errtext)
895     {
896       snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
897       line[DIM(line)-1] = 0;
898       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
899       if (rc)
900         return unlock_pinentry (rc);
901     }
902
903   memset (&parm, 0, sizeof parm);
904   parm.size = ASSUAN_LINELENGTH/2 - 5;
905   parm.buffer = gcry_malloc_secure (parm.size+10);
906   if (!parm.buffer)
907     return unlock_pinentry (out_of_core ());
908
909   saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
910   assuan_begin_confidential (entry_ctx);
911   rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
912                         inq_quality, entry_ctx, NULL, NULL);
913   assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
914   /* Most pinentries out in the wild return the old Assuan error code
915      for canceled which gets translated to an assuan Cancel error and
916      not to the code for a user cancel.  Fix this here. */
917   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
918     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
919   if (rc)
920     xfree (parm.buffer);
921   else
922     *retpass = parm.buffer;
923   return unlock_pinentry (rc);
924 }
925
926
927 \f
928 /* Pop up the PIN-entry, display the text and the prompt and ask the
929    user to confirm this.  We return 0 for success, ie. the user
930    confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
931    other error.  If WITH_CANCEL it true an extra cancel button is
932    displayed to allow the user to easily return a GPG_ERR_CANCELED.
933    if the Pinentry does not support this, the user can still cancel by
934    closing the Pinentry window.  */
935 int 
936 agent_get_confirmation (ctrl_t ctrl,
937                         const char *desc, const char *ok, 
938                         const char *notok, int with_cancel)
939 {
940   int rc;
941   char line[ASSUAN_LINELENGTH];
942
943   rc = start_pinentry (ctrl);
944   if (rc)
945     return rc;
946
947   if (desc)
948     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
949   else
950     snprintf (line, DIM(line)-1, "RESET");
951   line[DIM(line)-1] = 0;
952   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
953   /* Most pinentries out in the wild return the old Assuan error code
954      for canceled which gets translated to an assuan Cancel error and
955      not to the code for a user cancel.  Fix this here. */
956   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
957     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
958
959   if (rc)
960     return unlock_pinentry (rc);
961
962   if (ok)
963     {
964       snprintf (line, DIM(line)-1, "SETOK %s", ok);
965       line[DIM(line)-1] = 0;
966       rc = assuan_transact (entry_ctx,
967                             line, NULL, NULL, NULL, NULL, NULL, NULL);
968       if (rc)
969         return unlock_pinentry (rc);
970     }
971   if (notok)
972     {
973       /* Try to use the newer NOTOK feature if a cancel button is
974          requested.  If no cancel button is requested we keep on using
975          the standard cancel.  */
976       if (with_cancel)
977         {
978           snprintf (line, DIM(line)-1, "SETNOTOK %s", notok);
979           line[DIM(line)-1] = 0;
980           rc = assuan_transact (entry_ctx,
981                                 line, NULL, NULL, NULL, NULL, NULL, NULL);
982         }
983       else
984         rc = GPG_ERR_ASS_UNKNOWN_CMD;
985
986       if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
987         {
988           snprintf (line, DIM(line)-1, "SETCANCEL %s", notok);
989           line[DIM(line)-1] = 0;
990           rc = assuan_transact (entry_ctx, line,
991                                 NULL, NULL, NULL, NULL, NULL, NULL);
992         }
993       if (rc)
994         return unlock_pinentry (rc);
995     }
996
997   rc = assuan_transact (entry_ctx, "CONFIRM",
998                         NULL, NULL, NULL, NULL, NULL, NULL);
999   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1000     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1001
1002   return unlock_pinentry (rc);
1003 }
1004
1005
1006 \f
1007 /* Pop up the PINentry, display the text DESC and a button with the
1008    text OK_BTN (which may be NULL to use the default of "OK") and waut
1009    for the user to hit this button.  The return value is not
1010    relevant.  */
1011 int 
1012 agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
1013 {
1014   int rc;
1015   char line[ASSUAN_LINELENGTH];
1016
1017   rc = start_pinentry (ctrl);
1018   if (rc)
1019     return rc;
1020
1021   if (desc)
1022     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1023   else
1024     snprintf (line, DIM(line)-1, "RESET");
1025   line[DIM(line)-1] = 0;
1026   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1027   /* Most pinentries out in the wild return the old Assuan error code
1028      for canceled which gets translated to an assuan Cancel error and
1029      not to the code for a user cancel.  Fix this here. */
1030   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1031     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1032
1033   if (rc)
1034     return unlock_pinentry (rc);
1035
1036   if (ok_btn)
1037     {
1038       snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
1039       line[DIM(line)-1] = 0;
1040       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL,
1041                             NULL, NULL, NULL);
1042       if (rc)
1043         return unlock_pinentry (rc);
1044     }
1045   
1046   rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL,
1047                         NULL, NULL, NULL);
1048   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1049     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1050
1051   return unlock_pinentry (rc);
1052 }
1053
1054
1055 /* The thread running the popup message. */
1056 static void *
1057 popup_message_thread (void *arg)
1058 {
1059   (void)arg;
1060
1061   /* We use the --one-button hack instead of the MESSAGE command to
1062      allow the use of old Pinentries.  Those old Pinentries will then
1063      show an additional Cancel button but that is mostly a visual
1064      annoyance. */
1065   assuan_transact (entry_ctx, "CONFIRM --one-button", 
1066                    NULL, NULL, NULL, NULL, NULL, NULL);
1067   popup_finished = 1;
1068   return NULL;
1069 }
1070
1071
1072 /* Pop up a message window similar to the confirm one but keep it open
1073    until agent_popup_message_stop has been called.  It is crucial for
1074    the caller to make sure that the stop function gets called as soon
1075    as the message is not anymore required because the message is
1076    system modal and all other attempts to use the pinentry will fail
1077    (after a timeout). */
1078 int 
1079 agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
1080 {
1081   int rc;
1082   char line[ASSUAN_LINELENGTH];
1083   pth_attr_t tattr;
1084
1085   rc = start_pinentry (ctrl);
1086   if (rc)
1087     return rc;
1088
1089   if (desc)
1090     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1091   else
1092     snprintf (line, DIM(line)-1, "RESET");
1093   line[DIM(line)-1] = 0;
1094   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1095   if (rc)
1096     return unlock_pinentry (rc);
1097
1098   if (ok_btn)
1099     {
1100       snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
1101       line[DIM(line)-1] = 0;
1102       rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
1103       if (rc)
1104         return unlock_pinentry (rc);
1105     }
1106
1107   tattr = pth_attr_new();
1108   pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
1109   pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
1110   pth_attr_set (tattr, PTH_ATTR_NAME, "popup-message");
1111
1112   popup_finished = 0;
1113   popup_tid = pth_spawn (tattr, popup_message_thread, NULL);
1114   if (!popup_tid)
1115     {
1116       rc = gpg_error_from_syserror ();
1117       log_error ("error spawning popup message handler: %s\n",
1118                  strerror (errno) );
1119       pth_attr_destroy (tattr);
1120       return unlock_pinentry (rc);
1121     }
1122   pth_attr_destroy (tattr);
1123
1124   return 0;
1125 }
1126
1127 /* Close a popup window. */
1128 void
1129 agent_popup_message_stop (ctrl_t ctrl)
1130 {
1131   int rc;
1132   pid_t pid;
1133
1134   (void)ctrl;
1135
1136   if (!popup_tid || !entry_ctx)
1137     {
1138       log_debug ("agent_popup_message_stop called with no active popup\n");
1139       return; 
1140     }
1141
1142   pid = assuan_get_pid (entry_ctx);
1143   if (pid == (pid_t)(-1))
1144     ; /* No pid available can't send a kill. */
1145   else if (popup_finished)
1146     ; /* Already finished and ready for joining. */
1147 #ifdef HAVE_W32_SYSTEM
1148   /* Older versions of assuan set PID to 0 on Windows to indicate an
1149      invalid value.  */
1150   else if (pid != (pid_t) INVALID_HANDLE_VALUE
1151            && pid != 0)
1152     {
1153       HANDLE process = (HANDLE) pid;
1154       
1155       /* Arbitrary error code.  */
1156       TerminateProcess (process, 1);
1157     }
1158 #else
1159   else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
1160     { /* The daemon already died.  No need to send a kill.  However
1161          because we already waited for the process, we need to tell
1162          assuan that it should not wait again (done by
1163          unlock_pinentry). */
1164       if (rc == pid)
1165         assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
1166     }
1167   else if (pid > 0)
1168     kill (pid, SIGKILL);  /* Need to use SIGKILL due to bad
1169                              interaction of SIGINT with Pth. */
1170 #endif
1171
1172   /* Now wait for the thread to terminate. */
1173   rc = pth_join (popup_tid, NULL);
1174   if (!rc)
1175     log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
1176                strerror (errno));
1177   popup_tid = NULL;
1178   entry_owner = NULL;
1179
1180   /* Now we can close the connection. */
1181   unlock_pinentry (0);
1182 }
1183
1184