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