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