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