Add comment about Cherry.
[gnupg.git] / agent / command.c
blob9238a2219e36e95a7e6fe79c22a79905ff1e6388
1 /* command.c - gpg-agent command handler
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3 * 2006, 2008, 2009 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 <http://www.gnu.org/licenses/>.
21 /* FIXME: we should not use the default assuan buffering but setup
22 some buffering in secure mempory to protect session keys etc. */
24 #include <config.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <unistd.h>
32 #include <assert.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <dirent.h>
37 #include <assuan.h>
39 #include "i18n.h"
40 #include "agent.h"
42 /* maximum allowed size of the inquired ciphertext */
43 #define MAXLEN_CIPHERTEXT 4096
44 /* maximum allowed size of the key parameters */
45 #define MAXLEN_KEYPARAM 1024
47 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
50 #if MAX_DIGEST_LEN < 20
51 #error MAX_DIGEST_LEN shorter than keygrip
52 #endif
54 /* Data used to associate an Assuan context with local server data */
55 struct server_local_s
57 assuan_context_t assuan_ctx;
58 int message_fd;
59 int use_cache_for_signing;
60 char *keydesc; /* Allocated description for the next key
61 operation. */
62 int pause_io_logging; /* Used to suppress I/O logging during a command */
63 #ifdef HAVE_W32_SYSTEM
64 int stopme; /* If set to true the agent will be terminated after
65 the end of this session. */
66 #endif
67 int allow_pinentry_notify; /* Set if pinentry notifications should
68 be done. */
72 /* An entry for the getval/putval commands. */
73 struct putval_item_s
75 struct putval_item_s *next;
76 size_t off; /* Offset to the value into DATA. */
77 size_t len; /* Length of the value. */
78 char d[1]; /* Key | Nul | value. */
82 /* A list of key value pairs fpr the getval/putval commands. */
83 static struct putval_item_s *putval_list;
87 /* To help polling clients, we keep track of the number of certain
88 events. This structure keeps those counters. The counters are
89 integers and there should be no problem if they are overflowing as
90 callers need to check only whether a counter changed. The actual
91 values are not meaningful. */
92 struct
94 /* Incremented if any of the other counters below changed. */
95 unsigned int any;
97 /* Incremented if a key is added or removed from the internal privat
98 key database. */
99 unsigned int key;
101 /* Incremented if a change of the card readers stati has been
102 detected. */
103 unsigned int card;
105 } eventcounter;
109 /* Local prototypes. */
110 static int command_has_option (const char *cmd, const char *cmdopt);
115 /* Release the memory buffer MB but first wipe out the used memory. */
116 static void
117 clear_outbuf (membuf_t *mb)
119 void *p;
120 size_t n;
122 p = get_membuf (mb, &n);
123 if (p)
125 memset (p, 0, n);
126 xfree (p);
131 /* Write the content of memory buffer MB as assuan data to CTX and
132 wipe the buffer out afterwards. */
133 static gpg_error_t
134 write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
136 assuan_error_t ae;
137 void *p;
138 size_t n;
140 p = get_membuf (mb, &n);
141 if (!p)
142 return out_of_core ();
143 ae = assuan_send_data (ctx, p, n);
144 memset (p, 0, n);
145 xfree (p);
146 return ae;
150 static void
151 reset_notify (assuan_context_t ctx)
153 ctrl_t ctrl = assuan_get_pointer (ctx);
155 memset (ctrl->keygrip, 0, 20);
156 ctrl->have_keygrip = 0;
157 ctrl->digest.valuelen = 0;
159 xfree (ctrl->server_local->keydesc);
160 ctrl->server_local->keydesc = NULL;
164 /* Check whether the option NAME appears in LINE */
165 static int
166 has_option (const char *line, const char *name)
168 const char *s;
169 int n = strlen (name);
171 s = strstr (line, name);
172 return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
175 /* Same as has_option but does only test for the name of the option
176 and ignores an argument, i.e. with NAME being "--hash" it would
177 return true for "--hash" as well as for "--hash=foo". */
178 static int
179 has_option_name (const char *line, const char *name)
181 const char *s;
182 int n = strlen (name);
184 s = strstr (line, name);
185 return (s && (s == line || spacep (s-1))
186 && (!s[n] || spacep (s+n) || s[n] == '='));
189 /* Return a pointer to the argument of the option with NAME. If such
190 an option is not given, it returns NULL. */
191 static char *
192 option_value (const char *line, const char *name)
194 char *s;
195 int n = strlen (name);
197 s = strstr (line, name);
198 if (s && (s == line || spacep (s-1))
199 && s[n] && (spacep (s+n) || s[n] == '='))
201 s += n + 1;
202 s += strspn (s, " ");
203 if (*s && !spacep(s))
204 return s;
206 return NULL;
210 /* Skip over options. It is assumed that leading spaces have been
211 removed (this is the case for lines passed to a handler from
212 assuan). Blanks after the options are also removed. */
213 static char *
214 skip_options (char *line)
216 while ( *line == '-' && line[1] == '-' )
218 while (*line && !spacep (line))
219 line++;
220 while (spacep (line))
221 line++;
223 return line;
227 /* Replace all '+' by a blank. */
228 static void
229 plus_to_blank (char *s)
231 for (; *s; s++)
233 if (*s == '+')
234 *s = ' ';
239 /* Parse a hex string. Return an Assuan error code or 0 on success and the
240 length of the parsed string in LEN. */
241 static int
242 parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
244 const char *p;
245 size_t n;
247 /* parse the hash value */
248 for (p=string, n=0; hexdigitp (p); p++, n++)
250 if (*p != ' ' && *p != '\t' && *p)
251 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
252 if ((n&1))
253 return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
254 *len = n;
255 return 0;
258 /* Parse the keygrip in STRING into the provided buffer BUF. BUF must
259 provide space for 20 bytes. BUF is not changed if the function
260 returns an error. */
261 static int
262 parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
264 int rc;
265 size_t n;
267 rc = parse_hexstring (ctx, string, &n);
268 if (rc)
269 return rc;
270 n /= 2;
271 if (n != 20)
272 return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip");
274 if (hex2bin (string, buf, 20) < 0)
275 return set_error (GPG_ERR_BUG, "hex2bin");
277 return 0;
281 /* Write an assuan status line. */
282 gpg_error_t
283 agent_write_status (ctrl_t ctrl, const char *keyword, ...)
285 gpg_error_t err = 0;
286 va_list arg_ptr;
287 const char *text;
288 assuan_context_t ctx = ctrl->server_local->assuan_ctx;
289 char buf[950], *p;
290 size_t n;
292 va_start (arg_ptr, keyword);
294 p = buf;
295 n = 0;
296 while ( (text = va_arg (arg_ptr, const char *)) )
298 if (n)
300 *p++ = ' ';
301 n++;
303 for ( ; *text && n < DIM (buf)-3; n++, text++)
305 if (*text == '\n')
307 *p++ = '\\';
308 *p++ = 'n';
310 else if (*text == '\r')
312 *p++ = '\\';
313 *p++ = 'r';
315 else
316 *p++ = *text;
319 *p = 0;
320 err = assuan_write_status (ctx, keyword, buf);
322 va_end (arg_ptr);
323 return err;
327 /* Helper to notify the client about a launched Pinentry. Because
328 that might disturb some older clients, this is only done if enabled
329 via an option. Returns an gpg error code. */
330 gpg_error_t
331 agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
333 char line[100];
335 if (!ctrl || !ctrl->server_local
336 || !ctrl->server_local->allow_pinentry_notify)
337 return 0;
338 snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
339 return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
344 /* GETEVENTCOUNTER
346 Return a a status line named EVENTCOUNTER with the current values
347 of all event counters. The values are decimal numbers in the range
348 0 to UINT_MAX and wrapping around to 0. The actual values should
349 not be relied upon, they shall only be used to detect a change.
351 The currently defined counters are:
353 ANY - Incremented with any change of any of the other counters.
354 KEY - Incremented for added or removed private keys.
355 CARD - Incremented for changes of the card readers stati.
357 static int
358 cmd_geteventcounter (assuan_context_t ctx, char *line)
360 ctrl_t ctrl = assuan_get_pointer (ctx);
361 char any_counter[25];
362 char key_counter[25];
363 char card_counter[25];
365 (void)line;
367 snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any);
368 snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key);
369 snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card);
371 return agent_write_status (ctrl, "EVENTCOUNTER",
372 any_counter,
373 key_counter,
374 card_counter,
375 NULL);
379 /* This function should be called once for all key removals or
380 additions. This function is assured not to do any context
381 switches. */
382 void
383 bump_key_eventcounter (void)
385 eventcounter.key++;
386 eventcounter.any++;
389 /* This function should be called for all card reader status
390 changes. This function is assured not to do any context
391 switches. */
392 void
393 bump_card_eventcounter (void)
395 eventcounter.card++;
396 eventcounter.any++;
402 /* ISTRUSTED <hexstring_with_fingerprint>
404 Return OK when we have an entry with this fingerprint in our
405 trustlist */
406 static int
407 cmd_istrusted (assuan_context_t ctx, char *line)
409 ctrl_t ctrl = assuan_get_pointer (ctx);
410 int rc, n, i;
411 char *p;
412 char fpr[41];
414 /* Parse the fingerprint value. */
415 for (p=line,n=0; hexdigitp (p); p++, n++)
417 if (*p || !(n == 40 || n == 32))
418 return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
419 i = 0;
420 if (n==32)
422 strcpy (fpr, "00000000");
423 i += 8;
425 for (p=line; i < 40; p++, i++)
426 fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
427 fpr[i] = 0;
428 rc = agent_istrusted (ctrl, fpr, NULL);
429 if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
430 return rc;
431 else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
432 return gpg_error (GPG_ERR_NOT_TRUSTED);
433 else
435 log_error ("command is_trusted failed: %s\n", gpg_strerror (rc));
436 return rc;
440 /* LISTTRUSTED
442 List all entries from the trustlist */
443 static int
444 cmd_listtrusted (assuan_context_t ctx, char *line)
446 int rc;
448 (void)line;
450 rc = agent_listtrusted (ctx);
451 if (rc)
452 log_error ("command listtrusted failed: %s\n", gpg_strerror (rc));
453 return rc;
457 /* MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>
459 Store a new key in into the trustlist*/
460 static int
461 cmd_marktrusted (assuan_context_t ctx, char *line)
463 ctrl_t ctrl = assuan_get_pointer (ctx);
464 int rc, n, i;
465 char *p;
466 char fpr[41];
467 int flag;
469 /* parse the fingerprint value */
470 for (p=line,n=0; hexdigitp (p); p++, n++)
472 if (!spacep (p) || !(n == 40 || n == 32))
473 return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
474 i = 0;
475 if (n==32)
477 strcpy (fpr, "00000000");
478 i += 8;
480 for (p=line; i < 40; p++, i++)
481 fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
482 fpr[i] = 0;
484 while (spacep (p))
485 p++;
486 flag = *p++;
487 if ( (flag != 'S' && flag != 'P') || !spacep (p) )
488 return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
489 while (spacep (p))
490 p++;
492 rc = agent_marktrusted (ctrl, p, fpr, flag);
493 if (rc)
494 log_error ("command marktrusted failed: %s\n", gpg_strerror (rc));
495 return rc;
501 /* HAVEKEY <hexstring_with_keygrip>
503 Return success when the secret key is available */
504 static int
505 cmd_havekey (assuan_context_t ctx, char *line)
507 int rc;
508 unsigned char buf[20];
510 rc = parse_keygrip (ctx, line, buf);
511 if (rc)
512 return rc;
514 if (agent_key_available (buf))
515 return gpg_error (GPG_ERR_NO_SECKEY);
517 return 0;
521 /* SIGKEY <hexstring_with_keygrip>
522 SETKEY <hexstring_with_keygrip>
524 Set the key used for a sign or decrypt operation */
525 static int
526 cmd_sigkey (assuan_context_t ctx, char *line)
528 int rc;
529 ctrl_t ctrl = assuan_get_pointer (ctx);
531 rc = parse_keygrip (ctx, line, ctrl->keygrip);
532 if (rc)
533 return rc;
534 ctrl->have_keygrip = 1;
535 return 0;
539 /* SETKEYDESC plus_percent_escaped_string
541 Set a description to be used for the next PKSIGN or PKDECRYPT
542 operation if this operation requires the entry of a passphrase. If
543 this command is not used a default text will be used. Note, that
544 this description implictly selects the label used for the entry
545 box; if the string contains the string PIN (which in general will
546 not be translated), "PIN" is used, otherwise the translation of
547 "passphrase" is used. The description string should not contain
548 blanks unless they are percent or '+' escaped.
550 The description is only valid for the next PKSIGN or PKDECRYPT
551 operation.
553 static int
554 cmd_setkeydesc (assuan_context_t ctx, char *line)
556 ctrl_t ctrl = assuan_get_pointer (ctx);
557 char *desc, *p;
559 for (p=line; *p == ' '; p++)
561 desc = p;
562 p = strchr (desc, ' ');
563 if (p)
564 *p = 0; /* We ignore any garbage; we might late use it for other args. */
566 if (!desc || !*desc)
567 return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
569 /* Note, that we only need to replace the + characters and should
570 leave the other escaping in place because the escaped string is
571 send verbatim to the pinentry which does the unescaping (but not
572 the + replacing) */
573 plus_to_blank (desc);
575 xfree (ctrl->server_local->keydesc);
576 ctrl->server_local->keydesc = xtrystrdup (desc);
577 if (!ctrl->server_local->keydesc)
578 return out_of_core ();
579 return 0;
583 /* SETHASH --hash=<name>|<algonumber> <hexstring>
585 The client can use this command to tell the server about the data
586 (which usually is a hash) to be signed. */
587 static int
588 cmd_sethash (assuan_context_t ctx, char *line)
590 int rc;
591 size_t n;
592 char *p;
593 ctrl_t ctrl = assuan_get_pointer (ctx);
594 unsigned char *buf;
595 char *endp;
596 int algo;
598 /* Parse the alternative hash options which may be used instead of
599 the algo number. */
600 if (has_option_name (line, "--hash"))
602 if (has_option (line, "--hash=sha1"))
603 algo = GCRY_MD_SHA1;
604 else if (has_option (line, "--hash=sha224"))
605 algo = GCRY_MD_SHA224;
606 else if (has_option (line, "--hash=sha256"))
607 algo = GCRY_MD_SHA256;
608 else if (has_option (line, "--hash=sha384"))
609 algo = GCRY_MD_SHA384;
610 else if (has_option (line, "--hash=sha512"))
611 algo = GCRY_MD_SHA512;
612 else if (has_option (line, "--hash=rmd160"))
613 algo = GCRY_MD_RMD160;
614 else if (has_option (line, "--hash=md5"))
615 algo = GCRY_MD_MD5;
616 else if (has_option (line, "--hash=tls-md5sha1"))
617 algo = MD_USER_TLS_MD5SHA1;
618 else
619 return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
621 else
622 algo = 0;
624 line = skip_options (line);
626 if (!algo)
628 /* No hash option has been given: require an algo number instead */
629 algo = (int)strtoul (line, &endp, 10);
630 for (line = endp; *line == ' ' || *line == '\t'; line++)
632 if (!algo || gcry_md_test_algo (algo))
633 return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
635 ctrl->digest.algo = algo;
637 /* Parse the hash value. */
638 rc = parse_hexstring (ctx, line, &n);
639 if (rc)
640 return rc;
641 n /= 2;
642 if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
644 else if (n != 16 && n != 20 && n != 24
645 && n != 28 && n != 32 && n != 48 && n != 64)
646 return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
648 if (n > MAX_DIGEST_LEN)
649 return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
651 buf = ctrl->digest.value;
652 ctrl->digest.valuelen = n;
653 for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
654 buf[n] = xtoi_2 (p);
655 for (; n < ctrl->digest.valuelen; n++)
656 buf[n] = 0;
657 return 0;
661 /* PKSIGN <options>
663 Perform the actual sign operation. Neither input nor output are
664 sensitive to eavesdropping. */
665 static int
666 cmd_pksign (assuan_context_t ctx, char *line)
668 int rc;
669 cache_mode_t cache_mode = CACHE_MODE_NORMAL;
670 ctrl_t ctrl = assuan_get_pointer (ctx);
671 membuf_t outbuf;
673 (void)line;
675 if (opt.ignore_cache_for_signing)
676 cache_mode = CACHE_MODE_IGNORE;
677 else if (!ctrl->server_local->use_cache_for_signing)
678 cache_mode = CACHE_MODE_IGNORE;
680 init_membuf (&outbuf, 512);
682 rc = agent_pksign (ctrl, ctrl->server_local->keydesc,
683 &outbuf, cache_mode);
684 if (rc)
685 clear_outbuf (&outbuf);
686 else
687 rc = write_and_clear_outbuf (ctx, &outbuf);
688 if (rc)
689 log_error ("command pksign failed: %s\n", gpg_strerror (rc));
690 xfree (ctrl->server_local->keydesc);
691 ctrl->server_local->keydesc = NULL;
692 return rc;
695 /* PKDECRYPT <options>
697 Perform the actual decrypt operation. Input is not
698 sensitive to eavesdropping */
699 static int
700 cmd_pkdecrypt (assuan_context_t ctx, char *line)
702 int rc;
703 ctrl_t ctrl = assuan_get_pointer (ctx);
704 unsigned char *value;
705 size_t valuelen;
706 membuf_t outbuf;
708 (void)line;
710 /* First inquire the data to decrypt */
711 rc = assuan_inquire (ctx, "CIPHERTEXT",
712 &value, &valuelen, MAXLEN_CIPHERTEXT);
713 if (rc)
714 return rc;
716 init_membuf (&outbuf, 512);
718 rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
719 value, valuelen, &outbuf);
720 xfree (value);
721 if (rc)
722 clear_outbuf (&outbuf);
723 else
724 rc = write_and_clear_outbuf (ctx, &outbuf);
725 if (rc)
726 log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc));
727 xfree (ctrl->server_local->keydesc);
728 ctrl->server_local->keydesc = NULL;
729 return rc;
733 /* GENKEY
735 Generate a new key, store the secret part and return the public
736 part. Here is an example transaction:
738 C: GENKEY
739 S: INQUIRE KEYPARAM
740 C: D (genkey (rsa (nbits 1024)))
741 C: END
742 S: D (public-key
743 S: D (rsa (n 326487324683264) (e 10001)))
744 S OK key created
747 static int
748 cmd_genkey (assuan_context_t ctx, char *line)
750 ctrl_t ctrl = assuan_get_pointer (ctx);
751 int rc;
752 unsigned char *value;
753 size_t valuelen;
754 membuf_t outbuf;
756 (void)line;
758 /* First inquire the parameters */
759 rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
760 if (rc)
761 return rc;
763 init_membuf (&outbuf, 512);
765 rc = agent_genkey (ctrl, (char*)value, valuelen, &outbuf);
766 xfree (value);
767 if (rc)
768 clear_outbuf (&outbuf);
769 else
770 rc = write_and_clear_outbuf (ctx, &outbuf);
771 if (rc)
772 log_error ("command genkey failed: %s\n", gpg_strerror (rc));
773 return rc;
779 /* READKEY <hexstring_with_keygrip>
781 Return the public key for the given keygrip. */
782 static int
783 cmd_readkey (assuan_context_t ctx, char *line)
785 ctrl_t ctrl = assuan_get_pointer (ctx);
786 int rc;
787 unsigned char grip[20];
788 gcry_sexp_t s_pkey = NULL;
790 rc = parse_keygrip (ctx, line, grip);
791 if (rc)
792 return rc; /* Return immediately as this is already an Assuan error code.*/
794 rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
795 if (!rc)
797 size_t len;
798 unsigned char *buf;
800 len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
801 assert (len);
802 buf = xtrymalloc (len);
803 if (!buf)
804 rc = gpg_error_from_syserror ();
805 else
807 len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
808 assert (len);
809 rc = assuan_send_data (ctx, buf, len);
810 xfree (buf);
812 gcry_sexp_release (s_pkey);
815 if (rc)
816 log_error ("command readkey failed: %s\n", gpg_strerror (rc));
817 return rc;
822 /* KEYINFO [--list] <keygrip>
824 Return information about the key specified by the KEYGRIP. If the
825 key is not available GPG_ERR_NOT_FOUND is returned. If the option
826 --list is given the keygrip is ignored and information about all
827 available keys are returned. The information is returned as a
828 status line with this format:
830 KEYINFO <keygrip> <type> <serialno> <idstr>
832 KEYGRIP is the keygrip.
834 TYPE is describes the type of the key:
835 'D' - Regular key stored on disk,
836 'T' - Key is stored on a smartcard (token).
837 '-' - Unknown type.
839 SERIALNO is an ASCII string with the serial number of the
840 smartcard. If the serial number is not known a single
841 dash '-' is used instead.
843 IDSTR is the IDSTR used to distinguish keys on a smartcard. If it
844 is not known a dash is used instead.
846 More information may be added in the future.
848 static gpg_error_t
849 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip)
851 gpg_error_t err;
852 char hexgrip[40+1];
853 int keytype;
854 unsigned char *shadow_info = NULL;
855 char *serialno = NULL;
856 char *idstr = NULL;
857 const char *keytypestr;
859 err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
860 if (err)
861 goto leave;
863 /* Reformat the grip so that we use uppercase as good style. */
864 bin2hex (grip, 20, hexgrip);
866 if (keytype == PRIVATE_KEY_CLEAR
867 || keytype == PRIVATE_KEY_PROTECTED)
868 keytypestr = "D";
869 else if (keytype == PRIVATE_KEY_SHADOWED)
870 keytypestr = "T";
871 else
872 keytypestr = "-";
874 if (shadow_info)
876 err = parse_shadow_info (shadow_info, &serialno, &idstr);
877 if (err)
878 goto leave;
881 err = agent_write_status (ctrl, "KEYINFO",
882 hexgrip,
883 keytypestr,
884 serialno? serialno : "-",
885 idstr? idstr : "-",
886 NULL);
887 leave:
888 xfree (shadow_info);
889 xfree (serialno);
890 xfree (idstr);
891 return err;
895 static int
896 cmd_keyinfo (assuan_context_t ctx, char *line)
898 ctrl_t ctrl = assuan_get_pointer (ctx);
899 int err;
900 unsigned char grip[20];
901 DIR *dir = NULL;
902 int list_mode;
904 list_mode = has_option (line, "--list");
905 line = skip_options (line);
907 if (list_mode)
909 char *dirname;
910 struct dirent *dir_entry;
911 char hexgrip[41];
913 dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
914 if (!dirname)
916 err = gpg_error_from_syserror ();
917 goto leave;
919 dir = opendir (dirname);
920 if (!dir)
922 err = gpg_error_from_syserror ();
923 xfree (dirname);
924 goto leave;
926 xfree (dirname);
928 while ( (dir_entry = readdir (dir)) )
930 if (strlen (dir_entry->d_name) != 44
931 || strcmp (dir_entry->d_name + 40, ".key"))
932 continue;
933 strncpy (hexgrip, dir_entry->d_name, 40);
934 hexgrip[40] = 0;
936 if ( hex2bin (hexgrip, grip, 20) < 0 )
937 continue; /* Bad hex string. */
939 err = do_one_keyinfo (ctrl, grip);
940 if (err)
941 goto leave;
943 err = 0;
945 else
947 err = parse_keygrip (ctx, line, grip);
948 if (err)
949 goto leave;
950 err = do_one_keyinfo (ctrl, grip);
953 leave:
954 if (dir)
955 closedir (dir);
956 if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
957 log_error ("command keyinfo failed: %s\n", gpg_strerror (err));
958 return err;
963 static int
964 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
966 size_t n;
967 int rc;
969 assuan_begin_confidential (ctx);
970 n = strlen (pw);
971 if (via_data)
972 rc = assuan_send_data (ctx, pw, n);
973 else
975 char *p = xtrymalloc_secure (n*2+1);
976 if (!p)
977 rc = gpg_error_from_syserror ();
978 else
980 bin2hex (pw, n, p);
981 rc = assuan_set_okay_line (ctx, p);
982 xfree (p);
985 return rc;
989 /* GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]
990 [--qualitybar] <cache_id>
991 [<error_message> <prompt> <description>]
993 This function is usually used to ask for a passphrase to be used
994 for conventional encryption, but may also be used by programs which
995 need specal handling of passphrases. This command uses a syntax
996 which helps clients to use the agent with minimum effort. The
997 agent either returns with an error or with a OK followed by the hex
998 encoded passphrase. Note that the length of the strings is
999 implicitly limited by the maximum length of a command.
1001 If the option "--data" is used the passphrase is returned by usual
1002 data lines and not on the okay line.
1004 If the option "--check" is used the passphrase constraints checks as
1005 implemented by gpg-agent are applied. A check is not done if the
1006 passphrase has been found in the cache.
1008 If the option "--no-ask" is used and the passphrase is not in the
1009 cache the user will not be asked to enter a passphrase but the error
1010 code GPG_ERR_NO_DATA is returned.
1012 If the option "--qualitybar" is used a visual indication of the
1013 entered passphrase quality is shown. (Unless no minimum passphrase
1014 length has been configured.)
1017 static int
1018 cmd_get_passphrase (assuan_context_t ctx, char *line)
1020 ctrl_t ctrl = assuan_get_pointer (ctx);
1021 int rc;
1022 const char *pw;
1023 char *response;
1024 char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1025 const char *desc2 = _("Please re-enter this passphrase");
1026 char *p;
1027 void *cache_marker;
1028 int opt_data, opt_check, opt_no_ask, opt_qualbar;
1029 int opt_repeat = 0;
1030 char *repeat_errtext = NULL;
1032 opt_data = has_option (line, "--data");
1033 opt_check = has_option (line, "--check");
1034 opt_no_ask = has_option (line, "--no-ask");
1035 if (has_option_name (line, "--repeat"))
1037 p = option_value (line, "--repeat");
1038 if (p)
1039 opt_repeat = atoi (p);
1040 else
1041 opt_repeat = 1;
1043 opt_qualbar = has_option (line, "--qualitybar");
1044 line = skip_options (line);
1046 cacheid = line;
1047 p = strchr (cacheid, ' ');
1048 if (p)
1050 *p++ = 0;
1051 while (*p == ' ')
1052 p++;
1053 errtext = p;
1054 p = strchr (errtext, ' ');
1055 if (p)
1057 *p++ = 0;
1058 while (*p == ' ')
1059 p++;
1060 prompt = p;
1061 p = strchr (prompt, ' ');
1062 if (p)
1064 *p++ = 0;
1065 while (*p == ' ')
1066 p++;
1067 desc = p;
1068 p = strchr (desc, ' ');
1069 if (p)
1070 *p = 0; /* Ignore trailing garbage. */
1074 if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1075 return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1076 if (!desc)
1077 return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1079 if (!strcmp (cacheid, "X"))
1080 cacheid = NULL;
1081 if (!strcmp (errtext, "X"))
1082 errtext = NULL;
1083 if (!strcmp (prompt, "X"))
1084 prompt = NULL;
1085 if (!strcmp (desc, "X"))
1086 desc = NULL;
1088 pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker)
1089 : NULL;
1090 if (pw)
1092 rc = send_back_passphrase (ctx, opt_data, pw);
1093 agent_unlock_cache_entry (&cache_marker);
1095 else if (opt_no_ask)
1096 rc = gpg_error (GPG_ERR_NO_DATA);
1097 else
1099 /* Note, that we only need to replace the + characters and
1100 should leave the other escaping in place because the escaped
1101 string is send verbatim to the pinentry which does the
1102 unescaping (but not the + replacing) */
1103 if (errtext)
1104 plus_to_blank (errtext);
1105 if (prompt)
1106 plus_to_blank (prompt);
1107 if (desc)
1108 plus_to_blank (desc);
1110 next_try:
1111 rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1112 repeat_errtext? repeat_errtext:errtext,
1113 opt_qualbar);
1114 xfree (repeat_errtext);
1115 repeat_errtext = NULL;
1116 if (!rc)
1118 int i;
1120 if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1122 xfree (response);
1123 goto next_try;
1125 for (i = 0; i < opt_repeat; i++)
1127 char *response2;
1129 rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1130 errtext, 0);
1131 if (rc)
1132 break;
1133 if (strcmp (response2, response))
1135 xfree (response2);
1136 xfree (response);
1137 repeat_errtext = try_percent_escape
1138 (_("does not match - try again"), NULL);
1139 if (!repeat_errtext)
1141 rc = gpg_error_from_syserror ();
1142 break;
1144 goto next_try;
1146 xfree (response2);
1148 if (!rc)
1150 if (cacheid)
1151 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1152 rc = send_back_passphrase (ctx, opt_data, response);
1154 xfree (response);
1158 if (rc)
1159 log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc));
1160 return rc;
1164 /* CLEAR_PASSPHRASE <cache_id>
1166 may be used to invalidate the cache entry for a passphrase. The
1167 function returns with OK even when there is no cached passphrase.
1170 static int
1171 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1173 char *cacheid = NULL;
1174 char *p;
1176 /* parse the stuff */
1177 for (p=line; *p == ' '; p++)
1179 cacheid = p;
1180 p = strchr (cacheid, ' ');
1181 if (p)
1182 *p = 0; /* ignore garbage */
1183 if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1184 return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1186 agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0);
1187 return 0;
1191 /* GET_CONFIRMATION <description>
1193 This command may be used to ask for a simple confirmation.
1194 DESCRIPTION is displayed along with a Okay and Cancel button. This
1195 command uses a syntax which helps clients to use the agent with
1196 minimum effort. The agent either returns with an error or with a
1197 OK. Note, that the length of DESCRIPTION is implicitly limited by
1198 the maximum length of a command. DESCRIPTION should not contain
1199 any spaces, those must be encoded either percent escaped or simply
1200 as '+'.
1203 static int
1204 cmd_get_confirmation (assuan_context_t ctx, char *line)
1206 ctrl_t ctrl = assuan_get_pointer (ctx);
1207 int rc;
1208 char *desc = NULL;
1209 char *p;
1211 /* parse the stuff */
1212 for (p=line; *p == ' '; p++)
1214 desc = p;
1215 p = strchr (desc, ' ');
1216 if (p)
1217 *p = 0; /* We ignore any garbage -may be later used for other args. */
1219 if (!desc || !*desc)
1220 return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1222 if (!strcmp (desc, "X"))
1223 desc = NULL;
1225 /* Note, that we only need to replace the + characters and should
1226 leave the other escaping in place because the escaped string is
1227 send verbatim to the pinentry which does the unescaping (but not
1228 the + replacing) */
1229 if (desc)
1230 plus_to_blank (desc);
1232 rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1233 if (rc)
1234 log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
1235 return rc;
1240 /* LEARN [--send]
1242 Learn something about the currently inserted smartcard. With
1243 --send the new certificates are send back. */
1244 static int
1245 cmd_learn (assuan_context_t ctx, char *line)
1247 ctrl_t ctrl = assuan_get_pointer (ctx);
1248 int rc;
1250 rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1251 if (rc)
1252 log_error ("command learn failed: %s\n", gpg_strerror (rc));
1253 return rc;
1258 /* PASSWD <hexstring_with_keygrip>
1260 Change the passphrase/PIN for the key identified by keygrip in LINE. */
1261 static int
1262 cmd_passwd (assuan_context_t ctx, char *line)
1264 ctrl_t ctrl = assuan_get_pointer (ctx);
1265 int rc;
1266 unsigned char grip[20];
1267 gcry_sexp_t s_skey = NULL;
1268 unsigned char *shadow_info = NULL;
1270 rc = parse_keygrip (ctx, line, grip);
1271 if (rc)
1272 goto leave;
1274 ctrl->in_passwd++;
1275 rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
1276 grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1277 &s_skey);
1278 if (rc)
1280 else if (!s_skey)
1282 log_error ("changing a smartcard PIN is not yet supported\n");
1283 rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1285 else
1286 rc = agent_protect_and_store (ctrl, s_skey);
1287 ctrl->in_passwd--;
1289 xfree (ctrl->server_local->keydesc);
1290 ctrl->server_local->keydesc = NULL;
1292 leave:
1293 gcry_sexp_release (s_skey);
1294 xfree (shadow_info);
1295 if (rc)
1296 log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1297 return rc;
1300 /* PRESET_PASSPHRASE <string_or_keygrip> <timeout> <hexstring>
1302 Set the cached passphrase/PIN for the key identified by the keygrip
1303 to passwd for the given time, where -1 means infinite and 0 means
1304 the default (currently only a timeout of -1 is allowed, which means
1305 to never expire it). If passwd is not provided, ask for it via the
1306 pinentry module. */
1307 static int
1308 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1310 int rc;
1311 char *grip_clear = NULL;
1312 char *passphrase = NULL;
1313 int ttl;
1314 size_t len;
1316 if (!opt.allow_preset_passphrase)
1317 return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1319 grip_clear = line;
1320 while (*line && (*line != ' ' && *line != '\t'))
1321 line++;
1322 if (!*line)
1323 return gpg_error (GPG_ERR_MISSING_VALUE);
1324 *line = '\0';
1325 line++;
1326 while (*line && (*line == ' ' || *line == '\t'))
1327 line++;
1329 /* Currently, only infinite timeouts are allowed. */
1330 ttl = -1;
1331 if (line[0] != '-' || line[1] != '1')
1332 return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1333 line++;
1334 line++;
1335 while (!(*line != ' ' && *line != '\t'))
1336 line++;
1338 /* Syntax check the hexstring. */
1339 rc = parse_hexstring (ctx, line, &len);
1340 if (rc)
1341 return rc;
1342 line[len] = '\0';
1344 /* If there is a passphrase, use it. Currently, a passphrase is
1345 required. */
1346 if (*line)
1348 /* Do in-place conversion. */
1349 passphrase = line;
1350 if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1351 rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1353 else
1354 rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1356 if (!rc)
1357 rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1359 if (rc)
1360 log_error ("command preset_passphrase failed: %s\n", gpg_strerror (rc));
1362 return rc;
1366 /* SCD <commands to pass to the scdaemon>
1368 This is a general quote command to redirect everything to the
1369 SCDAEMON. */
1370 static int
1371 cmd_scd (assuan_context_t ctx, char *line)
1373 ctrl_t ctrl = assuan_get_pointer (ctx);
1374 int rc;
1376 rc = divert_generic_cmd (ctrl, line, ctx);
1378 return rc;
1383 /* GETVAL <key>
1385 Return the value for KEY from the special environment as created by
1386 PUTVAL.
1388 static int
1389 cmd_getval (assuan_context_t ctx, char *line)
1391 int rc = 0;
1392 char *key = NULL;
1393 char *p;
1394 struct putval_item_s *vl;
1396 for (p=line; *p == ' '; p++)
1398 key = p;
1399 p = strchr (key, ' ');
1400 if (p)
1402 *p++ = 0;
1403 for (; *p == ' '; p++)
1405 if (*p)
1406 return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
1408 if (!key || !*key)
1409 return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
1412 for (vl=putval_list; vl; vl = vl->next)
1413 if ( !strcmp (vl->d, key) )
1414 break;
1416 if (vl) /* Got an entry. */
1417 rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
1418 else
1419 return gpg_error (GPG_ERR_NO_DATA);
1421 if (rc)
1422 log_error ("command getval failed: %s\n", gpg_strerror (rc));
1423 return rc;
1427 /* PUTVAL <key> [<percent_escaped_value>]
1429 The gpg-agent maintains a kind of environment which may be used to
1430 store key/value pairs in it, so that they can be retrieved later.
1431 This may be used by helper daemons to daemonize themself on
1432 invocation and register them with gpg-agent. Callers of the
1433 daemon's service may now first try connect to get the information
1434 for that service from gpg-agent through the GETVAL command and then
1435 try to connect to that daemon. Only if that fails they may start
1436 an own instance of the service daemon.
1438 KEY is an an arbitrary symbol with the same syntax rules as keys
1439 for shell environment variables. PERCENT_ESCAPED_VALUE is the
1440 corresponsing value; they should be similar to the values of
1441 envronment variables but gpg-agent does not enforce any
1442 restrictions. If that value is not given any value under that KEY
1443 is removed from this special environment.
1445 static int
1446 cmd_putval (assuan_context_t ctx, char *line)
1448 int rc = 0;
1449 char *key = NULL;
1450 char *value = NULL;
1451 size_t valuelen = 0;
1452 char *p;
1453 struct putval_item_s *vl, *vlprev;
1455 for (p=line; *p == ' '; p++)
1457 key = p;
1458 p = strchr (key, ' ');
1459 if (p)
1461 *p++ = 0;
1462 for (; *p == ' '; p++)
1464 if (*p)
1466 value = p;
1467 p = strchr (value, ' ');
1468 if (p)
1469 *p = 0;
1470 valuelen = percent_plus_unescape_inplace (value, 0);
1473 if (!key || !*key)
1474 return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
1477 for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
1478 if ( !strcmp (vl->d, key) )
1479 break;
1481 if (vl) /* Delete old entry. */
1483 if (vlprev)
1484 vlprev->next = vl->next;
1485 else
1486 putval_list = vl->next;
1487 xfree (vl);
1490 if (valuelen) /* Add entry. */
1492 vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
1493 if (!vl)
1494 rc = gpg_error_from_syserror ();
1495 else
1497 vl->len = valuelen;
1498 vl->off = strlen (key) + 1;
1499 strcpy (vl->d, key);
1500 memcpy (vl->d + vl->off, value, valuelen);
1501 vl->next = putval_list;
1502 putval_list = vl;
1506 if (rc)
1507 log_error ("command putval failed: %s\n", gpg_strerror (rc));
1508 return rc;
1514 /* UPDATESTARTUPTTY
1516 Set startup TTY and X DISPLAY variables to the values of this
1517 session. This command is useful to pull future pinentries to
1518 another screen. It is only required because there is no way in the
1519 ssh-agent protocol to convey this information. */
1520 static int
1521 cmd_updatestartuptty (assuan_context_t ctx, char *line)
1523 ctrl_t ctrl = assuan_get_pointer (ctx);
1525 (void)line;
1527 xfree (opt.startup_display); opt.startup_display = NULL;
1528 xfree (opt.startup_ttyname); opt.startup_ttyname = NULL;
1529 xfree (opt.startup_ttytype); opt.startup_ttytype = NULL;
1530 xfree (opt.startup_lc_ctype); opt.startup_lc_ctype = NULL;
1531 xfree (opt.startup_lc_messages); opt.startup_lc_messages = NULL;
1532 xfree (opt.startup_xauthority); opt.startup_xauthority = NULL;
1534 if (ctrl->display)
1535 opt.startup_display = xtrystrdup (ctrl->display);
1536 if (ctrl->ttyname)
1537 opt.startup_ttyname = xtrystrdup (ctrl->ttyname);
1538 if (ctrl->ttytype)
1539 opt.startup_ttytype = xtrystrdup (ctrl->ttytype);
1540 if (ctrl->lc_ctype)
1541 opt.startup_lc_ctype = xtrystrdup (ctrl->lc_ctype);
1542 if (ctrl->lc_messages)
1543 opt.startup_lc_messages = xtrystrdup (ctrl->lc_messages);
1544 if (ctrl->xauthority)
1545 opt.startup_xauthority = xtrystrdup (ctrl->xauthority);
1546 if (ctrl->pinentry_user_data)
1547 opt.startup_pinentry_user_data = xtrystrdup (ctrl->pinentry_user_data);
1549 return 0;
1554 #ifdef HAVE_W32_SYSTEM
1555 /* KILLAGENT
1557 Under Windows we start the agent on the fly. Thus it also make
1558 sense to allow a client to stop the agent. */
1559 static int
1560 cmd_killagent (assuan_context_t ctx, char *line)
1562 ctrl_t ctrl = assuan_get_pointer (ctx);
1564 (void)line;
1566 ctrl->server_local->stopme = 1;
1567 return gpg_error (GPG_ERR_EOF);
1570 /* RELOADAGENT
1572 As signals are inconvenient under Windows, we provide this command
1573 to allow reloading of the configuration. */
1574 static int
1575 cmd_reloadagent (assuan_context_t ctx, char *line)
1577 (void)ctx;
1578 (void)line;
1580 agent_sighup_action ();
1581 return 0;
1583 #endif /*HAVE_W32_SYSTEM*/
1587 /* GETINFO <what>
1589 Multipurpose function to return a variety of information.
1590 Supported values for WHAT are:
1592 version - Return the version of the program.
1593 pid - Return the process id of the server.
1594 socket_name - Return the name of the socket.
1595 ssh_socket_name - Return the name of the ssh socket.
1596 scd_running - Return OK if the SCdaemon is already running.
1598 cmd_has_option CMD OPT
1599 - Returns OK if the command CMD implements the option OPT.
1601 static int
1602 cmd_getinfo (assuan_context_t ctx, char *line)
1604 int rc = 0;
1606 if (!strcmp (line, "version"))
1608 const char *s = VERSION;
1609 rc = assuan_send_data (ctx, s, strlen (s));
1611 else if (!strcmp (line, "pid"))
1613 char numbuf[50];
1615 snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1616 rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1618 else if (!strcmp (line, "socket_name"))
1620 const char *s = get_agent_socket_name ();
1622 if (s)
1623 rc = assuan_send_data (ctx, s, strlen (s));
1624 else
1625 rc = gpg_error (GPG_ERR_NO_DATA);
1627 else if (!strcmp (line, "ssh_socket_name"))
1629 const char *s = get_agent_ssh_socket_name ();
1631 if (s)
1632 rc = assuan_send_data (ctx, s, strlen (s));
1633 else
1634 rc = gpg_error (GPG_ERR_NO_DATA);
1636 else if (!strcmp (line, "scd_running"))
1638 rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
1640 else if (!strncmp (line, "cmd_has_option", 14)
1641 && (line[14] == ' ' || line[14] == '\t' || !line[14]))
1643 char *cmd, *cmdopt;
1644 line += 14;
1645 while (*line == ' ' || *line == '\t')
1646 line++;
1647 if (!*line)
1648 rc = gpg_error (GPG_ERR_MISSING_VALUE);
1649 else
1651 cmd = line;
1652 while (*line && (*line != ' ' && *line != '\t'))
1653 line++;
1654 if (!*line)
1655 rc = gpg_error (GPG_ERR_MISSING_VALUE);
1656 else
1658 *line++ = 0;
1659 while (*line == ' ' || *line == '\t')
1660 line++;
1661 if (!*line)
1662 rc = gpg_error (GPG_ERR_MISSING_VALUE);
1663 else
1665 cmdopt = line;
1666 if (!command_has_option (cmd, cmdopt))
1667 rc = gpg_error (GPG_ERR_GENERAL);
1672 else
1673 rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1674 return rc;
1679 static int
1680 option_handler (assuan_context_t ctx, const char *key, const char *value)
1682 ctrl_t ctrl = assuan_get_pointer (ctx);
1684 if (!strcmp (key, "display"))
1686 if (ctrl->display)
1687 xfree (ctrl->display);
1688 ctrl->display = xtrystrdup (value);
1689 if (!ctrl->display)
1690 return out_of_core ();
1692 else if (!strcmp (key, "ttyname"))
1694 if (!opt.keep_tty)
1696 if (ctrl->ttyname)
1697 xfree (ctrl->ttyname);
1698 ctrl->ttyname = xtrystrdup (value);
1699 if (!ctrl->ttyname)
1700 return out_of_core ();
1703 else if (!strcmp (key, "ttytype"))
1705 if (!opt.keep_tty)
1707 if (ctrl->ttytype)
1708 xfree (ctrl->ttytype);
1709 ctrl->ttytype = xtrystrdup (value);
1710 if (!ctrl->ttytype)
1711 return out_of_core ();
1714 else if (!strcmp (key, "lc-ctype"))
1716 if (ctrl->lc_ctype)
1717 xfree (ctrl->lc_ctype);
1718 ctrl->lc_ctype = xtrystrdup (value);
1719 if (!ctrl->lc_ctype)
1720 return out_of_core ();
1722 else if (!strcmp (key, "lc-messages"))
1724 if (ctrl->lc_messages)
1725 xfree (ctrl->lc_messages);
1726 ctrl->lc_messages = xtrystrdup (value);
1727 if (!ctrl->lc_messages)
1728 return out_of_core ();
1730 else if (!strcmp (key, "xauthority"))
1732 if (ctrl->xauthority)
1733 xfree (ctrl->xauthority);
1734 ctrl->xauthority = xtrystrdup (value);
1735 if (!ctrl->xauthority)
1736 return out_of_core ();
1738 else if (!strcmp (key, "pinentry-user-data"))
1740 if (ctrl->pinentry_user_data)
1741 xfree (ctrl->pinentry_user_data);
1742 ctrl->pinentry_user_data = xtrystrdup (value);
1743 if (!ctrl->pinentry_user_data)
1744 return out_of_core ();
1746 else if (!strcmp (key, "use-cache-for-signing"))
1747 ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
1748 else if (!strcmp (key, "allow-pinentry-notify"))
1749 ctrl->server_local->allow_pinentry_notify = 1;
1750 else
1751 return gpg_error (GPG_ERR_UNKNOWN_OPTION);
1753 return 0;
1759 /* Called by libassuan after all commands. ERR is the error from the
1760 last assuan operation and not the one returned from the command. */
1761 static void
1762 post_cmd_notify (assuan_context_t ctx, int err)
1764 ctrl_t ctrl = assuan_get_pointer (ctx);
1766 (void)err;
1768 /* Switch off any I/O monitor controlled logging pausing. */
1769 ctrl->server_local->pause_io_logging = 0;
1773 /* This function is called by libassuan for all I/O. We use it here
1774 to disable logging for the GETEVENTCOUNTER commands. This is so
1775 that the debug output won't get cluttered by this primitive
1776 command. */
1777 static unsigned int
1778 io_monitor (assuan_context_t ctx, int direction,
1779 const char *line, size_t linelen)
1781 ctrl_t ctrl = assuan_get_pointer (ctx);
1783 /* Note that we only check for the uppercase name. This allows to
1784 see the logging for debugging if using a non-upercase command
1785 name. */
1786 if (ctx && !direction
1787 && linelen >= 15
1788 && !strncmp (line, "GETEVENTCOUNTER", 15)
1789 && (linelen == 15 || spacep (line+15)))
1791 ctrl->server_local->pause_io_logging = 1;
1794 return ctrl->server_local->pause_io_logging? 1:0;
1798 /* Return true if the commznd CMD implements the option OPT. */
1799 static int
1800 command_has_option (const char *cmd, const char *cmdopt)
1802 if (!strcmp (cmd, "GET_PASSPHRASE"))
1804 if (!strcmp (cmdopt, "repeat"))
1805 return 1;
1808 return 0;
1812 /* Tell the assuan library about our commands */
1813 static int
1814 register_commands (assuan_context_t ctx)
1816 static struct {
1817 const char *name;
1818 int (*handler)(assuan_context_t, char *line);
1819 } table[] = {
1820 { "GETEVENTCOUNTER",cmd_geteventcounter },
1821 { "ISTRUSTED", cmd_istrusted },
1822 { "HAVEKEY", cmd_havekey },
1823 { "KEYINFO", cmd_keyinfo },
1824 { "SIGKEY", cmd_sigkey },
1825 { "SETKEY", cmd_sigkey },
1826 { "SETKEYDESC", cmd_setkeydesc },
1827 { "SETHASH", cmd_sethash },
1828 { "PKSIGN", cmd_pksign },
1829 { "PKDECRYPT", cmd_pkdecrypt },
1830 { "GENKEY", cmd_genkey },
1831 { "READKEY", cmd_readkey },
1832 { "GET_PASSPHRASE", cmd_get_passphrase },
1833 { "PRESET_PASSPHRASE", cmd_preset_passphrase },
1834 { "CLEAR_PASSPHRASE", cmd_clear_passphrase },
1835 { "GET_CONFIRMATION", cmd_get_confirmation },
1836 { "LISTTRUSTED", cmd_listtrusted },
1837 { "MARKTRUSTED", cmd_marktrusted },
1838 { "LEARN", cmd_learn },
1839 { "PASSWD", cmd_passwd },
1840 { "INPUT", NULL },
1841 { "OUTPUT", NULL },
1842 { "SCD", cmd_scd },
1843 { "GETVAL", cmd_getval },
1844 { "PUTVAL", cmd_putval },
1845 { "UPDATESTARTUPTTY", cmd_updatestartuptty },
1846 #ifdef HAVE_W32_SYSTEM
1847 { "KILLAGENT", cmd_killagent },
1848 { "RELOADAGENT", cmd_reloadagent },
1849 #endif
1850 { "GETINFO", cmd_getinfo },
1851 { NULL }
1853 int i, rc;
1855 for (i=0; table[i].name; i++)
1857 rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1858 if (rc)
1859 return rc;
1861 #ifdef HAVE_ASSUAN_SET_IO_MONITOR
1862 assuan_register_post_cmd_notify (ctx, post_cmd_notify);
1863 #endif
1864 assuan_register_reset_notify (ctx, reset_notify);
1865 assuan_register_option_handler (ctx, option_handler);
1866 return 0;
1870 /* Startup the server. If LISTEN_FD and FD is given as -1, this is a
1871 simple piper server, otherwise it is a regular server. CTRL is the
1872 control structure for this connection; it has only the basic
1873 intialization. */
1874 void
1875 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
1877 int rc;
1878 assuan_context_t ctx;
1880 if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
1882 int filedes[2];
1884 filedes[0] = 0;
1885 filedes[1] = 1;
1886 rc = assuan_init_pipe_server (&ctx, filedes);
1888 else if (listen_fd != GNUPG_INVALID_FD)
1890 rc = assuan_init_socket_server_ext (&ctx, listen_fd, 0);
1892 else
1894 rc = assuan_init_socket_server_ext (&ctx, fd, 2);
1896 if (rc)
1898 log_error ("failed to initialize the server: %s\n",
1899 gpg_strerror(rc));
1900 agent_exit (2);
1902 rc = register_commands (ctx);
1903 if (rc)
1905 log_error ("failed to register commands with Assuan: %s\n",
1906 gpg_strerror(rc));
1907 agent_exit (2);
1910 assuan_set_pointer (ctx, ctrl);
1911 ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1912 ctrl->server_local->assuan_ctx = ctx;
1913 ctrl->server_local->message_fd = -1;
1914 ctrl->server_local->use_cache_for_signing = 1;
1915 ctrl->digest.raw_value = 0;
1917 if (DBG_ASSUAN)
1918 assuan_set_log_stream (ctx, log_get_stream ());
1920 #ifdef HAVE_ASSUAN_SET_IO_MONITOR
1921 assuan_set_io_monitor (ctx, io_monitor);
1922 #endif
1924 for (;;)
1926 rc = assuan_accept (ctx);
1927 if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
1929 break;
1931 else if (rc)
1933 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1934 break;
1937 rc = assuan_process (ctx);
1938 if (rc)
1940 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1941 continue;
1945 /* Reset the SCD if needed. */
1946 agent_reset_scd (ctrl);
1948 /* Reset the pinentry (in case of popup messages). */
1949 agent_reset_query (ctrl);
1951 /* Cleanup. */
1952 assuan_deinit_server (ctx);
1953 #ifdef HAVE_W32_SYSTEM
1954 if (ctrl->server_local->stopme)
1955 agent_exit (0);
1956 #endif
1957 xfree (ctrl->server_local);
1958 ctrl->server_local = NULL;