Added option --data to KEYINFO to return the result with a data response.
[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] [--data] <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 unless --data was specified, 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, assuan_context_t ctx,
963     int data)
964 {
965   gpg_error_t err;
966   char hexgrip[40+1];
967   int keytype;
968   unsigned char *shadow_info = NULL;
969   char *serialno = NULL;
970   char *idstr = NULL;
971   const char *keytypestr;
972   char *cached;
973   char *pw;
974
975   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
976   if (err)
977     goto leave;
978
979   /* Reformat the grip so that we use uppercase as good style. */
980   bin2hex (grip, 20, hexgrip);
981
982   if (keytype == PRIVATE_KEY_CLEAR
983       || keytype == PRIVATE_KEY_PROTECTED)
984     keytypestr = "D";
985   else if (keytype == PRIVATE_KEY_SHADOWED)
986     keytypestr = "T";
987   else
988     keytypestr = "-";
989
990   pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
991   cached = pw ? "1" : "-";
992   xfree (pw);
993
994   if (shadow_info)
995     {
996       err = parse_shadow_info (shadow_info, &serialno, &idstr);
997       if (err)
998         goto leave;
999     }
1000
1001   if (!data)
1002     err = agent_write_status (ctrl, "KEYINFO",
1003                               hexgrip,
1004                               keytypestr,
1005                               serialno? serialno : "-",
1006                               idstr? idstr : "-",
1007                               cached,
1008                               NULL);
1009   else {
1010     char *string = xtryasprintf ("%s %s %s %s %s\n", hexgrip, keytypestr,
1011         serialno? serialno : "-", idstr? idstr : "-", cached);
1012
1013     if (!string)
1014       err = gpg_error_from_syserror ();
1015
1016     err = assuan_send_data(ctx, string, strlen(string));
1017     xfree(string);
1018   }
1019
1020  leave:
1021   xfree (shadow_info);
1022   xfree (serialno);
1023   xfree (idstr);
1024   return err;
1025 }
1026
1027
1028 static gpg_error_t
1029 cmd_keyinfo (assuan_context_t ctx, char *line)
1030 {
1031   ctrl_t ctrl = assuan_get_pointer (ctx);
1032   int err;
1033   unsigned char grip[20];
1034   DIR *dir = NULL;
1035   int list_mode;
1036   int opt_data;
1037
1038   list_mode = has_option (line, "--list");
1039   opt_data = has_option (line, "--data");
1040   line = skip_options (line);
1041
1042   if (list_mode)
1043     {
1044       char *dirname;
1045       struct dirent *dir_entry;
1046       char hexgrip[41];
1047
1048       dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1049       if (!dirname)
1050         {
1051           err = gpg_error_from_syserror ();
1052           goto leave;
1053         }
1054       dir = opendir (dirname);
1055       if (!dir)
1056         {
1057           err = gpg_error_from_syserror ();
1058           xfree (dirname);
1059           goto leave;
1060         }
1061       xfree (dirname);
1062
1063       while ( (dir_entry = readdir (dir)) )
1064         {
1065           if (strlen (dir_entry->d_name) != 44
1066               || strcmp (dir_entry->d_name + 40, ".key"))
1067             continue;
1068           strncpy (hexgrip, dir_entry->d_name, 40);
1069           hexgrip[40] = 0;
1070
1071           if ( hex2bin (hexgrip, grip, 20) < 0 )
1072             continue; /* Bad hex string.  */
1073
1074           err = do_one_keyinfo (ctrl, grip, ctx, opt_data);
1075           if (err)
1076             goto leave;
1077         }
1078       err = 0;
1079     }
1080   else
1081     {
1082       err = parse_keygrip (ctx, line, grip);
1083       if (err)
1084         goto leave;
1085       err = do_one_keyinfo (ctrl, grip, ctx, opt_data);
1086     }
1087
1088  leave:
1089   if (dir)
1090     closedir (dir);
1091   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1092     leave_cmd (ctx, err);
1093   return err;
1094 }
1095
1096
1097 \f
1098 static int
1099 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1100 {
1101   size_t n;
1102   int rc;
1103
1104   assuan_begin_confidential (ctx);
1105   n = strlen (pw);
1106   if (via_data)
1107     rc = assuan_send_data (ctx, pw, n);
1108   else
1109     {
1110       char *p = xtrymalloc_secure (n*2+1);
1111       if (!p)
1112         rc = gpg_error_from_syserror ();
1113       else
1114         {
1115           bin2hex (pw, n, p);
1116           rc = assuan_set_okay_line (ctx, p);
1117           xfree (p);
1118         }
1119     }
1120   return rc;
1121 }
1122
1123
1124 static const char hlp_get_passphrase[] =
1125   "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1126   "               [--qualitybar] <cache_id>\n"
1127   "               [<error_message> <prompt> <description>]\n"
1128   "\n"
1129   "This function is usually used to ask for a passphrase to be used\n"
1130   "for conventional encryption, but may also be used by programs which\n"
1131   "need specal handling of passphrases.  This command uses a syntax\n"
1132   "which helps clients to use the agent with minimum effort.  The\n"
1133   "agent either returns with an error or with a OK followed by the hex\n"
1134   "encoded passphrase.  Note that the length of the strings is\n"
1135   "implicitly limited by the maximum length of a command.\n"
1136   "\n"
1137   "If the option \"--data\" is used the passphrase is returned by usual\n"
1138   "data lines and not on the okay line.\n"
1139   "\n"
1140   "If the option \"--check\" is used the passphrase constraints checks as\n"
1141   "implemented by gpg-agent are applied.  A check is not done if the\n"
1142   "passphrase has been found in the cache.\n"
1143   "\n"
1144   "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1145   "cache the user will not be asked to enter a passphrase but the error\n"
1146   "code GPG_ERR_NO_DATA is returned.  \n"
1147   "\n"
1148   "If the option \"--qualitybar\" is used a visual indication of the\n"
1149   "entered passphrase quality is shown.  (Unless no minimum passphrase\n"
1150   "length has been configured.)";
1151 static gpg_error_t
1152 cmd_get_passphrase (assuan_context_t ctx, char *line)
1153 {
1154   ctrl_t ctrl = assuan_get_pointer (ctx);
1155   int rc;
1156   char *pw;
1157   char *response;
1158   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1159   const char *desc2 = _("Please re-enter this passphrase");
1160   char *p;
1161   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1162   int opt_repeat = 0;
1163   char *repeat_errtext = NULL;
1164
1165   opt_data = has_option (line, "--data");
1166   opt_check = has_option (line, "--check");
1167   opt_no_ask = has_option (line, "--no-ask");
1168   if (has_option_name (line, "--repeat"))
1169     {
1170       p = option_value (line, "--repeat");
1171       if (p)
1172         opt_repeat = atoi (p);
1173       else
1174         opt_repeat = 1;
1175     }
1176   opt_qualbar = has_option (line, "--qualitybar");
1177   line = skip_options (line);
1178
1179   cacheid = line;
1180   p = strchr (cacheid, ' ');
1181   if (p)
1182     {
1183       *p++ = 0;
1184       while (*p == ' ')
1185         p++;
1186       errtext = p;
1187       p = strchr (errtext, ' ');
1188       if (p)
1189         {
1190           *p++ = 0;
1191           while (*p == ' ')
1192             p++;
1193           prompt = p;
1194           p = strchr (prompt, ' ');
1195           if (p)
1196             {
1197               *p++ = 0;
1198               while (*p == ' ')
1199                 p++;
1200               desc = p;
1201               p = strchr (desc, ' ');
1202               if (p)
1203                 *p = 0; /* Ignore trailing garbage. */
1204             }
1205         }
1206     }
1207   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1208     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1209   if (!desc)
1210     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1211
1212   if (!strcmp (cacheid, "X"))
1213     cacheid = NULL;
1214   if (!strcmp (errtext, "X"))
1215     errtext = NULL;
1216   if (!strcmp (prompt, "X"))
1217     prompt = NULL;
1218   if (!strcmp (desc, "X"))
1219     desc = NULL;
1220
1221   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL) : NULL;
1222   if (pw)
1223     {
1224       rc = send_back_passphrase (ctx, opt_data, pw);
1225       xfree (pw);
1226     }
1227   else if (opt_no_ask)
1228     rc = gpg_error (GPG_ERR_NO_DATA);
1229   else
1230     {
1231       /* Note, that we only need to replace the + characters and
1232          should leave the other escaping in place because the escaped
1233          string is send verbatim to the pinentry which does the
1234          unescaping (but not the + replacing) */
1235       if (errtext)
1236         plus_to_blank (errtext);
1237       if (prompt)
1238         plus_to_blank (prompt);
1239       if (desc)
1240         plus_to_blank (desc);
1241
1242     next_try:
1243       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1244                                  repeat_errtext? repeat_errtext:errtext,
1245                                  opt_qualbar);
1246       xfree (repeat_errtext);
1247       repeat_errtext = NULL;
1248       if (!rc)
1249         {
1250           int i;
1251
1252           if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1253             {
1254               xfree (response);
1255               goto next_try;
1256             }
1257           for (i = 0; i < opt_repeat; i++)
1258             {
1259               char *response2;
1260
1261               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1262                                          errtext, 0);
1263               if (rc)
1264                 break;
1265               if (strcmp (response2, response))
1266                 {
1267                   xfree (response2);
1268                   xfree (response);
1269                   repeat_errtext = try_percent_escape
1270                     (_("does not match - try again"), NULL);
1271                   if (!repeat_errtext)
1272                     {
1273                       rc = gpg_error_from_syserror ();
1274                       break;
1275                     }
1276                   goto next_try;
1277                 }
1278               xfree (response2);
1279             }
1280           if (!rc)
1281             {
1282               if (cacheid)
1283                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1284               rc = send_back_passphrase (ctx, opt_data, response);
1285             }
1286           xfree (response);
1287         }
1288     }
1289
1290   return leave_cmd (ctx, rc);
1291 }
1292
1293
1294 static const char hlp_clear_passphrase[] =
1295   "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
1296   "\n"
1297   "may be used to invalidate the cache entry for a passphrase.  The\n"
1298   "function returns with OK even when there is no cached passphrase.\n"
1299   "The --mode=normal option is used to clear an entry for a cacheid\n"
1300   "added by the agent.\n";
1301 static gpg_error_t
1302 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1303 {
1304   char *cacheid = NULL;
1305   char *p;
1306   int opt_normal;
1307
1308   opt_normal = has_option (line, "--mode=normal");
1309   line = skip_options (line);
1310
1311   /* parse the stuff */
1312   for (p=line; *p == ' '; p++)
1313     ;
1314   cacheid = p;
1315   p = strchr (cacheid, ' ');
1316   if (p)
1317     *p = 0; /* ignore garbage */
1318   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1319     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1320
1321   agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
1322                    NULL, 0);
1323   return 0;
1324 }
1325
1326
1327 static const char hlp_get_confirmation[] =
1328   "GET_CONFIRMATION <description>\n"
1329   "\n"
1330   "This command may be used to ask for a simple confirmation.\n"
1331   "DESCRIPTION is displayed along with a Okay and Cancel button.  This\n"
1332   "command uses a syntax which helps clients to use the agent with\n"
1333   "minimum effort.  The agent either returns with an error or with a\n"
1334   "OK.  Note, that the length of DESCRIPTION is implicitly limited by\n"
1335   "the maximum length of a command. DESCRIPTION should not contain\n"
1336   "any spaces, those must be encoded either percent escaped or simply\n"
1337   "as '+'.";
1338 static gpg_error_t
1339 cmd_get_confirmation (assuan_context_t ctx, char *line)
1340 {
1341   ctrl_t ctrl = assuan_get_pointer (ctx);
1342   int rc;
1343   char *desc = NULL;
1344   char *p;
1345
1346   /* parse the stuff */
1347   for (p=line; *p == ' '; p++)
1348     ;
1349   desc = p;
1350   p = strchr (desc, ' ');
1351   if (p)
1352     *p = 0; /* We ignore any garbage -may be later used for other args. */
1353
1354   if (!desc || !*desc)
1355     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1356
1357   if (!strcmp (desc, "X"))
1358     desc = NULL;
1359
1360   /* Note, that we only need to replace the + characters and should
1361      leave the other escaping in place because the escaped string is
1362      send verbatim to the pinentry which does the unescaping (but not
1363      the + replacing) */
1364   if (desc)
1365     plus_to_blank (desc);
1366
1367   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1368   return leave_cmd (ctx, rc);
1369 }
1370
1371
1372 \f
1373 static const char hlp_learn[] =
1374   "LEARN [--send]\n"
1375   "\n"
1376   "Learn something about the currently inserted smartcard.  With\n"
1377   "--send the new certificates are send back.";
1378 static gpg_error_t
1379 cmd_learn (assuan_context_t ctx, char *line)
1380 {
1381   ctrl_t ctrl = assuan_get_pointer (ctx);
1382   int rc;
1383
1384   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1385   return leave_cmd (ctx, rc);
1386 }
1387
1388
1389 \f
1390 static const char hlp_passwd[] =
1391   "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] <hexstring_with_keygrip>\n"
1392   "\n"
1393   "Change the passphrase/PIN for the key identified by keygrip in LINE.";
1394 static gpg_error_t
1395 cmd_passwd (assuan_context_t ctx, char *line)
1396 {
1397   ctrl_t ctrl = assuan_get_pointer (ctx);
1398   gpg_error_t err;
1399   int c;
1400   char *cache_nonce = NULL;
1401   char *passwd_nonce = NULL;
1402   unsigned char grip[20];
1403   gcry_sexp_t s_skey = NULL;
1404   unsigned char *shadow_info = NULL;
1405   char *passphrase = NULL;
1406   char *pend;
1407
1408   cache_nonce = option_value (line, "--cache-nonce");
1409   if (cache_nonce)
1410     {
1411       for (pend = cache_nonce; *pend && !spacep (pend); pend++)
1412         ;
1413       c = *pend;
1414       *pend = '\0';
1415       cache_nonce = xtrystrdup (cache_nonce);
1416       *pend = c;
1417       if (!cache_nonce)
1418         {
1419           err = gpg_error_from_syserror ();
1420           goto leave;
1421         }
1422     }
1423
1424   passwd_nonce = option_value (line, "--passwd-nonce");
1425   if (passwd_nonce)
1426     {
1427       for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
1428         ;
1429       c = *pend;
1430       *pend = '\0';
1431       passwd_nonce = xtrystrdup (passwd_nonce);
1432       *pend = c;
1433       if (!passwd_nonce)
1434         {
1435           err = gpg_error_from_syserror ();
1436           goto leave;
1437         }
1438     }
1439
1440   line = skip_options (line);
1441
1442   err = parse_keygrip (ctx, line, grip);
1443   if (err)
1444     goto leave;
1445
1446   ctrl->in_passwd++;
1447   err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc,
1448                              grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1449                              &s_skey, &passphrase);
1450   if (err)
1451     ;
1452   else if (!s_skey)
1453     {
1454       log_error ("changing a smartcard PIN is not yet supported\n");
1455       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1456     }
1457   else
1458     {
1459       char *newpass = NULL;
1460
1461       if (passwd_nonce)
1462         newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
1463       err = agent_protect_and_store (ctrl, s_skey, &newpass);
1464       if (!err && passphrase)
1465         {
1466           /* A passphrase existed on the old key and the change was
1467              successful.  Return a nonce for that old passphrase to
1468              let the caller try to unprotect the other subkeys with
1469              the same key.  */
1470           if (!cache_nonce)
1471             {
1472               char buf[12];
1473               gcry_create_nonce (buf, 12);
1474               cache_nonce = bin2hex (buf, 12, NULL);
1475             }
1476           if (cache_nonce
1477               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1478                                    passphrase, 120 /*seconds*/))
1479             {
1480               assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1481               xfree (ctrl->server_local->last_cache_nonce);
1482               ctrl->server_local->last_cache_nonce = cache_nonce;
1483               cache_nonce = NULL;
1484             }
1485           if (newpass)
1486             {
1487               /* If we have a new passphrase (which might be empty) we
1488                  store it under a passwd nonce so that the caller may
1489                  send that nonce again to use it for another key. */
1490               if (!passwd_nonce)
1491                 {
1492                   char buf[12];
1493                   gcry_create_nonce (buf, 12);
1494                   passwd_nonce = bin2hex (buf, 12, NULL);
1495                 }
1496               if (passwd_nonce
1497                   && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1498                                        newpass, 120 /*seconds*/))
1499                 {
1500                   assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1501                   xfree (ctrl->server_local->last_passwd_nonce);
1502                   ctrl->server_local->last_passwd_nonce = passwd_nonce;
1503                   passwd_nonce = NULL;
1504                 }
1505             }
1506         }
1507       xfree (newpass);
1508     }
1509   ctrl->in_passwd--;
1510
1511   xfree (ctrl->server_local->keydesc);
1512   ctrl->server_local->keydesc = NULL;
1513
1514  leave:
1515   xfree (passphrase);
1516   gcry_sexp_release (s_skey);
1517   xfree (shadow_info);
1518   xfree (cache_nonce);
1519   return leave_cmd (ctx, err);
1520 }
1521
1522
1523 static const char hlp_preset_passphrase[] =
1524   "PRESET_PASSPHRASE <string_or_keygrip> <timeout> <hexstring>\n"
1525   "\n"
1526   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1527   "to passwd for the given time, where -1 means infinite and 0 means\n"
1528   "the default (currently only a timeout of -1 is allowed, which means\n"
1529   "to never expire it).  If passwd is not provided, ask for it via the\n"
1530   "pinentry module.";
1531 static gpg_error_t
1532 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1533 {
1534   int rc;
1535   char *grip_clear = NULL;
1536   char *passphrase = NULL;
1537   int ttl;
1538   size_t len;
1539
1540   if (!opt.allow_preset_passphrase)
1541     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1542
1543   grip_clear = line;
1544   while (*line && (*line != ' ' && *line != '\t'))
1545     line++;
1546   if (!*line)
1547     return gpg_error (GPG_ERR_MISSING_VALUE);
1548   *line = '\0';
1549   line++;
1550   while (*line && (*line == ' ' || *line == '\t'))
1551     line++;
1552
1553   /* Currently, only infinite timeouts are allowed.  */
1554   ttl = -1;
1555   if (line[0] != '-' || line[1] != '1')
1556     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1557   line++;
1558   line++;
1559   while (!(*line != ' ' && *line != '\t'))
1560     line++;
1561
1562   /* Syntax check the hexstring.  */
1563   len = 0;
1564   rc = parse_hexstring (ctx, line, &len);
1565   if (rc)
1566     return rc;
1567   line[len] = '\0';
1568
1569   /* If there is a passphrase, use it.  Currently, a passphrase is
1570      required.  */
1571   if (*line)
1572     {
1573       /* Do in-place conversion.  */
1574       passphrase = line;
1575       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1576         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1577     }
1578   else
1579     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1580
1581   if (!rc)
1582     rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1583
1584   return leave_cmd (ctx, rc);
1585 }
1586
1587
1588 \f
1589 static const char hlp_scd[] =
1590   "SCD <commands to pass to the scdaemon>\n"
1591   " \n"
1592   "This is a general quote command to redirect everything to the\n"
1593   "SCdaemon.";
1594 static gpg_error_t
1595 cmd_scd (assuan_context_t ctx, char *line)
1596 {
1597   ctrl_t ctrl = assuan_get_pointer (ctx);
1598   int rc;
1599
1600   rc = divert_generic_cmd (ctrl, line, ctx);
1601
1602   return rc;
1603 }
1604
1605
1606 \f
1607 static const char hlp_keywrap_key[] =
1608   "KEYWRAP_KEY [--clear] <mode>\n"
1609   "\n"
1610   "Return a key to wrap another key.  For now the key is returned\n"
1611   "verbatim and and thus makes not much sense because an eavesdropper on\n"
1612   "the gpg-agent connection will see the key as well as the wrapped key.\n"
1613   "However, this function may either be equipped with a public key\n"
1614   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
1615   "case wrapping the import and export of keys is a requirement for\n"
1616   "certain cryptographic validations and thus useful.  The key persists\n"
1617   "a RESET command but may be cleared using the option --clear.\n"
1618   "\n"
1619   "Supported modes are:\n"
1620   "  --import  - Return a key to import a key into gpg-agent\n"
1621   "  --export  - Return a key to export a key from gpg-agent";
1622 static gpg_error_t
1623 cmd_keywrap_key (assuan_context_t ctx, char *line)
1624 {
1625   ctrl_t ctrl = assuan_get_pointer (ctx);
1626   gpg_error_t err = 0;
1627   int clearopt = has_option (line, "--clear");
1628
1629
1630   assuan_begin_confidential (ctx);
1631   if (has_option (line, "--import"))
1632     {
1633       xfree (ctrl->server_local->import_key);
1634       if (clearopt)
1635         ctrl->server_local->import_key = NULL;
1636       else if (!(ctrl->server_local->import_key =
1637                  gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1638         err = gpg_error_from_syserror ();
1639       else
1640         err = assuan_send_data (ctx, ctrl->server_local->import_key,
1641                                 KEYWRAP_KEYSIZE);
1642     }
1643   else if (has_option (line, "--export"))
1644     {
1645       xfree (ctrl->server_local->export_key);
1646       if (clearopt)
1647         ctrl->server_local->export_key = NULL;
1648       else if (!(ctrl->server_local->export_key =
1649             gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1650         err = gpg_error_from_syserror ();
1651       else
1652         err = assuan_send_data (ctx, ctrl->server_local->export_key,
1653                                 KEYWRAP_KEYSIZE);
1654     }
1655   else
1656     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
1657   assuan_end_confidential (ctx);
1658
1659   return leave_cmd (ctx, err);
1660 }
1661
1662
1663 \f
1664 static const char hlp_import_key[] =
1665   "IMPORT_KEY [<cache_nonce>]\n"
1666   "\n"
1667   "Import a secret key into the key store.  The key is expected to be\n"
1668   "encrypted using the current session's key wrapping key (cf. command\n"
1669   "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
1670   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
1671   "key data.  The unwrapped key must be a canonical S-expression.";
1672 static gpg_error_t
1673 cmd_import_key (assuan_context_t ctx, char *line)
1674 {
1675   ctrl_t ctrl = assuan_get_pointer (ctx);
1676   gpg_error_t err;
1677   unsigned char *wrappedkey = NULL;
1678   size_t wrappedkeylen;
1679   gcry_cipher_hd_t cipherhd = NULL;
1680   unsigned char *key = NULL;
1681   size_t keylen, realkeylen;
1682   char *passphrase = NULL;
1683   unsigned char *finalkey = NULL;
1684   size_t finalkeylen;
1685   unsigned char grip[20];
1686   gcry_sexp_t openpgp_sexp = NULL;
1687   char *cache_nonce = NULL;
1688   char *p;
1689
1690   if (!ctrl->server_local->import_key)
1691     {
1692       err = gpg_error (GPG_ERR_MISSING_KEY);
1693       goto leave;
1694     }
1695
1696   p = line;
1697   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
1698     ;
1699   *p = '\0';
1700   if (*line)
1701     cache_nonce = xtrystrdup (line);
1702
1703   assuan_begin_confidential (ctx);
1704   err = assuan_inquire (ctx, "KEYDATA",
1705                         &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
1706   assuan_end_confidential (ctx);
1707   if (err)
1708     goto leave;
1709   if (wrappedkeylen < 24)
1710     {
1711       err = gpg_error (GPG_ERR_INV_LENGTH);
1712       goto leave;
1713     }
1714   keylen = wrappedkeylen - 8;
1715   key = xtrymalloc_secure (keylen);
1716   if (!key)
1717     {
1718       err = gpg_error_from_syserror ();
1719       goto leave;
1720     }
1721
1722   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1723                           GCRY_CIPHER_MODE_AESWRAP, 0);
1724   if (err)
1725     goto leave;
1726   err = gcry_cipher_setkey (cipherhd,
1727                             ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
1728   if (err)
1729     goto leave;
1730   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
1731   if (err)
1732     goto leave;
1733   gcry_cipher_close (cipherhd);
1734   cipherhd = NULL;
1735   xfree (wrappedkey);
1736   wrappedkey = NULL;
1737
1738   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1739   if (!realkeylen)
1740     goto leave; /* Invalid canonical encoded S-expression.  */
1741
1742   err = keygrip_from_canon_sexp (key, realkeylen, grip);
1743   if (err)
1744     {
1745       /* This might be due to an unsupported S-expression format.
1746          Check whether this is openpgp-private-key and trigger that
1747          import code.  */
1748       if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
1749         {
1750           const char *tag;
1751           size_t taglen;
1752
1753           tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
1754           if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
1755             ;
1756           else
1757             {
1758               gcry_sexp_release (openpgp_sexp);
1759               openpgp_sexp = NULL;
1760             }
1761         }
1762       if (!openpgp_sexp)
1763         goto leave; /* Note that ERR is still set.  */
1764     }
1765
1766
1767   if (openpgp_sexp)
1768     {
1769       /* In most cases the key is encrypted and thus the conversion
1770          function from the OpenPGP format to our internal format will
1771          ask for a passphrase.  That passphrase will be returned and
1772          used to protect the key using the same code as for regular
1773          key import. */
1774
1775       err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
1776                                   ctrl->server_local->keydesc, cache_nonce,
1777                                   &key, &passphrase);
1778       if (err)
1779         goto leave;
1780       realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1781       if (!realkeylen)
1782         goto leave; /* Invalid canonical encoded S-expression.  */
1783       if (passphrase)
1784         {
1785           if (!cache_nonce)
1786             {
1787               char buf[12];
1788               gcry_create_nonce (buf, 12);
1789               cache_nonce = bin2hex (buf, 12, NULL);
1790             }
1791           if (cache_nonce
1792               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1793                                    passphrase, 120 /*seconds*/))
1794             assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1795         }
1796     }
1797   else
1798     {
1799       if (!agent_key_available (grip))
1800         err = gpg_error (GPG_ERR_EEXIST);
1801       else
1802         err = agent_ask_new_passphrase
1803           (ctrl, _("Please enter the passphrase to protect the "
1804                    "imported object within the GnuPG system."),
1805            &passphrase);
1806       if (err)
1807         goto leave;
1808     }
1809
1810   if (passphrase)
1811     {
1812       err = agent_protect (key, passphrase, &finalkey, &finalkeylen);
1813       if (!err)
1814         err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
1815     }
1816   else
1817     err = agent_write_private_key (grip, key, realkeylen, 0);
1818
1819  leave:
1820   gcry_sexp_release (openpgp_sexp);
1821   xfree (finalkey);
1822   xfree (passphrase);
1823   xfree (key);
1824   gcry_cipher_close (cipherhd);
1825   xfree (wrappedkey);
1826   xfree (cache_nonce);
1827   xfree (ctrl->server_local->keydesc);
1828   ctrl->server_local->keydesc = NULL;
1829   return leave_cmd (ctx, err);
1830 }
1831
1832
1833 \f
1834 static const char hlp_export_key[] =
1835   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
1836   "\n"
1837   "Export a secret key from the key store.  The key will be encrypted\n"
1838   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
1839   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
1840   "prior to using this command.  The function takes the keygrip as argument.\n";
1841 static gpg_error_t
1842 cmd_export_key (assuan_context_t ctx, char *line)
1843 {
1844   ctrl_t ctrl = assuan_get_pointer (ctx);
1845   gpg_error_t err;
1846   unsigned char grip[20];
1847   gcry_sexp_t s_skey = NULL;
1848   unsigned char *key = NULL;
1849   size_t keylen;
1850   gcry_cipher_hd_t cipherhd = NULL;
1851   unsigned char *wrappedkey = NULL;
1852   size_t wrappedkeylen;
1853   int openpgp;
1854   char *cache_nonce;
1855   char *passphrase = NULL;
1856
1857   openpgp = has_option (line, "--openpgp");
1858   cache_nonce = option_value (line, "--cache-nonce");
1859   if (cache_nonce)
1860     {
1861       for (; *line && !spacep (line); line++)
1862         ;
1863       if (*line)
1864         *line++ = '\0';
1865       cache_nonce = xtrystrdup (cache_nonce);
1866       if (!cache_nonce)
1867         {
1868           err = gpg_error_from_syserror ();
1869           goto leave;
1870         }
1871     }
1872   line = skip_options (line);
1873
1874   if (!ctrl->server_local->export_key)
1875     {
1876       err = gpg_error (GPG_ERR_MISSING_KEY);
1877       goto leave;
1878     }
1879
1880   err = parse_keygrip (ctx, line, grip);
1881   if (err)
1882     goto leave;
1883
1884   if (agent_key_available (grip))
1885     {
1886       err = gpg_error (GPG_ERR_NO_SECKEY);
1887       goto leave;
1888     }
1889
1890   /* Get the key from the file.  With the openpgp flag we also ask for
1891      the passphrase so that we can use it to re-encrypt it.  */
1892   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
1893                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
1894                              openpgp ? &passphrase : NULL);
1895   if (err)
1896     goto leave;
1897   if (!s_skey)
1898     {
1899       /* Key is on a smartcard.  Actually we should not see this here
1900          because we do not pass a shadow_info variable to the above
1901          function, thus it will return this error directly.  */
1902       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
1903       goto leave;
1904     }
1905
1906   if (openpgp)
1907     {
1908       /* The openpgp option changes the key format into the OpenPGP
1909          key transfer format.  The result is already a padded
1910          canonical S-expression.  */
1911       if (!passphrase)
1912         {
1913           err = agent_ask_new_passphrase
1914             (ctrl, _("This key (or subkey) is not protected with a passphrase."
1915                      "  Please enter a new passphrase to export it."),
1916              &passphrase);
1917           if (err)
1918             goto leave;
1919         }
1920       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
1921     }
1922   else
1923     {
1924       /* Convert into a canonical S-expression and wrap that.  */
1925       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
1926     }
1927   if (err)
1928     goto leave;
1929   gcry_sexp_release (s_skey);
1930   s_skey = NULL;
1931
1932   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1933                           GCRY_CIPHER_MODE_AESWRAP, 0);
1934   if (err)
1935     goto leave;
1936   err = gcry_cipher_setkey (cipherhd,
1937                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
1938   if (err)
1939     goto leave;
1940
1941   wrappedkeylen = keylen + 8;
1942   wrappedkey = xtrymalloc (wrappedkeylen);
1943   if (!wrappedkey)
1944     {
1945       err = gpg_error_from_syserror ();
1946       goto leave;
1947     }
1948
1949   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
1950   if (err)
1951     goto leave;
1952   xfree (key);
1953   key = NULL;
1954   gcry_cipher_close (cipherhd);
1955   cipherhd = NULL;
1956
1957   assuan_begin_confidential (ctx);
1958   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
1959   assuan_end_confidential (ctx);
1960
1961
1962  leave:
1963   xfree (cache_nonce);
1964   xfree (passphrase);
1965   xfree (wrappedkey);
1966   gcry_cipher_close (cipherhd);
1967   xfree (key);
1968   gcry_sexp_release (s_skey);
1969   xfree (ctrl->server_local->keydesc);
1970   ctrl->server_local->keydesc = NULL;
1971
1972   return leave_cmd (ctx, err);
1973 }
1974
1975
1976
1977 \f
1978 static const char hlp_getval[] =
1979   "GETVAL <key>\n"
1980   "\n"
1981   "Return the value for KEY from the special environment as created by\n"
1982   "PUTVAL.";
1983 static gpg_error_t
1984 cmd_getval (assuan_context_t ctx, char *line)
1985 {
1986   int rc = 0;
1987   char *key = NULL;
1988   char *p;
1989   struct putval_item_s *vl;
1990
1991   for (p=line; *p == ' '; p++)
1992     ;
1993   key = p;
1994   p = strchr (key, ' ');
1995   if (p)
1996     {
1997       *p++ = 0;
1998       for (; *p == ' '; p++)
1999         ;
2000       if (*p)
2001         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2002     }
2003   if (!key || !*key)
2004     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2005
2006
2007   for (vl=putval_list; vl; vl = vl->next)
2008     if ( !strcmp (vl->d, key) )
2009       break;
2010
2011   if (vl) /* Got an entry. */
2012     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2013   else
2014     return gpg_error (GPG_ERR_NO_DATA);
2015
2016   return leave_cmd (ctx, rc);
2017 }
2018
2019
2020 static const char hlp_putval[] =
2021   "PUTVAL <key> [<percent_escaped_value>]\n"
2022   "\n"
2023   "The gpg-agent maintains a kind of environment which may be used to\n"
2024   "store key/value pairs in it, so that they can be retrieved later.\n"
2025   "This may be used by helper daemons to daemonize themself on\n"
2026   "invocation and register them with gpg-agent.  Callers of the\n"
2027   "daemon's service may now first try connect to get the information\n"
2028   "for that service from gpg-agent through the GETVAL command and then\n"
2029   "try to connect to that daemon.  Only if that fails they may start\n"
2030   "an own instance of the service daemon. \n"
2031   "\n"
2032   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2033   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2034   "corresponsing value; they should be similar to the values of\n"
2035   "envronment variables but gpg-agent does not enforce any\n"
2036   "restrictions.  If that value is not given any value under that KEY\n"
2037   "is removed from this special environment.";
2038 static gpg_error_t
2039 cmd_putval (assuan_context_t ctx, char *line)
2040 {
2041   int rc = 0;
2042   char *key = NULL;
2043   char *value = NULL;
2044   size_t valuelen = 0;
2045   char *p;
2046   struct putval_item_s *vl, *vlprev;
2047
2048   for (p=line; *p == ' '; p++)
2049     ;
2050   key = p;
2051   p = strchr (key, ' ');
2052   if (p)
2053     {
2054       *p++ = 0;
2055       for (; *p == ' '; p++)
2056         ;
2057       if (*p)
2058         {
2059           value = p;
2060           p = strchr (value, ' ');
2061           if (p)
2062             *p = 0;
2063           valuelen = percent_plus_unescape_inplace (value, 0);
2064         }
2065     }
2066   if (!key || !*key)
2067     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2068
2069
2070   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2071     if ( !strcmp (vl->d, key) )
2072       break;
2073
2074   if (vl) /* Delete old entry. */
2075     {
2076       if (vlprev)
2077         vlprev->next = vl->next;
2078       else
2079         putval_list = vl->next;
2080       xfree (vl);
2081     }
2082
2083   if (valuelen) /* Add entry. */
2084     {
2085       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2086       if (!vl)
2087         rc = gpg_error_from_syserror ();
2088       else
2089         {
2090           vl->len = valuelen;
2091           vl->off = strlen (key) + 1;
2092           strcpy (vl->d, key);
2093           memcpy (vl->d + vl->off, value, valuelen);
2094           vl->next = putval_list;
2095           putval_list = vl;
2096         }
2097     }
2098
2099   return leave_cmd (ctx, rc);
2100 }
2101
2102
2103
2104 \f
2105 static const char hlp_updatestartuptty[] =
2106   "UPDATESTARTUPTTY\n"
2107   "\n"
2108   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2109   "session.  This command is useful to pull future pinentries to\n"
2110   "another screen.  It is only required because there is no way in the\n"
2111   "ssh-agent protocol to convey this information.";
2112 static gpg_error_t
2113 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2114 {
2115   static const char *names[] =
2116     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2117   ctrl_t ctrl = assuan_get_pointer (ctx);
2118   gpg_error_t err = 0;
2119   session_env_t se;
2120   int idx;
2121   char *lc_ctype = NULL;
2122   char *lc_messages = NULL;
2123
2124   (void)line;
2125
2126   se = session_env_new ();
2127   if (!se)
2128     err = gpg_error_from_syserror ();
2129
2130   for (idx=0; !err && names[idx]; idx++)
2131     {
2132       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2133       if (value)
2134         err = session_env_setenv (se, names[idx], value);
2135     }
2136
2137   if (!err && ctrl->lc_ctype)
2138     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2139       err = gpg_error_from_syserror ();
2140
2141   if (!err && ctrl->lc_messages)
2142     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2143       err = gpg_error_from_syserror ();
2144
2145   if (err)
2146     {
2147       session_env_release (se);
2148       xfree (lc_ctype);
2149       xfree (lc_messages);
2150     }
2151   else
2152     {
2153       session_env_release (opt.startup_env);
2154       opt.startup_env = se;
2155       xfree (opt.startup_lc_ctype);
2156       opt.startup_lc_ctype = lc_ctype;
2157       xfree (opt.startup_lc_messages);
2158       opt.startup_lc_messages = lc_messages;
2159     }
2160
2161   return err;
2162 }
2163
2164
2165 \f
2166 static const char hlp_killagent[] =
2167   "KILLAGENT\n"
2168   "\n"
2169   "If the agent has been started using a standard socket\n"
2170   "we allow a client to stop the agent.";
2171 static gpg_error_t
2172 cmd_killagent (assuan_context_t ctx, char *line)
2173 {
2174   ctrl_t ctrl = assuan_get_pointer (ctx);
2175
2176   (void)line;
2177
2178   if (!opt.use_standard_socket)
2179     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
2180
2181   ctrl->server_local->stopme = 1;
2182   return gpg_error (GPG_ERR_EOF);
2183 }
2184
2185
2186 static const char hlp_reloadagent[] =
2187   "RELOADAGENT\n"
2188   "\n"
2189   "This command is an alternative to SIGHUP\n"
2190   "to reload the configuration.";
2191 static gpg_error_t
2192 cmd_reloadagent (assuan_context_t ctx, char *line)
2193 {
2194   (void)ctx;
2195   (void)line;
2196
2197   agent_sighup_action ();
2198   return 0;
2199 }
2200
2201
2202 \f
2203 static const char hlp_getinfo[] =
2204   "GETINFO <what>\n"
2205   "\n"
2206   "Multipurpose function to return a variety of information.\n"
2207   "Supported values for WHAT are:\n"
2208   "\n"
2209   "  version     - Return the version of the program.\n"
2210   "  pid         - Return the process id of the server.\n"
2211   "  socket_name - Return the name of the socket.\n"
2212   "  ssh_socket_name - Return the name of the ssh socket.\n"
2213   "  scd_running - Return OK if the SCdaemon is already running.\n"
2214   "  s2k_count   - Return the calibrated S2K count.\n"
2215   "  std_session_env - List the standard session environment.\n"
2216   "  std_startup_env - List the standard startup environment.\n"
2217   "  cmd_has_option\n"
2218   "              - Returns OK if the command CMD implements the option OPT\n.";
2219 static gpg_error_t
2220 cmd_getinfo (assuan_context_t ctx, char *line)
2221 {
2222   ctrl_t ctrl = assuan_get_pointer (ctx);
2223   int rc = 0;
2224
2225   if (!strcmp (line, "version"))
2226     {
2227       const char *s = VERSION;
2228       rc = assuan_send_data (ctx, s, strlen (s));
2229     }
2230   else if (!strcmp (line, "pid"))
2231     {
2232       char numbuf[50];
2233
2234       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2235       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2236     }
2237   else if (!strcmp (line, "socket_name"))
2238     {
2239       const char *s = get_agent_socket_name ();
2240
2241       if (s)
2242         rc = assuan_send_data (ctx, s, strlen (s));
2243       else
2244         rc = gpg_error (GPG_ERR_NO_DATA);
2245     }
2246   else if (!strcmp (line, "ssh_socket_name"))
2247     {
2248       const char *s = get_agent_ssh_socket_name ();
2249
2250       if (s)
2251         rc = assuan_send_data (ctx, s, strlen (s));
2252       else
2253         rc = gpg_error (GPG_ERR_NO_DATA);
2254     }
2255   else if (!strcmp (line, "scd_running"))
2256     {
2257       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2258     }
2259   else if (!strcmp (line, "s2k_count"))
2260     {
2261       char numbuf[50];
2262
2263       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2264       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2265     }
2266   else if (!strcmp (line, "std_session_env")
2267            || !strcmp (line, "std_startup_env"))
2268     {
2269       int iterator;
2270       const char *name, *value;
2271       char *string;
2272
2273       iterator = 0;
2274       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2275         {
2276           value = session_env_getenv_or_default
2277             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2278           if (value)
2279             {
2280               string = xtryasprintf ("%s=%s", name, value);
2281               if (!string)
2282                 rc = gpg_error_from_syserror ();
2283               else
2284                 {
2285                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2286                   if (!rc)
2287                     rc = assuan_send_data (ctx, NULL, 0);
2288                 }
2289               if (rc)
2290                 break;
2291             }
2292         }
2293     }
2294   else if (!strncmp (line, "cmd_has_option", 14)
2295            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2296     {
2297       char *cmd, *cmdopt;
2298       line += 14;
2299       while (*line == ' ' || *line == '\t')
2300         line++;
2301       if (!*line)
2302         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2303       else
2304         {
2305           cmd = line;
2306           while (*line && (*line != ' ' && *line != '\t'))
2307             line++;
2308           if (!*line)
2309             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2310           else
2311             {
2312               *line++ = 0;
2313               while (*line == ' ' || *line == '\t')
2314                 line++;
2315               if (!*line)
2316                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2317               else
2318                 {
2319                   cmdopt = line;
2320                   if (!command_has_option (cmd, cmdopt))
2321                     rc = gpg_error (GPG_ERR_GENERAL);
2322                 }
2323             }
2324         }
2325     }
2326   else
2327     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2328   return rc;
2329 }
2330
2331
2332 \f
2333 static gpg_error_t
2334 option_handler (assuan_context_t ctx, const char *key, const char *value)
2335 {
2336   ctrl_t ctrl = assuan_get_pointer (ctx);
2337   gpg_error_t err = 0;
2338
2339   if (!strcmp (key, "agent-awareness"))
2340     {
2341       /* The value is a version string telling us of which agent
2342          version the caller is aware of.  */
2343       ctrl->server_local->allow_fully_canceled =
2344         gnupg_compare_version (value, "2.1.0");
2345     }
2346   else if (!strcmp (key, "putenv"))
2347     {
2348       /* Change the session's environment to be used for the
2349          Pinentry.  Valid values are:
2350           <NAME>            Delete envvar NAME
2351           <KEY>=            Set envvar NAME to the empty string
2352           <KEY>=<VALUE>     Set envvar NAME to VALUE
2353       */
2354       err = session_env_putenv (ctrl->session_env, value);
2355     }
2356   else if (!strcmp (key, "display"))
2357     {
2358       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2359     }
2360   else if (!strcmp (key, "ttyname"))
2361     {
2362       if (!opt.keep_tty)
2363         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2364     }
2365   else if (!strcmp (key, "ttytype"))
2366     {
2367       if (!opt.keep_tty)
2368         err = session_env_setenv (ctrl->session_env, "TERM", value);
2369     }
2370   else if (!strcmp (key, "lc-ctype"))
2371     {
2372       if (ctrl->lc_ctype)
2373         xfree (ctrl->lc_ctype);
2374       ctrl->lc_ctype = xtrystrdup (value);
2375       if (!ctrl->lc_ctype)
2376         return out_of_core ();
2377     }
2378   else if (!strcmp (key, "lc-messages"))
2379     {
2380       if (ctrl->lc_messages)
2381         xfree (ctrl->lc_messages);
2382       ctrl->lc_messages = xtrystrdup (value);
2383       if (!ctrl->lc_messages)
2384         return out_of_core ();
2385     }
2386   else if (!strcmp (key, "xauthority"))
2387     {
2388       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
2389     }
2390   else if (!strcmp (key, "pinentry-user-data"))
2391     {
2392       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
2393     }
2394   else if (!strcmp (key, "use-cache-for-signing"))
2395     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
2396   else if (!strcmp (key, "allow-pinentry-notify"))
2397     ctrl->server_local->allow_pinentry_notify = 1;
2398   else
2399     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2400
2401   return err;
2402 }
2403
2404
2405
2406 \f
2407 /* Called by libassuan after all commands. ERR is the error from the
2408    last assuan operation and not the one returned from the command. */
2409 static void
2410 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
2411 {
2412   ctrl_t ctrl = assuan_get_pointer (ctx);
2413
2414   (void)err;
2415
2416   /* Switch off any I/O monitor controlled logging pausing. */
2417   ctrl->server_local->pause_io_logging = 0;
2418 }
2419
2420
2421 /* This function is called by libassuan for all I/O.  We use it here
2422    to disable logging for the GETEVENTCOUNTER commands.  This is so
2423    that the debug output won't get cluttered by this primitive
2424    command.  */
2425 static unsigned int
2426 io_monitor (assuan_context_t ctx, void *hook, int direction,
2427             const char *line, size_t linelen)
2428 {
2429   ctrl_t ctrl = assuan_get_pointer (ctx);
2430
2431   (void) hook;
2432
2433   /* Note that we only check for the uppercase name.  This allows to
2434      see the logging for debugging if using a non-upercase command
2435      name. */
2436   if (ctx && direction == ASSUAN_IO_FROM_PEER
2437       && linelen >= 15
2438       && !strncmp (line, "GETEVENTCOUNTER", 15)
2439       && (linelen == 15 || spacep (line+15)))
2440     {
2441       ctrl->server_local->pause_io_logging = 1;
2442     }
2443
2444   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2445 }
2446
2447
2448 /* Return true if the command CMD implements the option OPT.  */
2449 static int
2450 command_has_option (const char *cmd, const char *cmdopt)
2451 {
2452   if (!strcmp (cmd, "GET_PASSPHRASE"))
2453     {
2454       if (!strcmp (cmdopt, "repeat"))
2455           return 1;
2456     }
2457
2458   return 0;
2459 }
2460
2461
2462 /* Tell the assuan library about our commands */
2463 static int
2464 register_commands (assuan_context_t ctx)
2465 {
2466   static struct {
2467     const char *name;
2468     assuan_handler_t handler;
2469     const char * const help;
2470   } table[] = {
2471     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2472     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2473     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2474     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2475     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2476     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2477     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2478     { "SETHASH",        cmd_sethash,   hlp_sethash },
2479     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2480     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2481     { "GENKEY",         cmd_genkey,    hlp_genkey },
2482     { "READKEY",        cmd_readkey,   hlp_readkey },
2483     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2484     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2485     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2486     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2487     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2488     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2489     { "LEARN",          cmd_learn,     hlp_learn },
2490     { "PASSWD",         cmd_passwd,    hlp_passwd },
2491     { "INPUT",          NULL },
2492     { "OUTPUT",         NULL },
2493     { "SCD",            cmd_scd,       hlp_scd },
2494     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
2495     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
2496     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
2497     { "GETVAL",         cmd_getval,    hlp_getval },
2498     { "PUTVAL",         cmd_putval,    hlp_putval },
2499     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2500     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2501     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2502     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2503     { NULL }
2504   };
2505   int i, rc;
2506
2507   for (i=0; table[i].name; i++)
2508     {
2509       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2510                                     table[i].help);
2511       if (rc)
2512         return rc;
2513     }
2514   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2515   assuan_register_reset_notify (ctx, reset_notify);
2516   assuan_register_option_handler (ctx, option_handler);
2517   return 0;
2518 }
2519
2520
2521 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2522    simple piper server, otherwise it is a regular server.  CTRL is the
2523    control structure for this connection; it has only the basic
2524    intialization. */
2525 void
2526 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2527 {
2528   int rc;
2529   assuan_context_t ctx = NULL;
2530
2531   rc = assuan_new (&ctx);
2532   if (rc)
2533     {
2534       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2535       agent_exit (2);
2536     }
2537
2538   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2539     {
2540       assuan_fd_t filedes[2];
2541
2542       filedes[0] = assuan_fdopen (0);
2543       filedes[1] = assuan_fdopen (1);
2544       rc = assuan_init_pipe_server (ctx, filedes);
2545     }
2546   else if (listen_fd != GNUPG_INVALID_FD)
2547     {
2548       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2549       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2550          this branch is currently not used.  */
2551     }
2552   else
2553     {
2554       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2555     }
2556   if (rc)
2557     {
2558       log_error ("failed to initialize the server: %s\n",
2559                  gpg_strerror(rc));
2560       agent_exit (2);
2561     }
2562   rc = register_commands (ctx);
2563   if (rc)
2564     {
2565       log_error ("failed to register commands with Assuan: %s\n",
2566                  gpg_strerror(rc));
2567       agent_exit (2);
2568     }
2569
2570   assuan_set_pointer (ctx, ctrl);
2571   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2572   ctrl->server_local->assuan_ctx = ctx;
2573   ctrl->server_local->message_fd = -1;
2574   ctrl->server_local->use_cache_for_signing = 1;
2575   ctrl->digest.raw_value = 0;
2576
2577   assuan_set_io_monitor (ctx, io_monitor, NULL);
2578
2579   for (;;)
2580     {
2581       rc = assuan_accept (ctx);
2582       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
2583         {
2584           break;
2585         }
2586       else if (rc)
2587         {
2588           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2589           break;
2590         }
2591
2592       rc = assuan_process (ctx);
2593       if (rc)
2594         {
2595           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2596           continue;
2597         }
2598     }
2599
2600   /* Reset the nonce caches.  */
2601   clear_nonce_cache (ctrl);
2602
2603   /* Reset the SCD if needed. */
2604   agent_reset_scd (ctrl);
2605
2606   /* Reset the pinentry (in case of popup messages). */
2607   agent_reset_query (ctrl);
2608
2609   /* Cleanup.  */
2610   assuan_release (ctx);
2611   xfree (ctrl->server_local->keydesc);
2612   xfree (ctrl->server_local->import_key);
2613   xfree (ctrl->server_local->export_key);
2614   if (ctrl->server_local->stopme)
2615     agent_exit (0);
2616   xfree (ctrl->server_local);
2617   ctrl->server_local = NULL;
2618 }