Reworked passing of envars to Pinentry.
[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]] 
990                   [--qualitybar] <cache_id>
991                   [<error_message> <prompt> <description>]
992
993    This function is usually used to ask for a passphrase to be used
994    for conventional encryption, but may also be used by programs which
995    need specal handling of passphrases.  This command uses a syntax
996    which helps clients to use the agent with minimum effort.  The
997    agent either returns with an error or with a OK followed by the hex
998    encoded passphrase.  Note that the length of the strings is
999    implicitly limited by the maximum length of a command.
1000
1001    If the option "--data" is used the passphrase is returned by usual
1002    data lines and not on the okay line.
1003
1004    If the option "--check" is used the passphrase constraints checks as
1005    implemented by gpg-agent are applied.  A check is not done if the
1006    passphrase has been found in the cache.
1007
1008    If the option "--no-ask" is used and the passphrase is not in the
1009    cache the user will not be asked to enter a passphrase but the error
1010    code GPG_ERR_NO_DATA is returned.  
1011
1012    If the option "--qualitybar" is used a visual indication of the
1013    entered passphrase quality is shown.  (Unless no minimum passphrase
1014    length has been configured.)
1015 */
1016
1017 static int
1018 cmd_get_passphrase (assuan_context_t ctx, char *line)
1019 {
1020   ctrl_t ctrl = assuan_get_pointer (ctx);
1021   int rc;
1022   const char *pw;
1023   char *response;
1024   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1025   const char *desc2 = _("Please re-enter this passphrase");
1026   char *p;
1027   void *cache_marker;
1028   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1029   int opt_repeat = 0;
1030   char *repeat_errtext = NULL;
1031
1032   opt_data = has_option (line, "--data");
1033   opt_check = has_option (line, "--check");
1034   opt_no_ask = has_option (line, "--no-ask");
1035   if (has_option_name (line, "--repeat"))
1036     {
1037       p = option_value (line, "--repeat");
1038       if (p)
1039         opt_repeat = atoi (p);
1040       else
1041         opt_repeat = 1;
1042     }
1043   opt_qualbar = has_option (line, "--qualitybar");
1044   line = skip_options (line);
1045
1046   cacheid = line;
1047   p = strchr (cacheid, ' ');
1048   if (p)
1049     {
1050       *p++ = 0;
1051       while (*p == ' ')
1052         p++;
1053       errtext = p;
1054       p = strchr (errtext, ' ');
1055       if (p)
1056         {
1057           *p++ = 0;
1058           while (*p == ' ')
1059             p++;
1060           prompt = p;
1061           p = strchr (prompt, ' ');
1062           if (p)
1063             {
1064               *p++ = 0;
1065               while (*p == ' ')
1066                 p++;
1067               desc = p;
1068               p = strchr (desc, ' ');
1069               if (p)
1070                 *p = 0; /* Ignore trailing garbage. */
1071             }
1072         }
1073     }
1074   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1075     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1076   if (!desc)
1077     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1078
1079   if (!strcmp (cacheid, "X"))
1080     cacheid = NULL;
1081   if (!strcmp (errtext, "X"))
1082     errtext = NULL;
1083   if (!strcmp (prompt, "X"))
1084     prompt = NULL;
1085   if (!strcmp (desc, "X"))
1086     desc = NULL;
1087
1088   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL, &cache_marker)
1089                : NULL;
1090   if (pw)
1091     {
1092       rc = send_back_passphrase (ctx, opt_data, pw);
1093       agent_unlock_cache_entry (&cache_marker);
1094     }
1095   else if (opt_no_ask)
1096     rc = gpg_error (GPG_ERR_NO_DATA);
1097   else
1098     {
1099       /* Note, that we only need to replace the + characters and
1100          should leave the other escaping in place because the escaped
1101          string is send verbatim to the pinentry which does the
1102          unescaping (but not the + replacing) */
1103       if (errtext)
1104         plus_to_blank (errtext);
1105       if (prompt)
1106         plus_to_blank (prompt);
1107       if (desc)
1108         plus_to_blank (desc);
1109
1110     next_try:
1111       rc = agent_get_passphrase (ctrl, &response, desc, prompt, 
1112                                  repeat_errtext? repeat_errtext:errtext, 
1113                                  opt_qualbar);
1114       xfree (repeat_errtext);
1115       repeat_errtext = NULL;
1116       if (!rc)
1117         {
1118           int i;
1119
1120           if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1121             {
1122               xfree (response);
1123               goto next_try;
1124             }
1125           for (i = 0; i < opt_repeat; i++)
1126             {
1127               char *response2;
1128
1129               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1130                                          errtext, 0);
1131               if (rc)
1132                 break;
1133               if (strcmp (response2, response))
1134                 {
1135                   xfree (response2);
1136                   xfree (response);
1137                   repeat_errtext = try_percent_escape 
1138                     (_("does not match - try again"), NULL);
1139                   if (!repeat_errtext)
1140                     {
1141                       rc = gpg_error_from_syserror ();
1142                       break;
1143                     }
1144                   goto next_try;
1145                 }
1146               xfree (response2);
1147             }
1148           if (!rc)
1149             {
1150               if (cacheid)
1151                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1152               rc = send_back_passphrase (ctx, opt_data, response);
1153             }
1154           xfree (response);
1155         }
1156     }
1157
1158   if (rc)
1159     log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc));
1160   return rc;
1161 }
1162
1163
1164 /* CLEAR_PASSPHRASE <cache_id>
1165
1166    may be used to invalidate the cache entry for a passphrase.  The
1167    function returns with OK even when there is no cached passphrase.
1168 */
1169
1170 static int
1171 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1172 {
1173   char *cacheid = NULL;
1174   char *p;
1175
1176   /* parse the stuff */
1177   for (p=line; *p == ' '; p++)
1178     ;
1179   cacheid = p;
1180   p = strchr (cacheid, ' ');
1181   if (p)
1182     *p = 0; /* ignore garbage */
1183   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1184     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1185
1186   agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0);
1187   return 0;
1188 }
1189
1190
1191 /* GET_CONFIRMATION <description>
1192
1193    This command may be used to ask for a simple confirmation.
1194    DESCRIPTION is displayed along with a Okay and Cancel button.  This
1195    command uses a syntax which helps clients to use the agent with
1196    minimum effort.  The agent either returns with an error or with a
1197    OK.  Note, that the length of DESCRIPTION is implicitly limited by
1198    the maximum length of a command. DESCRIPTION should not contain
1199    any spaces, those must be encoded either percent escaped or simply
1200    as '+'.
1201 */
1202
1203 static int
1204 cmd_get_confirmation (assuan_context_t ctx, char *line)
1205 {
1206   ctrl_t ctrl = assuan_get_pointer (ctx);
1207   int rc;
1208   char *desc = NULL;
1209   char *p;
1210
1211   /* parse the stuff */
1212   for (p=line; *p == ' '; p++)
1213     ;
1214   desc = p;
1215   p = strchr (desc, ' ');
1216   if (p)
1217     *p = 0; /* We ignore any garbage -may be later used for other args. */
1218
1219   if (!desc || !*desc)
1220     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1221
1222   if (!strcmp (desc, "X"))
1223     desc = NULL;
1224
1225   /* Note, that we only need to replace the + characters and should
1226      leave the other escaping in place because the escaped string is
1227      send verbatim to the pinentry which does the unescaping (but not
1228      the + replacing) */
1229   if (desc)
1230     plus_to_blank (desc);
1231
1232   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1233   if (rc)
1234     log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
1235   return rc;
1236 }
1237
1238
1239 \f
1240 /* LEARN [--send]
1241
1242    Learn something about the currently inserted smartcard.  With
1243    --send the new certificates are send back.  */
1244 static int
1245 cmd_learn (assuan_context_t ctx, char *line)
1246 {
1247   ctrl_t ctrl = assuan_get_pointer (ctx);
1248   int rc;
1249
1250   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1251   if (rc)
1252     log_error ("command learn failed: %s\n", gpg_strerror (rc));
1253   return rc;
1254 }
1255
1256
1257 \f
1258 /* PASSWD <hexstring_with_keygrip>
1259   
1260    Change the passphrase/PIN for the key identified by keygrip in LINE. */
1261 static int
1262 cmd_passwd (assuan_context_t ctx, char *line)
1263 {
1264   ctrl_t ctrl = assuan_get_pointer (ctx);
1265   int rc;
1266   unsigned char grip[20];
1267   gcry_sexp_t s_skey = NULL;
1268   unsigned char *shadow_info = NULL;
1269
1270   rc = parse_keygrip (ctx, line, grip);
1271   if (rc)
1272     goto leave;
1273
1274   ctrl->in_passwd++;
1275   rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
1276                             grip, &shadow_info, CACHE_MODE_IGNORE, NULL, 
1277                             &s_skey);
1278   if (rc)
1279     ;
1280   else if (!s_skey)
1281     {
1282       log_error ("changing a smartcard PIN is not yet supported\n");
1283       rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1284     }
1285   else
1286     rc = agent_protect_and_store (ctrl, s_skey);
1287   ctrl->in_passwd--;
1288
1289   xfree (ctrl->server_local->keydesc);
1290   ctrl->server_local->keydesc = NULL;
1291
1292  leave:
1293   gcry_sexp_release (s_skey);
1294   xfree (shadow_info);
1295   if (rc)
1296     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1297   return rc;
1298 }
1299
1300 /* PRESET_PASSPHRASE <string_or_keygrip> <timeout> <hexstring>
1301   
1302    Set the cached passphrase/PIN for the key identified by the keygrip
1303    to passwd for the given time, where -1 means infinite and 0 means
1304    the default (currently only a timeout of -1 is allowed, which means
1305    to never expire it).  If passwd is not provided, ask for it via the
1306    pinentry module.  */
1307 static int
1308 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1309 {
1310   int rc;
1311   char *grip_clear = NULL;
1312   char *passphrase = NULL;
1313   int ttl;
1314   size_t len;
1315
1316   if (!opt.allow_preset_passphrase)
1317     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1318
1319   grip_clear = line;
1320   while (*line && (*line != ' ' && *line != '\t'))
1321     line++;
1322   if (!*line)
1323     return gpg_error (GPG_ERR_MISSING_VALUE);
1324   *line = '\0';
1325   line++;
1326   while (*line && (*line == ' ' || *line == '\t'))
1327     line++;
1328   
1329   /* Currently, only infinite timeouts are allowed.  */
1330   ttl = -1;
1331   if (line[0] != '-' || line[1] != '1')
1332     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1333   line++;
1334   line++;
1335   while (!(*line != ' ' && *line != '\t'))
1336     line++;
1337
1338   /* Syntax check the hexstring.  */
1339   rc = parse_hexstring (ctx, line, &len);
1340   if (rc)
1341     return rc;
1342   line[len] = '\0';
1343
1344   /* If there is a passphrase, use it.  Currently, a passphrase is
1345      required.  */
1346   if (*line)
1347     {
1348       /* Do in-place conversion.  */
1349       passphrase = line;
1350       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1351         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1352     }
1353   else
1354     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1355
1356   if (!rc)
1357     rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1358
1359   if (rc)
1360     log_error ("command preset_passphrase failed: %s\n", gpg_strerror (rc));
1361
1362   return rc;
1363 }
1364
1365 \f
1366 /* SCD <commands to pass to the scdaemon>
1367   
1368    This is a general quote command to redirect everything to the
1369    SCDAEMON. */
1370 static int
1371 cmd_scd (assuan_context_t ctx, char *line)
1372 {
1373   ctrl_t ctrl = assuan_get_pointer (ctx);
1374   int rc;
1375
1376   rc = divert_generic_cmd (ctrl, line, ctx);
1377
1378   return rc;
1379 }
1380
1381
1382 \f
1383 /* GETVAL <key>
1384
1385    Return the value for KEY from the special environment as created by
1386    PUTVAL.
1387  */
1388 static int
1389 cmd_getval (assuan_context_t ctx, char *line)
1390 {
1391   int rc = 0;
1392   char *key = NULL;
1393   char *p;
1394   struct putval_item_s *vl;
1395
1396   for (p=line; *p == ' '; p++)
1397     ;
1398   key = p;
1399   p = strchr (key, ' ');
1400   if (p)
1401     {
1402       *p++ = 0; 
1403       for (; *p == ' '; p++)
1404         ;
1405       if (*p)
1406         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
1407     }
1408   if (!key || !*key)
1409     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
1410
1411
1412   for (vl=putval_list; vl; vl = vl->next)
1413     if ( !strcmp (vl->d, key) )
1414       break;
1415
1416   if (vl) /* Got an entry. */
1417     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
1418   else
1419     return gpg_error (GPG_ERR_NO_DATA);
1420
1421   if (rc)
1422     log_error ("command getval failed: %s\n", gpg_strerror (rc));
1423   return rc;
1424 }
1425
1426
1427 /* PUTVAL <key> [<percent_escaped_value>]
1428
1429    The gpg-agent maintains a kind of environment which may be used to
1430    store key/value pairs in it, so that they can be retrieved later.
1431    This may be used by helper daemons to daemonize themself on
1432    invocation and register them with gpg-agent.  Callers of the
1433    daemon's service may now first try connect to get the information
1434    for that service from gpg-agent through the GETVAL command and then
1435    try to connect to that daemon.  Only if that fails they may start
1436    an own instance of the service daemon. 
1437
1438    KEY is an an arbitrary symbol with the same syntax rules as keys
1439    for shell environment variables.  PERCENT_ESCAPED_VALUE is the
1440    corresponsing value; they should be similar to the values of
1441    envronment variables but gpg-agent does not enforce any
1442    restrictions.  If that value is not given any value under that KEY
1443    is removed from this special environment.
1444 */
1445 static int
1446 cmd_putval (assuan_context_t ctx, char *line)
1447 {
1448   int rc = 0;
1449   char *key = NULL;
1450   char *value = NULL;
1451   size_t valuelen = 0;
1452   char *p;
1453   struct putval_item_s *vl, *vlprev;
1454
1455   for (p=line; *p == ' '; p++)
1456     ;
1457   key = p;
1458   p = strchr (key, ' ');
1459   if (p)
1460     {
1461       *p++ = 0; 
1462       for (; *p == ' '; p++)
1463         ;
1464       if (*p)
1465         {
1466           value = p;
1467           p = strchr (value, ' ');
1468           if (p)
1469             *p = 0;
1470           valuelen = percent_plus_unescape_inplace (value, 0);
1471         }
1472     }
1473   if (!key || !*key)
1474     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
1475
1476
1477   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
1478     if ( !strcmp (vl->d, key) )
1479       break;
1480
1481   if (vl) /* Delete old entry. */
1482     {
1483       if (vlprev)
1484         vlprev->next = vl->next;
1485       else
1486         putval_list = vl->next;
1487       xfree (vl);
1488     }
1489
1490   if (valuelen) /* Add entry. */  
1491     {
1492       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
1493       if (!vl)
1494         rc = gpg_error_from_syserror ();
1495       else
1496         {
1497           vl->len = valuelen;
1498           vl->off = strlen (key) + 1;
1499           strcpy (vl->d, key);
1500           memcpy (vl->d + vl->off, value, valuelen);
1501           vl->next = putval_list;
1502           putval_list = vl;
1503         }
1504     }
1505
1506   if (rc)
1507     log_error ("command putval failed: %s\n", gpg_strerror (rc));
1508   return rc;
1509 }
1510
1511
1512
1513 \f
1514 /* UPDATESTARTUPTTY 
1515   
1516   Set startup TTY and X DISPLAY variables to the values of this
1517   session.  This command is useful to pull future pinentries to
1518   another screen.  It is only required because there is no way in the
1519   ssh-agent protocol to convey this information.  */
1520 static int
1521 cmd_updatestartuptty (assuan_context_t ctx, char *line)
1522 {
1523   static const char *names[] = 
1524     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
1525   ctrl_t ctrl = assuan_get_pointer (ctx);
1526   gpg_error_t err = 0;
1527   session_env_t se;
1528   int idx;
1529   char *lc_ctype = NULL;
1530   char *lc_messages = NULL;
1531   
1532   (void)line;
1533
1534   se = session_env_new ();
1535   if (!se)
1536     err = gpg_error_from_syserror ();
1537
1538   for (idx=0; !err && names[idx]; idx++)
1539     {
1540       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
1541       if (value)
1542         err = session_env_setenv (se, names[idx], value);
1543     }
1544
1545   if (!err && ctrl->lc_ctype) 
1546     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
1547       err = gpg_error_from_syserror ();
1548
1549   if (!err && ctrl->lc_messages)
1550     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
1551       err = gpg_error_from_syserror ();
1552    
1553   if (err)
1554     {
1555       session_env_release (se);
1556       xfree (lc_ctype);
1557       xfree (lc_messages);
1558     }
1559   else
1560     {
1561       session_env_release (opt.startup_env);
1562       opt.startup_env = se;
1563       xfree (opt.startup_lc_ctype);
1564       opt.startup_lc_ctype = lc_ctype;
1565       xfree (opt.startup_lc_messages);
1566       opt.startup_lc_messages = lc_messages;
1567     }
1568
1569   return err;
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   gpg_error_t err = 0;
1704
1705   if (!strcmp (key, "putenv"))
1706     {
1707       /* Change the session's environment to be used for the
1708          Pinentry.  Valid values are:
1709           <NAME>            Delete envvar NAME
1710           <KEY>=            Set envvar NAME to the empty string
1711           <KEY>=<VALUE>     Set envvar NAME to VALUE
1712       */
1713       err = session_env_putenv (ctrl->session_env, value);
1714     }
1715   else if (!strcmp (key, "display"))
1716     {
1717       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
1718     }
1719   else if (!strcmp (key, "ttyname"))
1720     {
1721       if (!opt.keep_tty)
1722         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
1723     }
1724   else if (!strcmp (key, "ttytype"))
1725     {
1726       if (!opt.keep_tty)
1727         err = session_env_setenv (ctrl->session_env, "TERM", value);
1728     }
1729   else if (!strcmp (key, "lc-ctype"))
1730     {
1731       if (ctrl->lc_ctype)
1732         xfree (ctrl->lc_ctype);
1733       ctrl->lc_ctype = xtrystrdup (value);
1734       if (!ctrl->lc_ctype)
1735         return out_of_core ();
1736     }
1737   else if (!strcmp (key, "lc-messages"))
1738     {
1739       if (ctrl->lc_messages)
1740         xfree (ctrl->lc_messages);
1741       ctrl->lc_messages = xtrystrdup (value);
1742       if (!ctrl->lc_messages)
1743         return out_of_core ();
1744     }
1745   else if (!strcmp (key, "xauthority"))
1746     {
1747       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
1748     }
1749   else if (!strcmp (key, "pinentry-user-data"))
1750     {
1751       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
1752     }
1753   else if (!strcmp (key, "use-cache-for-signing"))
1754     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
1755   else if (!strcmp (key, "allow-pinentry-notify"))
1756     ctrl->server_local->allow_pinentry_notify = 1;
1757   else
1758     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
1759
1760   return err;
1761 }
1762
1763
1764
1765 \f
1766 /* Called by libassuan after all commands. ERR is the error from the
1767    last assuan operation and not the one returned from the command. */
1768 static void
1769 post_cmd_notify (assuan_context_t ctx, int err)
1770 {
1771   ctrl_t ctrl = assuan_get_pointer (ctx);
1772   
1773   (void)err;
1774
1775   /* Switch off any I/O monitor controlled logging pausing. */
1776   ctrl->server_local->pause_io_logging = 0;
1777 }
1778
1779
1780 /* This function is called by libassuan for all I/O.  We use it here
1781    to disable logging for the GETEVENTCOUNTER commands.  This is so
1782    that the debug output won't get cluttered by this primitive
1783    command.  */
1784 static unsigned int
1785 io_monitor (assuan_context_t ctx, int direction,
1786             const char *line, size_t linelen)
1787 {
1788   ctrl_t ctrl = assuan_get_pointer (ctx);
1789   
1790   /* Note that we only check for the uppercase name.  This allows to
1791      see the logging for debugging if using a non-upercase command
1792      name. */
1793   if (ctx && !direction 
1794       && linelen >= 15
1795       && !strncmp (line, "GETEVENTCOUNTER", 15)
1796       && (linelen == 15 || spacep (line+15)))
1797     {
1798       ctrl->server_local->pause_io_logging = 1;
1799     }
1800
1801   return ctrl->server_local->pause_io_logging? 1:0;
1802 }
1803
1804
1805 /* Return true if the commznd CMD implements the option OPT.  */
1806 static int
1807 command_has_option (const char *cmd, const char *cmdopt)
1808 {
1809   if (!strcmp (cmd, "GET_PASSPHRASE"))
1810     {
1811       if (!strcmp (cmdopt, "repeat"))
1812           return 1;
1813     }
1814       
1815   return 0;
1816 }
1817
1818
1819 /* Tell the assuan library about our commands */
1820 static int
1821 register_commands (assuan_context_t ctx)
1822 {
1823   static struct {
1824     const char *name;
1825     int (*handler)(assuan_context_t, char *line);
1826   } table[] = {
1827     { "GETEVENTCOUNTER",cmd_geteventcounter },
1828     { "ISTRUSTED",      cmd_istrusted },
1829     { "HAVEKEY",        cmd_havekey },
1830     { "KEYINFO",        cmd_keyinfo },
1831     { "SIGKEY",         cmd_sigkey },
1832     { "SETKEY",         cmd_sigkey },
1833     { "SETKEYDESC",     cmd_setkeydesc },
1834     { "SETHASH",        cmd_sethash },
1835     { "PKSIGN",         cmd_pksign },
1836     { "PKDECRYPT",      cmd_pkdecrypt },
1837     { "GENKEY",         cmd_genkey },
1838     { "READKEY",        cmd_readkey },
1839     { "GET_PASSPHRASE", cmd_get_passphrase },
1840     { "PRESET_PASSPHRASE", cmd_preset_passphrase },
1841     { "CLEAR_PASSPHRASE", cmd_clear_passphrase },
1842     { "GET_CONFIRMATION", cmd_get_confirmation },
1843     { "LISTTRUSTED",    cmd_listtrusted },
1844     { "MARKTRUSTED",    cmd_marktrusted },
1845     { "LEARN",          cmd_learn },
1846     { "PASSWD",         cmd_passwd },
1847     { "INPUT",          NULL }, 
1848     { "OUTPUT",         NULL }, 
1849     { "SCD",            cmd_scd },
1850     { "GETVAL",         cmd_getval },
1851     { "PUTVAL",         cmd_putval },
1852     { "UPDATESTARTUPTTY",  cmd_updatestartuptty },
1853 #ifdef HAVE_W32_SYSTEM
1854     { "KILLAGENT",      cmd_killagent },
1855     { "RELOADAGENT",    cmd_reloadagent },
1856 #endif
1857     { "GETINFO",        cmd_getinfo },
1858     { NULL }
1859   };
1860   int i, rc;
1861
1862   for (i=0; table[i].name; i++)
1863     {
1864       rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1865       if (rc)
1866         return rc;
1867     } 
1868 #ifdef HAVE_ASSUAN_SET_IO_MONITOR
1869   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
1870 #endif
1871   assuan_register_reset_notify (ctx, reset_notify);
1872   assuan_register_option_handler (ctx, option_handler);
1873   return 0;
1874 }
1875
1876
1877 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
1878    simple piper server, otherwise it is a regular server.  CTRL is the
1879    control structure for this connection; it has only the basic
1880    intialization. */
1881 void
1882 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
1883 {
1884   int rc;
1885   assuan_context_t ctx;
1886
1887   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
1888     {
1889       int filedes[2];
1890
1891       filedes[0] = 0;
1892       filedes[1] = 1;
1893       rc = assuan_init_pipe_server (&ctx, filedes);
1894     }
1895   else if (listen_fd != GNUPG_INVALID_FD)
1896     {
1897       rc = assuan_init_socket_server_ext (&ctx, listen_fd, 0);
1898     }
1899   else 
1900     {
1901       rc = assuan_init_socket_server_ext (&ctx, fd, 2);
1902     }
1903   if (rc)
1904     {
1905       log_error ("failed to initialize the server: %s\n",
1906                  gpg_strerror(rc));
1907       agent_exit (2);
1908     }
1909   rc = register_commands (ctx);
1910   if (rc)
1911     {
1912       log_error ("failed to register commands with Assuan: %s\n",
1913                  gpg_strerror(rc));
1914       agent_exit (2);
1915     }
1916
1917   assuan_set_pointer (ctx, ctrl);
1918   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1919   ctrl->server_local->assuan_ctx = ctx;
1920   ctrl->server_local->message_fd = -1;
1921   ctrl->server_local->use_cache_for_signing = 1;
1922   ctrl->digest.raw_value = 0;
1923
1924   if (DBG_ASSUAN)
1925     assuan_set_log_stream (ctx, log_get_stream ());
1926
1927 #ifdef HAVE_ASSUAN_SET_IO_MONITOR
1928   assuan_set_io_monitor (ctx, io_monitor);
1929 #endif
1930
1931   for (;;)
1932     {
1933       rc = assuan_accept (ctx);
1934       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
1935         {
1936           break;
1937         }
1938       else if (rc)
1939         {
1940           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1941           break;
1942         }
1943       
1944       rc = assuan_process (ctx);
1945       if (rc)
1946         {
1947           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1948           continue;
1949         }
1950     }
1951
1952   /* Reset the SCD if needed. */
1953   agent_reset_scd (ctrl);
1954
1955   /* Reset the pinentry (in case of popup messages). */
1956   agent_reset_query (ctrl);
1957
1958   /* Cleanup.  */
1959   assuan_deinit_server (ctx);
1960 #ifdef HAVE_W32_SYSTEM
1961   if (ctrl->server_local->stopme)
1962     agent_exit (0);
1963 #endif
1964   xfree (ctrl->server_local);
1965   ctrl->server_local = NULL;
1966 }
1967