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