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