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