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