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