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