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.
5 * This file is part of GnuPG.
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.
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.
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/>.
29 #ifndef HAVE_W32_SYSTEM
30 # include <sys/wait.h>
31 # include <sys/types.h>
33 # include <sys/utsname.h>
39 #include "../common/sysutils.h"
40 #include "../common/i18n.h"
41 #include "../common/zb32.h"
43 #ifdef _POSIX_OPEN_MAX
44 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
46 #define MAX_OPEN_FDS 20
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
54 #define LOCK_TIMEOUT (1*60)
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. Please do not change
61 * this value because pattern check files may let such passwords
63 #define DEFAULT_GENPIN_BITS 150
65 /* The assuan context of the current pinentry. */
66 static assuan_context_t entry_ctx;
68 /* A list of features of the current pinentry. */
71 /* The Pinentry support RS+US tabbing. This means that a RS (0x1e)
72 * starts a new tabbing block in which a US (0x1f) followed by a
73 * colon marks a colon. A pinentry can use this to pretty print
74 * name value pairs. */
75 unsigned int tabbing:1;
79 /* A mutex used to serialize access to the pinentry. */
80 static npth_mutex_t entry_lock;
82 /* The thread ID of the popup working thread. */
83 static npth_t popup_tid;
85 /* A flag used in communication between the popup working thread and
87 static int popup_finished;
91 /* Data to be passed to our callbacks, */
96 unsigned char *buffer;
98 unsigned int constraints_flags;
104 /* This function must be called once to initialize this module. This
105 has to be done before a second thread is spawned. We can't do the
106 static initialization because Pth emulation code might not be able
107 to do a static init; in particular, it is not possible for W32. */
109 initialize_module_call_pinentry (void)
111 static int initialized;
116 err = npth_mutex_init (&entry_lock, NULL);
118 log_fatal ("error initializing mutex: %s\n", strerror (err));
126 /* This function may be called to print information pertaining to the
127 current state of this module to the log. */
129 agent_query_dump_state (void)
131 log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
132 entry_ctx, (long)assuan_get_pid (entry_ctx), (void*)popup_tid);
135 /* Called to make sure that a popup window owned by the current
136 connection gets closed. */
138 agent_reset_query (ctrl_t ctrl)
140 if (entry_ctx && popup_tid && ctrl->pinentry_active)
142 agent_popup_message_stop (ctrl);
147 /* Unlock the pinentry so that another thread can start one and
148 disconnect that pinentry - we do this after the unlock so that a
149 stalled pinentry does not block other threads. Fixme: We should
150 have a timeout in Assuan for the disconnect operation. */
152 unlock_pinentry (ctrl_t ctrl, gpg_error_t rc)
154 assuan_context_t ctx = entry_ctx;
160 log_debug ("error calling pinentry: %s <%s>\n",
161 gpg_strerror (rc), gpg_strsource (rc));
163 /* Change the source of the error to pinentry so that the final
164 consumer of the error code knows that the problem is with
165 pinentry. For backward compatibility we do not do that for
166 some common error codes. */
167 switch (gpg_err_code (rc))
169 case GPG_ERR_NO_PIN_ENTRY:
170 case GPG_ERR_CANCELED:
171 case GPG_ERR_FULLY_CANCELED:
172 case GPG_ERR_ASS_UNKNOWN_INQUIRE:
173 case GPG_ERR_ASS_TOO_MUCH_DATA:
174 case GPG_ERR_NO_PASSPHRASE:
175 case GPG_ERR_BAD_PASSPHRASE:
176 case GPG_ERR_BAD_PIN:
179 case GPG_ERR_CORRUPTED_PROTECTION:
180 /* This comes from gpg-agent. */
184 rc = gpg_err_make (GPG_ERR_SOURCE_PINENTRY, gpg_err_code (rc));
189 if (--ctrl->pinentry_active == 0)
192 err = npth_mutex_unlock (&entry_lock);
195 log_error ("failed to release the entry lock: %s\n", strerror (err));
197 rc = gpg_error_from_errno (err);
199 assuan_release (ctx);
205 /* Helper for at_fork_cb which can also be called by the parent to
206 * show which envvars will be set. */
208 atfork_core (ctrl_t ctrl, int debug_mode)
211 const char *name, *assname, *value;
213 while ((name = session_env_list_stdenvnames (&iterator, &assname)))
215 /* For all new envvars (!ASSNAME) and the two medium old ones
216 * which do have an assuan name but are conveyed using
217 * environment variables, update the environment of the forked
218 * process. We also pass DISPLAY despite that --display is also
219 * used when exec-ing the pinentry. The reason is that for
220 * example the qt5ct tool does not have any arguments and thus
221 * relies on the DISPLAY envvar. The use case here is a global
222 * envvar like "QT_QPA_PLATFORMTHEME=qt5ct" which for example is
223 * useful when using the Qt pinentry under GNOME or XFCE.
226 || (!opt.keep_display && !strcmp (name, "DISPLAY"))
227 || !strcmp (name, "XAUTHORITY")
228 || !strcmp (name, "PINENTRY_USER_DATA"))
230 value = session_env_getenv (ctrl->session_env, name);
234 log_debug ("pinentry: atfork used setenv(%s,%s)\n",name,value);
236 gnupg_setenv (name, value, 1);
243 /* To make sure we leave no secrets in our image after forking of the
244 pinentry, we use this callback. */
246 atfork_cb (void *opaque, int where)
248 ctrl_t ctrl = opaque;
252 gcry_control (GCRYCTL_TERM_SECMEM);
253 atfork_core (ctrl, 0);
258 /* Status line callback for the FEATURES status. */
260 getinfo_features_cb (void *opaque, const char *line)
268 if ((args = has_leading_keyword (line, "FEATURES")))
270 tokens = strtokenize (args, " ");
272 return gpg_error_from_syserror ();
273 for (i=0; tokens[i]; i++)
274 if (!strcmp (tokens[i], "tabbing"))
275 entry_features.tabbing = 1;
284 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
286 unsigned long *pid = opaque;
289 /* There is only the pid in the server's response. */
290 if (length >= sizeof pidbuf)
291 length = sizeof pidbuf -1;
294 strncpy (pidbuf, buffer, length);
296 *pid = strtoul (pidbuf, NULL, 10);
302 /* Fork off the pin entry if this has not already been done. Note,
303 that this function must always be used to acquire the lock for the
304 pinentry - we will serialize _all_ pinentry calls.
307 start_pinentry (ctrl_t ctrl)
310 const char *full_pgmname;
312 assuan_context_t ctx;
314 assuan_fd_t no_close_list[3];
317 unsigned long pinentry_pid;
319 struct timespec abstime;
320 char *flavor_version;
323 if (ctrl->pinentry_active)
325 /* It's trying to use pinentry recursively. In this situation,
326 the thread holds ENTRY_LOCK already. */
327 ctrl->pinentry_active++;
331 npth_clock_gettime (&abstime);
332 abstime.tv_sec += LOCK_TIMEOUT;
333 err = npth_mutex_timedlock (&entry_lock, &abstime);
336 if (err == ETIMEDOUT)
337 rc = gpg_error (GPG_ERR_TIMEOUT);
339 rc = gpg_error_from_errno (rc);
340 log_error (_("failed to acquire the pinentry lock: %s\n"),
349 log_info ("starting a new PIN Entry\n");
351 #ifdef HAVE_W32_SYSTEM
357 #ifndef HAVE_W32_SYSTEM
358 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
360 log_error ("error flushing pending output: %s\n", strerror (errno));
361 /* At least Windows XP fails here with EBADF. According to docs
362 and Wine an fflush(NULL) is the same as _flushall. However
363 the Wine implementation does not flush stdin,stdout and stderr
364 - see above. Let's try to ignore the error. */
365 #ifndef HAVE_W32_SYSTEM
366 return unlock_pinentry (ctrl, tmperr);
370 full_pgmname = opt.pinentry_program;
371 if (!full_pgmname || !*full_pgmname)
372 full_pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY);
373 if ( !(pgmname = strrchr (full_pgmname, '/')))
374 pgmname = full_pgmname;
378 /* OS X needs the entire file name in argv[0], so that it can locate
379 the resource bundle. For other systems we stick to the usual
380 convention of supplying only the name of the program. */
382 argv[0] = full_pgmname;
387 if (!opt.keep_display
388 && (value = session_env_getenv (ctrl->session_env, "DISPLAY")))
390 argv[1] = "--display";
398 if (!opt.running_detached)
399 no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr));
400 no_close_list[i] = ASSUAN_INVALID_FD;
402 rc = assuan_new (&ctx);
405 log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
409 ctrl->pinentry_active = 1;
412 /* We don't want to log the pinentry communication to make the logs
413 easier to read. We might want to add a new debug option to enable
415 #ifdef ASSUAN_NO_LOGGING
416 assuan_set_flag (ctx, ASSUAN_NO_LOGGING, !opt.debug_pinentry);
419 /* Connect to the pinentry and perform initial handshaking. Note
420 that atfork is used to change the environment for pinentry. We
421 start the server in detached mode to suppress the console window
423 rc = assuan_pipe_connect (entry_ctx, full_pgmname, argv,
424 no_close_list, atfork_cb, ctrl,
425 ASSUAN_PIPE_CONNECT_DETACHED);
428 log_error ("can't connect to the PIN entry module '%s': %s\n",
429 full_pgmname, gpg_strerror (rc));
430 return unlock_pinentry (ctrl, gpg_error (GPG_ERR_NO_PIN_ENTRY));
434 log_debug ("connection to PIN entry established\n");
436 if (opt.debug_pinentry)
437 atfork_core (ctrl, 1); /* Just show the envvars set after the fork. */
439 value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA");
443 if (asprintf (&optstr, "OPTION pinentry-user-data=%s", value) < 0 )
444 return unlock_pinentry (ctrl, out_of_core ());
445 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
448 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
449 return unlock_pinentry (ctrl, rc);
452 rc = assuan_transact (entry_ctx,
453 opt.no_grab? "OPTION no-grab":"OPTION grab",
454 NULL, NULL, NULL, NULL, NULL, NULL);
457 if (gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED
458 || gpg_err_code (rc) == GPG_ERR_UNKNOWN_OPTION)
461 log_info ("Option no-grab/grab is ignored by pinentry.\n");
462 /* Keep going even if the feature is not supported. */
465 return unlock_pinentry (ctrl, rc);
468 value = session_env_getenv (ctrl->session_env, "GPG_TTY");
472 if (asprintf (&optstr, "OPTION ttyname=%s", value) < 0 )
473 return unlock_pinentry (ctrl, out_of_core ());
474 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
478 return unlock_pinentry (ctrl, rc);
480 value = session_env_getenv (ctrl->session_env, "TERM");
484 if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 )
485 return unlock_pinentry (ctrl, out_of_core ());
486 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
490 return unlock_pinentry (ctrl, rc);
495 if (asprintf (&optstr, "OPTION lc-ctype=%s", ctrl->lc_ctype) < 0 )
496 return unlock_pinentry (ctrl, out_of_core ());
497 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
501 return unlock_pinentry (ctrl, rc);
503 if (ctrl->lc_messages)
506 if (asprintf (&optstr, "OPTION lc-messages=%s", ctrl->lc_messages) < 0 )
507 return unlock_pinentry (ctrl, out_of_core ());
508 rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
512 return unlock_pinentry (ctrl, rc);
516 if (opt.allow_external_cache)
518 /* Indicate to the pinentry that it may read from an external cache.
520 It is essential that the pinentry respect this. If the
521 cached password is not up to date and retry == 1, then, using
522 a version of GPG Agent that doesn't support this, won't issue
523 another pin request and the user won't get a chance to
524 correct the password. */
525 rc = assuan_transact (entry_ctx, "OPTION allow-external-password-cache",
526 NULL, NULL, NULL, NULL, NULL, NULL);
527 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
528 return unlock_pinentry (ctrl, rc);
531 if (opt.allow_emacs_pinentry)
533 /* Indicate to the pinentry that it may read passphrase through
534 Emacs minibuffer, if possible. */
535 rc = assuan_transact (entry_ctx, "OPTION allow-emacs-prompt",
536 NULL, NULL, NULL, NULL, NULL, NULL);
537 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
538 return unlock_pinentry (ctrl, rc);
543 /* Provide a few default strings for use by the pinentries. This
544 * may help a pinentry to avoid implementing localization code.
545 * Note that gpg-agent has been set to utf-8 so that the strings
546 * are in the expected encoding. */
547 static const struct { const char *key, *value; int what; } tbl[] = {
548 /* TRANSLATORS: These are labels for buttons etc as used in
549 * Pinentries. In your translation copy the text before the
550 * second vertical bar verbatim; translate only the following
551 * text. An underscore indicates that the next letter should be
552 * used as an accelerator. Double the underscore to have
553 * pinentry display a literal underscore. */
554 { "ok", N_("|pinentry-label|_OK") },
555 { "cancel", N_("|pinentry-label|_Cancel") },
556 { "yes", N_("|pinentry-label|_Yes") },
557 { "no", N_("|pinentry-label|_No") },
558 { "prompt", N_("|pinentry-label|PIN:") },
559 { "pwmngr", N_("|pinentry-label|_Save in password manager"), 1 },
560 { "cf-visi",N_("Do you really want to make your "
561 "passphrase visible on the screen?") },
562 { "tt-visi",N_("|pinentry-tt|Make passphrase visible") },
563 { "tt-hide",N_("|pinentry-tt|Hide passphrase") },
564 { "capshint", N_("Caps Lock is on") },
571 for (idx=0; tbl[idx].key; idx++)
573 if (!opt.allow_external_cache && tbl[idx].what == 1)
574 continue; /* No need for it. */
575 s = L_(tbl[idx].value);
576 if (*s == '|' && (s2=strchr (s+1,'|')))
578 if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 )
579 return unlock_pinentry (ctrl, out_of_core ());
580 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
586 /* Tell the pinentry that we would prefer that the given character
587 is used as the invisible character by the entry widget. */
588 if (opt.pinentry_invisible_char)
591 if ((optstr = xtryasprintf ("OPTION invisible-char=%s",
592 opt.pinentry_invisible_char)))
594 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
596 /* We ignore errors because this is just a fancy thing and
597 older pinentries do not support this feature. */
602 if (opt.pinentry_timeout)
605 if ((optstr = xtryasprintf ("SETTIMEOUT %lu", opt.pinentry_timeout)))
607 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
609 /* We ignore errors because this is just a fancy thing. */
614 /* Tell the pinentry the name of a file it shall touch after having
615 messed with the tty. This is optional and only supported by
616 newer pinentries and thus we do no error checking. */
617 tmpstr = opt.pinentry_touch_file;
618 if (tmpstr && !strcmp (tmpstr, "/dev/null"))
621 tmpstr = get_agent_socket_name ();
626 if (asprintf (&optstr, "OPTION touch-file=%s", tmpstr ) < 0 )
630 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
636 /* Tell Pinentry about our client. */
637 if (ctrl->client_pid)
640 const char *nodename = "";
642 #ifndef HAVE_W32_SYSTEM
643 struct utsname utsbuf;
644 if (!uname (&utsbuf))
645 nodename = utsbuf.nodename;
646 #endif /*!HAVE_W32_SYSTEM*/
648 if ((optstr = xtryasprintf ("OPTION owner=%lu/%d %s",
649 ctrl->client_pid, ctrl->client_uid,
652 assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
654 /* We ignore errors because this is just a fancy thing and
655 older pinentries do not support this feature. */
661 /* Ask the pinentry for its version and flavor and store that as a
662 * string in MB. This information is useful for helping users to
663 * figure out Pinentry problems. Note that "flavor" may also return
664 * a status line with the features; we use a dedicated handler for
669 init_membuf (&mb, 256);
670 if (assuan_transact (entry_ctx, "GETINFO flavor",
673 getinfo_features_cb, NULL))
674 put_membuf_str (&mb, "unknown");
675 put_membuf_str (&mb, " ");
676 if (assuan_transact (entry_ctx, "GETINFO version",
677 put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
678 put_membuf_str (&mb, "unknown");
679 put_membuf_str (&mb, " ");
680 if (assuan_transact (entry_ctx, "GETINFO ttyinfo",
681 put_membuf_cb, &mb, NULL, NULL, NULL, NULL))
682 put_membuf_str (&mb, "? ? ?");
683 put_membuf (&mb, "", 1);
684 flavor_version = get_membuf (&mb, NULL);
688 /* Now ask the Pinentry for its PID. If the Pinentry is new enough
689 it will send the pid back and we will use an inquire to notify
690 our client. The client may answer the inquiry either with END or
691 with CAN to cancel the pinentry. */
692 rc = assuan_transact (entry_ctx, "GETINFO pid",
693 getinfo_pid_cb, &pinentry_pid,
694 NULL, NULL, NULL, NULL);
697 log_info ("You may want to update to a newer pinentry\n");
700 else if (!rc && pinentry_pid == (unsigned long)(-1L))
701 log_error ("pinentry did not return a PID\n");
704 rc = agent_inq_pinentry_launched (ctrl, pinentry_pid, flavor_version);
705 if (gpg_err_code (rc) == GPG_ERR_CANCELED
706 || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
707 return unlock_pinentry (ctrl, gpg_err_make (GPG_ERR_SOURCE_DEFAULT,
712 xfree (flavor_version);
718 /* Returns True if the pinentry is currently active. If WAITSECONDS is
719 greater than zero the function will wait for this many seconds
722 pinentry_active_p (ctrl_t ctrl, int waitseconds)
729 struct timespec abstime;
732 npth_clock_gettime (&abstime);
733 abstime.tv_sec += waitseconds;
734 err = npth_mutex_timedlock (&entry_lock, &abstime);
737 if (err == ETIMEDOUT)
738 rc = gpg_error (GPG_ERR_TIMEOUT);
740 rc = gpg_error (GPG_ERR_INTERNAL);
746 err = npth_mutex_trylock (&entry_lock);
748 return gpg_error (GPG_ERR_LOCKED);
751 err = npth_mutex_unlock (&entry_lock);
753 log_error ("failed to release the entry lock at %d: %s\n", __LINE__,
760 getpin_cb (void *opaque, const void *buffer, size_t length)
762 struct entry_parm_s *parm = opaque;
767 /* we expect the pin to fit on one line */
768 if (parm->lines || length >= parm->size)
769 return gpg_error (GPG_ERR_ASS_TOO_MUCH_DATA);
771 /* fixme: we should make sure that the assuan buffer is allocated in
772 secure memory or read the response byte by byte */
773 memcpy (parm->buffer, buffer, length);
774 parm->buffer[length] = 0;
781 all_digitsp( const char *s)
783 for (; *s && *s >= '0' && *s <= '9'; s++)
789 /* Return a new malloced string by unescaping the string S. Escaping
790 is percent escaping and '+'/space mapping. A binary Nul will
791 silently be replaced by a 0xFF. Function returns NULL to indicate
792 an out of memory status. Parsing stops at the end of the string or
793 a white space character. */
795 unescape_passphrase_string (const unsigned char *s)
799 buffer = d = xtrymalloc_secure (strlen ((const char*)s)+1);
802 while (*s && !spacep (s))
804 if (*s == '%' && s[1] && s[2])
826 /* Estimate the quality of the passphrase PW and return a value in the
829 estimate_passphrase_quality (const char *pw)
831 int goodlength = opt.min_passphrase_len + opt.min_passphrase_len/3;
838 for (length = 0, s = pw; *s; s++)
842 if (length > goodlength)
844 return ((length*10) / goodlength)*10;
848 /* Generate a random passphrase in zBase32 encoding (RFC-6189) to be
849 * used by Pinentry to suggest a passphrase. Note that we have the
850 * same algorithm in gpg.c for --gen-random at level 30. It is
851 * important that we always output exactly 30 characters to match the
852 * special exception we have in the pattern file for symmetric
857 unsigned int nbits = DEFAULT_GENPIN_BITS;
858 size_t nbytes = nbytes = (nbits + 7) / 8;
862 rand = gcry_random_bytes_secure (nbytes, GCRY_STRONG_RANDOM);
865 log_error ("failed to generate random pin\n");
869 generated = zb32_encode (rand, nbits);
875 /* Handle inquiries. */
878 assuan_context_t ctx;
879 unsigned int flags; /* CHECK_CONSTRAINTS_... */
880 int genpinhash_valid;
881 char genpinhash[32]; /* Hash of the last generated pin. */
885 /* Return true if PIN is indentical to the last generated pin. */
887 is_generated_pin (struct inq_cb_parm_s *parm, const char *pin)
891 if (!parm->genpinhash_valid)
895 /* Note that we compare the hash so that we do not need to save the
896 * generated PIN longer than needed. */
897 gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf, pin, strlen (pin));
899 if (!memcmp (hashbuf, parm->genpinhash, 32))
900 return 1; /* yes, it is the same. */
907 inq_cb (void *opaque, const char *line)
909 struct inq_cb_parm_s *parm = opaque;
914 if ((s = has_leading_keyword (line, "QUALITY")))
919 pin = unescape_passphrase_string (s);
921 err = gpg_error_from_syserror ();
924 percent = estimate_passphrase_quality (pin);
925 if (check_passphrase_constraints (NULL, pin, parm->flags, NULL))
927 snprintf (numbuf, sizeof numbuf, "%d", percent);
928 err = assuan_send_data (parm->ctx, numbuf, strlen (numbuf));
932 else if ((s = has_leading_keyword (line, "CHECKPIN")))
934 char *errtext = NULL;
937 if (!opt.enforce_passphrase_constraints)
939 log_error ("unexpected inquiry 'CHECKPIN' without enforced "
940 "passphrase constraints\n");
941 err = gpg_error (GPG_ERR_ASS_UNEXPECTED_CMD);
945 pin = unescape_passphrase_string (s);
947 err = gpg_error_from_syserror ();
950 if (!is_generated_pin (parm, pin)
951 && check_passphrase_constraints (NULL, pin,parm->flags, &errtext))
955 /* Unescape the percent-escaped errtext because
956 assuan_send_data escapes it again. */
957 errtextlen = percent_unescape_inplace (errtext, 0);
958 err = assuan_send_data (parm->ctx, errtext, errtextlen);
962 log_error ("passphrase check failed without error text\n");
963 err = gpg_error (GPG_ERR_GENERAL);
968 err = assuan_send_data (parm->ctx, NULL, 0);
974 else if ((s = has_leading_keyword (line, "GENPIN")))
978 parm->genpinhash_valid = 0;
979 pin = generate_pin ();
982 log_error ("failed to generate a passphrase\n");
983 err = gpg_error (GPG_ERR_GENERAL);
986 wasconf = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
987 assuan_begin_confidential (parm->ctx);
988 err = assuan_send_data (parm->ctx, pin, strlen (pin));
990 assuan_end_confidential (parm->ctx);
991 gcry_md_hash_buffer (GCRY_MD_SHA256, parm->genpinhash, pin, strlen (pin));
992 parm->genpinhash_valid = 1;
997 log_error ("unsupported inquiry '%s' from pinentry\n", line);
998 err = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
1006 /* Helper to setup pinentry for genpin action. */
1008 setup_genpin (ctrl_t ctrl)
1011 char line[ASSUAN_LINELENGTH];
1012 char *tmpstr, *tmpstr2;
1013 const char *tooltip;
1017 /* TRANSLATORS: This string is displayed by Pinentry as the label
1018 for generating a passphrase. */
1019 tmpstr = try_percent_escape (L_("Suggest"), "\t\r\n\f\v");
1020 snprintf (line, DIM(line), "SETGENPIN %s", tmpstr? tmpstr:"");
1022 err = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1023 if (gpg_err_code (err) == 103 /*(Old assuan error code)*/
1024 || gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD)
1025 ; /* Ignore Unknown Command from old Pinentry versions. */
1029 tmpstr2 = gnupg_get_help_string ("pinentry.genpin.tooltip", 0);
1034 /* TRANSLATORS: This string is a tooltip, shown by pinentry when
1035 hovering over the generate button. Please use an appropriate
1036 string to describe what this is about. The length of the
1037 tooltip is limited to about 900 characters. If you do not
1038 translate this entry, a default English text (see source)
1039 will be used. The strcmp thingy is there to detect a
1040 non-translated string. */
1041 tooltip = L_("pinentry.genpin.tooltip");
1042 if (!strcmp ("pinentry.genpin.tooltip", tooltip))
1043 tooltip = "Suggest a random passphrase.";
1045 tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
1047 snprintf (line, DIM(line), "SETGENPIN_TT %s", tmpstr? tmpstr:"");
1049 err = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1050 if (gpg_err_code (err) == 103 /*(Old assuan error code)*/
1051 || gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD)
1052 ; /* Ignore Unknown Command from old pinentry versions. */
1060 /* Helper to setup pinentry for formatted passphrase. */
1062 setup_formatted_passphrase (ctrl_t ctrl)
1064 static const struct { const char *key, *help_id, *value; } tbl[] = {
1065 { "hint", "pinentry.formatted_passphrase.hint",
1066 /* TRANSLATORS: This is a text shown by pinentry if the option
1067 for formatted passphrase is enabled. The length is
1068 limited to about 900 characters. */
1069 N_("Note: The blanks are not part of the passphrase.") },
1074 char line[ASSUAN_LINELENGTH];
1082 if (opt.pinentry_formatted_passphrase)
1084 snprintf (line, DIM(line), "OPTION formatted-passphrase");
1085 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL,
1087 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
1090 for (idx=0; tbl[idx].key; idx++)
1092 tmpstr = gnupg_get_help_string (tbl[idx].help_id, 0);
1096 s = L_(tbl[idx].value);
1097 escapedstr = try_percent_escape (s, "\t\r\n\f\v");
1099 if (escapedstr && *escapedstr)
1101 snprintf (line, DIM(line), "OPTION formatted-passphrase-%s=%s",
1102 tbl[idx].key, escapedstr);
1103 rc = assuan_transact (entry_ctx, line,
1104 NULL, NULL, NULL, NULL, NULL, NULL);
1109 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
1118 /* Helper to setup pinentry for enforced passphrase constraints. */
1120 setup_enforced_constraints (ctrl_t ctrl)
1122 static const struct { const char *key, *help_id, *value; } tbl[] = {
1123 { "hint-short", "pinentry.constraints.hint.short", NULL },
1124 { "hint-long", "pinentry.constraints.hint.long", NULL },
1125 /* TRANSLATORS: This is a text shown by pinentry as title of a dialog
1126 telling the user that the entered new passphrase does not satisfy
1127 the passphrase constraints. Please keep it short. */
1128 { "error-title", NULL, N_("Passphrase Not Allowed") },
1133 char line[ASSUAN_LINELENGTH];
1141 if (opt.enforce_passphrase_constraints)
1143 snprintf (line, DIM(line), "OPTION constraints-enforce");
1144 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL,
1146 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
1149 for (idx=0; tbl[idx].key; idx++)
1151 tmpstr = gnupg_get_help_string (tbl[idx].help_id, 0);
1154 else if (tbl[idx].value)
1155 s = L_(tbl[idx].value);
1158 log_error ("no help string found for %s\n", tbl[idx].help_id);
1161 escapedstr = try_percent_escape (s, "\t\r\n\f\v");
1163 if (escapedstr && *escapedstr)
1165 snprintf (line, DIM(line), "OPTION constraints-%s=%s",
1166 tbl[idx].key, escapedstr);
1167 rc = assuan_transact (entry_ctx, line,
1168 NULL, NULL, NULL, NULL, NULL, NULL);
1171 rc = 0; /* Ignore an empty string (would give an IPC error). */
1173 if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION)
1182 /* Helper for agent_askpin and agent_get_passphrase. */
1184 setup_qualitybar (ctrl_t ctrl)
1187 char line[ASSUAN_LINELENGTH];
1188 char *tmpstr, *tmpstr2;
1189 const char *tooltip;
1193 /* TRANSLATORS: This string is displayed by Pinentry as the label
1194 for the quality bar. */
1195 tmpstr = try_percent_escape (L_("Quality:"), "\t\r\n\f\v");
1196 snprintf (line, DIM(line), "SETQUALITYBAR %s", tmpstr? tmpstr:"");
1198 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1199 if (rc == 103 /*(Old assuan error code)*/
1200 || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1201 ; /* Ignore Unknown Command from old Pinentry versions. */
1205 tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
1210 /* TRANSLATORS: This string is a tooltip, shown by pinentry when
1211 hovering over the quality bar. Please use an appropriate
1212 string to describe what this is about. The length of the
1213 tooltip is limited to about 900 characters. If you do not
1214 translate this entry, a default english text (see source)
1216 tooltip = L_("pinentry.qualitybar.tooltip");
1217 if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
1218 tooltip = ("The quality of the text entered above.\n"
1219 "Please ask your administrator for "
1220 "details about the criteria.");
1222 tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
1224 snprintf (line, DIM(line), "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
1226 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1227 if (rc == 103 /*(Old assuan error code)*/
1228 || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1229 ; /* Ignore Unknown Command from old pinentry versions. */
1236 /* Check the button_info line for a close action. Also check for the
1237 PIN_REPEATED flag. */
1239 pinentry_status_cb (void *opaque, const char *line)
1241 unsigned int *flag = opaque;
1244 if ((args = has_leading_keyword (line, "BUTTON_INFO")))
1246 if (!strcmp (args, "close"))
1247 *flag |= PINENTRY_STATUS_CLOSE_BUTTON;
1249 else if (has_leading_keyword (line, "PIN_REPEATED"))
1251 *flag |= PINENTRY_STATUS_PIN_REPEATED;
1253 else if (has_leading_keyword (line, "PASSWORD_FROM_CACHE"))
1255 *flag |= PINENTRY_STATUS_PASSWORD_FROM_CACHE;
1262 /* Build a SETDESC command line. This is a dedicated function so that
1263 * it can remove control characters which are not supported by the
1264 * current Pinentry. */
1266 build_cmd_setdesc (char *line, size_t linelen, const char *desc)
1270 snprintf (line, linelen, "SETDESC %s", desc);
1271 if (!entry_features.tabbing)
1273 /* Remove RS and US. */
1274 for (src=dst=line; *src; src++)
1275 if (!strchr ("\x1e\x1f", *src))
1283 /* Watch the socket's EOF condition, while checking finish of
1284 foreground thread. When EOF condition is detected, terminate
1285 the pinentry process behind the assuan pipe.
1288 watch_sock (void *arg)
1290 pid_t pid = assuan_get_pid (entry_ctx);
1296 struct timeval timeout = { 0, 500000 };
1297 gnupg_fd_t sock = *(gnupg_fd_t *)arg;
1299 if (sock == GNUPG_INVALID_FD)
1303 FD_SET (FD2INT (sock), &fdset);
1304 err = npth_select (FD2INT (sock)+1, &fdset, NULL, NULL, &timeout);
1314 /* Possibly, it's EOF. */
1319 if (pid == (pid_t)(-1))
1320 ; /* No pid available can't send a kill. */
1321 #ifdef HAVE_W32_SYSTEM
1322 /* Older versions of assuan set PID to 0 on Windows to indicate an
1324 else if (pid != (pid_t) INVALID_HANDLE_VALUE && pid != 0)
1325 TerminateProcess ((HANDLE)pid, 1);
1336 watch_sock_start (gnupg_fd_t *sock_p, npth_t *thread_p)
1341 err = npth_attr_init (&tattr);
1344 log_error ("do_getpin: error npth_attr_init: %s\n", strerror (err));
1345 return gpg_error_from_errno (err);
1347 npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1349 err = npth_create (thread_p, &tattr, watch_sock, sock_p);
1350 npth_attr_destroy (&tattr);
1353 log_error ("do_getpin: error spawning thread: %s\n", strerror (err));
1354 return gpg_error_from_errno (err);
1361 watch_sock_end (gnupg_fd_t *sock_p, npth_t *thread_p)
1365 *sock_p = GNUPG_INVALID_FD;
1366 err = npth_join (*thread_p, NULL);
1368 log_error ("watch_sock_end: error joining thread: %s\n", strerror (err));
1372 /* Ask pinentry to get a pin by "GETPIN" command, spawning a thread
1373 detecting the socket's EOF.
1376 do_getpin (ctrl_t ctrl, struct entry_parm_s *parm)
1379 gnupg_fd_t sock_watched = ctrl->thread_startup.fd;
1382 struct inq_cb_parm_s inq_cb_parm;
1384 rc = watch_sock_start (&sock_watched, &thread);
1388 inq_cb_parm.ctx = entry_ctx;
1389 inq_cb_parm.flags = parm->constraints_flags;
1390 inq_cb_parm.genpinhash_valid = 0;
1392 wasconf = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
1393 assuan_begin_confidential (entry_ctx);
1394 rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, parm,
1395 inq_cb, &inq_cb_parm,
1396 pinentry_status_cb, &parm->status);
1398 assuan_end_confidential (entry_ctx);
1400 if (!rc && parm->buffer && is_generated_pin (&inq_cb_parm, parm->buffer))
1401 parm->status |= PINENTRY_STATUS_PASSWORD_GENERATED;
1403 parm->status &= ~PINENTRY_STATUS_PASSWORD_GENERATED;
1405 /* Most pinentries out in the wild return the old Assuan error code
1406 for canceled which gets translated to an assuan Cancel error and
1407 not to the code for a user cancel. Fix this here. */
1408 if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1409 rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1410 /* Change error code in case the window close button was clicked
1411 to cancel the operation. */
1412 if ((parm->status & PINENTRY_STATUS_CLOSE_BUTTON)
1413 && gpg_err_code (rc) == GPG_ERR_CANCELED)
1414 rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
1416 watch_sock_end (&sock_watched, &thread);
1421 /* Call the Entry and ask for the PIN. We do check for a valid PIN
1422 number here and repeat it as long as we have invalid formed
1423 numbers. KEYINFO and CACHE_MODE are used to tell pinentry something
1426 agent_askpin (ctrl_t ctrl,
1427 const char *desc_text, const char *prompt_text,
1428 const char *initial_errtext,
1429 struct pin_entry_info_s *pininfo,
1430 const char *keyinfo, cache_mode_t cache_mode)
1433 char line[ASSUAN_LINELENGTH];
1434 struct entry_parm_s parm;
1435 const char *errtext = NULL;
1440 return 0; /* fixme: we should return BAD PIN */
1442 if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1444 if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1445 return gpg_error (GPG_ERR_CANCELED);
1446 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1448 unsigned char *passphrase;
1451 *pininfo->pin = 0; /* Reset the PIN. */
1452 rc = pinentry_loopback (ctrl, "PASSPHRASE", &passphrase, &size,
1453 pininfo->max_length - 1);
1457 memcpy(&pininfo->pin, passphrase, size);
1459 pininfo->pin[size] = 0;
1460 if (pininfo->check_cb)
1462 /* More checks by utilizing the optional callback. */
1463 pininfo->cb_errtext = NULL;
1464 rc = pininfo->check_cb (pininfo);
1468 return gpg_error(GPG_ERR_NO_PIN_ENTRY);
1471 if (!pininfo || pininfo->max_length < 1)
1472 return gpg_error (GPG_ERR_INV_VALUE);
1473 if (!desc_text && pininfo->min_digits)
1474 desc_text = L_("Please enter your PIN, so that the secret key "
1475 "can be unlocked for this session");
1476 else if (!desc_text)
1477 desc_text = L_("Please enter your passphrase, so that the secret key "
1478 "can be unlocked for this session");
1481 is_pin = !!strstr (prompt_text, "PIN");
1483 is_pin = desc_text && strstr (desc_text, "PIN");
1485 rc = start_pinentry (ctrl);
1489 /* If we have a KEYINFO string and are normal, user, or ssh cache
1490 mode, we tell that the Pinentry so it may use it for own caching
1491 purposes. Most pinentries won't have this implemented and thus
1492 we do not error out in this case. */
1493 if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1494 || cache_mode == CACHE_MODE_USER
1495 || cache_mode == CACHE_MODE_SSH))
1496 snprintf (line, DIM(line), "SETKEYINFO %c/%s",
1497 cache_mode == CACHE_MODE_USER? 'u' :
1498 cache_mode == CACHE_MODE_SSH? 's' : 'n',
1501 snprintf (line, DIM(line), "SETKEYINFO --clear");
1503 rc = assuan_transact (entry_ctx, line,
1504 NULL, NULL, NULL, NULL, NULL, NULL);
1505 if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1506 return unlock_pinentry (ctrl, rc);
1508 build_cmd_setdesc (line, DIM(line), desc_text);
1509 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1511 return unlock_pinentry (ctrl, rc);
1513 snprintf (line, DIM(line), "SETPROMPT %s",
1514 prompt_text? prompt_text : is_pin? L_("PIN:") : L_("Passphrase:"));
1515 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1517 return unlock_pinentry (ctrl, rc);
1519 /* If a passphrase quality indicator has been requested and a
1520 minimum passphrase length has not been disabled, send the command
1522 if (pininfo->with_qualitybar && opt.min_passphrase_len )
1524 rc = setup_qualitybar (ctrl);
1526 return unlock_pinentry (ctrl, rc);
1529 if (initial_errtext)
1531 snprintf (line, DIM(line), "SETERROR %s", initial_errtext);
1532 rc = assuan_transact (entry_ctx, line,
1533 NULL, NULL, NULL, NULL, NULL, NULL);
1535 return unlock_pinentry (ctrl, rc);
1538 if (pininfo->with_repeat)
1540 snprintf (line, DIM(line), "SETREPEATERROR %s",
1541 L_("does not match - try again"));
1542 rc = assuan_transact (entry_ctx, line,
1543 NULL, NULL, NULL, NULL, NULL, NULL);
1545 pininfo->with_repeat = 0; /* Pinentry does not support it. */
1547 if (pininfo->with_repeat)
1549 snprintf (line, DIM(line), "SETREPEATOK %s",
1550 L_("Passphrases match."));
1551 rc = assuan_transact (entry_ctx, line,
1552 NULL, NULL, NULL, NULL, NULL, NULL);
1554 rc = 0; /* Pinentry does not support it. */
1558 pininfo->repeat_okay = 0;
1559 pininfo->status = 0;
1561 for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
1563 memset (&parm, 0, sizeof parm);
1564 parm.size = pininfo->max_length;
1565 *pininfo->pin = 0; /* Reset the PIN. */
1566 parm.buffer = (unsigned char*)pininfo->pin;
1567 parm.constraints_flags = pininfo->constraints_flags;
1571 /* TRANSLATORS: The string is appended to an error message in
1572 the pinentry. The %s is the actual error message, the
1573 two %d give the current and maximum number of tries. */
1574 snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"),
1575 errtext, pininfo->failed_tries+1, pininfo->max_tries);
1576 rc = assuan_transact (entry_ctx, line,
1577 NULL, NULL, NULL, NULL, NULL, NULL);
1579 return unlock_pinentry (ctrl, rc);
1583 if (pininfo->with_repeat)
1585 snprintf (line, DIM(line), "SETREPEAT %s", L_("Repeat:"));
1586 rc = assuan_transact (entry_ctx, line,
1587 NULL, NULL, NULL, NULL, NULL, NULL);
1589 return unlock_pinentry (ctrl, rc);
1592 rc = do_getpin (ctrl, &parm);
1593 pininfo->status = parm.status;
1594 is_generated = !!(parm.status & PINENTRY_STATUS_PASSWORD_GENERATED);
1596 if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
1597 errtext = is_pin? L_("PIN too long")
1598 : L_("Passphrase too long");
1600 return unlock_pinentry (ctrl, rc);
1602 if (!errtext && pininfo->min_digits && !is_generated)
1604 /* do some basic checks on the entered PIN. */
1605 if (!all_digitsp (pininfo->pin))
1606 errtext = L_("Invalid characters in PIN");
1607 else if (pininfo->max_digits
1608 && strlen (pininfo->pin) > pininfo->max_digits)
1609 errtext = L_("PIN too long");
1610 else if (strlen (pininfo->pin) < pininfo->min_digits)
1611 errtext = L_("PIN too short");
1614 if (!errtext && pininfo->check_cb && !is_generated)
1616 /* More checks by utilizing the optional callback. */
1617 pininfo->cb_errtext = NULL;
1618 rc = pininfo->check_cb (pininfo);
1619 /* When pinentry cache causes an error, return now. */
1621 && (pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1622 return unlock_pinentry (ctrl, rc);
1624 if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE)
1626 if (pininfo->cb_errtext)
1627 errtext = pininfo->cb_errtext;
1628 else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1629 || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
1630 errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase"));
1633 return unlock_pinentry (ctrl, rc);
1638 if (pininfo->with_repeat
1639 && (pininfo->status & PINENTRY_STATUS_PIN_REPEATED))
1640 pininfo->repeat_okay = 1;
1641 return unlock_pinentry (ctrl, 0); /* okay, got a PIN or passphrase */
1644 if ((pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1646 /* The password was read from the cache. Don't count this
1647 against the retry count. */
1648 pininfo->failed_tries --;
1652 return unlock_pinentry (ctrl, gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
1653 : GPG_ERR_BAD_PASSPHRASE));
1658 /* Ask for the passphrase using the supplied arguments. The returned
1659 passphrase needs to be freed by the caller. PININFO is optional
1660 and can be used to have constraints checking while the pinentry
1661 dialog is open (like what we do in agent_askpin). This is very
1662 similar to agent_askpin and we should eventually merge the two
1665 agent_get_passphrase (ctrl_t ctrl,
1666 char **retpass, const char *desc, const char *prompt,
1667 const char *errtext, int with_qualitybar,
1668 const char *keyinfo, cache_mode_t cache_mode,
1669 struct pin_entry_info_s *pininfo)
1674 char line[ASSUAN_LINELENGTH];
1675 struct entry_parm_s parm;
1679 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
1681 if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1683 unsigned char *passphrase;
1686 if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1687 return gpg_error (GPG_ERR_CANCELED);
1689 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK && pininfo)
1691 *pininfo->pin = 0; /* Reset the PIN. */
1692 rc = pinentry_loopback (ctrl, "PASSPHRASE",
1694 pininfo->max_length - 1);
1698 memcpy (&pininfo->pin, passphrase, size);
1699 wipememory (passphrase, size);
1701 pininfo->pin[size] = 0;
1702 if (pininfo->check_cb)
1704 /* More checks by utilizing the optional callback. */
1705 pininfo->cb_errtext = NULL;
1706 rc = pininfo->check_cb (pininfo);
1711 else if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1713 /* Legacy variant w/o PININFO. */
1714 return pinentry_loopback (ctrl, "PASSPHRASE",
1715 (unsigned char **)retpass, &size,
1716 MAX_PASSPHRASE_LEN);
1719 return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1722 rc = start_pinentry (ctrl);
1726 /* Set IS_PIN and if needed a default prompt. */
1728 is_pin = !!strstr (prompt, "PIN");
1731 is_pin = desc && strstr (desc, "PIN");
1732 prompt = is_pin? L_("PIN:"): L_("Passphrase:");
1735 /* If we have a KEYINFO string and are normal, user, or ssh cache
1736 mode, we tell that the Pinentry so it may use it for own caching
1737 purposes. Most pinentries won't have this implemented and thus
1738 we do not error out in this case. */
1739 if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
1740 || cache_mode == CACHE_MODE_USER
1741 || cache_mode == CACHE_MODE_SSH))
1742 snprintf (line, DIM(line), "SETKEYINFO %c/%s",
1743 cache_mode == CACHE_MODE_USER? 'u' :
1744 cache_mode == CACHE_MODE_SSH? 's' : 'n',
1747 snprintf (line, DIM(line), "SETKEYINFO --clear");
1749 rc = assuan_transact (entry_ctx, line,
1750 NULL, NULL, NULL, NULL, NULL, NULL);
1751 if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
1752 return unlock_pinentry (ctrl, rc);
1755 build_cmd_setdesc (line, DIM(line), desc);
1757 snprintf (line, DIM(line), "RESET");
1758 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1760 return unlock_pinentry (ctrl, rc);
1762 snprintf (line, DIM(line), "SETPROMPT %s", prompt);
1763 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1765 return unlock_pinentry (ctrl, rc);
1767 if ((with_qualitybar || (pininfo && pininfo->with_qualitybar))
1768 && opt.min_passphrase_len)
1770 rc = setup_qualitybar (ctrl);
1772 return unlock_pinentry (ctrl, rc);
1777 snprintf (line, DIM(line), "SETERROR %s", errtext);
1778 rc = assuan_transact (entry_ctx, line,
1779 NULL, NULL, NULL, NULL, NULL, NULL);
1781 return unlock_pinentry (ctrl, rc);
1784 rc = setup_formatted_passphrase (ctrl);
1786 return unlock_pinentry (ctrl, rc);
1790 /* Legacy method without PININFO. */
1791 memset (&parm, 0, sizeof parm);
1792 parm.size = ASSUAN_LINELENGTH/2 - 5;
1793 parm.buffer = gcry_malloc_secure (parm.size+10);
1795 return unlock_pinentry (ctrl, out_of_core ());
1797 rc = do_getpin (ctrl, &parm);
1799 xfree (parm.buffer);
1801 *retpass = parm.buffer;
1802 return unlock_pinentry (ctrl, rc);
1805 /* We got PININFO. */
1807 if (pininfo->with_repeat)
1809 snprintf (line, DIM(line), "SETREPEATERROR %s",
1810 L_("does not match - try again"));
1811 rc = assuan_transact (entry_ctx, line,
1812 NULL, NULL, NULL, NULL, NULL, NULL);
1814 pininfo->with_repeat = 0; /* Pinentry does not support it. */
1816 if (pininfo->with_repeat)
1818 snprintf (line, DIM(line), "SETREPEATOK %s",
1819 L_("Passphrases match."));
1820 rc = assuan_transact (entry_ctx, line,
1821 NULL, NULL, NULL, NULL, NULL, NULL);
1823 rc = 0; /* Pinentry does not support it. */
1826 (void)setup_genpin (ctrl);
1828 rc = setup_enforced_constraints (ctrl);
1830 return unlock_pinentry (ctrl, rc);
1832 pininfo->repeat_okay = 0;
1833 pininfo->status = 0;
1835 for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
1837 memset (&parm, 0, sizeof parm);
1838 parm.constraints_flags = pininfo->constraints_flags;
1839 parm.size = pininfo->max_length;
1840 parm.buffer = (unsigned char*)pininfo->pin;
1841 *pininfo->pin = 0; /* Reset the PIN. */
1845 /* TRANSLATORS: The string is appended to an error message in
1846 the pinentry. The %s is the actual error message, the
1847 two %d give the current and maximum number of tries. */
1848 snprintf (line, DIM(line), L_("SETERROR %s (try %d of %d)"),
1849 errtext, pininfo->failed_tries+1, pininfo->max_tries);
1850 rc = assuan_transact (entry_ctx, line,
1851 NULL, NULL, NULL, NULL, NULL, NULL);
1853 return unlock_pinentry (ctrl, rc);
1857 if (pininfo->with_repeat)
1859 snprintf (line, DIM(line), "SETREPEAT %s", L_("Repeat:"));
1860 rc = assuan_transact (entry_ctx, line,
1861 NULL, NULL, NULL, NULL, NULL, NULL);
1863 return unlock_pinentry (ctrl, rc);
1866 rc = do_getpin (ctrl, &parm);
1867 pininfo->status = parm.status;
1868 is_generated = !!(parm.status & PINENTRY_STATUS_PASSWORD_GENERATED);
1870 if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
1871 errtext = is_pin? L_("PIN too long")
1872 : L_("Passphrase too long");
1874 return unlock_pinentry (ctrl, rc);
1876 if (!errtext && pininfo->min_digits && !is_generated)
1878 /* do some basic checks on the entered PIN. */
1879 if (!all_digitsp (pininfo->pin))
1880 errtext = L_("Invalid characters in PIN");
1881 else if (pininfo->max_digits
1882 && strlen (pininfo->pin) > pininfo->max_digits)
1883 errtext = L_("PIN too long");
1884 else if (strlen (pininfo->pin) < pininfo->min_digits)
1885 errtext = L_("PIN too short");
1888 if (!errtext && pininfo->check_cb && !is_generated)
1890 /* More checks by utilizing the optional callback. */
1891 pininfo->cb_errtext = NULL;
1892 rc = pininfo->check_cb (pininfo);
1893 /* When pinentry cache causes an error, return now. */
1894 if (rc && (pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1895 return unlock_pinentry (ctrl, rc);
1897 if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE)
1899 if (pininfo->cb_errtext)
1900 errtext = pininfo->cb_errtext;
1901 else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
1902 || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
1903 errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase"));
1906 return unlock_pinentry (ctrl, rc);
1911 if (pininfo->with_repeat
1912 && (pininfo->status & PINENTRY_STATUS_PIN_REPEATED))
1913 pininfo->repeat_okay = 1;
1914 return unlock_pinentry (ctrl, 0); /* okay, got a PIN or passphrase */
1917 if ((pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
1919 /* The password was read from the Pinentry's own cache.
1920 Don't count this against the retry count. */
1921 pininfo->failed_tries--;
1925 return unlock_pinentry (ctrl, gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
1926 : GPG_ERR_BAD_PASSPHRASE));
1931 /* Pop up the PIN-entry, display the text and the prompt and ask the
1932 user to confirm this. We return 0 for success, ie. the user
1933 confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
1934 other error. If WITH_CANCEL it true an extra cancel button is
1935 displayed to allow the user to easily return a GPG_ERR_CANCELED.
1936 if the Pinentry does not support this, the user can still cancel by
1937 closing the Pinentry window. */
1939 agent_get_confirmation (ctrl_t ctrl,
1940 const char *desc, const char *ok,
1941 const char *notok, int with_cancel)
1944 char line[ASSUAN_LINELENGTH];
1946 if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
1948 if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
1949 return gpg_error (GPG_ERR_CANCELED);
1951 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1952 return pinentry_loopback_confirm (ctrl, desc, 1, ok, notok);
1954 return gpg_error (GPG_ERR_NO_PIN_ENTRY);
1957 rc = start_pinentry (ctrl);
1962 build_cmd_setdesc (line, DIM(line), desc);
1964 snprintf (line, DIM(line), "RESET");
1965 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1966 /* Most pinentries out in the wild return the old Assuan error code
1967 for canceled which gets translated to an assuan Cancel error and
1968 not to the code for a user cancel. Fix this here. */
1969 if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
1970 rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
1973 return unlock_pinentry (ctrl, rc);
1977 snprintf (line, DIM(line), "SETOK %s", ok);
1978 rc = assuan_transact (entry_ctx,
1979 line, NULL, NULL, NULL, NULL, NULL, NULL);
1981 return unlock_pinentry (ctrl, rc);
1985 /* Try to use the newer NOTOK feature if a cancel button is
1986 requested. If no cancel button is requested we keep on using
1987 the standard cancel. */
1990 snprintf (line, DIM(line), "SETNOTOK %s", notok);
1991 rc = assuan_transact (entry_ctx,
1992 line, NULL, NULL, NULL, NULL, NULL, NULL);
1995 rc = GPG_ERR_ASS_UNKNOWN_CMD;
1997 if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
1999 snprintf (line, DIM(line), "SETCANCEL %s", notok);
2000 rc = assuan_transact (entry_ctx, line,
2001 NULL, NULL, NULL, NULL, NULL, NULL);
2004 return unlock_pinentry (ctrl, rc);
2008 gnupg_fd_t sock_watched = ctrl->thread_startup.fd;
2011 rc = watch_sock_start (&sock_watched, &thread);
2014 rc = assuan_transact (entry_ctx, "CONFIRM",
2015 NULL, NULL, NULL, NULL, NULL, NULL);
2016 if (rc && gpg_err_source (rc)
2017 && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
2018 rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
2020 watch_sock_end (&sock_watched, &thread);
2023 return unlock_pinentry (ctrl, rc);
2029 /* The thread running the popup message. */
2031 popup_message_thread (void *arg)
2034 gnupg_fd_t sock_watched = *(gnupg_fd_t *)arg;
2037 rc = watch_sock_start (&sock_watched, &thread);
2041 /* We use the --one-button hack instead of the MESSAGE command to
2042 allow the use of old Pinentries. Those old Pinentries will then
2043 show an additional Cancel button but that is mostly a visual
2045 assuan_transact (entry_ctx, "CONFIRM --one-button",
2046 NULL, NULL, NULL, NULL, NULL, NULL);
2047 watch_sock_end (&sock_watched, &thread);
2053 /* Pop up a message window similar to the confirm one but keep it open
2054 until agent_popup_message_stop has been called. It is crucial for
2055 the caller to make sure that the stop function gets called as soon
2056 as the message is not anymore required because the message is
2057 system modal and all other attempts to use the pinentry will fail
2058 (after a timeout). */
2060 agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
2063 char line[ASSUAN_LINELENGTH];
2067 if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
2069 if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
2070 return gpg_error (GPG_ERR_CANCELED);
2072 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
2073 return pinentry_loopback_confirm (ctrl, desc, 0, ok_btn, NULL);
2075 return gpg_error (GPG_ERR_NO_PIN_ENTRY);
2078 rc = start_pinentry (ctrl);
2083 build_cmd_setdesc (line, DIM(line), desc);
2085 snprintf (line, DIM(line), "RESET");
2086 rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
2088 return unlock_pinentry (ctrl, rc);
2092 snprintf (line, DIM(line), "SETOK %s", ok_btn);
2093 rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
2095 return unlock_pinentry (ctrl, rc);
2098 err = npth_attr_init (&tattr);
2100 return unlock_pinentry (ctrl, gpg_error_from_errno (err));
2101 npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
2104 err = npth_create (&popup_tid, &tattr, popup_message_thread,
2105 &ctrl->thread_startup.fd);
2106 npth_attr_destroy (&tattr);
2109 rc = gpg_error_from_errno (err);
2110 log_error ("error spawning popup message handler: %s\n",
2112 return unlock_pinentry (ctrl, rc);
2114 npth_setname_np (popup_tid, "popup-message");
2119 /* Close a popup window. */
2121 agent_popup_message_stop (ctrl_t ctrl)
2128 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
2131 if (!popup_tid || !entry_ctx)
2133 log_debug ("agent_popup_message_stop called with no active popup\n");
2137 pid = assuan_get_pid (entry_ctx);
2138 if (pid == (pid_t)(-1))
2139 ; /* No pid available can't send a kill. */
2140 else if (popup_finished)
2141 ; /* Already finished and ready for joining. */
2142 #ifdef HAVE_W32_SYSTEM
2143 /* Older versions of assuan set PID to 0 on Windows to indicate an
2145 else if (pid != (pid_t) INVALID_HANDLE_VALUE
2148 HANDLE process = (HANDLE) pid;
2150 /* Arbitrary error code. */
2151 TerminateProcess (process, 1);
2158 /* Now wait for the thread to terminate. */
2159 rc = npth_join (popup_tid, NULL);
2161 log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
2163 /* Thread IDs are opaque, but we try our best here by resetting it
2164 to the same content that a static global variable has. */
2165 memset (&popup_tid, '\0', sizeof (popup_tid));
2167 /* Now we can close the connection. */
2168 unlock_pinentry (ctrl, 0);
2172 agent_clear_passphrase (ctrl_t ctrl,
2173 const char *keyinfo, cache_mode_t cache_mode)
2176 char line[ASSUAN_LINELENGTH];
2178 if (! (keyinfo && (cache_mode == CACHE_MODE_NORMAL
2179 || cache_mode == CACHE_MODE_USER
2180 || cache_mode == CACHE_MODE_SSH)))
2181 return gpg_error (GPG_ERR_NOT_SUPPORTED);
2183 rc = start_pinentry (ctrl);
2187 snprintf (line, DIM(line), "CLEARPASSPHRASE %c/%s",
2188 cache_mode == CACHE_MODE_USER? 'u' :
2189 cache_mode == CACHE_MODE_SSH? 's' : 'n',
2191 rc = assuan_transact (entry_ctx, line,
2192 NULL, NULL, NULL, NULL, NULL, NULL);
2194 return unlock_pinentry (ctrl, rc);