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