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