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