agent: New function agent_print_status.
[gnupg.git] / agent / command.c
1 /* command.c - gpg-agent command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010,
3  *               2011  Free Software Foundation, Inc.
4  *
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       memset (p, 0, 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   char any_counter[25];
503   char key_counter[25];
504   char card_counter[25];
505
506   (void)line;
507
508   snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any);
509   snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key);
510   snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card);
511
512   return agent_write_status (ctrl, "EVENTCOUNTER",
513                              any_counter,
514                              key_counter,
515                              card_counter,
516                              NULL);
517 }
518
519
520 /* This function should be called once for all key removals or
521    additions.  This function is assured not to do any context
522    switches. */
523 void
524 bump_key_eventcounter (void)
525 {
526   eventcounter.key++;
527   eventcounter.any++;
528 }
529
530
531 /* This function should be called for all card reader status
532    changes.  This function is assured not to do any context
533    switches. */
534 void
535 bump_card_eventcounter (void)
536 {
537   eventcounter.card++;
538   eventcounter.any++;
539 }
540
541
542
543 \f
544 static const char hlp_istrusted[] =
545   "ISTRUSTED <hexstring_with_fingerprint>\n"
546   "\n"
547   "Return OK when we have an entry with this fingerprint in our\n"
548   "trustlist";
549 static gpg_error_t
550 cmd_istrusted (assuan_context_t ctx, char *line)
551 {
552   ctrl_t ctrl = assuan_get_pointer (ctx);
553   int rc, n, i;
554   char *p;
555   char fpr[41];
556
557   /* Parse the fingerprint value. */
558   for (p=line,n=0; hexdigitp (p); p++, n++)
559     ;
560   if (*p || !(n == 40 || n == 32))
561     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
562   i = 0;
563   if (n==32)
564     {
565       strcpy (fpr, "00000000");
566       i += 8;
567     }
568   for (p=line; i < 40; p++, i++)
569     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
570   fpr[i] = 0;
571   rc = agent_istrusted (ctrl, fpr, NULL);
572   if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
573     return rc;
574   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
575     return gpg_error (GPG_ERR_NOT_TRUSTED);
576   else
577     return leave_cmd (ctx, rc);
578 }
579
580
581 static const char hlp_listtrusted[] =
582   "LISTTRUSTED\n"
583   "\n"
584   "List all entries from the trustlist.";
585 static gpg_error_t
586 cmd_listtrusted (assuan_context_t ctx, char *line)
587 {
588   int rc;
589
590   (void)line;
591
592   rc = agent_listtrusted (ctx);
593   return leave_cmd (ctx, rc);
594 }
595
596
597 static const char hlp_martrusted[] =
598   "MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>\n"
599   "\n"
600   "Store a new key in into the trustlist.";
601 static gpg_error_t
602 cmd_marktrusted (assuan_context_t ctx, char *line)
603 {
604   ctrl_t ctrl = assuan_get_pointer (ctx);
605   int rc, n, i;
606   char *p;
607   char fpr[41];
608   int flag;
609
610   /* parse the fingerprint value */
611   for (p=line,n=0; hexdigitp (p); p++, n++)
612     ;
613   if (!spacep (p) || !(n == 40 || n == 32))
614     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
615   i = 0;
616   if (n==32)
617     {
618       strcpy (fpr, "00000000");
619       i += 8;
620     }
621   for (p=line; i < 40; p++, i++)
622     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
623   fpr[i] = 0;
624
625   while (spacep (p))
626     p++;
627   flag = *p++;
628   if ( (flag != 'S' && flag != 'P') || !spacep (p) )
629     return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
630   while (spacep (p))
631     p++;
632
633   rc = agent_marktrusted (ctrl, p, fpr, flag);
634   return leave_cmd (ctx, rc);
635 }
636
637
638
639 \f
640 static const char hlp_havekey[] =
641   "HAVEKEY <hexstrings_with_keygrips>\n"
642   "\n"
643   "Return success if at least one of the secret keys with the given\n"
644   "keygrips is available.";
645 static gpg_error_t
646 cmd_havekey (assuan_context_t ctx, char *line)
647 {
648   gpg_error_t err;
649   unsigned char buf[20];
650
651   do
652     {
653       err = parse_keygrip (ctx, line, buf);
654       if (err)
655         return err;
656
657       if (!agent_key_available (buf))
658         return 0; /* Found.  */
659
660       while (*line && *line != ' ' && *line != '\t')
661         line++;
662       while (*line == ' ' || *line == '\t')
663         line++;
664     }
665   while (*line);
666
667   /* No leave_cmd() here because errors are expected and would clutter
668      the log.  */
669   return gpg_error (GPG_ERR_NO_SECKEY);
670 }
671
672
673 static const char hlp_sigkey[] =
674   "SIGKEY <hexstring_with_keygrip>\n"
675   "SETKEY <hexstring_with_keygrip>\n"
676   "\n"
677   "Set the  key used for a sign or decrypt operation.";
678 static gpg_error_t
679 cmd_sigkey (assuan_context_t ctx, char *line)
680 {
681   int rc;
682   ctrl_t ctrl = assuan_get_pointer (ctx);
683
684   rc = parse_keygrip (ctx, line, ctrl->keygrip);
685   if (rc)
686     return rc;
687   ctrl->have_keygrip = 1;
688   return 0;
689 }
690
691
692 static const char hlp_setkeydesc[] =
693   "SETKEYDESC plus_percent_escaped_string\n"
694   "\n"
695   "Set a description to be used for the next PKSIGN, PKDECRYPT, IMPORT_KEY\n"
696   "or EXPORT_KEY operation if this operation requires a passphrase.  If\n"
697   "this command is not used a default text will be used.  Note, that\n"
698   "this description implictly selects the label used for the entry\n"
699   "box; if the string contains the string PIN (which in general will\n"
700   "not be translated), \"PIN\" is used, otherwise the translation of\n"
701   "\"passphrase\" is used.  The description string should not contain\n"
702   "blanks unless they are percent or '+' escaped.\n"
703   "\n"
704   "The description is only valid for the next PKSIGN, PKDECRYPT,\n"
705   "IMPORT_KEY or EXPORT_KEY operation.";
706 static gpg_error_t
707 cmd_setkeydesc (assuan_context_t ctx, char *line)
708 {
709   ctrl_t ctrl = assuan_get_pointer (ctx);
710   char *desc, *p;
711
712   for (p=line; *p == ' '; p++)
713     ;
714   desc = p;
715   p = strchr (desc, ' ');
716   if (p)
717     *p = 0; /* We ignore any garbage; we might late use it for other args. */
718
719   if (!desc || !*desc)
720     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
721
722   /* Note, that we only need to replace the + characters and should
723      leave the other escaping in place because the escaped string is
724      send verbatim to the pinentry which does the unescaping (but not
725      the + replacing) */
726   plus_to_blank (desc);
727
728   xfree (ctrl->server_local->keydesc);
729   ctrl->server_local->keydesc = xtrystrdup (desc);
730   if (!ctrl->server_local->keydesc)
731     return out_of_core ();
732   return 0;
733 }
734
735
736 static const char hlp_sethash[] =
737   "SETHASH (--hash=<name>)|(<algonumber>) <hexstring>\n"
738   "\n"
739   "The client can use this command to tell the server about the data\n"
740   "(which usually is a hash) to be signed.";
741 static gpg_error_t
742 cmd_sethash (assuan_context_t ctx, char *line)
743 {
744   int rc;
745   size_t n;
746   char *p;
747   ctrl_t ctrl = assuan_get_pointer (ctx);
748   unsigned char *buf;
749   char *endp;
750   int algo;
751
752   /* Parse the alternative hash options which may be used instead of
753      the algo number.  */
754   if (has_option_name (line, "--hash"))
755     {
756       if (has_option (line, "--hash=sha1"))
757         algo = GCRY_MD_SHA1;
758       else if (has_option (line, "--hash=sha224"))
759         algo = GCRY_MD_SHA224;
760       else if (has_option (line, "--hash=sha256"))
761         algo = GCRY_MD_SHA256;
762       else if (has_option (line, "--hash=sha384"))
763         algo = GCRY_MD_SHA384;
764       else if (has_option (line, "--hash=sha512"))
765         algo = GCRY_MD_SHA512;
766       else if (has_option (line, "--hash=rmd160"))
767         algo = GCRY_MD_RMD160;
768       else if (has_option (line, "--hash=md5"))
769         algo = GCRY_MD_MD5;
770       else if (has_option (line, "--hash=tls-md5sha1"))
771         algo = MD_USER_TLS_MD5SHA1;
772       else
773         return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
774     }
775   else
776     algo = 0;
777
778   line = skip_options (line);
779
780   if (!algo)
781     {
782       /* No hash option has been given: require an algo number instead  */
783       algo = (int)strtoul (line, &endp, 10);
784       for (line = endp; *line == ' ' || *line == '\t'; line++)
785         ;
786       if (!algo || gcry_md_test_algo (algo))
787         return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
788     }
789   ctrl->digest.algo = algo;
790   ctrl->digest.raw_value = 0;
791
792   /* Parse the hash value. */
793   n = 0;
794   rc = parse_hexstring (ctx, line, &n);
795   if (rc)
796     return rc;
797   n /= 2;
798   if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
799     ;
800   else if (n != 16 && n != 20 && n != 24
801            && n != 28 && n != 32 && n != 48 && n != 64)
802     return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
803
804   if (n > MAX_DIGEST_LEN)
805     return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
806
807   buf = ctrl->digest.value;
808   ctrl->digest.valuelen = n;
809   for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
810     buf[n] = xtoi_2 (p);
811   for (; n < ctrl->digest.valuelen; n++)
812     buf[n] = 0;
813   return 0;
814 }
815
816
817 static const char hlp_pksign[] =
818   "PKSIGN [<options>] [<cache_nonce>]\n"
819   "\n"
820   "Perform the actual sign operation.  Neither input nor output are\n"
821   "sensitive to eavesdropping.";
822 static gpg_error_t
823 cmd_pksign (assuan_context_t ctx, char *line)
824 {
825   int rc;
826   cache_mode_t cache_mode = CACHE_MODE_NORMAL;
827   ctrl_t ctrl = assuan_get_pointer (ctx);
828   membuf_t outbuf;
829   char *cache_nonce = NULL;
830   char *p;
831
832   line = skip_options (line);
833
834   p = line;
835   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
836     ;
837   *p = '\0';
838   if (*line)
839     cache_nonce = xtrystrdup (line);
840
841   if (opt.ignore_cache_for_signing)
842     cache_mode = CACHE_MODE_IGNORE;
843   else if (!ctrl->server_local->use_cache_for_signing)
844     cache_mode = CACHE_MODE_IGNORE;
845
846   init_membuf (&outbuf, 512);
847
848   rc = agent_pksign (ctrl, cache_nonce, ctrl->server_local->keydesc,
849                      &outbuf, cache_mode);
850   if (rc)
851     clear_outbuf (&outbuf);
852   else
853     rc = write_and_clear_outbuf (ctx, &outbuf);
854
855   xfree (cache_nonce);
856   xfree (ctrl->server_local->keydesc);
857   ctrl->server_local->keydesc = NULL;
858   return leave_cmd (ctx, rc);
859 }
860
861
862 static const char hlp_pkdecrypt[] =
863   "PKDECRYPT [<options>]\n"
864   "\n"
865   "Perform the actual decrypt operation.  Input is not\n"
866   "sensitive to eavesdropping.";
867 static gpg_error_t
868 cmd_pkdecrypt (assuan_context_t ctx, char *line)
869 {
870   int rc;
871   ctrl_t ctrl = assuan_get_pointer (ctx);
872   unsigned char *value;
873   size_t valuelen;
874   membuf_t outbuf;
875
876   (void)line;
877
878   /* First inquire the data to decrypt */
879   rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_CIPHERTEXT);
880   if (!rc)
881     rc = assuan_inquire (ctx, "CIPHERTEXT",
882                         &value, &valuelen, MAXLEN_CIPHERTEXT);
883   if (rc)
884     return rc;
885
886   init_membuf (&outbuf, 512);
887
888   rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
889                         value, valuelen, &outbuf);
890   xfree (value);
891   if (rc)
892     clear_outbuf (&outbuf);
893   else
894     rc = write_and_clear_outbuf (ctx, &outbuf);
895   xfree (ctrl->server_local->keydesc);
896   ctrl->server_local->keydesc = NULL;
897   return leave_cmd (ctx, rc);
898 }
899
900
901 static const char hlp_genkey[] =
902   "GENKEY [--no-protection] [--preset] [<cache_nonce>]\n"
903   "\n"
904   "Generate a new key, store the secret part and return the public\n"
905   "part.  Here is an example transaction:\n"
906   "\n"
907   "  C: GENKEY\n"
908   "  S: INQUIRE KEYPARAM\n"
909   "  C: D (genkey (rsa (nbits  1024)))\n"
910   "  C: END\n"
911   "  S: D (public-key\n"
912   "  S: D   (rsa (n 326487324683264) (e 10001)))\n"
913   "  S: OK key created\n"
914   "\n"
915   "When the --preset option is used the passphrase for the generated\n"
916   "key will be added to the cache.\n"
917   "\n";
918 static gpg_error_t
919 cmd_genkey (assuan_context_t ctx, char *line)
920 {
921   ctrl_t ctrl = assuan_get_pointer (ctx);
922   int rc;
923   int no_protection;
924   unsigned char *value;
925   size_t valuelen;
926   membuf_t outbuf;
927   char *cache_nonce = NULL;
928   int opt_preset;
929   char *p;
930
931   opt_preset = has_option (line, "--preset");
932   no_protection = has_option (line, "--no-protection");
933   line = skip_options (line);
934
935   p = line;
936   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
937     ;
938   *p = '\0';
939   if (*line)
940     cache_nonce = xtrystrdup (line);
941
942   /* First inquire the parameters */
943   rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_KEYPARAM);
944   if (!rc)
945     rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
946   if (rc)
947     return rc;
948
949   init_membuf (&outbuf, 512);
950
951   rc = agent_genkey (ctrl, cache_nonce, (char*)value, valuelen, no_protection,
952                      opt_preset, &outbuf);
953   xfree (value);
954   if (rc)
955     clear_outbuf (&outbuf);
956   else
957     rc = write_and_clear_outbuf (ctx, &outbuf);
958   xfree (cache_nonce);
959   return leave_cmd (ctx, rc);
960 }
961
962
963
964 \f
965 static const char hlp_readkey[] =
966   "READKEY <hexstring_with_keygrip>\n"
967   "\n"
968   "Return the public key for the given keygrip.";
969 static gpg_error_t
970 cmd_readkey (assuan_context_t ctx, char *line)
971 {
972   ctrl_t ctrl = assuan_get_pointer (ctx);
973   int rc;
974   unsigned char grip[20];
975   gcry_sexp_t s_pkey = NULL;
976
977   rc = parse_keygrip (ctx, line, grip);
978   if (rc)
979     return rc; /* Return immediately as this is already an Assuan error code.*/
980
981   rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
982   if (!rc)
983     {
984       size_t len;
985       unsigned char *buf;
986
987       len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
988       assert (len);
989       buf = xtrymalloc (len);
990       if (!buf)
991         rc = gpg_error_from_syserror ();
992       else
993         {
994           len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
995           assert (len);
996           rc = assuan_send_data (ctx, buf, len);
997           xfree (buf);
998         }
999       gcry_sexp_release (s_pkey);
1000     }
1001
1002   return leave_cmd (ctx, rc);
1003 }
1004
1005
1006 \f
1007 static const char hlp_keyinfo[] =
1008   "KEYINFO [--list] [--data] [--ssh-fpr] <keygrip>\n"
1009   "\n"
1010   "Return information about the key specified by the KEYGRIP.  If the\n"
1011   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
1012   "--list is given the keygrip is ignored and information about all\n"
1013   "available keys are returned.  The information is returned as a\n"
1014   "status line unless --data was specified, with this format:\n"
1015   "\n"
1016   "  KEYINFO <keygrip> <type> <serialno> <idstr> <cached> <protection> <fpr>\n"
1017   "\n"
1018   "KEYGRIP is the keygrip.\n"
1019   "\n"
1020   "TYPE is describes the type of the key:\n"
1021   "    'D' - Regular key stored on disk,\n"
1022   "    'T' - Key is stored on a smartcard (token),\n"
1023   "    '-' - Unknown type.\n"
1024   "\n"
1025   "SERIALNO is an ASCII string with the serial number of the\n"
1026   "         smartcard.  If the serial number is not known a single\n"
1027   "         dash '-' is used instead.\n"
1028   "\n"
1029   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
1030   "      is not known a dash is used instead.\n"
1031   "\n"
1032   "CACHED is 1 if the passphrase for the key was found in the key cache.\n"
1033   "       If not, a '-' is used instead.\n"
1034   "\n"
1035   "PROTECTION describes the key protection type:\n"
1036   "    'P' - The key is protected with a passphrase,\n"
1037   "    'C' - The key is not protected,\n"
1038   "    '-' - Unknown protection.\n"
1039   "\n"
1040   "FPR returns the formatted ssh-style fingerprint of the key.  It is only\n"
1041   "    print if the option --ssh-fpr has been used. '-' is printed if the\n"
1042   "    fingerprint is not available.\n"
1043   "\n"
1044   "More information may be added in the future.";
1045 static gpg_error_t
1046 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
1047                 int data, int with_ssh_fpr)
1048 {
1049   gpg_error_t err;
1050   char hexgrip[40+1];
1051   char *fpr = NULL;
1052   int keytype;
1053   unsigned char *shadow_info = NULL;
1054   char *serialno = NULL;
1055   char *idstr = NULL;
1056   const char *keytypestr;
1057   const char *cached;
1058   const char *protectionstr;
1059   char *pw;
1060
1061   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
1062   if (err)
1063     goto leave;
1064
1065   /* Reformat the grip so that we use uppercase as good style. */
1066   bin2hex (grip, 20, hexgrip);
1067
1068   switch (keytype)
1069     {
1070     case PRIVATE_KEY_CLEAR: protectionstr = "C"; keytypestr = "D";
1071       break;
1072     case PRIVATE_KEY_PROTECTED: protectionstr = "P"; keytypestr = "D";
1073       break;
1074     case PRIVATE_KEY_SHADOWED: protectionstr = "-"; keytypestr = "T";
1075       break;
1076     default: protectionstr = "-"; keytypestr = "-";
1077       break;
1078     }
1079
1080   /* Compute the ssh fingerprint if requested.  */
1081   if (with_ssh_fpr)
1082     {
1083       gcry_sexp_t key;
1084
1085       if (!agent_raw_key_from_file (ctrl, grip, &key))
1086         {
1087           ssh_get_fingerprint_string (key, &fpr);
1088           gcry_sexp_release (key);
1089         }
1090     }
1091
1092   /* Here we have a little race by doing the cache check separately
1093      from the retrieval function.  Given that the cache flag is only a
1094      hint, it should not really matter.  */
1095   pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL);
1096   cached = pw ? "1" : "-";
1097   xfree (pw);
1098
1099   if (shadow_info)
1100     {
1101       err = parse_shadow_info (shadow_info, &serialno, &idstr);
1102       if (err)
1103         goto leave;
1104     }
1105
1106   if (!data)
1107     err = agent_write_status (ctrl, "KEYINFO",
1108                               hexgrip,
1109                               keytypestr,
1110                               serialno? serialno : "-",
1111                               idstr? idstr : "-",
1112                               cached,
1113                               protectionstr,
1114                               fpr? fpr : "-",
1115                               NULL);
1116   else
1117     {
1118       char *string;
1119
1120       string = xtryasprintf ("%s %s %s %s %s %s %s\n",
1121                              hexgrip, keytypestr,
1122                              serialno? serialno : "-",
1123                              idstr? idstr : "-", cached, protectionstr,
1124                              fpr? fpr : "-");
1125       if (!string)
1126         err = gpg_error_from_syserror ();
1127       else
1128         err = assuan_send_data (ctx, string, strlen(string));
1129       xfree (string);
1130     }
1131
1132  leave:
1133   xfree (fpr);
1134   xfree (shadow_info);
1135   xfree (serialno);
1136   xfree (idstr);
1137   return err;
1138 }
1139
1140
1141 /* Entry int for the command KEYINFO.  This function handles the
1142    command option processing.  For details see hlp_keyinfo above.  */
1143 static gpg_error_t
1144 cmd_keyinfo (assuan_context_t ctx, char *line)
1145 {
1146   ctrl_t ctrl = assuan_get_pointer (ctx);
1147   int err;
1148   unsigned char grip[20];
1149   DIR *dir = NULL;
1150   int list_mode;
1151   int opt_data, opt_ssh_fpr;
1152
1153   list_mode = has_option (line, "--list");
1154   opt_data = has_option (line, "--data");
1155   opt_ssh_fpr = has_option (line, "--ssh-fpr");
1156   line = skip_options (line);
1157
1158   if (list_mode)
1159     {
1160       char *dirname;
1161       struct dirent *dir_entry;
1162       char hexgrip[41];
1163
1164       dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1165       if (!dirname)
1166         {
1167           err = gpg_error_from_syserror ();
1168           goto leave;
1169         }
1170       dir = opendir (dirname);
1171       if (!dir)
1172         {
1173           err = gpg_error_from_syserror ();
1174           xfree (dirname);
1175           goto leave;
1176         }
1177       xfree (dirname);
1178
1179       while ( (dir_entry = readdir (dir)) )
1180         {
1181           if (strlen (dir_entry->d_name) != 44
1182               || strcmp (dir_entry->d_name + 40, ".key"))
1183             continue;
1184           strncpy (hexgrip, dir_entry->d_name, 40);
1185           hexgrip[40] = 0;
1186
1187           if ( hex2bin (hexgrip, grip, 20) < 0 )
1188             continue; /* Bad hex string.  */
1189
1190           err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr);
1191           if (err)
1192             goto leave;
1193         }
1194       err = 0;
1195     }
1196   else
1197     {
1198       err = parse_keygrip (ctx, line, grip);
1199       if (err)
1200         goto leave;
1201       err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr);
1202     }
1203
1204  leave:
1205   if (dir)
1206     closedir (dir);
1207   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1208     leave_cmd (ctx, err);
1209   return err;
1210 }
1211
1212
1213 \f
1214 /* Helper for cmd_get_passphrase.  */
1215 static int
1216 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1217 {
1218   size_t n;
1219   int rc;
1220
1221   assuan_begin_confidential (ctx);
1222   n = strlen (pw);
1223   if (via_data)
1224     rc = assuan_send_data (ctx, pw, n);
1225   else
1226     {
1227       char *p = xtrymalloc_secure (n*2+1);
1228       if (!p)
1229         rc = gpg_error_from_syserror ();
1230       else
1231         {
1232           bin2hex (pw, n, p);
1233           rc = assuan_set_okay_line (ctx, p);
1234           xfree (p);
1235         }
1236     }
1237   return rc;
1238 }
1239
1240
1241 static const char hlp_get_passphrase[] =
1242   "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1243   "               [--qualitybar] <cache_id>\n"
1244   "               [<error_message> <prompt> <description>]\n"
1245   "\n"
1246   "This function is usually used to ask for a passphrase to be used\n"
1247   "for conventional encryption, but may also be used by programs which\n"
1248   "need specal handling of passphrases.  This command uses a syntax\n"
1249   "which helps clients to use the agent with minimum effort.  The\n"
1250   "agent either returns with an error or with a OK followed by the hex\n"
1251   "encoded passphrase.  Note that the length of the strings is\n"
1252   "implicitly limited by the maximum length of a command.\n"
1253   "\n"
1254   "If the option \"--data\" is used the passphrase is returned by usual\n"
1255   "data lines and not on the okay line.\n"
1256   "\n"
1257   "If the option \"--check\" is used the passphrase constraints checks as\n"
1258   "implemented by gpg-agent are applied.  A check is not done if the\n"
1259   "passphrase has been found in the cache.\n"
1260   "\n"
1261   "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1262   "cache the user will not be asked to enter a passphrase but the error\n"
1263   "code GPG_ERR_NO_DATA is returned.  \n"
1264   "\n"
1265   "If the option \"--qualitybar\" is used a visual indication of the\n"
1266   "entered passphrase quality is shown.  (Unless no minimum passphrase\n"
1267   "length has been configured.)";
1268 static gpg_error_t
1269 cmd_get_passphrase (assuan_context_t ctx, char *line)
1270 {
1271   ctrl_t ctrl = assuan_get_pointer (ctx);
1272   int rc;
1273   char *pw;
1274   char *response;
1275   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1276   const char *desc2 = _("Please re-enter this passphrase");
1277   char *p;
1278   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1279   int opt_repeat = 0;
1280   char *repeat_errtext = NULL;
1281
1282   opt_data = has_option (line, "--data");
1283   opt_check = has_option (line, "--check");
1284   opt_no_ask = has_option (line, "--no-ask");
1285   if (has_option_name (line, "--repeat"))
1286     {
1287       p = option_value (line, "--repeat");
1288       if (p)
1289         opt_repeat = atoi (p);
1290       else
1291         opt_repeat = 1;
1292     }
1293   opt_qualbar = has_option (line, "--qualitybar");
1294   line = skip_options (line);
1295
1296   cacheid = line;
1297   p = strchr (cacheid, ' ');
1298   if (p)
1299     {
1300       *p++ = 0;
1301       while (*p == ' ')
1302         p++;
1303       errtext = p;
1304       p = strchr (errtext, ' ');
1305       if (p)
1306         {
1307           *p++ = 0;
1308           while (*p == ' ')
1309             p++;
1310           prompt = p;
1311           p = strchr (prompt, ' ');
1312           if (p)
1313             {
1314               *p++ = 0;
1315               while (*p == ' ')
1316                 p++;
1317               desc = p;
1318               p = strchr (desc, ' ');
1319               if (p)
1320                 *p = 0; /* Ignore trailing garbage. */
1321             }
1322         }
1323     }
1324   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1325     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1326   if (!desc)
1327     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1328
1329   if (!strcmp (cacheid, "X"))
1330     cacheid = NULL;
1331   if (!strcmp (errtext, "X"))
1332     errtext = NULL;
1333   if (!strcmp (prompt, "X"))
1334     prompt = NULL;
1335   if (!strcmp (desc, "X"))
1336     desc = NULL;
1337
1338   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_NORMAL) : NULL;
1339   if (pw)
1340     {
1341       rc = send_back_passphrase (ctx, opt_data, pw);
1342       xfree (pw);
1343     }
1344   else if (opt_no_ask)
1345     rc = gpg_error (GPG_ERR_NO_DATA);
1346   else
1347     {
1348       /* Note, that we only need to replace the + characters and
1349          should leave the other escaping in place because the escaped
1350          string is send verbatim to the pinentry which does the
1351          unescaping (but not the + replacing) */
1352       if (errtext)
1353         plus_to_blank (errtext);
1354       if (prompt)
1355         plus_to_blank (prompt);
1356       if (desc)
1357         plus_to_blank (desc);
1358
1359     next_try:
1360       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1361                                  repeat_errtext? repeat_errtext:errtext,
1362                                  opt_qualbar);
1363       xfree (repeat_errtext);
1364       repeat_errtext = NULL;
1365       if (!rc)
1366         {
1367           int i;
1368
1369           if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1370             {
1371               xfree (response);
1372               goto next_try;
1373             }
1374           for (i = 0; i < opt_repeat; i++)
1375             {
1376               char *response2;
1377
1378               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1379                                          errtext, 0);
1380               if (rc)
1381                 break;
1382               if (strcmp (response2, response))
1383                 {
1384                   xfree (response2);
1385                   xfree (response);
1386                   repeat_errtext = try_percent_escape
1387                     (_("does not match - try again"), NULL);
1388                   if (!repeat_errtext)
1389                     {
1390                       rc = gpg_error_from_syserror ();
1391                       break;
1392                     }
1393                   goto next_try;
1394                 }
1395               xfree (response2);
1396             }
1397           if (!rc)
1398             {
1399               if (cacheid)
1400                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1401               rc = send_back_passphrase (ctx, opt_data, response);
1402             }
1403           xfree (response);
1404         }
1405     }
1406
1407   return leave_cmd (ctx, rc);
1408 }
1409
1410
1411 static const char hlp_clear_passphrase[] =
1412   "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n"
1413   "\n"
1414   "may be used to invalidate the cache entry for a passphrase.  The\n"
1415   "function returns with OK even when there is no cached passphrase.\n"
1416   "The --mode=normal option is used to clear an entry for a cacheid\n"
1417   "added by the agent.\n";
1418 static gpg_error_t
1419 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1420 {
1421   char *cacheid = NULL;
1422   char *p;
1423   int opt_normal;
1424
1425   opt_normal = has_option (line, "--mode=normal");
1426   line = skip_options (line);
1427
1428   /* parse the stuff */
1429   for (p=line; *p == ' '; p++)
1430     ;
1431   cacheid = p;
1432   p = strchr (cacheid, ' ');
1433   if (p)
1434     *p = 0; /* ignore garbage */
1435   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1436     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1437
1438   agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER,
1439                    NULL, 0);
1440   return 0;
1441 }
1442
1443
1444 static const char hlp_get_confirmation[] =
1445   "GET_CONFIRMATION <description>\n"
1446   "\n"
1447   "This command may be used to ask for a simple confirmation.\n"
1448   "DESCRIPTION is displayed along with a Okay and Cancel button.  This\n"
1449   "command uses a syntax which helps clients to use the agent with\n"
1450   "minimum effort.  The agent either returns with an error or with a\n"
1451   "OK.  Note, that the length of DESCRIPTION is implicitly limited by\n"
1452   "the maximum length of a command. DESCRIPTION should not contain\n"
1453   "any spaces, those must be encoded either percent escaped or simply\n"
1454   "as '+'.";
1455 static gpg_error_t
1456 cmd_get_confirmation (assuan_context_t ctx, char *line)
1457 {
1458   ctrl_t ctrl = assuan_get_pointer (ctx);
1459   int rc;
1460   char *desc = NULL;
1461   char *p;
1462
1463   /* parse the stuff */
1464   for (p=line; *p == ' '; p++)
1465     ;
1466   desc = p;
1467   p = strchr (desc, ' ');
1468   if (p)
1469     *p = 0; /* We ignore any garbage -may be later used for other args. */
1470
1471   if (!desc || !*desc)
1472     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1473
1474   if (!strcmp (desc, "X"))
1475     desc = NULL;
1476
1477   /* Note, that we only need to replace the + characters and should
1478      leave the other escaping in place because the escaped string is
1479      send verbatim to the pinentry which does the unescaping (but not
1480      the + replacing) */
1481   if (desc)
1482     plus_to_blank (desc);
1483
1484   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1485   return leave_cmd (ctx, rc);
1486 }
1487
1488
1489 \f
1490 static const char hlp_learn[] =
1491   "LEARN [--send]\n"
1492   "\n"
1493   "Learn something about the currently inserted smartcard.  With\n"
1494   "--send the new certificates are send back.";
1495 static gpg_error_t
1496 cmd_learn (assuan_context_t ctx, char *line)
1497 {
1498   ctrl_t ctrl = assuan_get_pointer (ctx);
1499   int rc;
1500
1501   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1502   return leave_cmd (ctx, rc);
1503 }
1504
1505
1506 \f
1507 static const char hlp_passwd[] =
1508   "PASSWD [--cache-nonce=<c>] [--passwd-nonce=<s>] [--preset] <hexkeygrip>\n"
1509   "\n"
1510   "Change the passphrase/PIN for the key identified by keygrip in LINE. When\n"
1511   "--preset is used then the new passphrase will be added to the cache.\n";
1512 static gpg_error_t
1513 cmd_passwd (assuan_context_t ctx, char *line)
1514 {
1515   ctrl_t ctrl = assuan_get_pointer (ctx);
1516   gpg_error_t err;
1517   int c;
1518   char *cache_nonce = NULL;
1519   char *passwd_nonce = NULL;
1520   unsigned char grip[20];
1521   gcry_sexp_t s_skey = NULL;
1522   unsigned char *shadow_info = NULL;
1523   char *passphrase = NULL;
1524   char *pend;
1525   int opt_preset;
1526
1527   opt_preset = has_option (line, "--preset");
1528   cache_nonce = option_value (line, "--cache-nonce");
1529   if (cache_nonce)
1530     {
1531       for (pend = cache_nonce; *pend && !spacep (pend); pend++)
1532         ;
1533       c = *pend;
1534       *pend = '\0';
1535       cache_nonce = xtrystrdup (cache_nonce);
1536       *pend = c;
1537       if (!cache_nonce)
1538         {
1539           err = gpg_error_from_syserror ();
1540           goto leave;
1541         }
1542     }
1543
1544   passwd_nonce = option_value (line, "--passwd-nonce");
1545   if (passwd_nonce)
1546     {
1547       for (pend = passwd_nonce; *pend && !spacep (pend); pend++)
1548         ;
1549       c = *pend;
1550       *pend = '\0';
1551       passwd_nonce = xtrystrdup (passwd_nonce);
1552       *pend = c;
1553       if (!passwd_nonce)
1554         {
1555           err = gpg_error_from_syserror ();
1556           goto leave;
1557         }
1558     }
1559
1560   line = skip_options (line);
1561
1562   err = parse_keygrip (ctx, line, grip);
1563   if (err)
1564     goto leave;
1565
1566   ctrl->in_passwd++;
1567   err = agent_key_from_file (ctrl, cache_nonce, ctrl->server_local->keydesc,
1568                              grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1569                              &s_skey, &passphrase);
1570   if (err)
1571     ;
1572   else if (!s_skey)
1573     {
1574       log_error ("changing a smartcard PIN is not yet supported\n");
1575       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1576     }
1577   else
1578     {
1579       char *newpass = NULL;
1580
1581       if (passwd_nonce)
1582         newpass = agent_get_cache (passwd_nonce, CACHE_MODE_NONCE);
1583       err = agent_protect_and_store (ctrl, s_skey, &newpass);
1584       if (!err && passphrase)
1585         {
1586           /* A passphrase existed on the old key and the change was
1587              successful.  Return a nonce for that old passphrase to
1588              let the caller try to unprotect the other subkeys with
1589              the same key.  */
1590           if (!cache_nonce)
1591             {
1592               char buf[12];
1593               gcry_create_nonce (buf, 12);
1594               cache_nonce = bin2hex (buf, 12, NULL);
1595             }
1596           if (cache_nonce
1597               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1598                                    passphrase, CACHE_TTL_NONCE))
1599             {
1600               assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1601               xfree (ctrl->server_local->last_cache_nonce);
1602               ctrl->server_local->last_cache_nonce = cache_nonce;
1603               cache_nonce = NULL;
1604             }
1605           if (newpass)
1606             {
1607               /* If we have a new passphrase (which might be empty) we
1608                  store it under a passwd nonce so that the caller may
1609                  send that nonce again to use it for another key. */
1610               if (!passwd_nonce)
1611                 {
1612                   char buf[12];
1613                   gcry_create_nonce (buf, 12);
1614                   passwd_nonce = bin2hex (buf, 12, NULL);
1615                 }
1616               if (passwd_nonce
1617                   && !agent_put_cache (passwd_nonce, CACHE_MODE_NONCE,
1618                                        newpass, CACHE_TTL_NONCE))
1619                 {
1620                   assuan_write_status (ctx, "PASSWD_NONCE", passwd_nonce);
1621                   xfree (ctrl->server_local->last_passwd_nonce);
1622                   ctrl->server_local->last_passwd_nonce = passwd_nonce;
1623                   passwd_nonce = NULL;
1624                 }
1625             }
1626         }
1627       if (!err && opt_preset)
1628       {
1629           char hexgrip[40+1];
1630           bin2hex(grip, 20, hexgrip);
1631           err = agent_put_cache (hexgrip, CACHE_MODE_ANY, newpass,
1632                                  ctrl->cache_ttl_opt_preset);
1633       }
1634       xfree (newpass);
1635     }
1636   ctrl->in_passwd--;
1637
1638   xfree (ctrl->server_local->keydesc);
1639   ctrl->server_local->keydesc = NULL;
1640
1641  leave:
1642   xfree (passphrase);
1643   gcry_sexp_release (s_skey);
1644   xfree (shadow_info);
1645   xfree (cache_nonce);
1646   return leave_cmd (ctx, err);
1647 }
1648
1649
1650 static const char hlp_preset_passphrase[] =
1651   "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n"
1652   "\n"
1653   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1654   "to passwd for the given time, where -1 means infinite and 0 means\n"
1655   "the default (currently only a timeout of -1 is allowed, which means\n"
1656   "to never expire it).  If passwd is not provided, ask for it via the\n"
1657   "pinentry module unless --inquire is passed in which case the passphrase\n"
1658   "is retrieved from the client via a server inquire.\n";
1659 static gpg_error_t
1660 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1661 {
1662   int rc;
1663   char *grip_clear = NULL;
1664   unsigned char *passphrase = NULL;
1665   int ttl;
1666   size_t len;
1667   int opt_inquire;
1668
1669   if (!opt.allow_preset_passphrase)
1670     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1671
1672   opt_inquire = has_option (line, "--inquire");
1673   line = skip_options (line);
1674   grip_clear = line;
1675   while (*line && (*line != ' ' && *line != '\t'))
1676     line++;
1677   if (!*line)
1678     return gpg_error (GPG_ERR_MISSING_VALUE);
1679   *line = '\0';
1680   line++;
1681   while (*line && (*line == ' ' || *line == '\t'))
1682     line++;
1683
1684   /* Currently, only infinite timeouts are allowed.  */
1685   ttl = -1;
1686   if (line[0] != '-' || line[1] != '1')
1687     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1688   line++;
1689   line++;
1690   while (!(*line != ' ' && *line != '\t'))
1691     line++;
1692
1693   /* Syntax check the hexstring.  */
1694   len = 0;
1695   rc = parse_hexstring (ctx, line, &len);
1696   if (rc)
1697     return rc;
1698   line[len] = '\0';
1699
1700   /* If there is a passphrase, use it.  Currently, a passphrase is
1701      required.  */
1702   if (*line)
1703     {
1704       if (opt_inquire)
1705         {
1706           rc = set_error (GPG_ERR_ASS_PARAMETER,
1707                           "both --inquire and passphrase specified");
1708           goto leave;
1709         }
1710
1711       /* Do in-place conversion.  */
1712       passphrase = line;
1713       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1714         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1715     }
1716   else if (opt_inquire)
1717     {
1718       /* Note that the passphrase will be truncated at any null byte and the
1719        * limit is 480 characters. */
1720       size_t maxlen = 480;
1721
1722       rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", maxlen);
1723       if (!rc)
1724         rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, maxlen);
1725     }
1726   else
1727     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1728
1729   if (!rc)
1730     {
1731       rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1732       if (opt_inquire)
1733         xfree (passphrase);
1734     }
1735
1736 leave:
1737   return leave_cmd (ctx, rc);
1738 }
1739
1740
1741 \f
1742 static const char hlp_scd[] =
1743   "SCD <commands to pass to the scdaemon>\n"
1744   " \n"
1745   "This is a general quote command to redirect everything to the\n"
1746   "SCdaemon.";
1747 static gpg_error_t
1748 cmd_scd (assuan_context_t ctx, char *line)
1749 {
1750   ctrl_t ctrl = assuan_get_pointer (ctx);
1751   int rc;
1752
1753   rc = divert_generic_cmd (ctrl, line, ctx);
1754
1755   return rc;
1756 }
1757
1758
1759 \f
1760 static const char hlp_keywrap_key[] =
1761   "KEYWRAP_KEY [--clear] <mode>\n"
1762   "\n"
1763   "Return a key to wrap another key.  For now the key is returned\n"
1764   "verbatim and and thus makes not much sense because an eavesdropper on\n"
1765   "the gpg-agent connection will see the key as well as the wrapped key.\n"
1766   "However, this function may either be equipped with a public key\n"
1767   "mechanism or not used at all if the key is a pre-shared key.  In any\n"
1768   "case wrapping the import and export of keys is a requirement for\n"
1769   "certain cryptographic validations and thus useful.  The key persists\n"
1770   "a RESET command but may be cleared using the option --clear.\n"
1771   "\n"
1772   "Supported modes are:\n"
1773   "  --import  - Return a key to import a key into gpg-agent\n"
1774   "  --export  - Return a key to export a key from gpg-agent";
1775 static gpg_error_t
1776 cmd_keywrap_key (assuan_context_t ctx, char *line)
1777 {
1778   ctrl_t ctrl = assuan_get_pointer (ctx);
1779   gpg_error_t err = 0;
1780   int clearopt = has_option (line, "--clear");
1781
1782
1783   assuan_begin_confidential (ctx);
1784   if (has_option (line, "--import"))
1785     {
1786       xfree (ctrl->server_local->import_key);
1787       if (clearopt)
1788         ctrl->server_local->import_key = NULL;
1789       else if (!(ctrl->server_local->import_key =
1790                  gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1791         err = gpg_error_from_syserror ();
1792       else
1793         err = assuan_send_data (ctx, ctrl->server_local->import_key,
1794                                 KEYWRAP_KEYSIZE);
1795     }
1796   else if (has_option (line, "--export"))
1797     {
1798       xfree (ctrl->server_local->export_key);
1799       if (clearopt)
1800         ctrl->server_local->export_key = NULL;
1801       else if (!(ctrl->server_local->export_key =
1802             gcry_random_bytes (KEYWRAP_KEYSIZE, GCRY_STRONG_RANDOM)))
1803         err = gpg_error_from_syserror ();
1804       else
1805         err = assuan_send_data (ctx, ctrl->server_local->export_key,
1806                                 KEYWRAP_KEYSIZE);
1807     }
1808   else
1809     err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for MODE");
1810   assuan_end_confidential (ctx);
1811
1812   return leave_cmd (ctx, err);
1813 }
1814
1815
1816 \f
1817 static const char hlp_import_key[] =
1818   "IMPORT_KEY [<cache_nonce>]\n"
1819   "\n"
1820   "Import a secret key into the key store.  The key is expected to be\n"
1821   "encrypted using the current session's key wrapping key (cf. command\n"
1822   "KEYWRAP_KEY) using the AESWRAP-128 algorithm.  This function takes\n"
1823   "no arguments but uses the inquiry \"KEYDATA\" to ask for the actual\n"
1824   "key data.  The unwrapped key must be a canonical S-expression.";
1825 static gpg_error_t
1826 cmd_import_key (assuan_context_t ctx, char *line)
1827 {
1828   ctrl_t ctrl = assuan_get_pointer (ctx);
1829   gpg_error_t err;
1830   unsigned char *wrappedkey = NULL;
1831   size_t wrappedkeylen;
1832   gcry_cipher_hd_t cipherhd = NULL;
1833   unsigned char *key = NULL;
1834   size_t keylen, realkeylen;
1835   char *passphrase = NULL;
1836   unsigned char *finalkey = NULL;
1837   size_t finalkeylen;
1838   unsigned char grip[20];
1839   gcry_sexp_t openpgp_sexp = NULL;
1840   char *cache_nonce = NULL;
1841   char *p;
1842
1843   if (!ctrl->server_local->import_key)
1844     {
1845       err = gpg_error (GPG_ERR_MISSING_KEY);
1846       goto leave;
1847     }
1848
1849   p = line;
1850   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
1851     ;
1852   *p = '\0';
1853   if (*line)
1854     cache_nonce = xtrystrdup (line);
1855
1856   assuan_begin_confidential (ctx);
1857   err = assuan_inquire (ctx, "KEYDATA",
1858                         &wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
1859   assuan_end_confidential (ctx);
1860   if (err)
1861     goto leave;
1862   if (wrappedkeylen < 24)
1863     {
1864       err = gpg_error (GPG_ERR_INV_LENGTH);
1865       goto leave;
1866     }
1867   keylen = wrappedkeylen - 8;
1868   key = xtrymalloc_secure (keylen);
1869   if (!key)
1870     {
1871       err = gpg_error_from_syserror ();
1872       goto leave;
1873     }
1874
1875   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
1876                           GCRY_CIPHER_MODE_AESWRAP, 0);
1877   if (err)
1878     goto leave;
1879   err = gcry_cipher_setkey (cipherhd,
1880                             ctrl->server_local->import_key, KEYWRAP_KEYSIZE);
1881   if (err)
1882     goto leave;
1883   err = gcry_cipher_decrypt (cipherhd, key, keylen, wrappedkey, wrappedkeylen);
1884   if (err)
1885     goto leave;
1886   gcry_cipher_close (cipherhd);
1887   cipherhd = NULL;
1888   xfree (wrappedkey);
1889   wrappedkey = NULL;
1890
1891   realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1892   if (!realkeylen)
1893     goto leave; /* Invalid canonical encoded S-expression.  */
1894
1895   err = keygrip_from_canon_sexp (key, realkeylen, grip);
1896   if (err)
1897     {
1898       /* This might be due to an unsupported S-expression format.
1899          Check whether this is openpgp-private-key and trigger that
1900          import code.  */
1901       if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen))
1902         {
1903           const char *tag;
1904           size_t taglen;
1905
1906           tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen);
1907           if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19))
1908             ;
1909           else
1910             {
1911               gcry_sexp_release (openpgp_sexp);
1912               openpgp_sexp = NULL;
1913             }
1914         }
1915       if (!openpgp_sexp)
1916         goto leave; /* Note that ERR is still set.  */
1917     }
1918
1919
1920   if (openpgp_sexp)
1921     {
1922       /* In most cases the key is encrypted and thus the conversion
1923          function from the OpenPGP format to our internal format will
1924          ask for a passphrase.  That passphrase will be returned and
1925          used to protect the key using the same code as for regular
1926          key import. */
1927
1928       xfree (key);
1929       key = NULL;
1930       err = convert_from_openpgp (ctrl, openpgp_sexp, grip,
1931                                   ctrl->server_local->keydesc, cache_nonce,
1932                                   &key, &passphrase);
1933       if (err)
1934         goto leave;
1935       realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err);
1936       if (!realkeylen)
1937         goto leave; /* Invalid canonical encoded S-expression.  */
1938       if (passphrase)
1939         {
1940           if (!cache_nonce)
1941             {
1942               char buf[12];
1943               gcry_create_nonce (buf, 12);
1944               cache_nonce = bin2hex (buf, 12, NULL);
1945             }
1946           if (cache_nonce
1947               && !agent_put_cache (cache_nonce, CACHE_MODE_NONCE,
1948                                    passphrase, CACHE_TTL_NONCE))
1949             assuan_write_status (ctx, "CACHE_NONCE", cache_nonce);
1950         }
1951     }
1952   else
1953     {
1954       if (!agent_key_available (grip))
1955         err = gpg_error (GPG_ERR_EEXIST);
1956       else
1957         err = agent_ask_new_passphrase
1958           (ctrl, _("Please enter the passphrase to protect the "
1959                    "imported object within the GnuPG system."),
1960            &passphrase);
1961       if (err)
1962         goto leave;
1963     }
1964
1965   if (passphrase)
1966     {
1967       err = agent_protect (key, passphrase, &finalkey, &finalkeylen,
1968               ctrl->s2k_count);
1969       if (!err)
1970         err = agent_write_private_key (grip, finalkey, finalkeylen, 0);
1971     }
1972   else
1973     err = agent_write_private_key (grip, key, realkeylen, 0);
1974
1975  leave:
1976   gcry_sexp_release (openpgp_sexp);
1977   xfree (finalkey);
1978   xfree (passphrase);
1979   xfree (key);
1980   gcry_cipher_close (cipherhd);
1981   xfree (wrappedkey);
1982   xfree (cache_nonce);
1983   xfree (ctrl->server_local->keydesc);
1984   ctrl->server_local->keydesc = NULL;
1985   return leave_cmd (ctx, err);
1986 }
1987
1988
1989 \f
1990 static const char hlp_export_key[] =
1991   "EXPORT_KEY [--cache-nonce=<nonce>] [--openpgp] <hexstring_with_keygrip>\n"
1992   "\n"
1993   "Export a secret key from the key store.  The key will be encrypted\n"
1994   "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n"
1995   "using the AESWRAP-128 algorithm.  The caller needs to retrieve that key\n"
1996   "prior to using this command.  The function takes the keygrip as argument.\n";
1997 static gpg_error_t
1998 cmd_export_key (assuan_context_t ctx, char *line)
1999 {
2000   ctrl_t ctrl = assuan_get_pointer (ctx);
2001   gpg_error_t err;
2002   unsigned char grip[20];
2003   gcry_sexp_t s_skey = NULL;
2004   unsigned char *key = NULL;
2005   size_t keylen;
2006   gcry_cipher_hd_t cipherhd = NULL;
2007   unsigned char *wrappedkey = NULL;
2008   size_t wrappedkeylen;
2009   int openpgp;
2010   char *cache_nonce;
2011   char *passphrase = NULL;
2012
2013   openpgp = has_option (line, "--openpgp");
2014   cache_nonce = option_value (line, "--cache-nonce");
2015   if (cache_nonce)
2016     {
2017       for (; *line && !spacep (line); line++)
2018         ;
2019       if (*line)
2020         *line++ = '\0';
2021       cache_nonce = xtrystrdup (cache_nonce);
2022       if (!cache_nonce)
2023         {
2024           err = gpg_error_from_syserror ();
2025           goto leave;
2026         }
2027     }
2028   line = skip_options (line);
2029
2030   if (!ctrl->server_local->export_key)
2031     {
2032       err = gpg_error (GPG_ERR_MISSING_KEY);
2033       goto leave;
2034     }
2035
2036   err = parse_keygrip (ctx, line, grip);
2037   if (err)
2038     goto leave;
2039
2040   if (agent_key_available (grip))
2041     {
2042       err = gpg_error (GPG_ERR_NO_SECKEY);
2043       goto leave;
2044     }
2045
2046   /* Get the key from the file.  With the openpgp flag we also ask for
2047      the passphrase so that we can use it to re-encrypt it.  */
2048   err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
2049                              NULL, CACHE_MODE_IGNORE, NULL, &s_skey,
2050                              openpgp ? &passphrase : NULL);
2051   if (err)
2052     goto leave;
2053   if (!s_skey)
2054     {
2055       /* Key is on a smartcard.  Actually we should not see this here
2056          because we do not pass a shadow_info variable to the above
2057          function, thus it will return this error directly.  */
2058       err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
2059       goto leave;
2060     }
2061
2062   if (openpgp)
2063     {
2064       /* The openpgp option changes the key format into the OpenPGP
2065          key transfer format.  The result is already a padded
2066          canonical S-expression.  */
2067       if (!passphrase)
2068         {
2069           err = agent_ask_new_passphrase
2070             (ctrl, _("This key (or subkey) is not protected with a passphrase."
2071                      "  Please enter a new passphrase to export it."),
2072              &passphrase);
2073           if (err)
2074             goto leave;
2075         }
2076       err = convert_to_openpgp (ctrl, s_skey, passphrase, &key, &keylen);
2077     }
2078   else
2079     {
2080       /* Convert into a canonical S-expression and wrap that.  */
2081       err = make_canon_sexp_pad (s_skey, 1, &key, &keylen);
2082     }
2083   if (err)
2084     goto leave;
2085   gcry_sexp_release (s_skey);
2086   s_skey = NULL;
2087
2088   err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128,
2089                           GCRY_CIPHER_MODE_AESWRAP, 0);
2090   if (err)
2091     goto leave;
2092   err = gcry_cipher_setkey (cipherhd,
2093                             ctrl->server_local->export_key, KEYWRAP_KEYSIZE);
2094   if (err)
2095     goto leave;
2096
2097   wrappedkeylen = keylen + 8;
2098   wrappedkey = xtrymalloc (wrappedkeylen);
2099   if (!wrappedkey)
2100     {
2101       err = gpg_error_from_syserror ();
2102       goto leave;
2103     }
2104
2105   err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, key, keylen);
2106   if (err)
2107     goto leave;
2108   xfree (key);
2109   key = NULL;
2110   gcry_cipher_close (cipherhd);
2111   cipherhd = NULL;
2112
2113   assuan_begin_confidential (ctx);
2114   err = assuan_send_data (ctx, wrappedkey, wrappedkeylen);
2115   assuan_end_confidential (ctx);
2116
2117
2118  leave:
2119   xfree (cache_nonce);
2120   xfree (passphrase);
2121   xfree (wrappedkey);
2122   gcry_cipher_close (cipherhd);
2123   xfree (key);
2124   gcry_sexp_release (s_skey);
2125   xfree (ctrl->server_local->keydesc);
2126   ctrl->server_local->keydesc = NULL;
2127
2128   return leave_cmd (ctx, err);
2129 }
2130
2131
2132
2133 \f
2134 static const char hlp_getval[] =
2135   "GETVAL <key>\n"
2136   "\n"
2137   "Return the value for KEY from the special environment as created by\n"
2138   "PUTVAL.";
2139 static gpg_error_t
2140 cmd_getval (assuan_context_t ctx, char *line)
2141 {
2142   int rc = 0;
2143   char *key = NULL;
2144   char *p;
2145   struct putval_item_s *vl;
2146
2147   for (p=line; *p == ' '; p++)
2148     ;
2149   key = p;
2150   p = strchr (key, ' ');
2151   if (p)
2152     {
2153       *p++ = 0;
2154       for (; *p == ' '; p++)
2155         ;
2156       if (*p)
2157         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
2158     }
2159   if (!key || !*key)
2160     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2161
2162
2163   for (vl=putval_list; vl; vl = vl->next)
2164     if ( !strcmp (vl->d, key) )
2165       break;
2166
2167   if (vl) /* Got an entry. */
2168     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
2169   else
2170     return gpg_error (GPG_ERR_NO_DATA);
2171
2172   return leave_cmd (ctx, rc);
2173 }
2174
2175
2176 static const char hlp_putval[] =
2177   "PUTVAL <key> [<percent_escaped_value>]\n"
2178   "\n"
2179   "The gpg-agent maintains a kind of environment which may be used to\n"
2180   "store key/value pairs in it, so that they can be retrieved later.\n"
2181   "This may be used by helper daemons to daemonize themself on\n"
2182   "invocation and register them with gpg-agent.  Callers of the\n"
2183   "daemon's service may now first try connect to get the information\n"
2184   "for that service from gpg-agent through the GETVAL command and then\n"
2185   "try to connect to that daemon.  Only if that fails they may start\n"
2186   "an own instance of the service daemon. \n"
2187   "\n"
2188   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
2189   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
2190   "corresponsing value; they should be similar to the values of\n"
2191   "envronment variables but gpg-agent does not enforce any\n"
2192   "restrictions.  If that value is not given any value under that KEY\n"
2193   "is removed from this special environment.";
2194 static gpg_error_t
2195 cmd_putval (assuan_context_t ctx, char *line)
2196 {
2197   int rc = 0;
2198   char *key = NULL;
2199   char *value = NULL;
2200   size_t valuelen = 0;
2201   char *p;
2202   struct putval_item_s *vl, *vlprev;
2203
2204   for (p=line; *p == ' '; p++)
2205     ;
2206   key = p;
2207   p = strchr (key, ' ');
2208   if (p)
2209     {
2210       *p++ = 0;
2211       for (; *p == ' '; p++)
2212         ;
2213       if (*p)
2214         {
2215           value = p;
2216           p = strchr (value, ' ');
2217           if (p)
2218             *p = 0;
2219           valuelen = percent_plus_unescape_inplace (value, 0);
2220         }
2221     }
2222   if (!key || !*key)
2223     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
2224
2225
2226   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
2227     if ( !strcmp (vl->d, key) )
2228       break;
2229
2230   if (vl) /* Delete old entry. */
2231     {
2232       if (vlprev)
2233         vlprev->next = vl->next;
2234       else
2235         putval_list = vl->next;
2236       xfree (vl);
2237     }
2238
2239   if (valuelen) /* Add entry. */
2240     {
2241       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
2242       if (!vl)
2243         rc = gpg_error_from_syserror ();
2244       else
2245         {
2246           vl->len = valuelen;
2247           vl->off = strlen (key) + 1;
2248           strcpy (vl->d, key);
2249           memcpy (vl->d + vl->off, value, valuelen);
2250           vl->next = putval_list;
2251           putval_list = vl;
2252         }
2253     }
2254
2255   return leave_cmd (ctx, rc);
2256 }
2257
2258
2259
2260 \f
2261 static const char hlp_updatestartuptty[] =
2262   "UPDATESTARTUPTTY\n"
2263   "\n"
2264   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
2265   "session.  This command is useful to pull future pinentries to\n"
2266   "another screen.  It is only required because there is no way in the\n"
2267   "ssh-agent protocol to convey this information.";
2268 static gpg_error_t
2269 cmd_updatestartuptty (assuan_context_t ctx, char *line)
2270 {
2271   static const char *names[] =
2272     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
2273   ctrl_t ctrl = assuan_get_pointer (ctx);
2274   gpg_error_t err = 0;
2275   session_env_t se;
2276   int idx;
2277   char *lc_ctype = NULL;
2278   char *lc_messages = NULL;
2279
2280   (void)line;
2281
2282   se = session_env_new ();
2283   if (!se)
2284     err = gpg_error_from_syserror ();
2285
2286   for (idx=0; !err && names[idx]; idx++)
2287     {
2288       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
2289       if (value)
2290         err = session_env_setenv (se, names[idx], value);
2291     }
2292
2293   if (!err && ctrl->lc_ctype)
2294     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
2295       err = gpg_error_from_syserror ();
2296
2297   if (!err && ctrl->lc_messages)
2298     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
2299       err = gpg_error_from_syserror ();
2300
2301   if (err)
2302     {
2303       session_env_release (se);
2304       xfree (lc_ctype);
2305       xfree (lc_messages);
2306     }
2307   else
2308     {
2309       session_env_release (opt.startup_env);
2310       opt.startup_env = se;
2311       xfree (opt.startup_lc_ctype);
2312       opt.startup_lc_ctype = lc_ctype;
2313       xfree (opt.startup_lc_messages);
2314       opt.startup_lc_messages = lc_messages;
2315     }
2316
2317   return err;
2318 }
2319
2320
2321 \f
2322 static const char hlp_killagent[] =
2323   "KILLAGENT\n"
2324   "\n"
2325   "If the agent has been started using a standard socket\n"
2326   "we allow a client to stop the agent.";
2327 static gpg_error_t
2328 cmd_killagent (assuan_context_t ctx, char *line)
2329 {
2330   ctrl_t ctrl = assuan_get_pointer (ctx);
2331
2332   (void)line;
2333
2334   if (!opt.use_standard_socket)
2335     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
2336
2337   ctrl->server_local->stopme = 1;
2338   assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
2339   return 0;
2340 }
2341
2342
2343 static const char hlp_reloadagent[] =
2344   "RELOADAGENT\n"
2345   "\n"
2346   "This command is an alternative to SIGHUP\n"
2347   "to reload the configuration.";
2348 static gpg_error_t
2349 cmd_reloadagent (assuan_context_t ctx, char *line)
2350 {
2351   (void)ctx;
2352   (void)line;
2353
2354   agent_sighup_action ();
2355   return 0;
2356 }
2357
2358
2359 \f
2360 static const char hlp_getinfo[] =
2361   "GETINFO <what>\n"
2362   "\n"
2363   "Multipurpose function to return a variety of information.\n"
2364   "Supported values for WHAT are:\n"
2365   "\n"
2366   "  version     - Return the version of the program.\n"
2367   "  pid         - Return the process id of the server.\n"
2368   "  socket_name - Return the name of the socket.\n"
2369   "  ssh_socket_name - Return the name of the ssh socket.\n"
2370   "  scd_running - Return OK if the SCdaemon is already running.\n"
2371   "  s2k_count   - Return the calibrated S2K count.\n"
2372   "  std_session_env - List the standard session environment.\n"
2373   "  std_startup_env - List the standard startup environment.\n"
2374   "  cmd_has_option\n"
2375   "              - Returns OK if the command CMD implements the option OPT\n.";
2376 static gpg_error_t
2377 cmd_getinfo (assuan_context_t ctx, char *line)
2378 {
2379   ctrl_t ctrl = assuan_get_pointer (ctx);
2380   int rc = 0;
2381
2382   if (!strcmp (line, "version"))
2383     {
2384       const char *s = VERSION;
2385       rc = assuan_send_data (ctx, s, strlen (s));
2386     }
2387   else if (!strcmp (line, "pid"))
2388     {
2389       char numbuf[50];
2390
2391       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
2392       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2393     }
2394   else if (!strcmp (line, "socket_name"))
2395     {
2396       const char *s = get_agent_socket_name ();
2397
2398       if (s)
2399         rc = assuan_send_data (ctx, s, strlen (s));
2400       else
2401         rc = gpg_error (GPG_ERR_NO_DATA);
2402     }
2403   else if (!strcmp (line, "ssh_socket_name"))
2404     {
2405       const char *s = get_agent_ssh_socket_name ();
2406
2407       if (s)
2408         rc = assuan_send_data (ctx, s, strlen (s));
2409       else
2410         rc = gpg_error (GPG_ERR_NO_DATA);
2411     }
2412   else if (!strcmp (line, "scd_running"))
2413     {
2414       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
2415     }
2416   else if (!strcmp (line, "s2k_count"))
2417     {
2418       char numbuf[50];
2419
2420       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
2421       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
2422     }
2423   else if (!strcmp (line, "std_session_env")
2424            || !strcmp (line, "std_startup_env"))
2425     {
2426       int iterator;
2427       const char *name, *value;
2428       char *string;
2429
2430       iterator = 0;
2431       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
2432         {
2433           value = session_env_getenv_or_default
2434             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
2435           if (value)
2436             {
2437               string = xtryasprintf ("%s=%s", name, value);
2438               if (!string)
2439                 rc = gpg_error_from_syserror ();
2440               else
2441                 {
2442                   rc = assuan_send_data (ctx, string, strlen (string)+1);
2443                   if (!rc)
2444                     rc = assuan_send_data (ctx, NULL, 0);
2445                 }
2446               if (rc)
2447                 break;
2448             }
2449         }
2450     }
2451   else if (!strncmp (line, "cmd_has_option", 14)
2452            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
2453     {
2454       char *cmd, *cmdopt;
2455       line += 14;
2456       while (*line == ' ' || *line == '\t')
2457         line++;
2458       if (!*line)
2459         rc = gpg_error (GPG_ERR_MISSING_VALUE);
2460       else
2461         {
2462           cmd = line;
2463           while (*line && (*line != ' ' && *line != '\t'))
2464             line++;
2465           if (!*line)
2466             rc = gpg_error (GPG_ERR_MISSING_VALUE);
2467           else
2468             {
2469               *line++ = 0;
2470               while (*line == ' ' || *line == '\t')
2471                 line++;
2472               if (!*line)
2473                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
2474               else
2475                 {
2476                   cmdopt = line;
2477                   if (!command_has_option (cmd, cmdopt))
2478                     rc = gpg_error (GPG_ERR_GENERAL);
2479                 }
2480             }
2481         }
2482     }
2483   else
2484     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
2485   return rc;
2486 }
2487
2488
2489 \f
2490 /* This function is called by Libassuan to parse the OPTION command.
2491    It has been registered similar to the other Assuan commands.  */
2492 static gpg_error_t
2493 option_handler (assuan_context_t ctx, const char *key, const char *value)
2494 {
2495   ctrl_t ctrl = assuan_get_pointer (ctx);
2496   gpg_error_t err = 0;
2497
2498   if (!strcmp (key, "agent-awareness"))
2499     {
2500       /* The value is a version string telling us of which agent
2501          version the caller is aware of.  */
2502       ctrl->server_local->allow_fully_canceled =
2503         gnupg_compare_version (value, "2.1.0");
2504     }
2505   else if (!strcmp (key, "putenv"))
2506     {
2507       /* Change the session's environment to be used for the
2508          Pinentry.  Valid values are:
2509           <NAME>            Delete envvar NAME
2510           <KEY>=            Set envvar NAME to the empty string
2511           <KEY>=<VALUE>     Set envvar NAME to VALUE
2512       */
2513       err = session_env_putenv (ctrl->session_env, value);
2514     }
2515   else if (!strcmp (key, "display"))
2516     {
2517       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
2518     }
2519   else if (!strcmp (key, "ttyname"))
2520     {
2521       if (!opt.keep_tty)
2522         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
2523     }
2524   else if (!strcmp (key, "ttytype"))
2525     {
2526       if (!opt.keep_tty)
2527         err = session_env_setenv (ctrl->session_env, "TERM", value);
2528     }
2529   else if (!strcmp (key, "lc-ctype"))
2530     {
2531       if (ctrl->lc_ctype)
2532         xfree (ctrl->lc_ctype);
2533       ctrl->lc_ctype = xtrystrdup (value);
2534       if (!ctrl->lc_ctype)
2535         return out_of_core ();
2536     }
2537   else if (!strcmp (key, "lc-messages"))
2538     {
2539       if (ctrl->lc_messages)
2540         xfree (ctrl->lc_messages);
2541       ctrl->lc_messages = xtrystrdup (value);
2542       if (!ctrl->lc_messages)
2543         return out_of_core ();
2544     }
2545   else if (!strcmp (key, "xauthority"))
2546     {
2547       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
2548     }
2549   else if (!strcmp (key, "pinentry-user-data"))
2550     {
2551       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
2552     }
2553   else if (!strcmp (key, "use-cache-for-signing"))
2554     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
2555   else if (!strcmp (key, "allow-pinentry-notify"))
2556     ctrl->server_local->allow_pinentry_notify = 1;
2557   else if (!strcmp (key, "pinentry-mode"))
2558     {
2559       if (!strcmp (value, "ask") || !strcmp (value, "default"))
2560         ctrl->pinentry_mode = PINENTRY_MODE_ASK;
2561       else if (!strcmp (value, "cancel"))
2562         ctrl->pinentry_mode = PINENTRY_MODE_CANCEL;
2563       else if (!strcmp (value, "error"))
2564         ctrl->pinentry_mode = PINENTRY_MODE_ERROR;
2565       else if (!strcmp (value, "loopback"))
2566         {
2567           if (opt.allow_loopback_pinentry)
2568             ctrl->pinentry_mode = PINENTRY_MODE_LOOPBACK;
2569           else
2570             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2571         }
2572       else
2573         err = gpg_error (GPG_ERR_INV_VALUE);
2574     }
2575   else if (!strcmp (key, "cache-ttl-opt-preset"))
2576     {
2577       ctrl->cache_ttl_opt_preset = *value? atoi (value) : 0;
2578     }
2579   else if (!strcmp (key, "s2k-count"))
2580     {
2581       ctrl->s2k_count = *value? strtoul(value, NULL, 10) : 0;
2582       if (ctrl->s2k_count && ctrl->s2k_count < 65536)
2583         {
2584           ctrl->s2k_count = 0;
2585         }
2586     }
2587   else
2588     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2589
2590   return err;
2591 }
2592
2593
2594
2595 \f
2596 /* Called by libassuan after all commands. ERR is the error from the
2597    last assuan operation and not the one returned from the command. */
2598 static void
2599 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
2600 {
2601   ctrl_t ctrl = assuan_get_pointer (ctx);
2602
2603   (void)err;
2604
2605   /* Switch off any I/O monitor controlled logging pausing. */
2606   ctrl->server_local->pause_io_logging = 0;
2607 }
2608
2609
2610 /* This function is called by libassuan for all I/O.  We use it here
2611    to disable logging for the GETEVENTCOUNTER commands.  This is so
2612    that the debug output won't get cluttered by this primitive
2613    command.  */
2614 static unsigned int
2615 io_monitor (assuan_context_t ctx, void *hook, int direction,
2616             const char *line, size_t linelen)
2617 {
2618   ctrl_t ctrl = assuan_get_pointer (ctx);
2619
2620   (void) hook;
2621
2622   /* Note that we only check for the uppercase name.  This allows to
2623      see the logging for debugging if using a non-upercase command
2624      name. */
2625   if (ctx && direction == ASSUAN_IO_FROM_PEER
2626       && linelen >= 15
2627       && !strncmp (line, "GETEVENTCOUNTER", 15)
2628       && (linelen == 15 || spacep (line+15)))
2629     {
2630       ctrl->server_local->pause_io_logging = 1;
2631     }
2632
2633   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2634 }
2635
2636
2637 /* Return true if the command CMD implements the option OPT.  */
2638 static int
2639 command_has_option (const char *cmd, const char *cmdopt)
2640 {
2641   if (!strcmp (cmd, "GET_PASSPHRASE"))
2642     {
2643       if (!strcmp (cmdopt, "repeat"))
2644           return 1;
2645     }
2646
2647   return 0;
2648 }
2649
2650
2651 /* Tell Libassuan about our commands.  Also register the other Assuan
2652    handlers. */
2653 static int
2654 register_commands (assuan_context_t ctx)
2655 {
2656   static struct {
2657     const char *name;
2658     assuan_handler_t handler;
2659     const char * const help;
2660   } table[] = {
2661     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2662     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2663     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2664     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2665     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2666     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2667     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2668     { "SETHASH",        cmd_sethash,   hlp_sethash },
2669     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2670     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2671     { "GENKEY",         cmd_genkey,    hlp_genkey },
2672     { "READKEY",        cmd_readkey,   hlp_readkey },
2673     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2674     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2675     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2676     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2677     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2678     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2679     { "LEARN",          cmd_learn,     hlp_learn },
2680     { "PASSWD",         cmd_passwd,    hlp_passwd },
2681     { "INPUT",          NULL },
2682     { "OUTPUT",         NULL },
2683     { "SCD",            cmd_scd,       hlp_scd },
2684     { "KEYWRAP_KEY",    cmd_keywrap_key, hlp_keywrap_key },
2685     { "IMPORT_KEY",     cmd_import_key, hlp_import_key },
2686     { "EXPORT_KEY",     cmd_export_key, hlp_export_key },
2687     { "GETVAL",         cmd_getval,    hlp_getval },
2688     { "PUTVAL",         cmd_putval,    hlp_putval },
2689     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2690     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2691     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2692     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2693     { NULL }
2694   };
2695   int i, rc;
2696
2697   for (i=0; table[i].name; i++)
2698     {
2699       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2700                                     table[i].help);
2701       if (rc)
2702         return rc;
2703     }
2704   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2705   assuan_register_reset_notify (ctx, reset_notify);
2706   assuan_register_option_handler (ctx, option_handler);
2707   return 0;
2708 }
2709
2710
2711 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2712    simple piper server, otherwise it is a regular server.  CTRL is the
2713    control structure for this connection; it has only the basic
2714    intialization. */
2715 void
2716 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2717 {
2718   int rc;
2719   assuan_context_t ctx = NULL;
2720
2721   rc = assuan_new (&ctx);
2722   if (rc)
2723     {
2724       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2725       agent_exit (2);
2726     }
2727
2728   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2729     {
2730       assuan_fd_t filedes[2];
2731
2732       filedes[0] = assuan_fdopen (0);
2733       filedes[1] = assuan_fdopen (1);
2734       rc = assuan_init_pipe_server (ctx, filedes);
2735     }
2736   else if (listen_fd != GNUPG_INVALID_FD)
2737     {
2738       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2739       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2740          this branch is currently not used.  */
2741     }
2742   else
2743     {
2744       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2745     }
2746   if (rc)
2747     {
2748       log_error ("failed to initialize the server: %s\n",
2749                  gpg_strerror(rc));
2750       agent_exit (2);
2751     }
2752   rc = register_commands (ctx);
2753   if (rc)
2754     {
2755       log_error ("failed to register commands with Assuan: %s\n",
2756                  gpg_strerror(rc));
2757       agent_exit (2);
2758     }
2759
2760   assuan_set_pointer (ctx, ctrl);
2761   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2762   ctrl->server_local->assuan_ctx = ctx;
2763   ctrl->server_local->use_cache_for_signing = 1;
2764   ctrl->digest.raw_value = 0;
2765
2766   assuan_set_io_monitor (ctx, io_monitor, NULL);
2767
2768   for (;;)
2769     {
2770       rc = assuan_accept (ctx);
2771       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
2772         {
2773           break;
2774         }
2775       else if (rc)
2776         {
2777           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2778           break;
2779         }
2780
2781       rc = assuan_process (ctx);
2782       if (rc)
2783         {
2784           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2785           continue;
2786         }
2787     }
2788
2789   /* Reset the nonce caches.  */
2790   clear_nonce_cache (ctrl);
2791
2792   /* Reset the SCD if needed. */
2793   agent_reset_scd (ctrl);
2794
2795   /* Reset the pinentry (in case of popup messages). */
2796   agent_reset_query (ctrl);
2797
2798   /* Cleanup.  */
2799   assuan_release (ctx);
2800   xfree (ctrl->server_local->keydesc);
2801   xfree (ctrl->server_local->import_key);
2802   xfree (ctrl->server_local->export_key);
2803   if (ctrl->server_local->stopme)
2804     agent_exit (0);
2805   xfree (ctrl->server_local);
2806   ctrl->server_local = NULL;
2807 }
2808
2809
2810 /* Helper for the pinentry loopback mode.  It merely passes the
2811    parameters on to the client.  */
2812 gpg_error_t
2813 pinentry_loopback(ctrl_t ctrl, const char *keyword,
2814                   unsigned char **buffer, size_t *size,
2815                   size_t max_length)
2816 {
2817   gpg_error_t rc;
2818   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2819
2820   rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", max_length);
2821   if (rc)
2822     return rc;
2823
2824   assuan_begin_confidential (ctx);
2825   rc = assuan_inquire (ctx, keyword, buffer, size, max_length);
2826   assuan_end_confidential (ctx);
2827   return rc;
2828 }