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