Inform the client of the preset passphrase length.
[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       char buf[50];
1700       size_t maxlen = 480;
1701
1702       snprintf (buf, sizeof (buf), "%u", maxlen);
1703       rc = assuan_write_status (ctx, "INQUIRE_MAXLEN", buf);
1704       if (!rc)
1705         rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, maxlen);
1706     }
1707   else
1708     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1709
1710   if (!rc)
1711     {
1712       rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1713       if (opt_inquire)
1714         xfree (passphrase);
1715     }
1716
1717 leave:
1718   return leave_cmd (ctx, rc);
1719 }
1720
1721
1722 \f
1723 static const char hlp_scd[] =
1724   "SCD <commands to pass to the scdaemon>\n"
1725   " \n"
1726   "This is a general quote command to redirect everything to the\n"
1727   "SCdaemon.";
1728 static gpg_error_t
1729 cmd_scd (assuan_context_t ctx, char *line)
1730 {
1731   ctrl_t ctrl = assuan_get_pointer (ctx);
1732   int rc;
1733
1734   rc = divert_generic_cmd (ctrl, line, ctx);
1735
1736   return rc;
1737 }
1738
1739
1740 \f
1741 static const char hlp_keywrap_key[] =
1742   "KEYWRAP_KEY [--clear] <mode>\n"
1743   "\n"
1744   "Return a key to wrap another key.  For now the key is returned\n"
1745   "verbatim and and thus makes not much sense because an eavesdropper on\n"
1746   "the gpg-agent connection will see the key as well as the wrapped key.\n"
1747   "However, this function may either be equipped with a public key\n"
1748   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
1749   "case wrapping the import and export of keys is a requirement for\n"
1750   "certain cryptographic validations and thus useful.  The key persists\n"
1751   "a RESET command but may be cleared using the option --clear.\n"
1752   "\n"
1753   "Supported modes are:\n"
1754   "  --import  - Return a key to import a key into gpg-agent\n"
1755   "  --export  - Return a key to export a key from gpg-agent";
1756 static gpg_error_t
1757 cmd_keywrap_key (assuan_context_t ctx, char *line)
1758 {
1759   ctrl_t ctrl = assuan_get_pointer (ctx);
1760   gpg_error_t err = 0;
1761   int clearopt = has_option (line, "--clear");
1762
1763
1764   assuan_begin_confidential (ctx);
1765   if (has_option (line, "--import"))
1766     {
1767       xfree (ctrl->server_local->import_key);
1768       if (clearopt)
1769         ctrl->server_local->import_key = NULL;
1770       else if (!(ctrl->server_local->import_key =
1771                  gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1772         err = gpg_error_from_syserror ();
1773       else
1774         err = assuan_send_data (ctx, ctrl->server_local->import_key,
1775                                 KEYWRAP_KEYSIZE);
1776     }
1777   else if (has_option (line, "--export"))
1778     {
1779       xfree (ctrl->server_local->export_key);
1780       if (clearopt)
1781         ctrl->server_local->export_key = NULL;
1782       else if (!(ctrl->server_local->export_key =
1783             gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1784         err = gpg_error_from_syserror ();
1785       else
1786         err = assuan_send_data (ctx, ctrl->server_local->export_key,
1787                                 KEYWRAP_KEYSIZE);
1788     }
1789   else
1790     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
1791   assuan_end_confidential (ctx);
1792
1793   return leave_cmd (ctx, err);
1794 }
1795
1796
1797 \f
1798 static const char hlp_import_key[] =
1799   "IMPORT_KEY [<cache_nonce>]\n"
1800   "\n"
1801   "Import a secret key into the key store.  The key is expected to be\n"
1802   "encrypted using the current session's key wrapping key (cf. command\n"
1803   "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
1804   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
1805   "key data.  The unwrapped key must be a canonical S-expression.";
1806 static gpg_error_t
1807 cmd_import_key (assuan_context_t ctx, char *line)
1808 {
1809   ctrl_t ctrl = assuan_get_pointer (ctx);
1810   gpg_error_t err;
1811   unsigned char *wrappedkey = NULL;
1812   size_t wrappedkeylen;
1813   gcry_cipher_hd_t cipherhd = NULL;
1814   unsigned char *key = NULL;
1815   size_t keylen, realkeylen;
1816   char *passphrase = NULL;
1817   unsigned char *finalkey = NULL;
1818   size_t finalkeylen;
1819   unsigned char grip[20];
1820   gcry_sexp_t openpgp_sexp = NULL;
1821   char *cache_nonce = NULL;
1822   char *p;
1823
1824   if (!ctrl->server_local->import_key)
1825     {
1826       err = gpg_error (GPG_ERR_MISSING_KEY);
1827       goto leave;
1828     }
1829
1830   p = line;
1831   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
1832     ;
1833   *p = '\0';
1834   if (*line)
1835     cache_nonce = xtrystrdup (line);
1836
1837   assuan_begin_confidential (ctx);
1838   err = assuan_inquire (ctx, "KEYDATA",
1839                         &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
1840   assuan_end_confidential (ctx);
1841   if (err)
1842     goto leave;
1843   if (wrappedkeylen < 24)
1844     {
1845       err = gpg_error (GPG_ERR_INV_LENGTH);
1846       goto leave;
1847     }
1848   keylen = wrappedkeylen - 8;
1849   key = xtrymalloc_secure (keylen);
1850   if (!key)
1851     {
1852       err = gpg_error_from_syserror ();
1853       goto leave;
1854     }
1855
1856   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1857                           GCRY_CIPHER_MODE_AESWRAP, 0);
1858   if (err)
1859     goto leave;
1860   err = gcry_cipher_setkey (cipherhd,
1861                             ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
1862   if (err)
1863     goto leave;
1864   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
1865   if (err)
1866     goto leave;
1867   gcry_cipher_close (cipherhd);
1868   cipherhd = NULL;
1869   xfree (wrappedkey);
1870   wrappedkey = NULL;
1871
1872   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1873   if (!realkeylen)
1874     goto leave; /* Invalid canonical encoded S-expression.  */
1875
1876   err = keygrip_from_canon_sexp (key, realkeylen, grip);
1877   if (err)
1878     {
1879       /* This might be due to an unsupported S-expression format.
1880          Check whether this is openpgp-private-key and trigger that
1881          import code.  */
1882       if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
1883         {
1884           const char *tag;
1885           size_t taglen;
1886
1887           tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
1888           if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
1889             ;
1890           else
1891             {
1892               gcry_sexp_release (openpgp_sexp);
1893               openpgp_sexp = NULL;
1894             }
1895         }
1896       if (!openpgp_sexp)
1897         goto leave; /* Note that ERR is still set.  */
1898     }
1899
1900
1901   if (openpgp_sexp)
1902     {
1903       /* In most cases the key is encrypted and thus the conversion
1904          function from the OpenPGP format to our internal format will
1905          ask for a passphrase.  That passphrase will be returned and
1906          used to protect the key using the same code as for regular
1907          key import. */
1908
1909       xfree (key);
1910       key = NULL;
1911       err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
1912                                   ctrl->server_local->keydesc, cache_nonce,
1913                                   &key, &passphrase);
1914       if (err)
1915         goto leave;
1916       realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1917       if (!realkeylen)
1918         goto leave; /* Invalid canonical encoded S-expression.  */
1919       if (passphrase)
1920         {
1921           if (!cache_nonce)
1922             {
1923               char buf[12];
1924               gcry_create_nonce (buf, 12);
1925               cache_nonce = bin2hex (buf, 12, NULL);
1926             }
1927           if (cache_nonce
1928               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1929                                    passphrase, CACHE_TTL_NONCE))
1930             assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1931         }
1932     }
1933   else
1934     {
1935       if (!agent_key_available (grip))
1936         err = gpg_error (GPG_ERR_EEXIST);
1937       else
1938         err = agent_ask_new_passphrase
1939           (ctrl, _("Please enter the passphrase to protect the "
1940                    "imported object within the GnuPG system."),
1941            &passphrase);
1942       if (err)
1943         goto leave;
1944     }
1945
1946   if (passphrase)
1947     {
1948       err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
1949               ctrl->s2k_count);
1950       if (!err)
1951         err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
1952     }
1953   else
1954     err = agent_write_private_key (grip, key, realkeylen, 0);
1955
1956  leave:
1957   gcry_sexp_release (openpgp_sexp);
1958   xfree (finalkey);
1959   xfree (passphrase);
1960   xfree (key);
1961   gcry_cipher_close (cipherhd);
1962   xfree (wrappedkey);
1963   xfree (cache_nonce);
1964   xfree (ctrl->server_local->keydesc);
1965   ctrl->server_local->keydesc = NULL;
1966   return leave_cmd (ctx, err);
1967 }
1968
1969
1970 \f
1971 static const char hlp_export_key[] =
1972   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
1973   "\n"
1974   "Export a secret key from the key store.  The key will be encrypted\n"
1975   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
1976   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
1977   "prior to using this command.  The function takes the keygrip as argument.\n";
1978 static gpg_error_t
1979 cmd_export_key (assuan_context_t ctx, char *line)
1980 {
1981   ctrl_t ctrl = assuan_get_pointer (ctx);
1982   gpg_error_t err;
1983   unsigned char grip[20];
1984   gcry_sexp_t s_skey = NULL;
1985   unsigned char *key = NULL;
1986   size_t keylen;
1987   gcry_cipher_hd_t cipherhd = NULL;
1988   unsigned char *wrappedkey = NULL;
1989   size_t wrappedkeylen;
1990   int openpgp;
1991   char *cache_nonce;
1992   char *passphrase = NULL;
1993
1994   openpgp = has_option (line, "--openpgp");
1995   cache_nonce = option_value (line, "--cache-nonce");
1996   if (cache_nonce)
1997     {
1998       for (; *line && !spacep (line); line++)
1999         ;
2000       if (*line)
2001         *line++ = '\0';
2002       cache_nonce = xtrystrdup (cache_nonce);
2003       if (!cache_nonce)
2004         {
2005           err = gpg_error_from_syserror ();
2006           goto leave;
2007         }
2008     }
2009   line = skip_options (line);
2010
2011   if (!ctrl->server_local->export_key)
2012     {
2013       err = gpg_error (GPG_ERR_MISSING_KEY);
2014       goto leave;
2015     }
2016
2017   err = parse_keygrip (ctx, line, grip);
2018   if (err)
2019     goto leave;
2020
2021   if (agent_key_available (grip))
2022     {
2023       err = gpg_error (GPG_ERR_NO_SECKEY);
2024       goto leave;
2025     }
2026
2027   /* Get the key from the file.  With the openpgp flag we also ask for
2028      the passphrase so that we can use it to re-encrypt it.  */
2029   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
2030                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
2031                              openpgp ? &passphrase : NULL);
2032   if (err)
2033     goto leave;
2034   if (!s_skey)
2035     {
2036       /* Key is on a smartcard.  Actually we should not see this here
2037          because we do not pass a shadow_info variable to the above
2038          function, thus it will return this error directly.  */
2039       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2040       goto leave;
2041     }
2042
2043   if (openpgp)
2044     {
2045       /* The openpgp option changes the key format into the OpenPGP
2046          key transfer format.  The result is already a padded
2047          canonical S-expression.  */
2048       if (!passphrase)
2049         {
2050           err = agent_ask_new_passphrase
2051             (ctrl, _("This key (or subkey) is not protected with a passphrase."
2052                      "  Please enter a new passphrase to export it."),
2053              &passphrase);
2054           if (err)
2055             goto leave;
2056         }
2057       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
2058     }
2059   else
2060     {
2061       /* Convert into a canonical S-expression and wrap that.  */
2062       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
2063     }
2064   if (err)
2065     goto leave;
2066   gcry_sexp_release (s_skey);
2067   s_skey = NULL;
2068
2069   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2070                           GCRY_CIPHER_MODE_AESWRAP, 0);
2071   if (err)
2072     goto leave;
2073   err = gcry_cipher_setkey (cipherhd,
2074                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
2075   if (err)
2076     goto leave;
2077
2078   wrappedkeylen = keylen + 8;
2079   wrappedkey = xtrymalloc (wrappedkeylen);
2080   if (!wrappedkey)
2081     {
2082       err = gpg_error_from_syserror ();
2083       goto leave;
2084     }
2085
2086   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
2087   if (err)
2088     goto leave;
2089   xfree (key);
2090   key = NULL;
2091   gcry_cipher_close (cipherhd);
2092   cipherhd = NULL;
2093
2094   assuan_begin_confidential (ctx);
2095   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
2096   assuan_end_confidential (ctx);
2097
2098
2099  leave:
2100   xfree (cache_nonce);
2101   xfree (passphrase);
2102   xfree (wrappedkey);
2103   gcry_cipher_close (cipherhd);
2104   xfree (key);
2105   gcry_sexp_release (s_skey);
2106   xfree (ctrl->server_local->keydesc);
2107   ctrl->server_local->keydesc = NULL;
2108
2109   return leave_cmd (ctx, err);
2110 }
2111
2112
2113
2114 \f
2115 static const char hlp_getval[] =
2116   "GETVAL <key>\n"
2117   "\n"
2118   "Return the value for KEY from the special environment as created by\n"
2119   "PUTVAL.";
2120 static gpg_error_t
2121 cmd_getval (assuan_context_t ctx, char *line)
2122 {
2123   int rc = 0;
2124   char *key = NULL;
2125   char *p;
2126   struct putval_item_s *vl;
2127
2128   for (p=line; *p == ' '; p++)
2129     ;
2130   key = p;
2131   p = strchr (key, ' ');
2132   if (p)
2133     {
2134       *p++ = 0;
2135       for (; *p == ' '; p++)
2136         ;
2137       if (*p)
2138         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2139     }
2140   if (!key || !*key)
2141     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2142
2143
2144   for (vl=putval_list; vl; vl = vl->next)
2145     if ( !strcmp (vl->d, key) )
2146       break;
2147
2148   if (vl) /* Got an entry. */
2149     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2150   else
2151     return gpg_error (GPG_ERR_NO_DATA);
2152
2153   return leave_cmd (ctx, rc);
2154 }
2155
2156
2157 static const char hlp_putval[] =
2158   "PUTVAL <key> [<percent_escaped_value>]\n"
2159   "\n"
2160   "The gpg-agent maintains a kind of environment which may be used to\n"
2161   "store key/value pairs in it, so that they can be retrieved later.\n"
2162   "This may be used by helper daemons to daemonize themself on\n"
2163   "invocation and register them with gpg-agent.  Callers of the\n"
2164   "daemon's service may now first try connect to get the information\n"
2165   "for that service from gpg-agent through the GETVAL command and then\n"
2166   "try to connect to that daemon.  Only if that fails they may start\n"
2167   "an own instance of the service daemon. \n"
2168   "\n"
2169   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2170   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2171   "corresponsing value; they should be similar to the values of\n"
2172   "envronment variables but gpg-agent does not enforce any\n"
2173   "restrictions.  If that value is not given any value under that KEY\n"
2174   "is removed from this special environment.";
2175 static gpg_error_t
2176 cmd_putval (assuan_context_t ctx, char *line)
2177 {
2178   int rc = 0;
2179   char *key = NULL;
2180   char *value = NULL;
2181   size_t valuelen = 0;
2182   char *p;
2183   struct putval_item_s *vl, *vlprev;
2184
2185   for (p=line; *p == ' '; p++)
2186     ;
2187   key = p;
2188   p = strchr (key, ' ');
2189   if (p)
2190     {
2191       *p++ = 0;
2192       for (; *p == ' '; p++)
2193         ;
2194       if (*p)
2195         {
2196           value = p;
2197           p = strchr (value, ' ');
2198           if (p)
2199             *p = 0;
2200           valuelen = percent_plus_unescape_inplace (value, 0);
2201         }
2202     }
2203   if (!key || !*key)
2204     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2205
2206
2207   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2208     if ( !strcmp (vl->d, key) )
2209       break;
2210
2211   if (vl) /* Delete old entry. */
2212     {
2213       if (vlprev)
2214         vlprev->next = vl->next;
2215       else
2216         putval_list = vl->next;
2217       xfree (vl);
2218     }
2219
2220   if (valuelen) /* Add entry. */
2221     {
2222       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2223       if (!vl)
2224         rc = gpg_error_from_syserror ();
2225       else
2226         {
2227           vl->len = valuelen;
2228           vl->off = strlen (key) + 1;
2229           strcpy (vl->d, key);
2230           memcpy (vl->d + vl->off, value, valuelen);
2231           vl->next = putval_list;
2232           putval_list = vl;
2233         }
2234     }
2235
2236   return leave_cmd (ctx, rc);
2237 }
2238
2239
2240
2241 \f
2242 static const char hlp_updatestartuptty[] =
2243   "UPDATESTARTUPTTY\n"
2244   "\n"
2245   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2246   "session.  This command is useful to pull future pinentries to\n"
2247   "another screen.  It is only required because there is no way in the\n"
2248   "ssh-agent protocol to convey this information.";
2249 static gpg_error_t
2250 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2251 {
2252   static const char *names[] =
2253     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2254   ctrl_t ctrl = assuan_get_pointer (ctx);
2255   gpg_error_t err = 0;
2256   session_env_t se;
2257   int idx;
2258   char *lc_ctype = NULL;
2259   char *lc_messages = NULL;
2260
2261   (void)line;
2262
2263   se = session_env_new ();
2264   if (!se)
2265     err = gpg_error_from_syserror ();
2266
2267   for (idx=0; !err && names[idx]; idx++)
2268     {
2269       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2270       if (value)
2271         err = session_env_setenv (se, names[idx], value);
2272     }
2273
2274   if (!err && ctrl->lc_ctype)
2275     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2276       err = gpg_error_from_syserror ();
2277
2278   if (!err && ctrl->lc_messages)
2279     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2280       err = gpg_error_from_syserror ();
2281
2282   if (err)
2283     {
2284       session_env_release (se);
2285       xfree (lc_ctype);
2286       xfree (lc_messages);
2287     }
2288   else
2289     {
2290       session_env_release (opt.startup_env);
2291       opt.startup_env = se;
2292       xfree (opt.startup_lc_ctype);
2293       opt.startup_lc_ctype = lc_ctype;
2294       xfree (opt.startup_lc_messages);
2295       opt.startup_lc_messages = lc_messages;
2296     }
2297
2298   return err;
2299 }
2300
2301
2302 \f
2303 static const char hlp_killagent[] =
2304   "KILLAGENT\n"
2305   "\n"
2306   "If the agent has been started using a standard socket\n"
2307   "we allow a client to stop the agent.";
2308 static gpg_error_t
2309 cmd_killagent (assuan_context_t ctx, char *line)
2310 {
2311   ctrl_t ctrl = assuan_get_pointer (ctx);
2312
2313   (void)line;
2314
2315   if (!opt.use_standard_socket)
2316     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
2317
2318   ctrl->server_local->stopme = 1;
2319   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2320   return 0;
2321 }
2322
2323
2324 static const char hlp_reloadagent[] =
2325   "RELOADAGENT\n"
2326   "\n"
2327   "This command is an alternative to SIGHUP\n"
2328   "to reload the configuration.";
2329 static gpg_error_t
2330 cmd_reloadagent (assuan_context_t ctx, char *line)
2331 {
2332   (void)ctx;
2333   (void)line;
2334
2335   agent_sighup_action ();
2336   return 0;
2337 }
2338
2339
2340 \f
2341 static const char hlp_getinfo[] =
2342   "GETINFO <what>\n"
2343   "\n"
2344   "Multipurpose function to return a variety of information.\n"
2345   "Supported values for WHAT are:\n"
2346   "\n"
2347   "  version     - Return the version of the program.\n"
2348   "  pid         - Return the process id of the server.\n"
2349   "  socket_name - Return the name of the socket.\n"
2350   "  ssh_socket_name - Return the name of the ssh socket.\n"
2351   "  scd_running - Return OK if the SCdaemon is already running.\n"
2352   "  s2k_count   - Return the calibrated S2K count.\n"
2353   "  std_session_env - List the standard session environment.\n"
2354   "  std_startup_env - List the standard startup environment.\n"
2355   "  cmd_has_option\n"
2356   "              - Returns OK if the command CMD implements the option OPT\n.";
2357 static gpg_error_t
2358 cmd_getinfo (assuan_context_t ctx, char *line)
2359 {
2360   ctrl_t ctrl = assuan_get_pointer (ctx);
2361   int rc = 0;
2362
2363   if (!strcmp (line, "version"))
2364     {
2365       const char *s = VERSION;
2366       rc = assuan_send_data (ctx, s, strlen (s));
2367     }
2368   else if (!strcmp (line, "pid"))
2369     {
2370       char numbuf[50];
2371
2372       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2373       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2374     }
2375   else if (!strcmp (line, "socket_name"))
2376     {
2377       const char *s = get_agent_socket_name ();
2378
2379       if (s)
2380         rc = assuan_send_data (ctx, s, strlen (s));
2381       else
2382         rc = gpg_error (GPG_ERR_NO_DATA);
2383     }
2384   else if (!strcmp (line, "ssh_socket_name"))
2385     {
2386       const char *s = get_agent_ssh_socket_name ();
2387
2388       if (s)
2389         rc = assuan_send_data (ctx, s, strlen (s));
2390       else
2391         rc = gpg_error (GPG_ERR_NO_DATA);
2392     }
2393   else if (!strcmp (line, "scd_running"))
2394     {
2395       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2396     }
2397   else if (!strcmp (line, "s2k_count"))
2398     {
2399       char numbuf[50];
2400
2401       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2402       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2403     }
2404   else if (!strcmp (line, "std_session_env")
2405            || !strcmp (line, "std_startup_env"))
2406     {
2407       int iterator;
2408       const char *name, *value;
2409       char *string;
2410
2411       iterator = 0;
2412       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2413         {
2414           value = session_env_getenv_or_default
2415             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2416           if (value)
2417             {
2418               string = xtryasprintf ("%s=%s", name, value);
2419               if (!string)
2420                 rc = gpg_error_from_syserror ();
2421               else
2422                 {
2423                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2424                   if (!rc)
2425                     rc = assuan_send_data (ctx, NULL, 0);
2426                 }
2427               if (rc)
2428                 break;
2429             }
2430         }
2431     }
2432   else if (!strncmp (line, "cmd_has_option", 14)
2433            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2434     {
2435       char *cmd, *cmdopt;
2436       line += 14;
2437       while (*line == ' ' || *line == '\t')
2438         line++;
2439       if (!*line)
2440         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2441       else
2442         {
2443           cmd = line;
2444           while (*line && (*line != ' ' && *line != '\t'))
2445             line++;
2446           if (!*line)
2447             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2448           else
2449             {
2450               *line++ = 0;
2451               while (*line == ' ' || *line == '\t')
2452                 line++;
2453               if (!*line)
2454                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2455               else
2456                 {
2457                   cmdopt = line;
2458                   if (!command_has_option (cmd, cmdopt))
2459                     rc = gpg_error (GPG_ERR_GENERAL);
2460                 }
2461             }
2462         }
2463     }
2464   else
2465     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2466   return rc;
2467 }
2468
2469
2470 \f
2471 /* This function is called by Libassuan to parse the OPTION command.
2472    It has been registered similar to the other Assuan commands.  */
2473 static gpg_error_t
2474 option_handler (assuan_context_t ctx, const char *key, const char *value)
2475 {
2476   ctrl_t ctrl = assuan_get_pointer (ctx);
2477   gpg_error_t err = 0;
2478
2479   if (!strcmp (key, "agent-awareness"))
2480     {
2481       /* The value is a version string telling us of which agent
2482          version the caller is aware of.  */
2483       ctrl->server_local->allow_fully_canceled =
2484         gnupg_compare_version (value, "2.1.0");
2485     }
2486   else if (!strcmp (key, "putenv"))
2487     {
2488       /* Change the session's environment to be used for the
2489          Pinentry.  Valid values are:
2490           <NAME>            Delete envvar NAME
2491           <KEY>=            Set envvar NAME to the empty string
2492           <KEY>=<VALUE>     Set envvar NAME to VALUE
2493       */
2494       err = session_env_putenv (ctrl->session_env, value);
2495     }
2496   else if (!strcmp (key, "display"))
2497     {
2498       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2499     }
2500   else if (!strcmp (key, "ttyname"))
2501     {
2502       if (!opt.keep_tty)
2503         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2504     }
2505   else if (!strcmp (key, "ttytype"))
2506     {
2507       if (!opt.keep_tty)
2508         err = session_env_setenv (ctrl->session_env, "TERM", value);
2509     }
2510   else if (!strcmp (key, "lc-ctype"))
2511     {
2512       if (ctrl->lc_ctype)
2513         xfree (ctrl->lc_ctype);
2514       ctrl->lc_ctype = xtrystrdup (value);
2515       if (!ctrl->lc_ctype)
2516         return out_of_core ();
2517     }
2518   else if (!strcmp (key, "lc-messages"))
2519     {
2520       if (ctrl->lc_messages)
2521         xfree (ctrl->lc_messages);
2522       ctrl->lc_messages = xtrystrdup (value);
2523       if (!ctrl->lc_messages)
2524         return out_of_core ();
2525     }
2526   else if (!strcmp (key, "xauthority"))
2527     {
2528       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
2529     }
2530   else if (!strcmp (key, "pinentry-user-data"))
2531     {
2532       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
2533     }
2534   else if (!strcmp (key, "use-cache-for-signing"))
2535     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
2536   else if (!strcmp (key, "allow-pinentry-notify"))
2537     ctrl->server_local->allow_pinentry_notify = 1;
2538   else if (!strcmp (key, "pinentry-mode"))
2539     {
2540       if (!strcmp (value, "ask") || !strcmp (value, "default"))
2541         ctrl->pinentry_mode = PINENTRY_MODE_ASK;
2542       else if (!strcmp (value, "cancel"))
2543         ctrl->pinentry_mode = PINENTRY_MODE_CANCEL;
2544       else if (!strcmp (value, "error"))
2545         ctrl->pinentry_mode = PINENTRY_MODE_ERROR;
2546       else if (!strcmp (value, "loopback"))
2547         {
2548           if (opt.allow_loopback_pinentry)
2549             ctrl->pinentry_mode = PINENTRY_MODE_LOOPBACK;
2550           else
2551             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2552         }
2553       else
2554         err = gpg_error (GPG_ERR_INV_VALUE);
2555     }
2556   else if (!strcmp (key, "cache-ttl-opt-preset"))
2557     {
2558       ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
2559     }
2560   else if (!strcmp (key, "s2k-count"))
2561     {
2562       ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
2563       if (ctrl->s2k_count && ctrl->s2k_count < 65536)
2564         {
2565           ctrl->s2k_count = 0;
2566         }
2567     }
2568   else
2569     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2570
2571   return err;
2572 }
2573
2574
2575
2576 \f
2577 /* Called by libassuan after all commands. ERR is the error from the
2578    last assuan operation and not the one returned from the command. */
2579 static void
2580 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
2581 {
2582   ctrl_t ctrl = assuan_get_pointer (ctx);
2583
2584   (void)err;
2585
2586   /* Switch off any I/O monitor controlled logging pausing. */
2587   ctrl->server_local->pause_io_logging = 0;
2588 }
2589
2590
2591 /* This function is called by libassuan for all I/O.  We use it here
2592    to disable logging for the GETEVENTCOUNTER commands.  This is so
2593    that the debug output won't get cluttered by this primitive
2594    command.  */
2595 static unsigned int
2596 io_monitor (assuan_context_t ctx, void *hook, int direction,
2597             const char *line, size_t linelen)
2598 {
2599   ctrl_t ctrl = assuan_get_pointer (ctx);
2600
2601   (void) hook;
2602
2603   /* Note that we only check for the uppercase name.  This allows to
2604      see the logging for debugging if using a non-upercase command
2605      name. */
2606   if (ctx && direction == ASSUAN_IO_FROM_PEER
2607       && linelen >= 15
2608       && !strncmp (line, "GETEVENTCOUNTER", 15)
2609       && (linelen == 15 || spacep (line+15)))
2610     {
2611       ctrl->server_local->pause_io_logging = 1;
2612     }
2613
2614   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2615 }
2616
2617
2618 /* Return true if the command CMD implements the option OPT.  */
2619 static int
2620 command_has_option (const char *cmd, const char *cmdopt)
2621 {
2622   if (!strcmp (cmd, "GET_PASSPHRASE"))
2623     {
2624       if (!strcmp (cmdopt, "repeat"))
2625           return 1;
2626     }
2627
2628   return 0;
2629 }
2630
2631
2632 /* Tell Libassuan about our commands.  Also register the other Assuan
2633    handlers. */
2634 static int
2635 register_commands (assuan_context_t ctx)
2636 {
2637   static struct {
2638     const char *name;
2639     assuan_handler_t handler;
2640     const char * const help;
2641   } table[] = {
2642     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2643     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2644     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2645     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2646     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2647     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2648     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2649     { "SETHASH",        cmd_sethash,   hlp_sethash },
2650     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2651     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2652     { "GENKEY",         cmd_genkey,    hlp_genkey },
2653     { "READKEY",        cmd_readkey,   hlp_readkey },
2654     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2655     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2656     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2657     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2658     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2659     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2660     { "LEARN",          cmd_learn,     hlp_learn },
2661     { "PASSWD",         cmd_passwd,    hlp_passwd },
2662     { "INPUT",          NULL },
2663     { "OUTPUT",         NULL },
2664     { "SCD",            cmd_scd,       hlp_scd },
2665     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
2666     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
2667     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
2668     { "GETVAL",         cmd_getval,    hlp_getval },
2669     { "PUTVAL",         cmd_putval,    hlp_putval },
2670     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2671     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2672     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2673     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2674     { NULL }
2675   };
2676   int i, rc;
2677
2678   for (i=0; table[i].name; i++)
2679     {
2680       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2681                                     table[i].help);
2682       if (rc)
2683         return rc;
2684     }
2685   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2686   assuan_register_reset_notify (ctx, reset_notify);
2687   assuan_register_option_handler (ctx, option_handler);
2688   return 0;
2689 }
2690
2691
2692 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2693    simple piper server, otherwise it is a regular server.  CTRL is the
2694    control structure for this connection; it has only the basic
2695    intialization. */
2696 void
2697 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2698 {
2699   int rc;
2700   assuan_context_t ctx = NULL;
2701
2702   rc = assuan_new (&ctx);
2703   if (rc)
2704     {
2705       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2706       agent_exit (2);
2707     }
2708
2709   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2710     {
2711       assuan_fd_t filedes[2];
2712
2713       filedes[0] = assuan_fdopen (0);
2714       filedes[1] = assuan_fdopen (1);
2715       rc = assuan_init_pipe_server (ctx, filedes);
2716     }
2717   else if (listen_fd != GNUPG_INVALID_FD)
2718     {
2719       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2720       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2721          this branch is currently not used.  */
2722     }
2723   else
2724     {
2725       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2726     }
2727   if (rc)
2728     {
2729       log_error ("failed to initialize the server: %s\n",
2730                  gpg_strerror(rc));
2731       agent_exit (2);
2732     }
2733   rc = register_commands (ctx);
2734   if (rc)
2735     {
2736       log_error ("failed to register commands with Assuan: %s\n",
2737                  gpg_strerror(rc));
2738       agent_exit (2);
2739     }
2740
2741   assuan_set_pointer (ctx, ctrl);
2742   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2743   ctrl->server_local->assuan_ctx = ctx;
2744   ctrl->server_local->use_cache_for_signing = 1;
2745   ctrl->digest.raw_value = 0;
2746
2747   assuan_set_io_monitor (ctx, io_monitor, NULL);
2748
2749   for (;;)
2750     {
2751       rc = assuan_accept (ctx);
2752       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
2753         {
2754           break;
2755         }
2756       else if (rc)
2757         {
2758           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2759           break;
2760         }
2761
2762       rc = assuan_process (ctx);
2763       if (rc)
2764         {
2765           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2766           continue;
2767         }
2768     }
2769
2770   /* Reset the nonce caches.  */
2771   clear_nonce_cache (ctrl);
2772
2773   /* Reset the SCD if needed. */
2774   agent_reset_scd (ctrl);
2775
2776   /* Reset the pinentry (in case of popup messages). */
2777   agent_reset_query (ctrl);
2778
2779   /* Cleanup.  */
2780   assuan_release (ctx);
2781   xfree (ctrl->server_local->keydesc);
2782   xfree (ctrl->server_local->import_key);
2783   xfree (ctrl->server_local->export_key);
2784   if (ctrl->server_local->stopme)
2785     agent_exit (0);
2786   xfree (ctrl->server_local);
2787   ctrl->server_local = NULL;
2788 }
2789
2790
2791 /* Helper for the pinentry loopback mode.  It merely passes the
2792    parameters on to the client.  */
2793 gpg_error_t
2794 pinentry_loopback(ctrl_t ctrl, const char *keyword,
2795                   unsigned char **buffer, size_t *size,
2796                   size_t max_length)
2797 {
2798   gpg_error_t rc;
2799   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2800   char buf[50];
2801
2802   snprintf (buf, sizeof (buf), "%u", max_length);
2803   rc = assuan_write_status (ctx, "INQUIRE_MAXLEN", buf);
2804   if (rc)
2805     return rc;
2806
2807   assuan_begin_confidential (ctx);
2808   rc = assuan_inquire (ctx, keyword, buffer, size, max_length);
2809   assuan_end_confidential (ctx);
2810   return rc;
2811 }