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