c33c0d61facfb79e77bb64fc3343981b1a63dafd
[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
859   (void)line;
860
861   /* First inquire the data to decrypt */
862   rc = assuan_inquire (ctx, "CIPHERTEXT",
863                        &value, &valuelen, MAXLEN_CIPHERTEXT);
864   if (rc)
865     return rc;
866
867   init_membuf (&outbuf, 512);
868
869   rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
870                         value, valuelen, &outbuf);
871   xfree (value);
872   if (rc)
873     clear_outbuf (&outbuf);
874   else
875     rc = write_and_clear_outbuf (ctx, &outbuf);
876   xfree (ctrl->server_local->keydesc);
877   ctrl->server_local->keydesc = NULL;
878   return leave_cmd (ctx, rc);
879 }
880
881
882 static const char hlp_genkey[] =
883   "GENKEY [--no-protection] [--preset] [<cache_nonce>]\n"
884   "\n"
885   "Generate a new key, store the secret part and return the public\n"
886   "part.  Here is an example transaction:\n"
887   "\n"
888   "  C: GENKEY\n"
889   "  S: INQUIRE KEYPARAM\n"
890   "  C: D (genkey (rsa (nbits  1024)))\n"
891   "  C: END\n"
892   "  S: D (public-key\n"
893   "  S: D   (rsa (n 326487324683264) (e 10001)))\n"
894   "  S: OK key created\n"
895   "\n"
896   "When the --preset option is used the passphrase for the generated\n"
897   "key will be added to the cache.\n"
898   "\n";
899 static gpg_error_t
900 cmd_genkey (assuan_context_t ctx, char *line)
901 {
902   ctrl_t ctrl = assuan_get_pointer (ctx);
903   int rc;
904   int no_protection;
905   unsigned char *value;
906   size_t valuelen;
907   membuf_t outbuf;
908   char *cache_nonce = NULL;
909   int opt_preset;
910   char *p;
911
912   opt_preset = has_option (line, "--preset");
913   no_protection = has_option (line, "--no-protection");
914   line = skip_options (line);
915
916   p = line;
917   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
918     ;
919   *p = '\0';
920   if (*line)
921     cache_nonce = xtrystrdup (line);
922
923   /* First inquire the parameters */
924   rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
925   if (rc)
926     return rc;
927
928   init_membuf (&outbuf, 512);
929
930   rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
931                      opt_preset, &outbuf);
932   xfree (value);
933   if (rc)
934     clear_outbuf (&outbuf);
935   else
936     rc = write_and_clear_outbuf (ctx, &outbuf);
937   xfree (cache_nonce);
938   return leave_cmd (ctx, rc);
939 }
940
941
942
943 \f
944 static const char hlp_readkey[] =
945   "READKEY <hexstring_with_keygrip>\n"
946   "\n"
947   "Return the public key for the given keygrip.";
948 static gpg_error_t
949 cmd_readkey (assuan_context_t ctx, char *line)
950 {
951   ctrl_t ctrl = assuan_get_pointer (ctx);
952   int rc;
953   unsigned char grip[20];
954   gcry_sexp_t s_pkey = NULL;
955
956   rc = parse_keygrip (ctx, line, grip);
957   if (rc)
958     return rc; /* Return immediately as this is already an Assuan error code.*/
959
960   rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
961   if (!rc)
962     {
963       size_t len;
964       unsigned char *buf;
965
966       len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
967       assert (len);
968       buf = xtrymalloc (len);
969       if (!buf)
970         rc = gpg_error_from_syserror ();
971       else
972         {
973           len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
974           assert (len);
975           rc = assuan_send_data (ctx, buf, len);
976           xfree (buf);
977         }
978       gcry_sexp_release (s_pkey);
979     }
980
981   return leave_cmd (ctx, rc);
982 }
983
984
985 \f
986 static const char hlp_keyinfo[] =
987   "KEYINFO [--list] [--data] [--ssh-fpr] <keygrip>\n"
988   "\n"
989   "Return information about the key specified by the KEYGRIP.  If the\n"
990   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
991   "--list is given the keygrip is ignored and information about all\n"
992   "available keys are returned.  The information is returned as a\n"
993   "status line unless --data was specified, with this format:\n"
994   "\n"
995   "  KEYINFO <keygrip> <type> <serialno> <idstr> <cached> <protection> <fpr>\n"
996   "\n"
997   "KEYGRIP is the keygrip.\n"
998   "\n"
999   "TYPE is describes the type of the key:\n"
1000   "    'D' - Regular key stored on disk,\n"
1001   "    'T' - Key is stored on a smartcard (token),\n"
1002   "    '-' - Unknown type.\n"
1003   "\n"
1004   "SERIALNO is an ASCII string with the serial number of the\n"
1005   "         smartcard.  If the serial number is not known a single\n"
1006   "         dash '-' is used instead.\n"
1007   "\n"
1008   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
1009   "      is not known a dash is used instead.\n"
1010   "\n"
1011   "CACHED is 1 if the passphrase for the key was found in the key cache.\n"
1012   "       If not, a '-' is used instead.\n"
1013   "\n"
1014   "PROTECTION describes the key protection type:\n"
1015   "    'P' - The key is protected with a passphrase,\n"
1016   "    'C' - The key is not protected,\n"
1017   "    '-' - Unknown protection.\n"
1018   "\n"
1019   "FPR returns the formatted ssh-style fingerprint of the key.  It is only\n"
1020   "    print if the option --ssh-fpr has been used. '-' is printed if the\n"
1021   "    fingerprint is not available.\n"
1022   "\n"
1023   "More information may be added in the future.";
1024 static gpg_error_t
1025 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
1026                 int data, int with_ssh_fpr)
1027 {
1028   gpg_error_t err;
1029   char hexgrip[40+1];
1030   char *fpr = NULL;
1031   int keytype;
1032   unsigned char *shadow_info = NULL;
1033   char *serialno = NULL;
1034   char *idstr = NULL;
1035   const char *keytypestr;
1036   const char *cached;
1037   const char *protectionstr;
1038   char *pw;
1039
1040   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
1041   if (err)
1042     goto leave;
1043
1044   /* Reformat the grip so that we use uppercase as good style. */
1045   bin2hex (grip, 20, hexgrip);
1046
1047   switch (keytype)
1048     {
1049     case PRIVATE_KEY_CLEAR: protectionstr = "C"; keytypestr = "D";
1050       break;
1051     case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
1052       break;
1053     case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
1054       break;
1055     default: protectionstr = "-"; keytypestr = "-";
1056       break;
1057     }
1058
1059   /* Compute the ssh fingerprint if requested.  */
1060   if (with_ssh_fpr)
1061     {
1062       gcry_sexp_t key;
1063
1064       if (!agent_raw_key_from_file (ctrl, grip, &key))
1065         {
1066           ssh_get_fingerprint_string (key, &fpr);
1067           gcry_sexp_release (key);
1068         }
1069     }
1070
1071   /* Here we have a little race by doing the cache check separately
1072      from the retrieval function.  Given that the cache flag is only a
1073      hint, it should not really matter.  */
1074   pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
1075   cached = pw ? "1" : "-";
1076   xfree (pw);
1077
1078   if (shadow_info)
1079     {
1080       err = parse_shadow_info (shadow_info, &serialno, &idstr);
1081       if (err)
1082         goto leave;
1083     }
1084
1085   if (!data)
1086     err = agent_write_status (ctrl, "KEYINFO",
1087                               hexgrip,
1088                               keytypestr,
1089                               serialno? serialno : "-",
1090                               idstr? idstr : "-",
1091                               cached,
1092                               protectionstr,
1093                               fpr? fpr : "-",
1094                               NULL);
1095   else
1096     {
1097       char *string;
1098
1099       string = xtryasprintf ("%s %s %s %s %s %s %s\n",
1100                              hexgrip, keytypestr,
1101                              serialno? serialno : "-",
1102                              idstr? idstr : "-", cached, protectionstr,
1103                              fpr? fpr : "-");
1104       if (!string)
1105         err = gpg_error_from_syserror ();
1106       else
1107         err = assuan_send_data (ctx, string, strlen(string));
1108       xfree (string);
1109     }
1110
1111  leave:
1112   xfree (fpr);
1113   xfree (shadow_info);
1114   xfree (serialno);
1115   xfree (idstr);
1116   return err;
1117 }
1118
1119
1120 /* Entry int for the command KEYINFO.  This function handles the
1121    command option processing.  For details see hlp_keyinfo above.  */
1122 static gpg_error_t
1123 cmd_keyinfo (assuan_context_t ctx, char *line)
1124 {
1125   ctrl_t ctrl = assuan_get_pointer (ctx);
1126   int err;
1127   unsigned char grip[20];
1128   DIR *dir = NULL;
1129   int list_mode;
1130   int opt_data, opt_ssh_fpr;
1131
1132   list_mode = has_option (line, "--list");
1133   opt_data = has_option (line, "--data");
1134   opt_ssh_fpr = has_option (line, "--ssh-fpr");
1135   line = skip_options (line);
1136
1137   if (list_mode)
1138     {
1139       char *dirname;
1140       struct dirent *dir_entry;
1141       char hexgrip[41];
1142
1143       dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1144       if (!dirname)
1145         {
1146           err = gpg_error_from_syserror ();
1147           goto leave;
1148         }
1149       dir = opendir (dirname);
1150       if (!dir)
1151         {
1152           err = gpg_error_from_syserror ();
1153           xfree (dirname);
1154           goto leave;
1155         }
1156       xfree (dirname);
1157
1158       while ( (dir_entry = readdir (dir)) )
1159         {
1160           if (strlen (dir_entry->d_name) != 44
1161               || strcmp (dir_entry->d_name + 40, ".key"))
1162             continue;
1163           strncpy (hexgrip, dir_entry->d_name, 40);
1164           hexgrip[40] = 0;
1165
1166           if ( hex2bin (hexgrip, grip, 20) < 0 )
1167             continue; /* Bad hex string.  */
1168
1169           err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr);
1170           if (err)
1171             goto leave;
1172         }
1173       err = 0;
1174     }
1175   else
1176     {
1177       err = parse_keygrip (ctx, line, grip);
1178       if (err)
1179         goto leave;
1180       err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr);
1181     }
1182
1183  leave:
1184   if (dir)
1185     closedir (dir);
1186   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1187     leave_cmd (ctx, err);
1188   return err;
1189 }
1190
1191
1192 \f
1193 /* Helper for cmd_get_passphrase.  */
1194 static int
1195 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1196 {
1197   size_t n;
1198   int rc;
1199
1200   assuan_begin_confidential (ctx);
1201   n = strlen (pw);
1202   if (via_data)
1203     rc = assuan_send_data (ctx, pw, n);
1204   else
1205     {
1206       char *p = xtrymalloc_secure (n*2+1);
1207       if (!p)
1208         rc = gpg_error_from_syserror ();
1209       else
1210         {
1211           bin2hex (pw, n, p);
1212           rc = assuan_set_okay_line (ctx, p);
1213           xfree (p);
1214         }
1215     }
1216   return rc;
1217 }
1218
1219
1220 static const char hlp_get_passphrase[] =
1221   "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1222   "               [--qualitybar] <cache_id>\n"
1223   "               [<error_message> <prompt> <description>]\n"
1224   "\n"
1225   "This function is usually used to ask for a passphrase to be used\n"
1226   "for conventional encryption, but may also be used by programs which\n"
1227   "need specal handling of passphrases.  This command uses a syntax\n"
1228   "which helps clients to use the agent with minimum effort.  The\n"
1229   "agent either returns with an error or with a OK followed by the hex\n"
1230   "encoded passphrase.  Note that the length of the strings is\n"
1231   "implicitly limited by the maximum length of a command.\n"
1232   "\n"
1233   "If the option \"--data\" is used the passphrase is returned by usual\n"
1234   "data lines and not on the okay line.\n"
1235   "\n"
1236   "If the option \"--check\" is used the passphrase constraints checks as\n"
1237   "implemented by gpg-agent are applied.  A check is not done if the\n"
1238   "passphrase has been found in the cache.\n"
1239   "\n"
1240   "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1241   "cache the user will not be asked to enter a passphrase but the error\n"
1242   "code GPG_ERR_NO_DATA is returned.  \n"
1243   "\n"
1244   "If the option \"--qualitybar\" is used a visual indication of the\n"
1245   "entered passphrase quality is shown.  (Unless no minimum passphrase\n"
1246   "length has been configured.)";
1247 static gpg_error_t
1248 cmd_get_passphrase (assuan_context_t ctx, char *line)
1249 {
1250   ctrl_t ctrl = assuan_get_pointer (ctx);
1251   int rc;
1252   char *pw;
1253   char *response;
1254   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1255   const char *desc2 = _("Please re-enter this passphrase");
1256   char *p;
1257   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1258   int opt_repeat = 0;
1259   char *repeat_errtext = NULL;
1260
1261   opt_data = has_option (line, "--data");
1262   opt_check = has_option (line, "--check");
1263   opt_no_ask = has_option (line, "--no-ask");
1264   if (has_option_name (line, "--repeat"))
1265     {
1266       p = option_value (line, "--repeat");
1267       if (p)
1268         opt_repeat = atoi (p);
1269       else
1270         opt_repeat = 1;
1271     }
1272   opt_qualbar = has_option (line, "--qualitybar");
1273   line = skip_options (line);
1274
1275   cacheid = line;
1276   p = strchr (cacheid, ' ');
1277   if (p)
1278     {
1279       *p++ = 0;
1280       while (*p == ' ')
1281         p++;
1282       errtext = p;
1283       p = strchr (errtext, ' ');
1284       if (p)
1285         {
1286           *p++ = 0;
1287           while (*p == ' ')
1288             p++;
1289           prompt = p;
1290           p = strchr (prompt, ' ');
1291           if (p)
1292             {
1293               *p++ = 0;
1294               while (*p == ' ')
1295                 p++;
1296               desc = p;
1297               p = strchr (desc, ' ');
1298               if (p)
1299                 *p = 0; /* Ignore trailing garbage. */
1300             }
1301         }
1302     }
1303   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1304     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1305   if (!desc)
1306     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1307
1308   if (!strcmp (cacheid, "X"))
1309     cacheid = NULL;
1310   if (!strcmp (errtext, "X"))
1311     errtext = NULL;
1312   if (!strcmp (prompt, "X"))
1313     prompt = NULL;
1314   if (!strcmp (desc, "X"))
1315     desc = NULL;
1316
1317   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL) : NULL;
1318   if (pw)
1319     {
1320       rc = send_back_passphrase (ctx, opt_data, pw);
1321       xfree (pw);
1322     }
1323   else if (opt_no_ask)
1324     rc = gpg_error (GPG_ERR_NO_DATA);
1325   else
1326     {
1327       /* Note, that we only need to replace the + characters and
1328          should leave the other escaping in place because the escaped
1329          string is send verbatim to the pinentry which does the
1330          unescaping (but not the + replacing) */
1331       if (errtext)
1332         plus_to_blank (errtext);
1333       if (prompt)
1334         plus_to_blank (prompt);
1335       if (desc)
1336         plus_to_blank (desc);
1337
1338     next_try:
1339       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1340                                  repeat_errtext? repeat_errtext:errtext,
1341                                  opt_qualbar);
1342       xfree (repeat_errtext);
1343       repeat_errtext = NULL;
1344       if (!rc)
1345         {
1346           int i;
1347
1348           if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1349             {
1350               xfree (response);
1351               goto next_try;
1352             }
1353           for (i = 0; i < opt_repeat; i++)
1354             {
1355               char *response2;
1356
1357               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1358                                          errtext, 0);
1359               if (rc)
1360                 break;
1361               if (strcmp (response2, response))
1362                 {
1363                   xfree (response2);
1364                   xfree (response);
1365                   repeat_errtext = try_percent_escape
1366                     (_("does not match - try again"), NULL);
1367                   if (!repeat_errtext)
1368                     {
1369                       rc = gpg_error_from_syserror ();
1370                       break;
1371                     }
1372                   goto next_try;
1373                 }
1374               xfree (response2);
1375             }
1376           if (!rc)
1377             {
1378               if (cacheid)
1379                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1380               rc = send_back_passphrase (ctx, opt_data, response);
1381             }
1382           xfree (response);
1383         }
1384     }
1385
1386   return leave_cmd (ctx, rc);
1387 }
1388
1389
1390 static const char hlp_clear_passphrase[] =
1391   "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
1392   "\n"
1393   "may be used to invalidate the cache entry for a passphrase.  The\n"
1394   "function returns with OK even when there is no cached passphrase.\n"
1395   "The --mode=normal option is used to clear an entry for a cacheid\n"
1396   "added by the agent.\n";
1397 static gpg_error_t
1398 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1399 {
1400   char *cacheid = NULL;
1401   char *p;
1402   int opt_normal;
1403
1404   opt_normal = has_option (line, "--mode=normal");
1405   line = skip_options (line);
1406
1407   /* parse the stuff */
1408   for (p=line; *p == ' '; p++)
1409     ;
1410   cacheid = p;
1411   p = strchr (cacheid, ' ');
1412   if (p)
1413     *p = 0; /* ignore garbage */
1414   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1415     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1416
1417   agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
1418                    NULL, 0);
1419   return 0;
1420 }
1421
1422
1423 static const char hlp_get_confirmation[] =
1424   "GET_CONFIRMATION <description>\n"
1425   "\n"
1426   "This command may be used to ask for a simple confirmation.\n"
1427   "DESCRIPTION is displayed along with a Okay and Cancel button.  This\n"
1428   "command uses a syntax which helps clients to use the agent with\n"
1429   "minimum effort.  The agent either returns with an error or with a\n"
1430   "OK.  Note, that the length of DESCRIPTION is implicitly limited by\n"
1431   "the maximum length of a command. DESCRIPTION should not contain\n"
1432   "any spaces, those must be encoded either percent escaped or simply\n"
1433   "as '+'.";
1434 static gpg_error_t
1435 cmd_get_confirmation (assuan_context_t ctx, char *line)
1436 {
1437   ctrl_t ctrl = assuan_get_pointer (ctx);
1438   int rc;
1439   char *desc = NULL;
1440   char *p;
1441
1442   /* parse the stuff */
1443   for (p=line; *p == ' '; p++)
1444     ;
1445   desc = p;
1446   p = strchr (desc, ' ');
1447   if (p)
1448     *p = 0; /* We ignore any garbage -may be later used for other args. */
1449
1450   if (!desc || !*desc)
1451     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1452
1453   if (!strcmp (desc, "X"))
1454     desc = NULL;
1455
1456   /* Note, that we only need to replace the + characters and should
1457      leave the other escaping in place because the escaped string is
1458      send verbatim to the pinentry which does the unescaping (but not
1459      the + replacing) */
1460   if (desc)
1461     plus_to_blank (desc);
1462
1463   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1464   return leave_cmd (ctx, rc);
1465 }
1466
1467
1468 \f
1469 static const char hlp_learn[] =
1470   "LEARN [--send]\n"
1471   "\n"
1472   "Learn something about the currently inserted smartcard.  With\n"
1473   "--send the new certificates are send back.";
1474 static gpg_error_t
1475 cmd_learn (assuan_context_t ctx, char *line)
1476 {
1477   ctrl_t ctrl = assuan_get_pointer (ctx);
1478   int rc;
1479
1480   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1481   return leave_cmd (ctx, rc);
1482 }
1483
1484
1485 \f
1486 static const char hlp_passwd[] =
1487   "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset] <hexkeygrip>\n"
1488   "\n"
1489   "Change the passphrase/PIN for the key identified by keygrip in LINE. When\n"
1490   "--preset is used then the new passphrase will be added to the cache.\n";
1491 static gpg_error_t
1492 cmd_passwd (assuan_context_t ctx, char *line)
1493 {
1494   ctrl_t ctrl = assuan_get_pointer (ctx);
1495   gpg_error_t err;
1496   int c;
1497   char *cache_nonce = NULL;
1498   char *passwd_nonce = NULL;
1499   unsigned char grip[20];
1500   gcry_sexp_t s_skey = NULL;
1501   unsigned char *shadow_info = NULL;
1502   char *passphrase = NULL;
1503   char *pend;
1504   int opt_preset;
1505
1506   opt_preset = has_option (line, "--preset");
1507   cache_nonce = option_value (line, "--cache-nonce");
1508   if (cache_nonce)
1509     {
1510       for (pend = cache_nonce; *pend && !spacep (pend); pend++)
1511         ;
1512       c = *pend;
1513       *pend = '\0';
1514       cache_nonce = xtrystrdup (cache_nonce);
1515       *pend = c;
1516       if (!cache_nonce)
1517         {
1518           err = gpg_error_from_syserror ();
1519           goto leave;
1520         }
1521     }
1522
1523   passwd_nonce = option_value (line, "--passwd-nonce");
1524   if (passwd_nonce)
1525     {
1526       for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
1527         ;
1528       c = *pend;
1529       *pend = '\0';
1530       passwd_nonce = xtrystrdup (passwd_nonce);
1531       *pend = c;
1532       if (!passwd_nonce)
1533         {
1534           err = gpg_error_from_syserror ();
1535           goto leave;
1536         }
1537     }
1538
1539   line = skip_options (line);
1540
1541   err = parse_keygrip (ctx, line, grip);
1542   if (err)
1543     goto leave;
1544
1545   ctrl->in_passwd++;
1546   err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc,
1547                              grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1548                              &s_skey, &passphrase);
1549   if (err)
1550     ;
1551   else if (!s_skey)
1552     {
1553       log_error ("changing a smartcard PIN is not yet supported\n");
1554       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1555     }
1556   else
1557     {
1558       char *newpass = NULL;
1559
1560       if (passwd_nonce)
1561         newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
1562       err = agent_protect_and_store (ctrl, s_skey, &newpass);
1563       if (!err && passphrase)
1564         {
1565           /* A passphrase existed on the old key and the change was
1566              successful.  Return a nonce for that old passphrase to
1567              let the caller try to unprotect the other subkeys with
1568              the same key.  */
1569           if (!cache_nonce)
1570             {
1571               char buf[12];
1572               gcry_create_nonce (buf, 12);
1573               cache_nonce = bin2hex (buf, 12, NULL);
1574             }
1575           if (cache_nonce
1576               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1577                                    passphrase, CACHE_TTL_NONCE))
1578             {
1579               assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1580               xfree (ctrl->server_local->last_cache_nonce);
1581               ctrl->server_local->last_cache_nonce = cache_nonce;
1582               cache_nonce = NULL;
1583             }
1584           if (newpass)
1585             {
1586               /* If we have a new passphrase (which might be empty) we
1587                  store it under a passwd nonce so that the caller may
1588                  send that nonce again to use it for another key. */
1589               if (!passwd_nonce)
1590                 {
1591                   char buf[12];
1592                   gcry_create_nonce (buf, 12);
1593                   passwd_nonce = bin2hex (buf, 12, NULL);
1594                 }
1595               if (passwd_nonce
1596                   && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1597                                        newpass, CACHE_TTL_NONCE))
1598                 {
1599                   assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1600                   xfree (ctrl->server_local->last_passwd_nonce);
1601                   ctrl->server_local->last_passwd_nonce = passwd_nonce;
1602                   passwd_nonce = NULL;
1603                 }
1604             }
1605         }
1606       if (!err && opt_preset)
1607       {
1608           char hexgrip[40+1];
1609           bin2hex(grip, 20, hexgrip);
1610           err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass,
1611                                  ctrl->cache_ttl_opt_preset);
1612       }
1613       xfree (newpass);
1614     }
1615   ctrl->in_passwd--;
1616
1617   xfree (ctrl->server_local->keydesc);
1618   ctrl->server_local->keydesc = NULL;
1619
1620  leave:
1621   xfree (passphrase);
1622   gcry_sexp_release (s_skey);
1623   xfree (shadow_info);
1624   xfree (cache_nonce);
1625   return leave_cmd (ctx, err);
1626 }
1627
1628
1629 static const char hlp_preset_passphrase[] =
1630   "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n"
1631   "\n"
1632   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1633   "to passwd for the given time, where -1 means infinite and 0 means\n"
1634   "the default (currently only a timeout of -1 is allowed, which means\n"
1635   "to never expire it).  If passwd is not provided, ask for it via the\n"
1636   "pinentry module unless --inquire is passed in which case the passphrase\n"
1637   "is retrieved from the client via a server inquire.\n";
1638 static gpg_error_t
1639 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1640 {
1641   int rc;
1642   char *grip_clear = NULL;
1643   unsigned char *passphrase = NULL;
1644   int ttl;
1645   size_t len;
1646   int opt_inquire;
1647
1648   if (!opt.allow_preset_passphrase)
1649     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1650
1651   opt_inquire = has_option (line, "--inquire");
1652   line = skip_options (line);
1653   grip_clear = line;
1654   while (*line && (*line != ' ' && *line != '\t'))
1655     line++;
1656   if (!*line)
1657     return gpg_error (GPG_ERR_MISSING_VALUE);
1658   *line = '\0';
1659   line++;
1660   while (*line && (*line == ' ' || *line == '\t'))
1661     line++;
1662
1663   /* Currently, only infinite timeouts are allowed.  */
1664   ttl = -1;
1665   if (line[0] != '-' || line[1] != '1')
1666     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1667   line++;
1668   line++;
1669   while (!(*line != ' ' && *line != '\t'))
1670     line++;
1671
1672   /* Syntax check the hexstring.  */
1673   len = 0;
1674   rc = parse_hexstring (ctx, line, &len);
1675   if (rc)
1676     return rc;
1677   line[len] = '\0';
1678
1679   /* If there is a passphrase, use it.  Currently, a passphrase is
1680      required.  */
1681   if (*line)
1682     {
1683       if (opt_inquire)
1684         {
1685           rc = set_error (GPG_ERR_ASS_PARAMETER,
1686                           "both --inquire and passphrase specified");
1687           goto leave;
1688         }
1689
1690       /* Do in-place conversion.  */
1691       passphrase = line;
1692       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1693         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1694     }
1695   else if (opt_inquire)
1696     {
1697       /* Note that the passphrase will be truncated at any null byte and the
1698        * limit is 480 characters. */
1699       rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, 480);
1700     }
1701   else
1702     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1703
1704   if (!rc)
1705     {
1706       rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1707       if (opt_inquire)
1708         xfree (passphrase);
1709     }
1710
1711 leave:
1712   return leave_cmd (ctx, rc);
1713 }
1714
1715
1716 \f
1717 static const char hlp_scd[] =
1718   "SCD <commands to pass to the scdaemon>\n"
1719   " \n"
1720   "This is a general quote command to redirect everything to the\n"
1721   "SCdaemon.";
1722 static gpg_error_t
1723 cmd_scd (assuan_context_t ctx, char *line)
1724 {
1725   ctrl_t ctrl = assuan_get_pointer (ctx);
1726   int rc;
1727
1728   rc = divert_generic_cmd (ctrl, line, ctx);
1729
1730   return rc;
1731 }
1732
1733
1734 \f
1735 static const char hlp_keywrap_key[] =
1736   "KEYWRAP_KEY [--clear] <mode>\n"
1737   "\n"
1738   "Return a key to wrap another key.  For now the key is returned\n"
1739   "verbatim and and thus makes not much sense because an eavesdropper on\n"
1740   "the gpg-agent connection will see the key as well as the wrapped key.\n"
1741   "However, this function may either be equipped with a public key\n"
1742   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
1743   "case wrapping the import and export of keys is a requirement for\n"
1744   "certain cryptographic validations and thus useful.  The key persists\n"
1745   "a RESET command but may be cleared using the option --clear.\n"
1746   "\n"
1747   "Supported modes are:\n"
1748   "  --import  - Return a key to import a key into gpg-agent\n"
1749   "  --export  - Return a key to export a key from gpg-agent";
1750 static gpg_error_t
1751 cmd_keywrap_key (assuan_context_t ctx, char *line)
1752 {
1753   ctrl_t ctrl = assuan_get_pointer (ctx);
1754   gpg_error_t err = 0;
1755   int clearopt = has_option (line, "--clear");
1756
1757
1758   assuan_begin_confidential (ctx);
1759   if (has_option (line, "--import"))
1760     {
1761       xfree (ctrl->server_local->import_key);
1762       if (clearopt)
1763         ctrl->server_local->import_key = NULL;
1764       else if (!(ctrl->server_local->import_key =
1765                  gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1766         err = gpg_error_from_syserror ();
1767       else
1768         err = assuan_send_data (ctx, ctrl->server_local->import_key,
1769                                 KEYWRAP_KEYSIZE);
1770     }
1771   else if (has_option (line, "--export"))
1772     {
1773       xfree (ctrl->server_local->export_key);
1774       if (clearopt)
1775         ctrl->server_local->export_key = NULL;
1776       else if (!(ctrl->server_local->export_key =
1777             gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1778         err = gpg_error_from_syserror ();
1779       else
1780         err = assuan_send_data (ctx, ctrl->server_local->export_key,
1781                                 KEYWRAP_KEYSIZE);
1782     }
1783   else
1784     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
1785   assuan_end_confidential (ctx);
1786
1787   return leave_cmd (ctx, err);
1788 }
1789
1790
1791 \f
1792 static const char hlp_import_key[] =
1793   "IMPORT_KEY [<cache_nonce>]\n"
1794   "\n"
1795   "Import a secret key into the key store.  The key is expected to be\n"
1796   "encrypted using the current session's key wrapping key (cf. command\n"
1797   "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
1798   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
1799   "key data.  The unwrapped key must be a canonical S-expression.";
1800 static gpg_error_t
1801 cmd_import_key (assuan_context_t ctx, char *line)
1802 {
1803   ctrl_t ctrl = assuan_get_pointer (ctx);
1804   gpg_error_t err;
1805   unsigned char *wrappedkey = NULL;
1806   size_t wrappedkeylen;
1807   gcry_cipher_hd_t cipherhd = NULL;
1808   unsigned char *key = NULL;
1809   size_t keylen, realkeylen;
1810   char *passphrase = NULL;
1811   unsigned char *finalkey = NULL;
1812   size_t finalkeylen;
1813   unsigned char grip[20];
1814   gcry_sexp_t openpgp_sexp = NULL;
1815   char *cache_nonce = NULL;
1816   char *p;
1817
1818   if (!ctrl->server_local->import_key)
1819     {
1820       err = gpg_error (GPG_ERR_MISSING_KEY);
1821       goto leave;
1822     }
1823
1824   p = line;
1825   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
1826     ;
1827   *p = '\0';
1828   if (*line)
1829     cache_nonce = xtrystrdup (line);
1830
1831   assuan_begin_confidential (ctx);
1832   err = assuan_inquire (ctx, "KEYDATA",
1833                         &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
1834   assuan_end_confidential (ctx);
1835   if (err)
1836     goto leave;
1837   if (wrappedkeylen < 24)
1838     {
1839       err = gpg_error (GPG_ERR_INV_LENGTH);
1840       goto leave;
1841     }
1842   keylen = wrappedkeylen - 8;
1843   key = xtrymalloc_secure (keylen);
1844   if (!key)
1845     {
1846       err = gpg_error_from_syserror ();
1847       goto leave;
1848     }
1849
1850   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1851                           GCRY_CIPHER_MODE_AESWRAP, 0);
1852   if (err)
1853     goto leave;
1854   err = gcry_cipher_setkey (cipherhd,
1855                             ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
1856   if (err)
1857     goto leave;
1858   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
1859   if (err)
1860     goto leave;
1861   gcry_cipher_close (cipherhd);
1862   cipherhd = NULL;
1863   xfree (wrappedkey);
1864   wrappedkey = NULL;
1865
1866   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1867   if (!realkeylen)
1868     goto leave; /* Invalid canonical encoded S-expression.  */
1869
1870   err = keygrip_from_canon_sexp (key, realkeylen, grip);
1871   if (err)
1872     {
1873       /* This might be due to an unsupported S-expression format.
1874          Check whether this is openpgp-private-key and trigger that
1875          import code.  */
1876       if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
1877         {
1878           const char *tag;
1879           size_t taglen;
1880
1881           tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
1882           if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
1883             ;
1884           else
1885             {
1886               gcry_sexp_release (openpgp_sexp);
1887               openpgp_sexp = NULL;
1888             }
1889         }
1890       if (!openpgp_sexp)
1891         goto leave; /* Note that ERR is still set.  */
1892     }
1893
1894
1895   if (openpgp_sexp)
1896     {
1897       /* In most cases the key is encrypted and thus the conversion
1898          function from the OpenPGP format to our internal format will
1899          ask for a passphrase.  That passphrase will be returned and
1900          used to protect the key using the same code as for regular
1901          key import. */
1902
1903       xfree (key);
1904       key = NULL;
1905       err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
1906                                   ctrl->server_local->keydesc, cache_nonce,
1907                                   &key, &passphrase);
1908       if (err)
1909         goto leave;
1910       realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1911       if (!realkeylen)
1912         goto leave; /* Invalid canonical encoded S-expression.  */
1913       if (passphrase)
1914         {
1915           if (!cache_nonce)
1916             {
1917               char buf[12];
1918               gcry_create_nonce (buf, 12);
1919               cache_nonce = bin2hex (buf, 12, NULL);
1920             }
1921           if (cache_nonce
1922               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1923                                    passphrase, CACHE_TTL_NONCE))
1924             assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1925         }
1926     }
1927   else
1928     {
1929       if (!agent_key_available (grip))
1930         err = gpg_error (GPG_ERR_EEXIST);
1931       else
1932         err = agent_ask_new_passphrase
1933           (ctrl, _("Please enter the passphrase to protect the "
1934                    "imported object within the GnuPG system."),
1935            &passphrase);
1936       if (err)
1937         goto leave;
1938     }
1939
1940   if (passphrase)
1941     {
1942       err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
1943               ctrl->s2k_count);
1944       if (!err)
1945         err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
1946     }
1947   else
1948     err = agent_write_private_key (grip, key, realkeylen, 0);
1949
1950  leave:
1951   gcry_sexp_release (openpgp_sexp);
1952   xfree (finalkey);
1953   xfree (passphrase);
1954   xfree (key);
1955   gcry_cipher_close (cipherhd);
1956   xfree (wrappedkey);
1957   xfree (cache_nonce);
1958   xfree (ctrl->server_local->keydesc);
1959   ctrl->server_local->keydesc = NULL;
1960   return leave_cmd (ctx, err);
1961 }
1962
1963
1964 \f
1965 static const char hlp_export_key[] =
1966   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
1967   "\n"
1968   "Export a secret key from the key store.  The key will be encrypted\n"
1969   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
1970   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
1971   "prior to using this command.  The function takes the keygrip as argument.\n";
1972 static gpg_error_t
1973 cmd_export_key (assuan_context_t ctx, char *line)
1974 {
1975   ctrl_t ctrl = assuan_get_pointer (ctx);
1976   gpg_error_t err;
1977   unsigned char grip[20];
1978   gcry_sexp_t s_skey = NULL;
1979   unsigned char *key = NULL;
1980   size_t keylen;
1981   gcry_cipher_hd_t cipherhd = NULL;
1982   unsigned char *wrappedkey = NULL;
1983   size_t wrappedkeylen;
1984   int openpgp;
1985   char *cache_nonce;
1986   char *passphrase = NULL;
1987
1988   openpgp = has_option (line, "--openpgp");
1989   cache_nonce = option_value (line, "--cache-nonce");
1990   if (cache_nonce)
1991     {
1992       for (; *line && !spacep (line); line++)
1993         ;
1994       if (*line)
1995         *line++ = '\0';
1996       cache_nonce = xtrystrdup (cache_nonce);
1997       if (!cache_nonce)
1998         {
1999           err = gpg_error_from_syserror ();
2000           goto leave;
2001         }
2002     }
2003   line = skip_options (line);
2004
2005   if (!ctrl->server_local->export_key)
2006     {
2007       err = gpg_error (GPG_ERR_MISSING_KEY);
2008       goto leave;
2009     }
2010
2011   err = parse_keygrip (ctx, line, grip);
2012   if (err)
2013     goto leave;
2014
2015   if (agent_key_available (grip))
2016     {
2017       err = gpg_error (GPG_ERR_NO_SECKEY);
2018       goto leave;
2019     }
2020
2021   /* Get the key from the file.  With the openpgp flag we also ask for
2022      the passphrase so that we can use it to re-encrypt it.  */
2023   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
2024                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
2025                              openpgp ? &passphrase : NULL);
2026   if (err)
2027     goto leave;
2028   if (!s_skey)
2029     {
2030       /* Key is on a smartcard.  Actually we should not see this here
2031          because we do not pass a shadow_info variable to the above
2032          function, thus it will return this error directly.  */
2033       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2034       goto leave;
2035     }
2036
2037   if (openpgp)
2038     {
2039       /* The openpgp option changes the key format into the OpenPGP
2040          key transfer format.  The result is already a padded
2041          canonical S-expression.  */
2042       if (!passphrase)
2043         {
2044           err = agent_ask_new_passphrase
2045             (ctrl, _("This key (or subkey) is not protected with a passphrase."
2046                      "  Please enter a new passphrase to export it."),
2047              &passphrase);
2048           if (err)
2049             goto leave;
2050         }
2051       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
2052     }
2053   else
2054     {
2055       /* Convert into a canonical S-expression and wrap that.  */
2056       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
2057     }
2058   if (err)
2059     goto leave;
2060   gcry_sexp_release (s_skey);
2061   s_skey = NULL;
2062
2063   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2064                           GCRY_CIPHER_MODE_AESWRAP, 0);
2065   if (err)
2066     goto leave;
2067   err = gcry_cipher_setkey (cipherhd,
2068                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
2069   if (err)
2070     goto leave;
2071
2072   wrappedkeylen = keylen + 8;
2073   wrappedkey = xtrymalloc (wrappedkeylen);
2074   if (!wrappedkey)
2075     {
2076       err = gpg_error_from_syserror ();
2077       goto leave;
2078     }
2079
2080   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
2081   if (err)
2082     goto leave;
2083   xfree (key);
2084   key = NULL;
2085   gcry_cipher_close (cipherhd);
2086   cipherhd = NULL;
2087
2088   assuan_begin_confidential (ctx);
2089   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
2090   assuan_end_confidential (ctx);
2091
2092
2093  leave:
2094   xfree (cache_nonce);
2095   xfree (passphrase);
2096   xfree (wrappedkey);
2097   gcry_cipher_close (cipherhd);
2098   xfree (key);
2099   gcry_sexp_release (s_skey);
2100   xfree (ctrl->server_local->keydesc);
2101   ctrl->server_local->keydesc = NULL;
2102
2103   return leave_cmd (ctx, err);
2104 }
2105
2106
2107
2108 \f
2109 static const char hlp_getval[] =
2110   "GETVAL <key>\n"
2111   "\n"
2112   "Return the value for KEY from the special environment as created by\n"
2113   "PUTVAL.";
2114 static gpg_error_t
2115 cmd_getval (assuan_context_t ctx, char *line)
2116 {
2117   int rc = 0;
2118   char *key = NULL;
2119   char *p;
2120   struct putval_item_s *vl;
2121
2122   for (p=line; *p == ' '; p++)
2123     ;
2124   key = p;
2125   p = strchr (key, ' ');
2126   if (p)
2127     {
2128       *p++ = 0;
2129       for (; *p == ' '; p++)
2130         ;
2131       if (*p)
2132         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2133     }
2134   if (!key || !*key)
2135     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2136
2137
2138   for (vl=putval_list; vl; vl = vl->next)
2139     if ( !strcmp (vl->d, key) )
2140       break;
2141
2142   if (vl) /* Got an entry. */
2143     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2144   else
2145     return gpg_error (GPG_ERR_NO_DATA);
2146
2147   return leave_cmd (ctx, rc);
2148 }
2149
2150
2151 static const char hlp_putval[] =
2152   "PUTVAL <key> [<percent_escaped_value>]\n"
2153   "\n"
2154   "The gpg-agent maintains a kind of environment which may be used to\n"
2155   "store key/value pairs in it, so that they can be retrieved later.\n"
2156   "This may be used by helper daemons to daemonize themself on\n"
2157   "invocation and register them with gpg-agent.  Callers of the\n"
2158   "daemon's service may now first try connect to get the information\n"
2159   "for that service from gpg-agent through the GETVAL command and then\n"
2160   "try to connect to that daemon.  Only if that fails they may start\n"
2161   "an own instance of the service daemon. \n"
2162   "\n"
2163   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2164   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2165   "corresponsing value; they should be similar to the values of\n"
2166   "envronment variables but gpg-agent does not enforce any\n"
2167   "restrictions.  If that value is not given any value under that KEY\n"
2168   "is removed from this special environment.";
2169 static gpg_error_t
2170 cmd_putval (assuan_context_t ctx, char *line)
2171 {
2172   int rc = 0;
2173   char *key = NULL;
2174   char *value = NULL;
2175   size_t valuelen = 0;
2176   char *p;
2177   struct putval_item_s *vl, *vlprev;
2178
2179   for (p=line; *p == ' '; p++)
2180     ;
2181   key = p;
2182   p = strchr (key, ' ');
2183   if (p)
2184     {
2185       *p++ = 0;
2186       for (; *p == ' '; p++)
2187         ;
2188       if (*p)
2189         {
2190           value = p;
2191           p = strchr (value, ' ');
2192           if (p)
2193             *p = 0;
2194           valuelen = percent_plus_unescape_inplace (value, 0);
2195         }
2196     }
2197   if (!key || !*key)
2198     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2199
2200
2201   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2202     if ( !strcmp (vl->d, key) )
2203       break;
2204
2205   if (vl) /* Delete old entry. */
2206     {
2207       if (vlprev)
2208         vlprev->next = vl->next;
2209       else
2210         putval_list = vl->next;
2211       xfree (vl);
2212     }
2213
2214   if (valuelen) /* Add entry. */
2215     {
2216       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2217       if (!vl)
2218         rc = gpg_error_from_syserror ();
2219       else
2220         {
2221           vl->len = valuelen;
2222           vl->off = strlen (key) + 1;
2223           strcpy (vl->d, key);
2224           memcpy (vl->d + vl->off, value, valuelen);
2225           vl->next = putval_list;
2226           putval_list = vl;
2227         }
2228     }
2229
2230   return leave_cmd (ctx, rc);
2231 }
2232
2233
2234
2235 \f
2236 static const char hlp_updatestartuptty[] =
2237   "UPDATESTARTUPTTY\n"
2238   "\n"
2239   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2240   "session.  This command is useful to pull future pinentries to\n"
2241   "another screen.  It is only required because there is no way in the\n"
2242   "ssh-agent protocol to convey this information.";
2243 static gpg_error_t
2244 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2245 {
2246   static const char *names[] =
2247     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2248   ctrl_t ctrl = assuan_get_pointer (ctx);
2249   gpg_error_t err = 0;
2250   session_env_t se;
2251   int idx;
2252   char *lc_ctype = NULL;
2253   char *lc_messages = NULL;
2254
2255   (void)line;
2256
2257   se = session_env_new ();
2258   if (!se)
2259     err = gpg_error_from_syserror ();
2260
2261   for (idx=0; !err && names[idx]; idx++)
2262     {
2263       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2264       if (value)
2265         err = session_env_setenv (se, names[idx], value);
2266     }
2267
2268   if (!err && ctrl->lc_ctype)
2269     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2270       err = gpg_error_from_syserror ();
2271
2272   if (!err && ctrl->lc_messages)
2273     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2274       err = gpg_error_from_syserror ();
2275
2276   if (err)
2277     {
2278       session_env_release (se);
2279       xfree (lc_ctype);
2280       xfree (lc_messages);
2281     }
2282   else
2283     {
2284       session_env_release (opt.startup_env);
2285       opt.startup_env = se;
2286       xfree (opt.startup_lc_ctype);
2287       opt.startup_lc_ctype = lc_ctype;
2288       xfree (opt.startup_lc_messages);
2289       opt.startup_lc_messages = lc_messages;
2290     }
2291
2292   return err;
2293 }
2294
2295
2296 \f
2297 static const char hlp_killagent[] =
2298   "KILLAGENT\n"
2299   "\n"
2300   "If the agent has been started using a standard socket\n"
2301   "we allow a client to stop the agent.";
2302 static gpg_error_t
2303 cmd_killagent (assuan_context_t ctx, char *line)
2304 {
2305   ctrl_t ctrl = assuan_get_pointer (ctx);
2306
2307   (void)line;
2308
2309   if (!opt.use_standard_socket)
2310     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
2311
2312   ctrl->server_local->stopme = 1;
2313 #ifdef ASSUAN_FORCE_CLOSE
2314   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2315   return 0;
2316 #else
2317   return gpg_error (GPG_ERR_EOF);
2318 #endif
2319 }
2320
2321
2322 static const char hlp_reloadagent[] =
2323   "RELOADAGENT\n"
2324   "\n"
2325   "This command is an alternative to SIGHUP\n"
2326   "to reload the configuration.";
2327 static gpg_error_t
2328 cmd_reloadagent (assuan_context_t ctx, char *line)
2329 {
2330   (void)ctx;
2331   (void)line;
2332
2333   agent_sighup_action ();
2334   return 0;
2335 }
2336
2337
2338 \f
2339 static const char hlp_getinfo[] =
2340   "GETINFO <what>\n"
2341   "\n"
2342   "Multipurpose function to return a variety of information.\n"
2343   "Supported values for WHAT are:\n"
2344   "\n"
2345   "  version     - Return the version of the program.\n"
2346   "  pid         - Return the process id of the server.\n"
2347   "  socket_name - Return the name of the socket.\n"
2348   "  ssh_socket_name - Return the name of the ssh socket.\n"
2349   "  scd_running - Return OK if the SCdaemon is already running.\n"
2350   "  s2k_count   - Return the calibrated S2K count.\n"
2351   "  std_session_env - List the standard session environment.\n"
2352   "  std_startup_env - List the standard startup environment.\n"
2353   "  cmd_has_option\n"
2354   "              - Returns OK if the command CMD implements the option OPT\n.";
2355 static gpg_error_t
2356 cmd_getinfo (assuan_context_t ctx, char *line)
2357 {
2358   ctrl_t ctrl = assuan_get_pointer (ctx);
2359   int rc = 0;
2360
2361   if (!strcmp (line, "version"))
2362     {
2363       const char *s = VERSION;
2364       rc = assuan_send_data (ctx, s, strlen (s));
2365     }
2366   else if (!strcmp (line, "pid"))
2367     {
2368       char numbuf[50];
2369
2370       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2371       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2372     }
2373   else if (!strcmp (line, "socket_name"))
2374     {
2375       const char *s = get_agent_socket_name ();
2376
2377       if (s)
2378         rc = assuan_send_data (ctx, s, strlen (s));
2379       else
2380         rc = gpg_error (GPG_ERR_NO_DATA);
2381     }
2382   else if (!strcmp (line, "ssh_socket_name"))
2383     {
2384       const char *s = get_agent_ssh_socket_name ();
2385
2386       if (s)
2387         rc = assuan_send_data (ctx, s, strlen (s));
2388       else
2389         rc = gpg_error (GPG_ERR_NO_DATA);
2390     }
2391   else if (!strcmp (line, "scd_running"))
2392     {
2393       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2394     }
2395   else if (!strcmp (line, "s2k_count"))
2396     {
2397       char numbuf[50];
2398
2399       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2400       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2401     }
2402   else if (!strcmp (line, "std_session_env")
2403            || !strcmp (line, "std_startup_env"))
2404     {
2405       int iterator;
2406       const char *name, *value;
2407       char *string;
2408
2409       iterator = 0;
2410       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2411         {
2412           value = session_env_getenv_or_default
2413             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2414           if (value)
2415             {
2416               string = xtryasprintf ("%s=%s", name, value);
2417               if (!string)
2418                 rc = gpg_error_from_syserror ();
2419               else
2420                 {
2421                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2422                   if (!rc)
2423                     rc = assuan_send_data (ctx, NULL, 0);
2424                 }
2425               if (rc)
2426                 break;
2427             }
2428         }
2429     }
2430   else if (!strncmp (line, "cmd_has_option", 14)
2431            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2432     {
2433       char *cmd, *cmdopt;
2434       line += 14;
2435       while (*line == ' ' || *line == '\t')
2436         line++;
2437       if (!*line)
2438         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2439       else
2440         {
2441           cmd = line;
2442           while (*line && (*line != ' ' && *line != '\t'))
2443             line++;
2444           if (!*line)
2445             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2446           else
2447             {
2448               *line++ = 0;
2449               while (*line == ' ' || *line == '\t')
2450                 line++;
2451               if (!*line)
2452                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2453               else
2454                 {
2455                   cmdopt = line;
2456                   if (!command_has_option (cmd, cmdopt))
2457                     rc = gpg_error (GPG_ERR_GENERAL);
2458                 }
2459             }
2460         }
2461     }
2462   else
2463     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2464   return rc;
2465 }
2466
2467
2468 \f
2469 /* This function is called by Libassuan to parse the OPTION command.
2470    It has been registered similar to the other Assuan commands.  */
2471 static gpg_error_t
2472 option_handler (assuan_context_t ctx, const char *key, const char *value)
2473 {
2474   ctrl_t ctrl = assuan_get_pointer (ctx);
2475   gpg_error_t err = 0;
2476
2477   if (!strcmp (key, "agent-awareness"))
2478     {
2479       /* The value is a version string telling us of which agent
2480          version the caller is aware of.  */
2481       ctrl->server_local->allow_fully_canceled =
2482         gnupg_compare_version (value, "2.1.0");
2483     }
2484   else if (!strcmp (key, "putenv"))
2485     {
2486       /* Change the session's environment to be used for the
2487          Pinentry.  Valid values are:
2488           <NAME>            Delete envvar NAME
2489           <KEY>=            Set envvar NAME to the empty string
2490           <KEY>=<VALUE>     Set envvar NAME to VALUE
2491       */
2492       err = session_env_putenv (ctrl->session_env, value);
2493     }
2494   else if (!strcmp (key, "display"))
2495     {
2496       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2497     }
2498   else if (!strcmp (key, "ttyname"))
2499     {
2500       if (!opt.keep_tty)
2501         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2502     }
2503   else if (!strcmp (key, "ttytype"))
2504     {
2505       if (!opt.keep_tty)
2506         err = session_env_setenv (ctrl->session_env, "TERM", value);
2507     }
2508   else if (!strcmp (key, "lc-ctype"))
2509     {
2510       if (ctrl->lc_ctype)
2511         xfree (ctrl->lc_ctype);
2512       ctrl->lc_ctype = xtrystrdup (value);
2513       if (!ctrl->lc_ctype)
2514         return out_of_core ();
2515     }
2516   else if (!strcmp (key, "lc-messages"))
2517     {
2518       if (ctrl->lc_messages)
2519         xfree (ctrl->lc_messages);
2520       ctrl->lc_messages = xtrystrdup (value);
2521       if (!ctrl->lc_messages)
2522         return out_of_core ();
2523     }
2524   else if (!strcmp (key, "xauthority"))
2525     {
2526       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
2527     }
2528   else if (!strcmp (key, "pinentry-user-data"))
2529     {
2530       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
2531     }
2532   else if (!strcmp (key, "use-cache-for-signing"))
2533     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
2534   else if (!strcmp (key, "allow-pinentry-notify"))
2535     ctrl->server_local->allow_pinentry_notify = 1;
2536   else if (!strcmp (key, "pinentry-mode"))
2537     {
2538       if (!strcmp (value, "ask") || !strcmp (value, "default"))
2539         ctrl->pinentry_mode = PINENTRY_MODE_ASK;
2540       else if (!strcmp (value, "cancel"))
2541         ctrl->pinentry_mode = PINENTRY_MODE_CANCEL;
2542       else if (!strcmp (value, "error"))
2543         ctrl->pinentry_mode = PINENTRY_MODE_ERROR;
2544       else if (!strcmp (value, "loopback"))
2545         {
2546           if (opt.allow_loopback_pinentry)
2547             ctrl->pinentry_mode = PINENTRY_MODE_LOOPBACK;
2548           else
2549             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2550         }
2551       else
2552         err = gpg_error (GPG_ERR_INV_VALUE);
2553     }
2554   else if (!strcmp (key, "cache-ttl-opt-preset"))
2555     {
2556       ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
2557     }
2558   else if (!strcmp (key, "s2k-count"))
2559     {
2560       ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
2561       if (ctrl->s2k_count && ctrl->s2k_count < 65536)
2562         {
2563           ctrl->s2k_count = 0;
2564         }
2565     }
2566   else
2567     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2568
2569   return err;
2570 }
2571
2572
2573
2574 \f
2575 /* Called by libassuan after all commands. ERR is the error from the
2576    last assuan operation and not the one returned from the command. */
2577 static void
2578 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
2579 {
2580   ctrl_t ctrl = assuan_get_pointer (ctx);
2581
2582   (void)err;
2583
2584   /* Switch off any I/O monitor controlled logging pausing. */
2585   ctrl->server_local->pause_io_logging = 0;
2586 }
2587
2588
2589 /* This function is called by libassuan for all I/O.  We use it here
2590    to disable logging for the GETEVENTCOUNTER commands.  This is so
2591    that the debug output won't get cluttered by this primitive
2592    command.  */
2593 static unsigned int
2594 io_monitor (assuan_context_t ctx, void *hook, int direction,
2595             const char *line, size_t linelen)
2596 {
2597   ctrl_t ctrl = assuan_get_pointer (ctx);
2598
2599   (void) hook;
2600
2601   /* Note that we only check for the uppercase name.  This allows to
2602      see the logging for debugging if using a non-upercase command
2603      name. */
2604   if (ctx && direction == ASSUAN_IO_FROM_PEER
2605       && linelen >= 15
2606       && !strncmp (line, "GETEVENTCOUNTER", 15)
2607       && (linelen == 15 || spacep (line+15)))
2608     {
2609       ctrl->server_local->pause_io_logging = 1;
2610     }
2611
2612   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2613 }
2614
2615
2616 /* Return true if the command CMD implements the option OPT.  */
2617 static int
2618 command_has_option (const char *cmd, const char *cmdopt)
2619 {
2620   if (!strcmp (cmd, "GET_PASSPHRASE"))
2621     {
2622       if (!strcmp (cmdopt, "repeat"))
2623           return 1;
2624     }
2625
2626   return 0;
2627 }
2628
2629
2630 /* Tell Libassuan about our commands.  Also register the other Assuan
2631    handlers. */
2632 static int
2633 register_commands (assuan_context_t ctx)
2634 {
2635   static struct {
2636     const char *name;
2637     assuan_handler_t handler;
2638     const char * const help;
2639   } table[] = {
2640     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2641     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2642     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2643     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2644     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2645     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2646     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2647     { "SETHASH",        cmd_sethash,   hlp_sethash },
2648     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2649     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2650     { "GENKEY",         cmd_genkey,    hlp_genkey },
2651     { "READKEY",        cmd_readkey,   hlp_readkey },
2652     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2653     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2654     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2655     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2656     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2657     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2658     { "LEARN",          cmd_learn,     hlp_learn },
2659     { "PASSWD",         cmd_passwd,    hlp_passwd },
2660     { "INPUT",          NULL },
2661     { "OUTPUT",         NULL },
2662     { "SCD",            cmd_scd,       hlp_scd },
2663     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
2664     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
2665     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
2666     { "GETVAL",         cmd_getval,    hlp_getval },
2667     { "PUTVAL",         cmd_putval,    hlp_putval },
2668     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2669     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2670     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2671     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2672     { NULL }
2673   };
2674   int i, rc;
2675
2676   for (i=0; table[i].name; i++)
2677     {
2678       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2679                                     table[i].help);
2680       if (rc)
2681         return rc;
2682     }
2683   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2684   assuan_register_reset_notify (ctx, reset_notify);
2685   assuan_register_option_handler (ctx, option_handler);
2686   return 0;
2687 }
2688
2689
2690 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2691    simple piper server, otherwise it is a regular server.  CTRL is the
2692    control structure for this connection; it has only the basic
2693    intialization. */
2694 void
2695 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2696 {
2697   int rc;
2698   assuan_context_t ctx = NULL;
2699
2700   rc = assuan_new (&ctx);
2701   if (rc)
2702     {
2703       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2704       agent_exit (2);
2705     }
2706
2707   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2708     {
2709       assuan_fd_t filedes[2];
2710
2711       filedes[0] = assuan_fdopen (0);
2712       filedes[1] = assuan_fdopen (1);
2713       rc = assuan_init_pipe_server (ctx, filedes);
2714     }
2715   else if (listen_fd != GNUPG_INVALID_FD)
2716     {
2717       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2718       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2719          this branch is currently not used.  */
2720     }
2721   else
2722     {
2723       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2724     }
2725   if (rc)
2726     {
2727       log_error ("failed to initialize the server: %s\n",
2728                  gpg_strerror(rc));
2729       agent_exit (2);
2730     }
2731   rc = register_commands (ctx);
2732   if (rc)
2733     {
2734       log_error ("failed to register commands with Assuan: %s\n",
2735                  gpg_strerror(rc));
2736       agent_exit (2);
2737     }
2738
2739   assuan_set_pointer (ctx, ctrl);
2740   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2741   ctrl->server_local->assuan_ctx = ctx;
2742   ctrl->server_local->use_cache_for_signing = 1;
2743   ctrl->digest.raw_value = 0;
2744
2745   assuan_set_io_monitor (ctx, io_monitor, NULL);
2746
2747   for (;;)
2748     {
2749       rc = assuan_accept (ctx);
2750       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
2751         {
2752           break;
2753         }
2754       else if (rc)
2755         {
2756           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2757           break;
2758         }
2759
2760       rc = assuan_process (ctx);
2761       if (rc)
2762         {
2763           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2764           continue;
2765         }
2766     }
2767
2768   /* Reset the nonce caches.  */
2769   clear_nonce_cache (ctrl);
2770
2771   /* Reset the SCD if needed. */
2772   agent_reset_scd (ctrl);
2773
2774   /* Reset the pinentry (in case of popup messages). */
2775   agent_reset_query (ctrl);
2776
2777   /* Cleanup.  */
2778   assuan_release (ctx);
2779   xfree (ctrl->server_local->keydesc);
2780   xfree (ctrl->server_local->import_key);
2781   xfree (ctrl->server_local->export_key);
2782   if (ctrl->server_local->stopme)
2783     agent_exit (0);
2784   xfree (ctrl->server_local);
2785   ctrl->server_local = NULL;
2786 }
2787
2788
2789 /* Helper for the pinentry loopback mode.  It merely passes the
2790    parameters on to the client.  */
2791 gpg_error_t
2792 pinentry_loopback(ctrl_t ctrl, const char *keyword,
2793                   unsigned char **buffer, size_t *size,
2794                   size_t max_length)
2795 {
2796   gpg_error_t rc;
2797   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2798
2799   assuan_begin_confidential (ctx);
2800   rc = assuan_inquire (ctx, keyword, buffer, size, max_length);
2801   assuan_end_confidential (ctx);
2802   return rc;
2803 }