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