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