New gpg-agent command to list key information.
[gnupg.git] / agent / command.c
1 /* command.c - gpg-agent command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3  *               2006, 2008, 2009  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 <assuan.h>
38
39 #include "agent.h"
40
41 /* maximum allowed size of the inquired ciphertext */
42 #define MAXLEN_CIPHERTEXT 4096
43 /* maximum allowed size of the key parameters */
44 #define MAXLEN_KEYPARAM 1024
45
46 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
47
48
49 #if MAX_DIGEST_LEN < 20
50 #error MAX_DIGEST_LEN shorter than keygrip
51 #endif
52
53 /* Data used to associate an Assuan context with local server data */
54 struct server_local_s
55 {
56   assuan_context_t assuan_ctx;
57   int message_fd;
58   int use_cache_for_signing;
59   char *keydesc;  /* Allocated description for the next key
60                      operation. */
61   int pause_io_logging; /* Used to suppress I/O logging during a command */
62 #ifdef HAVE_W32_SYSTEM
63   int stopme;    /* If set to true the agent will be terminated after
64                     the end of this session.  */
65 #endif
66   int allow_pinentry_notify; /* Set if pinentry notifications should
67                                 be done. */
68 };
69
70
71 /* An entry for the getval/putval commands. */
72 struct putval_item_s
73 {
74   struct putval_item_s *next;
75   size_t off;  /* Offset to the value into DATA.  */
76   size_t len;  /* Length of the value.  */
77   char d[1];   /* Key | Nul | value.  */ 
78 };
79
80
81 /* A list of key value pairs fpr the getval/putval commands.  */
82 static struct putval_item_s *putval_list;
83
84
85 \f
86 /* To help polling clients, we keep track of the number of certain
87    events.  This structure keeps those counters.  The counters are
88    integers and there should be no problem if they are overflowing as
89    callers need to check only whether a counter changed.  The actual
90    values are not meaningful. */
91 struct 
92 {
93   /* Incremented if any of the other counters below changed. */
94   unsigned int any;
95
96   /* Incremented if a key is added or removed from the internal privat
97      key database. */
98   unsigned int key; 
99
100   /* Incremented if a change of the card readers stati has been
101      detected. */
102   unsigned int card;
103
104 } eventcounter;
105
106
107
108
109 \f
110 /* Release the memory buffer MB but first wipe out the used memory. */
111 static void
112 clear_outbuf (membuf_t *mb)
113 {
114   void *p;
115   size_t n;
116
117   p = get_membuf (mb, &n);
118   if (p)
119     {
120       memset (p, 0, n);
121       xfree (p);
122     }
123 }
124
125
126 /* Write the content of memory buffer MB as assuan data to CTX and
127    wipe the buffer out afterwards. */
128 static gpg_error_t
129 write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
130 {
131   assuan_error_t ae;
132   void *p;
133   size_t n;
134
135   p = get_membuf (mb, &n);
136   if (!p)
137     return out_of_core ();
138   ae = assuan_send_data (ctx, p, n);
139   memset (p, 0, n);
140   xfree (p);
141   return ae;
142 }
143
144
145 static void
146 reset_notify (assuan_context_t ctx)
147 {
148   ctrl_t ctrl = assuan_get_pointer (ctx);
149
150   memset (ctrl->keygrip, 0, 20);
151   ctrl->have_keygrip = 0;
152   ctrl->digest.valuelen = 0;
153
154   xfree (ctrl->server_local->keydesc);
155   ctrl->server_local->keydesc = NULL;
156 }
157
158
159 /* Check whether the option NAME appears in LINE */
160 static int
161 has_option (const char *line, const char *name)
162 {
163   const char *s;
164   int n = strlen (name);
165
166   s = strstr (line, name);
167   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
168 }
169
170 /* Same as has_option but does only test for the name of the option
171    and ignores an argument, i.e. with NAME being "--hash" it would
172    return true for "--hash" as well as for "--hash=foo". */
173 static int
174 has_option_name (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))
181           && (!s[n] || spacep (s+n) || s[n] == '='));
182 }
183
184
185 /* Skip over options.  It is assumed that leading spaces have been
186    removed (this is the case for lines passed to a handler from
187    assuan).  Blanks after the options are also removed. */
188 static char *
189 skip_options (char *line)
190 {
191   while ( *line == '-' && line[1] == '-' )
192     {
193       while (*line && !spacep (line))
194         line++;
195       while (spacep (line))
196         line++;
197     }
198   return line;
199 }
200
201
202 /* Replace all '+' by a blank. */
203 static void
204 plus_to_blank (char *s)
205 {
206   for (; *s; s++)
207     {
208       if (*s == '+')
209         *s = ' ';
210     }
211 }
212
213
214 /* Do the percent and plus/space unescaping in place and return the
215    length of the valid buffer. */
216 static size_t
217 percent_plus_unescape (char *string)
218 {
219   unsigned char *p = (unsigned char *)string;
220   size_t n = 0;
221
222   while (*string)
223     {
224       if (*string == '%' && string[1] && string[2])
225         { 
226           string++;
227           *p++ = xtoi_2 (string);
228           n++;
229           string+= 2;
230         }
231       else if (*string == '+')
232         {
233           *p++ = ' ';
234           n++;
235           string++;
236         }
237       else
238         {
239           *p++ = *string++;
240           n++;
241         }
242     }
243
244   return n;
245 }
246
247
248
249
250 /* Parse a hex string.  Return an Assuan error code or 0 on success and the
251    length of the parsed string in LEN. */
252 static int
253 parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
254 {
255   const char *p;
256   size_t n;
257
258   /* parse the hash value */
259   for (p=string, n=0; hexdigitp (p); p++, n++)
260     ;
261   if (*p != ' ' && *p != '\t' && *p)
262     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
263   if ((n&1))
264     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
265   *len = n;
266   return 0;
267 }
268
269 /* Parse the keygrip in STRING into the provided buffer BUF.  BUF must
270    provide space for 20 bytes. BUF is not changed if the function
271    returns an error. */
272 static int
273 parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
274 {
275   int rc;
276   size_t n;
277
278   rc = parse_hexstring (ctx, string, &n);
279   if (rc)
280     return rc;
281   n /= 2;
282   if (n != 20)
283     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip");
284
285   if (hex2bin (string, buf, 20) < 0)
286     return set_error (GPG_ERR_BUG, "hex2bin");
287
288   return 0;
289 }
290
291
292 /* Write an assuan status line. */
293 gpg_error_t
294 agent_write_status (ctrl_t ctrl, const char *keyword, ...)
295 {
296   gpg_error_t err = 0;
297   va_list arg_ptr;
298   const char *text;
299   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
300   char buf[950], *p;
301   size_t n;
302
303   va_start (arg_ptr, keyword);
304
305   p = buf; 
306   n = 0;
307   while ( (text = va_arg (arg_ptr, const char *)) )
308     {
309       if (n)
310         {
311           *p++ = ' ';
312           n++;
313         }
314       for ( ; *text && n < DIM (buf)-3; n++, text++)
315         {
316           if (*text == '\n')
317             {
318               *p++ = '\\';
319               *p++ = 'n';
320             }
321           else if (*text == '\r')
322             {
323               *p++ = '\\';
324               *p++ = 'r';
325             }
326           else
327             *p++ = *text;
328         }
329     }
330   *p = 0;
331   err = assuan_write_status (ctx, keyword, buf);
332
333   va_end (arg_ptr);
334   return err;
335 }
336
337
338 /* Helper to notify the client about a launched Pinentry.  Because
339    that might disturb some older clients, this is only done if enabled
340    via an option.  Returns an gpg error code. */
341 gpg_error_t
342 agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
343 {
344   char line[100];
345
346   if (!ctrl || !ctrl->server_local 
347       || !ctrl->server_local->allow_pinentry_notify)
348     return 0;
349   snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
350   return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
351 }
352
353
354 \f
355 /* GETEVENTCOUNTER
356
357    Return a a status line named EVENTCOUNTER with the current values
358    of all event counters.  The values are decimal numbers in the range
359    0 to UINT_MAX and wrapping around to 0.  The actual values should
360    not be relied upon, they shall only be used to detect a change.
361
362    The currently defined counters are:
363
364    ANY  - Incremented with any change of any of the other counters.
365    KEY  - Incremented for added or removed private keys.
366    CARD - Incremented for changes of the card readers stati.
367 */
368 static int
369 cmd_geteventcounter (assuan_context_t ctx, char *line)
370 {
371   ctrl_t ctrl = assuan_get_pointer (ctx);
372   char any_counter[25];
373   char key_counter[25];
374   char card_counter[25];
375
376   (void)line;
377
378   snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any);
379   snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key);
380   snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card);
381
382   return agent_write_status (ctrl, "EVENTCOUNTER",
383                              any_counter,
384                              key_counter,
385                              card_counter,
386                              NULL);
387 }
388
389
390 /* This function should be called once for all key removals or
391    additions.  This function is assured not to do any context
392    switches. */
393 void
394 bump_key_eventcounter (void)
395 {
396   eventcounter.key++;
397   eventcounter.any++;
398 }
399
400 /* This function should be called for all card reader status
401    changes.  This function is assured not to do any context
402    switches. */
403 void
404 bump_card_eventcounter (void)
405 {
406   eventcounter.card++;
407   eventcounter.any++;
408 }
409
410
411
412 \f
413 /* ISTRUSTED <hexstring_with_fingerprint>
414
415    Return OK when we have an entry with this fingerprint in our
416    trustlist */
417 static int
418 cmd_istrusted (assuan_context_t ctx, char *line)
419 {
420   ctrl_t ctrl = assuan_get_pointer (ctx);
421   int rc, n, i;
422   char *p;
423   char fpr[41];
424
425   /* Parse the fingerprint value. */
426   for (p=line,n=0; hexdigitp (p); p++, n++)
427     ;
428   if (*p || !(n == 40 || n == 32))
429     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
430   i = 0;
431   if (n==32)
432     {
433       strcpy (fpr, "00000000");
434       i += 8;
435     }
436   for (p=line; i < 40; p++, i++)
437     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
438   fpr[i] = 0;
439   rc = agent_istrusted (ctrl, fpr);
440   if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
441     return rc;
442   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
443     return gpg_error (GPG_ERR_NOT_TRUSTED);
444   else
445     {
446       log_error ("command is_trusted failed: %s\n", gpg_strerror (rc));
447       return rc;
448     }
449 }
450
451 /* LISTTRUSTED 
452
453    List all entries from the trustlist */
454 static int
455 cmd_listtrusted (assuan_context_t ctx, char *line)
456 {
457   int rc;
458   
459   (void)line;
460
461   rc = agent_listtrusted (ctx);
462   if (rc)
463     log_error ("command listtrusted failed: %s\n", gpg_strerror (rc));
464   return rc;
465 }
466
467
468 /* MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>
469
470    Store a new key in into the trustlist*/
471 static int
472 cmd_marktrusted (assuan_context_t ctx, char *line)
473 {
474   ctrl_t ctrl = assuan_get_pointer (ctx);
475   int rc, n, i;
476   char *p;
477   char fpr[41];
478   int flag;
479
480   /* parse the fingerprint value */
481   for (p=line,n=0; hexdigitp (p); p++, n++)
482     ;
483   if (!spacep (p) || !(n == 40 || n == 32))
484     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
485   i = 0;
486   if (n==32)
487     {
488       strcpy (fpr, "00000000");
489       i += 8;
490     }
491   for (p=line; i < 40; p++, i++)
492     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
493   fpr[i] = 0;
494   
495   while (spacep (p))
496     p++;
497   flag = *p++;
498   if ( (flag != 'S' && flag != 'P') || !spacep (p) )
499     return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
500   while (spacep (p))
501     p++;
502
503   rc = agent_marktrusted (ctrl, p, fpr, flag);
504   if (rc)
505     log_error ("command marktrusted failed: %s\n", gpg_strerror (rc));
506   return rc;
507 }
508
509
510
511 \f
512 /* HAVEKEY <hexstring_with_keygrip>
513   
514    Return success when the secret key is available */
515 static int
516 cmd_havekey (assuan_context_t ctx, char *line)
517 {
518   int rc;
519   unsigned char buf[20];
520
521   rc = parse_keygrip (ctx, line, buf);
522   if (rc)
523     return rc;
524
525   if (agent_key_available (buf))
526     return gpg_error (GPG_ERR_NO_SECKEY);
527
528   return 0;
529 }
530
531
532 /* SIGKEY <hexstring_with_keygrip>
533    SETKEY <hexstring_with_keygrip>
534   
535    Set the  key used for a sign or decrypt operation */
536 static int
537 cmd_sigkey (assuan_context_t ctx, char *line)
538 {
539   int rc;
540   ctrl_t ctrl = assuan_get_pointer (ctx);
541
542   rc = parse_keygrip (ctx, line, ctrl->keygrip);
543   if (rc)
544     return rc;
545   ctrl->have_keygrip = 1;
546   return 0;
547 }
548
549
550 /* SETKEYDESC plus_percent_escaped_string
551
552    Set a description to be used for the next PKSIGN or PKDECRYPT
553    operation if this operation requires the entry of a passphrase.  If
554    this command is not used a default text will be used.  Note, that
555    this description implictly selects the label used for the entry
556    box; if the string contains the string PIN (which in general will
557    not be translated), "PIN" is used, otherwise the translation of
558    "passphrase" is used.  The description string should not contain
559    blanks unless they are percent or '+' escaped.
560
561    The description is only valid for the next PKSIGN or PKDECRYPT
562    operation.
563 */
564 static int
565 cmd_setkeydesc (assuan_context_t ctx, char *line)
566 {
567   ctrl_t ctrl = assuan_get_pointer (ctx);
568   char *desc, *p;
569
570   for (p=line; *p == ' '; p++)
571     ;
572   desc = p;
573   p = strchr (desc, ' ');
574   if (p)
575     *p = 0; /* We ignore any garbage; we might late use it for other args. */
576
577   if (!desc || !*desc)
578     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
579
580   /* Note, that we only need to replace the + characters and should
581      leave the other escaping in place because the escaped string is
582      send verbatim to the pinentry which does the unescaping (but not
583      the + replacing) */
584   plus_to_blank (desc);
585
586   xfree (ctrl->server_local->keydesc);
587   ctrl->server_local->keydesc = xtrystrdup (desc);
588   if (!ctrl->server_local->keydesc)
589     return out_of_core ();
590   return 0;
591 }
592
593
594 /* SETHASH --hash=<name>|<algonumber> <hexstring> 
595
596   The client can use this command to tell the server about the data
597   (which usually is a hash) to be signed. */
598 static int
599 cmd_sethash (assuan_context_t ctx, char *line)
600 {
601   int rc;
602   size_t n;
603   char *p;
604   ctrl_t ctrl = assuan_get_pointer (ctx);
605   unsigned char *buf;
606   char *endp;
607   int algo;
608
609   /* Parse the alternative hash options which may be used instead of
610      the algo number.  */
611   if (has_option_name (line, "--hash"))
612     {
613       if (has_option (line, "--hash=sha1"))
614         algo = GCRY_MD_SHA1;
615       else if (has_option (line, "--hash=sha256"))
616         algo = GCRY_MD_SHA256;
617       else if (has_option (line, "--hash=rmd160"))
618         algo = GCRY_MD_RMD160;
619       else if (has_option (line, "--hash=md5"))
620         algo = GCRY_MD_MD5;
621       else if (has_option (line, "--hash=tls-md5sha1"))
622         algo = MD_USER_TLS_MD5SHA1;
623       else
624         return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
625     }
626   else
627     algo = 0;
628
629   line = skip_options (line);
630   
631   if (!algo)
632     {
633       /* No hash option has been given: require an algo number instead  */
634       algo = (int)strtoul (line, &endp, 10);
635       for (line = endp; *line == ' ' || *line == '\t'; line++)
636         ;
637       if (!algo || gcry_md_test_algo (algo))
638         return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
639     }
640   ctrl->digest.algo = algo;
641
642   /* Parse the hash value. */
643   rc = parse_hexstring (ctx, line, &n);
644   if (rc)
645     return rc;
646   n /= 2;
647   if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
648     ;
649   else if (n != 16 && n != 20 && n != 24 && n != 32)
650     return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
651
652   if (n > MAX_DIGEST_LEN)
653     return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
654
655   buf = ctrl->digest.value;
656   ctrl->digest.valuelen = n;
657   for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
658     buf[n] = xtoi_2 (p);
659   for (; n < ctrl->digest.valuelen; n++)
660     buf[n] = 0;
661   return 0;
662 }
663
664
665 /* PKSIGN <options>
666
667    Perform the actual sign operation. Neither input nor output are
668    sensitive to eavesdropping. */
669 static int
670 cmd_pksign (assuan_context_t ctx, char *line)
671 {
672   int rc;
673   cache_mode_t cache_mode = CACHE_MODE_NORMAL;
674   ctrl_t ctrl = assuan_get_pointer (ctx);
675   membuf_t outbuf;
676   
677   (void)line;
678   
679   if (opt.ignore_cache_for_signing)
680     cache_mode = CACHE_MODE_IGNORE;
681   else if (!ctrl->server_local->use_cache_for_signing)
682     cache_mode = CACHE_MODE_IGNORE;
683
684   init_membuf (&outbuf, 512);
685
686   rc = agent_pksign (ctrl, ctrl->server_local->keydesc,
687                      &outbuf, cache_mode);
688   if (rc)
689     clear_outbuf (&outbuf);
690   else
691     rc = write_and_clear_outbuf (ctx, &outbuf);
692   if (rc)
693     log_error ("command pksign failed: %s\n", gpg_strerror (rc));
694   xfree (ctrl->server_local->keydesc);
695   ctrl->server_local->keydesc = NULL;
696   return rc;
697 }
698
699 /* PKDECRYPT <options>
700
701    Perform the actual decrypt operation.  Input is not 
702    sensitive to eavesdropping */
703 static int
704 cmd_pkdecrypt (assuan_context_t ctx, char *line)
705 {
706   int rc;
707   ctrl_t ctrl = assuan_get_pointer (ctx);
708   unsigned char *value;
709   size_t valuelen;
710   membuf_t outbuf;
711
712   (void)line;
713
714   /* First inquire the data to decrypt */
715   rc = assuan_inquire (ctx, "CIPHERTEXT",
716                        &value, &valuelen, MAXLEN_CIPHERTEXT);
717   if (rc)
718     return rc;
719
720   init_membuf (&outbuf, 512);
721
722   rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
723                         value, valuelen, &outbuf);
724   xfree (value);
725   if (rc)
726     clear_outbuf (&outbuf);
727   else
728     rc = write_and_clear_outbuf (ctx, &outbuf);
729   if (rc)
730     log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc));
731   xfree (ctrl->server_local->keydesc);
732   ctrl->server_local->keydesc = NULL;
733   return rc;
734 }
735
736
737 /* GENKEY
738
739    Generate a new key, store the secret part and return the public
740    part.  Here is an example transaction:
741
742    C: GENKEY
743    S: INQUIRE KEYPARAM
744    C: D (genkey (rsa (nbits  1024)))
745    C: END
746    S: D (public-key
747    S: D   (rsa (n 326487324683264) (e 10001)))
748    S  OK key created
749 */
750
751 static int
752 cmd_genkey (assuan_context_t ctx, char *line)
753 {
754   ctrl_t ctrl = assuan_get_pointer (ctx);
755   int rc;
756   unsigned char *value;
757   size_t valuelen;
758   membuf_t outbuf;
759
760   (void)line;
761
762   /* First inquire the parameters */
763   rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
764   if (rc)
765     return rc;
766
767   init_membuf (&outbuf, 512);
768
769   rc = agent_genkey (ctrl, (char*)value, valuelen, &outbuf);
770   xfree (value);
771   if (rc)
772     clear_outbuf (&outbuf);
773   else
774     rc = write_and_clear_outbuf (ctx, &outbuf);
775   if (rc)
776     log_error ("command genkey failed: %s\n", gpg_strerror (rc));
777   return rc;
778 }
779
780
781
782 \f
783 /* READKEY <hexstring_with_keygrip>
784   
785    Return the public key for the given keygrip.  */
786 static int
787 cmd_readkey (assuan_context_t ctx, char *line)
788 {
789   ctrl_t ctrl = assuan_get_pointer (ctx);
790   int rc;
791   unsigned char grip[20];
792   gcry_sexp_t s_pkey = NULL;
793
794   rc = parse_keygrip (ctx, line, grip);
795   if (rc)
796     return rc; /* Return immediately as this is already an Assuan error code.*/
797
798   rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
799   if (!rc)
800     {
801       size_t len;
802       unsigned char *buf;
803
804       len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
805       assert (len);
806       buf = xtrymalloc (len);
807       if (!buf)
808         rc = gpg_error_from_syserror ();
809       else
810         {
811           len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
812           assert (len);
813           rc = assuan_send_data (ctx, buf, len);
814           xfree (buf);
815         }
816       gcry_sexp_release (s_pkey);
817     }
818
819   if (rc)
820     log_error ("command readkey failed: %s\n", gpg_strerror (rc));
821   return rc;
822 }
823
824
825 \f
826 /* KEYINFO [--list] <keygrip>
827
828    Return information about the key specified by the KEYGRIP.  If the
829    key is not available GPG_ERR_NOT_FOUND is returned.  If the option
830    --list is given the keygrip is ignored and information about all
831    available keys are returned.  The information is returned as a
832    status line with this format:
833
834      KEYINFO <keygrip> <type> <serialno> <idstr>
835
836    KEYGRIP is the keygrip.
837
838    TYPE is describes the type of the key:
839        'D' - Regular key stored on disk,
840        'T' - Key is stored on a smartcard (token).
841        '-' - Unknown type.
842
843    SERIALNO is an ASCII string with the serial number of the
844             smartcard.  If the serial number is not known a single
845             dash '-' is used instead.
846
847    IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it
848          is not known a dash is used instead.
849
850    More information may be added in the future.
851 */
852 static gpg_error_t
853 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip)
854 {
855   gpg_error_t err;
856   char hexgrip[40+1];
857   int keytype;
858   unsigned char *shadow_info = NULL;
859   char *serialno = NULL;
860   char *idstr = NULL;
861   const char *keytypestr;
862
863   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
864   if (err)
865     goto leave;
866
867   /* Reformat the grip so that we use uppercase as good style. */
868   bin2hex (grip, 20, hexgrip);
869       
870   if (keytype == PRIVATE_KEY_CLEAR 
871       || keytype == PRIVATE_KEY_PROTECTED)
872     keytypestr = "D";
873   else if (keytype == PRIVATE_KEY_SHADOWED)
874     keytypestr = "T";
875   else 
876     keytypestr = "-";
877       
878   if (shadow_info)
879     {
880       err = parse_shadow_info (shadow_info, &serialno, &idstr);
881       if (err)
882         goto leave;
883     }
884       
885   err = agent_write_status (ctrl, "KEYINFO",
886                             hexgrip,
887                             keytypestr,
888                             serialno? serialno : "-",
889                             idstr? idstr : "-",
890                             NULL);
891  leave:
892   xfree (shadow_info);
893   xfree (serialno);
894   xfree (idstr);
895   return err;
896 }
897
898
899 static int
900 cmd_keyinfo (assuan_context_t ctx, char *line)
901 {
902   ctrl_t ctrl = assuan_get_pointer (ctx);
903   int err;
904   unsigned char grip[20];
905   DIR *dir = NULL;
906   int list_mode;
907
908   list_mode = has_option (line, "--list");
909   line = skip_options (line);
910
911   if (list_mode)
912     {
913       char *dirname;
914       struct dirent *dir_entry;
915       char hexgrip[41];
916       
917       dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
918       if (!dirname)
919         {
920           err = gpg_error_from_syserror ();
921           goto leave;
922         }
923       dir = opendir (dirname);
924       if (!dir)
925         {
926           err = gpg_error_from_syserror ();
927           xfree (dirname);
928           goto leave;
929         }
930       xfree (dirname);
931
932       while ( (dir_entry = readdir (dir)) )
933         {
934           if (strlen (dir_entry->d_name) != 44
935               || strcmp (dir_entry->d_name + 40, ".key"))
936             continue;
937           strncpy (hexgrip, dir_entry->d_name, 40);
938           hexgrip[40] = 0;
939
940           if ( hex2bin (hexgrip, grip, 20) < 0 )
941             continue; /* Bad hex string.  */
942
943           err = do_one_keyinfo (ctrl, grip);
944           if (err)
945             goto leave;
946         }
947       err = 0;
948     }
949   else
950     {
951       err = parse_keygrip (ctx, line, grip);
952       if (err)
953         goto leave;
954       err = do_one_keyinfo (ctrl, grip);
955     }
956       
957  leave:
958   if (dir)
959     closedir (dir);
960   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
961     log_error ("command keyinfo failed: %s\n", gpg_strerror (err));
962   return err;
963 }
964
965
966 \f
967 static int
968 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
969 {
970   size_t n;
971   int rc;
972
973   assuan_begin_confidential (ctx);
974   n = strlen (pw);
975   if (via_data)
976     rc = assuan_send_data (ctx, pw, n);
977   else
978     {
979       char *p = xtrymalloc_secure (n*2+1);
980       if (!p)
981         rc = gpg_error_from_syserror ();
982       else
983         {
984           bin2hex (pw, n, p);
985           rc = assuan_set_okay_line (ctx, p);
986           xfree (p);
987         }
988     }
989   return rc;
990 }
991
992
993 /* GET_PASSPHRASE [--data] [--check] [--no-ask] <cache_id>
994                   [<error_message> <prompt> <description>]
995
996    This function is usually used to ask for a passphrase to be used
997    for conventional encryption, but may also be used by programs which
998    need specal handling of passphrases.  This command uses a syntax
999    which helps clients to use the agent with minimum effort.  The
1000    agent either returns with an error or with a OK followed by the hex
1001    encoded passphrase.  Note that the length of the strings is
1002    implicitly limited by the maximum length of a command.
1003
1004    If the option "--data" is used the passphrase is returned by usual
1005    data lines and not on the okay line.
1006
1007    If the option "--check" is used the passphrase constraints checks as
1008    implemented by gpg-agent are applied.  A check is not done if the
1009    passphrase has been found in the cache.
1010
1011    If the option "--no-ask" is used and the passphrase is not in the
1012    cache the user will not be asked to enter a passphrase but the error
1013    code GPG_ERR_NO_DATA is returned.  
1014 */
1015
1016 static int
1017 cmd_get_passphrase (assuan_context_t ctx, char *line)
1018 {
1019   ctrl_t ctrl = assuan_get_pointer (ctx);
1020   int rc;
1021   const char *pw;
1022   char *response;
1023   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1024   char *p;
1025   void *cache_marker;
1026   int opt_data, opt_check, opt_no_ask;
1027
1028   opt_data = has_option (line, "--data");
1029   opt_check = has_option (line, "--check");
1030   opt_no_ask = has_option (line, "--no-ask");
1031   line = skip_options (line);
1032
1033   cacheid = line;
1034   p = strchr (cacheid, ' ');
1035   if (p)
1036     {
1037       *p++ = 0;
1038       while (*p == ' ')
1039         p++;
1040       errtext = p;
1041       p = strchr (errtext, ' ');
1042       if (p)
1043         {
1044           *p++ = 0;
1045           while (*p == ' ')
1046             p++;
1047           prompt = p;
1048           p = strchr (prompt, ' ');
1049           if (p)
1050             {
1051               *p++ = 0;
1052               while (*p == ' ')
1053                 p++;
1054               desc = p;
1055               p = strchr (desc, ' ');
1056               if (p)
1057                 *p = 0; /* Ignore trailing garbage. */
1058             }
1059         }
1060     }
1061   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1062     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1063   if (!desc)
1064     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1065
1066   if (!strcmp (cacheid, "X"))
1067     cacheid = NULL;
1068   if (!strcmp (errtext, "X"))
1069     errtext = NULL;
1070   if (!strcmp (prompt, "X"))
1071     prompt = NULL;
1072   if (!strcmp (desc, "X"))
1073     desc = NULL;
1074
1075   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker)
1076                : NULL;
1077   if (pw)
1078     {
1079       rc = send_back_passphrase (ctx, opt_data, pw);
1080       agent_unlock_cache_entry (&cache_marker);
1081     }
1082   else if (opt_no_ask)
1083     rc = gpg_error (GPG_ERR_NO_DATA);
1084   else
1085     {
1086       /* Note, that we only need to replace the + characters and
1087          should leave the other escaping in place because the escaped
1088          string is send verbatim to the pinentry which does the
1089          unescaping (but not the + replacing) */
1090       if (errtext)
1091         plus_to_blank (errtext);
1092       if (prompt)
1093         plus_to_blank (prompt);
1094       if (desc)
1095         plus_to_blank (desc);
1096
1097       response = NULL;
1098       do
1099         {
1100           xfree (response);
1101           rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext);
1102         }
1103       while (!rc
1104              && opt_check
1105              && check_passphrase_constraints (ctrl, response, 0));
1106
1107       if (!rc)
1108         {
1109           if (cacheid)
1110             agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1111           rc = send_back_passphrase (ctx, opt_data, response);
1112           xfree (response);
1113         }
1114     }
1115
1116   if (rc)
1117     log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc));
1118   return rc;
1119 }
1120
1121
1122 /* CLEAR_PASSPHRASE <cache_id>
1123
1124    may be used to invalidate the cache entry for a passphrase.  The
1125    function returns with OK even when there is no cached passphrase.
1126 */
1127
1128 static int
1129 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1130 {
1131   char *cacheid = NULL;
1132   char *p;
1133
1134   /* parse the stuff */
1135   for (p=line; *p == ' '; p++)
1136     ;
1137   cacheid = p;
1138   p = strchr (cacheid, ' ');
1139   if (p)
1140     *p = 0; /* ignore garbage */
1141   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1142     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1143
1144   agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0);
1145   return 0;
1146 }
1147
1148
1149 /* GET_CONFIRMATION <description>
1150
1151    This command may be used to ask for a simple confirmation.
1152    DESCRIPTION is displayed along with a Okay and Cancel button.  This
1153    command uses a syntax which helps clients to use the agent with
1154    minimum effort.  The agent either returns with an error or with a
1155    OK.  Note, that the length of DESCRIPTION is implicitly limited by
1156    the maximum length of a command. DESCRIPTION should not contain
1157    any spaces, those must be encoded either percent escaped or simply
1158    as '+'.
1159 */
1160
1161 static int
1162 cmd_get_confirmation (assuan_context_t ctx, char *line)
1163 {
1164   ctrl_t ctrl = assuan_get_pointer (ctx);
1165   int rc;
1166   char *desc = NULL;
1167   char *p;
1168
1169   /* parse the stuff */
1170   for (p=line; *p == ' '; p++)
1171     ;
1172   desc = p;
1173   p = strchr (desc, ' ');
1174   if (p)
1175     *p = 0; /* We ignore any garbage -may be later used for other args. */
1176
1177   if (!desc || !*desc)
1178     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1179
1180   if (!strcmp (desc, "X"))
1181     desc = NULL;
1182
1183   /* Note, that we only need to replace the + characters and should
1184      leave the other escaping in place because the escaped string is
1185      send verbatim to the pinentry which does the unescaping (but not
1186      the + replacing) */
1187   if (desc)
1188     plus_to_blank (desc);
1189
1190   rc = agent_get_confirmation (ctrl, desc, NULL, NULL);
1191   if (rc)
1192     log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
1193   return rc;
1194 }
1195
1196
1197 \f
1198 /* LEARN [--send]
1199
1200    Learn something about the currently inserted smartcard.  With
1201    --send the new certificates are send back.  */
1202 static int
1203 cmd_learn (assuan_context_t ctx, char *line)
1204 {
1205   ctrl_t ctrl = assuan_get_pointer (ctx);
1206   int rc;
1207
1208   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1209   if (rc)
1210     log_error ("command learn failed: %s\n", gpg_strerror (rc));
1211   return rc;
1212 }
1213
1214
1215 \f
1216 /* PASSWD <hexstring_with_keygrip>
1217   
1218    Change the passphrase/PIN for the key identified by keygrip in LINE. */
1219 static int
1220 cmd_passwd (assuan_context_t ctx, char *line)
1221 {
1222   ctrl_t ctrl = assuan_get_pointer (ctx);
1223   int rc;
1224   unsigned char grip[20];
1225   gcry_sexp_t s_skey = NULL;
1226   unsigned char *shadow_info = NULL;
1227
1228   rc = parse_keygrip (ctx, line, grip);
1229   if (rc)
1230     goto leave;
1231
1232   ctrl->in_passwd++;
1233   rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
1234                             grip, &shadow_info, CACHE_MODE_IGNORE, &s_skey);
1235   if (rc)
1236     ;
1237   else if (!s_skey)
1238     {
1239       log_error ("changing a smartcard PIN is not yet supported\n");
1240       rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1241     }
1242   else
1243     rc = agent_protect_and_store (ctrl, s_skey);
1244   ctrl->in_passwd--;
1245
1246   xfree (ctrl->server_local->keydesc);
1247   ctrl->server_local->keydesc = NULL;
1248
1249  leave:
1250   gcry_sexp_release (s_skey);
1251   xfree (shadow_info);
1252   if (rc)
1253     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1254   return rc;
1255 }
1256
1257 /* PRESET_PASSPHRASE <string_or_keygrip> <timeout> <hexstring>
1258   
1259    Set the cached passphrase/PIN for the key identified by the keygrip
1260    to passwd for the given time, where -1 means infinite and 0 means
1261    the default (currently only a timeout of -1 is allowed, which means
1262    to never expire it).  If passwd is not provided, ask for it via the
1263    pinentry module.  */
1264 static int
1265 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1266 {
1267   int rc;
1268   char *grip_clear = NULL;
1269   char *passphrase = NULL;
1270   int ttl;
1271   size_t len;
1272
1273   if (!opt.allow_preset_passphrase)
1274     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1275
1276   grip_clear = line;
1277   while (*line && (*line != ' ' && *line != '\t'))
1278     line++;
1279   if (!*line)
1280     return gpg_error (GPG_ERR_MISSING_VALUE);
1281   *line = '\0';
1282   line++;
1283   while (*line && (*line == ' ' || *line == '\t'))
1284     line++;
1285   
1286   /* Currently, only infinite timeouts are allowed.  */
1287   ttl = -1;
1288   if (line[0] != '-' || line[1] != '1')
1289     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1290   line++;
1291   line++;
1292   while (!(*line != ' ' && *line != '\t'))
1293     line++;
1294
1295   /* Syntax check the hexstring.  */
1296   rc = parse_hexstring (ctx, line, &len);
1297   if (rc)
1298     return rc;
1299   line[len] = '\0';
1300
1301   /* If there is a passphrase, use it.  Currently, a passphrase is
1302      required.  */
1303   if (*line)
1304     {
1305       /* Do in-place conversion.  */
1306       passphrase = line;
1307       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1308         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1309     }
1310   else
1311     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1312
1313   if (!rc)
1314     rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1315
1316   if (rc)
1317     log_error ("command preset_passphrase failed: %s\n", gpg_strerror (rc));
1318
1319   return rc;
1320 }
1321
1322 \f
1323 /* SCD <commands to pass to the scdaemon>
1324   
1325    This is a general quote command to redirect everything to the
1326    SCDAEMON. */
1327 static int
1328 cmd_scd (assuan_context_t ctx, char *line)
1329 {
1330   ctrl_t ctrl = assuan_get_pointer (ctx);
1331   int rc;
1332
1333   rc = divert_generic_cmd (ctrl, line, ctx);
1334
1335   return rc;
1336 }
1337
1338
1339 \f
1340 /* GETVAL <key>
1341
1342    Return the value for KEY from the special environment as created by
1343    PUTVAL.
1344  */
1345 static int
1346 cmd_getval (assuan_context_t ctx, char *line)
1347 {
1348   int rc = 0;
1349   char *key = NULL;
1350   char *p;
1351   struct putval_item_s *vl;
1352
1353   for (p=line; *p == ' '; p++)
1354     ;
1355   key = p;
1356   p = strchr (key, ' ');
1357   if (p)
1358     {
1359       *p++ = 0; 
1360       for (; *p == ' '; p++)
1361         ;
1362       if (*p)
1363         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
1364     }
1365   if (!key || !*key)
1366     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
1367
1368
1369   for (vl=putval_list; vl; vl = vl->next)
1370     if ( !strcmp (vl->d, key) )
1371       break;
1372
1373   if (vl) /* Got an entry. */
1374     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
1375   else
1376     return gpg_error (GPG_ERR_NO_DATA);
1377
1378   if (rc)
1379     log_error ("command getval failed: %s\n", gpg_strerror (rc));
1380   return rc;
1381 }
1382
1383
1384 /* PUTVAL <key> [<percent_escaped_value>]
1385
1386    The gpg-agent maintains a kind of environment which may be used to
1387    store key/value pairs in it, so that they can be retrieved later.
1388    This may be used by helper daemons to daemonize themself on
1389    invocation and register them with gpg-agent.  Callers of the
1390    daemon's service may now first try connect to get the information
1391    for that service from gpg-agent through the GETVAL command and then
1392    try to connect to that daemon.  Only if that fails they may start
1393    an own instance of the service daemon. 
1394
1395    KEY is an an arbitrary symbol with the same syntax rules as keys
1396    for shell environment variables.  PERCENT_ESCAPED_VALUE is the
1397    corresponsing value; they should be similar to the values of
1398    envronment variables but gpg-agent does not enforce any
1399    restrictions.  If that value is not given any value under that KEY
1400    is removed from this special environment.
1401 */
1402 static int
1403 cmd_putval (assuan_context_t ctx, char *line)
1404 {
1405   int rc = 0;
1406   char *key = NULL;
1407   char *value = NULL;
1408   size_t valuelen = 0;
1409   char *p;
1410   struct putval_item_s *vl, *vlprev;
1411
1412   for (p=line; *p == ' '; p++)
1413     ;
1414   key = p;
1415   p = strchr (key, ' ');
1416   if (p)
1417     {
1418       *p++ = 0; 
1419       for (; *p == ' '; p++)
1420         ;
1421       if (*p)
1422         {
1423           value = p;
1424           p = strchr (value, ' ');
1425           if (p)
1426             *p = 0;
1427           valuelen = percent_plus_unescape (value);
1428         }
1429     }
1430   if (!key || !*key)
1431     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
1432
1433
1434   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
1435     if ( !strcmp (vl->d, key) )
1436       break;
1437
1438   if (vl) /* Delete old entry. */
1439     {
1440       if (vlprev)
1441         vlprev->next = vl->next;
1442       else
1443         putval_list = vl->next;
1444       xfree (vl);
1445     }
1446
1447   if (valuelen) /* Add entry. */  
1448     {
1449       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
1450       if (!vl)
1451         rc = gpg_error_from_syserror ();
1452       else
1453         {
1454           vl->len = valuelen;
1455           vl->off = strlen (key) + 1;
1456           strcpy (vl->d, key);
1457           memcpy (vl->d + vl->off, value, valuelen);
1458           vl->next = putval_list;
1459           putval_list = vl;
1460         }
1461     }
1462
1463   if (rc)
1464     log_error ("command putval failed: %s\n", gpg_strerror (rc));
1465   return rc;
1466 }
1467
1468
1469
1470 \f
1471 /* UPDATESTARTUPTTY 
1472   
1473   Set startup TTY and X DISPLAY variables to the values of this
1474   session.  This command is useful to pull future pinentries to
1475   another screen.  It is only required because there is no way in the
1476   ssh-agent protocol to convey this information.  */
1477 static int
1478 cmd_updatestartuptty (assuan_context_t ctx, char *line)
1479 {
1480   ctrl_t ctrl = assuan_get_pointer (ctx);
1481
1482   (void)line;
1483
1484   xfree (opt.startup_display); opt.startup_display = NULL;
1485   xfree (opt.startup_ttyname); opt.startup_ttyname = NULL;
1486   xfree (opt.startup_ttytype); opt.startup_ttytype = NULL;
1487   xfree (opt.startup_lc_ctype); opt.startup_lc_ctype = NULL;
1488   xfree (opt.startup_lc_messages); opt.startup_lc_messages = NULL;
1489   xfree (opt.startup_xauthority); opt.startup_xauthority = NULL;
1490
1491   if (ctrl->display)
1492     opt.startup_display = xtrystrdup (ctrl->display);
1493   if (ctrl->ttyname)
1494     opt.startup_ttyname = xtrystrdup (ctrl->ttyname);
1495   if (ctrl->ttytype)
1496     opt.startup_ttytype = xtrystrdup (ctrl->ttytype);
1497   if (ctrl->lc_ctype) 
1498     opt.startup_lc_ctype = xtrystrdup (ctrl->lc_ctype);
1499   if (ctrl->lc_messages)
1500     opt.startup_lc_messages = xtrystrdup (ctrl->lc_messages);
1501   if (ctrl->xauthority)
1502     opt.startup_xauthority = xtrystrdup (ctrl->xauthority);
1503   if (ctrl->pinentry_user_data)
1504     opt.startup_pinentry_user_data = xtrystrdup (ctrl->pinentry_user_data);
1505
1506   return 0;
1507 }
1508
1509
1510 \f
1511 #ifdef HAVE_W32_SYSTEM
1512 /* KILLAGENT
1513
1514    Under Windows we start the agent on the fly.  Thus it also make
1515    sense to allow a client to stop the agent. */
1516 static int
1517 cmd_killagent (assuan_context_t ctx, char *line)
1518 {
1519   ctrl_t ctrl = assuan_get_pointer (ctx);
1520
1521   (void)line;
1522
1523   ctrl->server_local->stopme = 1;
1524   return gpg_error (GPG_ERR_EOF);
1525 }
1526
1527 /* RELOADAGENT
1528
1529    As signals are inconvenient under Windows, we provide this command
1530    to allow reloading of the configuration.  */
1531 static int
1532 cmd_reloadagent (assuan_context_t ctx, char *line)
1533 {
1534   (void)ctx;
1535   (void)line;
1536
1537   agent_sighup_action ();
1538   return 0;
1539 }
1540 #endif /*HAVE_W32_SYSTEM*/
1541
1542
1543 \f
1544 /* GETINFO <what>
1545
1546    Multipurpose function to return a variety of information.
1547    Supported values for WHAT are:
1548
1549      version     - Return the version of the program.
1550      pid         - Return the process id of the server.
1551      socket_name - Return the name of the socket.
1552      ssh_socket_name - Return the name of the ssh socket.
1553      scd_running - Return OK if the SCdaemon is already running.
1554  */
1555 static int
1556 cmd_getinfo (assuan_context_t ctx, char *line)
1557 {
1558   int rc = 0;
1559
1560   if (!strcmp (line, "version"))
1561     {
1562       const char *s = VERSION;
1563       rc = assuan_send_data (ctx, s, strlen (s));
1564     }
1565   else if (!strcmp (line, "pid"))
1566     {
1567       char numbuf[50];
1568
1569       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1570       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1571     }
1572   else if (!strcmp (line, "socket_name"))
1573     {
1574       const char *s = get_agent_socket_name ();
1575
1576       if (s)
1577         rc = assuan_send_data (ctx, s, strlen (s));
1578       else
1579         rc = gpg_error (GPG_ERR_NO_DATA);
1580     }
1581   else if (!strcmp (line, "ssh_socket_name"))
1582     {
1583       const char *s = get_agent_ssh_socket_name ();
1584
1585       if (s)
1586         rc = assuan_send_data (ctx, s, strlen (s));
1587       else
1588         rc = gpg_error (GPG_ERR_NO_DATA);
1589     }
1590   else if (!strcmp (line, "scd_running"))
1591     {
1592       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
1593     }
1594   else
1595     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1596   return rc;
1597 }
1598
1599
1600 \f
1601 static int
1602 option_handler (assuan_context_t ctx, const char *key, const char *value)
1603 {
1604   ctrl_t ctrl = assuan_get_pointer (ctx);
1605
1606   if (!strcmp (key, "display"))
1607     {
1608       if (ctrl->display)
1609         xfree (ctrl->display);
1610       ctrl->display = xtrystrdup (value);
1611       if (!ctrl->display)
1612         return out_of_core ();
1613     }
1614   else if (!strcmp (key, "ttyname"))
1615     {
1616       if (!opt.keep_tty)
1617         {
1618           if (ctrl->ttyname)
1619             xfree (ctrl->ttyname);
1620           ctrl->ttyname = xtrystrdup (value);
1621           if (!ctrl->ttyname)
1622             return out_of_core ();
1623         }
1624     }
1625   else if (!strcmp (key, "ttytype"))
1626     {
1627       if (!opt.keep_tty)
1628         {
1629           if (ctrl->ttytype)
1630             xfree (ctrl->ttytype);
1631           ctrl->ttytype = xtrystrdup (value);
1632           if (!ctrl->ttytype)
1633             return out_of_core ();
1634         }
1635     }
1636   else if (!strcmp (key, "lc-ctype"))
1637     {
1638       if (ctrl->lc_ctype)
1639         xfree (ctrl->lc_ctype);
1640       ctrl->lc_ctype = xtrystrdup (value);
1641       if (!ctrl->lc_ctype)
1642         return out_of_core ();
1643     }
1644   else if (!strcmp (key, "lc-messages"))
1645     {
1646       if (ctrl->lc_messages)
1647         xfree (ctrl->lc_messages);
1648       ctrl->lc_messages = xtrystrdup (value);
1649       if (!ctrl->lc_messages)
1650         return out_of_core ();
1651     }
1652   else if (!strcmp (key, "xauthority"))
1653     {
1654       if (ctrl->xauthority)
1655         xfree (ctrl->xauthority);
1656       ctrl->xauthority = xtrystrdup (value);
1657       if (!ctrl->xauthority)
1658         return out_of_core ();
1659     }
1660   else if (!strcmp (key, "pinentry-user-data"))
1661     {
1662       if (ctrl->pinentry_user_data)
1663         xfree (ctrl->pinentry_user_data);
1664       ctrl->pinentry_user_data = xtrystrdup (value);
1665       if (!ctrl->pinentry_user_data)
1666         return out_of_core ();
1667     }
1668   else if (!strcmp (key, "use-cache-for-signing"))
1669     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
1670   else if (!strcmp (key, "allow-pinentry-notify"))
1671     ctrl->server_local->allow_pinentry_notify = 1;
1672   else
1673     return gpg_error (GPG_ERR_UNKNOWN_OPTION);
1674
1675   return 0;
1676 }
1677
1678
1679
1680 \f
1681 /* Called by libassuan after all commands. ERR is the error from the
1682    last assuan operation and not the one returned from the command. */
1683 static void
1684 post_cmd_notify (assuan_context_t ctx, int err)
1685 {
1686   ctrl_t ctrl = assuan_get_pointer (ctx);
1687   
1688   (void)err;
1689
1690   /* Switch off any I/O monitor controlled logging pausing. */
1691   ctrl->server_local->pause_io_logging = 0;
1692 }
1693
1694
1695 /* This function is called by libassuan for all I/O.  We use it here
1696    to disable logging for the GETEVENTCOUNTER commands.  This is so
1697    that the debug output won't get cluttered by this primitive
1698    command.  */
1699 static unsigned int
1700 io_monitor (assuan_context_t ctx, int direction,
1701             const char *line, size_t linelen)
1702 {
1703   ctrl_t ctrl = assuan_get_pointer (ctx);
1704   
1705   /* Note that we only check for the uppercase name.  This allows to
1706      see the logging for debugging if using a non-upercase command
1707      name. */
1708   if (ctx && !direction 
1709       && linelen >= 15
1710       && !strncmp (line, "GETEVENTCOUNTER", 15)
1711       && (linelen == 15 || spacep (line+15)))
1712     {
1713       ctrl->server_local->pause_io_logging = 1;
1714     }
1715
1716   return ctrl->server_local->pause_io_logging? 1:0;
1717 }
1718
1719
1720 /* Tell the assuan library about our commands */
1721 static int
1722 register_commands (assuan_context_t ctx)
1723 {
1724   static struct {
1725     const char *name;
1726     int (*handler)(assuan_context_t, char *line);
1727   } table[] = {
1728     { "GETEVENTCOUNTER",cmd_geteventcounter },
1729     { "ISTRUSTED",      cmd_istrusted },
1730     { "HAVEKEY",        cmd_havekey },
1731     { "KEYINFO",        cmd_keyinfo },
1732     { "SIGKEY",         cmd_sigkey },
1733     { "SETKEY",         cmd_sigkey },
1734     { "SETKEYDESC",     cmd_setkeydesc },
1735     { "SETHASH",        cmd_sethash },
1736     { "PKSIGN",         cmd_pksign },
1737     { "PKDECRYPT",      cmd_pkdecrypt },
1738     { "GENKEY",         cmd_genkey },
1739     { "READKEY",        cmd_readkey },
1740     { "GET_PASSPHRASE", cmd_get_passphrase },
1741     { "PRESET_PASSPHRASE", cmd_preset_passphrase },
1742     { "CLEAR_PASSPHRASE", cmd_clear_passphrase },
1743     { "GET_CONFIRMATION", cmd_get_confirmation },
1744     { "LISTTRUSTED",    cmd_listtrusted },
1745     { "MARKTRUSTED",    cmd_marktrusted },
1746     { "LEARN",          cmd_learn },
1747     { "PASSWD",         cmd_passwd },
1748     { "INPUT",          NULL }, 
1749     { "OUTPUT",         NULL }, 
1750     { "SCD",            cmd_scd },
1751     { "GETVAL",         cmd_getval },
1752     { "PUTVAL",         cmd_putval },
1753     { "UPDATESTARTUPTTY",  cmd_updatestartuptty },
1754 #ifdef HAVE_W32_SYSTEM
1755     { "KILLAGENT",      cmd_killagent },
1756     { "RELOADAGENT",    cmd_reloadagent },
1757 #endif
1758     { "GETINFO",        cmd_getinfo },
1759     { NULL }
1760   };
1761   int i, rc;
1762
1763   for (i=0; table[i].name; i++)
1764     {
1765       rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1766       if (rc)
1767         return rc;
1768     } 
1769 #ifdef HAVE_ASSUAN_SET_IO_MONITOR
1770   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
1771 #endif
1772   assuan_register_reset_notify (ctx, reset_notify);
1773   assuan_register_option_handler (ctx, option_handler);
1774   return 0;
1775 }
1776
1777
1778 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
1779    simple piper server, otherwise it is a regular server.  CTRL is the
1780    control structure for this connection; it has only the basic
1781    intialization. */
1782 void
1783 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
1784 {
1785   int rc;
1786   assuan_context_t ctx;
1787
1788   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
1789     {
1790       int filedes[2];
1791
1792       filedes[0] = 0;
1793       filedes[1] = 1;
1794       rc = assuan_init_pipe_server (&ctx, filedes);
1795     }
1796   else if (listen_fd != GNUPG_INVALID_FD)
1797     {
1798       rc = assuan_init_socket_server_ext (&ctx, listen_fd, 0);
1799     }
1800   else 
1801     {
1802       rc = assuan_init_socket_server_ext (&ctx, fd, 2);
1803     }
1804   if (rc)
1805     {
1806       log_error ("failed to initialize the server: %s\n",
1807                  gpg_strerror(rc));
1808       agent_exit (2);
1809     }
1810   rc = register_commands (ctx);
1811   if (rc)
1812     {
1813       log_error ("failed to register commands with Assuan: %s\n",
1814                  gpg_strerror(rc));
1815       agent_exit (2);
1816     }
1817
1818   assuan_set_pointer (ctx, ctrl);
1819   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1820   ctrl->server_local->assuan_ctx = ctx;
1821   ctrl->server_local->message_fd = -1;
1822   ctrl->server_local->use_cache_for_signing = 1;
1823   ctrl->digest.raw_value = 0;
1824
1825   if (DBG_ASSUAN)
1826     assuan_set_log_stream (ctx, log_get_stream ());
1827
1828 #ifdef HAVE_ASSUAN_SET_IO_MONITOR
1829   assuan_set_io_monitor (ctx, io_monitor);
1830 #endif
1831
1832   for (;;)
1833     {
1834       rc = assuan_accept (ctx);
1835       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
1836         {
1837           break;
1838         }
1839       else if (rc)
1840         {
1841           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1842           break;
1843         }
1844       
1845       rc = assuan_process (ctx);
1846       if (rc)
1847         {
1848           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1849           continue;
1850         }
1851     }
1852
1853   /* Reset the SCD if needed. */
1854   agent_reset_scd (ctrl);
1855
1856   /* Reset the pinentry (in case of popup messages). */
1857   agent_reset_query (ctrl);
1858
1859   /* Cleanup.  */
1860   assuan_deinit_server (ctx);
1861 #ifdef HAVE_W32_SYSTEM
1862   if (ctrl->server_local->stopme)
1863     agent_exit (0);
1864 #endif
1865   xfree (ctrl->server_local);
1866   ctrl->server_local = NULL;
1867 }
1868