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