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