1 /* command.c - gpg-agent command handler
2 * Copyright (C) 2001-2011 Free Software Foundation, Inc.
3 * Copyright (C) 2001-2013 Werner Koch
4 * Copyright (C) 2015 g10 Code GmbH.
6 * This file is part of GnuPG.
8 * GnuPG is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * GnuPG is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 /* FIXME: we should not use the default assuan buffering but setup
23 some buffering in secure mempory to protect session keys etc. */
34 #include <sys/types.h>
41 #include "cvt-openpgp.h"
42 #include "../common/ssh-utils.h"
43 #include "../common/asshelp.h"
46 /* Maximum allowed size of the inquired ciphertext. */
47 #define MAXLEN_CIPHERTEXT 4096
48 /* Maximum allowed size of the key parameters. */
49 #define MAXLEN_KEYPARAM 1024
50 /* Maximum allowed size of key data as used in inquiries (bytes). */
51 #define MAXLEN_KEYDATA 4096
52 /* The size of the import/export KEK key (in bytes). */
53 #define KEYWRAP_KEYSIZE (128/8)
55 /* A shortcut to call assuan_set_error using an gpg_err_code_t and a
57 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
59 /* Check that the maximum digest length we support has at least the
60 length of the keygrip. */
61 #if MAX_DIGEST_LEN < 20
62 #error MAX_DIGEST_LEN shorter than keygrip
65 /* Data used to associate an Assuan context with local server data.
66 This is this modules local part of the server_control_s struct. */
69 /* Our Assuan context. */
70 assuan_context_t assuan_ctx;
72 /* If this flag is true, the passphrase cache is used for signing
73 operations. It defaults to true but may be set on a per
74 connection base. The global option opt.ignore_cache_for_signing
75 takes precedence over this flag. */
76 int use_cache_for_signing;
78 /* An allocated description for the next key operation. This is
79 used if a pinnetry needs to be popped up. */
82 /* Flags to suppress I/O logging during a command. */
85 /* If this flags is set to true the agent will be terminated after
86 the end of the current session. */
89 /* Flag indicating whether pinentry notifications shall be done. */
90 int allow_pinentry_notify;
92 /* Malloced KEK (Key-Encryption-Key) for the import_key command. */
95 /* Malloced KEK for the export_key command. */
98 /* Client is aware of the error code GPG_ERR_FULLY_CANCELED. */
99 int allow_fully_canceled;
101 /* Last CACHE_NONCE sent as status (malloced). */
102 char *last_cache_nonce;
104 /* Last PASSWD_NONCE sent as status (malloced). */
105 char *last_passwd_nonce;
109 /* An entry for the getval/putval commands. */
112 struct putval_item_s *next;
113 size_t off; /* Offset to the value into DATA. */
114 size_t len; /* Length of the value. */
115 char d[1]; /* Key | Nul | value. */
119 /* A list of key value pairs fpr the getval/putval commands. */
120 static struct putval_item_s *putval_list;
124 /* To help polling clients, we keep track of the number of certain
125 events. This structure keeps those counters. The counters are
126 integers and there should be no problem if they are overflowing as
127 callers need to check only whether a counter changed. The actual
128 values are not meaningful. */
131 /* Incremented if any of the other counters below changed. */
134 /* Incremented if a key is added or removed from the internal privat
138 /* Incremented if a change of the card readers stati has been
146 /* Local prototypes. */
147 static int command_has_option (const char *cmd, const char *cmdopt);
152 /* Release the memory buffer MB but first wipe out the used memory. */
154 clear_outbuf (membuf_t *mb)
159 p = get_membuf (mb, &n);
168 /* Write the content of memory buffer MB as assuan data to CTX and
169 wipe the buffer out afterwards. */
171 write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
177 p = get_membuf (mb, &n);
179 return out_of_core ();
180 ae = assuan_send_data (ctx, p, n);
187 /* Clear the nonces used to enable the passphrase cache for certain
188 multi-command command sequences. */
190 clear_nonce_cache (ctrl_t ctrl)
192 if (ctrl->server_local->last_cache_nonce)
194 agent_put_cache (ctrl->server_local->last_cache_nonce,
195 CACHE_MODE_NONCE, NULL, 0);
196 xfree (ctrl->server_local->last_cache_nonce);
197 ctrl->server_local->last_cache_nonce = NULL;
199 if (ctrl->server_local->last_passwd_nonce)
201 agent_put_cache (ctrl->server_local->last_passwd_nonce,
202 CACHE_MODE_NONCE, NULL, 0);
203 xfree (ctrl->server_local->last_passwd_nonce);
204 ctrl->server_local->last_passwd_nonce = NULL;
209 /* This function is called by Libassuan whenever thee client sends a
210 reset. It has been registered similar to the other Assuan
213 reset_notify (assuan_context_t ctx, char *line)
215 ctrl_t ctrl = assuan_get_pointer (ctx);
219 memset (ctrl->keygrip, 0, 20);
220 ctrl->have_keygrip = 0;
221 ctrl->digest.valuelen = 0;
223 xfree (ctrl->server_local->keydesc);
224 ctrl->server_local->keydesc = NULL;
226 clear_nonce_cache (ctrl);
232 /* Skip over options in LINE.
234 Blanks after the options are also removed. Options are indicated
235 by two leading dashes followed by a string consisting of non-space
236 characters. The special option "--" indicates an explicit end of
237 options; all what follows will not be considered an option. The
238 first no-option string also indicates the end of option parsing. */
240 skip_options (const char *line)
242 while (spacep (line))
244 while ( *line == '-' && line[1] == '-' )
246 while (*line && !spacep (line))
248 while (spacep (line))
255 /* Check whether the option NAME appears in LINE. An example for a
256 line with options is:
257 --algo=42 --data foo bar
258 This function would then only return true if NAME is "data". */
260 has_option (const char *line, const char *name)
263 int n = strlen (name);
265 s = strstr (line, name);
266 if (s && s >= skip_options (line))
268 return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
272 /* Same as has_option but does only test for the name of the option
273 and ignores an argument, i.e. with NAME being "--hash" it would
274 return true for "--hash" as well as for "--hash=foo". */
276 has_option_name (const char *line, const char *name)
279 int n = strlen (name);
281 s = strstr (line, name);
282 if (s && s >= skip_options (line))
284 return (s && (s == line || spacep (s-1))
285 && (!s[n] || spacep (s+n) || s[n] == '='));
289 /* Return a pointer to the argument of the option with NAME. If such
290 an option is not given, NULL is retruned. */
292 option_value (const char *line, const char *name)
295 int n = strlen (name);
297 s = strstr (line, name);
298 if (s && s >= skip_options (line))
300 if (s && (s == line || spacep (s-1))
301 && s[n] && (spacep (s+n) || s[n] == '='))
304 s += strspn (s, " ");
305 if (*s && !spacep(s))
312 /* Replace all '+' by a blank in the string S. */
314 plus_to_blank (char *s)
324 /* Parse a hex string. Return an Assuan error code or 0 on success and the
325 length of the parsed string in LEN. */
327 parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
332 /* parse the hash value */
333 for (p=string, n=0; hexdigitp (p); p++, n++)
335 if (*p != ' ' && *p != '\t' && *p)
336 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
338 return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
344 /* Parse the keygrip in STRING into the provided buffer BUF. BUF must
345 provide space for 20 bytes. BUF is not changed if the function
348 parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
353 rc = parse_hexstring (ctx, string, &n);
358 return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip");
360 if (hex2bin (string, buf, 20) < 0)
361 return set_error (GPG_ERR_BUG, "hex2bin");
367 /* Write an Assuan status line. KEYWORD is the first item on the
368 status line. The following arguments are all separated by a space
369 in the output. The last argument must be a NULL. Linefeeds and
370 carriage returns characters (which are not allowed in an Assuan
371 status line) are silently quoted in C-style. */
373 agent_write_status (ctrl_t ctrl, const char *keyword, ...)
378 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
382 va_start (arg_ptr, keyword);
386 while ( (text = va_arg (arg_ptr, const char *)) )
393 for ( ; *text && n < DIM (buf)-3; n++, text++)
400 else if (*text == '\r')
410 err = assuan_write_status (ctx, keyword, buf);
417 /* This function is similar to print_assuan_status but takes a CTRL
418 arg instead of an assuan context as first argument. */
420 agent_print_status (ctrl_t ctrl, const char *keyword, const char *format, ...)
424 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
426 va_start (arg_ptr, format);
427 err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
433 /* Helper to notify the client about a launched Pinentry. Because
434 that might disturb some older clients, this is only done if enabled
435 via an option. Returns an gpg error code. */
437 agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
441 if (!ctrl || !ctrl->server_local
442 || !ctrl->server_local->allow_pinentry_notify)
444 snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
445 return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
449 /* An agent progress callback for Libgcrypt. This has been registered
450 * to be called via the progress dispatcher mechanism from
453 progress_cb (ctrl_t ctrl, const char *what, int printchar,
454 int current, int total)
456 if (!ctrl || !ctrl->server_local || !ctrl->server_local->assuan_ctx)
458 else if (printchar == '\n' && what && !strcmp (what, "primegen"))
459 agent_print_status (ctrl, "PROGRESS", "%.20s X 100 100", what);
461 agent_print_status (ctrl, "PROGRESS", "%.20s %c %d %d",
462 what, printchar=='\n'?'X':printchar, current, total);
466 /* Helper to print a message while leaving a command. */
468 leave_cmd (assuan_context_t ctx, gpg_error_t err)
472 const char *name = assuan_get_command_name (ctx);
476 /* Not all users of gpg-agent know about the fully canceled
477 error code; map it back if needed. */
478 if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
480 ctrl_t ctrl = assuan_get_pointer (ctx);
482 if (!ctrl->server_local->allow_fully_canceled)
483 err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED);
486 /* Most code from common/ does not know the error source, thus
488 if (gpg_err_source (err) == GPG_ERR_SOURCE_UNKNOWN)
489 err = gpg_err_make (GPG_ERR_SOURCE_DEFAULT, gpg_err_code (err));
491 if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
492 log_error ("command '%s' failed: %s\n", name,
495 log_error ("command '%s' failed: %s <%s>\n", name,
496 gpg_strerror (err), gpg_strsource (err));
503 static const char hlp_geteventcounter[] =
506 "Return a a status line named EVENTCOUNTER with the current values\n"
507 "of all event counters. The values are decimal numbers in the range\n"
508 "0 to UINT_MAX and wrapping around to 0. The actual values should\n"
509 "not be relied upon, they shall only be used to detect a change.\n"
511 "The currently defined counters are:\n"
513 "ANY - Incremented with any change of any of the other counters.\n"
514 "KEY - Incremented for added or removed private keys.\n"
515 "CARD - Incremented for changes of the card readers stati.";
517 cmd_geteventcounter (assuan_context_t ctx, char *line)
519 ctrl_t ctrl = assuan_get_pointer (ctx);
523 if (ctrl->restricted)
524 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
526 return agent_print_status (ctrl, "EVENTCOUNTER", "%u %u %u",
533 /* This function should be called once for all key removals or
534 additions. This function is assured not to do any context
537 bump_key_eventcounter (void)
544 /* This function should be called for all card reader status
545 changes. This function is assured not to do any context
548 bump_card_eventcounter (void)
557 static const char hlp_istrusted[] =
558 "ISTRUSTED <hexstring_with_fingerprint>\n"
560 "Return OK when we have an entry with this fingerprint in our\n"
563 cmd_istrusted (assuan_context_t ctx, char *line)
565 ctrl_t ctrl = assuan_get_pointer (ctx);
570 /* Parse the fingerprint value. */
571 for (p=line,n=0; hexdigitp (p); p++, n++)
573 if (*p || !(n == 40 || n == 32))
574 return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
578 strcpy (fpr, "00000000");
581 for (p=line; i < 40; p++, i++)
582 fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
584 rc = agent_istrusted (ctrl, fpr, NULL);
585 if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
587 else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
588 return gpg_error (GPG_ERR_NOT_TRUSTED);
590 return leave_cmd (ctx, rc);
594 static const char hlp_listtrusted[] =
597 "List all entries from the trustlist.";
599 cmd_listtrusted (assuan_context_t ctx, char *line)
601 ctrl_t ctrl = assuan_get_pointer (ctx);
606 if (ctrl->restricted)
607 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
609 rc = agent_listtrusted (ctx);
610 return leave_cmd (ctx, rc);
614 static const char hlp_martrusted[] =
615 "MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>\n"
617 "Store a new key in into the trustlist.";
619 cmd_marktrusted (assuan_context_t ctx, char *line)
621 ctrl_t ctrl = assuan_get_pointer (ctx);
627 if (ctrl->restricted)
628 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
630 /* parse the fingerprint value */
631 for (p=line,n=0; hexdigitp (p); p++, n++)
633 if (!spacep (p) || !(n == 40 || n == 32))
634 return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
638 strcpy (fpr, "00000000");
641 for (p=line; i < 40; p++, i++)
642 fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
648 if ( (flag != 'S' && flag != 'P') || !spacep (p) )
649 return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
653 rc = agent_marktrusted (ctrl, p, fpr, flag);
654 return leave_cmd (ctx, rc);
660 static const char hlp_havekey[] =
661 "HAVEKEY <hexstrings_with_keygrips>\n"
663 "Return success if at least one of the secret keys with the given\n"
664 "keygrips is available.";
666 cmd_havekey (assuan_context_t ctx, char *line)
669 unsigned char buf[20];
673 err = parse_keygrip (ctx, line, buf);
677 if (!agent_key_available (buf))
678 return 0; /* Found. */
680 while (*line && *line != ' ' && *line != '\t')
682 while (*line == ' ' || *line == '\t')
687 /* No leave_cmd() here because errors are expected and would clutter
689 return gpg_error (GPG_ERR_NO_SECKEY);
693 static const char hlp_sigkey[] =
694 "SIGKEY <hexstring_with_keygrip>\n"
695 "SETKEY <hexstring_with_keygrip>\n"
697 "Set the key used for a sign or decrypt operation.";
699 cmd_sigkey (assuan_context_t ctx, char *line)
702 ctrl_t ctrl = assuan_get_pointer (ctx);
704 rc = parse_keygrip (ctx, line, ctrl->keygrip);
707 ctrl->have_keygrip = 1;
712 static const char hlp_setkeydesc[] =
713 "SETKEYDESC plus_percent_escaped_string\n"
715 "Set a description to be used for the next PKSIGN, PKDECRYPT, IMPORT_KEY\n"
716 "or EXPORT_KEY operation if this operation requires a passphrase. If\n"
717 "this command is not used a default text will be used. Note, that\n"
718 "this description implictly selects the label used for the entry\n"
719 "box; if the string contains the string PIN (which in general will\n"
720 "not be translated), \"PIN\" is used, otherwise the translation of\n"
721 "\"passphrase\" is used. The description string should not contain\n"
722 "blanks unless they are percent or '+' escaped.\n"
724 "The description is only valid for the next PKSIGN, PKDECRYPT,\n"
725 "IMPORT_KEY, EXPORT_KEY, or DELETE_KEY operation.";
727 cmd_setkeydesc (assuan_context_t ctx, char *line)
729 ctrl_t ctrl = assuan_get_pointer (ctx);
732 for (p=line; *p == ' '; p++)
735 p = strchr (desc, ' ');
737 *p = 0; /* We ignore any garbage; we might late use it for other args. */
740 return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
742 /* Note, that we only need to replace the + characters and should
743 leave the other escaping in place because the escaped string is
744 send verbatim to the pinentry which does the unescaping (but not
746 plus_to_blank (desc);
748 xfree (ctrl->server_local->keydesc);
750 if (ctrl->restricted)
752 ctrl->server_local->keydesc = strconcat
753 ((ctrl->restricted == 2
754 ? _("Note: Request from the web browser.")
755 : _("Note: Request from a remote site.") ), "%0A%0A", desc, NULL);
758 ctrl->server_local->keydesc = xtrystrdup (desc);
759 if (!ctrl->server_local->keydesc)
760 return out_of_core ();
765 static const char hlp_sethash[] =
766 "SETHASH (--hash=<name>)|(<algonumber>) <hexstring>\n"
768 "The client can use this command to tell the server about the data\n"
769 "(which usually is a hash) to be signed.";
771 cmd_sethash (assuan_context_t ctx, char *line)
776 ctrl_t ctrl = assuan_get_pointer (ctx);
781 /* Parse the alternative hash options which may be used instead of
783 if (has_option_name (line, "--hash"))
785 if (has_option (line, "--hash=sha1"))
787 else if (has_option (line, "--hash=sha224"))
788 algo = GCRY_MD_SHA224;
789 else if (has_option (line, "--hash=sha256"))
790 algo = GCRY_MD_SHA256;
791 else if (has_option (line, "--hash=sha384"))
792 algo = GCRY_MD_SHA384;
793 else if (has_option (line, "--hash=sha512"))
794 algo = GCRY_MD_SHA512;
795 else if (has_option (line, "--hash=rmd160"))
796 algo = GCRY_MD_RMD160;
797 else if (has_option (line, "--hash=md5"))
799 else if (has_option (line, "--hash=tls-md5sha1"))
800 algo = MD_USER_TLS_MD5SHA1;
802 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
807 line = skip_options (line);
811 /* No hash option has been given: require an algo number instead */
812 algo = (int)strtoul (line, &endp, 10);
813 for (line = endp; *line == ' ' || *line == '\t'; line++)
815 if (!algo || gcry_md_test_algo (algo))
816 return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
818 ctrl->digest.algo = algo;
819 ctrl->digest.raw_value = 0;
821 /* Parse the hash value. */
823 rc = parse_hexstring (ctx, line, &n);
827 if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
829 else if (n != 16 && n != 20 && n != 24
830 && n != 28 && n != 32 && n != 48 && n != 64)
831 return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
833 if (n > MAX_DIGEST_LEN)
834 return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
836 buf = ctrl->digest.value;
837 ctrl->digest.valuelen = n;
838 for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
840 for (; n < ctrl->digest.valuelen; n++)
846 static const char hlp_pksign[] =
847 "PKSIGN [<options>] [<cache_nonce>]\n"
849 "Perform the actual sign operation. Neither input nor output are\n"
850 "sensitive to eavesdropping.";
852 cmd_pksign (assuan_context_t ctx, char *line)
855 cache_mode_t cache_mode = CACHE_MODE_NORMAL;
856 ctrl_t ctrl = assuan_get_pointer (ctx);
858 char *cache_nonce = NULL;
861 line = skip_options (line);
864 for (p=line; *p && *p != ' ' && *p != '\t'; p++)
868 cache_nonce = xtrystrdup (line);
870 if (opt.ignore_cache_for_signing)
871 cache_mode = CACHE_MODE_IGNORE;
872 else if (!ctrl->server_local->use_cache_for_signing)
873 cache_mode = CACHE_MODE_IGNORE;
875 init_membuf (&outbuf, 512);
877 rc = agent_pksign (ctrl, cache_nonce, ctrl->server_local->keydesc,
878 &outbuf, cache_mode);
880 clear_outbuf (&outbuf);
882 rc = write_and_clear_outbuf (ctx, &outbuf);
885 xfree (ctrl->server_local->keydesc);
886 ctrl->server_local->keydesc = NULL;
887 return leave_cmd (ctx, rc);
891 static const char hlp_pkdecrypt[] =
892 "PKDECRYPT [<options>]\n"
894 "Perform the actual decrypt operation. Input is not\n"
895 "sensitive to eavesdropping.";
897 cmd_pkdecrypt (assuan_context_t ctx, char *line)
900 ctrl_t ctrl = assuan_get_pointer (ctx);
901 unsigned char *value;
908 /* First inquire the data to decrypt */
909 rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_CIPHERTEXT);
911 rc = assuan_inquire (ctx, "CIPHERTEXT",
912 &value, &valuelen, MAXLEN_CIPHERTEXT);
916 init_membuf (&outbuf, 512);
918 rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
919 value, valuelen, &outbuf, &padding);
922 clear_outbuf (&outbuf);
926 rc = print_assuan_status (ctx, "PADDING", "%d", padding);
930 rc = write_and_clear_outbuf (ctx, &outbuf);
932 xfree (ctrl->server_local->keydesc);
933 ctrl->server_local->keydesc = NULL;
934 return leave_cmd (ctx, rc);
938 static const char hlp_genkey[] =
939 "GENKEY [--no-protection] [--preset] [--inq-passwd] [<cache_nonce>]\n"
941 "Generate a new key, store the secret part and return the public\n"
942 "part. Here is an example transaction:\n"
945 " S: INQUIRE KEYPARAM\n"
946 " C: D (genkey (rsa (nbits 2048)))\n"
948 " S: D (public-key\n"
949 " S: D (rsa (n 326487324683264) (e 10001)))\n"
950 " S: OK key created\n"
952 "When the --preset option is used the passphrase for the generated\n"
953 "key will be added to the cache. When --inq-passwd is used an inquire\n"
954 "with the keyword NEWPASSWD is used to request the passphrase for the\n"
957 cmd_genkey (assuan_context_t ctx, char *line)
959 ctrl_t ctrl = assuan_get_pointer (ctx);
962 unsigned char *value;
964 unsigned char *newpasswd = NULL;
966 char *cache_nonce = NULL;
972 if (ctrl->restricted)
973 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
975 no_protection = has_option (line, "--no-protection");
976 opt_preset = has_option (line, "--preset");
977 opt_inq_passwd = has_option (line, "--inq-passwd");
978 line = skip_options (line);
981 for (p=line; *p && *p != ' ' && *p != '\t'; p++)
985 cache_nonce = xtrystrdup (line);
987 /* First inquire the parameters */
988 rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_KEYPARAM);
990 rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
994 init_membuf (&outbuf, 512);
996 /* If requested, ask for the password to be used for the key. If
997 this is not used the regular Pinentry mechanism is used. */
998 if (opt_inq_passwd && !no_protection)
1000 /* (N is used as a dummy) */
1001 assuan_begin_confidential (ctx);
1002 rc = assuan_inquire (ctx, "NEWPASSWD", &newpasswd, &n, 256);
1003 assuan_end_confidential (ctx);
1008 /* Empty password given - switch to no-protection mode. */
1016 rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
1017 newpasswd, opt_preset, &outbuf);
1022 /* Assuan_inquire does not allow us to read into secure memory
1023 thus we need to wipe it ourself. */
1024 wipememory (newpasswd, strlen (newpasswd));
1029 clear_outbuf (&outbuf);
1031 rc = write_and_clear_outbuf (ctx, &outbuf);
1032 xfree (cache_nonce);
1033 return leave_cmd (ctx, rc);
1039 static const char hlp_readkey[] =
1040 "READKEY <hexstring_with_keygrip>\n"
1042 "Return the public key for the given keygrip.";
1044 cmd_readkey (assuan_context_t ctx, char *line)
1046 ctrl_t ctrl = assuan_get_pointer (ctx);
1048 unsigned char grip[20];
1049 gcry_sexp_t s_pkey = NULL;
1051 if (ctrl->restricted)
1052 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1054 rc = parse_keygrip (ctx, line, grip);
1056 return rc; /* Return immediately as this is already an Assuan error code.*/
1058 rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
1064 len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
1066 buf = xtrymalloc (len);
1068 rc = gpg_error_from_syserror ();
1071 len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
1073 rc = assuan_send_data (ctx, buf, len);
1076 gcry_sexp_release (s_pkey);
1079 return leave_cmd (ctx, rc);
1084 static const char hlp_keyinfo[] =
1085 "KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] <keygrip>\n"
1087 "Return information about the key specified by the KEYGRIP. If the\n"
1088 "key is not available GPG_ERR_NOT_FOUND is returned. If the option\n"
1089 "--list is given the keygrip is ignored and information about all\n"
1090 "available keys are returned. If --ssh-list is given information\n"
1091 "about all keys listed in the sshcontrol are returned. With --with-ssh\n"
1092 "information from sshcontrol is always added to the info. Unless --data\n"
1093 "is given, the information is returned as a status line using the format:\n"
1095 " KEYINFO <keygrip> <type> <serialno> <idstr> <cached> <protection> <fpr>\n"
1097 "KEYGRIP is the keygrip.\n"
1099 "TYPE is describes the type of the key:\n"
1100 " 'D' - Regular key stored on disk,\n"
1101 " 'T' - Key is stored on a smartcard (token),\n"
1102 " 'X' - Unknown type,\n"
1103 " '-' - Key is missing.\n"
1105 "SERIALNO is an ASCII string with the serial number of the\n"
1106 " smartcard. If the serial number is not known a single\n"
1107 " dash '-' is used instead.\n"
1109 "IDSTR is the IDSTR used to distinguish keys on a smartcard. If it\n"
1110 " is not known a dash is used instead.\n"
1112 "CACHED is 1 if the passphrase for the key was found in the key cache.\n"
1113 " If not, a '-' is used instead.\n"
1115 "PROTECTION describes the key protection type:\n"
1116 " 'P' - The key is protected with a passphrase,\n"
1117 " 'C' - The key is not protected,\n"
1118 " '-' - Unknown protection.\n"
1120 "FPR returns the formatted ssh-style fingerprint of the key. It is only\n"
1121 " printed if the option --ssh-fpr has been used. It defaults to '-'.\n"
1123 "TTL is the TTL in seconds for that key or '-' if n/a.\n"
1125 "FLAGS is a word consisting of one-letter flags:\n"
1126 " 'D' - The key has been disabled,\n"
1127 " 'S' - The key is listed in sshcontrol (requires --with-ssh),\n"
1128 " 'c' - Use of the key needs to be confirmed,\n"
1129 " '-' - No flags given.\n"
1131 "More information may be added in the future.";
1133 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
1134 int data, int with_ssh_fpr, int in_ssh,
1135 int ttl, int disabled, int confirm)
1141 unsigned char *shadow_info = NULL;
1142 char *serialno = NULL;
1144 const char *keytypestr;
1146 const char *protectionstr;
1148 int missing_key = 0;
1152 err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
1155 if (in_ssh && gpg_err_code (err) == GPG_ERR_NOT_FOUND)
1161 /* Reformat the grip so that we use uppercase as good style. */
1162 bin2hex (grip, 20, hexgrip);
1165 snprintf (ttlbuf, sizeof ttlbuf, "%d", ttl);
1167 strcpy (ttlbuf, "-");
1171 strcat (flagsbuf, "D");
1173 strcat (flagsbuf, "S");
1175 strcat (flagsbuf, "c");
1177 strcpy (flagsbuf, "-");
1182 protectionstr = "-"; keytypestr = "-";
1188 case PRIVATE_KEY_CLEAR:
1189 case PRIVATE_KEY_OPENPGP_NONE:
1190 protectionstr = "C"; keytypestr = "D";
1192 case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
1194 case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
1196 default: protectionstr = "-"; keytypestr = "X";
1201 /* Compute the ssh fingerprint if requested. */
1206 if (!agent_raw_key_from_file (ctrl, grip, &key))
1208 ssh_get_fingerprint_string (key, &fpr);
1209 gcry_sexp_release (key);
1213 /* Here we have a little race by doing the cache check separately
1214 from the retrieval function. Given that the cache flag is only a
1215 hint, it should not really matter. */
1216 pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
1217 cached = pw ? "1" : "-";
1222 err = parse_shadow_info (shadow_info, &serialno, &idstr, NULL);
1228 err = agent_write_status (ctrl, "KEYINFO",
1231 serialno? serialno : "-",
1243 string = xtryasprintf ("%s %s %s %s %s %s %s %s %s\n",
1244 hexgrip, keytypestr,
1245 serialno? serialno : "-",
1246 idstr? idstr : "-", cached, protectionstr,
1251 err = gpg_error_from_syserror ();
1253 err = assuan_send_data (ctx, string, strlen(string));
1259 xfree (shadow_info);
1266 /* Entry int for the command KEYINFO. This function handles the
1267 command option processing. For details see hlp_keyinfo above. */
1269 cmd_keyinfo (assuan_context_t ctx, char *line)
1271 ctrl_t ctrl = assuan_get_pointer (ctx);
1273 unsigned char grip[20];
1276 int opt_data, opt_ssh_fpr, opt_with_ssh;
1277 ssh_control_file_t cf = NULL;
1279 int disabled, ttl, confirm, is_ssh;
1281 if (ctrl->restricted)
1282 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1284 if (has_option (line, "--ssh-list"))
1287 list_mode = has_option (line, "--list");
1288 opt_data = has_option (line, "--data");
1289 opt_ssh_fpr = has_option (line, "--ssh-fpr");
1290 opt_with_ssh = has_option (line, "--with-ssh");
1291 line = skip_options (line);
1293 if (opt_with_ssh || list_mode == 2)
1294 cf = ssh_open_control_file ();
1300 while (!ssh_read_control_file (cf, hexgrip,
1301 &disabled, &ttl, &confirm))
1303 if (hex2bin (hexgrip, grip, 20) < 0 )
1304 continue; /* Bad hex string. */
1305 err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, 1,
1306 ttl, disabled, confirm);
1316 struct dirent *dir_entry;
1318 dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1321 err = gpg_error_from_syserror ();
1324 dir = opendir (dirname);
1327 err = gpg_error_from_syserror ();
1333 while ( (dir_entry = readdir (dir)) )
1335 if (strlen (dir_entry->d_name) != 44
1336 || strcmp (dir_entry->d_name + 40, ".key"))
1338 strncpy (hexgrip, dir_entry->d_name, 40);
1341 if ( hex2bin (hexgrip, grip, 20) < 0 )
1342 continue; /* Bad hex string. */
1344 disabled = ttl = confirm = is_ssh = 0;
1347 err = ssh_search_control_file (cf, hexgrip,
1348 &disabled, &ttl, &confirm);
1351 else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1355 err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
1356 ttl, disabled, confirm);
1364 err = parse_keygrip (ctx, line, grip);
1367 disabled = ttl = confirm = is_ssh = 0;
1370 err = ssh_search_control_file (cf, line,
1371 &disabled, &ttl, &confirm);
1374 else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1378 err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
1379 ttl, disabled, confirm);
1383 ssh_close_control_file (cf);
1386 if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1387 leave_cmd (ctx, err);
1393 /* Helper for cmd_get_passphrase. */
1395 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1400 assuan_begin_confidential (ctx);
1403 rc = assuan_send_data (ctx, pw, n);
1406 char *p = xtrymalloc_secure (n*2+1);
1408 rc = gpg_error_from_syserror ();
1412 rc = assuan_set_okay_line (ctx, p);
1420 static const char hlp_get_passphrase[] =
1421 "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1422 " [--qualitybar] <cache_id>\n"
1423 " [<error_message> <prompt> <description>]\n"
1425 "This function is usually used to ask for a passphrase to be used\n"
1426 "for conventional encryption, but may also be used by programs which\n"
1427 "need specal handling of passphrases. This command uses a syntax\n"
1428 "which helps clients to use the agent with minimum effort. The\n"
1429 "agent either returns with an error or with a OK followed by the hex\n"
1430 "encoded passphrase. Note that the length of the strings is\n"
1431 "implicitly limited by the maximum length of a command.\n"
1433 "If the option \"--data\" is used the passphrase is returned by usual\n"
1434 "data lines and not on the okay line.\n"
1436 "If the option \"--check\" is used the passphrase constraints checks as\n"
1437 "implemented by gpg-agent are applied. A check is not done if the\n"
1438 "passphrase has been found in the cache.\n"
1440 "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1441 "cache the user will not be asked to enter a passphrase but the error\n"
1442 "code GPG_ERR_NO_DATA is returned. \n"
1444 "If the option \"--qualitybar\" is used a visual indication of the\n"
1445 "entered passphrase quality is shown. (Unless no minimum passphrase\n"
1446 "length has been configured.)";
1448 cmd_get_passphrase (assuan_context_t ctx, char *line)
1450 ctrl_t ctrl = assuan_get_pointer (ctx);
1454 char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1455 const char *desc2 = _("Please re-enter this passphrase");
1457 int opt_data, opt_check, opt_no_ask, opt_qualbar;
1459 char *entry_errtext = NULL;
1461 if (ctrl->restricted)
1462 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1464 opt_data = has_option (line, "--data");
1465 opt_check = has_option (line, "--check");
1466 opt_no_ask = has_option (line, "--no-ask");
1467 if (has_option_name (line, "--repeat"))
1469 p = option_value (line, "--repeat");
1471 opt_repeat = atoi (p);
1475 opt_qualbar = has_option (line, "--qualitybar");
1476 line = skip_options (line);
1479 p = strchr (cacheid, ' ');
1486 p = strchr (errtext, ' ');
1493 p = strchr (prompt, ' ');
1500 p = strchr (desc, ' ');
1502 *p = 0; /* Ignore trailing garbage. */
1506 if (!*cacheid || strlen (cacheid) > 50)
1507 return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1509 return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1511 if (!strcmp (cacheid, "X"))
1513 if (!strcmp (errtext, "X"))
1515 if (!strcmp (prompt, "X"))
1517 if (!strcmp (desc, "X"))
1520 pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_USER) : NULL;
1523 rc = send_back_passphrase (ctx, opt_data, pw);
1526 else if (opt_no_ask)
1527 rc = gpg_error (GPG_ERR_NO_DATA);
1530 /* Note, that we only need to replace the + characters and
1531 should leave the other escaping in place because the escaped
1532 string is send verbatim to the pinentry which does the
1533 unescaping (but not the + replacing) */
1535 plus_to_blank (errtext);
1537 plus_to_blank (prompt);
1539 plus_to_blank (desc);
1542 rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1543 entry_errtext? entry_errtext:errtext,
1544 opt_qualbar, cacheid, CACHE_MODE_USER);
1545 xfree (entry_errtext);
1546 entry_errtext = NULL;
1552 && check_passphrase_constraints (ctrl, response, &entry_errtext))
1557 for (i = 0; i < opt_repeat; i++)
1561 if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
1564 rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1566 cacheid, CACHE_MODE_USER);
1569 if (strcmp (response2, response))
1573 entry_errtext = try_percent_escape
1574 (_("does not match - try again"), NULL);
1577 rc = gpg_error_from_syserror ();
1587 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1588 rc = send_back_passphrase (ctx, opt_data, response);
1594 return leave_cmd (ctx, rc);
1598 static const char hlp_clear_passphrase[] =
1599 "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
1601 "may be used to invalidate the cache entry for a passphrase. The\n"
1602 "function returns with OK even when there is no cached passphrase.\n"
1603 "The --mode=normal option is used to clear an entry for a cacheid\n"
1604 "added by the agent.\n";
1606 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1608 ctrl_t ctrl = assuan_get_pointer (ctx);
1609 char *cacheid = NULL;
1613 if (ctrl->restricted)
1614 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1616 opt_normal = has_option (line, "--mode=normal");
1617 line = skip_options (line);
1619 /* parse the stuff */
1620 for (p=line; *p == ' '; p++)
1623 p = strchr (cacheid, ' ');
1625 *p = 0; /* ignore garbage */
1626 if (!*cacheid || strlen (cacheid) > 50)
1627 return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1629 agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
1632 agent_clear_passphrase (ctrl, cacheid,
1633 opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER);
1639 static const char hlp_get_confirmation[] =
1640 "GET_CONFIRMATION <description>\n"
1642 "This command may be used to ask for a simple confirmation.\n"
1643 "DESCRIPTION is displayed along with a Okay and Cancel button. This\n"
1644 "command uses a syntax which helps clients to use the agent with\n"
1645 "minimum effort. The agent either returns with an error or with a\n"
1646 "OK. Note, that the length of DESCRIPTION is implicitly limited by\n"
1647 "the maximum length of a command. DESCRIPTION should not contain\n"
1648 "any spaces, those must be encoded either percent escaped or simply\n"
1651 cmd_get_confirmation (assuan_context_t ctx, char *line)
1653 ctrl_t ctrl = assuan_get_pointer (ctx);
1658 if (ctrl->restricted)
1659 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1661 /* parse the stuff */
1662 for (p=line; *p == ' '; p++)
1665 p = strchr (desc, ' ');
1667 *p = 0; /* We ignore any garbage -may be later used for other args. */
1670 return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1672 if (!strcmp (desc, "X"))
1675 /* Note, that we only need to replace the + characters and should
1676 leave the other escaping in place because the escaped string is
1677 send verbatim to the pinentry which does the unescaping (but not
1680 plus_to_blank (desc);
1682 rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1683 return leave_cmd (ctx, rc);
1688 static const char hlp_learn[] =
1689 "LEARN [--send] [--sendinfo] [--force]\n"
1691 "Learn something about the currently inserted smartcard. With\n"
1692 "--sendinfo information about the card is returned; with --send\n"
1693 "the available certificates are returned as D lines; with --force\n"
1694 "private key storage will be updated by the result.";
1696 cmd_learn (assuan_context_t ctx, char *line)
1698 ctrl_t ctrl = assuan_get_pointer (ctx);
1700 int send, sendinfo, force;
1702 send = has_option (line, "--send");
1703 sendinfo = send? 1 : has_option (line, "--sendinfo");
1704 force = has_option (line, "--force");
1706 if (ctrl->restricted)
1707 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1709 err = agent_handle_learn (ctrl, send, sendinfo? ctx : NULL, force);
1710 return leave_cmd (ctx, err);
1715 static const char hlp_passwd[] =
1716 "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset]\n"
1717 " [--verify] <hexkeygrip>\n"
1719 "Change the passphrase/PIN for the key identified by keygrip in LINE. If\n"
1720 "--preset is used then the new passphrase will be added to the cache.\n"
1721 "If --verify is used the command asks for the passphrase and verifies\n"
1722 "that the passphrase valid.\n";
1724 cmd_passwd (assuan_context_t ctx, char *line)
1726 ctrl_t ctrl = assuan_get_pointer (ctx);
1729 char *cache_nonce = NULL;
1730 char *passwd_nonce = NULL;
1731 unsigned char grip[20];
1732 gcry_sexp_t s_skey = NULL;
1733 unsigned char *shadow_info = NULL;
1734 char *passphrase = NULL;
1736 int opt_preset, opt_verify;
1738 if (ctrl->restricted)
1739 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1741 opt_preset = has_option (line, "--preset");
1742 cache_nonce = option_value (line, "--cache-nonce");
1743 opt_verify = has_option (line, "--verify");
1746 for (pend = cache_nonce; *pend && !spacep (pend); pend++)
1750 cache_nonce = xtrystrdup (cache_nonce);
1754 err = gpg_error_from_syserror ();
1759 passwd_nonce = option_value (line, "--passwd-nonce");
1762 for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
1766 passwd_nonce = xtrystrdup (passwd_nonce);
1770 err = gpg_error_from_syserror ();
1775 line = skip_options (line);
1777 err = parse_keygrip (ctx, line, grip);
1782 err = agent_key_from_file (ctrl,
1783 opt_verify? NULL : cache_nonce,
1784 ctrl->server_local->keydesc,
1785 grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1786 &s_skey, &passphrase);
1789 else if (shadow_info)
1791 log_error ("changing a smartcard PIN is not yet supported\n");
1792 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1794 else if (opt_verify)
1800 char *newpass = NULL;
1803 newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
1804 err = agent_protect_and_store (ctrl, s_skey, &newpass);
1805 if (!err && passphrase)
1807 /* A passphrase existed on the old key and the change was
1808 successful. Return a nonce for that old passphrase to
1809 let the caller try to unprotect the other subkeys with
1814 gcry_create_nonce (buf, 12);
1815 cache_nonce = bin2hex (buf, 12, NULL);
1818 && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1819 passphrase, CACHE_TTL_NONCE))
1821 assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1822 xfree (ctrl->server_local->last_cache_nonce);
1823 ctrl->server_local->last_cache_nonce = cache_nonce;
1828 /* If we have a new passphrase (which might be empty) we
1829 store it under a passwd nonce so that the caller may
1830 send that nonce again to use it for another key. */
1834 gcry_create_nonce (buf, 12);
1835 passwd_nonce = bin2hex (buf, 12, NULL);
1838 && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1839 newpass, CACHE_TTL_NONCE))
1841 assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1842 xfree (ctrl->server_local->last_passwd_nonce);
1843 ctrl->server_local->last_passwd_nonce = passwd_nonce;
1844 passwd_nonce = NULL;
1848 if (!err && opt_preset)
1851 bin2hex(grip, 20, hexgrip);
1852 err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass,
1853 ctrl->cache_ttl_opt_preset);
1859 xfree (ctrl->server_local->keydesc);
1860 ctrl->server_local->keydesc = NULL;
1864 gcry_sexp_release (s_skey);
1865 xfree (shadow_info);
1866 xfree (cache_nonce);
1867 return leave_cmd (ctx, err);
1871 static const char hlp_preset_passphrase[] =
1872 "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n"
1874 "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1875 "to passwd for the given time, where -1 means infinite and 0 means\n"
1876 "the default (currently only a timeout of -1 is allowed, which means\n"
1877 "to never expire it). If passwd is not provided, ask for it via the\n"
1878 "pinentry module unless --inquire is passed in which case the passphrase\n"
1879 "is retrieved from the client via a server inquire.\n";
1881 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1883 ctrl_t ctrl = assuan_get_pointer (ctx);
1885 char *grip_clear = NULL;
1886 unsigned char *passphrase = NULL;
1891 if (ctrl->restricted)
1892 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1894 if (!opt.allow_preset_passphrase)
1895 return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1897 opt_inquire = has_option (line, "--inquire");
1898 line = skip_options (line);
1900 while (*line && (*line != ' ' && *line != '\t'))
1903 return gpg_error (GPG_ERR_MISSING_VALUE);
1906 while (*line && (*line == ' ' || *line == '\t'))
1909 /* Currently, only infinite timeouts are allowed. */
1911 if (line[0] != '-' || line[1] != '1')
1912 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1915 while (!(*line != ' ' && *line != '\t'))
1918 /* Syntax check the hexstring. */
1920 rc = parse_hexstring (ctx, line, &len);
1925 /* If there is a passphrase, use it. Currently, a passphrase is
1931 rc = set_error (GPG_ERR_ASS_PARAMETER,
1932 "both --inquire and passphrase specified");
1936 /* Do in-place conversion. */
1938 if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1939 rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1941 else if (opt_inquire)
1943 /* Note that the passphrase will be truncated at any null byte and the
1944 * limit is 480 characters. */
1945 size_t maxlen = 480;
1947 rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%zu", maxlen);
1949 rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, maxlen);
1952 rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1956 rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1962 return leave_cmd (ctx, rc);
1967 static const char hlp_scd[] =
1968 "SCD <commands to pass to the scdaemon>\n"
1970 "This is a general quote command to redirect everything to the\n"
1973 cmd_scd (assuan_context_t ctx, char *line)
1975 ctrl_t ctrl = assuan_get_pointer (ctx);
1978 if (ctrl->restricted)
1979 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
1981 rc = divert_generic_cmd (ctrl, line, ctx);
1988 static const char hlp_keywrap_key[] =
1989 "KEYWRAP_KEY [--clear] <mode>\n"
1991 "Return a key to wrap another key. For now the key is returned\n"
1992 "verbatim and and thus makes not much sense because an eavesdropper on\n"
1993 "the gpg-agent connection will see the key as well as the wrapped key.\n"
1994 "However, this function may either be equipped with a public key\n"
1995 "mechanism or not used at all if the key is a pre-shared key. In any\n"
1996 "case wrapping the import and export of keys is a requirement for\n"
1997 "certain cryptographic validations and thus useful. The key persists\n"
1998 "until a RESET command but may be cleared using the option --clear.\n"
2000 "Supported modes are:\n"
2001 " --import - Return a key to import a key into gpg-agent\n"
2002 " --export - Return a key to export a key from gpg-agent";
2004 cmd_keywrap_key (assuan_context_t ctx, char *line)
2006 ctrl_t ctrl = assuan_get_pointer (ctx);
2007 gpg_error_t err = 0;
2008 int clearopt = has_option (line, "--clear");
2010 if (ctrl->restricted)
2011 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2013 assuan_begin_confidential (ctx);
2014 if (has_option (line, "--import"))
2016 xfree (ctrl->server_local->import_key);
2018 ctrl->server_local->import_key = NULL;
2019 else if (!(ctrl->server_local->import_key =
2020 gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
2021 err = gpg_error_from_syserror ();
2023 err = assuan_send_data (ctx, ctrl->server_local->import_key,
2026 else if (has_option (line, "--export"))
2028 xfree (ctrl->server_local->export_key);
2030 ctrl->server_local->export_key = NULL;
2031 else if (!(ctrl->server_local->export_key =
2032 gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
2033 err = gpg_error_from_syserror ();
2035 err = assuan_send_data (ctx, ctrl->server_local->export_key,
2039 err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
2040 assuan_end_confidential (ctx);
2042 return leave_cmd (ctx, err);
2047 static const char hlp_import_key[] =
2048 "IMPORT_KEY [--unattended] [--force] [<cache_nonce>]\n"
2050 "Import a secret key into the key store. The key is expected to be\n"
2051 "encrypted using the current session's key wrapping key (cf. command\n"
2052 "KEYWRAP_KEY) using the AESWRAP-128 algorithm. This function takes\n"
2053 "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
2054 "key data. The unwrapped key must be a canonical S-expression. The\n"
2055 "option --unattended tries to import the key as-is without any\n"
2056 "re-encryption. Existing key can be overwritten with --force.";
2058 cmd_import_key (assuan_context_t ctx, char *line)
2060 ctrl_t ctrl = assuan_get_pointer (ctx);
2064 unsigned char *wrappedkey = NULL;
2065 size_t wrappedkeylen;
2066 gcry_cipher_hd_t cipherhd = NULL;
2067 unsigned char *key = NULL;
2068 size_t keylen, realkeylen;
2069 char *passphrase = NULL;
2070 unsigned char *finalkey = NULL;
2072 unsigned char grip[20];
2073 gcry_sexp_t openpgp_sexp = NULL;
2074 char *cache_nonce = NULL;
2077 if (ctrl->restricted)
2078 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2080 if (!ctrl->server_local->import_key)
2082 err = gpg_error (GPG_ERR_MISSING_KEY);
2086 opt_unattended = has_option (line, "--unattended");
2087 force = has_option (line, "--force");
2088 line = skip_options (line);
2091 for (p=line; *p && *p != ' ' && *p != '\t'; p++)
2095 cache_nonce = xtrystrdup (line);
2097 assuan_begin_confidential (ctx);
2098 err = assuan_inquire (ctx, "KEYDATA",
2099 &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
2100 assuan_end_confidential (ctx);
2103 if (wrappedkeylen < 24)
2105 err = gpg_error (GPG_ERR_INV_LENGTH);
2108 keylen = wrappedkeylen - 8;
2109 key = xtrymalloc_secure (keylen);
2112 err = gpg_error_from_syserror ();
2116 err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2117 GCRY_CIPHER_MODE_AESWRAP, 0);
2120 err = gcry_cipher_setkey (cipherhd,
2121 ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
2124 err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
2127 gcry_cipher_close (cipherhd);
2132 realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
2134 goto leave; /* Invalid canonical encoded S-expression. */
2136 err = keygrip_from_canon_sexp (key, realkeylen, grip);
2139 /* This might be due to an unsupported S-expression format.
2140 Check whether this is openpgp-private-key and trigger that
2142 if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
2147 tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
2148 if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
2152 gcry_sexp_release (openpgp_sexp);
2153 openpgp_sexp = NULL;
2157 goto leave; /* Note that ERR is still set. */
2163 /* In most cases the key is encrypted and thus the conversion
2164 function from the OpenPGP format to our internal format will
2165 ask for a passphrase. That passphrase will be returned and
2166 used to protect the key using the same code as for regular
2171 err = convert_from_openpgp (ctrl, openpgp_sexp, force, grip,
2172 ctrl->server_local->keydesc, cache_nonce,
2173 &key, opt_unattended? NULL : &passphrase);
2176 realkeylen = gcry_sexp_canon_len (key, 0, NULL, &err);
2178 goto leave; /* Invalid canonical encoded S-expression. */
2181 assert (!opt_unattended);
2185 gcry_create_nonce (buf, 12);
2186 cache_nonce = bin2hex (buf, 12, NULL);
2189 && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
2190 passphrase, CACHE_TTL_NONCE))
2191 assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
2194 else if (opt_unattended)
2196 err = set_error (GPG_ERR_ASS_PARAMETER,
2197 "\"--unattended\" may only be used with OpenPGP keys");
2202 if (!force && !agent_key_available (grip))
2203 err = gpg_error (GPG_ERR_EEXIST);
2206 char *prompt = xtryasprintf
2207 (_("Please enter the passphrase to protect the "
2208 "imported object within the %s system."), GNUPG_NAME);
2210 err = gpg_error_from_syserror ();
2212 err = agent_ask_new_passphrase (ctrl, prompt, &passphrase);
2221 err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
2224 err = agent_write_private_key (grip, finalkey, finalkeylen, force);
2227 err = agent_write_private_key (grip, key, realkeylen, force);
2230 gcry_sexp_release (openpgp_sexp);
2234 gcry_cipher_close (cipherhd);
2236 xfree (cache_nonce);
2237 xfree (ctrl->server_local->keydesc);
2238 ctrl->server_local->keydesc = NULL;
2239 return leave_cmd (ctx, err);
2244 static const char hlp_export_key[] =
2245 "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
2247 "Export a secret key from the key store. The key will be encrypted\n"
2248 "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
2249 "using the AESWRAP-128 algorithm. The caller needs to retrieve that key\n"
2250 "prior to using this command. The function takes the keygrip as argument.\n";
2252 cmd_export_key (assuan_context_t ctx, char *line)
2254 ctrl_t ctrl = assuan_get_pointer (ctx);
2256 unsigned char grip[20];
2257 gcry_sexp_t s_skey = NULL;
2258 unsigned char *key = NULL;
2260 gcry_cipher_hd_t cipherhd = NULL;
2261 unsigned char *wrappedkey = NULL;
2262 size_t wrappedkeylen;
2265 char *passphrase = NULL;
2266 unsigned char *shadow_info = NULL;
2270 if (ctrl->restricted)
2271 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2273 openpgp = has_option (line, "--openpgp");
2274 cache_nonce = option_value (line, "--cache-nonce");
2277 for (pend = cache_nonce; *pend && !spacep (pend); pend++)
2281 cache_nonce = xtrystrdup (cache_nonce);
2285 err = gpg_error_from_syserror ();
2289 line = skip_options (line);
2291 if (!ctrl->server_local->export_key)
2293 err = set_error (GPG_ERR_MISSING_KEY, "did you run KEYWRAP_KEY ?");
2297 err = parse_keygrip (ctx, line, grip);
2301 if (agent_key_available (grip))
2303 err = gpg_error (GPG_ERR_NO_SECKEY);
2307 /* Get the key from the file. With the openpgp flag we also ask for
2308 the passphrase so that we can use it to re-encrypt it. */
2309 err = agent_key_from_file (ctrl, cache_nonce,
2310 ctrl->server_local->keydesc, grip,
2311 &shadow_info, CACHE_MODE_IGNORE, NULL, &s_skey,
2312 openpgp ? &passphrase : NULL);
2317 /* Key is on a smartcard. */
2318 err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2324 /* The openpgp option changes the key format into the OpenPGP
2325 key transfer format. The result is already a padded
2326 canonical S-expression. */
2329 err = agent_ask_new_passphrase
2330 (ctrl, _("This key (or subkey) is not protected with a passphrase."
2331 " Please enter a new passphrase to export it."),
2336 err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
2337 if (!err && passphrase)
2342 gcry_create_nonce (buf, 12);
2343 cache_nonce = bin2hex (buf, 12, NULL);
2346 && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
2347 passphrase, CACHE_TTL_NONCE))
2349 assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
2350 xfree (ctrl->server_local->last_cache_nonce);
2351 ctrl->server_local->last_cache_nonce = cache_nonce;
2358 /* Convert into a canonical S-expression and wrap that. */
2359 err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
2363 gcry_sexp_release (s_skey);
2366 err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2367 GCRY_CIPHER_MODE_AESWRAP, 0);
2370 err = gcry_cipher_setkey (cipherhd,
2371 ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
2375 wrappedkeylen = keylen + 8;
2376 wrappedkey = xtrymalloc (wrappedkeylen);
2379 err = gpg_error_from_syserror ();
2383 err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
2388 gcry_cipher_close (cipherhd);
2391 assuan_begin_confidential (ctx);
2392 err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
2393 assuan_end_confidential (ctx);
2397 xfree (cache_nonce);
2400 gcry_cipher_close (cipherhd);
2402 gcry_sexp_release (s_skey);
2403 xfree (ctrl->server_local->keydesc);
2404 ctrl->server_local->keydesc = NULL;
2405 xfree (shadow_info);
2407 return leave_cmd (ctx, err);
2412 static const char hlp_delete_key[] =
2413 "DELETE_KEY [--force] <hexstring_with_keygrip>\n"
2415 "Delete a secret key from the key store.\n"
2416 "Unless --force is used the agent asks the user for confirmation.\n";
2418 cmd_delete_key (assuan_context_t ctx, char *line)
2420 ctrl_t ctrl = assuan_get_pointer (ctx);
2423 unsigned char grip[20];
2425 if (ctrl->restricted)
2426 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2428 force = has_option (line, "--force");
2429 line = skip_options (line);
2431 err = parse_keygrip (ctx, line, grip);
2435 err = agent_delete_key (ctrl, ctrl->server_local->keydesc, grip, force );
2440 xfree (ctrl->server_local->keydesc);
2441 ctrl->server_local->keydesc = NULL;
2443 return leave_cmd (ctx, err);
2448 static const char hlp_keytocard[] =
2449 "KEYTOCARD [--force] <hexstring_with_keygrip> <serialno> <id> <timestamp>\n"
2452 cmd_keytocard (assuan_context_t ctx, char *line)
2454 ctrl_t ctrl = assuan_get_pointer (ctx);
2456 gpg_error_t err = 0;
2457 unsigned char grip[20];
2458 gcry_sexp_t s_skey = NULL;
2459 unsigned char *keydata;
2460 size_t keydatalen, timestamplen;
2461 const char *serialno, *timestamp_str, *id;
2462 unsigned char *shadow_info = NULL;
2465 if (ctrl->restricted)
2466 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2468 force = has_option (line, "--force");
2469 line = skip_options (line);
2471 err = parse_keygrip (ctx, line, grip);
2475 if (agent_key_available (grip))
2476 return gpg_error (GPG_ERR_NO_SECKEY);
2479 while (*line && (*line == ' ' || *line == '\t'))
2482 while (*line && (*line != ' ' && *line != '\t'))
2485 return gpg_error (GPG_ERR_MISSING_VALUE);
2488 while (*line && (*line == ' ' || *line == '\t'))
2491 while (*line && (*line != ' ' && *line != '\t'))
2494 return gpg_error (GPG_ERR_MISSING_VALUE);
2497 while (*line && (*line == ' ' || *line == '\t'))
2499 timestamp_str = line;
2500 while (*line && (*line != ' ' && *line != '\t'))
2504 timestamplen = line - timestamp_str;
2505 if (timestamplen != 15)
2506 return gpg_error (GPG_ERR_INV_VALUE);
2508 err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
2509 &shadow_info, CACHE_MODE_IGNORE, NULL,
2513 xfree (shadow_info);
2518 /* Key is on a smartcard already. */
2519 xfree (shadow_info);
2520 gcry_sexp_release (s_skey);
2521 return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2524 keydatalen = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
2525 keydata = xtrymalloc_secure (keydatalen + 30);
2526 if (keydata == NULL)
2528 gcry_sexp_release (s_skey);
2529 return gpg_error_from_syserror ();
2532 gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, keydata, keydatalen);
2533 gcry_sexp_release (s_skey);
2534 keydatalen--; /* Decrement for last '\0'. */
2535 /* Add timestamp "created-at" in the private key */
2536 timestamp = isotime2epoch (timestamp_str);
2537 snprintf (keydata+keydatalen-1, 30, "(10:created-at10:%010lu))", timestamp);
2538 keydatalen += 10 + 19 - 1;
2539 err = divert_writekey (ctrl, force, serialno, id, keydata, keydatalen);
2542 return leave_cmd (ctx, err);
2547 static const char hlp_getval[] =
2550 "Return the value for KEY from the special environment as created by\n"
2553 cmd_getval (assuan_context_t ctx, char *line)
2555 ctrl_t ctrl = assuan_get_pointer (ctx);
2559 struct putval_item_s *vl;
2561 if (ctrl->restricted)
2562 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2564 for (p=line; *p == ' '; p++)
2567 p = strchr (key, ' ');
2571 for (; *p == ' '; p++)
2574 return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2577 return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2580 for (vl=putval_list; vl; vl = vl->next)
2581 if ( !strcmp (vl->d, key) )
2584 if (vl) /* Got an entry. */
2585 rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2587 return gpg_error (GPG_ERR_NO_DATA);
2589 return leave_cmd (ctx, rc);
2593 static const char hlp_putval[] =
2594 "PUTVAL <key> [<percent_escaped_value>]\n"
2596 "The gpg-agent maintains a kind of environment which may be used to\n"
2597 "store key/value pairs in it, so that they can be retrieved later.\n"
2598 "This may be used by helper daemons to daemonize themself on\n"
2599 "invocation and register them with gpg-agent. Callers of the\n"
2600 "daemon's service may now first try connect to get the information\n"
2601 "for that service from gpg-agent through the GETVAL command and then\n"
2602 "try to connect to that daemon. Only if that fails they may start\n"
2603 "an own instance of the service daemon. \n"
2605 "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2606 "for shell environment variables. PERCENT_ESCAPED_VALUE is the\n"
2607 "corresponding value; they should be similar to the values of\n"
2608 "envronment variables but gpg-agent does not enforce any\n"
2609 "restrictions. If that value is not given any value under that KEY\n"
2610 "is removed from this special environment.";
2612 cmd_putval (assuan_context_t ctx, char *line)
2614 ctrl_t ctrl = assuan_get_pointer (ctx);
2618 size_t valuelen = 0;
2620 struct putval_item_s *vl, *vlprev;
2622 if (ctrl->restricted)
2623 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2625 for (p=line; *p == ' '; p++)
2628 p = strchr (key, ' ');
2632 for (; *p == ' '; p++)
2637 p = strchr (value, ' ');
2640 valuelen = percent_plus_unescape_inplace (value, 0);
2644 return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2647 for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2648 if ( !strcmp (vl->d, key) )
2651 if (vl) /* Delete old entry. */
2654 vlprev->next = vl->next;
2656 putval_list = vl->next;
2660 if (valuelen) /* Add entry. */
2662 vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2664 rc = gpg_error_from_syserror ();
2668 vl->off = strlen (key) + 1;
2669 strcpy (vl->d, key);
2670 memcpy (vl->d + vl->off, value, valuelen);
2671 vl->next = putval_list;
2676 return leave_cmd (ctx, rc);
2682 static const char hlp_updatestartuptty[] =
2683 "UPDATESTARTUPTTY\n"
2685 "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2686 "session. This command is useful to pull future pinentries to\n"
2687 "another screen. It is only required because there is no way in the\n"
2688 "ssh-agent protocol to convey this information.";
2690 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2692 static const char *names[] =
2693 { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2694 ctrl_t ctrl = assuan_get_pointer (ctx);
2695 gpg_error_t err = 0;
2698 char *lc_ctype = NULL;
2699 char *lc_messages = NULL;
2703 if (ctrl->restricted)
2704 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2706 se = session_env_new ();
2708 err = gpg_error_from_syserror ();
2710 for (idx=0; !err && names[idx]; idx++)
2712 const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2714 err = session_env_setenv (se, names[idx], value);
2717 if (!err && ctrl->lc_ctype)
2718 if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2719 err = gpg_error_from_syserror ();
2721 if (!err && ctrl->lc_messages)
2722 if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2723 err = gpg_error_from_syserror ();
2727 session_env_release (se);
2729 xfree (lc_messages);
2733 session_env_release (opt.startup_env);
2734 opt.startup_env = se;
2735 xfree (opt.startup_lc_ctype);
2736 opt.startup_lc_ctype = lc_ctype;
2737 xfree (opt.startup_lc_messages);
2738 opt.startup_lc_messages = lc_messages;
2746 static const char hlp_killagent[] =
2751 cmd_killagent (assuan_context_t ctx, char *line)
2753 ctrl_t ctrl = assuan_get_pointer (ctx);
2757 if (ctrl->restricted)
2758 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2760 ctrl->server_local->stopme = 1;
2761 assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2766 static const char hlp_reloadagent[] =
2769 "This command is an alternative to SIGHUP\n"
2770 "to reload the configuration.";
2772 cmd_reloadagent (assuan_context_t ctx, char *line)
2774 ctrl_t ctrl = assuan_get_pointer (ctx);
2778 if (ctrl->restricted)
2779 return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
2781 agent_sighup_action ();
2787 static const char hlp_getinfo[] =
2790 "Multipurpose function to return a variety of information.\n"
2791 "Supported values for WHAT are:\n"
2793 " version - Return the version of the program.\n"
2794 " pid - Return the process id of the server.\n"
2795 " socket_name - Return the name of the socket.\n"
2796 " ssh_socket_name - Return the name of the ssh socket.\n"
2797 " scd_running - Return OK if the SCdaemon is already running.\n"
2798 " s2k_count - Return the calibrated S2K count.\n"
2799 " std_env_names - List the names of the standard environment.\n"
2800 " std_session_env - List the standard session environment.\n"
2801 " std_startup_env - List the standard startup environment.\n"
2803 " - Returns OK if the command CMD implements the option OPT.\n"
2804 " restricted - Returns OK if the connection is in restricted mode.\n";
2806 cmd_getinfo (assuan_context_t ctx, char *line)
2808 ctrl_t ctrl = assuan_get_pointer (ctx);
2811 if (!strcmp (line, "version"))
2813 const char *s = VERSION;
2814 rc = assuan_send_data (ctx, s, strlen (s));
2816 else if (!strncmp (line, "cmd_has_option", 14)
2817 && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2821 while (*line == ' ' || *line == '\t')
2824 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2828 while (*line && (*line != ' ' && *line != '\t'))
2831 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2835 while (*line == ' ' || *line == '\t')
2838 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2842 if (!command_has_option (cmd, cmdopt))
2843 rc = gpg_error (GPG_ERR_GENERAL);
2848 else if (!strcmp (line, "s2k_count"))
2852 snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2853 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2855 else if (!strcmp (line, "restricted"))
2857 rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_GENERAL);
2859 else if (ctrl->restricted)
2861 rc = gpg_error (GPG_ERR_FORBIDDEN);
2863 /* All sub-commands below are not allowed in restricted mode. */
2864 else if (!strcmp (line, "pid"))
2868 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2869 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2871 else if (!strcmp (line, "socket_name"))
2873 const char *s = get_agent_socket_name ();
2876 rc = assuan_send_data (ctx, s, strlen (s));
2878 rc = gpg_error (GPG_ERR_NO_DATA);
2880 else if (!strcmp (line, "ssh_socket_name"))
2882 const char *s = get_agent_ssh_socket_name ();
2885 rc = assuan_send_data (ctx, s, strlen (s));
2887 rc = gpg_error (GPG_ERR_NO_DATA);
2889 else if (!strcmp (line, "scd_running"))
2891 rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2893 else if (!strcmp (line, "std_env_names"))
2899 while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2901 rc = assuan_send_data (ctx, name, strlen (name)+1);
2903 rc = assuan_send_data (ctx, NULL, 0);
2908 else if (!strcmp (line, "std_session_env")
2909 || !strcmp (line, "std_startup_env"))
2912 const char *name, *value;
2916 while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2918 value = session_env_getenv_or_default
2919 (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2922 string = xtryasprintf ("%s=%s", name, value);
2924 rc = gpg_error_from_syserror ();
2927 rc = assuan_send_data (ctx, string, strlen (string)+1);
2929 rc = assuan_send_data (ctx, NULL, 0);
2937 rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2943 /* This function is called by Libassuan to parse the OPTION command.
2944 It has been registered similar to the other Assuan commands. */
2946 option_handler (assuan_context_t ctx, const char *key, const char *value)
2948 ctrl_t ctrl = assuan_get_pointer (ctx);
2949 gpg_error_t err = 0;
2951 if (!strcmp (key, "agent-awareness"))
2953 /* The value is a version string telling us of which agent
2954 version the caller is aware of. */
2955 ctrl->server_local->allow_fully_canceled =
2956 gnupg_compare_version (value, "2.1.0");
2958 else if (ctrl->restricted)
2960 err = gpg_error (GPG_ERR_FORBIDDEN);
2962 /* All options below are not allowed in restricted mode. */
2963 else if (!strcmp (key, "putenv"))
2965 /* Change the session's environment to be used for the
2966 Pinentry. Valid values are:
2967 <NAME> Delete envvar NAME
2968 <KEY>= Set envvar NAME to the empty string
2969 <KEY>=<VALUE> Set envvar NAME to VALUE
2971 err = session_env_putenv (ctrl->session_env, value);
2973 else if (!strcmp (key, "display"))
2975 err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2977 else if (!strcmp (key, "ttyname"))
2980 err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2982 else if (!strcmp (key, "ttytype"))
2985 err = session_env_setenv (ctrl->session_env, "TERM", value);
2987 else if (!strcmp (key, "lc-ctype"))
2990 xfree (ctrl->lc_ctype);
2991 ctrl->lc_ctype = xtrystrdup (value);
2992 if (!ctrl->lc_ctype)
2993 return out_of_core ();
2995 else if (!strcmp (key, "lc-messages"))
2997 if (ctrl->lc_messages)
2998 xfree (ctrl->lc_messages);
2999 ctrl->lc_messages = xtrystrdup (value);
3000 if (!ctrl->lc_messages)
3001 return out_of_core ();
3003 else if (!strcmp (key, "xauthority"))
3005 err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
3007 else if (!strcmp (key, "pinentry-user-data"))
3009 err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
3011 else if (!strcmp (key, "use-cache-for-signing"))
3012 ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
3013 else if (!strcmp (key, "allow-pinentry-notify"))
3014 ctrl->server_local->allow_pinentry_notify = 1;
3015 else if (!strcmp (key, "pinentry-mode"))
3017 int tmp = parse_pinentry_mode (value);
3019 err = gpg_error (GPG_ERR_INV_VALUE);
3020 else if (tmp == PINENTRY_MODE_LOOPBACK && !opt.allow_loopback_pinentry)
3021 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
3023 ctrl->pinentry_mode = tmp;
3025 else if (!strcmp (key, "cache-ttl-opt-preset"))
3027 ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
3029 else if (!strcmp (key, "s2k-count"))
3031 ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
3032 if (ctrl->s2k_count && ctrl->s2k_count < 65536)
3034 ctrl->s2k_count = 0;
3038 err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
3046 /* Called by libassuan after all commands. ERR is the error from the
3047 last assuan operation and not the one returned from the command. */
3049 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
3051 ctrl_t ctrl = assuan_get_pointer (ctx);
3055 /* Switch off any I/O monitor controlled logging pausing. */
3056 ctrl->server_local->pause_io_logging = 0;
3060 /* This function is called by libassuan for all I/O. We use it here
3061 to disable logging for the GETEVENTCOUNTER commands. This is so
3062 that the debug output won't get cluttered by this primitive
3065 io_monitor (assuan_context_t ctx, void *hook, int direction,
3066 const char *line, size_t linelen)
3068 ctrl_t ctrl = assuan_get_pointer (ctx);
3072 /* Note that we only check for the uppercase name. This allows to
3073 see the logging for debugging if using a non-upercase command
3075 if (ctx && direction == ASSUAN_IO_FROM_PEER
3077 && !strncmp (line, "GETEVENTCOUNTER", 15)
3078 && (linelen == 15 || spacep (line+15)))
3080 ctrl->server_local->pause_io_logging = 1;
3083 return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
3087 /* Return true if the command CMD implements the option OPT. */
3089 command_has_option (const char *cmd, const char *cmdopt)
3091 if (!strcmp (cmd, "GET_PASSPHRASE"))
3093 if (!strcmp (cmdopt, "repeat"))
3101 /* Tell Libassuan about our commands. Also register the other Assuan
3104 register_commands (assuan_context_t ctx)
3108 assuan_handler_t handler;
3109 const char * const help;
3111 { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
3112 { "ISTRUSTED", cmd_istrusted, hlp_istrusted },
3113 { "HAVEKEY", cmd_havekey, hlp_havekey },
3114 { "KEYINFO", cmd_keyinfo, hlp_keyinfo },
3115 { "SIGKEY", cmd_sigkey, hlp_sigkey },
3116 { "SETKEY", cmd_sigkey, hlp_sigkey },
3117 { "SETKEYDESC", cmd_setkeydesc,hlp_setkeydesc },
3118 { "SETHASH", cmd_sethash, hlp_sethash },
3119 { "PKSIGN", cmd_pksign, hlp_pksign },
3120 { "PKDECRYPT", cmd_pkdecrypt, hlp_pkdecrypt },
3121 { "GENKEY", cmd_genkey, hlp_genkey },
3122 { "READKEY", cmd_readkey, hlp_readkey },
3123 { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
3124 { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
3125 { "CLEAR_PASSPHRASE", cmd_clear_passphrase, hlp_clear_passphrase },
3126 { "GET_CONFIRMATION", cmd_get_confirmation, hlp_get_confirmation },
3127 { "LISTTRUSTED", cmd_listtrusted, hlp_listtrusted },
3128 { "MARKTRUSTED", cmd_marktrusted, hlp_martrusted },
3129 { "LEARN", cmd_learn, hlp_learn },
3130 { "PASSWD", cmd_passwd, hlp_passwd },
3133 { "SCD", cmd_scd, hlp_scd },
3134 { "KEYWRAP_KEY", cmd_keywrap_key, hlp_keywrap_key },
3135 { "IMPORT_KEY", cmd_import_key, hlp_import_key },
3136 { "EXPORT_KEY", cmd_export_key, hlp_export_key },
3137 { "DELETE_KEY", cmd_delete_key, hlp_delete_key },
3138 { "GETVAL", cmd_getval, hlp_getval },
3139 { "PUTVAL", cmd_putval, hlp_putval },
3140 { "UPDATESTARTUPTTY", cmd_updatestartuptty, hlp_updatestartuptty },
3141 { "KILLAGENT", cmd_killagent, hlp_killagent },
3142 { "RELOADAGENT", cmd_reloadagent,hlp_reloadagent },
3143 { "GETINFO", cmd_getinfo, hlp_getinfo },
3144 { "KEYTOCARD", cmd_keytocard, hlp_keytocard },
3149 for (i=0; table[i].name; i++)
3151 rc = assuan_register_command (ctx, table[i].name, table[i].handler,
3156 assuan_register_post_cmd_notify (ctx, post_cmd_notify);
3157 assuan_register_reset_notify (ctx, reset_notify);
3158 assuan_register_option_handler (ctx, option_handler);
3163 /* Startup the server. If LISTEN_FD and FD is given as -1, this is a
3164 simple piper server, otherwise it is a regular server. CTRL is the
3165 control structure for this connection; it has only the basic
3168 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
3171 assuan_context_t ctx = NULL;
3173 if (ctrl->restricted)
3175 if (agent_copy_startup_env (ctrl))
3179 rc = assuan_new (&ctx);
3182 log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
3186 if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
3188 assuan_fd_t filedes[2];
3190 filedes[0] = assuan_fdopen (0);
3191 filedes[1] = assuan_fdopen (1);
3192 rc = assuan_init_pipe_server (ctx, filedes);
3194 else if (listen_fd != GNUPG_INVALID_FD)
3196 rc = assuan_init_socket_server (ctx, listen_fd, 0);
3197 /* FIXME: Need to call assuan_sock_set_nonce for Windows. But
3198 this branch is currently not used. */
3202 rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
3206 log_error ("failed to initialize the server: %s\n",
3210 rc = register_commands (ctx);
3213 log_error ("failed to register commands with Assuan: %s\n",
3218 assuan_set_pointer (ctx, ctrl);
3219 ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
3220 ctrl->server_local->assuan_ctx = ctx;
3221 ctrl->server_local->use_cache_for_signing = 1;
3222 ctrl->digest.raw_value = 0;
3224 assuan_set_io_monitor (ctx, io_monitor, NULL);
3225 agent_set_progress_cb (progress_cb, ctrl);
3229 rc = assuan_accept (ctx);
3230 if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
3236 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
3240 rc = assuan_process (ctx);
3243 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
3248 /* Reset the nonce caches. */
3249 clear_nonce_cache (ctrl);
3251 /* Reset the SCD if needed. */
3252 agent_reset_scd (ctrl);
3254 /* Reset the pinentry (in case of popup messages). */
3255 agent_reset_query (ctrl);
3258 assuan_release (ctx);
3259 xfree (ctrl->server_local->keydesc);
3260 xfree (ctrl->server_local->import_key);
3261 xfree (ctrl->server_local->export_key);
3262 if (ctrl->server_local->stopme)
3264 xfree (ctrl->server_local);
3265 ctrl->server_local = NULL;
3269 /* Helper for the pinentry loopback mode. It merely passes the
3270 parameters on to the client. */
3272 pinentry_loopback(ctrl_t ctrl, const char *keyword,
3273 unsigned char **buffer, size_t *size,
3277 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
3279 rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%zu", max_length);
3283 assuan_begin_confidential (ctx);
3284 rc = assuan_inquire (ctx, keyword, buffer, size, max_length);
3285 assuan_end_confidential (ctx);