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