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