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