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