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