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