gpg: Make decryption with the OpenPGP card work.
[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 or EXPORT_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 (!s_skey)
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         err = agent_ask_new_passphrase
2069           (ctrl, _("Please enter the passphrase to protect the "
2070                    "imported object within the GnuPG system."),
2071            &passphrase);
2072       if (err)
2073         goto leave;
2074     }
2075
2076   if (passphrase)
2077     {
2078       err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
2079                            ctrl->s2k_count);
2080       if (!err)
2081         err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
2082     }
2083   else
2084     err = agent_write_private_key (grip, key, realkeylen, 0);
2085
2086  leave:
2087   gcry_sexp_release (openpgp_sexp);
2088   xfree (finalkey);
2089   xfree (passphrase);
2090   xfree (key);
2091   gcry_cipher_close (cipherhd);
2092   xfree (wrappedkey);
2093   xfree (cache_nonce);
2094   xfree (ctrl->server_local->keydesc);
2095   ctrl->server_local->keydesc = NULL;
2096   return leave_cmd (ctx, err);
2097 }
2098
2099
2100 \f
2101 static const char hlp_export_key[] =
2102   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
2103   "\n"
2104   "Export a secret key from the key store.  The key will be encrypted\n"
2105   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
2106   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
2107   "prior to using this command.  The function takes the keygrip as argument.\n";
2108 static gpg_error_t
2109 cmd_export_key (assuan_context_t ctx, char *line)
2110 {
2111   ctrl_t ctrl = assuan_get_pointer (ctx);
2112   gpg_error_t err;
2113   unsigned char grip[20];
2114   gcry_sexp_t s_skey = NULL;
2115   unsigned char *key = NULL;
2116   size_t keylen;
2117   gcry_cipher_hd_t cipherhd = NULL;
2118   unsigned char *wrappedkey = NULL;
2119   size_t wrappedkeylen;
2120   int openpgp;
2121   char *cache_nonce;
2122   char *passphrase = NULL;
2123
2124   openpgp = has_option (line, "--openpgp");
2125   cache_nonce = option_value (line, "--cache-nonce");
2126   if (cache_nonce)
2127     {
2128       for (; *line && !spacep (line); line++)
2129         ;
2130       if (*line)
2131         *line++ = '\0';
2132       cache_nonce = xtrystrdup (cache_nonce);
2133       if (!cache_nonce)
2134         {
2135           err = gpg_error_from_syserror ();
2136           goto leave;
2137         }
2138     }
2139   line = skip_options (line);
2140
2141   if (!ctrl->server_local->export_key)
2142     {
2143       err = gpg_error (GPG_ERR_MISSING_KEY);
2144       goto leave;
2145     }
2146
2147   err = parse_keygrip (ctx, line, grip);
2148   if (err)
2149     goto leave;
2150
2151   if (agent_key_available (grip))
2152     {
2153       err = gpg_error (GPG_ERR_NO_SECKEY);
2154       goto leave;
2155     }
2156
2157   /* Get the key from the file.  With the openpgp flag we also ask for
2158      the passphrase so that we can use it to re-encrypt it.  */
2159   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
2160                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
2161                              openpgp ? &passphrase : NULL);
2162   if (err)
2163     goto leave;
2164   if (!s_skey)
2165     {
2166       /* Key is on a smartcard.  Actually we should not see this here
2167          because we do not pass a shadow_info variable to the above
2168          function, thus it will return this error directly.  */
2169       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2170       goto leave;
2171     }
2172
2173   if (openpgp)
2174     {
2175       /* The openpgp option changes the key format into the OpenPGP
2176          key transfer format.  The result is already a padded
2177          canonical S-expression.  */
2178       if (!passphrase)
2179         {
2180           err = agent_ask_new_passphrase
2181             (ctrl, _("This key (or subkey) is not protected with a passphrase."
2182                      "  Please enter a new passphrase to export it."),
2183              &passphrase);
2184           if (err)
2185             goto leave;
2186         }
2187       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
2188     }
2189   else
2190     {
2191       /* Convert into a canonical S-expression and wrap that.  */
2192       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
2193     }
2194   if (err)
2195     goto leave;
2196   gcry_sexp_release (s_skey);
2197   s_skey = NULL;
2198
2199   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2200                           GCRY_CIPHER_MODE_AESWRAP, 0);
2201   if (err)
2202     goto leave;
2203   err = gcry_cipher_setkey (cipherhd,
2204                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
2205   if (err)
2206     goto leave;
2207
2208   wrappedkeylen = keylen + 8;
2209   wrappedkey = xtrymalloc (wrappedkeylen);
2210   if (!wrappedkey)
2211     {
2212       err = gpg_error_from_syserror ();
2213       goto leave;
2214     }
2215
2216   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
2217   if (err)
2218     goto leave;
2219   xfree (key);
2220   key = NULL;
2221   gcry_cipher_close (cipherhd);
2222   cipherhd = NULL;
2223
2224   assuan_begin_confidential (ctx);
2225   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
2226   assuan_end_confidential (ctx);
2227
2228
2229  leave:
2230   xfree (cache_nonce);
2231   xfree (passphrase);
2232   xfree (wrappedkey);
2233   gcry_cipher_close (cipherhd);
2234   xfree (key);
2235   gcry_sexp_release (s_skey);
2236   xfree (ctrl->server_local->keydesc);
2237   ctrl->server_local->keydesc = NULL;
2238
2239   return leave_cmd (ctx, err);
2240 }
2241 \f
2242 static const char hlp_keytocard[] =
2243   "KEYTOCARD [--force] <hexstring_with_keygrip> <serialno> <id> <timestamp>\n"
2244   "\n";
2245 static gpg_error_t
2246 cmd_keytocard (assuan_context_t ctx, char *line)
2247 {
2248   ctrl_t ctrl = assuan_get_pointer (ctx);
2249   int force;
2250   gpg_error_t err = 0;
2251   unsigned char grip[20];
2252   gcry_sexp_t s_skey = NULL;
2253   gcry_sexp_t s_pkey = NULL;
2254   unsigned char *keydata;
2255   size_t keydatalen, timestamplen;
2256   const char *serialno, *timestamp_str, *id;
2257   unsigned char *shadow_info;
2258   unsigned char *shdkey;
2259   time_t timestamp;
2260
2261   force = has_option (line, "--force");
2262   line = skip_options (line);
2263
2264   err = parse_keygrip (ctx, line, grip);
2265   if (err)
2266     return err;
2267
2268   if (agent_key_available (grip))
2269     return gpg_error (GPG_ERR_NO_SECKEY);
2270
2271   line += 40;
2272   while (*line && (*line == ' ' || *line == '\t'))
2273     line++;
2274   serialno = line;
2275   while (*line && (*line != ' ' && *line != '\t'))
2276     line++;
2277   if (!*line)
2278     return gpg_error (GPG_ERR_MISSING_VALUE);
2279   *line = '\0';
2280   line++;
2281   while (*line && (*line == ' ' || *line == '\t'))
2282     line++;
2283   id = line;
2284   while (*line && (*line != ' ' && *line != '\t'))
2285     line++;
2286   if (!*line)
2287     return gpg_error (GPG_ERR_MISSING_VALUE);
2288   *line = '\0';
2289   line++;
2290   while (*line && (*line == ' ' || *line == '\t'))
2291     line++;
2292   timestamp_str = line;
2293   while (*line && (*line != ' ' && *line != '\t'))
2294     line++;
2295   if (*line)
2296     *line = '\0';
2297   timestamplen = line - timestamp_str;
2298   if (timestamplen != 15)
2299     return gpg_error (GPG_ERR_INV_VALUE);
2300
2301   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
2302                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey, NULL);
2303   if (err)
2304     return err;
2305   if (!s_skey)
2306     /* Key is on a smartcard already.  */
2307     return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2308
2309   keydatalen =  gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
2310   keydata = xtrymalloc_secure (keydatalen + 30);
2311   if (keydata == NULL)
2312     {
2313       gcry_sexp_release (s_skey);
2314       return gpg_error_from_syserror ();
2315     }
2316
2317   gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, keydata, keydatalen);
2318   gcry_sexp_release (s_skey);
2319   keydatalen--;                 /* Decrement for last '\0'.  */
2320   /* Add timestamp "created-at" in the private key */
2321   timestamp = isotime2epoch (timestamp_str);
2322   snprintf (keydata+keydatalen-1, 30, "(10:created-at10:%010lu))", timestamp);
2323   keydatalen += 10 + 19 - 1;
2324   err = divert_writekey (ctrl, force, serialno, id, keydata, keydatalen);
2325   if (err)
2326     {
2327       xfree (keydata);
2328       goto leave;
2329     }
2330   xfree (keydata);
2331
2332   err = agent_public_key_from_file (ctrl, grip, &s_pkey);
2333   if (err)
2334     goto leave;
2335
2336   shadow_info = make_shadow_info (serialno, id);
2337   if (!shadow_info)
2338     {
2339       err = gpg_error (GPG_ERR_ENOMEM);
2340       gcry_sexp_release (s_pkey);
2341       goto leave;
2342     }
2343   keydatalen = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
2344   keydata = xtrymalloc (keydatalen);
2345   if (keydata == NULL)
2346     {
2347       err = gpg_error_from_syserror ();
2348       gcry_sexp_release (s_pkey);
2349       goto leave;
2350     }
2351   gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keydata, keydatalen);
2352   gcry_sexp_release (s_pkey);
2353   err = agent_shadow_key (keydata, shadow_info, &shdkey);
2354   xfree (keydata);
2355   xfree (shadow_info);
2356   if (err)
2357     {
2358       log_error ("shadowing the key failed: %s\n", gpg_strerror (err));
2359       goto leave;
2360     }
2361
2362   keydatalen = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
2363   err = agent_write_private_key (grip, shdkey, keydatalen, 1);
2364   xfree (shdkey);
2365
2366  leave:
2367   return leave_cmd (ctx, err);
2368 }
2369 \f
2370 static const char hlp_getval[] =
2371   "GETVAL <key>\n"
2372   "\n"
2373   "Return the value for KEY from the special environment as created by\n"
2374   "PUTVAL.";
2375 static gpg_error_t
2376 cmd_getval (assuan_context_t ctx, char *line)
2377 {
2378   int rc = 0;
2379   char *key = NULL;
2380   char *p;
2381   struct putval_item_s *vl;
2382
2383   for (p=line; *p == ' '; p++)
2384     ;
2385   key = p;
2386   p = strchr (key, ' ');
2387   if (p)
2388     {
2389       *p++ = 0;
2390       for (; *p == ' '; p++)
2391         ;
2392       if (*p)
2393         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2394     }
2395   if (!key || !*key)
2396     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2397
2398
2399   for (vl=putval_list; vl; vl = vl->next)
2400     if ( !strcmp (vl->d, key) )
2401       break;
2402
2403   if (vl) /* Got an entry. */
2404     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2405   else
2406     return gpg_error (GPG_ERR_NO_DATA);
2407
2408   return leave_cmd (ctx, rc);
2409 }
2410
2411
2412 static const char hlp_putval[] =
2413   "PUTVAL <key> [<percent_escaped_value>]\n"
2414   "\n"
2415   "The gpg-agent maintains a kind of environment which may be used to\n"
2416   "store key/value pairs in it, so that they can be retrieved later.\n"
2417   "This may be used by helper daemons to daemonize themself on\n"
2418   "invocation and register them with gpg-agent.  Callers of the\n"
2419   "daemon's service may now first try connect to get the information\n"
2420   "for that service from gpg-agent through the GETVAL command and then\n"
2421   "try to connect to that daemon.  Only if that fails they may start\n"
2422   "an own instance of the service daemon. \n"
2423   "\n"
2424   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2425   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2426   "corresponsing value; they should be similar to the values of\n"
2427   "envronment variables but gpg-agent does not enforce any\n"
2428   "restrictions.  If that value is not given any value under that KEY\n"
2429   "is removed from this special environment.";
2430 static gpg_error_t
2431 cmd_putval (assuan_context_t ctx, char *line)
2432 {
2433   int rc = 0;
2434   char *key = NULL;
2435   char *value = NULL;
2436   size_t valuelen = 0;
2437   char *p;
2438   struct putval_item_s *vl, *vlprev;
2439
2440   for (p=line; *p == ' '; p++)
2441     ;
2442   key = p;
2443   p = strchr (key, ' ');
2444   if (p)
2445     {
2446       *p++ = 0;
2447       for (; *p == ' '; p++)
2448         ;
2449       if (*p)
2450         {
2451           value = p;
2452           p = strchr (value, ' ');
2453           if (p)
2454             *p = 0;
2455           valuelen = percent_plus_unescape_inplace (value, 0);
2456         }
2457     }
2458   if (!key || !*key)
2459     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2460
2461
2462   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2463     if ( !strcmp (vl->d, key) )
2464       break;
2465
2466   if (vl) /* Delete old entry. */
2467     {
2468       if (vlprev)
2469         vlprev->next = vl->next;
2470       else
2471         putval_list = vl->next;
2472       xfree (vl);
2473     }
2474
2475   if (valuelen) /* Add entry. */
2476     {
2477       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2478       if (!vl)
2479         rc = gpg_error_from_syserror ();
2480       else
2481         {
2482           vl->len = valuelen;
2483           vl->off = strlen (key) + 1;
2484           strcpy (vl->d, key);
2485           memcpy (vl->d + vl->off, value, valuelen);
2486           vl->next = putval_list;
2487           putval_list = vl;
2488         }
2489     }
2490
2491   return leave_cmd (ctx, rc);
2492 }
2493
2494
2495
2496 \f
2497 static const char hlp_updatestartuptty[] =
2498   "UPDATESTARTUPTTY\n"
2499   "\n"
2500   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2501   "session.  This command is useful to pull future pinentries to\n"
2502   "another screen.  It is only required because there is no way in the\n"
2503   "ssh-agent protocol to convey this information.";
2504 static gpg_error_t
2505 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2506 {
2507   static const char *names[] =
2508     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2509   ctrl_t ctrl = assuan_get_pointer (ctx);
2510   gpg_error_t err = 0;
2511   session_env_t se;
2512   int idx;
2513   char *lc_ctype = NULL;
2514   char *lc_messages = NULL;
2515
2516   (void)line;
2517
2518   se = session_env_new ();
2519   if (!se)
2520     err = gpg_error_from_syserror ();
2521
2522   for (idx=0; !err && names[idx]; idx++)
2523     {
2524       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2525       if (value)
2526         err = session_env_setenv (se, names[idx], value);
2527     }
2528
2529   if (!err && ctrl->lc_ctype)
2530     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2531       err = gpg_error_from_syserror ();
2532
2533   if (!err && ctrl->lc_messages)
2534     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2535       err = gpg_error_from_syserror ();
2536
2537   if (err)
2538     {
2539       session_env_release (se);
2540       xfree (lc_ctype);
2541       xfree (lc_messages);
2542     }
2543   else
2544     {
2545       session_env_release (opt.startup_env);
2546       opt.startup_env = se;
2547       xfree (opt.startup_lc_ctype);
2548       opt.startup_lc_ctype = lc_ctype;
2549       xfree (opt.startup_lc_messages);
2550       opt.startup_lc_messages = lc_messages;
2551     }
2552
2553   return err;
2554 }
2555
2556
2557 \f
2558 static const char hlp_killagent[] =
2559   "KILLAGENT\n"
2560   "\n"
2561   "If the agent has been started using a standard socket\n"
2562   "we allow a client to stop the agent.";
2563 static gpg_error_t
2564 cmd_killagent (assuan_context_t ctx, char *line)
2565 {
2566   ctrl_t ctrl = assuan_get_pointer (ctx);
2567
2568   (void)line;
2569
2570   if (!opt.use_standard_socket)
2571     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
2572
2573   ctrl->server_local->stopme = 1;
2574   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2575   return 0;
2576 }
2577
2578
2579 static const char hlp_reloadagent[] =
2580   "RELOADAGENT\n"
2581   "\n"
2582   "This command is an alternative to SIGHUP\n"
2583   "to reload the configuration.";
2584 static gpg_error_t
2585 cmd_reloadagent (assuan_context_t ctx, char *line)
2586 {
2587   (void)ctx;
2588   (void)line;
2589
2590   agent_sighup_action ();
2591   return 0;
2592 }
2593
2594
2595 \f
2596 static const char hlp_getinfo[] =
2597   "GETINFO <what>\n"
2598   "\n"
2599   "Multipurpose function to return a variety of information.\n"
2600   "Supported values for WHAT are:\n"
2601   "\n"
2602   "  version     - Return the version of the program.\n"
2603   "  pid         - Return the process id of the server.\n"
2604   "  socket_name - Return the name of the socket.\n"
2605   "  ssh_socket_name - Return the name of the ssh socket.\n"
2606   "  scd_running - Return OK if the SCdaemon is already running.\n"
2607   "  s2k_count   - Return the calibrated S2K count.\n"
2608   "  std_session_env - List the standard session environment.\n"
2609   "  std_startup_env - List the standard startup environment.\n"
2610   "  cmd_has_option\n"
2611   "              - Returns OK if the command CMD implements the option OPT\n.";
2612 static gpg_error_t
2613 cmd_getinfo (assuan_context_t ctx, char *line)
2614 {
2615   ctrl_t ctrl = assuan_get_pointer (ctx);
2616   int rc = 0;
2617
2618   if (!strcmp (line, "version"))
2619     {
2620       const char *s = VERSION;
2621       rc = assuan_send_data (ctx, s, strlen (s));
2622     }
2623   else if (!strcmp (line, "pid"))
2624     {
2625       char numbuf[50];
2626
2627       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2628       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2629     }
2630   else if (!strcmp (line, "socket_name"))
2631     {
2632       const char *s = get_agent_socket_name ();
2633
2634       if (s)
2635         rc = assuan_send_data (ctx, s, strlen (s));
2636       else
2637         rc = gpg_error (GPG_ERR_NO_DATA);
2638     }
2639   else if (!strcmp (line, "ssh_socket_name"))
2640     {
2641       const char *s = get_agent_ssh_socket_name ();
2642
2643       if (s)
2644         rc = assuan_send_data (ctx, s, strlen (s));
2645       else
2646         rc = gpg_error (GPG_ERR_NO_DATA);
2647     }
2648   else if (!strcmp (line, "scd_running"))
2649     {
2650       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2651     }
2652   else if (!strcmp (line, "s2k_count"))
2653     {
2654       char numbuf[50];
2655
2656       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2657       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2658     }
2659   else if (!strcmp (line, "std_session_env")
2660            || !strcmp (line, "std_startup_env"))
2661     {
2662       int iterator;
2663       const char *name, *value;
2664       char *string;
2665
2666       iterator = 0;
2667       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2668         {
2669           value = session_env_getenv_or_default
2670             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2671           if (value)
2672             {
2673               string = xtryasprintf ("%s=%s", name, value);
2674               if (!string)
2675                 rc = gpg_error_from_syserror ();
2676               else
2677                 {
2678                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2679                   if (!rc)
2680                     rc = assuan_send_data (ctx, NULL, 0);
2681                 }
2682               if (rc)
2683                 break;
2684             }
2685         }
2686     }
2687   else if (!strncmp (line, "cmd_has_option", 14)
2688            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2689     {
2690       char *cmd, *cmdopt;
2691       line += 14;
2692       while (*line == ' ' || *line == '\t')
2693         line++;
2694       if (!*line)
2695         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2696       else
2697         {
2698           cmd = line;
2699           while (*line && (*line != ' ' && *line != '\t'))
2700             line++;
2701           if (!*line)
2702             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2703           else
2704             {
2705               *line++ = 0;
2706               while (*line == ' ' || *line == '\t')
2707                 line++;
2708               if (!*line)
2709                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2710               else
2711                 {
2712                   cmdopt = line;
2713                   if (!command_has_option (cmd, cmdopt))
2714                     rc = gpg_error (GPG_ERR_GENERAL);
2715                 }
2716             }
2717         }
2718     }
2719   else
2720     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2721   return rc;
2722 }
2723
2724
2725 \f
2726 /* This function is called by Libassuan to parse the OPTION command.
2727    It has been registered similar to the other Assuan commands.  */
2728 static gpg_error_t
2729 option_handler (assuan_context_t ctx, const char *key, const char *value)
2730 {
2731   ctrl_t ctrl = assuan_get_pointer (ctx);
2732   gpg_error_t err = 0;
2733
2734   if (!strcmp (key, "agent-awareness"))
2735     {
2736       /* The value is a version string telling us of which agent
2737          version the caller is aware of.  */
2738       ctrl->server_local->allow_fully_canceled =
2739         gnupg_compare_version (value, "2.1.0");
2740     }
2741   else if (!strcmp (key, "putenv"))
2742     {
2743       /* Change the session's environment to be used for the
2744          Pinentry.  Valid values are:
2745           <NAME>            Delete envvar NAME
2746           <KEY>=            Set envvar NAME to the empty string
2747           <KEY>=<VALUE>     Set envvar NAME to VALUE
2748       */
2749       err = session_env_putenv (ctrl->session_env, value);
2750     }
2751   else if (!strcmp (key, "display"))
2752     {
2753       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2754     }
2755   else if (!strcmp (key, "ttyname"))
2756     {
2757       if (!opt.keep_tty)
2758         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2759     }
2760   else if (!strcmp (key, "ttytype"))
2761     {
2762       if (!opt.keep_tty)
2763         err = session_env_setenv (ctrl->session_env, "TERM", value);
2764     }
2765   else if (!strcmp (key, "lc-ctype"))
2766     {
2767       if (ctrl->lc_ctype)
2768         xfree (ctrl->lc_ctype);
2769       ctrl->lc_ctype = xtrystrdup (value);
2770       if (!ctrl->lc_ctype)
2771         return out_of_core ();
2772     }
2773   else if (!strcmp (key, "lc-messages"))
2774     {
2775       if (ctrl->lc_messages)
2776         xfree (ctrl->lc_messages);
2777       ctrl->lc_messages = xtrystrdup (value);
2778       if (!ctrl->lc_messages)
2779         return out_of_core ();
2780     }
2781   else if (!strcmp (key, "xauthority"))
2782     {
2783       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
2784     }
2785   else if (!strcmp (key, "pinentry-user-data"))
2786     {
2787       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
2788     }
2789   else if (!strcmp (key, "use-cache-for-signing"))
2790     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
2791   else if (!strcmp (key, "allow-pinentry-notify"))
2792     ctrl->server_local->allow_pinentry_notify = 1;
2793   else if (!strcmp (key, "pinentry-mode"))
2794     {
2795       int tmp = parse_pinentry_mode (value);
2796       if (tmp == -1)
2797         err = gpg_error (GPG_ERR_INV_VALUE);
2798       else if (tmp == PINENTRY_MODE_LOOPBACK && !opt.allow_loopback_pinentry)
2799         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2800       else
2801         ctrl->pinentry_mode = tmp;
2802     }
2803   else if (!strcmp (key, "cache-ttl-opt-preset"))
2804     {
2805       ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
2806     }
2807   else if (!strcmp (key, "s2k-count"))
2808     {
2809       ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
2810       if (ctrl->s2k_count && ctrl->s2k_count < 65536)
2811         {
2812           ctrl->s2k_count = 0;
2813         }
2814     }
2815   else
2816     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2817
2818   return err;
2819 }
2820
2821
2822
2823 \f
2824 /* Called by libassuan after all commands. ERR is the error from the
2825    last assuan operation and not the one returned from the command. */
2826 static void
2827 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
2828 {
2829   ctrl_t ctrl = assuan_get_pointer (ctx);
2830
2831   (void)err;
2832
2833   /* Switch off any I/O monitor controlled logging pausing. */
2834   ctrl->server_local->pause_io_logging = 0;
2835 }
2836
2837
2838 /* This function is called by libassuan for all I/O.  We use it here
2839    to disable logging for the GETEVENTCOUNTER commands.  This is so
2840    that the debug output won't get cluttered by this primitive
2841    command.  */
2842 static unsigned int
2843 io_monitor (assuan_context_t ctx, void *hook, int direction,
2844             const char *line, size_t linelen)
2845 {
2846   ctrl_t ctrl = assuan_get_pointer (ctx);
2847
2848   (void) hook;
2849
2850   /* Note that we only check for the uppercase name.  This allows to
2851      see the logging for debugging if using a non-upercase command
2852      name. */
2853   if (ctx && direction == ASSUAN_IO_FROM_PEER
2854       && linelen >= 15
2855       && !strncmp (line, "GETEVENTCOUNTER", 15)
2856       && (linelen == 15 || spacep (line+15)))
2857     {
2858       ctrl->server_local->pause_io_logging = 1;
2859     }
2860
2861   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2862 }
2863
2864
2865 /* Return true if the command CMD implements the option OPT.  */
2866 static int
2867 command_has_option (const char *cmd, const char *cmdopt)
2868 {
2869   if (!strcmp (cmd, "GET_PASSPHRASE"))
2870     {
2871       if (!strcmp (cmdopt, "repeat"))
2872           return 1;
2873     }
2874
2875   return 0;
2876 }
2877
2878
2879 /* Tell Libassuan about our commands.  Also register the other Assuan
2880    handlers. */
2881 static int
2882 register_commands (assuan_context_t ctx)
2883 {
2884   static struct {
2885     const char *name;
2886     assuan_handler_t handler;
2887     const char * const help;
2888   } table[] = {
2889     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2890     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2891     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2892     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2893     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2894     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2895     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2896     { "SETHASH",        cmd_sethash,   hlp_sethash },
2897     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2898     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2899     { "GENKEY",         cmd_genkey,    hlp_genkey },
2900     { "READKEY",        cmd_readkey,   hlp_readkey },
2901     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2902     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2903     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2904     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2905     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2906     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2907     { "LEARN",          cmd_learn,     hlp_learn },
2908     { "PASSWD",         cmd_passwd,    hlp_passwd },
2909     { "INPUT",          NULL },
2910     { "OUTPUT",         NULL },
2911     { "SCD",            cmd_scd,       hlp_scd },
2912     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
2913     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
2914     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
2915     { "GETVAL",         cmd_getval,    hlp_getval },
2916     { "PUTVAL",         cmd_putval,    hlp_putval },
2917     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2918     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2919     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2920     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2921     { "KEYTOCARD",      cmd_keytocard, hlp_keytocard },
2922     { NULL }
2923   };
2924   int i, rc;
2925
2926   for (i=0; table[i].name; i++)
2927     {
2928       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2929                                     table[i].help);
2930       if (rc)
2931         return rc;
2932     }
2933   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2934   assuan_register_reset_notify (ctx, reset_notify);
2935   assuan_register_option_handler (ctx, option_handler);
2936   return 0;
2937 }
2938
2939
2940 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2941    simple piper server, otherwise it is a regular server.  CTRL is the
2942    control structure for this connection; it has only the basic
2943    intialization. */
2944 void
2945 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2946 {
2947   int rc;
2948   assuan_context_t ctx = NULL;
2949
2950   rc = assuan_new (&ctx);
2951   if (rc)
2952     {
2953       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2954       agent_exit (2);
2955     }
2956
2957   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2958     {
2959       assuan_fd_t filedes[2];
2960
2961       filedes[0] = assuan_fdopen (0);
2962       filedes[1] = assuan_fdopen (1);
2963       rc = assuan_init_pipe_server (ctx, filedes);
2964     }
2965   else if (listen_fd != GNUPG_INVALID_FD)
2966     {
2967       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2968       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2969          this branch is currently not used.  */
2970     }
2971   else
2972     {
2973       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2974     }
2975   if (rc)
2976     {
2977       log_error ("failed to initialize the server: %s\n",
2978                  gpg_strerror(rc));
2979       agent_exit (2);
2980     }
2981   rc = register_commands (ctx);
2982   if (rc)
2983     {
2984       log_error ("failed to register commands with Assuan: %s\n",
2985                  gpg_strerror(rc));
2986       agent_exit (2);
2987     }
2988
2989   assuan_set_pointer (ctx, ctrl);
2990   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2991   ctrl->server_local->assuan_ctx = ctx;
2992   ctrl->server_local->use_cache_for_signing = 1;
2993   ctrl->digest.raw_value = 0;
2994
2995   assuan_set_io_monitor (ctx, io_monitor, NULL);
2996
2997   for (;;)
2998     {
2999       rc = assuan_accept (ctx);
3000       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
3001         {
3002           break;
3003         }
3004       else if (rc)
3005         {
3006           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
3007           break;
3008         }
3009
3010       rc = assuan_process (ctx);
3011       if (rc)
3012         {
3013           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
3014           continue;
3015         }
3016     }
3017
3018   /* Reset the nonce caches.  */
3019   clear_nonce_cache (ctrl);
3020
3021   /* Reset the SCD if needed. */
3022   agent_reset_scd (ctrl);
3023
3024   /* Reset the pinentry (in case of popup messages). */
3025   agent_reset_query (ctrl);
3026
3027   /* Cleanup.  */
3028   assuan_release (ctx);
3029   xfree (ctrl->server_local->keydesc);
3030   xfree (ctrl->server_local->import_key);
3031   xfree (ctrl->server_local->export_key);
3032   if (ctrl->server_local->stopme)
3033     agent_exit (0);
3034   xfree (ctrl->server_local);
3035   ctrl->server_local = NULL;
3036 }
3037
3038
3039 /* Helper for the pinentry loopback mode.  It merely passes the
3040    parameters on to the client.  */
3041 gpg_error_t
3042 pinentry_loopback(ctrl_t ctrl, const char *keyword,
3043                   unsigned char **buffer, size_t *size,
3044                   size_t max_length)
3045 {
3046   gpg_error_t rc;
3047   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
3048
3049   rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%zu", max_length);
3050   if (rc)
3051     return rc;
3052
3053   assuan_begin_confidential (ctx);
3054   rc = assuan_inquire (ctx, keyword, buffer, size, max_length);
3055   assuan_end_confidential (ctx);
3056   return rc;
3057 }