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