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