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 <unistd.h>
28 #include <sys/stat.h>
29 #ifndef HAVE_W32_SYSTEM
30 # include <sys/wait.h>
31 # include <sys/types.h>
32 # include <signal.h>
33 # include <sys/utsname.h>
34 #endif
35 #include <npth.h>
36
37 #include "agent.h"
38 #include <assuan.h>
39 #include "../common/sysutils.h"
40 #include "../common/i18n.h"
41 #include "../common/zb32.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 /* Define the number of bits to use for a generated pin. The
57 * passphrase will be rendered as zbase32 which results for 150 bits
58 * in a string of 30 characters. That fits nicely into the 5
59 * character blocking which pinentry can do. 128 bits would actually
60 * be sufficient but can't be formatted nicely. */
61 #define DEFAULT_GENPIN_BITS 150
62
63 /* The assuan context of the current pinentry. */
64 static assuan_context_t entry_ctx;
65
66 /* A list of features of the current pinentry. */
67 static struct
68 {
69 /* The Pinentry support RS+US tabbing. This means that a RS (0x1e)
70 * starts a new tabbing block in which a US (0x1f) followed by a
71 * colon marks a colon. A pinentry can use this to pretty print
72 * name value pairs. */
73 unsigned int tabbing:1;
74 } entry_features;
75
76
77 /* A mutex used to serialize access to the pinentry. */
78 static npth_mutex_t entry_lock;
79
80 /* The thread ID of the popup working thread. */
81 static npth_t popup_tid;
82
83 /* A flag used in communication between the popup working thread and
84 its stop function. */
85 static int popup_finished;
86
87
88
89 /* Data to be passed to our callbacks, */
90 struct entry_parm_s
91 {
92 int lines;
93 size_t size;
94 unsigned char *buffer;
95 int status;
96 unsigned int constraints_flags;
97 };
98
99
100
101
102 /* This function must be called once to initialize this module. This
103 has to be done before a second thread is spawned. We can't do the
104 static initialization because Pth emulation code might not be able
105 to do a static init; in particular, it is not possible for W32. */
106 void
initialize_module_call_pinentry(void)107 initialize_module_call_pinentry (void)
108 {
109 static int initialized;
110 int err;
111
112 if (!initialized)
113 {
114 err = npth_mutex_init (&entry_lock, NULL);
115 if (err)
116 log_fatal ("error initializing mutex: %s\n", strerror (err));
117
118 initialized = 1;
119 }
120 }
121
122
123
124 /* This function may be called to print information pertaining to the
125 current state of this module to the log. */
126 void
agent_query_dump_state(void)127 agent_query_dump_state (void)
128 {
129 log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
130 entry_ctx, (long)assuan_get_pid (entry_ctx), (void*)popup_tid);
131 }
132
133 /* Called to make sure that a popup window owned by the current
134 connection gets closed. */
135 void
agent_reset_query(ctrl_t ctrl)136 agent_reset_query (ctrl_t ctrl)
137 {
138 if (entry_ctx && popup_tid && ctrl->pinentry_active)
139 {
140 agent_popup_message_stop (ctrl);
141 }
142 }
143
144
145 /* Unlock the pinentry so that another thread can start one and
146 disconnect that pinentry - we do this after the unlock so that a
147 stalled pinentry does not block other threads. Fixme: We should
148 have a timeout in Assuan for the disconnect operation. */
149 static gpg_error_t
unlock_pinentry(ctrl_t ctrl,gpg_error_t rc)150 unlock_pinentry (ctrl_t ctrl, gpg_error_t rc)
151 {
152 assuan_context_t ctx = entry_ctx;
153 int err;
154
155 if (rc)
156 {
157 if (DBG_IPC)
158 log_debug ("error calling pinentry: %s <%s>\n",
159 gpg_strerror (rc), gpg_strsource (rc));
160
161 /* Change the source of the error to pinentry so that the final
162 consumer of the error code knows that the problem is with
163 pinentry. For backward compatibility we do not do that for
164 some common error codes. */
165 switch (gpg_err_code (rc))
166 {
167 case GPG_ERR_NO_PIN_ENTRY:
168 case GPG_ERR_CANCELED:
169 case GPG_ERR_FULLY_CANCELED:
170 case GPG_ERR_ASS_UNKNOWN_INQUIRE:
171 case GPG_ERR_ASS_TOO_MUCH_DATA:
172 case GPG_ERR_NO_PASSPHRASE:
173 case GPG_ERR_BAD_PASSPHRASE:
174 case GPG_ERR_BAD_PIN:
175 break;
176
177 case GPG_ERR_CORRUPTED_PROTECTION:
178 /* This comes from gpg-agent. */
179 break;
180
181 default:
182 rc = gpg_err_make (GPG_ERR_SOURCE_PINENTRY, gpg_err_code (rc));
183 break;
184 }
185 }
186
187 if (--ctrl->pinentry_active == 0)
188 {
189 entry_ctx = NULL;
190 err = npth_mutex_unlock (&entry_lock);
191 if (err)
192 {
193 log_error ("failed to release the entry lock: %s\n", strerror (err));
194 if (!rc)
195 rc = gpg_error_from_errno (err);
196 }
197 assuan_release (ctx);
198 }
199 return rc;
200 }
201
202
203 /* Helper for at_fork_cb which can also be called by the parent to
204 * show which envvars will be set. */
205 static void
atfork_core(ctrl_t ctrl,int debug_mode)206 atfork_core (ctrl_t ctrl, int debug_mode)
207 {
208 int iterator = 0;
209 const char *name, *assname, *value;
210
211 while ((name = session_env_list_stdenvnames (&iterator, &assname)))
212 {
213 /* For all new envvars (!ASSNAME) and the two medium old ones
214 * which do have an assuan name but are conveyed using
215 * environment variables, update the environment of the forked
216 * process. We also pass DISPLAY despite that --display is also
217 * used when exec-ing the pinentry. The reason is that for
218 * example the qt5ct tool does not have any arguments and thus
219 * relies on the DISPLAY envvar. The use case here is a global
220 * envvar like "QT_QPA_PLATFORMTHEME=qt5ct" which for example is
221 * useful when using the Qt pinentry under GNOME or XFCE.
222 */
223 if (!assname
224 || (!opt.keep_display && !strcmp (name, "DISPLAY"))
225 || !strcmp (name, "XAUTHORITY")
226 || !strcmp (name, "PINENTRY_USER_DATA"))
227 {
228 value = session_env_getenv (ctrl->session_env, name);
229 if (value)
230 {
231 if (debug_mode)
232 log_debug ("pinentry: atfork used setenv(%s,%s)\n",name,value);
233 else
234 gnupg_setenv (name, value, 1);
235 }
236 }
237 }
238 }
239
240
241 /* To make sure we leave no secrets in our image after forking of the
242 pinentry, we use this callback. */
243 static void
atfork_cb(void * opaque,int where)244 atfork_cb (void *opaque, int where)
245 {
246 ctrl_t ctrl = opaque;
247
248 if (!where)
249 {
250 gcry_control (GCRYCTL_TERM_SECMEM);
251 atfork_core (ctrl, 0);
252 }
253 }
254
255
256 /* Status line callback for the FEATURES status. */
257 static gpg_error_t
getinfo_features_cb(void * opaque,const char * line)258 getinfo_features_cb (void *opaque, const char *line)
259 {
260 const char *args;
261 char **tokens;
262 int i;
263
264 (void)opaque;
265
266 if ((args = has_leading_keyword (line, "FEATURES")))
267 {
268 tokens = strtokenize (args, " ");
269 if (!tokens)
270 return gpg_error_from_syserror ();
271 for (i=0; tokens[i]; i++)
272 if (!strcmp (tokens[i], "tabbing"))
273 entry_features.tabbing = 1;
274 xfree (tokens);
275 }
276
277 return 0;
278 }
279
280
281 static gpg_error_t
getinfo_pid_cb(void * opaque,const void * buffer,size_t length)282 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
283 {
284 unsigned long *pid = opaque;
285 char pidbuf[50];
286
287 /* There is only the pid in the server's response. */
288 if (length >= sizeof pidbuf)
289 length = sizeof pidbuf -1;
290 if (length)
291 {
292 strncpy (pidbuf, buffer, length);
293 pidbuf[length] = 0;
294 *pid = strtoul (pidbuf, NULL, 10);
295 }
296 return 0;
297 }
298
299
300 /* Fork off the pin entry if this has not already been done. Note,
301 that this function must always be used to acquire the lock for the
302 pinentry - we will serialize _all_ pinentry calls.
303 */
304 static gpg_error_t
start_pinentry(ctrl_t ctrl)305 start_pinentry (ctrl_t ctrl)
306 {
307 int rc = 0;
308 const char *full_pgmname;
309 const char *pgmname;
310 assuan_context_t ctx;
311 const char *argv[5];
312 assuan_fd_t no_close_list[3];
313 int i;
314 const char *tmpstr;
315 unsigned long pinentry_pid;
316 const char *value;
317 struct timespec abstime;
318 char *flavor_version;
319 int err;
320
321 if (ctrl->pinentry_active)
322 {
323 /* It's trying to use pinentry recursively. In this situation,
324 the thread holds ENTRY_LOCK already. */
325 ctrl->pinentry_active++;
326 return 0;
327 }
328
329 npth_clock_gettime (&abstime);
330 abstime.tv_sec += LOCK_TIMEOUT;
331 err = npth_mutex_timedlock (&entry_lock, &abstime);
332 if (err)
333 {
334 if (err == ETIMEDOUT)
335 rc = gpg_error (GPG_ERR_TIMEOUT);
336 else
337 rc = gpg_error_from_errno (rc);
338 log_error (_("failed to acquire the pinentry lock: %s\n"),
339 gpg_strerror (rc));
340 return rc;
341 }
342
343 if (entry_ctx)
344 return 0;
345
346 if (opt.verbose)
347 log_info ("starting a new PIN Entry\n");
348
349 #ifdef HAVE_W32_SYSTEM
350 fflush (stdout);
351 fflush (stderr);
352 #endif
353 if (fflush (NULL))
354 {
355 #ifndef HAVE_W32_SYSTEM
356 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
357 #endif
358 log_error ("error flushing pending output: %s\n", strerror (errno));
359 /* At least Windows XP fails here with EBADF. According to docs
360 and Wine an fflush(NULL) is the same as _flushall. However
361 the Wine implementation does not flush stdin,stdout and stderr
362 - see above. Let's try to ignore the error. */
363 #ifndef HAVE_W32_SYSTEM
364 return unlock_pinentry (ctrl, tmperr);
365 #endif
366 }
367
368 full_pgmname = opt.pinentry_program;
369 if (!full_pgmname || !*full_pgmname)
370 full_pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY);
371 if ( !(pgmname = strrchr (full_pgmname, '/')))
372 pgmname = full_pgmname;
373 else
374 pgmname++;
375
376 /* OS X needs the entire file name in argv[0], so that it can locate
377 the resource bundle. For other systems we stick to the usual
378 convention of supplying only the name of the program. */
379 #ifdef __APPLE__
380 argv[0] = full_pgmname;
381 #else /*!__APPLE__*/
382 argv[0] = pgmname;
383 #endif /*__APPLE__*/
384
385 if (!opt.keep_display
386 && (value = session_env_getenv (ctrl->session_env, "DISPLAY")))
387 {
388 argv[1] = "--display";
389 argv[2] = value;
390 argv[3] = NULL;
391 }
392 else
393 argv[1] = NULL;
394
395 i=0;
396 if (!opt.running_detached)
397 {
398 if (log_get_fd () != -1)
399 no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ());
400 no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
401 }
402 no_close_list[i] = ASSUAN_INVALID_FD;
403
404 rc = assuan_new (&ctx);
405 if (rc)
406 {
407 log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
408 return rc;
409 }
410
411 ctrl->pinentry_active = 1;
412 entry_ctx = ctx;
413
414 /* We don't want to log the pinentry communication to make the logs
415 easier to read. We might want to add a new debug option to enable
416 pinentry logging. */
417 #ifdef ASSUAN_NO_LOGGING
418 assuan_set_flag (ctx, ASSUAN_NO_LOGGING, !opt.debug_pinentry);
419 #endif
420
421 /* Connect to the pinentry and perform initial handshaking. Note
422 that atfork is used to change the environment for pinentry. We
423 start the server in detached mode to suppress the console window
424 under Windows. */
425 rc = assuan_pipe_connect (entry_ctx, full_pgmname, argv,
426 no_close_list, atfork_cb, ctrl,
427 ASSUAN_PIPE_CONNECT_DETACHED);
428 if (rc)
429 {
430 log_error ("can't connect to the PIN entry module '%s': %s\n",
431 full_pgmname, gpg_strerror (rc));
432 return unlock_pinentry (ctrl, gpg_error (GPG_ERR_NO_PIN_ENTRY));
433 }
434
435 if (DBG_IPC)
436 log_debug ("connection to PIN entry established\n");
437
438 if (opt.debug_pinentry)
439 atfork_core (ctrl, 1); /* Just show the envvars set after the fork. */
440
441 value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA");
442 if (value != NULL)
443 {
444 char *optstr;
445 if (asprintf (&optstr, "OPTION pinentry-user-data=%s", value) < 0 )
446 return unlock_pinentry (ctrl, out_of_core ());
447 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
448 NULL);
449 xfree (optstr);
450 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
451 return unlock_pinentry (ctrl, rc);
452 }
453
454 rc = assuan_transact (entry_ctx,
455 opt.no_grab? "OPTION no-grab":"OPTION grab",
456 NULL, NULL, NULL, NULL, NULL, NULL);
457 if (rc)
458 {
459 if (gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED
460 || gpg_err_code (rc) == GPG_ERR_UNKNOWN_OPTION)
461 {
462 if (opt.verbose)
463 log_info ("Option no-grab/grab is ignored by pinentry.\n");
464 /* Keep going even if the feature is not supported. */
465 }
466 else
467 return unlock_pinentry (ctrl, rc);
468 }
469
470 value = session_env_getenv (ctrl->session_env, "GPG_TTY");
471 if (value)
472 {
473 char *optstr;
474 if (asprintf (&optstr, "OPTION ttyname=%s", value) < 0 )
475 return unlock_pinentry (ctrl, out_of_core ());
476 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
477 NULL);
478 xfree (optstr);
479 if (rc)
480 return unlock_pinentry (ctrl, rc);
481 }
482 value = session_env_getenv (ctrl->session_env, "TERM");
483 if (value && *value)
484 {
485 char *optstr;
486 if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 )
487 return unlock_pinentry (ctrl, out_of_core ());
488 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
489 NULL);
490 xfree (optstr);
491 if (rc)
492 return unlock_pinentry (ctrl, rc);
493 }
494 if (ctrl->lc_ctype)
495 {
496 char *optstr;
497 if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 )
498 return unlock_pinentry (ctrl, out_of_core ());
499 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
500 NULL);
501 xfree (optstr);
502 if (rc)
503 return unlock_pinentry (ctrl, rc);
504 }
505 if (ctrl->lc_messages)
506 {
507 char *optstr;
508 if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 )
509 return unlock_pinentry (ctrl, out_of_core ());
510 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
511 NULL);
512 xfree (optstr);
513 if (rc)
514 return unlock_pinentry (ctrl, rc);
515 }
516
517
518 if (opt.allow_external_cache)
519 {
520 /* Indicate to the pinentry that it may read from an external cache.
521
522 It is essential that the pinentry respect this. If the
523 cached password is not up to date and retry == 1, then, using
524 a version of GPG Agent that doesn't support this, won't issue
525 another pin request and the user won't get a chance to
526 correct the password. */
527 rc = assuan_transact (entry_ctx, "OPTION allow-external-password-cache",
528 NULL, NULL, NULL, NULL, NULL, NULL);
529 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
530 return unlock_pinentry (ctrl, rc);
531 }
532
533 if (opt.allow_emacs_pinentry)
534 {
535 /* Indicate to the pinentry that it may read passphrase through
536 Emacs minibuffer, if possible. */
537 rc = assuan_transact (entry_ctx, "OPTION allow-emacs-prompt",
538 NULL, NULL, NULL, NULL, NULL, NULL);
539 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
540 return unlock_pinentry (ctrl, rc);
541 }
542
543
544 {
545 /* Provide a few default strings for use by the pinentries. This
546 * may help a pinentry to avoid implementing localization code.
547 * Note that gpg-agent has been set to utf-8 so that the strings
548 * are in the expected encoding. */
549 static const struct { const char *key, *value; int what; } tbl[] = {
550 /* TRANSLATORS: These are labels for buttons etc as used in
551 * Pinentries. In your translation copy the text before the
552 * second vertical bar verbatim; translate only the following
553 * text. An underscore indicates that the next letter should be
554 * used as an accelerator. Double the underscore to have
555 * pinentry display a literal underscore. */
556 { "ok", N_("|pinentry-label|_OK") },
557 { "cancel", N_("|pinentry-label|_Cancel") },
558 { "yes", N_("|pinentry-label|_Yes") },
559 { "no", N_("|pinentry-label|_No") },
560 { "prompt", N_("|pinentry-label|PIN:") },
561 { "pwmngr", N_("|pinentry-label|_Save in password manager"), 1 },
562 { "cf-visi",N_("Do you really want to make your "
563 "passphrase visible on the screen?") },
564 { "tt-visi",N_("|pinentry-tt|Make passphrase visible") },
565 { "tt-hide",N_("|pinentry-tt|Hide passphrase") },
566 { "capshint", N_("Caps Lock is on") },
567 { NULL, NULL}
568 };
569 char *optstr;
570 int idx;
571 const char *s, *s2;
572
573 for (idx=0; tbl[idx].key; idx++)
574 {
575 if (!opt.allow_external_cache && tbl[idx].what == 1)
576 continue; /* No need for it. */
577 s = L_(tbl[idx].value);
578 if (*s == '|' && (s2=strchr (s+1,'|')))
579 s = s2+1;
580 if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 )
581 return unlock_pinentry (ctrl, out_of_core ());
582 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
583 NULL);
584 xfree (optstr);
585 }
586 }
587
588 /* Tell the pinentry that we would prefer that the given character
589 is used as the invisible character by the entry widget. */
590 if (opt.pinentry_invisible_char)
591 {
592 char *optstr;
593 if ((optstr = xtryasprintf ("OPTION invisible-char=%s",
594 opt.pinentry_invisible_char)))
595 {
596 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
597 NULL);
598 /* We ignore errors because this is just a fancy thing and
599 older pinentries do not support this feature. */
600 xfree (optstr);
601 }
602 }
603
604 if (opt.pinentry_timeout)
605 {
606 char *optstr;
607 if ((optstr = xtryasprintf ("SETTIMEOUT %lu", opt.pinentry_timeout)))
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. */
612 xfree (optstr);
613 }
614 }
615
616 /* Tell the pinentry the name of a file it shall touch after having
617 messed with the tty. This is optional and only supported by
618 newer pinentries and thus we do no error checking. */
619 tmpstr = opt.pinentry_touch_file;
620 if (tmpstr && !strcmp (tmpstr, "/dev/null"))
621 tmpstr = NULL;
622 else if (!tmpstr)
623 tmpstr = get_agent_socket_name ();
624 if (tmpstr)
625 {
626 char *optstr;
627
628 if (asprintf (&optstr, "OPTION touch-file=%s", tmpstr ) < 0 )
629 ;
630 else
631 {
632 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
633 NULL);
634 xfree (optstr);
635 }
636 }
637
638 /* Tell Pinentry about our client. */
639 if (ctrl->client_pid)
640 {
641 char *optstr;
642 const char *nodename = "";
643
644 #ifndef HAVE_W32_SYSTEM
645 struct utsname utsbuf;
646 if (!uname (&utsbuf))
647 nodename = utsbuf.nodename;
648 #endif /*!HAVE_W32_SYSTEM*/
649
650 if ((optstr = xtryasprintf ("OPTION owner=%lu/%d %s",
651 ctrl->client_pid, ctrl->client_uid,
652 nodename)))
653 {
654 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
655 NULL);
656 /* We ignore errors because this is just a fancy thing and
657 older pinentries do not support this feature. */
658 xfree (optstr);
659 }
660 }
661
662
663 /* Ask the pinentry for its version and flavor and store that as a
664 * string in MB. This information is useful for helping users to
665 * figure out Pinentry problems. Note that "flavor" may also return
666 * a status line with the features; we use a dedicated handler for
667 * that. */
668 {
669 membuf_t mb;
670
671 init_membuf (&mb, 256);
672 if (assuan_transact (entry_ctx, "GETINFO flavor",
673 put_membuf_cb, &mb,
674 NULL, NULL,
675 getinfo_features_cb, NULL))
676 put_membuf_str (&mb, "unknown");
677 put_membuf_str (&mb, " ");
678 if (assuan_transact (entry_ctx, "GETINFO version",
679 put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
680 put_membuf_str (&mb, "unknown");
681 put_membuf_str (&mb, " ");
682 if (assuan_transact (entry_ctx, "GETINFO ttyinfo",
683 put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
684 put_membuf_str (&mb, "? ? ?");
685 put_membuf (&mb, "", 1);
686 flavor_version = get_membuf (&mb, NULL);
687 }
688
689
690 /* Now ask the Pinentry for its PID. If the Pinentry is new enough
691 it will send the pid back and we will use an inquire to notify
692 our client. The client may answer the inquiry either with END or
693 with CAN to cancel the pinentry. */
694 rc = assuan_transact (entry_ctx, "GETINFO pid",
695 getinfo_pid_cb, &pinentry_pid,
696 NULL, NULL, NULL, NULL);
697 if (rc)
698 {
699 log_info ("You may want to update to a newer pinentry\n");
700 rc = 0;
701 }
702 else if (!rc && pinentry_pid == (unsigned long)(-1L))
703 log_error ("pinentry did not return a PID\n");
704 else
705 {
706 rc = agent_inq_pinentry_launched (ctrl, pinentry_pid, flavor_version);
707 if (gpg_err_code (rc) == GPG_ERR_CANCELED
708 || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
709 return unlock_pinentry (ctrl, gpg_err_make (GPG_ERR_SOURCE_DEFAULT,
710 gpg_err_code (rc)));
711 rc = 0;
712 }
713
714 xfree (flavor_version);
715
716 return rc;
717 }
718
719
720 /* Returns True if the pinentry is currently active. If WAITSECONDS is
721 greater than zero the function will wait for this many seconds
722 before returning. */
723 int
pinentry_active_p(ctrl_t ctrl,int waitseconds)724 pinentry_active_p (ctrl_t ctrl, int waitseconds)
725 {
726 int err;
727 (void)ctrl;
728
729 if (waitseconds > 0)
730 {
731 struct timespec abstime;
732 int rc;
733
734 npth_clock_gettime (&abstime);
735 abstime.tv_sec += waitseconds;
736 err = npth_mutex_timedlock (&entry_lock, &abstime);
737 if (err)
738 {
739 if (err == ETIMEDOUT)
740 rc = gpg_error (GPG_ERR_TIMEOUT);
741 else
742 rc = gpg_error (GPG_ERR_INTERNAL);
743 return rc;
744 }
745 }
746 else
747 {
748 err = npth_mutex_trylock (&entry_lock);
749 if (err)
750 return gpg_error (GPG_ERR_LOCKED);
751 }
752
753 err = npth_mutex_unlock (&entry_lock);
754 if (err)
755 log_error ("failed to release the entry lock at %d: %s\n", __LINE__,
756 strerror (errno));
757 return 0;
758 }
759
760
761 static gpg_error_t
getpin_cb(void * opaque,const void * buffer,size_t length)762 getpin_cb (void *opaque, const void *buffer, size_t length)
763 {
764 struct entry_parm_s *parm = opaque;
765
766 if (!buffer)
767 return 0;
768
769 /* we expect the pin to fit on one line */
770 if (parm->lines || length >= parm->size)
771 return gpg_error (GPG_ERR_ASS_TOO_MUCH_DATA);
772
773 /* fixme: we should make sure that the assuan buffer is allocated in
774 secure memory or read the response byte by byte */
775 memcpy (parm->buffer, buffer, length);
776 parm->buffer[length] = 0;
777 parm->lines++;
778 return 0;
779 }
780
781
782 static int
all_digitsp(const char * s)783 all_digitsp( const char *s)
784 {
785 for (; *s && *s >= '0' && *s <= '9'; s++)
786 ;
787 return !*s;
788 }
789
790
791 /* Return a new malloced string by unescaping the string S. Escaping
792 is percent escaping and '+'/space mapping. A binary Nul will
793 silently be replaced by a 0xFF. Function returns NULL to indicate
794 an out of memory status. Parsing stops at the end of the string or
795 a white space character. */
796 static char *
unescape_passphrase_string(const unsigned char * s)797 unescape_passphrase_string (const unsigned char *s)
798 {
799 char *buffer, *d;
800
801 buffer = d = xtrymalloc_secure (strlen ((const char*)s)+1);
802 if (!buffer)
803 return NULL;
804 while (*s && !spacep (s))
805 {
806 if (*s == '%' && s[1] && s[2])
807 {
808 s++;
809 *d = xtoi_2 (s);
810 if (!*d)
811 *d = '\xff';
812 d++;
813 s += 2;
814 }
815 else if (*s == '+')
816 {
817 *d++ = ' ';
818 s++;
819 }
820 else
821 *d++ = *s++;
822 }
823 *d = 0;
824 return buffer;
825 }
826
827
828 /* Estimate the quality of the passphrase PW and return a value in the
829 range 0..100. */
830 static int
estimate_passphrase_quality(const char * pw)831 estimate_passphrase_quality (const char *pw)
832 {
833 int goodlength = opt.min_passphrase_len + opt.min_passphrase_len/3;
834 int length;
835 const char *s;
836
837 if (goodlength < 1)
838 return 0;
839
840 for (length = 0, s = pw; *s; s++)
841 if (!spacep (s))
842 length ++;
843
844 if (length > goodlength)
845 return 100;
846 return ((length*10) / goodlength)*10;
847 }
848
849
850 /* Generate a random passphrase in zBase32 encoding (RFC-6189) to be
851 * used by Pinentry to suggest a passphrase. */
852 static char *
generate_pin(void)853 generate_pin (void)
854 {
855 unsigned int nbits = opt.min_passphrase_len * 8;
856 size_t nbytes;
857 void *rand;
858 char *generated;
859
860 if (nbits < 128)
861 nbits = DEFAULT_GENPIN_BITS;
862
863 nbytes = (nbits + 7) / 8;
864
865 rand = gcry_random_bytes_secure (nbytes, GCRY_STRONG_RANDOM);
866 if (!rand)
867 {
868 log_error ("failed to generate random pin\n");
869 return NULL;
870 }
871
872 generated = zb32_encode (rand, nbits);
873 gcry_free (rand);
874 return generated;
875 }
876
877
878 /* Handle inquiries. */
879 struct inq_cb_parm_s
880 {
881 assuan_context_t ctx;
882 unsigned int flags; /* CHECK_CONSTRAINTS_... */
883 int genpinhash_valid;
884 char genpinhash[32]; /* Hash of the last generated pin. */
885 };
886
887
888 /* Return true if PIN is indentical to the last generated pin. */
889 static int
is_generated_pin(struct inq_cb_parm_s * parm,const char * pin)890 is_generated_pin (struct inq_cb_parm_s *parm, const char *pin)
891 {
892 char hashbuf[32];
893
894 if (!parm->genpinhash_valid)
895 return 0;
896 if (!*pin)
897 return 0;
898 /* Note that we compare the hash so that we do not need to save the
899 * generated PIN longer than needed. */
900 gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, pin, strlen (pin));
901
902 if (!memcmp (hashbuf, parm->genpinhash, 32))
903 return 1; /* yes, it is the same. */
904
905 return 0;
906 }
907
908
909 static gpg_error_t
inq_cb(void * opaque,const char * line)910 inq_cb (void *opaque, const char *line)
911 {
912 struct inq_cb_parm_s *parm = opaque;
913 gpg_error_t err;
914 const char *s;
915 char *pin;
916
917 if ((s = has_leading_keyword (line, "QUALITY")))
918 {
919 char numbuf[20];
920 int percent;
921
922 pin = unescape_passphrase_string (s);
923 if (!pin)
924 err = gpg_error_from_syserror ();
925 else
926 {
927 percent = estimate_passphrase_quality (pin);
928 if (check_passphrase_constraints (NULL, pin, parm->flags, NULL))
929 percent = -percent;
930 snprintf (numbuf, sizeof numbuf, "%d", percent);
931 err = assuan_send_data (parm->ctx, numbuf, strlen (numbuf));
932 xfree (pin);
933 }
934 }
935 else if ((s = has_leading_keyword (line, "CHECKPIN")))
936 {
937 char *errtext = NULL;
938 size_t errtextlen;
939
940 if (!opt.enforce_passphrase_constraints)
941 {
942 log_error ("unexpected inquiry 'CHECKPIN' without enforced "
943 "passphrase constraints\n");
944 err = gpg_error (GPG_ERR_ASS_UNEXPECTED_CMD);
945 goto leave;
946 }
947
948 pin = unescape_passphrase_string (s);
949 if (!pin)
950 err = gpg_error_from_syserror ();
951 else
952 {
953 if (!is_generated_pin (parm, pin)
954 && check_passphrase_constraints (NULL, pin,parm->flags, &errtext))
955 {
956 if (errtext)
957 {
958 /* Unescape the percent-escaped errtext because
959 assuan_send_data escapes it again. */
960 errtextlen = percent_unescape_inplace (errtext, 0);
961 err = assuan_send_data (parm->ctx, errtext, errtextlen);
962 }
963 else
964 {
965 log_error ("passphrase check failed without error text\n");
966 err = gpg_error (GPG_ERR_GENERAL);
967 }
968 }
969 else
970 {
971 err = assuan_send_data (parm->ctx, NULL, 0);
972 }
973 xfree (errtext);
974 xfree (pin);
975 }
976 }
977 else if ((s = has_leading_keyword (line, "GENPIN")))
978 {
979 int wasconf;
980
981 parm->genpinhash_valid = 0;
982 pin = generate_pin ();
983 if (!pin)
984 {
985 log_error ("failed to generate a passphrase\n");
986 err = gpg_error (GPG_ERR_GENERAL);
987 goto leave;
988 }
989 wasconf = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
990 assuan_begin_confidential (parm->ctx);
991 err = assuan_send_data (parm->ctx, pin, strlen (pin));
992 if (!wasconf)
993 assuan_end_confidential (parm->ctx);
994 gcry_md_hash_buffer (GCRY_MD_SHA256, parm->genpinhash, pin, strlen (pin));
995 parm->genpinhash_valid = 1;
996 xfree (pin);
997 }
998 else
999 {
1000 log_error ("unsupported inquiry '%s' from pinentry\n", line);
1001 err = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
1002 }
1003
1004 leave:
1005 return err;
1006 }
1007
1008
1009 /* Helper to setup pinentry for genpin action. */
1010 static gpg_error_t
setup_genpin(ctrl_t ctrl)1011 setup_genpin (ctrl_t ctrl)
1012 {
1013 gpg_error_t err;
1014 char line[ASSUAN_LINELENGTH];
1015 char *tmpstr, *tmpstr2;
1016 const char *tooltip;
1017
1018 (void)ctrl;
1019
1020 /* TRANSLATORS: This string is displayed by Pinentry as the label
1021 for generating a passphrase. */
1022 tmpstr = try_percent_escape (L_("Suggest"), "\t\r\n\f\v");
1023 snprintf (line, DIM(line), "SETGENPIN %s", tmpstr? tmpstr:"");
1024 xfree (tmpstr);
1025 err = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1026 if (gpg_err_code (err) == 103 /*(Old assuan error code)*/
1027 || gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD)
1028 ; /* Ignore Unknown Command from old Pinentry versions. */
1029 else if (err)
1030 return err;
1031
1032 tmpstr2 = gnupg_get_help_string ("pinentry.genpin.tooltip", 0);
1033 if (tmpstr2)
1034 tooltip = tmpstr2;
1035 else
1036 {
1037 /* TRANSLATORS: This string is a tooltip, shown by pinentry when
1038 hovering over the generate button. Please use an appropriate
1039 string to describe what this is about. The length of the
1040 tooltip is limited to about 900 characters. If you do not
1041 translate this entry, a default English text (see source)
1042 will be used. The strcmp thingy is there to detect a
1043 non-translated string. */
1044 tooltip = L_("pinentry.genpin.tooltip");
1045 if (!strcmp ("pinentry.genpin.tooltip", tooltip))
1046 tooltip = "Suggest a random passphrase.";
1047 }
1048 tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
1049 xfree (tmpstr2);
1050 snprintf (line, DIM(line), "SETGENPIN_TT %s", tmpstr? tmpstr:"");
1051 xfree (tmpstr);
1052 err = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1053 if (gpg_err_code (err) == 103 /*(Old assuan error code)*/
1054 || gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD)
1055 ; /* Ignore Unknown Command from old pinentry versions. */
1056 else if (err)
1057 return err;
1058
1059 return 0;
1060 }
1061
1062
1063 /* Helper to setup pinentry for formatted passphrase. */
1064 static gpg_error_t
setup_formatted_passphrase(ctrl_t ctrl)1065 setup_formatted_passphrase (ctrl_t ctrl)
1066 {
1067 static const struct { const char *key, *help_id, *value; } tbl[] = {
1068 /* TRANSLATORS: This is a text shown by pinentry if the option
1069 for formatted passphrase is enabled. The length is
1070 limited to about 900 characters. */
1071 { "hint", "pinentry.formatted_passphrase.hint",
1072 N_("Note: The blanks are not part of the passphrase.") },
1073 { NULL, NULL }
1074 };
1075
1076 gpg_error_t rc;
1077 char line[ASSUAN_LINELENGTH];
1078 int idx;
1079 char *tmpstr;
1080 const char *s;
1081 char *escapedstr;
1082
1083 (void)ctrl;
1084
1085 if (opt.pinentry_formatted_passphrase)
1086 {
1087 snprintf (line, DIM(line), "OPTION formatted-passphrase");
1088 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL,
1089 NULL);
1090 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
1091 return rc;
1092
1093 for (idx=0; tbl[idx].key; idx++)
1094 {
1095 tmpstr = gnupg_get_help_string (tbl[idx].help_id, 0);
1096 if (tmpstr)
1097 s = tmpstr;
1098 else
1099 s = L_(tbl[idx].value);
1100 escapedstr = try_percent_escape (s, "\t\r\n\f\v");
1101 xfree (tmpstr);
1102 if (escapedstr && *escapedstr)
1103 {
1104 snprintf (line, DIM(line), "OPTION formatted-passphrase-%s=%s",
1105 tbl[idx].key, escapedstr);
1106 rc = assuan_transact (entry_ctx, line,
1107 NULL, NULL, NULL, NULL, NULL, NULL);
1108 }
1109 else
1110 rc = 0;
1111 xfree (escapedstr);
1112 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
1113 return rc;
1114 }
1115 }
1116
1117 return 0;
1118 }
1119
1120
1121 /* Helper to setup pinentry for enforced passphrase constraints. */
1122 static gpg_error_t
setup_enforced_constraints(ctrl_t ctrl)1123 setup_enforced_constraints (ctrl_t ctrl)
1124 {
1125 static const struct { const char *key, *help_id, *value; } tbl[] = {
1126 { "hint-short", "pinentry.constraints.hint.short", NULL },
1127 { "hint-long", "pinentry.constraints.hint.long", NULL },
1128 /* TRANSLATORS: This is a text shown by pinentry as title of a dialog
1129 telling the user that the entered new passphrase does not satisfy
1130 the passphrase constraints. Please keep it short. */
1131 { "error-title", NULL, N_("Passphrase Not Allowed") },
1132 { NULL, NULL }
1133 };
1134
1135 gpg_error_t rc;
1136 char line[ASSUAN_LINELENGTH];
1137 int idx;
1138 char *tmpstr;
1139 const char *s;
1140 char *escapedstr;
1141
1142 (void)ctrl;
1143
1144 if (opt.enforce_passphrase_constraints)
1145 {
1146 snprintf (line, DIM(line), "OPTION constraints-enforce");
1147 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL,
1148 NULL);
1149 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
1150 return rc;
1151
1152 for (idx=0; tbl[idx].key; idx++)
1153 {
1154 tmpstr = gnupg_get_help_string (tbl[idx].help_id, 0);
1155 if (tmpstr)
1156 s = tmpstr;
1157 else if (tbl[idx].value)
1158 s = L_(tbl[idx].value);
1159 else
1160 {
1161 log_error ("no help string found for %s\n", tbl[idx].help_id);
1162 continue;
1163 }
1164 escapedstr = try_percent_escape (s, "\t\r\n\f\v");
1165 xfree (tmpstr);
1166 if (escapedstr && *escapedstr)
1167 {
1168 snprintf (line, DIM(line), "OPTION constraints-%s=%s",
1169 tbl[idx].key, escapedstr);
1170 rc = assuan_transact (entry_ctx, line,
1171 NULL, NULL, NULL, NULL, NULL, NULL);
1172 }
1173 else
1174 rc = 0; /* Ignore an empty string (would give an IPC error). */
1175 xfree (escapedstr);
1176 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
1177 return rc;
1178 }
1179 }
1180
1181 return 0;
1182 }
1183
1184
1185 /* Helper for agent_askpin and agent_get_passphrase. */
1186 static gpg_error_t
setup_qualitybar(ctrl_t ctrl)1187 setup_qualitybar (ctrl_t ctrl)
1188 {
1189 int rc;
1190 char line[ASSUAN_LINELENGTH];
1191 char *tmpstr, *tmpstr2;
1192 const char *tooltip;
1193
1194 (void)ctrl;
1195
1196 /* TRANSLATORS: This string is displayed by Pinentry as the label
1197 for the quality bar. */
1198 tmpstr = try_percent_escape (L_("Quality:"), "\t\r\n\f\v");
1199 snprintf (line, DIM(line), "SETQUALITYBAR %s", tmpstr? tmpstr:"");
1200 xfree (tmpstr);
1201 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1202 if (rc == 103 /*(Old assuan error code)*/
1203 || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1204 ; /* Ignore Unknown Command from old Pinentry versions. */
1205 else if (rc)
1206 return rc;
1207
1208 tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
1209 if (tmpstr2)
1210 tooltip = tmpstr2;
1211 else
1212 {
1213 /* TRANSLATORS: This string is a tooltip, shown by pinentry when
1214 hovering over the quality bar. Please use an appropriate
1215 string to describe what this is about. The length of the
1216 tooltip is limited to about 900 characters. If you do not
1217 translate this entry, a default english text (see source)
1218 will be used. */
1219 tooltip = L_("pinentry.qualitybar.tooltip");
1220 if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
1221 tooltip = ("The quality of the text entered above.\n"
1222 "Please ask your administrator for "
1223 "details about the criteria.");
1224 }
1225 tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
1226 xfree (tmpstr2);
1227 snprintf (line, DIM(line), "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
1228 xfree (tmpstr);
1229 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1230 if (rc == 103 /*(Old assuan error code)*/
1231 || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1232 ; /* Ignore Unknown Command from old pinentry versions. */
1233 else if (rc)
1234 return rc;
1235
1236 return 0;
1237 }
1238
1239 /* Check the button_info line for a close action. Also check for the
1240 PIN_REPEATED flag. */
1241 static gpg_error_t
pinentry_status_cb(void * opaque,const char * line)1242 pinentry_status_cb (void *opaque, const char *line)
1243 {
1244 unsigned int *flag = opaque;
1245 const char *args;
1246
1247 if ((args = has_leading_keyword (line, "BUTTON_INFO")))
1248 {
1249 if (!strcmp (args, "close"))
1250 *flag |= PINENTRY_STATUS_CLOSE_BUTTON;
1251 }
1252 else if (has_leading_keyword (line, "PIN_REPEATED"))
1253 {
1254 *flag |= PINENTRY_STATUS_PIN_REPEATED;
1255 }
1256 else if (has_leading_keyword (line, "PASSWORD_FROM_CACHE"))
1257 {
1258 *flag |= PINENTRY_STATUS_PASSWORD_FROM_CACHE;
1259 }
1260
1261 return 0;
1262 }
1263
1264
1265 /* Build a SETDESC command line. This is a dedicated function so that
1266 * it can remove control characters which are not supported by the
1267 * current Pinentry. */
1268 static void
build_cmd_setdesc(char * line,size_t linelen,const char * desc)1269 build_cmd_setdesc (char *line, size_t linelen, const char *desc)
1270 {
1271 char *src, *dst;
1272
1273 snprintf (line, linelen, "SETDESC %s", desc);
1274 if (!entry_features.tabbing)
1275 {
1276 /* Remove RS and US. */
1277 for (src=dst=line; *src; src++)
1278 if (!strchr ("\x1e\x1f", *src))
1279 *dst++ = *src;
1280 *dst = 0;
1281 }
1282 }
1283
1284
1285
1286 /* Watch the socket's EOF condition, while checking finish of
1287 foreground thread. When EOF condition is detected, terminate
1288 the pinentry process behind the assuan pipe.
1289 */
1290 static void *
watch_sock(void * arg)1291 watch_sock (void *arg)
1292 {
1293 pid_t pid = assuan_get_pid (entry_ctx);
1294
1295 while (1)
1296 {
1297 int err;
1298 fd_set fdset;
1299 struct timeval timeout = { 0, 500000 };
1300 gnupg_fd_t sock = *(gnupg_fd_t *)arg;
1301
1302 if (sock == GNUPG_INVALID_FD)
1303 return NULL;
1304
1305 FD_ZERO (&fdset);
1306 FD_SET (FD2INT (sock), &fdset);
1307 err = npth_select (FD2INT (sock)+1, &fdset, NULL, NULL, &timeout);
1308
1309 if (err < 0)
1310 {
1311 if (errno == EINTR)
1312 continue;
1313 else
1314 return NULL;
1315 }
1316
1317 /* Possibly, it's EOF. */
1318 if (err > 0)
1319 break;
1320 }
1321
1322 if (pid == (pid_t)(-1))
1323 ; /* No pid available can't send a kill. */
1324 #ifdef HAVE_W32_SYSTEM
1325 /* Older versions of assuan set PID to 0 on Windows to indicate an
1326 invalid value. */
1327 else if (pid != (pid_t) INVALID_HANDLE_VALUE && pid != 0)
1328 TerminateProcess ((HANDLE)pid, 1);
1329 #else
1330 else if (pid > 0)
1331 kill (pid, SIGINT);
1332 #endif
1333
1334 return NULL;
1335 }
1336
1337
1338 static gpg_error_t
watch_sock_start(gnupg_fd_t * sock_p,npth_t * thread_p)1339 watch_sock_start (gnupg_fd_t *sock_p, npth_t *thread_p)
1340 {
1341 npth_attr_t tattr;
1342 int err;
1343
1344 err = npth_attr_init (&tattr);
1345 if (err)
1346 {
1347 log_error ("do_getpin: error npth_attr_init: %s\n", strerror (err));
1348 return gpg_error_from_errno (err);
1349 }
1350 npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1351
1352 err = npth_create (thread_p, &tattr, watch_sock, sock_p);
1353 npth_attr_destroy (&tattr);
1354 if (err)
1355 {
1356 log_error ("do_getpin: error spawning thread: %s\n", strerror (err));
1357 return gpg_error_from_errno (err);
1358 }
1359
1360 return 0;
1361 }
1362
1363 static void
watch_sock_end(gnupg_fd_t * sock_p,npth_t * thread_p)1364 watch_sock_end (gnupg_fd_t *sock_p, npth_t *thread_p)
1365 {
1366 int err;
1367
1368 *sock_p = GNUPG_INVALID_FD;
1369 err = npth_join (*thread_p, NULL);
1370 if (err)
1371 log_error ("watch_sock_end: error joining thread: %s\n", strerror (err));
1372 }
1373
1374
1375 /* Ask pinentry to get a pin by "GETPIN" command, spawning a thread
1376 detecting the socket's EOF.
1377 */
1378 static gpg_error_t
do_getpin(ctrl_t ctrl,struct entry_parm_s * parm)1379 do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
1380 {
1381 gpg_error_t rc;
1382 gnupg_fd_t sock_watched = ctrl->thread_startup.fd;
1383 npth_t thread;
1384 int wasconf;
1385 struct inq_cb_parm_s inq_cb_parm;
1386
1387 rc = watch_sock_start (&sock_watched, &thread);
1388 if (rc)
1389 return rc;
1390
1391 inq_cb_parm.ctx = entry_ctx;
1392 inq_cb_parm.flags = parm->constraints_flags;
1393 inq_cb_parm.genpinhash_valid = 0;
1394
1395 wasconf = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
1396 assuan_begin_confidential (entry_ctx);
1397 rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, parm,
1398 inq_cb, &inq_cb_parm,
1399 pinentry_status_cb, &parm->status);
1400 if (!wasconf)
1401 assuan_end_confidential (entry_ctx);
1402
1403 if (!rc && parm->buffer && is_generated_pin (&inq_cb_parm, parm->buffer))
1404 parm->status |= PINENTRY_STATUS_PASSWORD_GENERATED;
1405 else
1406 parm->status &= ~PINENTRY_STATUS_PASSWORD_GENERATED;
1407
1408 /* Most pinentries out in the wild return the old Assuan error code
1409 for canceled which gets translated to an assuan Cancel error and
1410 not to the code for a user cancel. Fix this here. */
1411 if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1412 rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1413 /* Change error code in case the window close button was clicked
1414 to cancel the operation. */
1415 if ((parm->status & PINENTRY_STATUS_CLOSE_BUTTON)
1416 && gpg_err_code (rc) == GPG_ERR_CANCELED)
1417 rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
1418
1419 watch_sock_end (&sock_watched, &thread);
1420
1421 return rc;
1422 }
1423
1424 /* Call the Entry and ask for the PIN. We do check for a valid PIN
1425 number here and repeat it as long as we have invalid formed
1426 numbers. KEYINFO and CACHE_MODE are used to tell pinentry something
1427 about the key. */
1428 gpg_error_t
agent_askpin(ctrl_t ctrl,const char * desc_text,const char * prompt_text,const char * initial_errtext,struct pin_entry_info_s * pininfo,const char * keyinfo,cache_mode_t cache_mode)1429 agent_askpin (ctrl_t ctrl,
1430 const char *desc_text, const char *prompt_text,
1431 const char *initial_errtext,
1432 struct pin_entry_info_s *pininfo,
1433 const char *keyinfo, cache_mode_t cache_mode)
1434 {
1435 gpg_error_t rc;
1436 char line[ASSUAN_LINELENGTH];
1437 struct entry_parm_s parm;
1438 const char *errtext = NULL;
1439 int is_pin = 0;
1440 int is_generated;
1441
1442 if (opt.batch)
1443 return 0; /* fixme: we should return BAD PIN */
1444
1445 if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1446 {
1447 if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1448 return gpg_error (GPG_ERR_CANCELED);
1449 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1450 {
1451 unsigned char *passphrase;
1452 size_t size;
1453
1454 *pininfo->pin = 0; /* Reset the PIN. */
1455 rc = pinentry_loopback (ctrl, "PASSPHRASE", &passphrase, &size,
1456 pininfo->max_length - 1);
1457 if (rc)
1458 return rc;
1459
1460 memcpy(&pininfo->pin, passphrase, size);
1461 xfree(passphrase);
1462 pininfo->pin[size] = 0;
1463 if (pininfo->check_cb)
1464 {
1465 /* More checks by utilizing the optional callback. */
1466 pininfo->cb_errtext = NULL;
1467 rc = pininfo->check_cb (pininfo);
1468 }
1469 return rc;
1470 }
1471 return gpg_error(GPG_ERR_NO_PIN_ENTRY);
1472 }
1473
1474 if (!pininfo || pininfo->max_length < 1)
1475 return gpg_error (GPG_ERR_INV_VALUE);
1476 if (!desc_text && pininfo->min_digits)
1477 desc_text = L_("Please enter your PIN, so that the secret key "
1478 "can be unlocked for this session");
1479 else if (!desc_text)
1480 desc_text = L_("Please enter your passphrase, so that the secret key "
1481 "can be unlocked for this session");
1482
1483 if (prompt_text)
1484 is_pin = !!strstr (prompt_text, "PIN");
1485 else
1486 is_pin = desc_text && strstr (desc_text, "PIN");
1487
1488 rc = start_pinentry (ctrl);
1489 if (rc)
1490 return rc;
1491
1492 /* If we have a KEYINFO string and are normal, user, or ssh cache
1493 mode, we tell that the Pinentry so it may use it for own caching
1494 purposes. Most pinentries won't have this implemented and thus
1495 we do not error out in this case. */
1496 if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1497 || cache_mode == CACHE_MODE_USER
1498 || cache_mode == CACHE_MODE_SSH))
1499 snprintf (line, DIM(line), "SETKEYINFO %c/%s",
1500 cache_mode == CACHE_MODE_USER? 'u' :
1501 cache_mode == CACHE_MODE_SSH? 's' : 'n',
1502 keyinfo);
1503 else
1504 snprintf (line, DIM(line), "SETKEYINFO --clear");
1505
1506 rc = assuan_transact (entry_ctx, line,
1507 NULL, NULL, NULL, NULL, NULL, NULL);
1508 if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1509 return unlock_pinentry (ctrl, rc);
1510
1511 build_cmd_setdesc (line, DIM(line), desc_text);
1512 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1513 if (rc)
1514 return unlock_pinentry (ctrl, rc);
1515
1516 snprintf (line, DIM(line), "SETPROMPT %s",
1517 prompt_text? prompt_text : is_pin? L_("PIN:") : L_("Passphrase:"));
1518 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1519 if (rc)
1520 return unlock_pinentry (ctrl, rc);
1521
1522 /* If a passphrase quality indicator has been requested and a
1523 minimum passphrase length has not been disabled, send the command
1524 to the pinentry. */
1525 if (pininfo->with_qualitybar && opt.min_passphrase_len )
1526 {
1527 rc = setup_qualitybar (ctrl);
1528 if (rc)
1529 return unlock_pinentry (ctrl, rc);
1530 }
1531
1532 if (initial_errtext)
1533 {
1534 snprintf (line, DIM(line), "SETERROR %s", initial_errtext);
1535 rc = assuan_transact (entry_ctx, line,
1536 NULL, NULL, NULL, NULL, NULL, NULL);
1537 if (rc)
1538 return unlock_pinentry (ctrl, rc);
1539 }
1540
1541 if (pininfo->with_repeat)
1542 {
1543 snprintf (line, DIM(line), "SETREPEATERROR %s",
1544 L_("does not match - try again"));
1545 rc = assuan_transact (entry_ctx, line,
1546 NULL, NULL, NULL, NULL, NULL, NULL);
1547 if (rc)
1548 pininfo->with_repeat = 0; /* Pinentry does not support it. */
1549 }
1550 pininfo->repeat_okay = 0;
1551 pininfo->status = 0;
1552
1553 for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
1554 {
1555 memset (&parm, 0, sizeof parm);
1556 parm.size = pininfo->max_length;
1557 *pininfo->pin = 0; /* Reset the PIN. */
1558 parm.buffer = (unsigned char*)pininfo->pin;
1559 parm.constraints_flags = pininfo->constraints_flags;
1560
1561 if (errtext)
1562 {
1563 /* TRANSLATORS: The string is appended to an error message in
1564 the pinentry. The %s is the actual error message, the
1565 two %d give the current and maximum number of tries. */
1566 snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"),
1567 errtext, pininfo->failed_tries+1, pininfo->max_tries);
1568 rc = assuan_transact (entry_ctx, line,
1569 NULL, NULL, NULL, NULL, NULL, NULL);
1570 if (rc)
1571 return unlock_pinentry (ctrl, rc);
1572 errtext = NULL;
1573 }
1574
1575 if (pininfo->with_repeat)
1576 {
1577 snprintf (line, DIM(line), "SETREPEAT %s", L_("Repeat:"));
1578 rc = assuan_transact (entry_ctx, line,
1579 NULL, NULL, NULL, NULL, NULL, NULL);
1580 if (rc)
1581 return unlock_pinentry (ctrl, rc);
1582 }
1583
1584 rc = do_getpin (ctrl, &parm);
1585 pininfo->status = parm.status;
1586 is_generated = !!(parm.status & PINENTRY_STATUS_PASSWORD_GENERATED);
1587
1588 if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
1589 errtext = is_pin? L_("PIN too long")
1590 : L_("Passphrase too long");
1591 else if (rc)
1592 return unlock_pinentry (ctrl, rc);
1593
1594 if (!errtext && pininfo->min_digits && !is_generated)
1595 {
1596 /* do some basic checks on the entered PIN. */
1597 if (!all_digitsp (pininfo->pin))
1598 errtext = L_("Invalid characters in PIN");
1599 else if (pininfo->max_digits
1600 && strlen (pininfo->pin) > pininfo->max_digits)
1601 errtext = L_("PIN too long");
1602 else if (strlen (pininfo->pin) < pininfo->min_digits)
1603 errtext = L_("PIN too short");
1604 }
1605
1606 if (!errtext && pininfo->check_cb && !is_generated)
1607 {
1608 /* More checks by utilizing the optional callback. */
1609 pininfo->cb_errtext = NULL;
1610 rc = pininfo->check_cb (pininfo);
1611 /* When pinentry cache causes an error, return now. */
1612 if (rc
1613 && (pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1614 return unlock_pinentry (ctrl, rc);
1615
1616 if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE)
1617 {
1618 if (pininfo->cb_errtext)
1619 errtext = pininfo->cb_errtext;
1620 else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1621 || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
1622 errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase"));
1623 }
1624 else if (rc)
1625 return unlock_pinentry (ctrl, rc);
1626 }
1627
1628 if (!errtext)
1629 {
1630 if (pininfo->with_repeat
1631 && (pininfo->status & PINENTRY_STATUS_PIN_REPEATED))
1632 pininfo->repeat_okay = 1;
1633 return unlock_pinentry (ctrl, 0); /* okay, got a PIN or passphrase */
1634 }
1635
1636 if ((pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1637 {
1638 /* The password was read from the cache. Don't count this
1639 against the retry count. */
1640 pininfo->failed_tries --;
1641 }
1642 }
1643
1644 return unlock_pinentry (ctrl, gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
1645 : GPG_ERR_BAD_PASSPHRASE));
1646 }
1647
1648
1649
1650 /* Ask for the passphrase using the supplied arguments. The returned
1651 passphrase needs to be freed by the caller. PININFO is optional
1652 and can be used to have constraints checking while the pinentry
1653 dialog is open (like what we do in agent_askpin). This is very
1654 similar to agent_askpin and we should eventually merge the two
1655 functions. */
1656 int
agent_get_passphrase(ctrl_t ctrl,char ** retpass,const char * desc,const char * prompt,const char * errtext,int with_qualitybar,const char * keyinfo,cache_mode_t cache_mode,struct pin_entry_info_s * pininfo)1657 agent_get_passphrase (ctrl_t ctrl,
1658 char **retpass, const char *desc, const char *prompt,
1659 const char *errtext, int with_qualitybar,
1660 const char *keyinfo, cache_mode_t cache_mode,
1661 struct pin_entry_info_s *pininfo)
1662 {
1663 int rc;
1664 int is_pin;
1665 int is_generated;
1666 char line[ASSUAN_LINELENGTH];
1667 struct entry_parm_s parm;
1668
1669 *retpass = NULL;
1670 if (opt.batch)
1671 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
1672
1673 if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1674 {
1675 unsigned char *passphrase;
1676 size_t size;
1677
1678 if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1679 return gpg_error (GPG_ERR_CANCELED);
1680
1681 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK && pininfo)
1682 {
1683 *pininfo->pin = 0; /* Reset the PIN. */
1684 rc = pinentry_loopback (ctrl, "PASSPHRASE",
1685 &passphrase, &size,
1686 pininfo->max_length - 1);
1687 if (rc)
1688 return rc;
1689
1690 memcpy (&pininfo->pin, passphrase, size);
1691 wipememory (passphrase, size);
1692 xfree (passphrase);
1693 pininfo->pin[size] = 0;
1694 if (pininfo->check_cb)
1695 {
1696 /* More checks by utilizing the optional callback. */
1697 pininfo->cb_errtext = NULL;
1698 rc = pininfo->check_cb (pininfo);
1699 }
1700 return rc;
1701
1702 }
1703 else if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1704 {
1705 /* Legacy variant w/o PININFO. */
1706 return pinentry_loopback (ctrl, "PASSPHRASE",
1707 (unsigned char **)retpass, &size,
1708 MAX_PASSPHRASE_LEN);
1709 }
1710
1711 return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1712 }
1713
1714 rc = start_pinentry (ctrl);
1715 if (rc)
1716 return rc;
1717
1718 /* Set IS_PIN and if needed a default prompt. */
1719 if (prompt)
1720 is_pin = !!strstr (prompt, "PIN");
1721 else
1722 {
1723 is_pin = desc && strstr (desc, "PIN");
1724 prompt = is_pin? L_("PIN:"): L_("Passphrase:");
1725 }
1726
1727 /* If we have a KEYINFO string and are normal, user, or ssh cache
1728 mode, we tell that the Pinentry so it may use it for own caching
1729 purposes. Most pinentries won't have this implemented and thus
1730 we do not error out in this case. */
1731 if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1732 || cache_mode == CACHE_MODE_USER
1733 || cache_mode == CACHE_MODE_SSH))
1734 snprintf (line, DIM(line), "SETKEYINFO %c/%s",
1735 cache_mode == CACHE_MODE_USER? 'u' :
1736 cache_mode == CACHE_MODE_SSH? 's' : 'n',
1737 keyinfo);
1738 else
1739 snprintf (line, DIM(line), "SETKEYINFO --clear");
1740
1741 rc = assuan_transact (entry_ctx, line,
1742 NULL, NULL, NULL, NULL, NULL, NULL);
1743 if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1744 return unlock_pinentry (ctrl, rc);
1745
1746 if (desc)
1747 build_cmd_setdesc (line, DIM(line), desc);
1748 else
1749 snprintf (line, DIM(line), "RESET");
1750 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1751 if (rc)
1752 return unlock_pinentry (ctrl, rc);
1753
1754 snprintf (line, DIM(line), "SETPROMPT %s", prompt);
1755 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1756 if (rc)
1757 return unlock_pinentry (ctrl, rc);
1758
1759 if ((with_qualitybar || (pininfo && pininfo->with_qualitybar))
1760 && opt.min_passphrase_len)
1761 {
1762 rc = setup_qualitybar (ctrl);
1763 if (rc)
1764 return unlock_pinentry (ctrl, rc);
1765 }
1766
1767 if (errtext)
1768 {
1769 snprintf (line, DIM(line), "SETERROR %s", errtext);
1770 rc = assuan_transact (entry_ctx, line,
1771 NULL, NULL, NULL, NULL, NULL, NULL);
1772 if (rc)
1773 return unlock_pinentry (ctrl, rc);
1774 }
1775
1776 rc = setup_formatted_passphrase (ctrl);
1777 if (rc)
1778 return unlock_pinentry (ctrl, rc);
1779
1780 if (!pininfo)
1781 {
1782 /* Legacy method without PININFO. */
1783 memset (&parm, 0, sizeof parm);
1784 parm.size = ASSUAN_LINELENGTH/2 - 5;
1785 parm.buffer = gcry_malloc_secure (parm.size+10);
1786 if (!parm.buffer)
1787 return unlock_pinentry (ctrl, out_of_core ());
1788
1789 rc = do_getpin (ctrl, &parm);
1790 if (rc)
1791 xfree (parm.buffer);
1792 else
1793 *retpass = parm.buffer;
1794 return unlock_pinentry (ctrl, rc);
1795 }
1796
1797 /* We got PININFO. */
1798
1799 if (pininfo->with_repeat)
1800 {
1801 snprintf (line, DIM(line), "SETREPEATERROR %s",
1802 L_("does not match - try again"));
1803 rc = assuan_transact (entry_ctx, line,
1804 NULL, NULL, NULL, NULL, NULL, NULL);
1805 if (rc)
1806 pininfo->with_repeat = 0; /* Pinentry does not support it. */
1807
1808 (void)setup_genpin (ctrl);
1809
1810 rc = setup_enforced_constraints (ctrl);
1811 if (rc)
1812 return unlock_pinentry (ctrl, rc);
1813 }
1814 pininfo->repeat_okay = 0;
1815 pininfo->status = 0;
1816
1817 for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
1818 {
1819 memset (&parm, 0, sizeof parm);
1820 parm.constraints_flags = pininfo->constraints_flags;
1821 parm.size = pininfo->max_length;
1822 parm.buffer = (unsigned char*)pininfo->pin;
1823 *pininfo->pin = 0; /* Reset the PIN. */
1824
1825 if (errtext)
1826 {
1827 /* TRANSLATORS: The string is appended to an error message in
1828 the pinentry. The %s is the actual error message, the
1829 two %d give the current and maximum number of tries. */
1830 snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"),
1831 errtext, pininfo->failed_tries+1, pininfo->max_tries);
1832 rc = assuan_transact (entry_ctx, line,
1833 NULL, NULL, NULL, NULL, NULL, NULL);
1834 if (rc)
1835 return unlock_pinentry (ctrl, rc);
1836 errtext = NULL;
1837 }
1838
1839 if (pininfo->with_repeat)
1840 {
1841 snprintf (line, DIM(line), "SETREPEAT %s", L_("Repeat:"));
1842 rc = assuan_transact (entry_ctx, line,
1843 NULL, NULL, NULL, NULL, NULL, NULL);
1844 if (rc)
1845 return unlock_pinentry (ctrl, rc);
1846 }
1847
1848 rc = do_getpin (ctrl, &parm);
1849 pininfo->status = parm.status;
1850 is_generated = !!(parm.status & PINENTRY_STATUS_PASSWORD_GENERATED);
1851
1852 if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
1853 errtext = is_pin? L_("PIN too long")
1854 : L_("Passphrase too long");
1855 else if (rc)
1856 return unlock_pinentry (ctrl, rc);
1857
1858 if (!errtext && pininfo->min_digits && !is_generated)
1859 {
1860 /* do some basic checks on the entered PIN. */
1861 if (!all_digitsp (pininfo->pin))
1862 errtext = L_("Invalid characters in PIN");
1863 else if (pininfo->max_digits
1864 && strlen (pininfo->pin) > pininfo->max_digits)
1865 errtext = L_("PIN too long");
1866 else if (strlen (pininfo->pin) < pininfo->min_digits)
1867 errtext = L_("PIN too short");
1868 }
1869
1870 if (!errtext && pininfo->check_cb && !is_generated)
1871 {
1872 /* More checks by utilizing the optional callback. */
1873 pininfo->cb_errtext = NULL;
1874 rc = pininfo->check_cb (pininfo);
1875 /* When pinentry cache causes an error, return now. */
1876 if (rc && (pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1877 return unlock_pinentry (ctrl, rc);
1878
1879 if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE)
1880 {
1881 if (pininfo->cb_errtext)
1882 errtext = pininfo->cb_errtext;
1883 else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1884 || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
1885 errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase"));
1886 }
1887 else if (rc)
1888 return unlock_pinentry (ctrl, rc);
1889 }
1890
1891 if (!errtext)
1892 {
1893 if (pininfo->with_repeat
1894 && (pininfo->status & PINENTRY_STATUS_PIN_REPEATED))
1895 pininfo->repeat_okay = 1;
1896 return unlock_pinentry (ctrl, 0); /* okay, got a PIN or passphrase */
1897 }
1898
1899 if ((pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1900 {
1901 /* The password was read from the Pinentry's own cache.
1902 Don't count this against the retry count. */
1903 pininfo->failed_tries--;
1904 }
1905 }
1906
1907 return unlock_pinentry (ctrl, gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
1908 : GPG_ERR_BAD_PASSPHRASE));
1909 }
1910
1911
1912
1913 /* Pop up the PIN-entry, display the text and the prompt and ask the
1914 user to confirm this. We return 0 for success, ie. the user
1915 confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
1916 other error. If WITH_CANCEL it true an extra cancel button is
1917 displayed to allow the user to easily return a GPG_ERR_CANCELED.
1918 if the Pinentry does not support this, the user can still cancel by
1919 closing the Pinentry window. */
1920 int
agent_get_confirmation(ctrl_t ctrl,const char * desc,const char * ok,const char * notok,int with_cancel)1921 agent_get_confirmation (ctrl_t ctrl,
1922 const char *desc, const char *ok,
1923 const char *notok, int with_cancel)
1924 {
1925 int rc;
1926 char line[ASSUAN_LINELENGTH];
1927
1928 if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1929 {
1930 if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1931 return gpg_error (GPG_ERR_CANCELED);
1932
1933 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1934 return pinentry_loopback_confirm (ctrl, desc, 1, ok, notok);
1935
1936 return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1937 }
1938
1939 rc = start_pinentry (ctrl);
1940 if (rc)
1941 return rc;
1942
1943 if (desc)
1944 build_cmd_setdesc (line, DIM(line), desc);
1945 else
1946 snprintf (line, DIM(line), "RESET");
1947 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1948 /* Most pinentries out in the wild return the old Assuan error code
1949 for canceled which gets translated to an assuan Cancel error and
1950 not to the code for a user cancel. Fix this here. */
1951 if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1952 rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1953
1954 if (rc)
1955 return unlock_pinentry (ctrl, rc);
1956
1957 if (ok)
1958 {
1959 snprintf (line, DIM(line), "SETOK %s", ok);
1960 rc = assuan_transact (entry_ctx,
1961 line, NULL, NULL, NULL, NULL, NULL, NULL);
1962 if (rc)
1963 return unlock_pinentry (ctrl, rc);
1964 }
1965 if (notok)
1966 {
1967 /* Try to use the newer NOTOK feature if a cancel button is
1968 requested. If no cancel button is requested we keep on using
1969 the standard cancel. */
1970 if (with_cancel)
1971 {
1972 snprintf (line, DIM(line), "SETNOTOK %s", notok);
1973 rc = assuan_transact (entry_ctx,
1974 line, NULL, NULL, NULL, NULL, NULL, NULL);
1975 }
1976 else
1977 rc = GPG_ERR_ASS_UNKNOWN_CMD;
1978
1979 if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1980 {
1981 snprintf (line, DIM(line), "SETCANCEL %s", notok);
1982 rc = assuan_transact (entry_ctx, line,
1983 NULL, NULL, NULL, NULL, NULL, NULL);
1984 }
1985 if (rc)
1986 return unlock_pinentry (ctrl, rc);
1987 }
1988
1989 {
1990 gnupg_fd_t sock_watched = ctrl->thread_startup.fd;
1991 npth_t thread;
1992
1993 rc = watch_sock_start (&sock_watched, &thread);
1994 if (!rc)
1995 {
1996 rc = assuan_transact (entry_ctx, "CONFIRM",
1997 NULL, NULL, NULL, NULL, NULL, NULL);
1998 if (rc && gpg_err_source (rc)
1999 && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
2000 rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
2001
2002 watch_sock_end (&sock_watched, &thread);
2003 }
2004
2005 return unlock_pinentry (ctrl, rc);
2006 }
2007 }
2008
2009
2010
2011 /* The thread running the popup message. */
2012 static void *
popup_message_thread(void * arg)2013 popup_message_thread (void *arg)
2014 {
2015 gpg_error_t rc;
2016 gnupg_fd_t sock_watched = *(gnupg_fd_t *)arg;
2017 npth_t thread;
2018
2019 rc = watch_sock_start (&sock_watched, &thread);
2020 if (rc)
2021 return NULL;
2022
2023 /* We use the --one-button hack instead of the MESSAGE command to
2024 allow the use of old Pinentries. Those old Pinentries will then
2025 show an additional Cancel button but that is mostly a visual
2026 annoyance. */
2027 assuan_transact (entry_ctx, "CONFIRM --one-button",
2028 NULL, NULL, NULL, NULL, NULL, NULL);
2029 watch_sock_end (&sock_watched, &thread);
2030 popup_finished = 1;
2031 return NULL;
2032 }
2033
2034
2035 /* Pop up a message window similar to the confirm one but keep it open
2036 until agent_popup_message_stop has been called. It is crucial for
2037 the caller to make sure that the stop function gets called as soon
2038 as the message is not anymore required because the message is
2039 system modal and all other attempts to use the pinentry will fail
2040 (after a timeout). */
2041 int
agent_popup_message_start(ctrl_t ctrl,const char * desc,const char * ok_btn)2042 agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
2043 {
2044 int rc;
2045 char line[ASSUAN_LINELENGTH];
2046 npth_attr_t tattr;
2047 int err;
2048
2049 if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
2050 {
2051 if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
2052 return gpg_error (GPG_ERR_CANCELED);
2053
2054 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
2055 return pinentry_loopback_confirm (ctrl, desc, 0, ok_btn, NULL);
2056
2057 return gpg_error (GPG_ERR_NO_PIN_ENTRY);
2058 }
2059
2060 rc = start_pinentry (ctrl);
2061 if (rc)
2062 return rc;
2063
2064 if (desc)
2065 build_cmd_setdesc (line, DIM(line), desc);
2066 else
2067 snprintf (line, DIM(line), "RESET");
2068 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2069 if (rc)
2070 return unlock_pinentry (ctrl, rc);
2071
2072 if (ok_btn)
2073 {
2074 snprintf (line, DIM(line), "SETOK %s", ok_btn);
2075 rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
2076 if (rc)
2077 return unlock_pinentry (ctrl, rc);
2078 }
2079
2080 err = npth_attr_init (&tattr);
2081 if (err)
2082 return unlock_pinentry (ctrl, gpg_error_from_errno (err));
2083 npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
2084
2085 popup_finished = 0;
2086 err = npth_create (&popup_tid, &tattr, popup_message_thread,
2087 &ctrl->thread_startup.fd);
2088 npth_attr_destroy (&tattr);
2089 if (err)
2090 {
2091 rc = gpg_error_from_errno (err);
2092 log_error ("error spawning popup message handler: %s\n",
2093 strerror (err) );
2094 return unlock_pinentry (ctrl, rc);
2095 }
2096 npth_setname_np (popup_tid, "popup-message");
2097
2098 return 0;
2099 }
2100
2101 /* Close a popup window. */
2102 void
agent_popup_message_stop(ctrl_t ctrl)2103 agent_popup_message_stop (ctrl_t ctrl)
2104 {
2105 int rc;
2106 pid_t pid;
2107
2108 (void)ctrl;
2109
2110 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
2111 return;
2112
2113 if (!popup_tid || !entry_ctx)
2114 {
2115 log_debug ("agent_popup_message_stop called with no active popup\n");
2116 return;
2117 }
2118
2119 pid = assuan_get_pid (entry_ctx);
2120 if (pid == (pid_t)(-1))
2121 ; /* No pid available can't send a kill. */
2122 else if (popup_finished)
2123 ; /* Already finished and ready for joining. */
2124 #ifdef HAVE_W32_SYSTEM
2125 /* Older versions of assuan set PID to 0 on Windows to indicate an
2126 invalid value. */
2127 else if (pid != (pid_t) INVALID_HANDLE_VALUE
2128 && pid != 0)
2129 {
2130 HANDLE process = (HANDLE) pid;
2131
2132 /* Arbitrary error code. */
2133 TerminateProcess (process, 1);
2134 }
2135 #else
2136 else if (pid > 0)
2137 kill (pid, SIGINT);
2138 #endif
2139
2140 /* Now wait for the thread to terminate. */
2141 rc = npth_join (popup_tid, NULL);
2142 if (rc)
2143 log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
2144 strerror (rc));
2145 /* Thread IDs are opaque, but we try our best here by resetting it
2146 to the same content that a static global variable has. */
2147 memset (&popup_tid, '\0', sizeof (popup_tid));
2148
2149 /* Now we can close the connection. */
2150 unlock_pinentry (ctrl, 0);
2151 }
2152
2153 int
agent_clear_passphrase(ctrl_t ctrl,const char * keyinfo,cache_mode_t cache_mode)2154 agent_clear_passphrase (ctrl_t ctrl,
2155 const char *keyinfo, cache_mode_t cache_mode)
2156 {
2157 int rc;
2158 char line[ASSUAN_LINELENGTH];
2159
2160 if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
2161 || cache_mode == CACHE_MODE_USER
2162 || cache_mode == CACHE_MODE_SSH)))
2163 return gpg_error (GPG_ERR_NOT_SUPPORTED);
2164
2165 rc = start_pinentry (ctrl);
2166 if (rc)
2167 return rc;
2168
2169 snprintf (line, DIM(line), "CLEARPASSPHRASE %c/%s",
2170 cache_mode == CACHE_MODE_USER? 'u' :
2171 cache_mode == CACHE_MODE_SSH? 's' : 'n',
2172 keyinfo);
2173 rc = assuan_transact (entry_ctx, line,
2174 NULL, NULL, NULL, NULL, NULL, NULL);
2175
2176 return unlock_pinentry (ctrl, rc);
2177 }
2178