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