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