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