Switch to deterministic DSA.
[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   const char *s;
600   char *pin;
601   int rc;
602   int percent;
603   char numbuf[20];
604
605   if ((s = has_leading_keyword (line, "QUALITY")))
606     {
607       pin = unescape_passphrase_string (s);
608       if (!pin)
609         rc = gpg_error_from_syserror ();
610       else
611         {
612           percent = estimate_passphrase_quality (pin);
613           if (check_passphrase_constraints (NULL, pin, 1))
614             percent = -percent;
615           snprintf (numbuf, sizeof numbuf, "%d", percent);
616           rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
617           xfree (pin);
618         }
619     }
620   else
621     {
622       log_error ("unsupported inquiry '%s' from pinentry\n", line);
623       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
624     }
625
626   return rc;
627 }
628
629
630 /* Helper for agent_askpin and agent_get_passphrase.  */
631 static int
632 setup_qualitybar (void)
633 {
634   int rc;
635   char line[ASSUAN_LINELENGTH];
636   char *tmpstr, *tmpstr2;
637   const char *tooltip;
638
639   /* TRANSLATORS: This string is displayed by Pinentry as the label
640      for the quality bar.  */
641   tmpstr = try_percent_escape (_("Quality:"), "\t\r\n\f\v");
642   snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:"");
643   line[DIM(line)-1] = 0;
644   xfree (tmpstr);
645   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
646   if (rc == 103 /*(Old assuan error code)*/
647       || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
648     ; /* Ignore Unknown Command from old Pinentry versions.  */
649   else if (rc)
650     return rc;
651
652   tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
653   if (tmpstr2)
654     tooltip = tmpstr2;
655   else
656     {
657       /* TRANSLATORS: This string is a tooltip, shown by pinentry when
658          hovering over the quality bar.  Please use an appropriate
659          string to describe what this is about.  The length of the
660          tooltip is limited to about 900 characters.  If you do not
661          translate this entry, a default english text (see source)
662          will be used. */
663       tooltip =  _("pinentry.qualitybar.tooltip");
664       if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
665         tooltip = ("The quality of the text entered above.\n"
666                    "Please ask your administrator for "
667                    "details about the criteria.");
668     }
669   tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
670   xfree (tmpstr2);
671   snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
672   line[DIM(line)-1] = 0;
673   xfree (tmpstr);
674   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
675   if (rc == 103 /*(Old assuan error code)*/
676           || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
677     ; /* Ignore Unknown Command from old pinentry versions.  */
678   else if (rc)
679     return rc;
680
681   return 0;
682 }
683
684
685 /* Check the button_info line for a close action.  */
686 static gpg_error_t
687 close_button_status_cb (void *opaque, const char *line)
688 {
689   int *flag = opaque;
690   const char *keyword = line;
691   int keywordlen;
692
693   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
694     ;
695   while (spacep (line))
696     line++;
697   if (keywordlen == 11 && !memcmp (keyword, "BUTTON_INFO", keywordlen))
698     {
699       if ( !strcmp (line, "close") )
700         *flag = 1;
701     }
702
703   return 0;
704 }
705
706
707
708 \f
709 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
710    number here and repeat it as long as we have invalid formed
711    numbers. */
712 int
713 agent_askpin (ctrl_t ctrl,
714               const char *desc_text, const char *prompt_text,
715               const char *initial_errtext,
716               struct pin_entry_info_s *pininfo)
717 {
718   int rc;
719   char line[ASSUAN_LINELENGTH];
720   struct entry_parm_s parm;
721   const char *errtext = NULL;
722   int is_pin = 0;
723   int saveflag;
724   int close_button;
725
726   if (opt.batch)
727     return 0; /* fixme: we should return BAD PIN */
728
729   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
730     {
731       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
732         return gpg_error (GPG_ERR_CANCELED);
733       if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
734         {
735           unsigned char *passphrase;
736           size_t size;
737
738           *pininfo->pin = 0; /* Reset the PIN. */
739           rc = pinentry_loopback(ctrl, "PASSPHRASE", &passphrase, &size,
740                   pininfo->max_length);
741           if (rc)
742             return rc;
743
744           memcpy(&pininfo->pin, passphrase, size);
745           xfree(passphrase);
746           pininfo->pin[size] = 0;
747           if (pininfo->check_cb)
748             {
749               /* More checks by utilizing the optional callback. */
750               pininfo->cb_errtext = NULL;
751               rc = pininfo->check_cb (pininfo);
752             }
753           return rc;
754         }
755       return gpg_error(GPG_ERR_NO_PIN_ENTRY);
756     }
757
758   if (!pininfo || pininfo->max_length < 1)
759     return gpg_error (GPG_ERR_INV_VALUE);
760   if (!desc_text && pininfo->min_digits)
761     desc_text = _("Please enter your PIN, so that the secret key "
762                   "can be unlocked for this session");
763   else if (!desc_text)
764     desc_text = _("Please enter your passphrase, so that the secret key "
765                   "can be unlocked for this session");
766
767   if (prompt_text)
768     is_pin = !!strstr (prompt_text, "PIN");
769   else
770     is_pin = desc_text && strstr (desc_text, "PIN");
771
772   rc = start_pinentry (ctrl);
773   if (rc)
774     return rc;
775
776   snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
777   line[DIM(line)-1] = 0;
778   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
779   if (rc)
780     return unlock_pinentry (rc);
781
782   snprintf (line, DIM(line)-1, "SETPROMPT %s",
783             prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:");
784   line[DIM(line)-1] = 0;
785   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
786   if (rc)
787     return unlock_pinentry (rc);
788
789   /* If a passphrase quality indicator has been requested and a
790      minimum passphrase length has not been disabled, send the command
791      to the pinentry.  */
792   if (pininfo->with_qualitybar && opt.min_passphrase_len )
793     {
794       rc = setup_qualitybar ();
795       if (rc)
796         return unlock_pinentry (rc);
797     }
798
799   if (initial_errtext)
800     {
801       snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext);
802       line[DIM(line)-1] = 0;
803       rc = assuan_transact (entry_ctx, line,
804                             NULL, NULL, NULL, NULL, NULL, NULL);
805       if (rc)
806         return unlock_pinentry (rc);
807     }
808
809   for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
810     {
811       memset (&parm, 0, sizeof parm);
812       parm.size = pininfo->max_length;
813       *pininfo->pin = 0; /* Reset the PIN. */
814       parm.buffer = (unsigned char*)pininfo->pin;
815
816       if (errtext)
817         {
818           /* TRANSLATORS: The string is appended to an error message in
819              the pinentry.  The %s is the actual error message, the
820              two %d give the current and maximum number of tries. */
821           snprintf (line, DIM(line)-1, _("SETERROR %s (try %d of %d)"),
822                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
823           line[DIM(line)-1] = 0;
824           rc = assuan_transact (entry_ctx, line,
825                                 NULL, NULL, NULL, NULL, NULL, NULL);
826           if (rc)
827             return unlock_pinentry (rc);
828           errtext = NULL;
829         }
830
831       saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
832       assuan_begin_confidential (entry_ctx);
833       close_button = 0;
834       rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
835                             inq_quality, entry_ctx,
836                             close_button_status_cb, &close_button);
837       assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
838       /* Most pinentries out in the wild return the old Assuan error code
839          for canceled which gets translated to an assuan Cancel error and
840          not to the code for a user cancel.  Fix this here. */
841       if (rc && gpg_err_source (rc)
842           && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
843         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
844
845       /* Change error code in case the window close button was clicked
846          to cancel the operation.  */
847       if (close_button && gpg_err_code (rc) == GPG_ERR_CANCELED)
848         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
849
850       if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
851         errtext = is_pin? _("PIN too long")
852                         : _("Passphrase too long");
853       else if (rc)
854         return unlock_pinentry (rc);
855
856       if (!errtext && pininfo->min_digits)
857         {
858           /* do some basic checks on the entered PIN. */
859           if (!all_digitsp (pininfo->pin))
860             errtext = _("Invalid characters in PIN");
861           else if (pininfo->max_digits
862                    && strlen (pininfo->pin) > pininfo->max_digits)
863             errtext = _("PIN too long");
864           else if (strlen (pininfo->pin) < pininfo->min_digits)
865             errtext = _("PIN too short");
866         }
867
868       if (!errtext && pininfo->check_cb)
869         {
870           /* More checks by utilizing the optional callback. */
871           pininfo->cb_errtext = NULL;
872           rc = pininfo->check_cb (pininfo);
873           if (rc == -1 && pininfo->cb_errtext)
874             errtext = pininfo->cb_errtext;
875           else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
876                    || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
877             errtext = (is_pin? _("Bad PIN")
878                        : _("Bad Passphrase"));
879           else if (rc)
880             return unlock_pinentry (rc);
881         }
882
883       if (!errtext)
884         return unlock_pinentry (0); /* okay, got a PIN or passphrase */
885     }
886
887   return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
888                           : GPG_ERR_BAD_PASSPHRASE));
889 }
890
891
892 \f
893 /* Ask for the passphrase using the supplied arguments.  The returned
894    passphrase needs to be freed by the caller. */
895 int
896 agent_get_passphrase (ctrl_t ctrl,
897                       char **retpass, const char *desc, const char *prompt,
898                       const char *errtext, int with_qualitybar)
899 {
900
901   int rc;
902   char line[ASSUAN_LINELENGTH];
903   struct entry_parm_s parm;
904   int saveflag;
905   int close_button;
906
907   *retpass = NULL;
908   if (opt.batch)
909     return gpg_error (GPG_ERR_BAD_PASSPHRASE);
910
911   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
912     {
913       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
914         return gpg_error (GPG_ERR_CANCELED);
915
916       if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
917         {
918           size_t size;
919           size_t len = ASSUAN_LINELENGTH/2;
920           unsigned char *buffer = gcry_malloc_secure (len);
921
922           rc = pinentry_loopback(ctrl, "PASSPHRASE", &buffer, &size, len);
923           if (rc)
924             xfree(buffer);
925           else
926             {
927               buffer[size] = 0;
928               *retpass = buffer;
929             }
930           return rc;
931         }
932       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
933     }
934
935   rc = start_pinentry (ctrl);
936   if (rc)
937     return rc;
938
939   if (!prompt)
940     prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");
941
942
943   if (desc)
944     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
945   else
946     snprintf (line, DIM(line)-1, "RESET");
947   line[DIM(line)-1] = 0;
948   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
949   if (rc)
950     return unlock_pinentry (rc);
951
952   snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
953   line[DIM(line)-1] = 0;
954   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
955   if (rc)
956     return unlock_pinentry (rc);
957
958   if (with_qualitybar && opt.min_passphrase_len)
959     {
960       rc = setup_qualitybar ();
961       if (rc)
962         return unlock_pinentry (rc);
963     }
964
965   if (errtext)
966     {
967       snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
968       line[DIM(line)-1] = 0;
969       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
970       if (rc)
971         return unlock_pinentry (rc);
972     }
973
974   memset (&parm, 0, sizeof parm);
975   parm.size = ASSUAN_LINELENGTH/2 - 5;
976   parm.buffer = gcry_malloc_secure (parm.size+10);
977   if (!parm.buffer)
978     return unlock_pinentry (out_of_core ());
979
980   saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
981   assuan_begin_confidential (entry_ctx);
982   close_button = 0;
983   rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
984                         inq_quality, entry_ctx,
985                         close_button_status_cb, &close_button);
986   assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
987   /* Most pinentries out in the wild return the old Assuan error code
988      for canceled which gets translated to an assuan Cancel error and
989      not to the code for a user cancel.  Fix this here. */
990   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
991     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
992   /* Change error code in case the window close button was clicked
993      to cancel the operation.  */
994   if (close_button && gpg_err_code (rc) == GPG_ERR_CANCELED)
995     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
996
997   if (rc)
998     xfree (parm.buffer);
999   else
1000     *retpass = parm.buffer;
1001   return unlock_pinentry (rc);
1002 }
1003
1004
1005 \f
1006 /* Pop up the PIN-entry, display the text and the prompt and ask the
1007    user to confirm this.  We return 0 for success, ie. the user
1008    confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
1009    other error.  If WITH_CANCEL it true an extra cancel button is
1010    displayed to allow the user to easily return a GPG_ERR_CANCELED.
1011    if the Pinentry does not support this, the user can still cancel by
1012    closing the Pinentry window.  */
1013 int
1014 agent_get_confirmation (ctrl_t ctrl,
1015                         const char *desc, const char *ok,
1016                         const char *notok, int with_cancel)
1017 {
1018   int rc;
1019   char line[ASSUAN_LINELENGTH];
1020
1021   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1022     {
1023       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1024         return gpg_error (GPG_ERR_CANCELED);
1025
1026       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1027     }
1028
1029   rc = start_pinentry (ctrl);
1030   if (rc)
1031     return rc;
1032
1033   if (desc)
1034     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1035   else
1036     snprintf (line, DIM(line)-1, "RESET");
1037   line[DIM(line)-1] = 0;
1038   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1039   /* Most pinentries out in the wild return the old Assuan error code
1040      for canceled which gets translated to an assuan Cancel error and
1041      not to the code for a user cancel.  Fix this here. */
1042   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1043     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1044
1045   if (rc)
1046     return unlock_pinentry (rc);
1047
1048   if (ok)
1049     {
1050       snprintf (line, DIM(line)-1, "SETOK %s", ok);
1051       line[DIM(line)-1] = 0;
1052       rc = assuan_transact (entry_ctx,
1053                             line, NULL, NULL, NULL, NULL, NULL, NULL);
1054       if (rc)
1055         return unlock_pinentry (rc);
1056     }
1057   if (notok)
1058     {
1059       /* Try to use the newer NOTOK feature if a cancel button is
1060          requested.  If no cancel button is requested we keep on using
1061          the standard cancel.  */
1062       if (with_cancel)
1063         {
1064           snprintf (line, DIM(line)-1, "SETNOTOK %s", notok);
1065           line[DIM(line)-1] = 0;
1066           rc = assuan_transact (entry_ctx,
1067                                 line, NULL, NULL, NULL, NULL, NULL, NULL);
1068         }
1069       else
1070         rc = GPG_ERR_ASS_UNKNOWN_CMD;
1071
1072       if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1073         {
1074           snprintf (line, DIM(line)-1, "SETCANCEL %s", notok);
1075           line[DIM(line)-1] = 0;
1076           rc = assuan_transact (entry_ctx, line,
1077                                 NULL, NULL, NULL, NULL, NULL, NULL);
1078         }
1079       if (rc)
1080         return unlock_pinentry (rc);
1081     }
1082
1083   rc = assuan_transact (entry_ctx, "CONFIRM",
1084                         NULL, NULL, NULL, NULL, NULL, NULL);
1085   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1086     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1087
1088   return unlock_pinentry (rc);
1089 }
1090
1091
1092 \f
1093 /* Pop up the PINentry, display the text DESC and a button with the
1094    text OK_BTN (which may be NULL to use the default of "OK") and wait
1095    for the user to hit this button.  The return value is not
1096    relevant.  */
1097 int
1098 agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
1099 {
1100   int rc;
1101   char line[ASSUAN_LINELENGTH];
1102
1103   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1104     return gpg_error (GPG_ERR_CANCELED);
1105
1106   rc = start_pinentry (ctrl);
1107   if (rc)
1108     return rc;
1109
1110   if (desc)
1111     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1112   else
1113     snprintf (line, DIM(line)-1, "RESET");
1114   line[DIM(line)-1] = 0;
1115   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1116   /* Most pinentries out in the wild return the old Assuan error code
1117      for canceled which gets translated to an assuan Cancel error and
1118      not to the code for a user cancel.  Fix this here. */
1119   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1120     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1121
1122   if (rc)
1123     return unlock_pinentry (rc);
1124
1125   if (ok_btn)
1126     {
1127       snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
1128       line[DIM(line)-1] = 0;
1129       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL,
1130                             NULL, NULL, NULL);
1131       if (rc)
1132         return unlock_pinentry (rc);
1133     }
1134
1135   rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL,
1136                         NULL, NULL, NULL);
1137   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1138     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1139
1140   return unlock_pinentry (rc);
1141 }
1142
1143
1144 /* The thread running the popup message. */
1145 static void *
1146 popup_message_thread (void *arg)
1147 {
1148   (void)arg;
1149
1150   /* We use the --one-button hack instead of the MESSAGE command to
1151      allow the use of old Pinentries.  Those old Pinentries will then
1152      show an additional Cancel button but that is mostly a visual
1153      annoyance. */
1154   assuan_transact (entry_ctx, "CONFIRM --one-button",
1155                    NULL, NULL, NULL, NULL, NULL, NULL);
1156   popup_finished = 1;
1157   return NULL;
1158 }
1159
1160
1161 /* Pop up a message window similar to the confirm one but keep it open
1162    until agent_popup_message_stop has been called.  It is crucial for
1163    the caller to make sure that the stop function gets called as soon
1164    as the message is not anymore required because the message is
1165    system modal and all other attempts to use the pinentry will fail
1166    (after a timeout). */
1167 int
1168 agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
1169 {
1170   int rc;
1171   char line[ASSUAN_LINELENGTH];
1172   npth_attr_t tattr;
1173   int err;
1174
1175   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1176     return gpg_error (GPG_ERR_CANCELED);
1177
1178   rc = start_pinentry (ctrl);
1179   if (rc)
1180     return rc;
1181
1182   if (desc)
1183     snprintf (line, DIM(line)-1, "SETDESC %s", desc);
1184   else
1185     snprintf (line, DIM(line)-1, "RESET");
1186   line[DIM(line)-1] = 0;
1187   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1188   if (rc)
1189     return unlock_pinentry (rc);
1190
1191   if (ok_btn)
1192     {
1193       snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
1194       line[DIM(line)-1] = 0;
1195       rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
1196       if (rc)
1197         return unlock_pinentry (rc);
1198     }
1199
1200   err = npth_attr_init (&tattr);
1201   if (err)
1202     return unlock_pinentry (gpg_error_from_errno (err));
1203   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1204
1205   popup_finished = 0;
1206   err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL);
1207   npth_attr_destroy (&tattr);
1208   if (err)
1209     {
1210       rc = gpg_error_from_errno (err);
1211       log_error ("error spawning popup message handler: %s\n",
1212                  strerror (err) );
1213       return unlock_pinentry (rc);
1214     }
1215   npth_setname_np (popup_tid, "popup-message");
1216
1217   return 0;
1218 }
1219
1220 /* Close a popup window. */
1221 void
1222 agent_popup_message_stop (ctrl_t ctrl)
1223 {
1224   int rc;
1225   pid_t pid;
1226
1227   (void)ctrl;
1228
1229   if (!popup_tid || !entry_ctx)
1230     {
1231       log_debug ("agent_popup_message_stop called with no active popup\n");
1232       return;
1233     }
1234
1235   pid = assuan_get_pid (entry_ctx);
1236   if (pid == (pid_t)(-1))
1237     ; /* No pid available can't send a kill. */
1238   else if (popup_finished)
1239     ; /* Already finished and ready for joining. */
1240 #ifdef HAVE_W32_SYSTEM
1241   /* Older versions of assuan set PID to 0 on Windows to indicate an
1242      invalid value.  */
1243   else if (pid != (pid_t) INVALID_HANDLE_VALUE
1244            && pid != 0)
1245     {
1246       HANDLE process = (HANDLE) pid;
1247
1248       /* Arbitrary error code.  */
1249       TerminateProcess (process, 1);
1250     }
1251 #else
1252   else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
1253     { /* The daemon already died.  No need to send a kill.  However
1254          because we already waited for the process, we need to tell
1255          assuan that it should not wait again (done by
1256          unlock_pinentry). */
1257       if (rc == pid)
1258         assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
1259     }
1260   else if (pid > 0)
1261     kill (pid, SIGINT);
1262 #endif
1263
1264   /* Now wait for the thread to terminate. */
1265   rc = npth_join (popup_tid, NULL);
1266   if (rc)
1267     log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
1268                strerror (rc));
1269   /* Thread IDs are opaque, but we try our best here by resetting it
1270      to the same content that a static global variable has.  */
1271   memset (&popup_tid, '\0', sizeof (popup_tid));
1272   entry_owner = NULL;
1273
1274   /* Now we can close the connection. */
1275   unlock_pinentry (0);
1276 }