Added gpg-agent OPTION "s2k-count".
[gnupg.git] / agent / command.c
1 /* command.c - gpg-agent command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010,
3  *               2011  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 "agent.h"
38 #include <assuan.h>
39 #include "i18n.h"
40 #include "cvt-openpgp.h"
41
42
43 /* Maximum allowed size of the inquired ciphertext.  */
44 #define MAXLEN_CIPHERTEXT 4096
45 /* Maximum allowed size of the key parameters.  */
46 #define MAXLEN_KEYPARAM 1024
47 /* Maximum allowed size of key data as used in inquiries (bytes). */
48 #define MAXLEN_KEYDATA 4096
49 /* The size of the import/export KEK key (in bytes).  */
50 #define KEYWRAP_KEYSIZE (128/8)
51
52 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
53
54
55 #if MAX_DIGEST_LEN < 20
56 #error MAX_DIGEST_LEN shorter than keygrip
57 #endif
58
59 /* Data used to associate an Assuan context with local server data */
60 struct server_local_s
61 {
62   assuan_context_t assuan_ctx;
63   int message_fd;
64   int use_cache_for_signing;
65   char *keydesc;  /* Allocated description for the next key
66                      operation. */
67   int pause_io_logging; /* Used to suppress I/O logging during a command */
68   int stopme;    /* If set to true the agent will be terminated after
69                     the end of this session.  */
70   int allow_pinentry_notify; /* Set if pinentry notifications should
71                                 be done. */
72   void *import_key;  /* Malloced KEK for the import_key command.  */
73   void *export_key;  /* Malloced KEK for the export_key command.  */
74   int allow_fully_canceled; /* Client is aware of GPG_ERR_FULLY_CANCELED.  */
75   char *last_cache_nonce;   /* Last CACHE_NOCNE sent as status (malloced).  */
76   char *last_passwd_nonce;  /* Last PASSWD_NOCNE sent as status (malloced). */
77 };
78
79
80 /* An entry for the getval/putval commands. */
81 struct putval_item_s
82 {
83   struct putval_item_s *next;
84   size_t off;  /* Offset to the value into DATA.  */
85   size_t len;  /* Length of the value.  */
86   char d[1];   /* Key | Nul | value.  */
87 };
88
89
90 /* A list of key value pairs fpr the getval/putval commands.  */
91 static struct putval_item_s *putval_list;
92
93
94 \f
95 /* To help polling clients, we keep track of the number of certain
96    events.  This structure keeps those counters.  The counters are
97    integers and there should be no problem if they are overflowing as
98    callers need to check only whether a counter changed.  The actual
99    values are not meaningful. */
100 struct
101 {
102   /* Incremented if any of the other counters below changed. */
103   unsigned int any;
104
105   /* Incremented if a key is added or removed from the internal privat
106      key database. */
107   unsigned int key;
108
109   /* Incremented if a change of the card readers stati has been
110      detected. */
111   unsigned int card;
112
113 } eventcounter;
114
115
116 \f
117 /*  Local prototypes.  */
118 static int command_has_option (const char *cmd, const char *cmdopt);
119
120
121
122 \f
123 /* Release the memory buffer MB but first wipe out the used memory. */
124 static void
125 clear_outbuf (membuf_t *mb)
126 {
127   void *p;
128   size_t n;
129
130   p = get_membuf (mb, &n);
131   if (p)
132     {
133       memset (p, 0, n);
134       xfree (p);
135     }
136 }
137
138
139 /* Write the content of memory buffer MB as assuan data to CTX and
140    wipe the buffer out afterwards. */
141 static gpg_error_t
142 write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
143 {
144   gpg_error_t ae;
145   void *p;
146   size_t n;
147
148   p = get_membuf (mb, &n);
149   if (!p)
150     return out_of_core ();
151   ae = assuan_send_data (ctx, p, n);
152   memset (p, 0, n);
153   xfree (p);
154   return ae;
155 }
156
157
158 static void
159 clear_nonce_cache (ctrl_t ctrl)
160 {
161   if (ctrl->server_local->last_cache_nonce)
162     {
163       agent_put_cache (ctrl->server_local->last_cache_nonce,
164                        CACHE_MODE_NONCE, NULL, 0);
165       xfree (ctrl->server_local->last_cache_nonce);
166       ctrl->server_local->last_cache_nonce = NULL;
167     }
168   if (ctrl->server_local->last_passwd_nonce)
169     {
170       agent_put_cache (ctrl->server_local->last_passwd_nonce,
171                        CACHE_MODE_NONCE, NULL, 0);
172       xfree (ctrl->server_local->last_passwd_nonce);
173       ctrl->server_local->last_passwd_nonce = NULL;
174     }
175 }
176
177
178 static gpg_error_t
179 reset_notify (assuan_context_t ctx, char *line)
180 {
181   ctrl_t ctrl = assuan_get_pointer (ctx);
182
183   (void) line;
184
185   memset (ctrl->keygrip, 0, 20);
186   ctrl->have_keygrip = 0;
187   ctrl->digest.valuelen = 0;
188
189   xfree (ctrl->server_local->keydesc);
190   ctrl->server_local->keydesc = NULL;
191
192   clear_nonce_cache (ctrl);
193
194   return 0;
195 }
196
197
198 /* Skip over options.
199    Blanks after the options are also removed. */
200 static char *
201 skip_options (const char *line)
202 {
203   while (spacep (line))
204     line++;
205   while ( *line == '-' && line[1] == '-' )
206     {
207       while (*line && !spacep (line))
208         line++;
209       while (spacep (line))
210         line++;
211     }
212   return (char*)line;
213 }
214
215 /* Check whether the option NAME appears in LINE */
216 static int
217 has_option (const char *line, const char *name)
218 {
219   const char *s;
220   int n = strlen (name);
221
222   s = strstr (line, name);
223   if (s && s >= skip_options (line))
224     return 0;
225   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
226 }
227
228 /* Same as has_option but does only test for the name of the option
229    and ignores an argument, i.e. with NAME being "--hash" it would
230    return true for "--hash" as well as for "--hash=foo". */
231 static int
232 has_option_name (const char *line, const char *name)
233 {
234   const char *s;
235   int n = strlen (name);
236
237   s = strstr (line, name);
238   if (s && s >= skip_options (line))
239     return 0;
240   return (s && (s == line || spacep (s-1))
241           && (!s[n] || spacep (s+n) || s[n] == '='));
242 }
243
244 /* Return a pointer to the argument of the option with NAME.  If such
245    an option is not given, it returns NULL. */
246 static char *
247 option_value (const char *line, const char *name)
248 {
249   char *s;
250   int n = strlen (name);
251
252   s = strstr (line, name);
253   if (s && s >= skip_options (line))
254     return NULL;
255   if (s && (s == line || spacep (s-1))
256       && s[n] && (spacep (s+n) || s[n] == '='))
257     {
258       s += n + 1;
259       s += strspn (s, " ");
260       if (*s && !spacep(s))
261         return s;
262     }
263   return NULL;
264 }
265
266
267 /* Replace all '+' by a blank. */
268 static void
269 plus_to_blank (char *s)
270 {
271   for (; *s; s++)
272     {
273       if (*s == '+')
274         *s = ' ';
275     }
276 }
277
278
279 /* Parse a hex string.  Return an Assuan error code or 0 on success and the
280    length of the parsed string in LEN. */
281 static int
282 parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
283 {
284   const char *p;
285   size_t n;
286
287   /* parse the hash value */
288   for (p=string, n=0; hexdigitp (p); p++, n++)
289     ;
290   if (*p != ' ' && *p != '\t' && *p)
291     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
292   if ((n&1))
293     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
294   *len = n;
295   return 0;
296 }
297
298 /* Parse the keygrip in STRING into the provided buffer BUF.  BUF must
299    provide space for 20 bytes. BUF is not changed if the function
300    returns an error. */
301 static int
302 parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
303 {
304   int rc;
305   size_t n = 0;
306
307   rc = parse_hexstring (ctx, string, &n);
308   if (rc)
309     return rc;
310   n /= 2;
311   if (n != 20)
312     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip");
313
314   if (hex2bin (string, buf, 20) < 0)
315     return set_error (GPG_ERR_BUG, "hex2bin");
316
317   return 0;
318 }
319
320
321 /* Write an assuan status line. */
322 gpg_error_t
323 agent_write_status (ctrl_t ctrl, const char *keyword, ...)
324 {
325   gpg_error_t err = 0;
326   va_list arg_ptr;
327   const char *text;
328   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
329   char buf[950], *p;
330   size_t n;
331
332   va_start (arg_ptr, keyword);
333
334   p = buf;
335   n = 0;
336   while ( (text = va_arg (arg_ptr, const char *)) )
337     {
338       if (n)
339         {
340           *p++ = ' ';
341           n++;
342         }
343       for ( ; *text && n < DIM (buf)-3; n++, text++)
344         {
345           if (*text == '\n')
346             {
347               *p++ = '\\';
348               *p++ = 'n';
349             }
350           else if (*text == '\r')
351             {
352               *p++ = '\\';
353               *p++ = 'r';
354             }
355           else
356             *p++ = *text;
357         }
358     }
359   *p = 0;
360   err = assuan_write_status (ctx, keyword, buf);
361
362   va_end (arg_ptr);
363   return err;
364 }
365
366
367 /* Helper to notify the client about a launched Pinentry.  Because
368    that might disturb some older clients, this is only done if enabled
369    via an option.  Returns an gpg error code. */
370 gpg_error_t
371 agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
372 {
373   char line[100];
374
375   if (!ctrl || !ctrl->server_local
376       || !ctrl->server_local->allow_pinentry_notify)
377     return 0;
378   snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
379   return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
380 }
381
382
383 /* Helper to print a message while leaving a command.  */
384 static gpg_error_t
385 leave_cmd (assuan_context_t ctx, gpg_error_t err)
386 {
387   if (err)
388     {
389       const char *name = assuan_get_command_name (ctx);
390       if (!name)
391         name = "?";
392
393       /* Not all users of gpg-agent know about the fully canceled
394          error code; map it back if needed.  */
395       if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
396         {
397           ctrl_t ctrl = assuan_get_pointer (ctx);
398
399           if (!ctrl->server_local->allow_fully_canceled)
400             err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED);
401         }
402
403       /* Most code from common/ does not know the error source, thus
404          we fix this here.  */
405       if (gpg_err_source (err) == GPG_ERR_SOURCE_UNKNOWN)
406         err = gpg_err_make (GPG_ERR_SOURCE_DEFAULT, gpg_err_code (err));
407
408       if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
409         log_error ("command '%s' failed: %s\n", name,
410                    gpg_strerror (err));
411       else
412         log_error ("command '%s' failed: %s <%s>\n", name,
413                    gpg_strerror (err), gpg_strsource (err));
414     }
415   return err;
416 }
417
418
419 \f
420 static const char hlp_geteventcounter[] =
421   "GETEVENTCOUNTER\n"
422   "\n"
423   "Return a a status line named EVENTCOUNTER with the current values\n"
424   "of all event counters.  The values are decimal numbers in the range\n"
425   "0 to UINT_MAX and wrapping around to 0.  The actual values should\n"
426   "not be relied upon, they shall only be used to detect a change.\n"
427   "\n"
428   "The currently defined counters are:\n"
429   "\n"
430   "ANY  - Incremented with any change of any of the other counters.\n"
431   "KEY  - Incremented for added or removed private keys.\n"
432   "CARD - Incremented for changes of the card readers stati.";
433 static gpg_error_t
434 cmd_geteventcounter (assuan_context_t ctx, char *line)
435 {
436   ctrl_t ctrl = assuan_get_pointer (ctx);
437   char any_counter[25];
438   char key_counter[25];
439   char card_counter[25];
440
441   (void)line;
442
443   snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any);
444   snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key);
445   snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card);
446
447   return agent_write_status (ctrl, "EVENTCOUNTER",
448                              any_counter,
449                              key_counter,
450                              card_counter,
451                              NULL);
452 }
453
454
455 /* This function should be called once for all key removals or
456    additions.  This function is assured not to do any context
457    switches. */
458 void
459 bump_key_eventcounter (void)
460 {
461   eventcounter.key++;
462   eventcounter.any++;
463 }
464
465 /* This function should be called for all card reader status
466    changes.  This function is assured not to do any context
467    switches. */
468 void
469 bump_card_eventcounter (void)
470 {
471   eventcounter.card++;
472   eventcounter.any++;
473 }
474
475
476
477 \f
478 static const char hlp_istrusted[] =
479   "ISTRUSTED <hexstring_with_fingerprint>\n"
480   "\n"
481   "Return OK when we have an entry with this fingerprint in our\n"
482   "trustlist";
483 static gpg_error_t
484 cmd_istrusted (assuan_context_t ctx, char *line)
485 {
486   ctrl_t ctrl = assuan_get_pointer (ctx);
487   int rc, n, i;
488   char *p;
489   char fpr[41];
490
491   /* Parse the fingerprint value. */
492   for (p=line,n=0; hexdigitp (p); p++, n++)
493     ;
494   if (*p || !(n == 40 || n == 32))
495     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
496   i = 0;
497   if (n==32)
498     {
499       strcpy (fpr, "00000000");
500       i += 8;
501     }
502   for (p=line; i < 40; p++, i++)
503     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
504   fpr[i] = 0;
505   rc = agent_istrusted (ctrl, fpr, NULL);
506   if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
507     return rc;
508   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
509     return gpg_error (GPG_ERR_NOT_TRUSTED);
510   else
511     return leave_cmd (ctx, rc);
512 }
513
514
515 static const char hlp_listtrusted[] =
516   "LISTTRUSTED\n"
517   "\n"
518   "List all entries from the trustlist.";
519 static gpg_error_t
520 cmd_listtrusted (assuan_context_t ctx, char *line)
521 {
522   int rc;
523
524   (void)line;
525
526   rc = agent_listtrusted (ctx);
527   return leave_cmd (ctx, rc);
528 }
529
530
531 static const char hlp_martrusted[] =
532   "MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>\n"
533   "\n"
534   "Store a new key in into the trustlist.";
535 static gpg_error_t
536 cmd_marktrusted (assuan_context_t ctx, char *line)
537 {
538   ctrl_t ctrl = assuan_get_pointer (ctx);
539   int rc, n, i;
540   char *p;
541   char fpr[41];
542   int flag;
543
544   /* parse the fingerprint value */
545   for (p=line,n=0; hexdigitp (p); p++, n++)
546     ;
547   if (!spacep (p) || !(n == 40 || n == 32))
548     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
549   i = 0;
550   if (n==32)
551     {
552       strcpy (fpr, "00000000");
553       i += 8;
554     }
555   for (p=line; i < 40; p++, i++)
556     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
557   fpr[i] = 0;
558
559   while (spacep (p))
560     p++;
561   flag = *p++;
562   if ( (flag != 'S' && flag != 'P') || !spacep (p) )
563     return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
564   while (spacep (p))
565     p++;
566
567   rc = agent_marktrusted (ctrl, p, fpr, flag);
568   return leave_cmd (ctx, rc);
569 }
570
571
572
573 \f
574 static const char hlp_havekey[] =
575   "HAVEKEY <hexstrings_with_keygrips>\n"
576   "\n"
577   "Return success if at least one of the secret keys with the given\n"
578   "keygrips is available.";
579 static gpg_error_t
580 cmd_havekey (assuan_context_t ctx, char *line)
581 {
582   gpg_error_t err;
583   unsigned char buf[20];
584
585   do
586     {
587       err = parse_keygrip (ctx, line, buf);
588       if (err)
589         return err;
590
591       if (!agent_key_available (buf))
592         return 0; /* Found.  */
593
594       while (*line && *line != ' ' && *line != '\t')
595         line++;
596       while (*line == ' ' || *line == '\t')
597         line++;
598     }
599   while (*line);
600
601   /* No leave_cmd() here because errors are expected and would clutter
602      the log.  */
603   return gpg_error (GPG_ERR_NO_SECKEY);
604 }
605
606
607 static const char hlp_sigkey[] =
608   "SIGKEY <hexstring_with_keygrip>\n"
609   "SETKEY <hexstring_with_keygrip>\n"
610   "\n"
611   "Set the  key used for a sign or decrypt operation.";
612 static gpg_error_t
613 cmd_sigkey (assuan_context_t ctx, char *line)
614 {
615   int rc;
616   ctrl_t ctrl = assuan_get_pointer (ctx);
617
618   rc = parse_keygrip (ctx, line, ctrl->keygrip);
619   if (rc)
620     return rc;
621   ctrl->have_keygrip = 1;
622   return 0;
623 }
624
625
626 static const char hlp_setkeydesc[] =
627   "SETKEYDESC plus_percent_escaped_string\n"
628   "\n"
629   "Set a description to be used for the next PKSIGN, PKDECRYPT, IMPORT_KEY\n"
630   "or EXPORT_KEY operation if this operation requires a passphrase.  If\n"
631   "this command is not used a default text will be used.  Note, that\n"
632   "this description implictly selects the label used for the entry\n"
633   "box; if the string contains the string PIN (which in general will\n"
634   "not be translated), \"PIN\" is used, otherwise the translation of\n"
635   "\"passphrase\" is used.  The description string should not contain\n"
636   "blanks unless they are percent or '+' escaped.\n"
637   "\n"
638   "The description is only valid for the next PKSIGN, PKDECRYPT,\n"
639   "IMPORT_KEY or EXPORT_KEY operation.";
640 static gpg_error_t
641 cmd_setkeydesc (assuan_context_t ctx, char *line)
642 {
643   ctrl_t ctrl = assuan_get_pointer (ctx);
644   char *desc, *p;
645
646   for (p=line; *p == ' '; p++)
647     ;
648   desc = p;
649   p = strchr (desc, ' ');
650   if (p)
651     *p = 0; /* We ignore any garbage; we might late use it for other args. */
652
653   if (!desc || !*desc)
654     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
655
656   /* Note, that we only need to replace the + characters and should
657      leave the other escaping in place because the escaped string is
658      send verbatim to the pinentry which does the unescaping (but not
659      the + replacing) */
660   plus_to_blank (desc);
661
662   xfree (ctrl->server_local->keydesc);
663   ctrl->server_local->keydesc = xtrystrdup (desc);
664   if (!ctrl->server_local->keydesc)
665     return out_of_core ();
666   return 0;
667 }
668
669
670 static const char hlp_sethash[] =
671   "SETHASH (--hash=<name>)|(<algonumber>) <hexstring>\n"
672   "\n"
673   "The client can use this command to tell the server about the data\n"
674   "(which usually is a hash) to be signed.";
675 static gpg_error_t
676 cmd_sethash (assuan_context_t ctx, char *line)
677 {
678   int rc;
679   size_t n;
680   char *p;
681   ctrl_t ctrl = assuan_get_pointer (ctx);
682   unsigned char *buf;
683   char *endp;
684   int algo;
685
686   /* Parse the alternative hash options which may be used instead of
687      the algo number.  */
688   if (has_option_name (line, "--hash"))
689     {
690       if (has_option (line, "--hash=sha1"))
691         algo = GCRY_MD_SHA1;
692       else if (has_option (line, "--hash=sha224"))
693         algo = GCRY_MD_SHA224;
694       else if (has_option (line, "--hash=sha256"))
695         algo = GCRY_MD_SHA256;
696       else if (has_option (line, "--hash=sha384"))
697         algo = GCRY_MD_SHA384;
698       else if (has_option (line, "--hash=sha512"))
699         algo = GCRY_MD_SHA512;
700       else if (has_option (line, "--hash=rmd160"))
701         algo = GCRY_MD_RMD160;
702       else if (has_option (line, "--hash=md5"))
703         algo = GCRY_MD_MD5;
704       else if (has_option (line, "--hash=tls-md5sha1"))
705         algo = MD_USER_TLS_MD5SHA1;
706       else
707         return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
708     }
709   else
710     algo = 0;
711
712   line = skip_options (line);
713
714   if (!algo)
715     {
716       /* No hash option has been given: require an algo number instead  */
717       algo = (int)strtoul (line, &endp, 10);
718       for (line = endp; *line == ' ' || *line == '\t'; line++)
719         ;
720       if (!algo || gcry_md_test_algo (algo))
721         return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
722     }
723   ctrl->digest.algo = algo;
724   ctrl->digest.raw_value = 0;
725
726   /* Parse the hash value. */
727   n = 0;
728   rc = parse_hexstring (ctx, line, &n);
729   if (rc)
730     return rc;
731   n /= 2;
732   if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
733     ;
734   else if (n != 16 && n != 20 && n != 24
735            && n != 28 && n != 32 && n != 48 && n != 64)
736     return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
737
738   if (n > MAX_DIGEST_LEN)
739     return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
740
741   buf = ctrl->digest.value;
742   ctrl->digest.valuelen = n;
743   for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
744     buf[n] = xtoi_2 (p);
745   for (; n < ctrl->digest.valuelen; n++)
746     buf[n] = 0;
747   return 0;
748 }
749
750
751 static const char hlp_pksign[] =
752   "PKSIGN [<options>] [<cache_nonce>]\n"
753   "\n"
754   "Perform the actual sign operation.  Neither input nor output are\n"
755   "sensitive to eavesdropping.";
756 static gpg_error_t
757 cmd_pksign (assuan_context_t ctx, char *line)
758 {
759   int rc;
760   cache_mode_t cache_mode = CACHE_MODE_NORMAL;
761   ctrl_t ctrl = assuan_get_pointer (ctx);
762   membuf_t outbuf;
763   char *cache_nonce = NULL;
764   char *p;
765
766   line = skip_options (line);
767
768   p = line;
769   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
770     ;
771   *p = '\0';
772   if (*line)
773     cache_nonce = xtrystrdup (line);
774
775   if (opt.ignore_cache_for_signing)
776     cache_mode = CACHE_MODE_IGNORE;
777   else if (!ctrl->server_local->use_cache_for_signing)
778     cache_mode = CACHE_MODE_IGNORE;
779
780   init_membuf (&outbuf, 512);
781
782   rc = agent_pksign (ctrl, cache_nonce, ctrl->server_local->keydesc,
783                      &outbuf, cache_mode);
784   if (rc)
785     clear_outbuf (&outbuf);
786   else
787     rc = write_and_clear_outbuf (ctx, &outbuf);
788
789   xfree (cache_nonce);
790   xfree (ctrl->server_local->keydesc);
791   ctrl->server_local->keydesc = NULL;
792   return leave_cmd (ctx, rc);
793 }
794
795
796 static const char hlp_pkdecrypt[] =
797   "PKDECRYPT [<options>]\n"
798   "\n"
799   "Perform the actual decrypt operation.  Input is not\n"
800   "sensitive to eavesdropping.";
801 static gpg_error_t
802 cmd_pkdecrypt (assuan_context_t ctx, char *line)
803 {
804   int rc;
805   ctrl_t ctrl = assuan_get_pointer (ctx);
806   unsigned char *value;
807   size_t valuelen;
808   membuf_t outbuf;
809
810   (void)line;
811
812   /* First inquire the data to decrypt */
813   rc = assuan_inquire (ctx, "CIPHERTEXT",
814                        &value, &valuelen, MAXLEN_CIPHERTEXT);
815   if (rc)
816     return rc;
817
818   init_membuf (&outbuf, 512);
819
820   rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
821                         value, valuelen, &outbuf);
822   xfree (value);
823   if (rc)
824     clear_outbuf (&outbuf);
825   else
826     rc = write_and_clear_outbuf (ctx, &outbuf);
827   xfree (ctrl->server_local->keydesc);
828   ctrl->server_local->keydesc = NULL;
829   return leave_cmd (ctx, rc);
830 }
831
832
833 static const char hlp_genkey[] =
834   "GENKEY [--no-protection] [--preset] [<cache_nonce>]\n"
835   "\n"
836   "Generate a new key, store the secret part and return the public\n"
837   "part.  Here is an example transaction:\n"
838   "\n"
839   "  C: GENKEY\n"
840   "  S: INQUIRE KEYPARAM\n"
841   "  C: D (genkey (rsa (nbits  1024)))\n"
842   "  C: END\n"
843   "  S: D (public-key\n"
844   "  S: D   (rsa (n 326487324683264) (e 10001)))\n"
845   "  S: OK key created\n"
846   "\n"
847   "When the --preset option is used the passphrase for the generated\n"
848   "key will be added to the cache.\n"
849   "\n";
850 static gpg_error_t
851 cmd_genkey (assuan_context_t ctx, char *line)
852 {
853   ctrl_t ctrl = assuan_get_pointer (ctx);
854   int rc;
855   int no_protection;
856   unsigned char *value;
857   size_t valuelen;
858   membuf_t outbuf;
859   char *cache_nonce = NULL;
860   int opt_preset;
861   char *p;
862
863   opt_preset = has_option (line, "--preset");
864   no_protection = has_option (line, "--no-protection");
865   line = skip_options (line);
866
867   p = line;
868   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
869     ;
870   *p = '\0';
871   if (*line)
872     cache_nonce = xtrystrdup (line);
873
874   /* First inquire the parameters */
875   rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
876   if (rc)
877     return rc;
878
879   init_membuf (&outbuf, 512);
880
881   rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
882                      opt_preset, &outbuf);
883   xfree (value);
884   if (rc)
885     clear_outbuf (&outbuf);
886   else
887     rc = write_and_clear_outbuf (ctx, &outbuf);
888   xfree (cache_nonce);
889   return leave_cmd (ctx, rc);
890 }
891
892
893
894 \f
895 static const char hlp_readkey[] =
896   "READKEY <hexstring_with_keygrip>\n"
897   "\n"
898   "Return the public key for the given keygrip.";
899 static gpg_error_t
900 cmd_readkey (assuan_context_t ctx, char *line)
901 {
902   ctrl_t ctrl = assuan_get_pointer (ctx);
903   int rc;
904   unsigned char grip[20];
905   gcry_sexp_t s_pkey = NULL;
906
907   rc = parse_keygrip (ctx, line, grip);
908   if (rc)
909     return rc; /* Return immediately as this is already an Assuan error code.*/
910
911   rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
912   if (!rc)
913     {
914       size_t len;
915       unsigned char *buf;
916
917       len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
918       assert (len);
919       buf = xtrymalloc (len);
920       if (!buf)
921         rc = gpg_error_from_syserror ();
922       else
923         {
924           len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
925           assert (len);
926           rc = assuan_send_data (ctx, buf, len);
927           xfree (buf);
928         }
929       gcry_sexp_release (s_pkey);
930     }
931
932   return leave_cmd (ctx, rc);
933 }
934
935
936 \f
937 static const char hlp_keyinfo[] =
938   "KEYINFO [--list] [--data] <keygrip>\n"
939   "\n"
940   "Return information about the key specified by the KEYGRIP.  If the\n"
941   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
942   "--list is given the keygrip is ignored and information about all\n"
943   "available keys are returned.  The information is returned as a\n"
944   "status line unless --data was specified, with this format:\n"
945   "\n"
946   "  KEYINFO <keygrip> <type> <serialno> <idstr> <cached> <protection>\n"
947   "\n"
948   "KEYGRIP is the keygrip.\n"
949   "\n"
950   "TYPE is describes the type of the key:\n"
951   "    'D' - Regular key stored on disk,\n"
952   "    'T' - Key is stored on a smartcard (token),\n"
953   "    '-' - Unknown type.\n"
954   "\n"
955   "SERIALNO is an ASCII string with the serial number of the\n"
956   "         smartcard.  If the serial number is not known a single\n"
957   "         dash '-' is used instead.\n"
958   "\n"
959   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
960   "      is not known a dash is used instead.\n"
961   "\n"
962   "CACHED is 1 if the passphrase for the key was found in the key cache.\n"
963   "       If not, a '-' is used instead.\n"
964   "\n"
965   "PROTECTION describes the key protection type:\n"
966   "    'P' - The key is protected with a passphrase,\n"
967   "    'C' - The key is not protected,\n"
968   "    '-' - Unknown protection.\n"
969   "\n"
970   "More information may be added in the future.";
971 static gpg_error_t
972 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
973                 int data)
974 {
975   gpg_error_t err;
976   char hexgrip[40+1];
977   int keytype;
978   unsigned char *shadow_info = NULL;
979   char *serialno = NULL;
980   char *idstr = NULL;
981   const char *keytypestr;
982   const char *cached;
983   const char *protectionstr;
984   char *pw;
985
986   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
987   if (err)
988     goto leave;
989
990   /* Reformat the grip so that we use uppercase as good style. */
991   bin2hex (grip, 20, hexgrip);
992
993   switch (keytype)
994     {
995     case PRIVATE_KEY_CLEAR: protectionstr = "C"; keytypestr = "D";
996       break;
997     case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
998       break;
999     case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
1000       break;
1001     default: protectionstr = "-"; keytypestr = "-";
1002       break;
1003     }
1004
1005   /* Here we have a little race by doing the cache check separately
1006      from the retrieval function.  Given that the cache flag is only a
1007      hint, it should not really matter.  */
1008   pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
1009   cached = pw ? "1" : "-";
1010   xfree (pw);
1011
1012   if (shadow_info)
1013     {
1014       err = parse_shadow_info (shadow_info, &serialno, &idstr);
1015       if (err)
1016         goto leave;
1017     }
1018
1019   if (!data)
1020     err = agent_write_status (ctrl, "KEYINFO",
1021                               hexgrip,
1022                               keytypestr,
1023                               serialno? serialno : "-",
1024                               idstr? idstr : "-",
1025                               cached,
1026                               protectionstr,
1027                               NULL);
1028   else
1029     {
1030       char *string;
1031
1032       string = xtryasprintf ("%s %s %s %s %s %s\n",
1033                              hexgrip, keytypestr,
1034                              serialno? serialno : "-",
1035                              idstr? idstr : "-", cached, protectionstr);
1036       if (!string)
1037         err = gpg_error_from_syserror ();
1038       else
1039         err = assuan_send_data (ctx, string, strlen(string));
1040       xfree (string);
1041     }
1042
1043  leave:
1044   xfree (shadow_info);
1045   xfree (serialno);
1046   xfree (idstr);
1047   return err;
1048 }
1049
1050
1051 static gpg_error_t
1052 cmd_keyinfo (assuan_context_t ctx, char *line)
1053 {
1054   ctrl_t ctrl = assuan_get_pointer (ctx);
1055   int err;
1056   unsigned char grip[20];
1057   DIR *dir = NULL;
1058   int list_mode;
1059   int opt_data;
1060
1061   list_mode = has_option (line, "--list");
1062   opt_data = has_option (line, "--data");
1063   line = skip_options (line);
1064
1065   if (list_mode)
1066     {
1067       char *dirname;
1068       struct dirent *dir_entry;
1069       char hexgrip[41];
1070
1071       dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1072       if (!dirname)
1073         {
1074           err = gpg_error_from_syserror ();
1075           goto leave;
1076         }
1077       dir = opendir (dirname);
1078       if (!dir)
1079         {
1080           err = gpg_error_from_syserror ();
1081           xfree (dirname);
1082           goto leave;
1083         }
1084       xfree (dirname);
1085
1086       while ( (dir_entry = readdir (dir)) )
1087         {
1088           if (strlen (dir_entry->d_name) != 44
1089               || strcmp (dir_entry->d_name + 40, ".key"))
1090             continue;
1091           strncpy (hexgrip, dir_entry->d_name, 40);
1092           hexgrip[40] = 0;
1093
1094           if ( hex2bin (hexgrip, grip, 20) < 0 )
1095             continue; /* Bad hex string.  */
1096
1097           err = do_one_keyinfo (ctrl, grip, ctx, opt_data);
1098           if (err)
1099             goto leave;
1100         }
1101       err = 0;
1102     }
1103   else
1104     {
1105       err = parse_keygrip (ctx, line, grip);
1106       if (err)
1107         goto leave;
1108       err = do_one_keyinfo (ctrl, grip, ctx, opt_data);
1109     }
1110
1111  leave:
1112   if (dir)
1113     closedir (dir);
1114   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1115     leave_cmd (ctx, err);
1116   return err;
1117 }
1118
1119
1120 \f
1121 static int
1122 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1123 {
1124   size_t n;
1125   int rc;
1126
1127   assuan_begin_confidential (ctx);
1128   n = strlen (pw);
1129   if (via_data)
1130     rc = assuan_send_data (ctx, pw, n);
1131   else
1132     {
1133       char *p = xtrymalloc_secure (n*2+1);
1134       if (!p)
1135         rc = gpg_error_from_syserror ();
1136       else
1137         {
1138           bin2hex (pw, n, p);
1139           rc = assuan_set_okay_line (ctx, p);
1140           xfree (p);
1141         }
1142     }
1143   return rc;
1144 }
1145
1146
1147 static const char hlp_get_passphrase[] =
1148   "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1149   "               [--qualitybar] <cache_id>\n"
1150   "               [<error_message> <prompt> <description>]\n"
1151   "\n"
1152   "This function is usually used to ask for a passphrase to be used\n"
1153   "for conventional encryption, but may also be used by programs which\n"
1154   "need specal handling of passphrases.  This command uses a syntax\n"
1155   "which helps clients to use the agent with minimum effort.  The\n"
1156   "agent either returns with an error or with a OK followed by the hex\n"
1157   "encoded passphrase.  Note that the length of the strings is\n"
1158   "implicitly limited by the maximum length of a command.\n"
1159   "\n"
1160   "If the option \"--data\" is used the passphrase is returned by usual\n"
1161   "data lines and not on the okay line.\n"
1162   "\n"
1163   "If the option \"--check\" is used the passphrase constraints checks as\n"
1164   "implemented by gpg-agent are applied.  A check is not done if the\n"
1165   "passphrase has been found in the cache.\n"
1166   "\n"
1167   "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1168   "cache the user will not be asked to enter a passphrase but the error\n"
1169   "code GPG_ERR_NO_DATA is returned.  \n"
1170   "\n"
1171   "If the option \"--qualitybar\" is used a visual indication of the\n"
1172   "entered passphrase quality is shown.  (Unless no minimum passphrase\n"
1173   "length has been configured.)";
1174 static gpg_error_t
1175 cmd_get_passphrase (assuan_context_t ctx, char *line)
1176 {
1177   ctrl_t ctrl = assuan_get_pointer (ctx);
1178   int rc;
1179   char *pw;
1180   char *response;
1181   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1182   const char *desc2 = _("Please re-enter this passphrase");
1183   char *p;
1184   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1185   int opt_repeat = 0;
1186   char *repeat_errtext = NULL;
1187
1188   opt_data = has_option (line, "--data");
1189   opt_check = has_option (line, "--check");
1190   opt_no_ask = has_option (line, "--no-ask");
1191   if (has_option_name (line, "--repeat"))
1192     {
1193       p = option_value (line, "--repeat");
1194       if (p)
1195         opt_repeat = atoi (p);
1196       else
1197         opt_repeat = 1;
1198     }
1199   opt_qualbar = has_option (line, "--qualitybar");
1200   line = skip_options (line);
1201
1202   cacheid = line;
1203   p = strchr (cacheid, ' ');
1204   if (p)
1205     {
1206       *p++ = 0;
1207       while (*p == ' ')
1208         p++;
1209       errtext = p;
1210       p = strchr (errtext, ' ');
1211       if (p)
1212         {
1213           *p++ = 0;
1214           while (*p == ' ')
1215             p++;
1216           prompt = p;
1217           p = strchr (prompt, ' ');
1218           if (p)
1219             {
1220               *p++ = 0;
1221               while (*p == ' ')
1222                 p++;
1223               desc = p;
1224               p = strchr (desc, ' ');
1225               if (p)
1226                 *p = 0; /* Ignore trailing garbage. */
1227             }
1228         }
1229     }
1230   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1231     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1232   if (!desc)
1233     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1234
1235   if (!strcmp (cacheid, "X"))
1236     cacheid = NULL;
1237   if (!strcmp (errtext, "X"))
1238     errtext = NULL;
1239   if (!strcmp (prompt, "X"))
1240     prompt = NULL;
1241   if (!strcmp (desc, "X"))
1242     desc = NULL;
1243
1244   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL) : NULL;
1245   if (pw)
1246     {
1247       rc = send_back_passphrase (ctx, opt_data, pw);
1248       xfree (pw);
1249     }
1250   else if (opt_no_ask)
1251     rc = gpg_error (GPG_ERR_NO_DATA);
1252   else
1253     {
1254       /* Note, that we only need to replace the + characters and
1255          should leave the other escaping in place because the escaped
1256          string is send verbatim to the pinentry which does the
1257          unescaping (but not the + replacing) */
1258       if (errtext)
1259         plus_to_blank (errtext);
1260       if (prompt)
1261         plus_to_blank (prompt);
1262       if (desc)
1263         plus_to_blank (desc);
1264
1265     next_try:
1266       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1267                                  repeat_errtext? repeat_errtext:errtext,
1268                                  opt_qualbar);
1269       xfree (repeat_errtext);
1270       repeat_errtext = NULL;
1271       if (!rc)
1272         {
1273           int i;
1274
1275           if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1276             {
1277               xfree (response);
1278               goto next_try;
1279             }
1280           for (i = 0; i < opt_repeat; i++)
1281             {
1282               char *response2;
1283
1284               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1285                                          errtext, 0);
1286               if (rc)
1287                 break;
1288               if (strcmp (response2, response))
1289                 {
1290                   xfree (response2);
1291                   xfree (response);
1292                   repeat_errtext = try_percent_escape
1293                     (_("does not match - try again"), NULL);
1294                   if (!repeat_errtext)
1295                     {
1296                       rc = gpg_error_from_syserror ();
1297                       break;
1298                     }
1299                   goto next_try;
1300                 }
1301               xfree (response2);
1302             }
1303           if (!rc)
1304             {
1305               if (cacheid)
1306                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1307               rc = send_back_passphrase (ctx, opt_data, response);
1308             }
1309           xfree (response);
1310         }
1311     }
1312
1313   return leave_cmd (ctx, rc);
1314 }
1315
1316
1317 static const char hlp_clear_passphrase[] =
1318   "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
1319   "\n"
1320   "may be used to invalidate the cache entry for a passphrase.  The\n"
1321   "function returns with OK even when there is no cached passphrase.\n"
1322   "The --mode=normal option is used to clear an entry for a cacheid\n"
1323   "added by the agent.\n";
1324 static gpg_error_t
1325 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1326 {
1327   char *cacheid = NULL;
1328   char *p;
1329   int opt_normal;
1330
1331   opt_normal = has_option (line, "--mode=normal");
1332   line = skip_options (line);
1333
1334   /* parse the stuff */
1335   for (p=line; *p == ' '; p++)
1336     ;
1337   cacheid = p;
1338   p = strchr (cacheid, ' ');
1339   if (p)
1340     *p = 0; /* ignore garbage */
1341   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1342     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1343
1344   agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
1345                    NULL, 0);
1346   return 0;
1347 }
1348
1349
1350 static const char hlp_get_confirmation[] =
1351   "GET_CONFIRMATION <description>\n"
1352   "\n"
1353   "This command may be used to ask for a simple confirmation.\n"
1354   "DESCRIPTION is displayed along with a Okay and Cancel button.  This\n"
1355   "command uses a syntax which helps clients to use the agent with\n"
1356   "minimum effort.  The agent either returns with an error or with a\n"
1357   "OK.  Note, that the length of DESCRIPTION is implicitly limited by\n"
1358   "the maximum length of a command. DESCRIPTION should not contain\n"
1359   "any spaces, those must be encoded either percent escaped or simply\n"
1360   "as '+'.";
1361 static gpg_error_t
1362 cmd_get_confirmation (assuan_context_t ctx, char *line)
1363 {
1364   ctrl_t ctrl = assuan_get_pointer (ctx);
1365   int rc;
1366   char *desc = NULL;
1367   char *p;
1368
1369   /* parse the stuff */
1370   for (p=line; *p == ' '; p++)
1371     ;
1372   desc = p;
1373   p = strchr (desc, ' ');
1374   if (p)
1375     *p = 0; /* We ignore any garbage -may be later used for other args. */
1376
1377   if (!desc || !*desc)
1378     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1379
1380   if (!strcmp (desc, "X"))
1381     desc = NULL;
1382
1383   /* Note, that we only need to replace the + characters and should
1384      leave the other escaping in place because the escaped string is
1385      send verbatim to the pinentry which does the unescaping (but not
1386      the + replacing) */
1387   if (desc)
1388     plus_to_blank (desc);
1389
1390   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1391   return leave_cmd (ctx, rc);
1392 }
1393
1394
1395 \f
1396 static const char hlp_learn[] =
1397   "LEARN [--send]\n"
1398   "\n"
1399   "Learn something about the currently inserted smartcard.  With\n"
1400   "--send the new certificates are send back.";
1401 static gpg_error_t
1402 cmd_learn (assuan_context_t ctx, char *line)
1403 {
1404   ctrl_t ctrl = assuan_get_pointer (ctx);
1405   int rc;
1406
1407   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1408   return leave_cmd (ctx, rc);
1409 }
1410
1411
1412 \f
1413 static const char hlp_passwd[] =
1414   "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset] <hexkeygrip>\n"
1415   "\n"
1416   "Change the passphrase/PIN for the key identified by keygrip in LINE. When\n"
1417   "--preset is used then the new passphrase will be added to the cache.\n";
1418 static gpg_error_t
1419 cmd_passwd (assuan_context_t ctx, char *line)
1420 {
1421   ctrl_t ctrl = assuan_get_pointer (ctx);
1422   gpg_error_t err;
1423   int c;
1424   char *cache_nonce = NULL;
1425   char *passwd_nonce = NULL;
1426   unsigned char grip[20];
1427   gcry_sexp_t s_skey = NULL;
1428   unsigned char *shadow_info = NULL;
1429   char *passphrase = NULL;
1430   char *pend;
1431   int opt_preset;
1432
1433   opt_preset = has_option (line, "--preset");
1434   cache_nonce = option_value (line, "--cache-nonce");
1435   if (cache_nonce)
1436     {
1437       for (pend = cache_nonce; *pend && !spacep (pend); pend++)
1438         ;
1439       c = *pend;
1440       *pend = '\0';
1441       cache_nonce = xtrystrdup (cache_nonce);
1442       *pend = c;
1443       if (!cache_nonce)
1444         {
1445           err = gpg_error_from_syserror ();
1446           goto leave;
1447         }
1448     }
1449
1450   passwd_nonce = option_value (line, "--passwd-nonce");
1451   if (passwd_nonce)
1452     {
1453       for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
1454         ;
1455       c = *pend;
1456       *pend = '\0';
1457       passwd_nonce = xtrystrdup (passwd_nonce);
1458       *pend = c;
1459       if (!passwd_nonce)
1460         {
1461           err = gpg_error_from_syserror ();
1462           goto leave;
1463         }
1464     }
1465
1466   line = skip_options (line);
1467
1468   err = parse_keygrip (ctx, line, grip);
1469   if (err)
1470     goto leave;
1471
1472   ctrl->in_passwd++;
1473   err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc,
1474                              grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1475                              &s_skey, &passphrase);
1476   if (err)
1477     ;
1478   else if (!s_skey)
1479     {
1480       log_error ("changing a smartcard PIN is not yet supported\n");
1481       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1482     }
1483   else
1484     {
1485       char *newpass = NULL;
1486
1487       if (passwd_nonce)
1488         newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
1489       err = agent_protect_and_store (ctrl, s_skey, &newpass);
1490       if (!err && passphrase)
1491         {
1492           /* A passphrase existed on the old key and the change was
1493              successful.  Return a nonce for that old passphrase to
1494              let the caller try to unprotect the other subkeys with
1495              the same key.  */
1496           if (!cache_nonce)
1497             {
1498               char buf[12];
1499               gcry_create_nonce (buf, 12);
1500               cache_nonce = bin2hex (buf, 12, NULL);
1501             }
1502           if (cache_nonce
1503               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1504                                    passphrase, CACHE_TTL_NONCE))
1505             {
1506               assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1507               xfree (ctrl->server_local->last_cache_nonce);
1508               ctrl->server_local->last_cache_nonce = cache_nonce;
1509               cache_nonce = NULL;
1510             }
1511           if (newpass)
1512             {
1513               /* If we have a new passphrase (which might be empty) we
1514                  store it under a passwd nonce so that the caller may
1515                  send that nonce again to use it for another key. */
1516               if (!passwd_nonce)
1517                 {
1518                   char buf[12];
1519                   gcry_create_nonce (buf, 12);
1520                   passwd_nonce = bin2hex (buf, 12, NULL);
1521                 }
1522               if (passwd_nonce
1523                   && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1524                                        newpass, CACHE_TTL_NONCE))
1525                 {
1526                   assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1527                   xfree (ctrl->server_local->last_passwd_nonce);
1528                   ctrl->server_local->last_passwd_nonce = passwd_nonce;
1529                   passwd_nonce = NULL;
1530                 }
1531             }
1532         }
1533       if (!err && opt_preset)
1534       {
1535           char hexgrip[40+1];
1536           bin2hex(grip, 20, hexgrip);
1537           err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass,
1538                                  ctrl->cache_ttl_opt_preset);
1539       }
1540       xfree (newpass);
1541     }
1542   ctrl->in_passwd--;
1543
1544   xfree (ctrl->server_local->keydesc);
1545   ctrl->server_local->keydesc = NULL;
1546
1547  leave:
1548   xfree (passphrase);
1549   gcry_sexp_release (s_skey);
1550   xfree (shadow_info);
1551   xfree (cache_nonce);
1552   return leave_cmd (ctx, err);
1553 }
1554
1555
1556 static const char hlp_preset_passphrase[] =
1557   "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n"
1558   "\n"
1559   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1560   "to passwd for the given time, where -1 means infinite and 0 means\n"
1561   "the default (currently only a timeout of -1 is allowed, which means\n"
1562   "to never expire it).  If passwd is not provided, ask for it via the\n"
1563   "pinentry module unless --inquire is passed in which case the passphrase\n"
1564   "is retrieved from the client via a server inquire.\n";
1565 static gpg_error_t
1566 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1567 {
1568   int rc;
1569   char *grip_clear = NULL;
1570   unsigned char *passphrase = NULL;
1571   int ttl;
1572   size_t len;
1573   int opt_inquire;
1574
1575   if (!opt.allow_preset_passphrase)
1576     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1577
1578   opt_inquire = has_option (line, "--inquire");
1579   line = skip_options (line);
1580   grip_clear = line;
1581   while (*line && (*line != ' ' && *line != '\t'))
1582     line++;
1583   if (!*line)
1584     return gpg_error (GPG_ERR_MISSING_VALUE);
1585   *line = '\0';
1586   line++;
1587   while (*line && (*line == ' ' || *line == '\t'))
1588     line++;
1589
1590   /* Currently, only infinite timeouts are allowed.  */
1591   ttl = -1;
1592   if (line[0] != '-' || line[1] != '1')
1593     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1594   line++;
1595   line++;
1596   while (!(*line != ' ' && *line != '\t'))
1597     line++;
1598
1599   /* Syntax check the hexstring.  */
1600   len = 0;
1601   rc = parse_hexstring (ctx, line, &len);
1602   if (rc)
1603     return rc;
1604   line[len] = '\0';
1605
1606   /* If there is a passphrase, use it.  Currently, a passphrase is
1607      required.  */
1608   if (*line)
1609     {
1610       if (opt_inquire)
1611         {
1612           rc = set_error (GPG_ERR_ASS_PARAMETER,
1613                           "both --inquire and passphrase specified");
1614           goto leave;
1615         }
1616
1617       /* Do in-place conversion.  */
1618       passphrase = line;
1619       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1620         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1621     }
1622   else if (opt_inquire)
1623     {
1624       /* Note that the passphrase will be truncated at any null byte and the
1625        * limit is 480 characters. */
1626       rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, 480);
1627     }
1628   else
1629     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1630
1631   if (!rc)
1632     {
1633       rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1634       if (opt_inquire)
1635         xfree (passphrase);
1636     }
1637
1638 leave:
1639   return leave_cmd (ctx, rc);
1640 }
1641
1642
1643 \f
1644 static const char hlp_scd[] =
1645   "SCD <commands to pass to the scdaemon>\n"
1646   " \n"
1647   "This is a general quote command to redirect everything to the\n"
1648   "SCdaemon.";
1649 static gpg_error_t
1650 cmd_scd (assuan_context_t ctx, char *line)
1651 {
1652   ctrl_t ctrl = assuan_get_pointer (ctx);
1653   int rc;
1654
1655   rc = divert_generic_cmd (ctrl, line, ctx);
1656
1657   return rc;
1658 }
1659
1660
1661 \f
1662 static const char hlp_keywrap_key[] =
1663   "KEYWRAP_KEY [--clear] <mode>\n"
1664   "\n"
1665   "Return a key to wrap another key.  For now the key is returned\n"
1666   "verbatim and and thus makes not much sense because an eavesdropper on\n"
1667   "the gpg-agent connection will see the key as well as the wrapped key.\n"
1668   "However, this function may either be equipped with a public key\n"
1669   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
1670   "case wrapping the import and export of keys is a requirement for\n"
1671   "certain cryptographic validations and thus useful.  The key persists\n"
1672   "a RESET command but may be cleared using the option --clear.\n"
1673   "\n"
1674   "Supported modes are:\n"
1675   "  --import  - Return a key to import a key into gpg-agent\n"
1676   "  --export  - Return a key to export a key from gpg-agent";
1677 static gpg_error_t
1678 cmd_keywrap_key (assuan_context_t ctx, char *line)
1679 {
1680   ctrl_t ctrl = assuan_get_pointer (ctx);
1681   gpg_error_t err = 0;
1682   int clearopt = has_option (line, "--clear");
1683
1684
1685   assuan_begin_confidential (ctx);
1686   if (has_option (line, "--import"))
1687     {
1688       xfree (ctrl->server_local->import_key);
1689       if (clearopt)
1690         ctrl->server_local->import_key = NULL;
1691       else if (!(ctrl->server_local->import_key =
1692                  gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1693         err = gpg_error_from_syserror ();
1694       else
1695         err = assuan_send_data (ctx, ctrl->server_local->import_key,
1696                                 KEYWRAP_KEYSIZE);
1697     }
1698   else if (has_option (line, "--export"))
1699     {
1700       xfree (ctrl->server_local->export_key);
1701       if (clearopt)
1702         ctrl->server_local->export_key = NULL;
1703       else if (!(ctrl->server_local->export_key =
1704             gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1705         err = gpg_error_from_syserror ();
1706       else
1707         err = assuan_send_data (ctx, ctrl->server_local->export_key,
1708                                 KEYWRAP_KEYSIZE);
1709     }
1710   else
1711     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
1712   assuan_end_confidential (ctx);
1713
1714   return leave_cmd (ctx, err);
1715 }
1716
1717
1718 \f
1719 static const char hlp_import_key[] =
1720   "IMPORT_KEY [<cache_nonce>]\n"
1721   "\n"
1722   "Import a secret key into the key store.  The key is expected to be\n"
1723   "encrypted using the current session's key wrapping key (cf. command\n"
1724   "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
1725   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
1726   "key data.  The unwrapped key must be a canonical S-expression.";
1727 static gpg_error_t
1728 cmd_import_key (assuan_context_t ctx, char *line)
1729 {
1730   ctrl_t ctrl = assuan_get_pointer (ctx);
1731   gpg_error_t err;
1732   unsigned char *wrappedkey = NULL;
1733   size_t wrappedkeylen;
1734   gcry_cipher_hd_t cipherhd = NULL;
1735   unsigned char *key = NULL;
1736   size_t keylen, realkeylen;
1737   char *passphrase = NULL;
1738   unsigned char *finalkey = NULL;
1739   size_t finalkeylen;
1740   unsigned char grip[20];
1741   gcry_sexp_t openpgp_sexp = NULL;
1742   char *cache_nonce = NULL;
1743   char *p;
1744
1745   if (!ctrl->server_local->import_key)
1746     {
1747       err = gpg_error (GPG_ERR_MISSING_KEY);
1748       goto leave;
1749     }
1750
1751   p = line;
1752   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
1753     ;
1754   *p = '\0';
1755   if (*line)
1756     cache_nonce = xtrystrdup (line);
1757
1758   assuan_begin_confidential (ctx);
1759   err = assuan_inquire (ctx, "KEYDATA",
1760                         &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
1761   assuan_end_confidential (ctx);
1762   if (err)
1763     goto leave;
1764   if (wrappedkeylen < 24)
1765     {
1766       err = gpg_error (GPG_ERR_INV_LENGTH);
1767       goto leave;
1768     }
1769   keylen = wrappedkeylen - 8;
1770   key = xtrymalloc_secure (keylen);
1771   if (!key)
1772     {
1773       err = gpg_error_from_syserror ();
1774       goto leave;
1775     }
1776
1777   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1778                           GCRY_CIPHER_MODE_AESWRAP, 0);
1779   if (err)
1780     goto leave;
1781   err = gcry_cipher_setkey (cipherhd,
1782                             ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
1783   if (err)
1784     goto leave;
1785   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
1786   if (err)
1787     goto leave;
1788   gcry_cipher_close (cipherhd);
1789   cipherhd = NULL;
1790   xfree (wrappedkey);
1791   wrappedkey = NULL;
1792
1793   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1794   if (!realkeylen)
1795     goto leave; /* Invalid canonical encoded S-expression.  */
1796
1797   err = keygrip_from_canon_sexp (key, realkeylen, grip);
1798   if (err)
1799     {
1800       /* This might be due to an unsupported S-expression format.
1801          Check whether this is openpgp-private-key and trigger that
1802          import code.  */
1803       if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
1804         {
1805           const char *tag;
1806           size_t taglen;
1807
1808           tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
1809           if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
1810             ;
1811           else
1812             {
1813               gcry_sexp_release (openpgp_sexp);
1814               openpgp_sexp = NULL;
1815             }
1816         }
1817       if (!openpgp_sexp)
1818         goto leave; /* Note that ERR is still set.  */
1819     }
1820
1821
1822   if (openpgp_sexp)
1823     {
1824       /* In most cases the key is encrypted and thus the conversion
1825          function from the OpenPGP format to our internal format will
1826          ask for a passphrase.  That passphrase will be returned and
1827          used to protect the key using the same code as for regular
1828          key import. */
1829
1830       xfree (key);
1831       key = NULL;
1832       err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
1833                                   ctrl->server_local->keydesc, cache_nonce,
1834                                   &key, &passphrase);
1835       if (err)
1836         goto leave;
1837       realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1838       if (!realkeylen)
1839         goto leave; /* Invalid canonical encoded S-expression.  */
1840       if (passphrase)
1841         {
1842           if (!cache_nonce)
1843             {
1844               char buf[12];
1845               gcry_create_nonce (buf, 12);
1846               cache_nonce = bin2hex (buf, 12, NULL);
1847             }
1848           if (cache_nonce
1849               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1850                                    passphrase, CACHE_TTL_NONCE))
1851             assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1852         }
1853     }
1854   else
1855     {
1856       if (!agent_key_available (grip))
1857         err = gpg_error (GPG_ERR_EEXIST);
1858       else
1859         err = agent_ask_new_passphrase
1860           (ctrl, _("Please enter the passphrase to protect the "
1861                    "imported object within the GnuPG system."),
1862            &passphrase);
1863       if (err)
1864         goto leave;
1865     }
1866
1867   if (passphrase)
1868     {
1869       err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
1870               ctrl->s2k_count);
1871       if (!err)
1872         err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
1873     }
1874   else
1875     err = agent_write_private_key (grip, key, realkeylen, 0);
1876
1877  leave:
1878   gcry_sexp_release (openpgp_sexp);
1879   xfree (finalkey);
1880   xfree (passphrase);
1881   xfree (key);
1882   gcry_cipher_close (cipherhd);
1883   xfree (wrappedkey);
1884   xfree (cache_nonce);
1885   xfree (ctrl->server_local->keydesc);
1886   ctrl->server_local->keydesc = NULL;
1887   return leave_cmd (ctx, err);
1888 }
1889
1890
1891 \f
1892 static const char hlp_export_key[] =
1893   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
1894   "\n"
1895   "Export a secret key from the key store.  The key will be encrypted\n"
1896   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
1897   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
1898   "prior to using this command.  The function takes the keygrip as argument.\n";
1899 static gpg_error_t
1900 cmd_export_key (assuan_context_t ctx, char *line)
1901 {
1902   ctrl_t ctrl = assuan_get_pointer (ctx);
1903   gpg_error_t err;
1904   unsigned char grip[20];
1905   gcry_sexp_t s_skey = NULL;
1906   unsigned char *key = NULL;
1907   size_t keylen;
1908   gcry_cipher_hd_t cipherhd = NULL;
1909   unsigned char *wrappedkey = NULL;
1910   size_t wrappedkeylen;
1911   int openpgp;
1912   char *cache_nonce;
1913   char *passphrase = NULL;
1914
1915   openpgp = has_option (line, "--openpgp");
1916   cache_nonce = option_value (line, "--cache-nonce");
1917   if (cache_nonce)
1918     {
1919       for (; *line && !spacep (line); line++)
1920         ;
1921       if (*line)
1922         *line++ = '\0';
1923       cache_nonce = xtrystrdup (cache_nonce);
1924       if (!cache_nonce)
1925         {
1926           err = gpg_error_from_syserror ();
1927           goto leave;
1928         }
1929     }
1930   line = skip_options (line);
1931
1932   if (!ctrl->server_local->export_key)
1933     {
1934       err = gpg_error (GPG_ERR_MISSING_KEY);
1935       goto leave;
1936     }
1937
1938   err = parse_keygrip (ctx, line, grip);
1939   if (err)
1940     goto leave;
1941
1942   if (agent_key_available (grip))
1943     {
1944       err = gpg_error (GPG_ERR_NO_SECKEY);
1945       goto leave;
1946     }
1947
1948   /* Get the key from the file.  With the openpgp flag we also ask for
1949      the passphrase so that we can use it to re-encrypt it.  */
1950   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
1951                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
1952                              openpgp ? &passphrase : NULL);
1953   if (err)
1954     goto leave;
1955   if (!s_skey)
1956     {
1957       /* Key is on a smartcard.  Actually we should not see this here
1958          because we do not pass a shadow_info variable to the above
1959          function, thus it will return this error directly.  */
1960       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
1961       goto leave;
1962     }
1963
1964   if (openpgp)
1965     {
1966       /* The openpgp option changes the key format into the OpenPGP
1967          key transfer format.  The result is already a padded
1968          canonical S-expression.  */
1969       if (!passphrase)
1970         {
1971           err = agent_ask_new_passphrase
1972             (ctrl, _("This key (or subkey) is not protected with a passphrase."
1973                      "  Please enter a new passphrase to export it."),
1974              &passphrase);
1975           if (err)
1976             goto leave;
1977         }
1978       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
1979     }
1980   else
1981     {
1982       /* Convert into a canonical S-expression and wrap that.  */
1983       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
1984     }
1985   if (err)
1986     goto leave;
1987   gcry_sexp_release (s_skey);
1988   s_skey = NULL;
1989
1990   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1991                           GCRY_CIPHER_MODE_AESWRAP, 0);
1992   if (err)
1993     goto leave;
1994   err = gcry_cipher_setkey (cipherhd,
1995                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
1996   if (err)
1997     goto leave;
1998
1999   wrappedkeylen = keylen + 8;
2000   wrappedkey = xtrymalloc (wrappedkeylen);
2001   if (!wrappedkey)
2002     {
2003       err = gpg_error_from_syserror ();
2004       goto leave;
2005     }
2006
2007   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
2008   if (err)
2009     goto leave;
2010   xfree (key);
2011   key = NULL;
2012   gcry_cipher_close (cipherhd);
2013   cipherhd = NULL;
2014
2015   assuan_begin_confidential (ctx);
2016   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
2017   assuan_end_confidential (ctx);
2018
2019
2020  leave:
2021   xfree (cache_nonce);
2022   xfree (passphrase);
2023   xfree (wrappedkey);
2024   gcry_cipher_close (cipherhd);
2025   xfree (key);
2026   gcry_sexp_release (s_skey);
2027   xfree (ctrl->server_local->keydesc);
2028   ctrl->server_local->keydesc = NULL;
2029
2030   return leave_cmd (ctx, err);
2031 }
2032
2033
2034
2035 \f
2036 static const char hlp_getval[] =
2037   "GETVAL <key>\n"
2038   "\n"
2039   "Return the value for KEY from the special environment as created by\n"
2040   "PUTVAL.";
2041 static gpg_error_t
2042 cmd_getval (assuan_context_t ctx, char *line)
2043 {
2044   int rc = 0;
2045   char *key = NULL;
2046   char *p;
2047   struct putval_item_s *vl;
2048
2049   for (p=line; *p == ' '; p++)
2050     ;
2051   key = p;
2052   p = strchr (key, ' ');
2053   if (p)
2054     {
2055       *p++ = 0;
2056       for (; *p == ' '; p++)
2057         ;
2058       if (*p)
2059         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2060     }
2061   if (!key || !*key)
2062     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2063
2064
2065   for (vl=putval_list; vl; vl = vl->next)
2066     if ( !strcmp (vl->d, key) )
2067       break;
2068
2069   if (vl) /* Got an entry. */
2070     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2071   else
2072     return gpg_error (GPG_ERR_NO_DATA);
2073
2074   return leave_cmd (ctx, rc);
2075 }
2076
2077
2078 static const char hlp_putval[] =
2079   "PUTVAL <key> [<percent_escaped_value>]\n"
2080   "\n"
2081   "The gpg-agent maintains a kind of environment which may be used to\n"
2082   "store key/value pairs in it, so that they can be retrieved later.\n"
2083   "This may be used by helper daemons to daemonize themself on\n"
2084   "invocation and register them with gpg-agent.  Callers of the\n"
2085   "daemon's service may now first try connect to get the information\n"
2086   "for that service from gpg-agent through the GETVAL command and then\n"
2087   "try to connect to that daemon.  Only if that fails they may start\n"
2088   "an own instance of the service daemon. \n"
2089   "\n"
2090   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2091   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2092   "corresponsing value; they should be similar to the values of\n"
2093   "envronment variables but gpg-agent does not enforce any\n"
2094   "restrictions.  If that value is not given any value under that KEY\n"
2095   "is removed from this special environment.";
2096 static gpg_error_t
2097 cmd_putval (assuan_context_t ctx, char *line)
2098 {
2099   int rc = 0;
2100   char *key = NULL;
2101   char *value = NULL;
2102   size_t valuelen = 0;
2103   char *p;
2104   struct putval_item_s *vl, *vlprev;
2105
2106   for (p=line; *p == ' '; p++)
2107     ;
2108   key = p;
2109   p = strchr (key, ' ');
2110   if (p)
2111     {
2112       *p++ = 0;
2113       for (; *p == ' '; p++)
2114         ;
2115       if (*p)
2116         {
2117           value = p;
2118           p = strchr (value, ' ');
2119           if (p)
2120             *p = 0;
2121           valuelen = percent_plus_unescape_inplace (value, 0);
2122         }
2123     }
2124   if (!key || !*key)
2125     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2126
2127
2128   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2129     if ( !strcmp (vl->d, key) )
2130       break;
2131
2132   if (vl) /* Delete old entry. */
2133     {
2134       if (vlprev)
2135         vlprev->next = vl->next;
2136       else
2137         putval_list = vl->next;
2138       xfree (vl);
2139     }
2140
2141   if (valuelen) /* Add entry. */
2142     {
2143       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2144       if (!vl)
2145         rc = gpg_error_from_syserror ();
2146       else
2147         {
2148           vl->len = valuelen;
2149           vl->off = strlen (key) + 1;
2150           strcpy (vl->d, key);
2151           memcpy (vl->d + vl->off, value, valuelen);
2152           vl->next = putval_list;
2153           putval_list = vl;
2154         }
2155     }
2156
2157   return leave_cmd (ctx, rc);
2158 }
2159
2160
2161
2162 \f
2163 static const char hlp_updatestartuptty[] =
2164   "UPDATESTARTUPTTY\n"
2165   "\n"
2166   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2167   "session.  This command is useful to pull future pinentries to\n"
2168   "another screen.  It is only required because there is no way in the\n"
2169   "ssh-agent protocol to convey this information.";
2170 static gpg_error_t
2171 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2172 {
2173   static const char *names[] =
2174     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2175   ctrl_t ctrl = assuan_get_pointer (ctx);
2176   gpg_error_t err = 0;
2177   session_env_t se;
2178   int idx;
2179   char *lc_ctype = NULL;
2180   char *lc_messages = NULL;
2181
2182   (void)line;
2183
2184   se = session_env_new ();
2185   if (!se)
2186     err = gpg_error_from_syserror ();
2187
2188   for (idx=0; !err && names[idx]; idx++)
2189     {
2190       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2191       if (value)
2192         err = session_env_setenv (se, names[idx], value);
2193     }
2194
2195   if (!err && ctrl->lc_ctype)
2196     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2197       err = gpg_error_from_syserror ();
2198
2199   if (!err && ctrl->lc_messages)
2200     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2201       err = gpg_error_from_syserror ();
2202
2203   if (err)
2204     {
2205       session_env_release (se);
2206       xfree (lc_ctype);
2207       xfree (lc_messages);
2208     }
2209   else
2210     {
2211       session_env_release (opt.startup_env);
2212       opt.startup_env = se;
2213       xfree (opt.startup_lc_ctype);
2214       opt.startup_lc_ctype = lc_ctype;
2215       xfree (opt.startup_lc_messages);
2216       opt.startup_lc_messages = lc_messages;
2217     }
2218
2219   return err;
2220 }
2221
2222
2223 \f
2224 static const char hlp_killagent[] =
2225   "KILLAGENT\n"
2226   "\n"
2227   "If the agent has been started using a standard socket\n"
2228   "we allow a client to stop the agent.";
2229 static gpg_error_t
2230 cmd_killagent (assuan_context_t ctx, char *line)
2231 {
2232   ctrl_t ctrl = assuan_get_pointer (ctx);
2233
2234   (void)line;
2235
2236   if (!opt.use_standard_socket)
2237     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
2238
2239   ctrl->server_local->stopme = 1;
2240   return gpg_error (GPG_ERR_EOF);
2241 }
2242
2243
2244 static const char hlp_reloadagent[] =
2245   "RELOADAGENT\n"
2246   "\n"
2247   "This command is an alternative to SIGHUP\n"
2248   "to reload the configuration.";
2249 static gpg_error_t
2250 cmd_reloadagent (assuan_context_t ctx, char *line)
2251 {
2252   (void)ctx;
2253   (void)line;
2254
2255   agent_sighup_action ();
2256   return 0;
2257 }
2258
2259
2260 \f
2261 static const char hlp_getinfo[] =
2262   "GETINFO <what>\n"
2263   "\n"
2264   "Multipurpose function to return a variety of information.\n"
2265   "Supported values for WHAT are:\n"
2266   "\n"
2267   "  version     - Return the version of the program.\n"
2268   "  pid         - Return the process id of the server.\n"
2269   "  socket_name - Return the name of the socket.\n"
2270   "  ssh_socket_name - Return the name of the ssh socket.\n"
2271   "  scd_running - Return OK if the SCdaemon is already running.\n"
2272   "  s2k_count   - Return the calibrated S2K count.\n"
2273   "  std_session_env - List the standard session environment.\n"
2274   "  std_startup_env - List the standard startup environment.\n"
2275   "  cmd_has_option\n"
2276   "              - Returns OK if the command CMD implements the option OPT\n.";
2277 static gpg_error_t
2278 cmd_getinfo (assuan_context_t ctx, char *line)
2279 {
2280   ctrl_t ctrl = assuan_get_pointer (ctx);
2281   int rc = 0;
2282
2283   if (!strcmp (line, "version"))
2284     {
2285       const char *s = VERSION;
2286       rc = assuan_send_data (ctx, s, strlen (s));
2287     }
2288   else if (!strcmp (line, "pid"))
2289     {
2290       char numbuf[50];
2291
2292       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2293       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2294     }
2295   else if (!strcmp (line, "socket_name"))
2296     {
2297       const char *s = get_agent_socket_name ();
2298
2299       if (s)
2300         rc = assuan_send_data (ctx, s, strlen (s));
2301       else
2302         rc = gpg_error (GPG_ERR_NO_DATA);
2303     }
2304   else if (!strcmp (line, "ssh_socket_name"))
2305     {
2306       const char *s = get_agent_ssh_socket_name ();
2307
2308       if (s)
2309         rc = assuan_send_data (ctx, s, strlen (s));
2310       else
2311         rc = gpg_error (GPG_ERR_NO_DATA);
2312     }
2313   else if (!strcmp (line, "scd_running"))
2314     {
2315       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2316     }
2317   else if (!strcmp (line, "s2k_count"))
2318     {
2319       char numbuf[50];
2320
2321       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2322       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2323     }
2324   else if (!strcmp (line, "std_session_env")
2325            || !strcmp (line, "std_startup_env"))
2326     {
2327       int iterator;
2328       const char *name, *value;
2329       char *string;
2330
2331       iterator = 0;
2332       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2333         {
2334           value = session_env_getenv_or_default
2335             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2336           if (value)
2337             {
2338               string = xtryasprintf ("%s=%s", name, value);
2339               if (!string)
2340                 rc = gpg_error_from_syserror ();
2341               else
2342                 {
2343                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2344                   if (!rc)
2345                     rc = assuan_send_data (ctx, NULL, 0);
2346                 }
2347               if (rc)
2348                 break;
2349             }
2350         }
2351     }
2352   else if (!strncmp (line, "cmd_has_option", 14)
2353            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2354     {
2355       char *cmd, *cmdopt;
2356       line += 14;
2357       while (*line == ' ' || *line == '\t')
2358         line++;
2359       if (!*line)
2360         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2361       else
2362         {
2363           cmd = line;
2364           while (*line && (*line != ' ' && *line != '\t'))
2365             line++;
2366           if (!*line)
2367             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2368           else
2369             {
2370               *line++ = 0;
2371               while (*line == ' ' || *line == '\t')
2372                 line++;
2373               if (!*line)
2374                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2375               else
2376                 {
2377                   cmdopt = line;
2378                   if (!command_has_option (cmd, cmdopt))
2379                     rc = gpg_error (GPG_ERR_GENERAL);
2380                 }
2381             }
2382         }
2383     }
2384   else
2385     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2386   return rc;
2387 }
2388
2389
2390 \f
2391 static gpg_error_t
2392 option_handler (assuan_context_t ctx, const char *key, const char *value)
2393 {
2394   ctrl_t ctrl = assuan_get_pointer (ctx);
2395   gpg_error_t err = 0;
2396
2397   if (!strcmp (key, "agent-awareness"))
2398     {
2399       /* The value is a version string telling us of which agent
2400          version the caller is aware of.  */
2401       ctrl->server_local->allow_fully_canceled =
2402         gnupg_compare_version (value, "2.1.0");
2403     }
2404   else if (!strcmp (key, "putenv"))
2405     {
2406       /* Change the session's environment to be used for the
2407          Pinentry.  Valid values are:
2408           <NAME>            Delete envvar NAME
2409           <KEY>=            Set envvar NAME to the empty string
2410           <KEY>=<VALUE>     Set envvar NAME to VALUE
2411       */
2412       err = session_env_putenv (ctrl->session_env, value);
2413     }
2414   else if (!strcmp (key, "display"))
2415     {
2416       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2417     }
2418   else if (!strcmp (key, "ttyname"))
2419     {
2420       if (!opt.keep_tty)
2421         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2422     }
2423   else if (!strcmp (key, "ttytype"))
2424     {
2425       if (!opt.keep_tty)
2426         err = session_env_setenv (ctrl->session_env, "TERM", value);
2427     }
2428   else if (!strcmp (key, "lc-ctype"))
2429     {
2430       if (ctrl->lc_ctype)
2431         xfree (ctrl->lc_ctype);
2432       ctrl->lc_ctype = xtrystrdup (value);
2433       if (!ctrl->lc_ctype)
2434         return out_of_core ();
2435     }
2436   else if (!strcmp (key, "lc-messages"))
2437     {
2438       if (ctrl->lc_messages)
2439         xfree (ctrl->lc_messages);
2440       ctrl->lc_messages = xtrystrdup (value);
2441       if (!ctrl->lc_messages)
2442         return out_of_core ();
2443     }
2444   else if (!strcmp (key, "xauthority"))
2445     {
2446       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
2447     }
2448   else if (!strcmp (key, "pinentry-user-data"))
2449     {
2450       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
2451     }
2452   else if (!strcmp (key, "use-cache-for-signing"))
2453     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
2454   else if (!strcmp (key, "allow-pinentry-notify"))
2455     ctrl->server_local->allow_pinentry_notify = 1;
2456   else if (!strcmp (key, "pinentry-mode"))
2457     {
2458       if (!strcmp (value, "ask") || !strcmp (value, "default"))
2459         ctrl->pinentry_mode = PINENTRY_MODE_ASK;
2460       else if (!strcmp (value, "cancel"))
2461         ctrl->pinentry_mode = PINENTRY_MODE_CANCEL;
2462       else if (!strcmp (value, "error"))
2463         ctrl->pinentry_mode = PINENTRY_MODE_ERROR;
2464       else if (!strcmp (value, "loopback"))
2465         {
2466           if (opt.allow_loopback_pinentry)
2467             ctrl->pinentry_mode = PINENTRY_MODE_LOOPBACK;
2468           else
2469             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2470         }
2471       else
2472         err = gpg_error (GPG_ERR_INV_VALUE);
2473     }
2474   else if (!strcmp (key, "cache-ttl-opt-preset"))
2475     {
2476       ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
2477     }
2478   else if (!strcmp (key, "s2k-count"))
2479     {
2480       ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
2481       if (ctrl->s2k_count && ctrl->s2k_count < 65536) {
2482           ctrl->s2k_count = 0;
2483           err = gpg_error (GPG_ERR_INV_VALUE);
2484       }
2485     }
2486   else
2487     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2488
2489   return err;
2490 }
2491
2492
2493
2494 \f
2495 /* Called by libassuan after all commands. ERR is the error from the
2496    last assuan operation and not the one returned from the command. */
2497 static void
2498 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
2499 {
2500   ctrl_t ctrl = assuan_get_pointer (ctx);
2501
2502   (void)err;
2503
2504   /* Switch off any I/O monitor controlled logging pausing. */
2505   ctrl->server_local->pause_io_logging = 0;
2506 }
2507
2508
2509 /* This function is called by libassuan for all I/O.  We use it here
2510    to disable logging for the GETEVENTCOUNTER commands.  This is so
2511    that the debug output won't get cluttered by this primitive
2512    command.  */
2513 static unsigned int
2514 io_monitor (assuan_context_t ctx, void *hook, int direction,
2515             const char *line, size_t linelen)
2516 {
2517   ctrl_t ctrl = assuan_get_pointer (ctx);
2518
2519   (void) hook;
2520
2521   /* Note that we only check for the uppercase name.  This allows to
2522      see the logging for debugging if using a non-upercase command
2523      name. */
2524   if (ctx && direction == ASSUAN_IO_FROM_PEER
2525       && linelen >= 15
2526       && !strncmp (line, "GETEVENTCOUNTER", 15)
2527       && (linelen == 15 || spacep (line+15)))
2528     {
2529       ctrl->server_local->pause_io_logging = 1;
2530     }
2531
2532   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2533 }
2534
2535
2536 /* Return true if the command CMD implements the option OPT.  */
2537 static int
2538 command_has_option (const char *cmd, const char *cmdopt)
2539 {
2540   if (!strcmp (cmd, "GET_PASSPHRASE"))
2541     {
2542       if (!strcmp (cmdopt, "repeat"))
2543           return 1;
2544     }
2545
2546   return 0;
2547 }
2548
2549
2550 /* Tell the assuan library about our commands */
2551 static int
2552 register_commands (assuan_context_t ctx)
2553 {
2554   static struct {
2555     const char *name;
2556     assuan_handler_t handler;
2557     const char * const help;
2558   } table[] = {
2559     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2560     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2561     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2562     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2563     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2564     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2565     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2566     { "SETHASH",        cmd_sethash,   hlp_sethash },
2567     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2568     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2569     { "GENKEY",         cmd_genkey,    hlp_genkey },
2570     { "READKEY",        cmd_readkey,   hlp_readkey },
2571     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2572     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2573     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2574     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2575     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2576     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2577     { "LEARN",          cmd_learn,     hlp_learn },
2578     { "PASSWD",         cmd_passwd,    hlp_passwd },
2579     { "INPUT",          NULL },
2580     { "OUTPUT",         NULL },
2581     { "SCD",            cmd_scd,       hlp_scd },
2582     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
2583     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
2584     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
2585     { "GETVAL",         cmd_getval,    hlp_getval },
2586     { "PUTVAL",         cmd_putval,    hlp_putval },
2587     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2588     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2589     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2590     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2591     { NULL }
2592   };
2593   int i, rc;
2594
2595   for (i=0; table[i].name; i++)
2596     {
2597       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2598                                     table[i].help);
2599       if (rc)
2600         return rc;
2601     }
2602   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2603   assuan_register_reset_notify (ctx, reset_notify);
2604   assuan_register_option_handler (ctx, option_handler);
2605   return 0;
2606 }
2607
2608
2609 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2610    simple piper server, otherwise it is a regular server.  CTRL is the
2611    control structure for this connection; it has only the basic
2612    intialization. */
2613 void
2614 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2615 {
2616   int rc;
2617   assuan_context_t ctx = NULL;
2618
2619   rc = assuan_new (&ctx);
2620   if (rc)
2621     {
2622       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2623       agent_exit (2);
2624     }
2625
2626   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2627     {
2628       assuan_fd_t filedes[2];
2629
2630       filedes[0] = assuan_fdopen (0);
2631       filedes[1] = assuan_fdopen (1);
2632       rc = assuan_init_pipe_server (ctx, filedes);
2633     }
2634   else if (listen_fd != GNUPG_INVALID_FD)
2635     {
2636       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2637       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2638          this branch is currently not used.  */
2639     }
2640   else
2641     {
2642       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2643     }
2644   if (rc)
2645     {
2646       log_error ("failed to initialize the server: %s\n",
2647                  gpg_strerror(rc));
2648       agent_exit (2);
2649     }
2650   rc = register_commands (ctx);
2651   if (rc)
2652     {
2653       log_error ("failed to register commands with Assuan: %s\n",
2654                  gpg_strerror(rc));
2655       agent_exit (2);
2656     }
2657
2658   assuan_set_pointer (ctx, ctrl);
2659   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2660   ctrl->server_local->assuan_ctx = ctx;
2661   ctrl->server_local->message_fd = -1;
2662   ctrl->server_local->use_cache_for_signing = 1;
2663   ctrl->digest.raw_value = 0;
2664
2665   assuan_set_io_monitor (ctx, io_monitor, NULL);
2666
2667   for (;;)
2668     {
2669       rc = assuan_accept (ctx);
2670       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
2671         {
2672           break;
2673         }
2674       else if (rc)
2675         {
2676           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2677           break;
2678         }
2679
2680       rc = assuan_process (ctx);
2681       if (rc)
2682         {
2683           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2684           continue;
2685         }
2686     }
2687
2688   /* Reset the nonce caches.  */
2689   clear_nonce_cache (ctrl);
2690
2691   /* Reset the SCD if needed. */
2692   agent_reset_scd (ctrl);
2693
2694   /* Reset the pinentry (in case of popup messages). */
2695   agent_reset_query (ctrl);
2696
2697   /* Cleanup.  */
2698   assuan_release (ctx);
2699   xfree (ctrl->server_local->keydesc);
2700   xfree (ctrl->server_local->import_key);
2701   xfree (ctrl->server_local->export_key);
2702   if (ctrl->server_local->stopme)
2703     agent_exit (0);
2704   xfree (ctrl->server_local);
2705   ctrl->server_local = NULL;
2706 }