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