Allow listing of ssh fingerprint with the agent's KEYINFO command.
[gnupg.git] / agent / command.c
1 /* command.c - gpg-agent command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010,
3  *               2011  Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /* FIXME: we should not use the default assuan buffering but setup
22    some buffering in secure mempory to protect session keys etc. */
23
24 #include <config.h>
25
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>
36
37 #include "agent.h"
38 #include <assuan.h>
39 #include "i18n.h"
40 #include "cvt-openpgp.h"
41 #include "../common/ssh-utils.h"
42
43
44 /* Maximum allowed size of the inquired ciphertext.  */
45 #define MAXLEN_CIPHERTEXT 4096
46 /* Maximum allowed size of the key parameters.  */
47 #define MAXLEN_KEYPARAM 1024
48 /* Maximum allowed size of key data as used in inquiries (bytes). */
49 #define MAXLEN_KEYDATA 4096
50 /* The size of the import/export KEK key (in bytes).  */
51 #define KEYWRAP_KEYSIZE (128/8)
52
53 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
54
55
56 #if MAX_DIGEST_LEN < 20
57 #error MAX_DIGEST_LEN shorter than keygrip
58 #endif
59
60 /* Data used to associate an Assuan context with local server data */
61 struct server_local_s
62 {
63   assuan_context_t assuan_ctx;
64   int message_fd;
65   int use_cache_for_signing;
66   char *keydesc;  /* Allocated description for the next key
67                      operation. */
68   int pause_io_logging; /* Used to suppress I/O logging during a command */
69   int stopme;    /* If set to true the agent will be terminated after
70                     the end of this session.  */
71   int allow_pinentry_notify; /* Set if pinentry notifications should
72                                 be done. */
73   void *import_key;  /* Malloced KEK for the import_key command.  */
74   void *export_key;  /* Malloced KEK for the export_key command.  */
75   int allow_fully_canceled; /* Client is aware of GPG_ERR_FULLY_CANCELED.  */
76   char *last_cache_nonce;   /* Last CACHE_NOCNE sent as status (malloced).  */
77   char *last_passwd_nonce;  /* Last PASSWD_NOCNE sent as status (malloced). */
78 };
79
80
81 /* An entry for the getval/putval commands. */
82 struct putval_item_s
83 {
84   struct putval_item_s *next;
85   size_t off;  /* Offset to the value into DATA.  */
86   size_t len;  /* Length of the value.  */
87   char d[1];   /* Key | Nul | value.  */
88 };
89
90
91 /* A list of key value pairs fpr the getval/putval commands.  */
92 static struct putval_item_s *putval_list;
93
94
95 \f
96 /* To help polling clients, we keep track of the number of certain
97    events.  This structure keeps those counters.  The counters are
98    integers and there should be no problem if they are overflowing as
99    callers need to check only whether a counter changed.  The actual
100    values are not meaningful. */
101 struct
102 {
103   /* Incremented if any of the other counters below changed. */
104   unsigned int any;
105
106   /* Incremented if a key is added or removed from the internal privat
107      key database. */
108   unsigned int key;
109
110   /* Incremented if a change of the card readers stati has been
111      detected. */
112   unsigned int card;
113
114 } eventcounter;
115
116
117 \f
118 /*  Local prototypes.  */
119 static int command_has_option (const char *cmd, const char *cmdopt);
120
121
122
123 \f
124 /* Release the memory buffer MB but first wipe out the used memory. */
125 static void
126 clear_outbuf (membuf_t *mb)
127 {
128   void *p;
129   size_t n;
130
131   p = get_membuf (mb, &n);
132   if (p)
133     {
134       memset (p, 0, n);
135       xfree (p);
136     }
137 }
138
139
140 /* Write the content of memory buffer MB as assuan data to CTX and
141    wipe the buffer out afterwards. */
142 static gpg_error_t
143 write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
144 {
145   gpg_error_t ae;
146   void *p;
147   size_t n;
148
149   p = get_membuf (mb, &n);
150   if (!p)
151     return out_of_core ();
152   ae = assuan_send_data (ctx, p, n);
153   memset (p, 0, n);
154   xfree (p);
155   return ae;
156 }
157
158
159 static void
160 clear_nonce_cache (ctrl_t ctrl)
161 {
162   if (ctrl->server_local->last_cache_nonce)
163     {
164       agent_put_cache (ctrl->server_local->last_cache_nonce,
165                        CACHE_MODE_NONCE, NULL, 0);
166       xfree (ctrl->server_local->last_cache_nonce);
167       ctrl->server_local->last_cache_nonce = NULL;
168     }
169   if (ctrl->server_local->last_passwd_nonce)
170     {
171       agent_put_cache (ctrl->server_local->last_passwd_nonce,
172                        CACHE_MODE_NONCE, NULL, 0);
173       xfree (ctrl->server_local->last_passwd_nonce);
174       ctrl->server_local->last_passwd_nonce = NULL;
175     }
176 }
177
178
179 static gpg_error_t
180 reset_notify (assuan_context_t ctx, char *line)
181 {
182   ctrl_t ctrl = assuan_get_pointer (ctx);
183
184   (void) line;
185
186   memset (ctrl->keygrip, 0, 20);
187   ctrl->have_keygrip = 0;
188   ctrl->digest.valuelen = 0;
189
190   xfree (ctrl->server_local->keydesc);
191   ctrl->server_local->keydesc = NULL;
192
193   clear_nonce_cache (ctrl);
194
195   return 0;
196 }
197
198
199 /* Skip over options.
200    Blanks after the options are also removed. */
201 static char *
202 skip_options (const char *line)
203 {
204   while (spacep (line))
205     line++;
206   while ( *line == '-' && line[1] == '-' )
207     {
208       while (*line && !spacep (line))
209         line++;
210       while (spacep (line))
211         line++;
212     }
213   return (char*)line;
214 }
215
216 /* Check whether the option NAME appears in LINE */
217 static int
218 has_option (const char *line, const char *name)
219 {
220   const char *s;
221   int n = strlen (name);
222
223   s = strstr (line, name);
224   if (s && s >= skip_options (line))
225     return 0;
226   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
227 }
228
229 /* Same as has_option but does only test for the name of the option
230    and ignores an argument, i.e. with NAME being "--hash" it would
231    return true for "--hash" as well as for "--hash=foo". */
232 static int
233 has_option_name (const char *line, const char *name)
234 {
235   const char *s;
236   int n = strlen (name);
237
238   s = strstr (line, name);
239   if (s && s >= skip_options (line))
240     return 0;
241   return (s && (s == line || spacep (s-1))
242           && (!s[n] || spacep (s+n) || s[n] == '='));
243 }
244
245 /* Return a pointer to the argument of the option with NAME.  If such
246    an option is not given, it returns NULL. */
247 static char *
248 option_value (const char *line, const char *name)
249 {
250   char *s;
251   int n = strlen (name);
252
253   s = strstr (line, name);
254   if (s && s >= skip_options (line))
255     return NULL;
256   if (s && (s == line || spacep (s-1))
257       && s[n] && (spacep (s+n) || s[n] == '='))
258     {
259       s += n + 1;
260       s += strspn (s, " ");
261       if (*s && !spacep(s))
262         return s;
263     }
264   return NULL;
265 }
266
267
268 /* Replace all '+' by a blank. */
269 static void
270 plus_to_blank (char *s)
271 {
272   for (; *s; s++)
273     {
274       if (*s == '+')
275         *s = ' ';
276     }
277 }
278
279
280 /* Parse a hex string.  Return an Assuan error code or 0 on success and the
281    length of the parsed string in LEN. */
282 static int
283 parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
284 {
285   const char *p;
286   size_t n;
287
288   /* parse the hash value */
289   for (p=string, n=0; hexdigitp (p); p++, n++)
290     ;
291   if (*p != ' ' && *p != '\t' && *p)
292     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
293   if ((n&1))
294     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
295   *len = n;
296   return 0;
297 }
298
299 /* Parse the keygrip in STRING into the provided buffer BUF.  BUF must
300    provide space for 20 bytes. BUF is not changed if the function
301    returns an error. */
302 static int
303 parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
304 {
305   int rc;
306   size_t n = 0;
307
308   rc = parse_hexstring (ctx, string, &n);
309   if (rc)
310     return rc;
311   n /= 2;
312   if (n != 20)
313     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip");
314
315   if (hex2bin (string, buf, 20) < 0)
316     return set_error (GPG_ERR_BUG, "hex2bin");
317
318   return 0;
319 }
320
321
322 /* Write an assuan status line. */
323 gpg_error_t
324 agent_write_status (ctrl_t ctrl, const char *keyword, ...)
325 {
326   gpg_error_t err = 0;
327   va_list arg_ptr;
328   const char *text;
329   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
330   char buf[950], *p;
331   size_t n;
332
333   va_start (arg_ptr, keyword);
334
335   p = buf;
336   n = 0;
337   while ( (text = va_arg (arg_ptr, const char *)) )
338     {
339       if (n)
340         {
341           *p++ = ' ';
342           n++;
343         }
344       for ( ; *text && n < DIM (buf)-3; n++, text++)
345         {
346           if (*text == '\n')
347             {
348               *p++ = '\\';
349               *p++ = 'n';
350             }
351           else if (*text == '\r')
352             {
353               *p++ = '\\';
354               *p++ = 'r';
355             }
356           else
357             *p++ = *text;
358         }
359     }
360   *p = 0;
361   err = assuan_write_status (ctx, keyword, buf);
362
363   va_end (arg_ptr);
364   return err;
365 }
366
367
368 /* Helper to notify the client about a launched Pinentry.  Because
369    that might disturb some older clients, this is only done if enabled
370    via an option.  Returns an gpg error code. */
371 gpg_error_t
372 agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
373 {
374   char line[100];
375
376   if (!ctrl || !ctrl->server_local
377       || !ctrl->server_local->allow_pinentry_notify)
378     return 0;
379   snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
380   return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
381 }
382
383
384 /* Helper to print a message while leaving a command.  */
385 static gpg_error_t
386 leave_cmd (assuan_context_t ctx, gpg_error_t err)
387 {
388   if (err)
389     {
390       const char *name = assuan_get_command_name (ctx);
391       if (!name)
392         name = "?";
393
394       /* Not all users of gpg-agent know about the fully canceled
395          error code; map it back if needed.  */
396       if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
397         {
398           ctrl_t ctrl = assuan_get_pointer (ctx);
399
400           if (!ctrl->server_local->allow_fully_canceled)
401             err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED);
402         }
403
404       /* Most code from common/ does not know the error source, thus
405          we fix this here.  */
406       if (gpg_err_source (err) == GPG_ERR_SOURCE_UNKNOWN)
407         err = gpg_err_make (GPG_ERR_SOURCE_DEFAULT, gpg_err_code (err));
408
409       if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
410         log_error ("command '%s' failed: %s\n", name,
411                    gpg_strerror (err));
412       else
413         log_error ("command '%s' failed: %s <%s>\n", name,
414                    gpg_strerror (err), gpg_strsource (err));
415     }
416   return err;
417 }
418
419
420 \f
421 static const char hlp_geteventcounter[] =
422   "GETEVENTCOUNTER\n"
423   "\n"
424   "Return a a status line named EVENTCOUNTER with the current values\n"
425   "of all event counters.  The values are decimal numbers in the range\n"
426   "0 to UINT_MAX and wrapping around to 0.  The actual values should\n"
427   "not be relied upon, they shall only be used to detect a change.\n"
428   "\n"
429   "The currently defined counters are:\n"
430   "\n"
431   "ANY  - Incremented with any change of any of the other counters.\n"
432   "KEY  - Incremented for added or removed private keys.\n"
433   "CARD - Incremented for changes of the card readers stati.";
434 static gpg_error_t
435 cmd_geteventcounter (assuan_context_t ctx, char *line)
436 {
437   ctrl_t ctrl = assuan_get_pointer (ctx);
438   char any_counter[25];
439   char key_counter[25];
440   char card_counter[25];
441
442   (void)line;
443
444   snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any);
445   snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key);
446   snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card);
447
448   return agent_write_status (ctrl, "EVENTCOUNTER",
449                              any_counter,
450                              key_counter,
451                              card_counter,
452                              NULL);
453 }
454
455
456 /* This function should be called once for all key removals or
457    additions.  This function is assured not to do any context
458    switches. */
459 void
460 bump_key_eventcounter (void)
461 {
462   eventcounter.key++;
463   eventcounter.any++;
464 }
465
466 /* This function should be called for all card reader status
467    changes.  This function is assured not to do any context
468    switches. */
469 void
470 bump_card_eventcounter (void)
471 {
472   eventcounter.card++;
473   eventcounter.any++;
474 }
475
476
477
478 \f
479 static const char hlp_istrusted[] =
480   "ISTRUSTED <hexstring_with_fingerprint>\n"
481   "\n"
482   "Return OK when we have an entry with this fingerprint in our\n"
483   "trustlist";
484 static gpg_error_t
485 cmd_istrusted (assuan_context_t ctx, char *line)
486 {
487   ctrl_t ctrl = assuan_get_pointer (ctx);
488   int rc, n, i;
489   char *p;
490   char fpr[41];
491
492   /* Parse the fingerprint value. */
493   for (p=line,n=0; hexdigitp (p); p++, n++)
494     ;
495   if (*p || !(n == 40 || n == 32))
496     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
497   i = 0;
498   if (n==32)
499     {
500       strcpy (fpr, "00000000");
501       i += 8;
502     }
503   for (p=line; i < 40; p++, i++)
504     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
505   fpr[i] = 0;
506   rc = agent_istrusted (ctrl, fpr, NULL);
507   if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
508     return rc;
509   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
510     return gpg_error (GPG_ERR_NOT_TRUSTED);
511   else
512     return leave_cmd (ctx, rc);
513 }
514
515
516 static const char hlp_listtrusted[] =
517   "LISTTRUSTED\n"
518   "\n"
519   "List all entries from the trustlist.";
520 static gpg_error_t
521 cmd_listtrusted (assuan_context_t ctx, char *line)
522 {
523   int rc;
524
525   (void)line;
526
527   rc = agent_listtrusted (ctx);
528   return leave_cmd (ctx, rc);
529 }
530
531
532 static const char hlp_martrusted[] =
533   "MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>\n"
534   "\n"
535   "Store a new key in into the trustlist.";
536 static gpg_error_t
537 cmd_marktrusted (assuan_context_t ctx, char *line)
538 {
539   ctrl_t ctrl = assuan_get_pointer (ctx);
540   int rc, n, i;
541   char *p;
542   char fpr[41];
543   int flag;
544
545   /* parse the fingerprint value */
546   for (p=line,n=0; hexdigitp (p); p++, n++)
547     ;
548   if (!spacep (p) || !(n == 40 || n == 32))
549     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
550   i = 0;
551   if (n==32)
552     {
553       strcpy (fpr, "00000000");
554       i += 8;
555     }
556   for (p=line; i < 40; p++, i++)
557     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
558   fpr[i] = 0;
559
560   while (spacep (p))
561     p++;
562   flag = *p++;
563   if ( (flag != 'S' && flag != 'P') || !spacep (p) )
564     return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
565   while (spacep (p))
566     p++;
567
568   rc = agent_marktrusted (ctrl, p, fpr, flag);
569   return leave_cmd (ctx, rc);
570 }
571
572
573
574 \f
575 static const char hlp_havekey[] =
576   "HAVEKEY <hexstrings_with_keygrips>\n"
577   "\n"
578   "Return success if at least one of the secret keys with the given\n"
579   "keygrips is available.";
580 static gpg_error_t
581 cmd_havekey (assuan_context_t ctx, char *line)
582 {
583   gpg_error_t err;
584   unsigned char buf[20];
585
586   do
587     {
588       err = parse_keygrip (ctx, line, buf);
589       if (err)
590         return err;
591
592       if (!agent_key_available (buf))
593         return 0; /* Found.  */
594
595       while (*line && *line != ' ' && *line != '\t')
596         line++;
597       while (*line == ' ' || *line == '\t')
598         line++;
599     }
600   while (*line);
601
602   /* No leave_cmd() here because errors are expected and would clutter
603      the log.  */
604   return gpg_error (GPG_ERR_NO_SECKEY);
605 }
606
607
608 static const char hlp_sigkey[] =
609   "SIGKEY <hexstring_with_keygrip>\n"
610   "SETKEY <hexstring_with_keygrip>\n"
611   "\n"
612   "Set the  key used for a sign or decrypt operation.";
613 static gpg_error_t
614 cmd_sigkey (assuan_context_t ctx, char *line)
615 {
616   int rc;
617   ctrl_t ctrl = assuan_get_pointer (ctx);
618
619   rc = parse_keygrip (ctx, line, ctrl->keygrip);
620   if (rc)
621     return rc;
622   ctrl->have_keygrip = 1;
623   return 0;
624 }
625
626
627 static const char hlp_setkeydesc[] =
628   "SETKEYDESC plus_percent_escaped_string\n"
629   "\n"
630   "Set a description to be used for the next PKSIGN, PKDECRYPT, IMPORT_KEY\n"
631   "or EXPORT_KEY operation if this operation requires a passphrase.  If\n"
632   "this command is not used a default text will be used.  Note, that\n"
633   "this description implictly selects the label used for the entry\n"
634   "box; if the string contains the string PIN (which in general will\n"
635   "not be translated), \"PIN\" is used, otherwise the translation of\n"
636   "\"passphrase\" is used.  The description string should not contain\n"
637   "blanks unless they are percent or '+' escaped.\n"
638   "\n"
639   "The description is only valid for the next PKSIGN, PKDECRYPT,\n"
640   "IMPORT_KEY or EXPORT_KEY operation.";
641 static gpg_error_t
642 cmd_setkeydesc (assuan_context_t ctx, char *line)
643 {
644   ctrl_t ctrl = assuan_get_pointer (ctx);
645   char *desc, *p;
646
647   for (p=line; *p == ' '; p++)
648     ;
649   desc = p;
650   p = strchr (desc, ' ');
651   if (p)
652     *p = 0; /* We ignore any garbage; we might late use it for other args. */
653
654   if (!desc || !*desc)
655     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
656
657   /* Note, that we only need to replace the + characters and should
658      leave the other escaping in place because the escaped string is
659      send verbatim to the pinentry which does the unescaping (but not
660      the + replacing) */
661   plus_to_blank (desc);
662
663   xfree (ctrl->server_local->keydesc);
664   ctrl->server_local->keydesc = xtrystrdup (desc);
665   if (!ctrl->server_local->keydesc)
666     return out_of_core ();
667   return 0;
668 }
669
670
671 static const char hlp_sethash[] =
672   "SETHASH (--hash=<name>)|(<algonumber>) <hexstring>\n"
673   "\n"
674   "The client can use this command to tell the server about the data\n"
675   "(which usually is a hash) to be signed.";
676 static gpg_error_t
677 cmd_sethash (assuan_context_t ctx, char *line)
678 {
679   int rc;
680   size_t n;
681   char *p;
682   ctrl_t ctrl = assuan_get_pointer (ctx);
683   unsigned char *buf;
684   char *endp;
685   int algo;
686
687   /* Parse the alternative hash options which may be used instead of
688      the algo number.  */
689   if (has_option_name (line, "--hash"))
690     {
691       if (has_option (line, "--hash=sha1"))
692         algo = GCRY_MD_SHA1;
693       else if (has_option (line, "--hash=sha224"))
694         algo = GCRY_MD_SHA224;
695       else if (has_option (line, "--hash=sha256"))
696         algo = GCRY_MD_SHA256;
697       else if (has_option (line, "--hash=sha384"))
698         algo = GCRY_MD_SHA384;
699       else if (has_option (line, "--hash=sha512"))
700         algo = GCRY_MD_SHA512;
701       else if (has_option (line, "--hash=rmd160"))
702         algo = GCRY_MD_RMD160;
703       else if (has_option (line, "--hash=md5"))
704         algo = GCRY_MD_MD5;
705       else if (has_option (line, "--hash=tls-md5sha1"))
706         algo = MD_USER_TLS_MD5SHA1;
707       else
708         return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
709     }
710   else
711     algo = 0;
712
713   line = skip_options (line);
714
715   if (!algo)
716     {
717       /* No hash option has been given: require an algo number instead  */
718       algo = (int)strtoul (line, &endp, 10);
719       for (line = endp; *line == ' ' || *line == '\t'; line++)
720         ;
721       if (!algo || gcry_md_test_algo (algo))
722         return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
723     }
724   ctrl->digest.algo = algo;
725   ctrl->digest.raw_value = 0;
726
727   /* Parse the hash value. */
728   n = 0;
729   rc = parse_hexstring (ctx, line, &n);
730   if (rc)
731     return rc;
732   n /= 2;
733   if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
734     ;
735   else if (n != 16 && n != 20 && n != 24
736            && n != 28 && n != 32 && n != 48 && n != 64)
737     return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
738
739   if (n > MAX_DIGEST_LEN)
740     return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
741
742   buf = ctrl->digest.value;
743   ctrl->digest.valuelen = n;
744   for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
745     buf[n] = xtoi_2 (p);
746   for (; n < ctrl->digest.valuelen; n++)
747     buf[n] = 0;
748   return 0;
749 }
750
751
752 static const char hlp_pksign[] =
753   "PKSIGN [<options>] [<cache_nonce>]\n"
754   "\n"
755   "Perform the actual sign operation.  Neither input nor output are\n"
756   "sensitive to eavesdropping.";
757 static gpg_error_t
758 cmd_pksign (assuan_context_t ctx, char *line)
759 {
760   int rc;
761   cache_mode_t cache_mode = CACHE_MODE_NORMAL;
762   ctrl_t ctrl = assuan_get_pointer (ctx);
763   membuf_t outbuf;
764   char *cache_nonce = NULL;
765   char *p;
766
767   line = skip_options (line);
768
769   p = line;
770   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
771     ;
772   *p = '\0';
773   if (*line)
774     cache_nonce = xtrystrdup (line);
775
776   if (opt.ignore_cache_for_signing)
777     cache_mode = CACHE_MODE_IGNORE;
778   else if (!ctrl->server_local->use_cache_for_signing)
779     cache_mode = CACHE_MODE_IGNORE;
780
781   init_membuf (&outbuf, 512);
782
783   rc = agent_pksign (ctrl, cache_nonce, ctrl->server_local->keydesc,
784                      &outbuf, cache_mode);
785   if (rc)
786     clear_outbuf (&outbuf);
787   else
788     rc = write_and_clear_outbuf (ctx, &outbuf);
789
790   xfree (cache_nonce);
791   xfree (ctrl->server_local->keydesc);
792   ctrl->server_local->keydesc = NULL;
793   return leave_cmd (ctx, rc);
794 }
795
796
797 static const char hlp_pkdecrypt[] =
798   "PKDECRYPT [<options>]\n"
799   "\n"
800   "Perform the actual decrypt operation.  Input is not\n"
801   "sensitive to eavesdropping.";
802 static gpg_error_t
803 cmd_pkdecrypt (assuan_context_t ctx, char *line)
804 {
805   int rc;
806   ctrl_t ctrl = assuan_get_pointer (ctx);
807   unsigned char *value;
808   size_t valuelen;
809   membuf_t outbuf;
810
811   (void)line;
812
813   /* First inquire the data to decrypt */
814   rc = assuan_inquire (ctx, "CIPHERTEXT",
815                        &value, &valuelen, MAXLEN_CIPHERTEXT);
816   if (rc)
817     return rc;
818
819   init_membuf (&outbuf, 512);
820
821   rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
822                         value, valuelen, &outbuf);
823   xfree (value);
824   if (rc)
825     clear_outbuf (&outbuf);
826   else
827     rc = write_and_clear_outbuf (ctx, &outbuf);
828   xfree (ctrl->server_local->keydesc);
829   ctrl->server_local->keydesc = NULL;
830   return leave_cmd (ctx, rc);
831 }
832
833
834 static const char hlp_genkey[] =
835   "GENKEY [--no-protection] [--preset] [<cache_nonce>]\n"
836   "\n"
837   "Generate a new key, store the secret part and return the public\n"
838   "part.  Here is an example transaction:\n"
839   "\n"
840   "  C: GENKEY\n"
841   "  S: INQUIRE KEYPARAM\n"
842   "  C: D (genkey (rsa (nbits  1024)))\n"
843   "  C: END\n"
844   "  S: D (public-key\n"
845   "  S: D   (rsa (n 326487324683264) (e 10001)))\n"
846   "  S: OK key created\n"
847   "\n"
848   "When the --preset option is used the passphrase for the generated\n"
849   "key will be added to the cache.\n"
850   "\n";
851 static gpg_error_t
852 cmd_genkey (assuan_context_t ctx, char *line)
853 {
854   ctrl_t ctrl = assuan_get_pointer (ctx);
855   int rc;
856   int no_protection;
857   unsigned char *value;
858   size_t valuelen;
859   membuf_t outbuf;
860   char *cache_nonce = NULL;
861   int opt_preset;
862   char *p;
863
864   opt_preset = has_option (line, "--preset");
865   no_protection = has_option (line, "--no-protection");
866   line = skip_options (line);
867
868   p = line;
869   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
870     ;
871   *p = '\0';
872   if (*line)
873     cache_nonce = xtrystrdup (line);
874
875   /* First inquire the parameters */
876   rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
877   if (rc)
878     return rc;
879
880   init_membuf (&outbuf, 512);
881
882   rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
883                      opt_preset, &outbuf);
884   xfree (value);
885   if (rc)
886     clear_outbuf (&outbuf);
887   else
888     rc = write_and_clear_outbuf (ctx, &outbuf);
889   xfree (cache_nonce);
890   return leave_cmd (ctx, rc);
891 }
892
893
894
895 \f
896 static const char hlp_readkey[] =
897   "READKEY <hexstring_with_keygrip>\n"
898   "\n"
899   "Return the public key for the given keygrip.";
900 static gpg_error_t
901 cmd_readkey (assuan_context_t ctx, char *line)
902 {
903   ctrl_t ctrl = assuan_get_pointer (ctx);
904   int rc;
905   unsigned char grip[20];
906   gcry_sexp_t s_pkey = NULL;
907
908   rc = parse_keygrip (ctx, line, grip);
909   if (rc)
910     return rc; /* Return immediately as this is already an Assuan error code.*/
911
912   rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
913   if (!rc)
914     {
915       size_t len;
916       unsigned char *buf;
917
918       len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
919       assert (len);
920       buf = xtrymalloc (len);
921       if (!buf)
922         rc = gpg_error_from_syserror ();
923       else
924         {
925           len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
926           assert (len);
927           rc = assuan_send_data (ctx, buf, len);
928           xfree (buf);
929         }
930       gcry_sexp_release (s_pkey);
931     }
932
933   return leave_cmd (ctx, rc);
934 }
935
936
937 \f
938 static const char hlp_keyinfo[] =
939   "KEYINFO [--list] [--data] [--ssh-fpr] <keygrip>\n"
940   "\n"
941   "Return information about the key specified by the KEYGRIP.  If the\n"
942   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
943   "--list is given the keygrip is ignored and information about all\n"
944   "available keys are returned.  The information is returned as a\n"
945   "status line unless --data was specified, with this format:\n"
946   "\n"
947   "  KEYINFO <keygrip> <type> <serialno> <idstr> <cached> <protection> <fpr>\n"
948   "\n"
949   "KEYGRIP is the keygrip.\n"
950   "\n"
951   "TYPE is describes the type of the key:\n"
952   "    'D' - Regular key stored on disk,\n"
953   "    'T' - Key is stored on a smartcard (token),\n"
954   "    '-' - Unknown type.\n"
955   "\n"
956   "SERIALNO is an ASCII string with the serial number of the\n"
957   "         smartcard.  If the serial number is not known a single\n"
958   "         dash '-' is used instead.\n"
959   "\n"
960   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
961   "      is not known a dash is used instead.\n"
962   "\n"
963   "CACHED is 1 if the passphrase for the key was found in the key cache.\n"
964   "       If not, a '-' is used instead.\n"
965   "\n"
966   "PROTECTION describes the key protection type:\n"
967   "    'P' - The key is protected with a passphrase,\n"
968   "    'C' - The key is not protected,\n"
969   "    '-' - Unknown protection.\n"
970   "\n"
971   "FPR returns the formatted ssh-style fingerprint of the key.  It is only\n"
972   "    print if the option --ssh-fpr has been used. '-' is printed if the\n"
973   "    fingerprint is not available.\n"
974   "\n"
975   "More information may be added in the future.";
976 static gpg_error_t
977 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
978                 int data, int with_ssh_fpr)
979 {
980   gpg_error_t err;
981   char hexgrip[40+1];
982   char *fpr = NULL;
983   int keytype;
984   unsigned char *shadow_info = NULL;
985   char *serialno = NULL;
986   char *idstr = NULL;
987   const char *keytypestr;
988   const char *cached;
989   const char *protectionstr;
990   char *pw;
991
992   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
993   if (err)
994     goto leave;
995
996   /* Reformat the grip so that we use uppercase as good style. */
997   bin2hex (grip, 20, hexgrip);
998
999   switch (keytype)
1000     {
1001     case PRIVATE_KEY_CLEAR: protectionstr = "C"; keytypestr = "D";
1002       break;
1003     case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
1004       break;
1005     case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
1006       break;
1007     default: protectionstr = "-"; keytypestr = "-";
1008       break;
1009     }
1010
1011   /* Compute the ssh fingerprint if requested.  */
1012   if (with_ssh_fpr)
1013     {
1014       gcry_sexp_t key;
1015
1016       if (!agent_raw_key_from_file (ctrl, grip, &key))
1017         {
1018           ssh_get_fingerprint_string (key, &fpr);
1019           gcry_sexp_release (key);
1020         }
1021     }
1022
1023   /* Here we have a little race by doing the cache check separately
1024      from the retrieval function.  Given that the cache flag is only a
1025      hint, it should not really matter.  */
1026   pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
1027   cached = pw ? "1" : "-";
1028   xfree (pw);
1029
1030   if (shadow_info)
1031     {
1032       err = parse_shadow_info (shadow_info, &serialno, &idstr);
1033       if (err)
1034         goto leave;
1035     }
1036
1037   if (!data)
1038     err = agent_write_status (ctrl, "KEYINFO",
1039                               hexgrip,
1040                               keytypestr,
1041                               serialno? serialno : "-",
1042                               idstr? idstr : "-",
1043                               cached,
1044                               protectionstr,
1045                               fpr? fpr : "-",
1046                               NULL);
1047   else
1048     {
1049       char *string;
1050
1051       string = xtryasprintf ("%s %s %s %s %s %s %s\n",
1052                              hexgrip, keytypestr,
1053                              serialno? serialno : "-",
1054                              idstr? idstr : "-", cached, protectionstr,
1055                              fpr? fpr : "-");
1056       if (!string)
1057         err = gpg_error_from_syserror ();
1058       else
1059         err = assuan_send_data (ctx, string, strlen(string));
1060       xfree (string);
1061     }
1062
1063  leave:
1064   xfree (fpr);
1065   xfree (shadow_info);
1066   xfree (serialno);
1067   xfree (idstr);
1068   return err;
1069 }
1070
1071
1072 static gpg_error_t
1073 cmd_keyinfo (assuan_context_t ctx, char *line)
1074 {
1075   ctrl_t ctrl = assuan_get_pointer (ctx);
1076   int err;
1077   unsigned char grip[20];
1078   DIR *dir = NULL;
1079   int list_mode;
1080   int opt_data, opt_ssh_fpr;
1081
1082   list_mode = has_option (line, "--list");
1083   opt_data = has_option (line, "--data");
1084   opt_ssh_fpr = has_option (line, "--ssh-fpr");
1085   line = skip_options (line);
1086
1087   if (list_mode)
1088     {
1089       char *dirname;
1090       struct dirent *dir_entry;
1091       char hexgrip[41];
1092
1093       dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1094       if (!dirname)
1095         {
1096           err = gpg_error_from_syserror ();
1097           goto leave;
1098         }
1099       dir = opendir (dirname);
1100       if (!dir)
1101         {
1102           err = gpg_error_from_syserror ();
1103           xfree (dirname);
1104           goto leave;
1105         }
1106       xfree (dirname);
1107
1108       while ( (dir_entry = readdir (dir)) )
1109         {
1110           if (strlen (dir_entry->d_name) != 44
1111               || strcmp (dir_entry->d_name + 40, ".key"))
1112             continue;
1113           strncpy (hexgrip, dir_entry->d_name, 40);
1114           hexgrip[40] = 0;
1115
1116           if ( hex2bin (hexgrip, grip, 20) < 0 )
1117             continue; /* Bad hex string.  */
1118
1119           err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr);
1120           if (err)
1121             goto leave;
1122         }
1123       err = 0;
1124     }
1125   else
1126     {
1127       err = parse_keygrip (ctx, line, grip);
1128       if (err)
1129         goto leave;
1130       err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr);
1131     }
1132
1133  leave:
1134   if (dir)
1135     closedir (dir);
1136   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1137     leave_cmd (ctx, err);
1138   return err;
1139 }
1140
1141
1142 \f
1143 static int
1144 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1145 {
1146   size_t n;
1147   int rc;
1148
1149   assuan_begin_confidential (ctx);
1150   n = strlen (pw);
1151   if (via_data)
1152     rc = assuan_send_data (ctx, pw, n);
1153   else
1154     {
1155       char *p = xtrymalloc_secure (n*2+1);
1156       if (!p)
1157         rc = gpg_error_from_syserror ();
1158       else
1159         {
1160           bin2hex (pw, n, p);
1161           rc = assuan_set_okay_line (ctx, p);
1162           xfree (p);
1163         }
1164     }
1165   return rc;
1166 }
1167
1168
1169 static const char hlp_get_passphrase[] =
1170   "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1171   "               [--qualitybar] <cache_id>\n"
1172   "               [<error_message> <prompt> <description>]\n"
1173   "\n"
1174   "This function is usually used to ask for a passphrase to be used\n"
1175   "for conventional encryption, but may also be used by programs which\n"
1176   "need specal handling of passphrases.  This command uses a syntax\n"
1177   "which helps clients to use the agent with minimum effort.  The\n"
1178   "agent either returns with an error or with a OK followed by the hex\n"
1179   "encoded passphrase.  Note that the length of the strings is\n"
1180   "implicitly limited by the maximum length of a command.\n"
1181   "\n"
1182   "If the option \"--data\" is used the passphrase is returned by usual\n"
1183   "data lines and not on the okay line.\n"
1184   "\n"
1185   "If the option \"--check\" is used the passphrase constraints checks as\n"
1186   "implemented by gpg-agent are applied.  A check is not done if the\n"
1187   "passphrase has been found in the cache.\n"
1188   "\n"
1189   "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1190   "cache the user will not be asked to enter a passphrase but the error\n"
1191   "code GPG_ERR_NO_DATA is returned.  \n"
1192   "\n"
1193   "If the option \"--qualitybar\" is used a visual indication of the\n"
1194   "entered passphrase quality is shown.  (Unless no minimum passphrase\n"
1195   "length has been configured.)";
1196 static gpg_error_t
1197 cmd_get_passphrase (assuan_context_t ctx, char *line)
1198 {
1199   ctrl_t ctrl = assuan_get_pointer (ctx);
1200   int rc;
1201   char *pw;
1202   char *response;
1203   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1204   const char *desc2 = _("Please re-enter this passphrase");
1205   char *p;
1206   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1207   int opt_repeat = 0;
1208   char *repeat_errtext = NULL;
1209
1210   opt_data = has_option (line, "--data");
1211   opt_check = has_option (line, "--check");
1212   opt_no_ask = has_option (line, "--no-ask");
1213   if (has_option_name (line, "--repeat"))
1214     {
1215       p = option_value (line, "--repeat");
1216       if (p)
1217         opt_repeat = atoi (p);
1218       else
1219         opt_repeat = 1;
1220     }
1221   opt_qualbar = has_option (line, "--qualitybar");
1222   line = skip_options (line);
1223
1224   cacheid = line;
1225   p = strchr (cacheid, ' ');
1226   if (p)
1227     {
1228       *p++ = 0;
1229       while (*p == ' ')
1230         p++;
1231       errtext = p;
1232       p = strchr (errtext, ' ');
1233       if (p)
1234         {
1235           *p++ = 0;
1236           while (*p == ' ')
1237             p++;
1238           prompt = p;
1239           p = strchr (prompt, ' ');
1240           if (p)
1241             {
1242               *p++ = 0;
1243               while (*p == ' ')
1244                 p++;
1245               desc = p;
1246               p = strchr (desc, ' ');
1247               if (p)
1248                 *p = 0; /* Ignore trailing garbage. */
1249             }
1250         }
1251     }
1252   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1253     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1254   if (!desc)
1255     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1256
1257   if (!strcmp (cacheid, "X"))
1258     cacheid = NULL;
1259   if (!strcmp (errtext, "X"))
1260     errtext = NULL;
1261   if (!strcmp (prompt, "X"))
1262     prompt = NULL;
1263   if (!strcmp (desc, "X"))
1264     desc = NULL;
1265
1266   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL) : NULL;
1267   if (pw)
1268     {
1269       rc = send_back_passphrase (ctx, opt_data, pw);
1270       xfree (pw);
1271     }
1272   else if (opt_no_ask)
1273     rc = gpg_error (GPG_ERR_NO_DATA);
1274   else
1275     {
1276       /* Note, that we only need to replace the + characters and
1277          should leave the other escaping in place because the escaped
1278          string is send verbatim to the pinentry which does the
1279          unescaping (but not the + replacing) */
1280       if (errtext)
1281         plus_to_blank (errtext);
1282       if (prompt)
1283         plus_to_blank (prompt);
1284       if (desc)
1285         plus_to_blank (desc);
1286
1287     next_try:
1288       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1289                                  repeat_errtext? repeat_errtext:errtext,
1290                                  opt_qualbar);
1291       xfree (repeat_errtext);
1292       repeat_errtext = NULL;
1293       if (!rc)
1294         {
1295           int i;
1296
1297           if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1298             {
1299               xfree (response);
1300               goto next_try;
1301             }
1302           for (i = 0; i < opt_repeat; i++)
1303             {
1304               char *response2;
1305
1306               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1307                                          errtext, 0);
1308               if (rc)
1309                 break;
1310               if (strcmp (response2, response))
1311                 {
1312                   xfree (response2);
1313                   xfree (response);
1314                   repeat_errtext = try_percent_escape
1315                     (_("does not match - try again"), NULL);
1316                   if (!repeat_errtext)
1317                     {
1318                       rc = gpg_error_from_syserror ();
1319                       break;
1320                     }
1321                   goto next_try;
1322                 }
1323               xfree (response2);
1324             }
1325           if (!rc)
1326             {
1327               if (cacheid)
1328                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1329               rc = send_back_passphrase (ctx, opt_data, response);
1330             }
1331           xfree (response);
1332         }
1333     }
1334
1335   return leave_cmd (ctx, rc);
1336 }
1337
1338
1339 static const char hlp_clear_passphrase[] =
1340   "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
1341   "\n"
1342   "may be used to invalidate the cache entry for a passphrase.  The\n"
1343   "function returns with OK even when there is no cached passphrase.\n"
1344   "The --mode=normal option is used to clear an entry for a cacheid\n"
1345   "added by the agent.\n";
1346 static gpg_error_t
1347 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1348 {
1349   char *cacheid = NULL;
1350   char *p;
1351   int opt_normal;
1352
1353   opt_normal = has_option (line, "--mode=normal");
1354   line = skip_options (line);
1355
1356   /* parse the stuff */
1357   for (p=line; *p == ' '; p++)
1358     ;
1359   cacheid = p;
1360   p = strchr (cacheid, ' ');
1361   if (p)
1362     *p = 0; /* ignore garbage */
1363   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1364     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1365
1366   agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
1367                    NULL, 0);
1368   return 0;
1369 }
1370
1371
1372 static const char hlp_get_confirmation[] =
1373   "GET_CONFIRMATION <description>\n"
1374   "\n"
1375   "This command may be used to ask for a simple confirmation.\n"
1376   "DESCRIPTION is displayed along with a Okay and Cancel button.  This\n"
1377   "command uses a syntax which helps clients to use the agent with\n"
1378   "minimum effort.  The agent either returns with an error or with a\n"
1379   "OK.  Note, that the length of DESCRIPTION is implicitly limited by\n"
1380   "the maximum length of a command. DESCRIPTION should not contain\n"
1381   "any spaces, those must be encoded either percent escaped or simply\n"
1382   "as '+'.";
1383 static gpg_error_t
1384 cmd_get_confirmation (assuan_context_t ctx, char *line)
1385 {
1386   ctrl_t ctrl = assuan_get_pointer (ctx);
1387   int rc;
1388   char *desc = NULL;
1389   char *p;
1390
1391   /* parse the stuff */
1392   for (p=line; *p == ' '; p++)
1393     ;
1394   desc = p;
1395   p = strchr (desc, ' ');
1396   if (p)
1397     *p = 0; /* We ignore any garbage -may be later used for other args. */
1398
1399   if (!desc || !*desc)
1400     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1401
1402   if (!strcmp (desc, "X"))
1403     desc = NULL;
1404
1405   /* Note, that we only need to replace the + characters and should
1406      leave the other escaping in place because the escaped string is
1407      send verbatim to the pinentry which does the unescaping (but not
1408      the + replacing) */
1409   if (desc)
1410     plus_to_blank (desc);
1411
1412   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1413   return leave_cmd (ctx, rc);
1414 }
1415
1416
1417 \f
1418 static const char hlp_learn[] =
1419   "LEARN [--send]\n"
1420   "\n"
1421   "Learn something about the currently inserted smartcard.  With\n"
1422   "--send the new certificates are send back.";
1423 static gpg_error_t
1424 cmd_learn (assuan_context_t ctx, char *line)
1425 {
1426   ctrl_t ctrl = assuan_get_pointer (ctx);
1427   int rc;
1428
1429   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1430   return leave_cmd (ctx, rc);
1431 }
1432
1433
1434 \f
1435 static const char hlp_passwd[] =
1436   "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset] <hexkeygrip>\n"
1437   "\n"
1438   "Change the passphrase/PIN for the key identified by keygrip in LINE. When\n"
1439   "--preset is used then the new passphrase will be added to the cache.\n";
1440 static gpg_error_t
1441 cmd_passwd (assuan_context_t ctx, char *line)
1442 {
1443   ctrl_t ctrl = assuan_get_pointer (ctx);
1444   gpg_error_t err;
1445   int c;
1446   char *cache_nonce = NULL;
1447   char *passwd_nonce = NULL;
1448   unsigned char grip[20];
1449   gcry_sexp_t s_skey = NULL;
1450   unsigned char *shadow_info = NULL;
1451   char *passphrase = NULL;
1452   char *pend;
1453   int opt_preset;
1454
1455   opt_preset = has_option (line, "--preset");
1456   cache_nonce = option_value (line, "--cache-nonce");
1457   if (cache_nonce)
1458     {
1459       for (pend = cache_nonce; *pend && !spacep (pend); pend++)
1460         ;
1461       c = *pend;
1462       *pend = '\0';
1463       cache_nonce = xtrystrdup (cache_nonce);
1464       *pend = c;
1465       if (!cache_nonce)
1466         {
1467           err = gpg_error_from_syserror ();
1468           goto leave;
1469         }
1470     }
1471
1472   passwd_nonce = option_value (line, "--passwd-nonce");
1473   if (passwd_nonce)
1474     {
1475       for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
1476         ;
1477       c = *pend;
1478       *pend = '\0';
1479       passwd_nonce = xtrystrdup (passwd_nonce);
1480       *pend = c;
1481       if (!passwd_nonce)
1482         {
1483           err = gpg_error_from_syserror ();
1484           goto leave;
1485         }
1486     }
1487
1488   line = skip_options (line);
1489
1490   err = parse_keygrip (ctx, line, grip);
1491   if (err)
1492     goto leave;
1493
1494   ctrl->in_passwd++;
1495   err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc,
1496                              grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1497                              &s_skey, &passphrase);
1498   if (err)
1499     ;
1500   else if (!s_skey)
1501     {
1502       log_error ("changing a smartcard PIN is not yet supported\n");
1503       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1504     }
1505   else
1506     {
1507       char *newpass = NULL;
1508
1509       if (passwd_nonce)
1510         newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
1511       err = agent_protect_and_store (ctrl, s_skey, &newpass);
1512       if (!err && passphrase)
1513         {
1514           /* A passphrase existed on the old key and the change was
1515              successful.  Return a nonce for that old passphrase to
1516              let the caller try to unprotect the other subkeys with
1517              the same key.  */
1518           if (!cache_nonce)
1519             {
1520               char buf[12];
1521               gcry_create_nonce (buf, 12);
1522               cache_nonce = bin2hex (buf, 12, NULL);
1523             }
1524           if (cache_nonce
1525               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1526                                    passphrase, CACHE_TTL_NONCE))
1527             {
1528               assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1529               xfree (ctrl->server_local->last_cache_nonce);
1530               ctrl->server_local->last_cache_nonce = cache_nonce;
1531               cache_nonce = NULL;
1532             }
1533           if (newpass)
1534             {
1535               /* If we have a new passphrase (which might be empty) we
1536                  store it under a passwd nonce so that the caller may
1537                  send that nonce again to use it for another key. */
1538               if (!passwd_nonce)
1539                 {
1540                   char buf[12];
1541                   gcry_create_nonce (buf, 12);
1542                   passwd_nonce = bin2hex (buf, 12, NULL);
1543                 }
1544               if (passwd_nonce
1545                   && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1546                                        newpass, CACHE_TTL_NONCE))
1547                 {
1548                   assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1549                   xfree (ctrl->server_local->last_passwd_nonce);
1550                   ctrl->server_local->last_passwd_nonce = passwd_nonce;
1551                   passwd_nonce = NULL;
1552                 }
1553             }
1554         }
1555       if (!err && opt_preset)
1556       {
1557           char hexgrip[40+1];
1558           bin2hex(grip, 20, hexgrip);
1559           err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass,
1560                                  ctrl->cache_ttl_opt_preset);
1561       }
1562       xfree (newpass);
1563     }
1564   ctrl->in_passwd--;
1565
1566   xfree (ctrl->server_local->keydesc);
1567   ctrl->server_local->keydesc = NULL;
1568
1569  leave:
1570   xfree (passphrase);
1571   gcry_sexp_release (s_skey);
1572   xfree (shadow_info);
1573   xfree (cache_nonce);
1574   return leave_cmd (ctx, err);
1575 }
1576
1577
1578 static const char hlp_preset_passphrase[] =
1579   "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n"
1580   "\n"
1581   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1582   "to passwd for the given time, where -1 means infinite and 0 means\n"
1583   "the default (currently only a timeout of -1 is allowed, which means\n"
1584   "to never expire it).  If passwd is not provided, ask for it via the\n"
1585   "pinentry module unless --inquire is passed in which case the passphrase\n"
1586   "is retrieved from the client via a server inquire.\n";
1587 static gpg_error_t
1588 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1589 {
1590   int rc;
1591   char *grip_clear = NULL;
1592   unsigned char *passphrase = NULL;
1593   int ttl;
1594   size_t len;
1595   int opt_inquire;
1596
1597   if (!opt.allow_preset_passphrase)
1598     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1599
1600   opt_inquire = has_option (line, "--inquire");
1601   line = skip_options (line);
1602   grip_clear = line;
1603   while (*line && (*line != ' ' && *line != '\t'))
1604     line++;
1605   if (!*line)
1606     return gpg_error (GPG_ERR_MISSING_VALUE);
1607   *line = '\0';
1608   line++;
1609   while (*line && (*line == ' ' || *line == '\t'))
1610     line++;
1611
1612   /* Currently, only infinite timeouts are allowed.  */
1613   ttl = -1;
1614   if (line[0] != '-' || line[1] != '1')
1615     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1616   line++;
1617   line++;
1618   while (!(*line != ' ' && *line != '\t'))
1619     line++;
1620
1621   /* Syntax check the hexstring.  */
1622   len = 0;
1623   rc = parse_hexstring (ctx, line, &len);
1624   if (rc)
1625     return rc;
1626   line[len] = '\0';
1627
1628   /* If there is a passphrase, use it.  Currently, a passphrase is
1629      required.  */
1630   if (*line)
1631     {
1632       if (opt_inquire)
1633         {
1634           rc = set_error (GPG_ERR_ASS_PARAMETER,
1635                           "both --inquire and passphrase specified");
1636           goto leave;
1637         }
1638
1639       /* Do in-place conversion.  */
1640       passphrase = line;
1641       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1642         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1643     }
1644   else if (opt_inquire)
1645     {
1646       /* Note that the passphrase will be truncated at any null byte and the
1647        * limit is 480 characters. */
1648       rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, 480);
1649     }
1650   else
1651     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1652
1653   if (!rc)
1654     {
1655       rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1656       if (opt_inquire)
1657         xfree (passphrase);
1658     }
1659
1660 leave:
1661   return leave_cmd (ctx, rc);
1662 }
1663
1664
1665 \f
1666 static const char hlp_scd[] =
1667   "SCD <commands to pass to the scdaemon>\n"
1668   " \n"
1669   "This is a general quote command to redirect everything to the\n"
1670   "SCdaemon.";
1671 static gpg_error_t
1672 cmd_scd (assuan_context_t ctx, char *line)
1673 {
1674   ctrl_t ctrl = assuan_get_pointer (ctx);
1675   int rc;
1676
1677   rc = divert_generic_cmd (ctrl, line, ctx);
1678
1679   return rc;
1680 }
1681
1682
1683 \f
1684 static const char hlp_keywrap_key[] =
1685   "KEYWRAP_KEY [--clear] <mode>\n"
1686   "\n"
1687   "Return a key to wrap another key.  For now the key is returned\n"
1688   "verbatim and and thus makes not much sense because an eavesdropper on\n"
1689   "the gpg-agent connection will see the key as well as the wrapped key.\n"
1690   "However, this function may either be equipped with a public key\n"
1691   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
1692   "case wrapping the import and export of keys is a requirement for\n"
1693   "certain cryptographic validations and thus useful.  The key persists\n"
1694   "a RESET command but may be cleared using the option --clear.\n"
1695   "\n"
1696   "Supported modes are:\n"
1697   "  --import  - Return a key to import a key into gpg-agent\n"
1698   "  --export  - Return a key to export a key from gpg-agent";
1699 static gpg_error_t
1700 cmd_keywrap_key (assuan_context_t ctx, char *line)
1701 {
1702   ctrl_t ctrl = assuan_get_pointer (ctx);
1703   gpg_error_t err = 0;
1704   int clearopt = has_option (line, "--clear");
1705
1706
1707   assuan_begin_confidential (ctx);
1708   if (has_option (line, "--import"))
1709     {
1710       xfree (ctrl->server_local->import_key);
1711       if (clearopt)
1712         ctrl->server_local->import_key = NULL;
1713       else if (!(ctrl->server_local->import_key =
1714                  gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1715         err = gpg_error_from_syserror ();
1716       else
1717         err = assuan_send_data (ctx, ctrl->server_local->import_key,
1718                                 KEYWRAP_KEYSIZE);
1719     }
1720   else if (has_option (line, "--export"))
1721     {
1722       xfree (ctrl->server_local->export_key);
1723       if (clearopt)
1724         ctrl->server_local->export_key = NULL;
1725       else if (!(ctrl->server_local->export_key =
1726             gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1727         err = gpg_error_from_syserror ();
1728       else
1729         err = assuan_send_data (ctx, ctrl->server_local->export_key,
1730                                 KEYWRAP_KEYSIZE);
1731     }
1732   else
1733     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
1734   assuan_end_confidential (ctx);
1735
1736   return leave_cmd (ctx, err);
1737 }
1738
1739
1740 \f
1741 static const char hlp_import_key[] =
1742   "IMPORT_KEY [<cache_nonce>]\n"
1743   "\n"
1744   "Import a secret key into the key store.  The key is expected to be\n"
1745   "encrypted using the current session's key wrapping key (cf. command\n"
1746   "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
1747   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
1748   "key data.  The unwrapped key must be a canonical S-expression.";
1749 static gpg_error_t
1750 cmd_import_key (assuan_context_t ctx, char *line)
1751 {
1752   ctrl_t ctrl = assuan_get_pointer (ctx);
1753   gpg_error_t err;
1754   unsigned char *wrappedkey = NULL;
1755   size_t wrappedkeylen;
1756   gcry_cipher_hd_t cipherhd = NULL;
1757   unsigned char *key = NULL;
1758   size_t keylen, realkeylen;
1759   char *passphrase = NULL;
1760   unsigned char *finalkey = NULL;
1761   size_t finalkeylen;
1762   unsigned char grip[20];
1763   gcry_sexp_t openpgp_sexp = NULL;
1764   char *cache_nonce = NULL;
1765   char *p;
1766
1767   if (!ctrl->server_local->import_key)
1768     {
1769       err = gpg_error (GPG_ERR_MISSING_KEY);
1770       goto leave;
1771     }
1772
1773   p = line;
1774   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
1775     ;
1776   *p = '\0';
1777   if (*line)
1778     cache_nonce = xtrystrdup (line);
1779
1780   assuan_begin_confidential (ctx);
1781   err = assuan_inquire (ctx, "KEYDATA",
1782                         &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
1783   assuan_end_confidential (ctx);
1784   if (err)
1785     goto leave;
1786   if (wrappedkeylen < 24)
1787     {
1788       err = gpg_error (GPG_ERR_INV_LENGTH);
1789       goto leave;
1790     }
1791   keylen = wrappedkeylen - 8;
1792   key = xtrymalloc_secure (keylen);
1793   if (!key)
1794     {
1795       err = gpg_error_from_syserror ();
1796       goto leave;
1797     }
1798
1799   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1800                           GCRY_CIPHER_MODE_AESWRAP, 0);
1801   if (err)
1802     goto leave;
1803   err = gcry_cipher_setkey (cipherhd,
1804                             ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
1805   if (err)
1806     goto leave;
1807   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
1808   if (err)
1809     goto leave;
1810   gcry_cipher_close (cipherhd);
1811   cipherhd = NULL;
1812   xfree (wrappedkey);
1813   wrappedkey = NULL;
1814
1815   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1816   if (!realkeylen)
1817     goto leave; /* Invalid canonical encoded S-expression.  */
1818
1819   err = keygrip_from_canon_sexp (key, realkeylen, grip);
1820   if (err)
1821     {
1822       /* This might be due to an unsupported S-expression format.
1823          Check whether this is openpgp-private-key and trigger that
1824          import code.  */
1825       if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
1826         {
1827           const char *tag;
1828           size_t taglen;
1829
1830           tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
1831           if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
1832             ;
1833           else
1834             {
1835               gcry_sexp_release (openpgp_sexp);
1836               openpgp_sexp = NULL;
1837             }
1838         }
1839       if (!openpgp_sexp)
1840         goto leave; /* Note that ERR is still set.  */
1841     }
1842
1843
1844   if (openpgp_sexp)
1845     {
1846       /* In most cases the key is encrypted and thus the conversion
1847          function from the OpenPGP format to our internal format will
1848          ask for a passphrase.  That passphrase will be returned and
1849          used to protect the key using the same code as for regular
1850          key import. */
1851
1852       xfree (key);
1853       key = NULL;
1854       err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
1855                                   ctrl->server_local->keydesc, cache_nonce,
1856                                   &key, &passphrase);
1857       if (err)
1858         goto leave;
1859       realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1860       if (!realkeylen)
1861         goto leave; /* Invalid canonical encoded S-expression.  */
1862       if (passphrase)
1863         {
1864           if (!cache_nonce)
1865             {
1866               char buf[12];
1867               gcry_create_nonce (buf, 12);
1868               cache_nonce = bin2hex (buf, 12, NULL);
1869             }
1870           if (cache_nonce
1871               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1872                                    passphrase, CACHE_TTL_NONCE))
1873             assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1874         }
1875     }
1876   else
1877     {
1878       if (!agent_key_available (grip))
1879         err = gpg_error (GPG_ERR_EEXIST);
1880       else
1881         err = agent_ask_new_passphrase
1882           (ctrl, _("Please enter the passphrase to protect the "
1883                    "imported object within the GnuPG system."),
1884            &passphrase);
1885       if (err)
1886         goto leave;
1887     }
1888
1889   if (passphrase)
1890     {
1891       err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
1892               ctrl->s2k_count);
1893       if (!err)
1894         err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
1895     }
1896   else
1897     err = agent_write_private_key (grip, key, realkeylen, 0);
1898
1899  leave:
1900   gcry_sexp_release (openpgp_sexp);
1901   xfree (finalkey);
1902   xfree (passphrase);
1903   xfree (key);
1904   gcry_cipher_close (cipherhd);
1905   xfree (wrappedkey);
1906   xfree (cache_nonce);
1907   xfree (ctrl->server_local->keydesc);
1908   ctrl->server_local->keydesc = NULL;
1909   return leave_cmd (ctx, err);
1910 }
1911
1912
1913 \f
1914 static const char hlp_export_key[] =
1915   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
1916   "\n"
1917   "Export a secret key from the key store.  The key will be encrypted\n"
1918   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
1919   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
1920   "prior to using this command.  The function takes the keygrip as argument.\n";
1921 static gpg_error_t
1922 cmd_export_key (assuan_context_t ctx, char *line)
1923 {
1924   ctrl_t ctrl = assuan_get_pointer (ctx);
1925   gpg_error_t err;
1926   unsigned char grip[20];
1927   gcry_sexp_t s_skey = NULL;
1928   unsigned char *key = NULL;
1929   size_t keylen;
1930   gcry_cipher_hd_t cipherhd = NULL;
1931   unsigned char *wrappedkey = NULL;
1932   size_t wrappedkeylen;
1933   int openpgp;
1934   char *cache_nonce;
1935   char *passphrase = NULL;
1936
1937   openpgp = has_option (line, "--openpgp");
1938   cache_nonce = option_value (line, "--cache-nonce");
1939   if (cache_nonce)
1940     {
1941       for (; *line && !spacep (line); line++)
1942         ;
1943       if (*line)
1944         *line++ = '\0';
1945       cache_nonce = xtrystrdup (cache_nonce);
1946       if (!cache_nonce)
1947         {
1948           err = gpg_error_from_syserror ();
1949           goto leave;
1950         }
1951     }
1952   line = skip_options (line);
1953
1954   if (!ctrl->server_local->export_key)
1955     {
1956       err = gpg_error (GPG_ERR_MISSING_KEY);
1957       goto leave;
1958     }
1959
1960   err = parse_keygrip (ctx, line, grip);
1961   if (err)
1962     goto leave;
1963
1964   if (agent_key_available (grip))
1965     {
1966       err = gpg_error (GPG_ERR_NO_SECKEY);
1967       goto leave;
1968     }
1969
1970   /* Get the key from the file.  With the openpgp flag we also ask for
1971      the passphrase so that we can use it to re-encrypt it.  */
1972   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
1973                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
1974                              openpgp ? &passphrase : NULL);
1975   if (err)
1976     goto leave;
1977   if (!s_skey)
1978     {
1979       /* Key is on a smartcard.  Actually we should not see this here
1980          because we do not pass a shadow_info variable to the above
1981          function, thus it will return this error directly.  */
1982       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
1983       goto leave;
1984     }
1985
1986   if (openpgp)
1987     {
1988       /* The openpgp option changes the key format into the OpenPGP
1989          key transfer format.  The result is already a padded
1990          canonical S-expression.  */
1991       if (!passphrase)
1992         {
1993           err = agent_ask_new_passphrase
1994             (ctrl, _("This key (or subkey) is not protected with a passphrase."
1995                      "  Please enter a new passphrase to export it."),
1996              &passphrase);
1997           if (err)
1998             goto leave;
1999         }
2000       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
2001     }
2002   else
2003     {
2004       /* Convert into a canonical S-expression and wrap that.  */
2005       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
2006     }
2007   if (err)
2008     goto leave;
2009   gcry_sexp_release (s_skey);
2010   s_skey = NULL;
2011
2012   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2013                           GCRY_CIPHER_MODE_AESWRAP, 0);
2014   if (err)
2015     goto leave;
2016   err = gcry_cipher_setkey (cipherhd,
2017                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
2018   if (err)
2019     goto leave;
2020
2021   wrappedkeylen = keylen + 8;
2022   wrappedkey = xtrymalloc (wrappedkeylen);
2023   if (!wrappedkey)
2024     {
2025       err = gpg_error_from_syserror ();
2026       goto leave;
2027     }
2028
2029   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
2030   if (err)
2031     goto leave;
2032   xfree (key);
2033   key = NULL;
2034   gcry_cipher_close (cipherhd);
2035   cipherhd = NULL;
2036
2037   assuan_begin_confidential (ctx);
2038   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
2039   assuan_end_confidential (ctx);
2040
2041
2042  leave:
2043   xfree (cache_nonce);
2044   xfree (passphrase);
2045   xfree (wrappedkey);
2046   gcry_cipher_close (cipherhd);
2047   xfree (key);
2048   gcry_sexp_release (s_skey);
2049   xfree (ctrl->server_local->keydesc);
2050   ctrl->server_local->keydesc = NULL;
2051
2052   return leave_cmd (ctx, err);
2053 }
2054
2055
2056
2057 \f
2058 static const char hlp_getval[] =
2059   "GETVAL <key>\n"
2060   "\n"
2061   "Return the value for KEY from the special environment as created by\n"
2062   "PUTVAL.";
2063 static gpg_error_t
2064 cmd_getval (assuan_context_t ctx, char *line)
2065 {
2066   int rc = 0;
2067   char *key = NULL;
2068   char *p;
2069   struct putval_item_s *vl;
2070
2071   for (p=line; *p == ' '; p++)
2072     ;
2073   key = p;
2074   p = strchr (key, ' ');
2075   if (p)
2076     {
2077       *p++ = 0;
2078       for (; *p == ' '; p++)
2079         ;
2080       if (*p)
2081         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2082     }
2083   if (!key || !*key)
2084     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2085
2086
2087   for (vl=putval_list; vl; vl = vl->next)
2088     if ( !strcmp (vl->d, key) )
2089       break;
2090
2091   if (vl) /* Got an entry. */
2092     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2093   else
2094     return gpg_error (GPG_ERR_NO_DATA);
2095
2096   return leave_cmd (ctx, rc);
2097 }
2098
2099
2100 static const char hlp_putval[] =
2101   "PUTVAL <key> [<percent_escaped_value>]\n"
2102   "\n"
2103   "The gpg-agent maintains a kind of environment which may be used to\n"
2104   "store key/value pairs in it, so that they can be retrieved later.\n"
2105   "This may be used by helper daemons to daemonize themself on\n"
2106   "invocation and register them with gpg-agent.  Callers of the\n"
2107   "daemon's service may now first try connect to get the information\n"
2108   "for that service from gpg-agent through the GETVAL command and then\n"
2109   "try to connect to that daemon.  Only if that fails they may start\n"
2110   "an own instance of the service daemon. \n"
2111   "\n"
2112   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2113   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2114   "corresponsing value; they should be similar to the values of\n"
2115   "envronment variables but gpg-agent does not enforce any\n"
2116   "restrictions.  If that value is not given any value under that KEY\n"
2117   "is removed from this special environment.";
2118 static gpg_error_t
2119 cmd_putval (assuan_context_t ctx, char *line)
2120 {
2121   int rc = 0;
2122   char *key = NULL;
2123   char *value = NULL;
2124   size_t valuelen = 0;
2125   char *p;
2126   struct putval_item_s *vl, *vlprev;
2127
2128   for (p=line; *p == ' '; p++)
2129     ;
2130   key = p;
2131   p = strchr (key, ' ');
2132   if (p)
2133     {
2134       *p++ = 0;
2135       for (; *p == ' '; p++)
2136         ;
2137       if (*p)
2138         {
2139           value = p;
2140           p = strchr (value, ' ');
2141           if (p)
2142             *p = 0;
2143           valuelen = percent_plus_unescape_inplace (value, 0);
2144         }
2145     }
2146   if (!key || !*key)
2147     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2148
2149
2150   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2151     if ( !strcmp (vl->d, key) )
2152       break;
2153
2154   if (vl) /* Delete old entry. */
2155     {
2156       if (vlprev)
2157         vlprev->next = vl->next;
2158       else
2159         putval_list = vl->next;
2160       xfree (vl);
2161     }
2162
2163   if (valuelen) /* Add entry. */
2164     {
2165       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2166       if (!vl)
2167         rc = gpg_error_from_syserror ();
2168       else
2169         {
2170           vl->len = valuelen;
2171           vl->off = strlen (key) + 1;
2172           strcpy (vl->d, key);
2173           memcpy (vl->d + vl->off, value, valuelen);
2174           vl->next = putval_list;
2175           putval_list = vl;
2176         }
2177     }
2178
2179   return leave_cmd (ctx, rc);
2180 }
2181
2182
2183
2184 \f
2185 static const char hlp_updatestartuptty[] =
2186   "UPDATESTARTUPTTY\n"
2187   "\n"
2188   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2189   "session.  This command is useful to pull future pinentries to\n"
2190   "another screen.  It is only required because there is no way in the\n"
2191   "ssh-agent protocol to convey this information.";
2192 static gpg_error_t
2193 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2194 {
2195   static const char *names[] =
2196     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2197   ctrl_t ctrl = assuan_get_pointer (ctx);
2198   gpg_error_t err = 0;
2199   session_env_t se;
2200   int idx;
2201   char *lc_ctype = NULL;
2202   char *lc_messages = NULL;
2203
2204   (void)line;
2205
2206   se = session_env_new ();
2207   if (!se)
2208     err = gpg_error_from_syserror ();
2209
2210   for (idx=0; !err && names[idx]; idx++)
2211     {
2212       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2213       if (value)
2214         err = session_env_setenv (se, names[idx], value);
2215     }
2216
2217   if (!err && ctrl->lc_ctype)
2218     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2219       err = gpg_error_from_syserror ();
2220
2221   if (!err && ctrl->lc_messages)
2222     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2223       err = gpg_error_from_syserror ();
2224
2225   if (err)
2226     {
2227       session_env_release (se);
2228       xfree (lc_ctype);
2229       xfree (lc_messages);
2230     }
2231   else
2232     {
2233       session_env_release (opt.startup_env);
2234       opt.startup_env = se;
2235       xfree (opt.startup_lc_ctype);
2236       opt.startup_lc_ctype = lc_ctype;
2237       xfree (opt.startup_lc_messages);
2238       opt.startup_lc_messages = lc_messages;
2239     }
2240
2241   return err;
2242 }
2243
2244
2245 \f
2246 static const char hlp_killagent[] =
2247   "KILLAGENT\n"
2248   "\n"
2249   "If the agent has been started using a standard socket\n"
2250   "we allow a client to stop the agent.";
2251 static gpg_error_t
2252 cmd_killagent (assuan_context_t ctx, char *line)
2253 {
2254   ctrl_t ctrl = assuan_get_pointer (ctx);
2255
2256   (void)line;
2257
2258   if (!opt.use_standard_socket)
2259     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
2260
2261   ctrl->server_local->stopme = 1;
2262   return gpg_error (GPG_ERR_EOF);
2263 }
2264
2265
2266 static const char hlp_reloadagent[] =
2267   "RELOADAGENT\n"
2268   "\n"
2269   "This command is an alternative to SIGHUP\n"
2270   "to reload the configuration.";
2271 static gpg_error_t
2272 cmd_reloadagent (assuan_context_t ctx, char *line)
2273 {
2274   (void)ctx;
2275   (void)line;
2276
2277   agent_sighup_action ();
2278   return 0;
2279 }
2280
2281
2282 \f
2283 static const char hlp_getinfo[] =
2284   "GETINFO <what>\n"
2285   "\n"
2286   "Multipurpose function to return a variety of information.\n"
2287   "Supported values for WHAT are:\n"
2288   "\n"
2289   "  version     - Return the version of the program.\n"
2290   "  pid         - Return the process id of the server.\n"
2291   "  socket_name - Return the name of the socket.\n"
2292   "  ssh_socket_name - Return the name of the ssh socket.\n"
2293   "  scd_running - Return OK if the SCdaemon is already running.\n"
2294   "  s2k_count   - Return the calibrated S2K count.\n"
2295   "  std_session_env - List the standard session environment.\n"
2296   "  std_startup_env - List the standard startup environment.\n"
2297   "  cmd_has_option\n"
2298   "              - Returns OK if the command CMD implements the option OPT\n.";
2299 static gpg_error_t
2300 cmd_getinfo (assuan_context_t ctx, char *line)
2301 {
2302   ctrl_t ctrl = assuan_get_pointer (ctx);
2303   int rc = 0;
2304
2305   if (!strcmp (line, "version"))
2306     {
2307       const char *s = VERSION;
2308       rc = assuan_send_data (ctx, s, strlen (s));
2309     }
2310   else if (!strcmp (line, "pid"))
2311     {
2312       char numbuf[50];
2313
2314       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2315       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2316     }
2317   else if (!strcmp (line, "socket_name"))
2318     {
2319       const char *s = get_agent_socket_name ();
2320
2321       if (s)
2322         rc = assuan_send_data (ctx, s, strlen (s));
2323       else
2324         rc = gpg_error (GPG_ERR_NO_DATA);
2325     }
2326   else if (!strcmp (line, "ssh_socket_name"))
2327     {
2328       const char *s = get_agent_ssh_socket_name ();
2329
2330       if (s)
2331         rc = assuan_send_data (ctx, s, strlen (s));
2332       else
2333         rc = gpg_error (GPG_ERR_NO_DATA);
2334     }
2335   else if (!strcmp (line, "scd_running"))
2336     {
2337       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2338     }
2339   else if (!strcmp (line, "s2k_count"))
2340     {
2341       char numbuf[50];
2342
2343       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2344       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2345     }
2346   else if (!strcmp (line, "std_session_env")
2347            || !strcmp (line, "std_startup_env"))
2348     {
2349       int iterator;
2350       const char *name, *value;
2351       char *string;
2352
2353       iterator = 0;
2354       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2355         {
2356           value = session_env_getenv_or_default
2357             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2358           if (value)
2359             {
2360               string = xtryasprintf ("%s=%s", name, value);
2361               if (!string)
2362                 rc = gpg_error_from_syserror ();
2363               else
2364                 {
2365                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2366                   if (!rc)
2367                     rc = assuan_send_data (ctx, NULL, 0);
2368                 }
2369               if (rc)
2370                 break;
2371             }
2372         }
2373     }
2374   else if (!strncmp (line, "cmd_has_option", 14)
2375            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2376     {
2377       char *cmd, *cmdopt;
2378       line += 14;
2379       while (*line == ' ' || *line == '\t')
2380         line++;
2381       if (!*line)
2382         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2383       else
2384         {
2385           cmd = line;
2386           while (*line && (*line != ' ' && *line != '\t'))
2387             line++;
2388           if (!*line)
2389             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2390           else
2391             {
2392               *line++ = 0;
2393               while (*line == ' ' || *line == '\t')
2394                 line++;
2395               if (!*line)
2396                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2397               else
2398                 {
2399                   cmdopt = line;
2400                   if (!command_has_option (cmd, cmdopt))
2401                     rc = gpg_error (GPG_ERR_GENERAL);
2402                 }
2403             }
2404         }
2405     }
2406   else
2407     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2408   return rc;
2409 }
2410
2411
2412 \f
2413 static gpg_error_t
2414 option_handler (assuan_context_t ctx, const char *key, const char *value)
2415 {
2416   ctrl_t ctrl = assuan_get_pointer (ctx);
2417   gpg_error_t err = 0;
2418
2419   if (!strcmp (key, "agent-awareness"))
2420     {
2421       /* The value is a version string telling us of which agent
2422          version the caller is aware of.  */
2423       ctrl->server_local->allow_fully_canceled =
2424         gnupg_compare_version (value, "2.1.0");
2425     }
2426   else if (!strcmp (key, "putenv"))
2427     {
2428       /* Change the session's environment to be used for the
2429          Pinentry.  Valid values are:
2430           <NAME>            Delete envvar NAME
2431           <KEY>=            Set envvar NAME to the empty string
2432           <KEY>=<VALUE>     Set envvar NAME to VALUE
2433       */
2434       err = session_env_putenv (ctrl->session_env, value);
2435     }
2436   else if (!strcmp (key, "display"))
2437     {
2438       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2439     }
2440   else if (!strcmp (key, "ttyname"))
2441     {
2442       if (!opt.keep_tty)
2443         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2444     }
2445   else if (!strcmp (key, "ttytype"))
2446     {
2447       if (!opt.keep_tty)
2448         err = session_env_setenv (ctrl->session_env, "TERM", value);
2449     }
2450   else if (!strcmp (key, "lc-ctype"))
2451     {
2452       if (ctrl->lc_ctype)
2453         xfree (ctrl->lc_ctype);
2454       ctrl->lc_ctype = xtrystrdup (value);
2455       if (!ctrl->lc_ctype)
2456         return out_of_core ();
2457     }
2458   else if (!strcmp (key, "lc-messages"))
2459     {
2460       if (ctrl->lc_messages)
2461         xfree (ctrl->lc_messages);
2462       ctrl->lc_messages = xtrystrdup (value);
2463       if (!ctrl->lc_messages)
2464         return out_of_core ();
2465     }
2466   else if (!strcmp (key, "xauthority"))
2467     {
2468       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
2469     }
2470   else if (!strcmp (key, "pinentry-user-data"))
2471     {
2472       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
2473     }
2474   else if (!strcmp (key, "use-cache-for-signing"))
2475     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
2476   else if (!strcmp (key, "allow-pinentry-notify"))
2477     ctrl->server_local->allow_pinentry_notify = 1;
2478   else if (!strcmp (key, "pinentry-mode"))
2479     {
2480       if (!strcmp (value, "ask") || !strcmp (value, "default"))
2481         ctrl->pinentry_mode = PINENTRY_MODE_ASK;
2482       else if (!strcmp (value, "cancel"))
2483         ctrl->pinentry_mode = PINENTRY_MODE_CANCEL;
2484       else if (!strcmp (value, "error"))
2485         ctrl->pinentry_mode = PINENTRY_MODE_ERROR;
2486       else if (!strcmp (value, "loopback"))
2487         {
2488           if (opt.allow_loopback_pinentry)
2489             ctrl->pinentry_mode = PINENTRY_MODE_LOOPBACK;
2490           else
2491             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2492         }
2493       else
2494         err = gpg_error (GPG_ERR_INV_VALUE);
2495     }
2496   else if (!strcmp (key, "cache-ttl-opt-preset"))
2497     {
2498       ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
2499     }
2500   else if (!strcmp (key, "s2k-count"))
2501     {
2502       ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
2503       if (ctrl->s2k_count && ctrl->s2k_count < 65536) {
2504           ctrl->s2k_count = 0;
2505           err = gpg_error (GPG_ERR_INV_VALUE);
2506       }
2507     }
2508   else
2509     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2510
2511   return err;
2512 }
2513
2514
2515
2516 \f
2517 /* Called by libassuan after all commands. ERR is the error from the
2518    last assuan operation and not the one returned from the command. */
2519 static void
2520 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
2521 {
2522   ctrl_t ctrl = assuan_get_pointer (ctx);
2523
2524   (void)err;
2525
2526   /* Switch off any I/O monitor controlled logging pausing. */
2527   ctrl->server_local->pause_io_logging = 0;
2528 }
2529
2530
2531 /* This function is called by libassuan for all I/O.  We use it here
2532    to disable logging for the GETEVENTCOUNTER commands.  This is so
2533    that the debug output won't get cluttered by this primitive
2534    command.  */
2535 static unsigned int
2536 io_monitor (assuan_context_t ctx, void *hook, int direction,
2537             const char *line, size_t linelen)
2538 {
2539   ctrl_t ctrl = assuan_get_pointer (ctx);
2540
2541   (void) hook;
2542
2543   /* Note that we only check for the uppercase name.  This allows to
2544      see the logging for debugging if using a non-upercase command
2545      name. */
2546   if (ctx && direction == ASSUAN_IO_FROM_PEER
2547       && linelen >= 15
2548       && !strncmp (line, "GETEVENTCOUNTER", 15)
2549       && (linelen == 15 || spacep (line+15)))
2550     {
2551       ctrl->server_local->pause_io_logging = 1;
2552     }
2553
2554   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2555 }
2556
2557
2558 /* Return true if the command CMD implements the option OPT.  */
2559 static int
2560 command_has_option (const char *cmd, const char *cmdopt)
2561 {
2562   if (!strcmp (cmd, "GET_PASSPHRASE"))
2563     {
2564       if (!strcmp (cmdopt, "repeat"))
2565           return 1;
2566     }
2567
2568   return 0;
2569 }
2570
2571
2572 /* Tell the assuan library about our commands */
2573 static int
2574 register_commands (assuan_context_t ctx)
2575 {
2576   static struct {
2577     const char *name;
2578     assuan_handler_t handler;
2579     const char * const help;
2580   } table[] = {
2581     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2582     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2583     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2584     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2585     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2586     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2587     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2588     { "SETHASH",        cmd_sethash,   hlp_sethash },
2589     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2590     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2591     { "GENKEY",         cmd_genkey,    hlp_genkey },
2592     { "READKEY",        cmd_readkey,   hlp_readkey },
2593     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2594     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2595     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2596     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2597     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2598     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2599     { "LEARN",          cmd_learn,     hlp_learn },
2600     { "PASSWD",         cmd_passwd,    hlp_passwd },
2601     { "INPUT",          NULL },
2602     { "OUTPUT",         NULL },
2603     { "SCD",            cmd_scd,       hlp_scd },
2604     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
2605     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
2606     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
2607     { "GETVAL",         cmd_getval,    hlp_getval },
2608     { "PUTVAL",         cmd_putval,    hlp_putval },
2609     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2610     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2611     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2612     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2613     { NULL }
2614   };
2615   int i, rc;
2616
2617   for (i=0; table[i].name; i++)
2618     {
2619       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2620                                     table[i].help);
2621       if (rc)
2622         return rc;
2623     }
2624   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2625   assuan_register_reset_notify (ctx, reset_notify);
2626   assuan_register_option_handler (ctx, option_handler);
2627   return 0;
2628 }
2629
2630
2631 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2632    simple piper server, otherwise it is a regular server.  CTRL is the
2633    control structure for this connection; it has only the basic
2634    intialization. */
2635 void
2636 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2637 {
2638   int rc;
2639   assuan_context_t ctx = NULL;
2640
2641   rc = assuan_new (&ctx);
2642   if (rc)
2643     {
2644       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2645       agent_exit (2);
2646     }
2647
2648   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2649     {
2650       assuan_fd_t filedes[2];
2651
2652       filedes[0] = assuan_fdopen (0);
2653       filedes[1] = assuan_fdopen (1);
2654       rc = assuan_init_pipe_server (ctx, filedes);
2655     }
2656   else if (listen_fd != GNUPG_INVALID_FD)
2657     {
2658       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2659       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2660          this branch is currently not used.  */
2661     }
2662   else
2663     {
2664       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2665     }
2666   if (rc)
2667     {
2668       log_error ("failed to initialize the server: %s\n",
2669                  gpg_strerror(rc));
2670       agent_exit (2);
2671     }
2672   rc = register_commands (ctx);
2673   if (rc)
2674     {
2675       log_error ("failed to register commands with Assuan: %s\n",
2676                  gpg_strerror(rc));
2677       agent_exit (2);
2678     }
2679
2680   assuan_set_pointer (ctx, ctrl);
2681   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2682   ctrl->server_local->assuan_ctx = ctx;
2683   ctrl->server_local->message_fd = -1;
2684   ctrl->server_local->use_cache_for_signing = 1;
2685   ctrl->digest.raw_value = 0;
2686
2687   assuan_set_io_monitor (ctx, io_monitor, NULL);
2688
2689   for (;;)
2690     {
2691       rc = assuan_accept (ctx);
2692       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
2693         {
2694           break;
2695         }
2696       else if (rc)
2697         {
2698           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2699           break;
2700         }
2701
2702       rc = assuan_process (ctx);
2703       if (rc)
2704         {
2705           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2706           continue;
2707         }
2708     }
2709
2710   /* Reset the nonce caches.  */
2711   clear_nonce_cache (ctrl);
2712
2713   /* Reset the SCD if needed. */
2714   agent_reset_scd (ctrl);
2715
2716   /* Reset the pinentry (in case of popup messages). */
2717   agent_reset_query (ctrl);
2718
2719   /* Cleanup.  */
2720   assuan_release (ctx);
2721   xfree (ctrl->server_local->keydesc);
2722   xfree (ctrl->server_local->import_key);
2723   xfree (ctrl->server_local->export_key);
2724   if (ctrl->server_local->stopme)
2725     agent_exit (0);
2726   xfree (ctrl->server_local);
2727   ctrl->server_local = NULL;
2728 }