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