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