ef7600794b87e8b47c65b3a43fc4c9a4984d1221
[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 <https://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 # include <sys/utsname.h>
35 #endif
36 #include <npth.h>
37
38 #include "agent.h"
39 #include <assuan.h>
40 #include "../common/sysutils.h"
41 #include "../common/i18n.h"
42
43 #ifdef _POSIX_OPEN_MAX
44 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
45 #else
46 #define MAX_OPEN_FDS 20
47 #endif
48
49
50 /* Because access to the pinentry must be serialized (it is and shall
51    be a global mutually exclusive dialog) we better timeout pending
52    requests after some time.  1 minute seem to be a reasonable
53    time. */
54 #define LOCK_TIMEOUT  (1*60)
55
56 /* The assuan context of the current pinentry. */
57 static assuan_context_t entry_ctx;
58
59 /* A list of features of the current pinentry.  */
60 static struct
61 {
62   /* The Pinentry support RS+US tabbing.  This means that a RS (0x1e)
63    * starts a new tabbing block in which a US (0x1f) followed by a
64    * colon marks a colon.  A pinentry can use this to pretty print
65    * name value pairs.  */
66   unsigned int tabbing:1;
67 } entry_features;
68
69
70 /* The control variable of the connection owning the current pinentry.
71    This is only valid if ENTRY_CTX is not NULL.  Note, that we care
72    only about the value of the pointer and that it should never be
73    dereferenced.  */
74 static ctrl_t entry_owner;
75
76 /* A mutex used to serialize access to the pinentry. */
77 static npth_mutex_t entry_lock;
78
79 /* The thread ID of the popup working thread. */
80 static npth_t  popup_tid;
81
82 /* A flag used in communication between the popup working thread and
83    its stop function. */
84 static int popup_finished;
85
86
87
88 /* Data to be passed to our callbacks, */
89 struct entry_parm_s
90 {
91   int lines;
92   size_t size;
93   unsigned char *buffer;
94 };
95
96
97
98 \f
99 /* This function must be called once to initialize this module.  This
100    has to be done before a second thread is spawned.  We can't do the
101    static initialization because Pth emulation code might not be able
102    to do a static init; in particular, it is not possible for W32. */
103 void
104 initialize_module_call_pinentry (void)
105 {
106   static int initialized;
107
108   if (!initialized)
109     {
110       if (npth_mutex_init (&entry_lock, NULL))
111         initialized = 1;
112     }
113 }
114
115
116
117 /* This function may be called to print information pertaining to the
118    current state of this module to the log. */
119 void
120 agent_query_dump_state (void)
121 {
122   log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
123             entry_ctx, (long)assuan_get_pid (entry_ctx), (void*)popup_tid);
124 }
125
126 /* Called to make sure that a popup window owned by the current
127    connection gets closed. */
128 void
129 agent_reset_query (ctrl_t ctrl)
130 {
131   if (entry_ctx && popup_tid && entry_owner == ctrl)
132     {
133       agent_popup_message_stop (ctrl);
134     }
135 }
136
137
138 /* Unlock the pinentry so that another thread can start one and
139    disconnect that pinentry - we do this after the unlock so that a
140    stalled pinentry does not block other threads.  Fixme: We should
141    have a timeout in Assuan for the disconnect operation. */
142 static gpg_error_t
143 unlock_pinentry (gpg_error_t rc)
144 {
145   assuan_context_t ctx = entry_ctx;
146   int err;
147
148   if (rc)
149     {
150       if (DBG_IPC)
151         log_debug ("error calling pinentry: %s <%s>\n",
152                    gpg_strerror (rc), gpg_strsource (rc));
153
154       /* Change the source of the error to pinentry so that the final
155          consumer of the error code knows that the problem is with
156          pinentry.  For backward compatibility we do not do that for
157          some common error codes.  */
158       switch (gpg_err_code (rc))
159         {
160         case GPG_ERR_NO_PIN_ENTRY:
161         case GPG_ERR_CANCELED:
162         case GPG_ERR_FULLY_CANCELED:
163         case GPG_ERR_ASS_UNKNOWN_INQUIRE:
164         case GPG_ERR_ASS_TOO_MUCH_DATA:
165         case GPG_ERR_NO_PASSPHRASE:
166         case GPG_ERR_BAD_PASSPHRASE:
167         case GPG_ERR_BAD_PIN:
168           break;
169
170         case GPG_ERR_CORRUPTED_PROTECTION:
171           /* This comes from gpg-agent.  */
172           break;
173
174         default:
175           rc = gpg_err_make (GPG_ERR_SOURCE_PINENTRY, gpg_err_code (rc));
176           break;
177         }
178     }
179
180   if (--entry_owner->pinentry_level == 0)
181     {
182       entry_owner = NULL;
183       entry_ctx = NULL;
184       err = npth_mutex_unlock (&entry_lock);
185       if (err)
186         {
187           log_error ("failed to release the entry lock: %s\n", strerror (err));
188           if (!rc)
189             rc = gpg_error_from_errno (err);
190         }
191       assuan_release (ctx);
192     }
193   return rc;
194 }
195
196
197 /* To make sure we leave no secrets in our image after forking of the
198    pinentry, we use this callback. */
199 static void
200 atfork_cb (void *opaque, int where)
201 {
202   ctrl_t ctrl = opaque;
203
204   if (!where)
205     {
206       int iterator = 0;
207       const char *name, *assname, *value;
208
209       gcry_control (GCRYCTL_TERM_SECMEM);
210
211       while ((name = session_env_list_stdenvnames (&iterator, &assname)))
212         {
213           /* For all new envvars (!ASSNAME) and the two medium old
214              ones which do have an assuan name but are conveyed using
215              environment variables, update the environment of the
216              forked process.  */
217           if (!assname
218               || !strcmp (name, "XAUTHORITY")
219               || !strcmp (name, "PINENTRY_USER_DATA"))
220             {
221               value = session_env_getenv (ctrl->session_env, name);
222               if (value)
223                 gnupg_setenv (name, value, 1);
224             }
225         }
226     }
227 }
228
229
230 /* Status line callback for the FEATURES status.  */
231 static gpg_error_t
232 getinfo_features_cb (void *opaque, const char *line)
233 {
234   const char *args;
235   char **tokens;
236   int i;
237
238   (void)opaque;
239
240   if ((args = has_leading_keyword (line, "FEATURES")))
241     {
242       tokens = strtokenize (args, " ");
243       if (!tokens)
244         return gpg_error_from_syserror ();
245       for (i=0; tokens[i]; i++)
246         if (!strcmp (tokens[i], "tabbing"))
247           entry_features.tabbing = 1;
248       xfree (tokens);
249     }
250
251   return 0;
252 }
253
254
255 static gpg_error_t
256 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
257 {
258   unsigned long *pid = opaque;
259   char pidbuf[50];
260
261   /* There is only the pid in the server's response.  */
262   if (length >= sizeof pidbuf)
263     length = sizeof pidbuf -1;
264   if (length)
265     {
266       strncpy (pidbuf, buffer, length);
267       pidbuf[length] = 0;
268       *pid = strtoul (pidbuf, NULL, 10);
269     }
270   return 0;
271 }
272
273
274 /* Fork off the pin entry if this has not already been done.  Note,
275    that this function must always be used to acquire the lock for the
276    pinentry - we will serialize _all_ pinentry calls.
277  */
278 static gpg_error_t
279 start_pinentry (ctrl_t ctrl)
280 {
281   int rc = 0;
282   const char *full_pgmname;
283   const char *pgmname;
284   assuan_context_t ctx;
285   const char *argv[5];
286   assuan_fd_t no_close_list[3];
287   int i;
288   const char *tmpstr;
289   unsigned long pinentry_pid;
290   const char *value;
291   struct timespec abstime;
292   char *flavor_version;
293   int err;
294
295   if (entry_owner == ctrl)
296     {
297       /* Allow recursive use of pinentry.  */
298       ctrl->pinentry_level++;
299       return 0;
300     }
301
302   npth_clock_gettime (&abstime);
303   abstime.tv_sec += LOCK_TIMEOUT;
304   err = npth_mutex_timedlock (&entry_lock, &abstime);
305   if (err)
306     {
307       if (err == ETIMEDOUT)
308         rc = gpg_error (GPG_ERR_TIMEOUT);
309       else
310         rc = gpg_error_from_errno (rc);
311       log_error (_("failed to acquire the pinentry lock: %s\n"),
312                  gpg_strerror (rc));
313       return rc;
314     }
315
316   entry_owner = ctrl;
317
318   if (entry_ctx)
319     return 0;
320
321   if (opt.verbose)
322     log_info ("starting a new PIN Entry\n");
323
324 #ifdef HAVE_W32_SYSTEM
325   fflush (stdout);
326   fflush (stderr);
327 #endif
328   if (fflush (NULL))
329     {
330 #ifndef HAVE_W32_SYSTEM
331       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
332 #endif
333       log_error ("error flushing pending output: %s\n", strerror (errno));
334       /* At least Windows XP fails here with EBADF.  According to docs
335          and Wine an fflush(NULL) is the same as _flushall.  However
336          the Wine implementation does not flush stdin,stdout and stderr
337          - see above.  Let's try to ignore the error. */
338 #ifndef HAVE_W32_SYSTEM
339       return unlock_pinentry (tmperr);
340 #endif
341     }
342
343   full_pgmname = opt.pinentry_program;
344   if (!full_pgmname || !*full_pgmname)
345     full_pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY);
346   if ( !(pgmname = strrchr (full_pgmname, '/')))
347     pgmname = full_pgmname;
348   else
349     pgmname++;
350
351   /* OS X needs the entire file name in argv[0], so that it can locate
352      the resource bundle.  For other systems we stick to the usual
353      convention of supplying only the name of the program.  */
354 #ifdef __APPLE__
355   argv[0] = full_pgmname;
356 #else /*!__APPLE__*/
357   argv[0] = pgmname;
358 #endif /*__APPLE__*/
359
360   if (!opt.keep_display
361       && (value = session_env_getenv (ctrl->session_env, "DISPLAY")))
362     {
363       argv[1] = "--display";
364       argv[2] = value;
365       argv[3] = NULL;
366     }
367   else
368     argv[1] = NULL;
369
370   i=0;
371   if (!opt.running_detached)
372     {
373       if (log_get_fd () != -1)
374         no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
375       no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
376     }
377   no_close_list[i] = ASSUAN_INVALID_FD;
378
379   rc = assuan_new (&ctx);
380   if (rc)
381     {
382       log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
383       return rc;
384     }
385
386   ctrl->pinentry_level = 1;
387   entry_ctx = ctx;
388
389   /* We don't want to log the pinentry communication to make the logs
390      easier to read.  We might want to add a new debug option to enable
391      pinentry logging.  */
392 #ifdef ASSUAN_NO_LOGGING
393   assuan_set_flag (ctx, ASSUAN_NO_LOGGING, !opt.debug_pinentry);
394 #endif
395
396   /* Connect to the pinentry and perform initial handshaking.  Note
397      that atfork is used to change the environment for pinentry.  We
398      start the server in detached mode to suppress the console window
399      under Windows.  */
400   rc = assuan_pipe_connect (entry_ctx, full_pgmname, argv,
401                             no_close_list, atfork_cb, ctrl,
402                             ASSUAN_PIPE_CONNECT_DETACHED);
403   if (rc)
404     {
405       log_error ("can't connect to the PIN entry module '%s': %s\n",
406                  full_pgmname, gpg_strerror (rc));
407       return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY));
408     }
409
410   if (DBG_IPC)
411     log_debug ("connection to PIN entry established\n");
412
413   value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA");
414   if (value != NULL)
415     {
416       char *optstr;
417       if (asprintf (&optstr, "OPTION pinentry-user-data=%s", value) < 0 )
418         return unlock_pinentry (out_of_core ());
419       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
420                             NULL);
421       xfree (optstr);
422       if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
423         return unlock_pinentry (rc);
424     }
425
426   rc = assuan_transact (entry_ctx,
427                         opt.no_grab? "OPTION no-grab":"OPTION grab",
428                         NULL, NULL, NULL, NULL, NULL, NULL);
429   if (rc)
430     return unlock_pinentry (rc);
431
432   value = session_env_getenv (ctrl->session_env, "GPG_TTY");
433   if (value)
434     {
435       char *optstr;
436       if (asprintf (&optstr, "OPTION ttyname=%s", value) < 0 )
437         return unlock_pinentry (out_of_core ());
438       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
439                             NULL);
440       xfree (optstr);
441       if (rc)
442         return unlock_pinentry (rc);
443     }
444   value = session_env_getenv (ctrl->session_env, "TERM");
445   if (value)
446     {
447       char *optstr;
448       if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 )
449         return unlock_pinentry (out_of_core ());
450       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
451                             NULL);
452       xfree (optstr);
453       if (rc)
454         return unlock_pinentry (rc);
455     }
456   if (ctrl->lc_ctype)
457     {
458       char *optstr;
459       if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 )
460         return unlock_pinentry (out_of_core ());
461       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
462                             NULL);
463       xfree (optstr);
464       if (rc)
465         return unlock_pinentry (rc);
466     }
467   if (ctrl->lc_messages)
468     {
469       char *optstr;
470       if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 )
471         return unlock_pinentry (out_of_core ());
472       rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
473                             NULL);
474       xfree (optstr);
475       if (rc)
476         return unlock_pinentry (rc);
477     }
478
479
480   if (opt.allow_external_cache)
481     {
482       /* Indicate to the pinentry that it may read from an external cache.
483
484          It is essential that the pinentry respect this.  If the
485          cached password is not up to date and retry == 1, then, using
486          a version of GPG Agent that doesn't support this, won't issue
487          another pin request and the user won't get a chance to
488          correct the password.  */
489       rc = assuan_transact (entry_ctx, "OPTION allow-external-password-cache",
490                             NULL, NULL, NULL, NULL, NULL, NULL);
491       if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
492         return unlock_pinentry (rc);
493     }
494
495   if (opt.allow_emacs_pinentry)
496     {
497       /* Indicate to the pinentry that it may read passphrase through
498          Emacs minibuffer, if possible.  */
499       rc = assuan_transact (entry_ctx, "OPTION allow-emacs-prompt",
500                             NULL, NULL, NULL, NULL, NULL, NULL);
501       if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
502         return unlock_pinentry (rc);
503     }
504
505
506   {
507     /* Provide a few default strings for use by the pinentries.  This
508        may help a pinentry to avoid implementing localization code.  */
509     static const struct { const char *key, *value; int what; } tbl[] = {
510       /* TRANSLATORS: These are labels for buttons etc used in
511          Pinentries.  An underscore indicates that the next letter
512          should be used as an accelerator.  Double the underscore for
513          a literal one.  The actual to be translated text starts after
514          the second vertical bar.  Note that gpg-agent has been set to
515          utf-8 so that the strings are in the expected encoding.  */
516       { "ok",     N_("|pinentry-label|_OK") },
517       { "cancel", N_("|pinentry-label|_Cancel") },
518       { "yes",    N_("|pinentry-label|_Yes") },
519       { "no",     N_("|pinentry-label|_No") },
520       { "prompt", N_("|pinentry-label|PIN:") },
521       { "pwmngr", N_("|pinentry-label|_Save in password manager"), 1 },
522       { "cf-visi",N_("Do you really want to make your "
523                      "passphrase visible on the screen?") },
524       { "tt-visi",N_("|pinentry-tt|Make passphrase visible") },
525       { "tt-hide",N_("|pinentry-tt|Hide passphrase") },
526       { NULL, NULL}
527     };
528     char *optstr;
529     int idx;
530     const char *s, *s2;
531
532     for (idx=0; tbl[idx].key; idx++)
533       {
534         if (!opt.allow_external_cache && tbl[idx].what == 1)
535           continue;  /* No need for it.  */
536         s = L_(tbl[idx].value);
537         if (*s == '|' && (s2=strchr (s+1,'|')))
538           s = s2+1;
539         if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 )
540           return unlock_pinentry (out_of_core ());
541         assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
542                          NULL);
543         xfree (optstr);
544       }
545   }
546
547   /* Tell the pinentry that we would prefer that the given character
548      is used as the invisible character by the entry widget.  */
549   if (opt.pinentry_invisible_char)
550     {
551       char *optstr;
552       if ((optstr = xtryasprintf ("OPTION invisible-char=%s",
553                                   opt.pinentry_invisible_char)))
554         {
555           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
556                            NULL);
557           /* We ignore errors because this is just a fancy thing and
558              older pinentries do not support this feature.  */
559           xfree (optstr);
560         }
561     }
562
563   if (opt.pinentry_timeout)
564     {
565       char *optstr;
566       if ((optstr = xtryasprintf ("SETTIMEOUT %lu", opt.pinentry_timeout)))
567         {
568           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
569                            NULL);
570           /* We ignore errors because this is just a fancy thing.  */
571           xfree (optstr);
572         }
573     }
574
575   /* Tell the pinentry the name of a file it shall touch after having
576      messed with the tty.  This is optional and only supported by
577      newer pinentries and thus we do no error checking. */
578   tmpstr = opt.pinentry_touch_file;
579   if (tmpstr && !strcmp (tmpstr, "/dev/null"))
580     tmpstr = NULL;
581   else if (!tmpstr)
582     tmpstr = get_agent_socket_name ();
583   if (tmpstr)
584     {
585       char *optstr;
586
587       if (asprintf (&optstr, "OPTION touch-file=%s", tmpstr ) < 0 )
588         ;
589       else
590         {
591           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
592                            NULL);
593           xfree (optstr);
594         }
595     }
596
597   /* Tell Pinentry about our client.  */
598   if (ctrl->client_pid)
599     {
600       char *optstr;
601       const char *nodename = "";
602
603 #ifndef HAVE_W32_SYSTEM
604       struct utsname utsbuf;
605       if (!uname (&utsbuf))
606         nodename = utsbuf.nodename;
607 #endif /*!HAVE_W32_SYSTEM*/
608
609       if ((optstr = xtryasprintf ("OPTION owner=%lu/%d %s",
610                                   ctrl->client_pid, ctrl->client_uid,
611                                   nodename)))
612         {
613           assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
614                            NULL);
615           /* We ignore errors because this is just a fancy thing and
616              older pinentries do not support this feature.  */
617           xfree (optstr);
618         }
619     }
620
621
622   /* Ask the pinentry for its version and flavor and store that as a
623    * string in MB.  This information is useful for helping users to
624    * figure out Pinentry problems.  Noet that "flavor" may also return
625    * a status line with the features; we use a dedicated handler for
626    * that.  */
627   {
628     membuf_t mb;
629
630     init_membuf (&mb, 256);
631     if (assuan_transact (entry_ctx, "GETINFO flavor",
632                          put_membuf_cb, &mb,
633                          NULL, NULL,
634                          getinfo_features_cb, NULL))
635       put_membuf_str (&mb, "unknown");
636     put_membuf_str (&mb, " ");
637     if (assuan_transact (entry_ctx, "GETINFO version",
638                          put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
639       put_membuf_str (&mb, "unknown");
640     put_membuf_str (&mb, " ");
641     if (assuan_transact (entry_ctx, "GETINFO ttyinfo",
642                          put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
643       put_membuf_str (&mb, "? ? ?");
644     put_membuf (&mb, "", 1);
645     flavor_version = get_membuf (&mb, NULL);
646   }
647
648
649   /* Now ask the Pinentry for its PID.  If the Pinentry is new enough
650      it will send the pid back and we will use an inquire to notify
651      our client.  The client may answer the inquiry either with END or
652      with CAN to cancel the pinentry. */
653   rc = assuan_transact (entry_ctx, "GETINFO pid",
654                         getinfo_pid_cb, &pinentry_pid,
655                         NULL, NULL, NULL, NULL);
656   if (rc)
657     {
658       log_info ("You may want to update to a newer pinentry\n");
659       rc = 0;
660     }
661   else if (!rc && (pid_t)pinentry_pid == (pid_t)(-1))
662     log_error ("pinentry did not return a PID\n");
663   else
664     {
665       rc = agent_inq_pinentry_launched (ctrl, pinentry_pid, flavor_version);
666       if (gpg_err_code (rc) == GPG_ERR_CANCELED
667           || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
668         return unlock_pinentry (gpg_err_make (GPG_ERR_SOURCE_DEFAULT,
669                                               gpg_err_code (rc)));
670       rc = 0;
671     }
672
673   xfree (flavor_version);
674
675   return rc;
676 }
677
678
679 /* Returns True if the pinentry is currently active. If WAITSECONDS is
680    greater than zero the function will wait for this many seconds
681    before returning.  */
682 int
683 pinentry_active_p (ctrl_t ctrl, int waitseconds)
684 {
685   int err;
686   (void)ctrl;
687
688   if (waitseconds > 0)
689     {
690       struct timespec abstime;
691       int rc;
692
693       npth_clock_gettime (&abstime);
694       abstime.tv_sec += waitseconds;
695       err = npth_mutex_timedlock (&entry_lock, &abstime);
696       if (err)
697         {
698           if (err == ETIMEDOUT)
699             rc = gpg_error (GPG_ERR_TIMEOUT);
700           else
701             rc = gpg_error (GPG_ERR_INTERNAL);
702           return rc;
703         }
704     }
705   else
706     {
707       err = npth_mutex_trylock (&entry_lock);
708       if (err)
709         return gpg_error (GPG_ERR_LOCKED);
710     }
711
712   err = npth_mutex_unlock (&entry_lock);
713   if (err)
714     log_error ("failed to release the entry lock at %d: %s\n", __LINE__,
715                strerror (errno));
716   return 0;
717 }
718
719
720 static gpg_error_t
721 getpin_cb (void *opaque, const void *buffer, size_t length)
722 {
723   struct entry_parm_s *parm = opaque;
724
725   if (!buffer)
726     return 0;
727
728   /* we expect the pin to fit on one line */
729   if (parm->lines || length >= parm->size)
730     return gpg_error (GPG_ERR_ASS_TOO_MUCH_DATA);
731
732   /* fixme: we should make sure that the assuan buffer is allocated in
733      secure memory or read the response byte by byte */
734   memcpy (parm->buffer, buffer, length);
735   parm->buffer[length] = 0;
736   parm->lines++;
737   return 0;
738 }
739
740
741 static int
742 all_digitsp( const char *s)
743 {
744   for (; *s && *s >= '0' && *s <= '9'; s++)
745     ;
746   return !*s;
747 }
748
749
750 /* Return a new malloced string by unescaping the string S.  Escaping
751    is percent escaping and '+'/space mapping.  A binary Nul will
752    silently be replaced by a 0xFF.  Function returns NULL to indicate
753    an out of memory status.  Parsing stops at the end of the string or
754    a white space character. */
755 static char *
756 unescape_passphrase_string (const unsigned char *s)
757 {
758   char *buffer, *d;
759
760   buffer = d = xtrymalloc_secure (strlen ((const char*)s)+1);
761   if (!buffer)
762     return NULL;
763   while (*s && !spacep (s))
764     {
765       if (*s == '%' && s[1] && s[2])
766         {
767           s++;
768           *d = xtoi_2 (s);
769           if (!*d)
770             *d = '\xff';
771           d++;
772           s += 2;
773         }
774       else if (*s == '+')
775         {
776           *d++ = ' ';
777           s++;
778         }
779       else
780         *d++ = *s++;
781     }
782   *d = 0;
783   return buffer;
784 }
785
786
787 /* Estimate the quality of the passphrase PW and return a value in the
788    range 0..100.  */
789 static int
790 estimate_passphrase_quality (const char *pw)
791 {
792   int goodlength = opt.min_passphrase_len + opt.min_passphrase_len/3;
793   int length;
794   const char *s;
795
796   if (goodlength < 1)
797     return 0;
798
799   for (length = 0, s = pw; *s; s++)
800     if (!spacep (s))
801       length ++;
802
803   if (length > goodlength)
804     return 100;
805   return ((length*10) / goodlength)*10;
806 }
807
808
809 /* Handle the QUALITY inquiry. */
810 static gpg_error_t
811 inq_quality (void *opaque, const char *line)
812 {
813   assuan_context_t ctx = opaque;
814   const char *s;
815   char *pin;
816   int rc;
817   int percent;
818   char numbuf[20];
819
820   if ((s = has_leading_keyword (line, "QUALITY")))
821     {
822       pin = unescape_passphrase_string (s);
823       if (!pin)
824         rc = gpg_error_from_syserror ();
825       else
826         {
827           percent = estimate_passphrase_quality (pin);
828           if (check_passphrase_constraints (NULL, pin, NULL))
829             percent = -percent;
830           snprintf (numbuf, sizeof numbuf, "%d", percent);
831           rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
832           xfree (pin);
833         }
834     }
835   else
836     {
837       log_error ("unsupported inquiry '%s' from pinentry\n", line);
838       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
839     }
840
841   return rc;
842 }
843
844
845 /* Helper for agent_askpin and agent_get_passphrase.  */
846 static gpg_error_t
847 setup_qualitybar (ctrl_t ctrl)
848 {
849   int rc;
850   char line[ASSUAN_LINELENGTH];
851   char *tmpstr, *tmpstr2;
852   const char *tooltip;
853
854   (void)ctrl;
855
856   /* TRANSLATORS: This string is displayed by Pinentry as the label
857      for the quality bar.  */
858   tmpstr = try_percent_escape (L_("Quality:"), "\t\r\n\f\v");
859   snprintf (line, DIM(line), "SETQUALITYBAR %s", tmpstr? tmpstr:"");
860   xfree (tmpstr);
861   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
862   if (rc == 103 /*(Old assuan error code)*/
863       || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
864     ; /* Ignore Unknown Command from old Pinentry versions.  */
865   else if (rc)
866     return rc;
867
868   tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
869   if (tmpstr2)
870     tooltip = tmpstr2;
871   else
872     {
873       /* TRANSLATORS: This string is a tooltip, shown by pinentry when
874          hovering over the quality bar.  Please use an appropriate
875          string to describe what this is about.  The length of the
876          tooltip is limited to about 900 characters.  If you do not
877          translate this entry, a default english text (see source)
878          will be used. */
879       tooltip =  L_("pinentry.qualitybar.tooltip");
880       if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
881         tooltip = ("The quality of the text entered above.\n"
882                    "Please ask your administrator for "
883                    "details about the criteria.");
884     }
885   tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
886   xfree (tmpstr2);
887   snprintf (line, DIM(line), "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
888   xfree (tmpstr);
889   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
890   if (rc == 103 /*(Old assuan error code)*/
891           || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
892     ; /* Ignore Unknown Command from old pinentry versions.  */
893   else if (rc)
894     return rc;
895
896   return 0;
897 }
898
899 enum
900   {
901     PINENTRY_STATUS_CLOSE_BUTTON = 1 << 0,
902     PINENTRY_STATUS_PIN_REPEATED = 1 << 8,
903     PINENTRY_STATUS_PASSWORD_FROM_CACHE = 1 << 9
904   };
905
906 /* Check the button_info line for a close action.  Also check for the
907    PIN_REPEATED flag.  */
908 static gpg_error_t
909 pinentry_status_cb (void *opaque, const char *line)
910 {
911   unsigned int *flag = opaque;
912   const char *args;
913
914   if ((args = has_leading_keyword (line, "BUTTON_INFO")))
915     {
916       if (!strcmp (args, "close"))
917         *flag |= PINENTRY_STATUS_CLOSE_BUTTON;
918     }
919   else if (has_leading_keyword (line, "PIN_REPEATED"))
920     {
921       *flag |= PINENTRY_STATUS_PIN_REPEATED;
922     }
923   else if (has_leading_keyword (line, "PASSWORD_FROM_CACHE"))
924     {
925       *flag |= PINENTRY_STATUS_PASSWORD_FROM_CACHE;
926     }
927
928   return 0;
929 }
930
931
932 /* Build a SETDESC command line.  This is a dedicated function so that
933  * it can remove control characters which are not supported by the
934  * current Pinentry.  */
935 static void
936 build_cmd_setdesc (char *line, size_t linelen, const char *desc)
937 {
938   char *src, *dst;
939
940   snprintf (line, linelen, "SETDESC %s", desc);
941   if (!entry_features.tabbing)
942     {
943       /* Remove RS and US.  */
944       for (src=dst=line; *src; src++)
945         if (!strchr ("\x1e\x1f", *src))
946           *dst++ = *src;
947       *dst = 0;
948     }
949 }
950
951
952 \f
953 /* Call the Entry and ask for the PIN.  We do check for a valid PIN
954    number here and repeat it as long as we have invalid formed
955    numbers.  KEYINFO and CACHE_MODE are used to tell pinentry something
956    about the key. */
957 gpg_error_t
958 agent_askpin (ctrl_t ctrl,
959               const char *desc_text, const char *prompt_text,
960               const char *initial_errtext,
961               struct pin_entry_info_s *pininfo,
962               const char *keyinfo, cache_mode_t cache_mode)
963 {
964   gpg_error_t rc;
965   char line[ASSUAN_LINELENGTH];
966   struct entry_parm_s parm;
967   const char *errtext = NULL;
968   int is_pin = 0;
969   int saveflag;
970   unsigned int pinentry_status;
971
972   if (opt.batch)
973     return 0; /* fixme: we should return BAD PIN */
974
975   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
976     {
977       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
978         return gpg_error (GPG_ERR_CANCELED);
979       if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
980         {
981           unsigned char *passphrase;
982           size_t size;
983
984           *pininfo->pin = 0; /* Reset the PIN. */
985           rc = pinentry_loopback (ctrl, "PASSPHRASE", &passphrase, &size,
986                                   pininfo->max_length - 1);
987           if (rc)
988             return rc;
989
990           memcpy(&pininfo->pin, passphrase, size);
991           xfree(passphrase);
992           pininfo->pin[size] = 0;
993           if (pininfo->check_cb)
994             {
995               /* More checks by utilizing the optional callback. */
996               pininfo->cb_errtext = NULL;
997               rc = pininfo->check_cb (pininfo);
998             }
999           return rc;
1000         }
1001       return gpg_error(GPG_ERR_NO_PIN_ENTRY);
1002     }
1003
1004   if (!pininfo || pininfo->max_length < 1)
1005     return gpg_error (GPG_ERR_INV_VALUE);
1006   if (!desc_text && pininfo->min_digits)
1007     desc_text = L_("Please enter your PIN, so that the secret key "
1008                    "can be unlocked for this session");
1009   else if (!desc_text)
1010     desc_text = L_("Please enter your passphrase, so that the secret key "
1011                    "can be unlocked for this session");
1012
1013   if (prompt_text)
1014     is_pin = !!strstr (prompt_text, "PIN");
1015   else
1016     is_pin = desc_text && strstr (desc_text, "PIN");
1017
1018   rc = start_pinentry (ctrl);
1019   if (rc)
1020     return rc;
1021
1022   /* If we have a KEYINFO string and are normal, user, or ssh cache
1023      mode, we tell that the Pinentry so it may use it for own caching
1024      purposes.  Most pinentries won't have this implemented and thus
1025      we do not error out in this case.  */
1026   if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1027                   || cache_mode == CACHE_MODE_USER
1028                   || cache_mode == CACHE_MODE_SSH))
1029     snprintf (line, DIM(line), "SETKEYINFO %c/%s",
1030               cache_mode == CACHE_MODE_USER? 'u' :
1031               cache_mode == CACHE_MODE_SSH? 's' : 'n',
1032               keyinfo);
1033   else
1034     snprintf (line, DIM(line), "SETKEYINFO --clear");
1035
1036   rc = assuan_transact (entry_ctx, line,
1037                         NULL, NULL, NULL, NULL, NULL, NULL);
1038   if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1039     return unlock_pinentry (rc);
1040
1041   build_cmd_setdesc (line, DIM(line), desc_text);
1042   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1043   if (rc)
1044     return unlock_pinentry (rc);
1045
1046   snprintf (line, DIM(line), "SETPROMPT %s",
1047             prompt_text? prompt_text : is_pin? L_("PIN:") : L_("Passphrase:"));
1048   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1049   if (rc)
1050     return unlock_pinentry (rc);
1051
1052   /* If a passphrase quality indicator has been requested and a
1053      minimum passphrase length has not been disabled, send the command
1054      to the pinentry.  */
1055   if (pininfo->with_qualitybar && opt.min_passphrase_len )
1056     {
1057       rc = setup_qualitybar (ctrl);
1058       if (rc)
1059         return unlock_pinentry (rc);
1060     }
1061
1062   if (initial_errtext)
1063     {
1064       snprintf (line, DIM(line), "SETERROR %s", initial_errtext);
1065       rc = assuan_transact (entry_ctx, line,
1066                             NULL, NULL, NULL, NULL, NULL, NULL);
1067       if (rc)
1068         return unlock_pinentry (rc);
1069     }
1070
1071   if (pininfo->with_repeat)
1072     {
1073       snprintf (line, DIM(line), "SETREPEATERROR %s",
1074                 L_("does not match - try again"));
1075       rc = assuan_transact (entry_ctx, line,
1076                             NULL, NULL, NULL, NULL, NULL, NULL);
1077       if (rc)
1078         pininfo->with_repeat = 0; /* Pinentry does not support it.  */
1079     }
1080   pininfo->repeat_okay = 0;
1081
1082   for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
1083     {
1084       memset (&parm, 0, sizeof parm);
1085       parm.size = pininfo->max_length;
1086       *pininfo->pin = 0; /* Reset the PIN. */
1087       parm.buffer = (unsigned char*)pininfo->pin;
1088
1089       if (errtext)
1090         {
1091           /* TRANSLATORS: The string is appended to an error message in
1092              the pinentry.  The %s is the actual error message, the
1093              two %d give the current and maximum number of tries. */
1094           snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"),
1095                     errtext, pininfo->failed_tries+1, pininfo->max_tries);
1096           rc = assuan_transact (entry_ctx, line,
1097                                 NULL, NULL, NULL, NULL, NULL, NULL);
1098           if (rc)
1099             return unlock_pinentry (rc);
1100           errtext = NULL;
1101         }
1102
1103       if (pininfo->with_repeat)
1104         {
1105           snprintf (line, DIM(line), "SETREPEAT %s", L_("Repeat:"));
1106           rc = assuan_transact (entry_ctx, line,
1107                                 NULL, NULL, NULL, NULL, NULL, NULL);
1108           if (rc)
1109             return unlock_pinentry (rc);
1110         }
1111
1112       saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
1113       assuan_begin_confidential (entry_ctx);
1114       pinentry_status = 0;
1115       rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
1116                             inq_quality, entry_ctx,
1117                             pinentry_status_cb, &pinentry_status);
1118       assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
1119       /* Most pinentries out in the wild return the old Assuan error code
1120          for canceled which gets translated to an assuan Cancel error and
1121          not to the code for a user cancel.  Fix this here. */
1122       if (rc && gpg_err_source (rc)
1123           && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1124         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1125
1126
1127       /* Change error code in case the window close button was clicked
1128          to cancel the operation.  */
1129       if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON)
1130           && gpg_err_code (rc) == GPG_ERR_CANCELED)
1131         rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
1132
1133       if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
1134         errtext = is_pin? L_("PIN too long")
1135                         : L_("Passphrase too long");
1136       else if (rc)
1137         return unlock_pinentry (rc);
1138
1139       if (!errtext && pininfo->min_digits)
1140         {
1141           /* do some basic checks on the entered PIN. */
1142           if (!all_digitsp (pininfo->pin))
1143             errtext = L_("Invalid characters in PIN");
1144           else if (pininfo->max_digits
1145                    && strlen (pininfo->pin) > pininfo->max_digits)
1146             errtext = L_("PIN too long");
1147           else if (strlen (pininfo->pin) < pininfo->min_digits)
1148             errtext = L_("PIN too short");
1149         }
1150
1151       if (!errtext && pininfo->check_cb)
1152         {
1153           /* More checks by utilizing the optional callback. */
1154           pininfo->cb_errtext = NULL;
1155           rc = pininfo->check_cb (pininfo);
1156           if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1157               && pininfo->cb_errtext)
1158             errtext = pininfo->cb_errtext;
1159           else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1160                    || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
1161             errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase"));
1162           else if (rc)
1163             return unlock_pinentry (rc);
1164         }
1165
1166       if (!errtext)
1167         {
1168           if (pininfo->with_repeat
1169               && (pinentry_status & PINENTRY_STATUS_PIN_REPEATED))
1170             pininfo->repeat_okay = 1;
1171           return unlock_pinentry (0); /* okay, got a PIN or passphrase */
1172         }
1173
1174       if ((pinentry_status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1175         /* The password was read from the cache.  Don't count this
1176            against the retry count.  */
1177         pininfo->failed_tries --;
1178     }
1179
1180   return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
1181                           : GPG_ERR_BAD_PASSPHRASE));
1182 }
1183
1184
1185 \f
1186 /* Ask for the passphrase using the supplied arguments.  The returned
1187    passphrase needs to be freed by the caller. */
1188 int
1189 agent_get_passphrase (ctrl_t ctrl,
1190                       char **retpass, const char *desc, const char *prompt,
1191                       const char *errtext, int with_qualitybar,
1192                       const char *keyinfo, cache_mode_t cache_mode)
1193 {
1194
1195   int rc;
1196   char line[ASSUAN_LINELENGTH];
1197   struct entry_parm_s parm;
1198   int saveflag;
1199   unsigned int pinentry_status;
1200
1201   *retpass = NULL;
1202   if (opt.batch)
1203     return gpg_error (GPG_ERR_BAD_PASSPHRASE);
1204
1205   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1206     {
1207       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1208         return gpg_error (GPG_ERR_CANCELED);
1209
1210       if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1211         {
1212           size_t size;
1213
1214           return pinentry_loopback (ctrl, "PASSPHRASE",
1215                                     (unsigned char **)retpass, &size,
1216                                     MAX_PASSPHRASE_LEN);
1217         }
1218       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1219     }
1220
1221   rc = start_pinentry (ctrl);
1222   if (rc)
1223     return rc;
1224
1225   if (!prompt)
1226     prompt = desc && strstr (desc, "PIN")? L_("PIN:"): L_("Passphrase:");
1227
1228
1229   /* If we have a KEYINFO string and are normal, user, or ssh cache
1230      mode, we tell that the Pinentry so it may use it for own caching
1231      purposes.  Most pinentries won't have this implemented and thus
1232      we do not error out in this case.  */
1233   if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1234                   || cache_mode == CACHE_MODE_USER
1235                   || cache_mode == CACHE_MODE_SSH))
1236     snprintf (line, DIM(line), "SETKEYINFO %c/%s",
1237               cache_mode == CACHE_MODE_USER? 'u' :
1238               cache_mode == CACHE_MODE_SSH? 's' : 'n',
1239               keyinfo);
1240   else
1241     snprintf (line, DIM(line), "SETKEYINFO --clear");
1242
1243   rc = assuan_transact (entry_ctx, line,
1244                         NULL, NULL, NULL, NULL, NULL, NULL);
1245   if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1246     return unlock_pinentry (rc);
1247
1248
1249   if (desc)
1250     build_cmd_setdesc (line, DIM(line), desc);
1251   else
1252     snprintf (line, DIM(line), "RESET");
1253   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1254   if (rc)
1255     return unlock_pinentry (rc);
1256
1257   snprintf (line, DIM(line), "SETPROMPT %s", prompt);
1258   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1259   if (rc)
1260     return unlock_pinentry (rc);
1261
1262   if (with_qualitybar && opt.min_passphrase_len)
1263     {
1264       rc = setup_qualitybar (ctrl);
1265       if (rc)
1266         return unlock_pinentry (rc);
1267     }
1268
1269   if (errtext)
1270     {
1271       snprintf (line, DIM(line), "SETERROR %s", errtext);
1272       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1273       if (rc)
1274         return unlock_pinentry (rc);
1275     }
1276
1277   memset (&parm, 0, sizeof parm);
1278   parm.size = ASSUAN_LINELENGTH/2 - 5;
1279   parm.buffer = gcry_malloc_secure (parm.size+10);
1280   if (!parm.buffer)
1281     return unlock_pinentry (out_of_core ());
1282
1283   saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
1284   assuan_begin_confidential (entry_ctx);
1285   pinentry_status = 0;
1286   rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
1287                         inq_quality, entry_ctx,
1288                         pinentry_status_cb, &pinentry_status);
1289   assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
1290   /* Most pinentries out in the wild return the old Assuan error code
1291      for canceled which gets translated to an assuan Cancel error and
1292      not to the code for a user cancel.  Fix this here. */
1293   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1294     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1295   /* Change error code in case the window close button was clicked
1296      to cancel the operation.  */
1297   if ((pinentry_status & PINENTRY_STATUS_CLOSE_BUTTON)
1298       && gpg_err_code (rc) == GPG_ERR_CANCELED)
1299     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
1300
1301   if (rc)
1302     xfree (parm.buffer);
1303   else
1304     *retpass = parm.buffer;
1305   return unlock_pinentry (rc);
1306 }
1307
1308
1309 \f
1310 /* Pop up the PIN-entry, display the text and the prompt and ask the
1311    user to confirm this.  We return 0 for success, ie. the user
1312    confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
1313    other error.  If WITH_CANCEL it true an extra cancel button is
1314    displayed to allow the user to easily return a GPG_ERR_CANCELED.
1315    if the Pinentry does not support this, the user can still cancel by
1316    closing the Pinentry window.  */
1317 int
1318 agent_get_confirmation (ctrl_t ctrl,
1319                         const char *desc, const char *ok,
1320                         const char *notok, int with_cancel)
1321 {
1322   int rc;
1323   char line[ASSUAN_LINELENGTH];
1324
1325   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1326     {
1327       if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1328         return gpg_error (GPG_ERR_CANCELED);
1329
1330       return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1331     }
1332
1333   rc = start_pinentry (ctrl);
1334   if (rc)
1335     return rc;
1336
1337   if (desc)
1338     build_cmd_setdesc (line, DIM(line), desc);
1339   else
1340     snprintf (line, DIM(line), "RESET");
1341   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1342   /* Most pinentries out in the wild return the old Assuan error code
1343      for canceled which gets translated to an assuan Cancel error and
1344      not to the code for a user cancel.  Fix this here. */
1345   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1346     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1347
1348   if (rc)
1349     return unlock_pinentry (rc);
1350
1351   if (ok)
1352     {
1353       snprintf (line, DIM(line), "SETOK %s", ok);
1354       rc = assuan_transact (entry_ctx,
1355                             line, NULL, NULL, NULL, NULL, NULL, NULL);
1356       if (rc)
1357         return unlock_pinentry (rc);
1358     }
1359   if (notok)
1360     {
1361       /* Try to use the newer NOTOK feature if a cancel button is
1362          requested.  If no cancel button is requested we keep on using
1363          the standard cancel.  */
1364       if (with_cancel)
1365         {
1366           snprintf (line, DIM(line), "SETNOTOK %s", notok);
1367           rc = assuan_transact (entry_ctx,
1368                                 line, NULL, NULL, NULL, NULL, NULL, NULL);
1369         }
1370       else
1371         rc = GPG_ERR_ASS_UNKNOWN_CMD;
1372
1373       if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1374         {
1375           snprintf (line, DIM(line), "SETCANCEL %s", notok);
1376           rc = assuan_transact (entry_ctx, line,
1377                                 NULL, NULL, NULL, NULL, NULL, NULL);
1378         }
1379       if (rc)
1380         return unlock_pinentry (rc);
1381     }
1382
1383   rc = assuan_transact (entry_ctx, "CONFIRM",
1384                         NULL, NULL, NULL, NULL, NULL, NULL);
1385   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1386     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1387
1388   return unlock_pinentry (rc);
1389 }
1390
1391
1392 \f
1393 /* Pop up the PINentry, display the text DESC and a button with the
1394    text OK_BTN (which may be NULL to use the default of "OK") and wait
1395    for the user to hit this button.  The return value is not
1396    relevant.  */
1397 int
1398 agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
1399 {
1400   int rc;
1401   char line[ASSUAN_LINELENGTH];
1402
1403   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1404     return gpg_error (GPG_ERR_CANCELED);
1405
1406   rc = start_pinentry (ctrl);
1407   if (rc)
1408     return rc;
1409
1410   if (desc)
1411     build_cmd_setdesc (line, DIM(line), desc);
1412   else
1413     snprintf (line, DIM(line), "RESET");
1414   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1415   /* Most pinentries out in the wild return the old Assuan error code
1416      for canceled which gets translated to an assuan Cancel error and
1417      not to the code for a user cancel.  Fix this here. */
1418   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1419     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1420
1421   if (rc)
1422     return unlock_pinentry (rc);
1423
1424   if (ok_btn)
1425     {
1426       snprintf (line, DIM(line), "SETOK %s", ok_btn);
1427       rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL,
1428                             NULL, NULL, NULL);
1429       if (rc)
1430         return unlock_pinentry (rc);
1431     }
1432
1433   rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL,
1434                         NULL, NULL, NULL);
1435   if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1436     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1437
1438   return unlock_pinentry (rc);
1439 }
1440
1441
1442 /* The thread running the popup message. */
1443 static void *
1444 popup_message_thread (void *arg)
1445 {
1446   (void)arg;
1447
1448   /* We use the --one-button hack instead of the MESSAGE command to
1449      allow the use of old Pinentries.  Those old Pinentries will then
1450      show an additional Cancel button but that is mostly a visual
1451      annoyance. */
1452   assuan_transact (entry_ctx, "CONFIRM --one-button",
1453                    NULL, NULL, NULL, NULL, NULL, NULL);
1454   popup_finished = 1;
1455   return NULL;
1456 }
1457
1458
1459 /* Pop up a message window similar to the confirm one but keep it open
1460    until agent_popup_message_stop has been called.  It is crucial for
1461    the caller to make sure that the stop function gets called as soon
1462    as the message is not anymore required because the message is
1463    system modal and all other attempts to use the pinentry will fail
1464    (after a timeout). */
1465 int
1466 agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
1467 {
1468   int rc;
1469   char line[ASSUAN_LINELENGTH];
1470   npth_attr_t tattr;
1471   int err;
1472
1473   if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1474     return gpg_error (GPG_ERR_CANCELED);
1475
1476   rc = start_pinentry (ctrl);
1477   if (rc)
1478     return rc;
1479
1480   if (desc)
1481     build_cmd_setdesc (line, DIM(line), desc);
1482   else
1483     snprintf (line, DIM(line), "RESET");
1484   rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1485   if (rc)
1486     return unlock_pinentry (rc);
1487
1488   if (ok_btn)
1489     {
1490       snprintf (line, DIM(line), "SETOK %s", ok_btn);
1491       rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
1492       if (rc)
1493         return unlock_pinentry (rc);
1494     }
1495
1496   err = npth_attr_init (&tattr);
1497   if (err)
1498     return unlock_pinentry (gpg_error_from_errno (err));
1499   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1500
1501   popup_finished = 0;
1502   err = npth_create (&popup_tid, &tattr, popup_message_thread, NULL);
1503   npth_attr_destroy (&tattr);
1504   if (err)
1505     {
1506       rc = gpg_error_from_errno (err);
1507       log_error ("error spawning popup message handler: %s\n",
1508                  strerror (err) );
1509       return unlock_pinentry (rc);
1510     }
1511   npth_setname_np (popup_tid, "popup-message");
1512
1513   return 0;
1514 }
1515
1516 /* Close a popup window. */
1517 void
1518 agent_popup_message_stop (ctrl_t ctrl)
1519 {
1520   int rc;
1521   pid_t pid;
1522
1523   (void)ctrl;
1524
1525   if (!popup_tid || !entry_ctx)
1526     {
1527       log_debug ("agent_popup_message_stop called with no active popup\n");
1528       return;
1529     }
1530
1531   pid = assuan_get_pid (entry_ctx);
1532   if (pid == (pid_t)(-1))
1533     ; /* No pid available can't send a kill. */
1534   else if (popup_finished)
1535     ; /* Already finished and ready for joining. */
1536 #ifdef HAVE_W32_SYSTEM
1537   /* Older versions of assuan set PID to 0 on Windows to indicate an
1538      invalid value.  */
1539   else if (pid != (pid_t) INVALID_HANDLE_VALUE
1540            && pid != 0)
1541     {
1542       HANDLE process = (HANDLE) pid;
1543
1544       /* Arbitrary error code.  */
1545       TerminateProcess (process, 1);
1546     }
1547 #else
1548   else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
1549     { /* The daemon already died.  No need to send a kill.  However
1550          because we already waited for the process, we need to tell
1551          assuan that it should not wait again (done by
1552          unlock_pinentry). */
1553       if (rc == pid)
1554         assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
1555     }
1556   else if (pid > 0)
1557     kill (pid, SIGINT);
1558 #endif
1559
1560   /* Now wait for the thread to terminate. */
1561   rc = npth_join (popup_tid, NULL);
1562   if (rc)
1563     log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
1564                strerror (rc));
1565   /* Thread IDs are opaque, but we try our best here by resetting it
1566      to the same content that a static global variable has.  */
1567   memset (&popup_tid, '\0', sizeof (popup_tid));
1568
1569   /* Now we can close the connection. */
1570   unlock_pinentry (0);
1571 }
1572
1573 int
1574 agent_clear_passphrase (ctrl_t ctrl,
1575                         const char *keyinfo, cache_mode_t cache_mode)
1576 {
1577   int rc;
1578   char line[ASSUAN_LINELENGTH];
1579
1580   if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1581                      || cache_mode == CACHE_MODE_USER
1582                      || cache_mode == CACHE_MODE_SSH)))
1583     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1584
1585   rc = start_pinentry (ctrl);
1586   if (rc)
1587     return rc;
1588
1589   snprintf (line, DIM(line), "CLEARPASSPHRASE %c/%s",
1590             cache_mode == CACHE_MODE_USER? 'u' :
1591             cache_mode == CACHE_MODE_SSH? 's' : 'n',
1592             keyinfo);
1593   rc = assuan_transact (entry_ctx, line,
1594                         NULL, NULL, NULL, NULL, NULL, NULL);
1595
1596   return unlock_pinentry (rc);
1597 }