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