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