Added option --inquire to PRESET_PASSPHRASE. Note that the inquired passphrase will...
[gnupg.git] / agent / command.c
1 /* command.c - gpg-agent command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3  *               2006, 2008, 2009, 2010  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] [<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 static gpg_error_t
848 cmd_genkey (assuan_context_t ctx, char *line)
849 {
850   ctrl_t ctrl = assuan_get_pointer (ctx);
851   int rc;
852   int no_protection;
853   unsigned char *value;
854   size_t valuelen;
855   membuf_t outbuf;
856   char *cache_nonce = NULL;
857   char *p;
858
859   no_protection = has_option (line, "--no-protection");
860   line = skip_options (line);
861
862   p = line;
863   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
864     ;
865   *p = '\0';
866   if (*line)
867     cache_nonce = xtrystrdup (line);
868
869   /* First inquire the parameters */
870   rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
871   if (rc)
872     return rc;
873
874   init_membuf (&outbuf, 512);
875
876   rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
877                      &outbuf);
878   xfree (value);
879   if (rc)
880     clear_outbuf (&outbuf);
881   else
882     rc = write_and_clear_outbuf (ctx, &outbuf);
883   xfree (cache_nonce);
884   return leave_cmd (ctx, rc);
885 }
886
887
888
889 \f
890 static const char hlp_readkey[] =
891   "READKEY <hexstring_with_keygrip>\n"
892   "\n"
893   "Return the public key for the given keygrip.";
894 static gpg_error_t
895 cmd_readkey (assuan_context_t ctx, char *line)
896 {
897   ctrl_t ctrl = assuan_get_pointer (ctx);
898   int rc;
899   unsigned char grip[20];
900   gcry_sexp_t s_pkey = NULL;
901
902   rc = parse_keygrip (ctx, line, grip);
903   if (rc)
904     return rc; /* Return immediately as this is already an Assuan error code.*/
905
906   rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
907   if (!rc)
908     {
909       size_t len;
910       unsigned char *buf;
911
912       len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
913       assert (len);
914       buf = xtrymalloc (len);
915       if (!buf)
916         rc = gpg_error_from_syserror ();
917       else
918         {
919           len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
920           assert (len);
921           rc = assuan_send_data (ctx, buf, len);
922           xfree (buf);
923         }
924       gcry_sexp_release (s_pkey);
925     }
926
927   return leave_cmd (ctx, rc);
928 }
929
930
931 \f
932 static const char hlp_keyinfo[] =
933   "KEYINFO [--list] [--data] <keygrip>\n"
934   "\n"
935   "Return information about the key specified by the KEYGRIP.  If the\n"
936   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
937   "--list is given the keygrip is ignored and information about all\n"
938   "available keys are returned.  The information is returned as a\n"
939   "status line unless --data was specified, with this format:\n"
940   "\n"
941   "  KEYINFO <keygrip> <type> <serialno> <idstr> <cached>\n"
942   "\n"
943   "KEYGRIP is the keygrip.\n"
944   "\n"
945   "TYPE is describes the type of the key:\n"
946   "    'D' - Regular key stored on disk,\n"
947   "    'T' - Key is stored on a smartcard (token),\n"
948   "    '-' - Unknown type.\n"
949   "\n"
950   "SERIALNO is an ASCII string with the serial number of the\n"
951   "         smartcard.  If the serial number is not known a single\n"
952   "         dash '-' is used instead.\n"
953   "\n"
954   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
955   "      is not known a dash is used instead.\n"
956   "\n"
957   "CACHED is 1 if the passphrase for the key was found in the key cache.\n"
958   "       If not, a '-' is used instead.\n"
959   "\n"
960   "More information may be added in the future.";
961 static gpg_error_t
962 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
963                 int data)
964 {
965   gpg_error_t err;
966   char hexgrip[40+1];
967   int keytype;
968   unsigned char *shadow_info = NULL;
969   char *serialno = NULL;
970   char *idstr = NULL;
971   const char *keytypestr;
972   const char *cached;
973   char *pw;
974
975   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
976   if (err)
977     goto leave;
978
979   /* Reformat the grip so that we use uppercase as good style. */
980   bin2hex (grip, 20, hexgrip);
981
982   if (keytype == PRIVATE_KEY_CLEAR
983       || keytype == PRIVATE_KEY_PROTECTED)
984     keytypestr = "D";
985   else if (keytype == PRIVATE_KEY_SHADOWED)
986     keytypestr = "T";
987   else
988     keytypestr = "-";
989
990   /* Here we have a little race by doing the cache check separately
991      from the retrieval function.  Given that the cache flag is only a
992      hint, it should not really matter.  */
993   pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
994   cached = pw ? "1" : "-";
995   xfree (pw);
996
997   if (shadow_info)
998     {
999       err = parse_shadow_info (shadow_info, &serialno, &idstr);
1000       if (err)
1001         goto leave;
1002     }
1003
1004   if (!data)
1005     err = agent_write_status (ctrl, "KEYINFO",
1006                               hexgrip,
1007                               keytypestr,
1008                               serialno? serialno : "-",
1009                               idstr? idstr : "-",
1010                               cached,
1011                               NULL);
1012   else
1013     {
1014       char *string;
1015
1016       string = xtryasprintf ("%s %s %s %s %s\n",
1017                              hexgrip, keytypestr,
1018                              serialno? serialno : "-",
1019                              idstr? idstr : "-", cached);
1020       if (!string)
1021         err = gpg_error_from_syserror ();
1022       else
1023         err = assuan_send_data (ctx, string, strlen(string));
1024       xfree (string);
1025     }
1026
1027  leave:
1028   xfree (shadow_info);
1029   xfree (serialno);
1030   xfree (idstr);
1031   return err;
1032 }
1033
1034
1035 static gpg_error_t
1036 cmd_keyinfo (assuan_context_t ctx, char *line)
1037 {
1038   ctrl_t ctrl = assuan_get_pointer (ctx);
1039   int err;
1040   unsigned char grip[20];
1041   DIR *dir = NULL;
1042   int list_mode;
1043   int opt_data;
1044
1045   list_mode = has_option (line, "--list");
1046   opt_data = has_option (line, "--data");
1047   line = skip_options (line);
1048
1049   if (list_mode)
1050     {
1051       char *dirname;
1052       struct dirent *dir_entry;
1053       char hexgrip[41];
1054
1055       dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1056       if (!dirname)
1057         {
1058           err = gpg_error_from_syserror ();
1059           goto leave;
1060         }
1061       dir = opendir (dirname);
1062       if (!dir)
1063         {
1064           err = gpg_error_from_syserror ();
1065           xfree (dirname);
1066           goto leave;
1067         }
1068       xfree (dirname);
1069
1070       while ( (dir_entry = readdir (dir)) )
1071         {
1072           if (strlen (dir_entry->d_name) != 44
1073               || strcmp (dir_entry->d_name + 40, ".key"))
1074             continue;
1075           strncpy (hexgrip, dir_entry->d_name, 40);
1076           hexgrip[40] = 0;
1077
1078           if ( hex2bin (hexgrip, grip, 20) < 0 )
1079             continue; /* Bad hex string.  */
1080
1081           err = do_one_keyinfo (ctrl, grip, ctx, opt_data);
1082           if (err)
1083             goto leave;
1084         }
1085       err = 0;
1086     }
1087   else
1088     {
1089       err = parse_keygrip (ctx, line, grip);
1090       if (err)
1091         goto leave;
1092       err = do_one_keyinfo (ctrl, grip, ctx, opt_data);
1093     }
1094
1095  leave:
1096   if (dir)
1097     closedir (dir);
1098   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1099     leave_cmd (ctx, err);
1100   return err;
1101 }
1102
1103
1104 \f
1105 static int
1106 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1107 {
1108   size_t n;
1109   int rc;
1110
1111   assuan_begin_confidential (ctx);
1112   n = strlen (pw);
1113   if (via_data)
1114     rc = assuan_send_data (ctx, pw, n);
1115   else
1116     {
1117       char *p = xtrymalloc_secure (n*2+1);
1118       if (!p)
1119         rc = gpg_error_from_syserror ();
1120       else
1121         {
1122           bin2hex (pw, n, p);
1123           rc = assuan_set_okay_line (ctx, p);
1124           xfree (p);
1125         }
1126     }
1127   return rc;
1128 }
1129
1130
1131 static const char hlp_get_passphrase[] =
1132   "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1133   "               [--qualitybar] <cache_id>\n"
1134   "               [<error_message> <prompt> <description>]\n"
1135   "\n"
1136   "This function is usually used to ask for a passphrase to be used\n"
1137   "for conventional encryption, but may also be used by programs which\n"
1138   "need specal handling of passphrases.  This command uses a syntax\n"
1139   "which helps clients to use the agent with minimum effort.  The\n"
1140   "agent either returns with an error or with a OK followed by the hex\n"
1141   "encoded passphrase.  Note that the length of the strings is\n"
1142   "implicitly limited by the maximum length of a command.\n"
1143   "\n"
1144   "If the option \"--data\" is used the passphrase is returned by usual\n"
1145   "data lines and not on the okay line.\n"
1146   "\n"
1147   "If the option \"--check\" is used the passphrase constraints checks as\n"
1148   "implemented by gpg-agent are applied.  A check is not done if the\n"
1149   "passphrase has been found in the cache.\n"
1150   "\n"
1151   "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1152   "cache the user will not be asked to enter a passphrase but the error\n"
1153   "code GPG_ERR_NO_DATA is returned.  \n"
1154   "\n"
1155   "If the option \"--qualitybar\" is used a visual indication of the\n"
1156   "entered passphrase quality is shown.  (Unless no minimum passphrase\n"
1157   "length has been configured.)";
1158 static gpg_error_t
1159 cmd_get_passphrase (assuan_context_t ctx, char *line)
1160 {
1161   ctrl_t ctrl = assuan_get_pointer (ctx);
1162   int rc;
1163   char *pw;
1164   char *response;
1165   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1166   const char *desc2 = _("Please re-enter this passphrase");
1167   char *p;
1168   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1169   int opt_repeat = 0;
1170   char *repeat_errtext = NULL;
1171
1172   opt_data = has_option (line, "--data");
1173   opt_check = has_option (line, "--check");
1174   opt_no_ask = has_option (line, "--no-ask");
1175   if (has_option_name (line, "--repeat"))
1176     {
1177       p = option_value (line, "--repeat");
1178       if (p)
1179         opt_repeat = atoi (p);
1180       else
1181         opt_repeat = 1;
1182     }
1183   opt_qualbar = has_option (line, "--qualitybar");
1184   line = skip_options (line);
1185
1186   cacheid = line;
1187   p = strchr (cacheid, ' ');
1188   if (p)
1189     {
1190       *p++ = 0;
1191       while (*p == ' ')
1192         p++;
1193       errtext = p;
1194       p = strchr (errtext, ' ');
1195       if (p)
1196         {
1197           *p++ = 0;
1198           while (*p == ' ')
1199             p++;
1200           prompt = p;
1201           p = strchr (prompt, ' ');
1202           if (p)
1203             {
1204               *p++ = 0;
1205               while (*p == ' ')
1206                 p++;
1207               desc = p;
1208               p = strchr (desc, ' ');
1209               if (p)
1210                 *p = 0; /* Ignore trailing garbage. */
1211             }
1212         }
1213     }
1214   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1215     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1216   if (!desc)
1217     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1218
1219   if (!strcmp (cacheid, "X"))
1220     cacheid = NULL;
1221   if (!strcmp (errtext, "X"))
1222     errtext = NULL;
1223   if (!strcmp (prompt, "X"))
1224     prompt = NULL;
1225   if (!strcmp (desc, "X"))
1226     desc = NULL;
1227
1228   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL) : NULL;
1229   if (pw)
1230     {
1231       rc = send_back_passphrase (ctx, opt_data, pw);
1232       xfree (pw);
1233     }
1234   else if (opt_no_ask)
1235     rc = gpg_error (GPG_ERR_NO_DATA);
1236   else
1237     {
1238       /* Note, that we only need to replace the + characters and
1239          should leave the other escaping in place because the escaped
1240          string is send verbatim to the pinentry which does the
1241          unescaping (but not the + replacing) */
1242       if (errtext)
1243         plus_to_blank (errtext);
1244       if (prompt)
1245         plus_to_blank (prompt);
1246       if (desc)
1247         plus_to_blank (desc);
1248
1249     next_try:
1250       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1251                                  repeat_errtext? repeat_errtext:errtext,
1252                                  opt_qualbar);
1253       xfree (repeat_errtext);
1254       repeat_errtext = NULL;
1255       if (!rc)
1256         {
1257           int i;
1258
1259           if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1260             {
1261               xfree (response);
1262               goto next_try;
1263             }
1264           for (i = 0; i < opt_repeat; i++)
1265             {
1266               char *response2;
1267
1268               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1269                                          errtext, 0);
1270               if (rc)
1271                 break;
1272               if (strcmp (response2, response))
1273                 {
1274                   xfree (response2);
1275                   xfree (response);
1276                   repeat_errtext = try_percent_escape
1277                     (_("does not match - try again"), NULL);
1278                   if (!repeat_errtext)
1279                     {
1280                       rc = gpg_error_from_syserror ();
1281                       break;
1282                     }
1283                   goto next_try;
1284                 }
1285               xfree (response2);
1286             }
1287           if (!rc)
1288             {
1289               if (cacheid)
1290                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1291               rc = send_back_passphrase (ctx, opt_data, response);
1292             }
1293           xfree (response);
1294         }
1295     }
1296
1297   return leave_cmd (ctx, rc);
1298 }
1299
1300
1301 static const char hlp_clear_passphrase[] =
1302   "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
1303   "\n"
1304   "may be used to invalidate the cache entry for a passphrase.  The\n"
1305   "function returns with OK even when there is no cached passphrase.\n"
1306   "The --mode=normal option is used to clear an entry for a cacheid\n"
1307   "added by the agent.\n";
1308 static gpg_error_t
1309 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1310 {
1311   char *cacheid = NULL;
1312   char *p;
1313   int opt_normal;
1314
1315   opt_normal = has_option (line, "--mode=normal");
1316   line = skip_options (line);
1317
1318   /* parse the stuff */
1319   for (p=line; *p == ' '; p++)
1320     ;
1321   cacheid = p;
1322   p = strchr (cacheid, ' ');
1323   if (p)
1324     *p = 0; /* ignore garbage */
1325   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1326     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1327
1328   agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
1329                    NULL, 0);
1330   return 0;
1331 }
1332
1333
1334 static const char hlp_get_confirmation[] =
1335   "GET_CONFIRMATION <description>\n"
1336   "\n"
1337   "This command may be used to ask for a simple confirmation.\n"
1338   "DESCRIPTION is displayed along with a Okay and Cancel button.  This\n"
1339   "command uses a syntax which helps clients to use the agent with\n"
1340   "minimum effort.  The agent either returns with an error or with a\n"
1341   "OK.  Note, that the length of DESCRIPTION is implicitly limited by\n"
1342   "the maximum length of a command. DESCRIPTION should not contain\n"
1343   "any spaces, those must be encoded either percent escaped or simply\n"
1344   "as '+'.";
1345 static gpg_error_t
1346 cmd_get_confirmation (assuan_context_t ctx, char *line)
1347 {
1348   ctrl_t ctrl = assuan_get_pointer (ctx);
1349   int rc;
1350   char *desc = NULL;
1351   char *p;
1352
1353   /* parse the stuff */
1354   for (p=line; *p == ' '; p++)
1355     ;
1356   desc = p;
1357   p = strchr (desc, ' ');
1358   if (p)
1359     *p = 0; /* We ignore any garbage -may be later used for other args. */
1360
1361   if (!desc || !*desc)
1362     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1363
1364   if (!strcmp (desc, "X"))
1365     desc = NULL;
1366
1367   /* Note, that we only need to replace the + characters and should
1368      leave the other escaping in place because the escaped string is
1369      send verbatim to the pinentry which does the unescaping (but not
1370      the + replacing) */
1371   if (desc)
1372     plus_to_blank (desc);
1373
1374   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1375   return leave_cmd (ctx, rc);
1376 }
1377
1378
1379 \f
1380 static const char hlp_learn[] =
1381   "LEARN [--send]\n"
1382   "\n"
1383   "Learn something about the currently inserted smartcard.  With\n"
1384   "--send the new certificates are send back.";
1385 static gpg_error_t
1386 cmd_learn (assuan_context_t ctx, char *line)
1387 {
1388   ctrl_t ctrl = assuan_get_pointer (ctx);
1389   int rc;
1390
1391   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1392   return leave_cmd (ctx, rc);
1393 }
1394
1395
1396 \f
1397 static const char hlp_passwd[] =
1398   "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] <hexstring_with_keygrip>\n"
1399   "\n"
1400   "Change the passphrase/PIN for the key identified by keygrip in LINE.";
1401 static gpg_error_t
1402 cmd_passwd (assuan_context_t ctx, char *line)
1403 {
1404   ctrl_t ctrl = assuan_get_pointer (ctx);
1405   gpg_error_t err;
1406   int c;
1407   char *cache_nonce = NULL;
1408   char *passwd_nonce = NULL;
1409   unsigned char grip[20];
1410   gcry_sexp_t s_skey = NULL;
1411   unsigned char *shadow_info = NULL;
1412   char *passphrase = NULL;
1413   char *pend;
1414
1415   cache_nonce = option_value (line, "--cache-nonce");
1416   if (cache_nonce)
1417     {
1418       for (pend = cache_nonce; *pend && !spacep (pend); pend++)
1419         ;
1420       c = *pend;
1421       *pend = '\0';
1422       cache_nonce = xtrystrdup (cache_nonce);
1423       *pend = c;
1424       if (!cache_nonce)
1425         {
1426           err = gpg_error_from_syserror ();
1427           goto leave;
1428         }
1429     }
1430
1431   passwd_nonce = option_value (line, "--passwd-nonce");
1432   if (passwd_nonce)
1433     {
1434       for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
1435         ;
1436       c = *pend;
1437       *pend = '\0';
1438       passwd_nonce = xtrystrdup (passwd_nonce);
1439       *pend = c;
1440       if (!passwd_nonce)
1441         {
1442           err = gpg_error_from_syserror ();
1443           goto leave;
1444         }
1445     }
1446
1447   line = skip_options (line);
1448
1449   err = parse_keygrip (ctx, line, grip);
1450   if (err)
1451     goto leave;
1452
1453   ctrl->in_passwd++;
1454   err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc,
1455                              grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1456                              &s_skey, &passphrase);
1457   if (err)
1458     ;
1459   else if (!s_skey)
1460     {
1461       log_error ("changing a smartcard PIN is not yet supported\n");
1462       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1463     }
1464   else
1465     {
1466       char *newpass = NULL;
1467
1468       if (passwd_nonce)
1469         newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
1470       err = agent_protect_and_store (ctrl, s_skey, &newpass);
1471       if (!err && passphrase)
1472         {
1473           /* A passphrase existed on the old key and the change was
1474              successful.  Return a nonce for that old passphrase to
1475              let the caller try to unprotect the other subkeys with
1476              the same key.  */
1477           if (!cache_nonce)
1478             {
1479               char buf[12];
1480               gcry_create_nonce (buf, 12);
1481               cache_nonce = bin2hex (buf, 12, NULL);
1482             }
1483           if (cache_nonce
1484               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1485                                    passphrase, 120 /*seconds*/))
1486             {
1487               assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1488               xfree (ctrl->server_local->last_cache_nonce);
1489               ctrl->server_local->last_cache_nonce = cache_nonce;
1490               cache_nonce = NULL;
1491             }
1492           if (newpass)
1493             {
1494               /* If we have a new passphrase (which might be empty) we
1495                  store it under a passwd nonce so that the caller may
1496                  send that nonce again to use it for another key. */
1497               if (!passwd_nonce)
1498                 {
1499                   char buf[12];
1500                   gcry_create_nonce (buf, 12);
1501                   passwd_nonce = bin2hex (buf, 12, NULL);
1502                 }
1503               if (passwd_nonce
1504                   && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1505                                        newpass, 120 /*seconds*/))
1506                 {
1507                   assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1508                   xfree (ctrl->server_local->last_passwd_nonce);
1509                   ctrl->server_local->last_passwd_nonce = passwd_nonce;
1510                   passwd_nonce = NULL;
1511                 }
1512             }
1513         }
1514       xfree (newpass);
1515     }
1516   ctrl->in_passwd--;
1517
1518   xfree (ctrl->server_local->keydesc);
1519   ctrl->server_local->keydesc = NULL;
1520
1521  leave:
1522   xfree (passphrase);
1523   gcry_sexp_release (s_skey);
1524   xfree (shadow_info);
1525   xfree (cache_nonce);
1526   return leave_cmd (ctx, err);
1527 }
1528
1529
1530 static const char hlp_preset_passphrase[] =
1531   "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n"
1532   "\n"
1533   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1534   "to passwd for the given time, where -1 means infinite and 0 means\n"
1535   "the default (currently only a timeout of -1 is allowed, which means\n"
1536   "to never expire it).  If passwd is not provided, ask for it via the\n"
1537   "pinentry module unless --inquire is passed in which case the passphrase\n"
1538   "is retrieved from the client via a server inquire.\n";
1539 static gpg_error_t
1540 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1541 {
1542   int rc;
1543   char *grip_clear = NULL;
1544   unsigned char *passphrase = NULL;
1545   int ttl;
1546   size_t len;
1547   int opt_inquire;
1548
1549   if (!opt.allow_preset_passphrase)
1550     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1551
1552   opt_inquire = has_option (line, "--inquire");
1553   line = skip_options (line);
1554   grip_clear = line;
1555   while (*line && (*line != ' ' && *line != '\t'))
1556     line++;
1557   if (!*line)
1558     return gpg_error (GPG_ERR_MISSING_VALUE);
1559   *line = '\0';
1560   line++;
1561   while (*line && (*line == ' ' || *line == '\t'))
1562     line++;
1563
1564   /* Currently, only infinite timeouts are allowed.  */
1565   ttl = -1;
1566   if (line[0] != '-' || line[1] != '1')
1567     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1568   line++;
1569   line++;
1570   while (!(*line != ' ' && *line != '\t'))
1571     line++;
1572
1573   /* Syntax check the hexstring.  */
1574   len = 0;
1575   rc = parse_hexstring (ctx, line, &len);
1576   if (rc)
1577     return rc;
1578   line[len] = '\0';
1579
1580   /* If there is a passphrase, use it.  Currently, a passphrase is
1581      required.  */
1582   if (*line)
1583     {
1584       if (opt_inquire)
1585         {
1586           rc = set_error (GPG_ERR_ASS_PARAMETER,
1587                           "both --inquire and passphrase specified");
1588           goto leave;
1589         }
1590
1591       /* Do in-place conversion.  */
1592       passphrase = line;
1593       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1594         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1595     }
1596   else if (opt_inquire)
1597     {
1598       /* Note that the passphrase will be truncated at any null byte and the
1599        * limit is 480 characters. */
1600       rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, 480);
1601     }
1602   else
1603     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1604
1605   if (!rc)
1606     {
1607       rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1608       if (opt_inquire)
1609         xfree (passphrase);
1610     }
1611
1612 leave:
1613   return leave_cmd (ctx, rc);
1614 }
1615
1616
1617 \f
1618 static const char hlp_scd[] =
1619   "SCD <commands to pass to the scdaemon>\n"
1620   " \n"
1621   "This is a general quote command to redirect everything to the\n"
1622   "SCdaemon.";
1623 static gpg_error_t
1624 cmd_scd (assuan_context_t ctx, char *line)
1625 {
1626   ctrl_t ctrl = assuan_get_pointer (ctx);
1627   int rc;
1628
1629   rc = divert_generic_cmd (ctrl, line, ctx);
1630
1631   return rc;
1632 }
1633
1634
1635 \f
1636 static const char hlp_keywrap_key[] =
1637   "KEYWRAP_KEY [--clear] <mode>\n"
1638   "\n"
1639   "Return a key to wrap another key.  For now the key is returned\n"
1640   "verbatim and and thus makes not much sense because an eavesdropper on\n"
1641   "the gpg-agent connection will see the key as well as the wrapped key.\n"
1642   "However, this function may either be equipped with a public key\n"
1643   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
1644   "case wrapping the import and export of keys is a requirement for\n"
1645   "certain cryptographic validations and thus useful.  The key persists\n"
1646   "a RESET command but may be cleared using the option --clear.\n"
1647   "\n"
1648   "Supported modes are:\n"
1649   "  --import  - Return a key to import a key into gpg-agent\n"
1650   "  --export  - Return a key to export a key from gpg-agent";
1651 static gpg_error_t
1652 cmd_keywrap_key (assuan_context_t ctx, char *line)
1653 {
1654   ctrl_t ctrl = assuan_get_pointer (ctx);
1655   gpg_error_t err = 0;
1656   int clearopt = has_option (line, "--clear");
1657
1658
1659   assuan_begin_confidential (ctx);
1660   if (has_option (line, "--import"))
1661     {
1662       xfree (ctrl->server_local->import_key);
1663       if (clearopt)
1664         ctrl->server_local->import_key = NULL;
1665       else if (!(ctrl->server_local->import_key =
1666                  gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1667         err = gpg_error_from_syserror ();
1668       else
1669         err = assuan_send_data (ctx, ctrl->server_local->import_key,
1670                                 KEYWRAP_KEYSIZE);
1671     }
1672   else if (has_option (line, "--export"))
1673     {
1674       xfree (ctrl->server_local->export_key);
1675       if (clearopt)
1676         ctrl->server_local->export_key = NULL;
1677       else if (!(ctrl->server_local->export_key =
1678             gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1679         err = gpg_error_from_syserror ();
1680       else
1681         err = assuan_send_data (ctx, ctrl->server_local->export_key,
1682                                 KEYWRAP_KEYSIZE);
1683     }
1684   else
1685     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
1686   assuan_end_confidential (ctx);
1687
1688   return leave_cmd (ctx, err);
1689 }
1690
1691
1692 \f
1693 static const char hlp_import_key[] =
1694   "IMPORT_KEY [<cache_nonce>]\n"
1695   "\n"
1696   "Import a secret key into the key store.  The key is expected to be\n"
1697   "encrypted using the current session's key wrapping key (cf. command\n"
1698   "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
1699   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
1700   "key data.  The unwrapped key must be a canonical S-expression.";
1701 static gpg_error_t
1702 cmd_import_key (assuan_context_t ctx, char *line)
1703 {
1704   ctrl_t ctrl = assuan_get_pointer (ctx);
1705   gpg_error_t err;
1706   unsigned char *wrappedkey = NULL;
1707   size_t wrappedkeylen;
1708   gcry_cipher_hd_t cipherhd = NULL;
1709   unsigned char *key = NULL;
1710   size_t keylen, realkeylen;
1711   char *passphrase = NULL;
1712   unsigned char *finalkey = NULL;
1713   size_t finalkeylen;
1714   unsigned char grip[20];
1715   gcry_sexp_t openpgp_sexp = NULL;
1716   char *cache_nonce = NULL;
1717   char *p;
1718
1719   if (!ctrl->server_local->import_key)
1720     {
1721       err = gpg_error (GPG_ERR_MISSING_KEY);
1722       goto leave;
1723     }
1724
1725   p = line;
1726   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
1727     ;
1728   *p = '\0';
1729   if (*line)
1730     cache_nonce = xtrystrdup (line);
1731
1732   assuan_begin_confidential (ctx);
1733   err = assuan_inquire (ctx, "KEYDATA",
1734                         &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
1735   assuan_end_confidential (ctx);
1736   if (err)
1737     goto leave;
1738   if (wrappedkeylen < 24)
1739     {
1740       err = gpg_error (GPG_ERR_INV_LENGTH);
1741       goto leave;
1742     }
1743   keylen = wrappedkeylen - 8;
1744   key = xtrymalloc_secure (keylen);
1745   if (!key)
1746     {
1747       err = gpg_error_from_syserror ();
1748       goto leave;
1749     }
1750
1751   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1752                           GCRY_CIPHER_MODE_AESWRAP, 0);
1753   if (err)
1754     goto leave;
1755   err = gcry_cipher_setkey (cipherhd,
1756                             ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
1757   if (err)
1758     goto leave;
1759   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
1760   if (err)
1761     goto leave;
1762   gcry_cipher_close (cipherhd);
1763   cipherhd = NULL;
1764   xfree (wrappedkey);
1765   wrappedkey = NULL;
1766
1767   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1768   if (!realkeylen)
1769     goto leave; /* Invalid canonical encoded S-expression.  */
1770
1771   err = keygrip_from_canon_sexp (key, realkeylen, grip);
1772   if (err)
1773     {
1774       /* This might be due to an unsupported S-expression format.
1775          Check whether this is openpgp-private-key and trigger that
1776          import code.  */
1777       if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
1778         {
1779           const char *tag;
1780           size_t taglen;
1781
1782           tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
1783           if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
1784             ;
1785           else
1786             {
1787               gcry_sexp_release (openpgp_sexp);
1788               openpgp_sexp = NULL;
1789             }
1790         }
1791       if (!openpgp_sexp)
1792         goto leave; /* Note that ERR is still set.  */
1793     }
1794
1795
1796   if (openpgp_sexp)
1797     {
1798       /* In most cases the key is encrypted and thus the conversion
1799          function from the OpenPGP format to our internal format will
1800          ask for a passphrase.  That passphrase will be returned and
1801          used to protect the key using the same code as for regular
1802          key import. */
1803
1804       err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
1805                                   ctrl->server_local->keydesc, cache_nonce,
1806                                   &key, &passphrase);
1807       if (err)
1808         goto leave;
1809       realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1810       if (!realkeylen)
1811         goto leave; /* Invalid canonical encoded S-expression.  */
1812       if (passphrase)
1813         {
1814           if (!cache_nonce)
1815             {
1816               char buf[12];
1817               gcry_create_nonce (buf, 12);
1818               cache_nonce = bin2hex (buf, 12, NULL);
1819             }
1820           if (cache_nonce
1821               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1822                                    passphrase, 120 /*seconds*/))
1823             assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1824         }
1825     }
1826   else
1827     {
1828       if (!agent_key_available (grip))
1829         err = gpg_error (GPG_ERR_EEXIST);
1830       else
1831         err = agent_ask_new_passphrase
1832           (ctrl, _("Please enter the passphrase to protect the "
1833                    "imported object within the GnuPG system."),
1834            &passphrase);
1835       if (err)
1836         goto leave;
1837     }
1838
1839   if (passphrase)
1840     {
1841       err = agent_protect (key, passphrase, &finalkey, &finalkeylen);
1842       if (!err)
1843         err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
1844     }
1845   else
1846     err = agent_write_private_key (grip, key, realkeylen, 0);
1847
1848  leave:
1849   gcry_sexp_release (openpgp_sexp);
1850   xfree (finalkey);
1851   xfree (passphrase);
1852   xfree (key);
1853   gcry_cipher_close (cipherhd);
1854   xfree (wrappedkey);
1855   xfree (cache_nonce);
1856   xfree (ctrl->server_local->keydesc);
1857   ctrl->server_local->keydesc = NULL;
1858   return leave_cmd (ctx, err);
1859 }
1860
1861
1862 \f
1863 static const char hlp_export_key[] =
1864   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
1865   "\n"
1866   "Export a secret key from the key store.  The key will be encrypted\n"
1867   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
1868   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
1869   "prior to using this command.  The function takes the keygrip as argument.\n";
1870 static gpg_error_t
1871 cmd_export_key (assuan_context_t ctx, char *line)
1872 {
1873   ctrl_t ctrl = assuan_get_pointer (ctx);
1874   gpg_error_t err;
1875   unsigned char grip[20];
1876   gcry_sexp_t s_skey = NULL;
1877   unsigned char *key = NULL;
1878   size_t keylen;
1879   gcry_cipher_hd_t cipherhd = NULL;
1880   unsigned char *wrappedkey = NULL;
1881   size_t wrappedkeylen;
1882   int openpgp;
1883   char *cache_nonce;
1884   char *passphrase = NULL;
1885
1886   openpgp = has_option (line, "--openpgp");
1887   cache_nonce = option_value (line, "--cache-nonce");
1888   if (cache_nonce)
1889     {
1890       for (; *line && !spacep (line); line++)
1891         ;
1892       if (*line)
1893         *line++ = '\0';
1894       cache_nonce = xtrystrdup (cache_nonce);
1895       if (!cache_nonce)
1896         {
1897           err = gpg_error_from_syserror ();
1898           goto leave;
1899         }
1900     }
1901   line = skip_options (line);
1902
1903   if (!ctrl->server_local->export_key)
1904     {
1905       err = gpg_error (GPG_ERR_MISSING_KEY);
1906       goto leave;
1907     }
1908
1909   err = parse_keygrip (ctx, line, grip);
1910   if (err)
1911     goto leave;
1912
1913   if (agent_key_available (grip))
1914     {
1915       err = gpg_error (GPG_ERR_NO_SECKEY);
1916       goto leave;
1917     }
1918
1919   /* Get the key from the file.  With the openpgp flag we also ask for
1920      the passphrase so that we can use it to re-encrypt it.  */
1921   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
1922                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
1923                              openpgp ? &passphrase : NULL);
1924   if (err)
1925     goto leave;
1926   if (!s_skey)
1927     {
1928       /* Key is on a smartcard.  Actually we should not see this here
1929          because we do not pass a shadow_info variable to the above
1930          function, thus it will return this error directly.  */
1931       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
1932       goto leave;
1933     }
1934
1935   if (openpgp)
1936     {
1937       /* The openpgp option changes the key format into the OpenPGP
1938          key transfer format.  The result is already a padded
1939          canonical S-expression.  */
1940       if (!passphrase)
1941         {
1942           err = agent_ask_new_passphrase
1943             (ctrl, _("This key (or subkey) is not protected with a passphrase."
1944                      "  Please enter a new passphrase to export it."),
1945              &passphrase);
1946           if (err)
1947             goto leave;
1948         }
1949       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
1950     }
1951   else
1952     {
1953       /* Convert into a canonical S-expression and wrap that.  */
1954       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
1955     }
1956   if (err)
1957     goto leave;
1958   gcry_sexp_release (s_skey);
1959   s_skey = NULL;
1960
1961   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1962                           GCRY_CIPHER_MODE_AESWRAP, 0);
1963   if (err)
1964     goto leave;
1965   err = gcry_cipher_setkey (cipherhd,
1966                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
1967   if (err)
1968     goto leave;
1969
1970   wrappedkeylen = keylen + 8;
1971   wrappedkey = xtrymalloc (wrappedkeylen);
1972   if (!wrappedkey)
1973     {
1974       err = gpg_error_from_syserror ();
1975       goto leave;
1976     }
1977
1978   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
1979   if (err)
1980     goto leave;
1981   xfree (key);
1982   key = NULL;
1983   gcry_cipher_close (cipherhd);
1984   cipherhd = NULL;
1985
1986   assuan_begin_confidential (ctx);
1987   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
1988   assuan_end_confidential (ctx);
1989
1990
1991  leave:
1992   xfree (cache_nonce);
1993   xfree (passphrase);
1994   xfree (wrappedkey);
1995   gcry_cipher_close (cipherhd);
1996   xfree (key);
1997   gcry_sexp_release (s_skey);
1998   xfree (ctrl->server_local->keydesc);
1999   ctrl->server_local->keydesc = NULL;
2000
2001   return leave_cmd (ctx, err);
2002 }
2003
2004
2005
2006 \f
2007 static const char hlp_getval[] =
2008   "GETVAL <key>\n"
2009   "\n"
2010   "Return the value for KEY from the special environment as created by\n"
2011   "PUTVAL.";
2012 static gpg_error_t
2013 cmd_getval (assuan_context_t ctx, char *line)
2014 {
2015   int rc = 0;
2016   char *key = NULL;
2017   char *p;
2018   struct putval_item_s *vl;
2019
2020   for (p=line; *p == ' '; p++)
2021     ;
2022   key = p;
2023   p = strchr (key, ' ');
2024   if (p)
2025     {
2026       *p++ = 0;
2027       for (; *p == ' '; p++)
2028         ;
2029       if (*p)
2030         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2031     }
2032   if (!key || !*key)
2033     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2034
2035
2036   for (vl=putval_list; vl; vl = vl->next)
2037     if ( !strcmp (vl->d, key) )
2038       break;
2039
2040   if (vl) /* Got an entry. */
2041     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2042   else
2043     return gpg_error (GPG_ERR_NO_DATA);
2044
2045   return leave_cmd (ctx, rc);
2046 }
2047
2048
2049 static const char hlp_putval[] =
2050   "PUTVAL <key> [<percent_escaped_value>]\n"
2051   "\n"
2052   "The gpg-agent maintains a kind of environment which may be used to\n"
2053   "store key/value pairs in it, so that they can be retrieved later.\n"
2054   "This may be used by helper daemons to daemonize themself on\n"
2055   "invocation and register them with gpg-agent.  Callers of the\n"
2056   "daemon's service may now first try connect to get the information\n"
2057   "for that service from gpg-agent through the GETVAL command and then\n"
2058   "try to connect to that daemon.  Only if that fails they may start\n"
2059   "an own instance of the service daemon. \n"
2060   "\n"
2061   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2062   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2063   "corresponsing value; they should be similar to the values of\n"
2064   "envronment variables but gpg-agent does not enforce any\n"
2065   "restrictions.  If that value is not given any value under that KEY\n"
2066   "is removed from this special environment.";
2067 static gpg_error_t
2068 cmd_putval (assuan_context_t ctx, char *line)
2069 {
2070   int rc = 0;
2071   char *key = NULL;
2072   char *value = NULL;
2073   size_t valuelen = 0;
2074   char *p;
2075   struct putval_item_s *vl, *vlprev;
2076
2077   for (p=line; *p == ' '; p++)
2078     ;
2079   key = p;
2080   p = strchr (key, ' ');
2081   if (p)
2082     {
2083       *p++ = 0;
2084       for (; *p == ' '; p++)
2085         ;
2086       if (*p)
2087         {
2088           value = p;
2089           p = strchr (value, ' ');
2090           if (p)
2091             *p = 0;
2092           valuelen = percent_plus_unescape_inplace (value, 0);
2093         }
2094     }
2095   if (!key || !*key)
2096     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2097
2098
2099   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2100     if ( !strcmp (vl->d, key) )
2101       break;
2102
2103   if (vl) /* Delete old entry. */
2104     {
2105       if (vlprev)
2106         vlprev->next = vl->next;
2107       else
2108         putval_list = vl->next;
2109       xfree (vl);
2110     }
2111
2112   if (valuelen) /* Add entry. */
2113     {
2114       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2115       if (!vl)
2116         rc = gpg_error_from_syserror ();
2117       else
2118         {
2119           vl->len = valuelen;
2120           vl->off = strlen (key) + 1;
2121           strcpy (vl->d, key);
2122           memcpy (vl->d + vl->off, value, valuelen);
2123           vl->next = putval_list;
2124           putval_list = vl;
2125         }
2126     }
2127
2128   return leave_cmd (ctx, rc);
2129 }
2130
2131
2132
2133 \f
2134 static const char hlp_updatestartuptty[] =
2135   "UPDATESTARTUPTTY\n"
2136   "\n"
2137   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2138   "session.  This command is useful to pull future pinentries to\n"
2139   "another screen.  It is only required because there is no way in the\n"
2140   "ssh-agent protocol to convey this information.";
2141 static gpg_error_t
2142 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2143 {
2144   static const char *names[] =
2145     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2146   ctrl_t ctrl = assuan_get_pointer (ctx);
2147   gpg_error_t err = 0;
2148   session_env_t se;
2149   int idx;
2150   char *lc_ctype = NULL;
2151   char *lc_messages = NULL;
2152
2153   (void)line;
2154
2155   se = session_env_new ();
2156   if (!se)
2157     err = gpg_error_from_syserror ();
2158
2159   for (idx=0; !err && names[idx]; idx++)
2160     {
2161       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2162       if (value)
2163         err = session_env_setenv (se, names[idx], value);
2164     }
2165
2166   if (!err && ctrl->lc_ctype)
2167     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2168       err = gpg_error_from_syserror ();
2169
2170   if (!err && ctrl->lc_messages)
2171     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2172       err = gpg_error_from_syserror ();
2173
2174   if (err)
2175     {
2176       session_env_release (se);
2177       xfree (lc_ctype);
2178       xfree (lc_messages);
2179     }
2180   else
2181     {
2182       session_env_release (opt.startup_env);
2183       opt.startup_env = se;
2184       xfree (opt.startup_lc_ctype);
2185       opt.startup_lc_ctype = lc_ctype;
2186       xfree (opt.startup_lc_messages);
2187       opt.startup_lc_messages = lc_messages;
2188     }
2189
2190   return err;
2191 }
2192
2193
2194 \f
2195 static const char hlp_killagent[] =
2196   "KILLAGENT\n"
2197   "\n"
2198   "If the agent has been started using a standard socket\n"
2199   "we allow a client to stop the agent.";
2200 static gpg_error_t
2201 cmd_killagent (assuan_context_t ctx, char *line)
2202 {
2203   ctrl_t ctrl = assuan_get_pointer (ctx);
2204
2205   (void)line;
2206
2207   if (!opt.use_standard_socket)
2208     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
2209
2210   ctrl->server_local->stopme = 1;
2211   return gpg_error (GPG_ERR_EOF);
2212 }
2213
2214
2215 static const char hlp_reloadagent[] =
2216   "RELOADAGENT\n"
2217   "\n"
2218   "This command is an alternative to SIGHUP\n"
2219   "to reload the configuration.";
2220 static gpg_error_t
2221 cmd_reloadagent (assuan_context_t ctx, char *line)
2222 {
2223   (void)ctx;
2224   (void)line;
2225
2226   agent_sighup_action ();
2227   return 0;
2228 }
2229
2230
2231 \f
2232 static const char hlp_getinfo[] =
2233   "GETINFO <what>\n"
2234   "\n"
2235   "Multipurpose function to return a variety of information.\n"
2236   "Supported values for WHAT are:\n"
2237   "\n"
2238   "  version     - Return the version of the program.\n"
2239   "  pid         - Return the process id of the server.\n"
2240   "  socket_name - Return the name of the socket.\n"
2241   "  ssh_socket_name - Return the name of the ssh socket.\n"
2242   "  scd_running - Return OK if the SCdaemon is already running.\n"
2243   "  s2k_count   - Return the calibrated S2K count.\n"
2244   "  std_session_env - List the standard session environment.\n"
2245   "  std_startup_env - List the standard startup environment.\n"
2246   "  cmd_has_option\n"
2247   "              - Returns OK if the command CMD implements the option OPT\n.";
2248 static gpg_error_t
2249 cmd_getinfo (assuan_context_t ctx, char *line)
2250 {
2251   ctrl_t ctrl = assuan_get_pointer (ctx);
2252   int rc = 0;
2253
2254   if (!strcmp (line, "version"))
2255     {
2256       const char *s = VERSION;
2257       rc = assuan_send_data (ctx, s, strlen (s));
2258     }
2259   else if (!strcmp (line, "pid"))
2260     {
2261       char numbuf[50];
2262
2263       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2264       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2265     }
2266   else if (!strcmp (line, "socket_name"))
2267     {
2268       const char *s = get_agent_socket_name ();
2269
2270       if (s)
2271         rc = assuan_send_data (ctx, s, strlen (s));
2272       else
2273         rc = gpg_error (GPG_ERR_NO_DATA);
2274     }
2275   else if (!strcmp (line, "ssh_socket_name"))
2276     {
2277       const char *s = get_agent_ssh_socket_name ();
2278
2279       if (s)
2280         rc = assuan_send_data (ctx, s, strlen (s));
2281       else
2282         rc = gpg_error (GPG_ERR_NO_DATA);
2283     }
2284   else if (!strcmp (line, "scd_running"))
2285     {
2286       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2287     }
2288   else if (!strcmp (line, "s2k_count"))
2289     {
2290       char numbuf[50];
2291
2292       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2293       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2294     }
2295   else if (!strcmp (line, "std_session_env")
2296            || !strcmp (line, "std_startup_env"))
2297     {
2298       int iterator;
2299       const char *name, *value;
2300       char *string;
2301
2302       iterator = 0;
2303       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2304         {
2305           value = session_env_getenv_or_default
2306             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2307           if (value)
2308             {
2309               string = xtryasprintf ("%s=%s", name, value);
2310               if (!string)
2311                 rc = gpg_error_from_syserror ();
2312               else
2313                 {
2314                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2315                   if (!rc)
2316                     rc = assuan_send_data (ctx, NULL, 0);
2317                 }
2318               if (rc)
2319                 break;
2320             }
2321         }
2322     }
2323   else if (!strncmp (line, "cmd_has_option", 14)
2324            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2325     {
2326       char *cmd, *cmdopt;
2327       line += 14;
2328       while (*line == ' ' || *line == '\t')
2329         line++;
2330       if (!*line)
2331         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2332       else
2333         {
2334           cmd = line;
2335           while (*line && (*line != ' ' && *line != '\t'))
2336             line++;
2337           if (!*line)
2338             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2339           else
2340             {
2341               *line++ = 0;
2342               while (*line == ' ' || *line == '\t')
2343                 line++;
2344               if (!*line)
2345                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2346               else
2347                 {
2348                   cmdopt = line;
2349                   if (!command_has_option (cmd, cmdopt))
2350                     rc = gpg_error (GPG_ERR_GENERAL);
2351                 }
2352             }
2353         }
2354     }
2355   else
2356     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2357   return rc;
2358 }
2359
2360
2361 \f
2362 static gpg_error_t
2363 option_handler (assuan_context_t ctx, const char *key, const char *value)
2364 {
2365   ctrl_t ctrl = assuan_get_pointer (ctx);
2366   gpg_error_t err = 0;
2367
2368   if (!strcmp (key, "agent-awareness"))
2369     {
2370       /* The value is a version string telling us of which agent
2371          version the caller is aware of.  */
2372       ctrl->server_local->allow_fully_canceled =
2373         gnupg_compare_version (value, "2.1.0");
2374     }
2375   else if (!strcmp (key, "putenv"))
2376     {
2377       /* Change the session's environment to be used for the
2378          Pinentry.  Valid values are:
2379           <NAME>            Delete envvar NAME
2380           <KEY>=            Set envvar NAME to the empty string
2381           <KEY>=<VALUE>     Set envvar NAME to VALUE
2382       */
2383       err = session_env_putenv (ctrl->session_env, value);
2384     }
2385   else if (!strcmp (key, "display"))
2386     {
2387       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2388     }
2389   else if (!strcmp (key, "ttyname"))
2390     {
2391       if (!opt.keep_tty)
2392         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2393     }
2394   else if (!strcmp (key, "ttytype"))
2395     {
2396       if (!opt.keep_tty)
2397         err = session_env_setenv (ctrl->session_env, "TERM", value);
2398     }
2399   else if (!strcmp (key, "lc-ctype"))
2400     {
2401       if (ctrl->lc_ctype)
2402         xfree (ctrl->lc_ctype);
2403       ctrl->lc_ctype = xtrystrdup (value);
2404       if (!ctrl->lc_ctype)
2405         return out_of_core ();
2406     }
2407   else if (!strcmp (key, "lc-messages"))
2408     {
2409       if (ctrl->lc_messages)
2410         xfree (ctrl->lc_messages);
2411       ctrl->lc_messages = xtrystrdup (value);
2412       if (!ctrl->lc_messages)
2413         return out_of_core ();
2414     }
2415   else if (!strcmp (key, "xauthority"))
2416     {
2417       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
2418     }
2419   else if (!strcmp (key, "pinentry-user-data"))
2420     {
2421       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
2422     }
2423   else if (!strcmp (key, "use-cache-for-signing"))
2424     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
2425   else if (!strcmp (key, "allow-pinentry-notify"))
2426     ctrl->server_local->allow_pinentry_notify = 1;
2427   else if (!strcmp (key, "pinentry-mode"))
2428     {
2429       if (!strcmp (value, "ask") || !strcmp (value, "default"))
2430         ctrl->pinentry_mode = PINENTRY_MODE_ASK;
2431       else if (!strcmp (value, "cancel"))
2432         ctrl->pinentry_mode = PINENTRY_MODE_CANCEL;
2433       else if (!strcmp (value, "error"))
2434         ctrl->pinentry_mode = PINENTRY_MODE_ERROR;
2435       else if (!strcmp (value, "loopback"))
2436         {
2437           if (opt.allow_loopback_pinentry)
2438             ctrl->pinentry_mode = PINENTRY_MODE_LOOPBACK;
2439           else
2440             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2441         }
2442       else
2443         err = gpg_error (GPG_ERR_INV_VALUE);
2444     }
2445   else
2446     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2447
2448   return err;
2449 }
2450
2451
2452
2453 \f
2454 /* Called by libassuan after all commands. ERR is the error from the
2455    last assuan operation and not the one returned from the command. */
2456 static void
2457 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
2458 {
2459   ctrl_t ctrl = assuan_get_pointer (ctx);
2460
2461   (void)err;
2462
2463   /* Switch off any I/O monitor controlled logging pausing. */
2464   ctrl->server_local->pause_io_logging = 0;
2465 }
2466
2467
2468 /* This function is called by libassuan for all I/O.  We use it here
2469    to disable logging for the GETEVENTCOUNTER commands.  This is so
2470    that the debug output won't get cluttered by this primitive
2471    command.  */
2472 static unsigned int
2473 io_monitor (assuan_context_t ctx, void *hook, int direction,
2474             const char *line, size_t linelen)
2475 {
2476   ctrl_t ctrl = assuan_get_pointer (ctx);
2477
2478   (void) hook;
2479
2480   /* Note that we only check for the uppercase name.  This allows to
2481      see the logging for debugging if using a non-upercase command
2482      name. */
2483   if (ctx && direction == ASSUAN_IO_FROM_PEER
2484       && linelen >= 15
2485       && !strncmp (line, "GETEVENTCOUNTER", 15)
2486       && (linelen == 15 || spacep (line+15)))
2487     {
2488       ctrl->server_local->pause_io_logging = 1;
2489     }
2490
2491   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2492 }
2493
2494
2495 /* Return true if the command CMD implements the option OPT.  */
2496 static int
2497 command_has_option (const char *cmd, const char *cmdopt)
2498 {
2499   if (!strcmp (cmd, "GET_PASSPHRASE"))
2500     {
2501       if (!strcmp (cmdopt, "repeat"))
2502           return 1;
2503     }
2504
2505   return 0;
2506 }
2507
2508
2509 /* Tell the assuan library about our commands */
2510 static int
2511 register_commands (assuan_context_t ctx)
2512 {
2513   static struct {
2514     const char *name;
2515     assuan_handler_t handler;
2516     const char * const help;
2517   } table[] = {
2518     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2519     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2520     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2521     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2522     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2523     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2524     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2525     { "SETHASH",        cmd_sethash,   hlp_sethash },
2526     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2527     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2528     { "GENKEY",         cmd_genkey,    hlp_genkey },
2529     { "READKEY",        cmd_readkey,   hlp_readkey },
2530     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2531     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2532     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2533     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2534     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2535     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2536     { "LEARN",          cmd_learn,     hlp_learn },
2537     { "PASSWD",         cmd_passwd,    hlp_passwd },
2538     { "INPUT",          NULL },
2539     { "OUTPUT",         NULL },
2540     { "SCD",            cmd_scd,       hlp_scd },
2541     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
2542     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
2543     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
2544     { "GETVAL",         cmd_getval,    hlp_getval },
2545     { "PUTVAL",         cmd_putval,    hlp_putval },
2546     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2547     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2548     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2549     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2550     { NULL }
2551   };
2552   int i, rc;
2553
2554   for (i=0; table[i].name; i++)
2555     {
2556       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2557                                     table[i].help);
2558       if (rc)
2559         return rc;
2560     }
2561   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2562   assuan_register_reset_notify (ctx, reset_notify);
2563   assuan_register_option_handler (ctx, option_handler);
2564   return 0;
2565 }
2566
2567
2568 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2569    simple piper server, otherwise it is a regular server.  CTRL is the
2570    control structure for this connection; it has only the basic
2571    intialization. */
2572 void
2573 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2574 {
2575   int rc;
2576   assuan_context_t ctx = NULL;
2577
2578   rc = assuan_new (&ctx);
2579   if (rc)
2580     {
2581       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2582       agent_exit (2);
2583     }
2584
2585   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2586     {
2587       assuan_fd_t filedes[2];
2588
2589       filedes[0] = assuan_fdopen (0);
2590       filedes[1] = assuan_fdopen (1);
2591       rc = assuan_init_pipe_server (ctx, filedes);
2592     }
2593   else if (listen_fd != GNUPG_INVALID_FD)
2594     {
2595       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2596       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2597          this branch is currently not used.  */
2598     }
2599   else
2600     {
2601       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2602     }
2603   if (rc)
2604     {
2605       log_error ("failed to initialize the server: %s\n",
2606                  gpg_strerror(rc));
2607       agent_exit (2);
2608     }
2609   rc = register_commands (ctx);
2610   if (rc)
2611     {
2612       log_error ("failed to register commands with Assuan: %s\n",
2613                  gpg_strerror(rc));
2614       agent_exit (2);
2615     }
2616
2617   assuan_set_pointer (ctx, ctrl);
2618   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2619   ctrl->server_local->assuan_ctx = ctx;
2620   ctrl->server_local->message_fd = -1;
2621   ctrl->server_local->use_cache_for_signing = 1;
2622   ctrl->digest.raw_value = 0;
2623
2624   assuan_set_io_monitor (ctx, io_monitor, NULL);
2625
2626   for (;;)
2627     {
2628       rc = assuan_accept (ctx);
2629       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
2630         {
2631           break;
2632         }
2633       else if (rc)
2634         {
2635           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2636           break;
2637         }
2638
2639       rc = assuan_process (ctx);
2640       if (rc)
2641         {
2642           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2643           continue;
2644         }
2645     }
2646
2647   /* Reset the nonce caches.  */
2648   clear_nonce_cache (ctrl);
2649
2650   /* Reset the SCD if needed. */
2651   agent_reset_scd (ctrl);
2652
2653   /* Reset the pinentry (in case of popup messages). */
2654   agent_reset_query (ctrl);
2655
2656   /* Cleanup.  */
2657   assuan_release (ctx);
2658   xfree (ctrl->server_local->keydesc);
2659   xfree (ctrl->server_local->import_key);
2660   xfree (ctrl->server_local->export_key);
2661   if (ctrl->server_local->stopme)
2662     agent_exit (0);
2663   xfree (ctrl->server_local);
2664   ctrl->server_local = NULL;
2665 }