agent: Cleanup caching code for command GET_PASSPHRASE.
[gnupg.git] / agent / command.c
1 /* command.c - gpg-agent command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3  *               2006, 2008, 2009  Free Software Foundation, Inc.
4  * Copyright (C) 2013 Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 /* FIXME: we should not use the default assuan buffering but setup
23    some buffering in secure mempory to protect session keys etc. */
24
25 #include <config.h>
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <unistd.h>
33 #include <assert.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <dirent.h>
37
38 #include "agent.h"
39 #include <assuan.h>
40 #include "i18n.h"
41 #include "../common/ssh-utils.h"
42
43 /* maximum allowed size of the inquired ciphertext */
44 #define MAXLEN_CIPHERTEXT 4096
45 /* maximum allowed size of the key parameters */
46 #define MAXLEN_KEYPARAM 1024
47
48 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
49
50
51 #if MAX_DIGEST_LEN < 20
52 #error MAX_DIGEST_LEN shorter than keygrip
53 #endif
54
55 /* Data used to associate an Assuan context with local server data */
56 struct server_local_s
57 {
58   assuan_context_t assuan_ctx;
59   int message_fd;
60   int use_cache_for_signing;
61   char *keydesc;  /* Allocated description for the next key
62                      operation. */
63   int pause_io_logging; /* Used to suppress I/O logging during a command */
64   int stopme;    /* If set to true the agent will be terminated after
65                     the end of this session.  */
66   int allow_pinentry_notify; /* Set if pinentry notifications should
67                                 be done. */
68 };
69
70
71 /* An entry for the getval/putval commands. */
72 struct putval_item_s
73 {
74   struct putval_item_s *next;
75   size_t off;  /* Offset to the value into DATA.  */
76   size_t len;  /* Length of the value.  */
77   char d[1];   /* Key | Nul | value.  */
78 };
79
80
81 /* A list of key value pairs fpr the getval/putval commands.  */
82 static struct putval_item_s *putval_list;
83
84
85 \f
86 /* To help polling clients, we keep track of the number of certain
87    events.  This structure keeps those counters.  The counters are
88    integers and there should be no problem if they are overflowing as
89    callers need to check only whether a counter changed.  The actual
90    values are not meaningful. */
91 struct
92 {
93   /* Incremented if any of the other counters below changed. */
94   unsigned int any;
95
96   /* Incremented if a key is added or removed from the internal privat
97      key database. */
98   unsigned int key;
99
100   /* Incremented if a change of the card readers stati has been
101      detected. */
102   unsigned int card;
103
104 } eventcounter;
105
106
107 \f
108 /*  Local prototypes.  */
109 static int command_has_option (const char *cmd, const char *cmdopt);
110
111
112
113 \f
114 /* Release the memory buffer MB but first wipe out the used memory. */
115 static void
116 clear_outbuf (membuf_t *mb)
117 {
118   void *p;
119   size_t n;
120
121   p = get_membuf (mb, &n);
122   if (p)
123     {
124       memset (p, 0, n);
125       xfree (p);
126     }
127 }
128
129
130 /* Write the content of memory buffer MB as assuan data to CTX and
131    wipe the buffer out afterwards. */
132 static gpg_error_t
133 write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
134 {
135   gpg_error_t ae;
136   void *p;
137   size_t n;
138
139   p = get_membuf (mb, &n);
140   if (!p)
141     return out_of_core ();
142   ae = assuan_send_data (ctx, p, n);
143   memset (p, 0, n);
144   xfree (p);
145   return ae;
146 }
147
148
149 static gpg_error_t
150 reset_notify (assuan_context_t ctx, char *line)
151 {
152   ctrl_t ctrl = assuan_get_pointer (ctx);
153
154   (void) line;
155
156   memset (ctrl->keygrip, 0, 20);
157   ctrl->have_keygrip = 0;
158   ctrl->digest.valuelen = 0;
159
160   xfree (ctrl->server_local->keydesc);
161   ctrl->server_local->keydesc = NULL;
162   return 0;
163 }
164
165
166 /* Check whether the option NAME appears in LINE */
167 static int
168 has_option (const char *line, const char *name)
169 {
170   const char *s;
171   int n = strlen (name);
172
173   s = strstr (line, name);
174   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
175 }
176
177 /* Same as has_option but does only test for the name of the option
178    and ignores an argument, i.e. with NAME being "--hash" it would
179    return true for "--hash" as well as for "--hash=foo". */
180 static int
181 has_option_name (const char *line, const char *name)
182 {
183   const char *s;
184   int n = strlen (name);
185
186   s = strstr (line, name);
187   return (s && (s == line || spacep (s-1))
188           && (!s[n] || spacep (s+n) || s[n] == '='));
189 }
190
191 /* Return a pointer to the argument of the option with NAME.  If such
192    an option is not given, it returns NULL. */
193 static char *
194 option_value (const char *line, const char *name)
195 {
196   char *s;
197   int n = strlen (name);
198
199   s = strstr (line, name);
200   if (s && (s == line || spacep (s-1))
201       && s[n] && (spacep (s+n) || s[n] == '='))
202     {
203       s += n + 1;
204       s += strspn (s, " ");
205       if (*s && !spacep(s))
206         return s;
207     }
208   return NULL;
209 }
210
211
212 /* Skip over options.  It is assumed that leading spaces have been
213    removed (this is the case for lines passed to a handler from
214    assuan).  Blanks after the options are also removed. */
215 static char *
216 skip_options (char *line)
217 {
218   while ( *line == '-' && line[1] == '-' )
219     {
220       while (*line && !spacep (line))
221         line++;
222       while (spacep (line))
223         line++;
224     }
225   return line;
226 }
227
228
229 /* Replace all '+' by a blank. */
230 static void
231 plus_to_blank (char *s)
232 {
233   for (; *s; s++)
234     {
235       if (*s == '+')
236         *s = ' ';
237     }
238 }
239
240
241 /* Parse a hex string.  Return an Assuan error code or 0 on success and the
242    length of the parsed string in LEN. */
243 static int
244 parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
245 {
246   const char *p;
247   size_t n;
248
249   /* parse the hash value */
250   for (p=string, n=0; hexdigitp (p); p++, n++)
251     ;
252   if (*p != ' ' && *p != '\t' && *p)
253     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
254   if ((n&1))
255     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
256   *len = n;
257   return 0;
258 }
259
260 /* Parse the keygrip in STRING into the provided buffer BUF.  BUF must
261    provide space for 20 bytes. BUF is not changed if the function
262    returns an error. */
263 static int
264 parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
265 {
266   int rc;
267   size_t n = 0;
268
269   rc = parse_hexstring (ctx, string, &n);
270   if (rc)
271     return rc;
272   n /= 2;
273   if (n != 20)
274     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip");
275
276   if (hex2bin (string, buf, 20) < 0)
277     return set_error (GPG_ERR_BUG, "hex2bin");
278
279   return 0;
280 }
281
282
283 /* Write an assuan status line. */
284 gpg_error_t
285 agent_write_status (ctrl_t ctrl, const char *keyword, ...)
286 {
287   gpg_error_t err = 0;
288   va_list arg_ptr;
289   const char *text;
290   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
291   char buf[950], *p;
292   size_t n;
293
294   va_start (arg_ptr, keyword);
295
296   p = buf;
297   n = 0;
298   while ( (text = va_arg (arg_ptr, const char *)) )
299     {
300       if (n)
301         {
302           *p++ = ' ';
303           n++;
304         }
305       for ( ; *text && n < DIM (buf)-3; n++, text++)
306         {
307           if (*text == '\n')
308             {
309               *p++ = '\\';
310               *p++ = 'n';
311             }
312           else if (*text == '\r')
313             {
314               *p++ = '\\';
315               *p++ = 'r';
316             }
317           else
318             *p++ = *text;
319         }
320     }
321   *p = 0;
322   err = assuan_write_status (ctx, keyword, buf);
323
324   va_end (arg_ptr);
325   return err;
326 }
327
328
329 /* Helper to notify the client about a launched Pinentry.  Because
330    that might disturb some older clients, this is only done if enabled
331    via an option.  Returns an gpg error code. */
332 gpg_error_t
333 agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
334 {
335   char line[100];
336
337   if (!ctrl || !ctrl->server_local
338       || !ctrl->server_local->allow_pinentry_notify)
339     return 0;
340   snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
341   return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
342 }
343
344
345 \f
346 static const char hlp_geteventcounter[] =
347   "GETEVENTCOUNTER\n"
348   "\n"
349   "Return a a status line named EVENTCOUNTER with the current values\n"
350   "of all event counters.  The values are decimal numbers in the range\n"
351   "0 to UINT_MAX and wrapping around to 0.  The actual values should\n"
352   "not be relied upon, they shall only be used to detect a change.\n"
353   "\n"
354   "The currently defined counters are:\n"
355   "\n"
356   "ANY  - Incremented with any change of any of the other counters.\n"
357   "KEY  - Incremented for added or removed private keys.\n"
358   "CARD - Incremented for changes of the card readers stati.";
359 static gpg_error_t
360 cmd_geteventcounter (assuan_context_t ctx, char *line)
361 {
362   ctrl_t ctrl = assuan_get_pointer (ctx);
363   char any_counter[25];
364   char key_counter[25];
365   char card_counter[25];
366
367   (void)line;
368
369   snprintf (any_counter, sizeof any_counter, "%u", eventcounter.any);
370   snprintf (key_counter, sizeof key_counter, "%u", eventcounter.key);
371   snprintf (card_counter, sizeof card_counter, "%u", eventcounter.card);
372
373   return agent_write_status (ctrl, "EVENTCOUNTER",
374                              any_counter,
375                              key_counter,
376                              card_counter,
377                              NULL);
378 }
379
380
381 /* This function should be called once for all key removals or
382    additions.  This function is assured not to do any context
383    switches. */
384 void
385 bump_key_eventcounter (void)
386 {
387   eventcounter.key++;
388   eventcounter.any++;
389 }
390
391 /* This function should be called for all card reader status
392    changes.  This function is assured not to do any context
393    switches. */
394 void
395 bump_card_eventcounter (void)
396 {
397   eventcounter.card++;
398   eventcounter.any++;
399 }
400
401
402
403 \f
404 static const char hlp_istrusted[] =
405   "ISTRUSTED <hexstring_with_fingerprint>\n"
406   "\n"
407   "Return OK when we have an entry with this fingerprint in our\n"
408   "trustlist";
409 static gpg_error_t
410 cmd_istrusted (assuan_context_t ctx, char *line)
411 {
412   ctrl_t ctrl = assuan_get_pointer (ctx);
413   int rc, n, i;
414   char *p;
415   char fpr[41];
416
417   /* Parse the fingerprint value. */
418   for (p=line,n=0; hexdigitp (p); p++, n++)
419     ;
420   if (*p || !(n == 40 || n == 32))
421     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
422   i = 0;
423   if (n==32)
424     {
425       strcpy (fpr, "00000000");
426       i += 8;
427     }
428   for (p=line; i < 40; p++, i++)
429     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
430   fpr[i] = 0;
431   rc = agent_istrusted (ctrl, fpr, NULL);
432   if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
433     return rc;
434   else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
435     return gpg_error (GPG_ERR_NOT_TRUSTED);
436   else
437     {
438       log_error ("command is_trusted failed: %s\n", gpg_strerror (rc));
439       return rc;
440     }
441 }
442
443
444 static const char hlp_listtrusted[] =
445   "LISTTRUSTED\n"
446   "\n"
447   "List all entries from the trustlist.";
448 static gpg_error_t
449 cmd_listtrusted (assuan_context_t ctx, char *line)
450 {
451   int rc;
452
453   (void)line;
454
455   rc = agent_listtrusted (ctx);
456   if (rc)
457     log_error ("command listtrusted failed: %s\n", gpg_strerror (rc));
458   return rc;
459 }
460
461
462 static const char hlp_martrusted[] =
463   "MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>\n"
464   "\n"
465   "Store a new key in into the trustlist.";
466 static gpg_error_t
467 cmd_marktrusted (assuan_context_t ctx, char *line)
468 {
469   ctrl_t ctrl = assuan_get_pointer (ctx);
470   int rc, n, i;
471   char *p;
472   char fpr[41];
473   int flag;
474
475   /* parse the fingerprint value */
476   for (p=line,n=0; hexdigitp (p); p++, n++)
477     ;
478   if (!spacep (p) || !(n == 40 || n == 32))
479     return set_error (GPG_ERR_ASS_PARAMETER, "invalid fingerprint");
480   i = 0;
481   if (n==32)
482     {
483       strcpy (fpr, "00000000");
484       i += 8;
485     }
486   for (p=line; i < 40; p++, i++)
487     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
488   fpr[i] = 0;
489
490   while (spacep (p))
491     p++;
492   flag = *p++;
493   if ( (flag != 'S' && flag != 'P') || !spacep (p) )
494     return set_error (GPG_ERR_ASS_PARAMETER, "invalid flag - must be P or S");
495   while (spacep (p))
496     p++;
497
498   rc = agent_marktrusted (ctrl, p, fpr, flag);
499   if (rc)
500     log_error ("command marktrusted failed: %s\n", gpg_strerror (rc));
501   return rc;
502 }
503
504
505
506 \f
507 static const char hlp_havekey[] =
508   "HAVEKEY <hexstring_with_keygrip>\n"
509   "\n"
510   "Return success when the secret key is available.";
511 static gpg_error_t
512 cmd_havekey (assuan_context_t ctx, char *line)
513 {
514   int rc;
515   unsigned char buf[20];
516
517   rc = parse_keygrip (ctx, line, buf);
518   if (rc)
519     return rc;
520
521   if (agent_key_available (buf))
522     return gpg_error (GPG_ERR_NO_SECKEY);
523
524   return 0;
525 }
526
527
528 static const char hlp_sigkey[] =
529   "SIGKEY <hexstring_with_keygrip>\n"
530   "SETKEY <hexstring_with_keygrip>\n"
531   "\n"
532   "Set the  key used for a sign or decrypt operation.";
533 static gpg_error_t
534 cmd_sigkey (assuan_context_t ctx, char *line)
535 {
536   int rc;
537   ctrl_t ctrl = assuan_get_pointer (ctx);
538
539   rc = parse_keygrip (ctx, line, ctrl->keygrip);
540   if (rc)
541     return rc;
542   ctrl->have_keygrip = 1;
543   return 0;
544 }
545
546
547 static const char hlp_setkeydesc[] =
548   "SETKEYDESC plus_percent_escaped_string\n"
549   "\n"
550   "Set a description to be used for the next PKSIGN or PKDECRYPT\n"
551   "operation if this operation requires the entry of a passphrase.  If\n"
552   "this command is not used a default text will be used.  Note, that\n"
553   "this description implictly selects the label used for the entry\n"
554   "box; if the string contains the string PIN (which in general will\n"
555   "not be translated), \"PIN\" is used, otherwise the translation of\n"
556   "\"passphrase\" is used.  The description string should not contain\n"
557   "blanks unless they are percent or '+' escaped.\n"
558   "\n"
559   "The description is only valid for the next PKSIGN or PKDECRYPT\n"
560   "operation.";
561 static gpg_error_t
562 cmd_setkeydesc (assuan_context_t ctx, char *line)
563 {
564   ctrl_t ctrl = assuan_get_pointer (ctx);
565   char *desc, *p;
566
567   for (p=line; *p == ' '; p++)
568     ;
569   desc = p;
570   p = strchr (desc, ' ');
571   if (p)
572     *p = 0; /* We ignore any garbage; we might late use it for other args. */
573
574   if (!desc || !*desc)
575     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
576
577   /* Note, that we only need to replace the + characters and should
578      leave the other escaping in place because the escaped string is
579      send verbatim to the pinentry which does the unescaping (but not
580      the + replacing) */
581   plus_to_blank (desc);
582
583   xfree (ctrl->server_local->keydesc);
584   ctrl->server_local->keydesc = xtrystrdup (desc);
585   if (!ctrl->server_local->keydesc)
586     return out_of_core ();
587   return 0;
588 }
589
590
591 static const char hlp_sethash[] =
592   "SETHASH --hash=<name>|<algonumber> <hexstring>\n"
593   "\n"
594   "The client can use this command to tell the server about the data\n"
595   "(which usually is a hash) to be signed.";
596 static gpg_error_t
597 cmd_sethash (assuan_context_t ctx, char *line)
598 {
599   int rc;
600   size_t n;
601   char *p;
602   ctrl_t ctrl = assuan_get_pointer (ctx);
603   unsigned char *buf;
604   char *endp;
605   int algo;
606
607   /* Parse the alternative hash options which may be used instead of
608      the algo number.  */
609   if (has_option_name (line, "--hash"))
610     {
611       if (has_option (line, "--hash=sha1"))
612         algo = GCRY_MD_SHA1;
613       else if (has_option (line, "--hash=sha224"))
614         algo = GCRY_MD_SHA224;
615       else if (has_option (line, "--hash=sha256"))
616         algo = GCRY_MD_SHA256;
617       else if (has_option (line, "--hash=sha384"))
618         algo = GCRY_MD_SHA384;
619       else if (has_option (line, "--hash=sha512"))
620         algo = GCRY_MD_SHA512;
621       else if (has_option (line, "--hash=rmd160"))
622         algo = GCRY_MD_RMD160;
623       else if (has_option (line, "--hash=md5"))
624         algo = GCRY_MD_MD5;
625       else if (has_option (line, "--hash=tls-md5sha1"))
626         algo = MD_USER_TLS_MD5SHA1;
627       else
628         return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
629     }
630   else
631     algo = 0;
632
633   line = skip_options (line);
634
635   if (!algo)
636     {
637       /* No hash option has been given: require an algo number instead  */
638       algo = (int)strtoul (line, &endp, 10);
639       for (line = endp; *line == ' ' || *line == '\t'; line++)
640         ;
641       if (!algo || gcry_md_test_algo (algo))
642         return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
643     }
644   ctrl->digest.algo = algo;
645
646   /* Parse the hash value. */
647   n = 0;
648   rc = parse_hexstring (ctx, line, &n);
649   if (rc)
650     return rc;
651   n /= 2;
652   if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
653     ;
654   else if (n != 16 && n != 20 && n != 24
655            && n != 28 && n != 32 && n != 48 && n != 64)
656     return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
657
658   if (n > MAX_DIGEST_LEN)
659     return set_error (GPG_ERR_ASS_PARAMETER, "hash value to long");
660
661   buf = ctrl->digest.value;
662   ctrl->digest.valuelen = n;
663   for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
664     buf[n] = xtoi_2 (p);
665   for (; n < ctrl->digest.valuelen; n++)
666     buf[n] = 0;
667   return 0;
668 }
669
670
671 static const char hlp_pksign[] =
672   "PKSIGN [options]\n"
673   "\n"
674   "Perform the actual sign operation.  Neither input nor output are\n"
675   "sensitive to eavesdropping.";
676 static gpg_error_t
677 cmd_pksign (assuan_context_t ctx, char *line)
678 {
679   int rc;
680   cache_mode_t cache_mode = CACHE_MODE_NORMAL;
681   ctrl_t ctrl = assuan_get_pointer (ctx);
682   membuf_t outbuf;
683
684   (void)line;
685
686   if (opt.ignore_cache_for_signing)
687     cache_mode = CACHE_MODE_IGNORE;
688   else if (!ctrl->server_local->use_cache_for_signing)
689     cache_mode = CACHE_MODE_IGNORE;
690
691   init_membuf (&outbuf, 512);
692
693   rc = agent_pksign (ctrl, ctrl->server_local->keydesc,
694                      &outbuf, cache_mode);
695   if (rc)
696     clear_outbuf (&outbuf);
697   else
698     rc = write_and_clear_outbuf (ctx, &outbuf);
699   if (rc)
700     log_error ("command pksign failed: %s\n", gpg_strerror (rc));
701   xfree (ctrl->server_local->keydesc);
702   ctrl->server_local->keydesc = NULL;
703   return rc;
704 }
705
706
707 static const char hlp_pkdecrypt[] =
708   "PKDECRYPT <options>\n"
709   "\n"
710   "Perform the actual decrypt operation.  Input is not\n"
711   "sensitive to eavesdropping.";
712 static gpg_error_t
713 cmd_pkdecrypt (assuan_context_t ctx, char *line)
714 {
715   int rc;
716   ctrl_t ctrl = assuan_get_pointer (ctx);
717   unsigned char *value;
718   size_t valuelen;
719   membuf_t outbuf;
720
721   (void)line;
722
723   /* First inquire the data to decrypt */
724   rc = assuan_inquire (ctx, "CIPHERTEXT",
725                        &value, &valuelen, MAXLEN_CIPHERTEXT);
726   if (rc)
727     return rc;
728
729   init_membuf (&outbuf, 512);
730
731   rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
732                         value, valuelen, &outbuf);
733   xfree (value);
734   if (rc)
735     clear_outbuf (&outbuf);
736   else
737     rc = write_and_clear_outbuf (ctx, &outbuf);
738   if (rc)
739     log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc));
740   xfree (ctrl->server_local->keydesc);
741   ctrl->server_local->keydesc = NULL;
742   return rc;
743 }
744
745
746 static const char hlp_genkey[] =
747   "GENKEY\n"
748   "\n"
749   "Generate a new key, store the secret part and return the public\n"
750   "part.  Here is an example transaction:\n"
751   "\n"
752   "  C: GENKEY\n"
753   "  S: INQUIRE KEYPARAM\n"
754   "  C: D (genkey (rsa (nbits  1024)))\n"
755   "  C: END\n"
756   "  S: D (public-key\n"
757   "  S: D   (rsa (n 326487324683264) (e 10001)))\n"
758   "  S: OK key created\n"
759   "\n";
760 static gpg_error_t
761 cmd_genkey (assuan_context_t ctx, char *line)
762 {
763   ctrl_t ctrl = assuan_get_pointer (ctx);
764   int rc;
765   unsigned char *value;
766   size_t valuelen;
767   membuf_t outbuf;
768
769   (void)line;
770
771   /* First inquire the parameters */
772   rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
773   if (rc)
774     return rc;
775
776   init_membuf (&outbuf, 512);
777
778   rc = agent_genkey (ctrl, (char*)value, valuelen, &outbuf);
779   xfree (value);
780   if (rc)
781     clear_outbuf (&outbuf);
782   else
783     rc = write_and_clear_outbuf (ctx, &outbuf);
784   if (rc)
785     log_error ("command genkey failed: %s\n", gpg_strerror (rc));
786   return rc;
787 }
788
789
790
791 \f
792 static const char hlp_readkey[] =
793   "READKEY <hexstring_with_keygrip>\n"
794   "\n"
795   "Return the public key for the given keygrip.";
796 static gpg_error_t
797 cmd_readkey (assuan_context_t ctx, char *line)
798 {
799   ctrl_t ctrl = assuan_get_pointer (ctx);
800   int rc;
801   unsigned char grip[20];
802   gcry_sexp_t s_pkey = NULL;
803
804   rc = parse_keygrip (ctx, line, grip);
805   if (rc)
806     return rc; /* Return immediately as this is already an Assuan error code.*/
807
808   rc = agent_public_key_from_file (ctrl, grip, &s_pkey);
809   if (!rc)
810     {
811       size_t len;
812       unsigned char *buf;
813
814       len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
815       assert (len);
816       buf = xtrymalloc (len);
817       if (!buf)
818         rc = gpg_error_from_syserror ();
819       else
820         {
821           len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len);
822           assert (len);
823           rc = assuan_send_data (ctx, buf, len);
824           xfree (buf);
825         }
826       gcry_sexp_release (s_pkey);
827     }
828
829   if (rc)
830     log_error ("command readkey failed: %s\n", gpg_strerror (rc));
831   return rc;
832 }
833
834
835 \f
836 static const char hlp_keyinfo[] =
837   "KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] <keygrip>\n"
838   "\n"
839   "Return information about the key specified by the KEYGRIP.  If the\n"
840   "key is not available GPG_ERR_NOT_FOUND is returned.  If the option\n"
841   "--list is given the keygrip is ignored and information about all\n"
842   "available keys are returned.  If --ssh-list is given information\n"
843   "about all keys listed in the sshcontrol are returned.  With --with-ssh\n"
844   "information from sshcontrol is always added to the info. Unless --data\n"
845   "is given, the information is returned as a status line using the format:\n"
846   "\n"
847   "  KEYINFO <keygrip> <type> <serialno> <idstr> - - <fpr> <ttl> <flags>\n"
848   "\n"
849   "KEYGRIP is the keygrip.\n"
850   "\n"
851   "TYPE describes the type of the key:\n"
852   "    'D' - Regular key stored on disk,\n"
853   "    'T' - Key is stored on a smartcard (token),\n"
854   "    'X' - Unknown type,\n"
855   "    '-' - Key is missing.\n"
856   "\n"
857   "SERIALNO is an ASCII string with the serial number of the\n"
858   "         smartcard.  If the serial number is not known a single\n"
859   "         dash '-' is used instead.\n"
860   "\n"
861   "IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it\n"
862   "      is not known a dash is used instead.\n"
863   "\n"
864   "FPR returns the formatted ssh-style fingerprint of the key.  It is only\n"
865   "    printed if the option --ssh-fpr has been used.  It defaults to '-'.\n"
866   "\n"
867   "TTL is the TTL in seconds for that key or '-' if n/a.\n"
868   "\n"
869   "FLAGS is a word consisting of one-letter flags:\n"
870   "      'D' - The key has been disabled,\n"
871   "      'S' - The key is listed in sshcontrol (requires --with-ssh),\n"
872   "      'c' - Use of the key needs to be confirmed,\n"
873   "      '-' - No flags given.\n"
874   "\n"
875   "More information may be added in the future.";
876 static gpg_error_t
877 do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
878                 int data, int with_ssh_fpr, int in_ssh,
879                 int ttl, int disabled, int confirm)
880 {
881   gpg_error_t err;
882   char hexgrip[40+1];
883   char *fpr = NULL;
884   int keytype;
885   unsigned char *shadow_info = NULL;
886   char *serialno = NULL;
887   char *idstr = NULL;
888   const char *keytypestr;
889   int missing_key = 0;
890   char ttlbuf[20];
891   char flagsbuf[5];
892
893   err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
894   if (err)
895     {
896       if (in_ssh && gpg_err_code (err) == GPG_ERR_NOT_FOUND)
897         missing_key = 1;
898       else
899         goto leave;
900     }
901
902   /* Reformat the grip so that we use uppercase as good style. */
903   bin2hex (grip, 20, hexgrip);
904
905   if (ttl > 0)
906     snprintf (ttlbuf, sizeof ttlbuf, "%d", ttl);
907   else
908     strcpy (ttlbuf, "-");
909
910   *flagsbuf = 0;
911   if (disabled)
912     strcat (flagsbuf, "D");
913   if (in_ssh)
914     strcat (flagsbuf, "S");
915   if (confirm)
916     strcat (flagsbuf, "c");
917   if (!*flagsbuf)
918     strcpy (flagsbuf, "-");
919
920
921   if (missing_key)
922     {
923       keytypestr = "-";
924     }
925   else
926     {
927       switch (keytype)
928         {
929         case PRIVATE_KEY_CLEAR: keytypestr = "D";
930           break;
931         case PRIVATE_KEY_PROTECTED: keytypestr = "D";
932           break;
933         case PRIVATE_KEY_SHADOWED: keytypestr = "T";
934           break;
935         default: keytypestr = "X";
936           break;
937         }
938     }
939
940   /* Compute the ssh fingerprint if requested.  */
941   if (with_ssh_fpr)
942     {
943       gcry_sexp_t key;
944
945       if (!agent_raw_key_from_file (ctrl, grip, &key))
946         {
947           ssh_get_fingerprint_string (key, &fpr);
948           gcry_sexp_release (key);
949         }
950     }
951
952   if (shadow_info)
953     {
954       err = parse_shadow_info (shadow_info, &serialno, &idstr);
955       if (err)
956         goto leave;
957     }
958
959   /* Note that we don't support the CACHED and PROTECTION values as
960      gnupg 2.1 does.  We print '-' instead.  However we support the
961      ssh fingerprint.  */
962   if (!data)
963     err = agent_write_status (ctrl, "KEYINFO",
964                               hexgrip,
965                               keytypestr,
966                               serialno? serialno : "-",
967                               idstr? idstr : "-",
968                               "-",
969                               "-",
970                               fpr? fpr : "-",
971                               ttlbuf,
972                               flagsbuf,
973                               NULL);
974   else
975     {
976       char *string;
977
978       string = xtryasprintf ("%s %s %s %s - - %s %s %s\n",
979                              hexgrip, keytypestr,
980                              serialno? serialno : "-",
981                              idstr? idstr : "-",
982                              fpr? fpr : "-",
983                              ttlbuf,
984                              flagsbuf);
985
986       if (!string)
987         err = gpg_error_from_syserror ();
988       else
989         err = assuan_send_data (ctx, string, strlen(string));
990       xfree (string);
991     }
992
993  leave:
994   xfree (fpr);
995   xfree (shadow_info);
996   xfree (serialno);
997   xfree (idstr);
998   return err;
999 }
1000
1001
1002 static gpg_error_t
1003 cmd_keyinfo (assuan_context_t ctx, char *line)
1004 {
1005   ctrl_t ctrl = assuan_get_pointer (ctx);
1006   int err;
1007   unsigned char grip[20];
1008   DIR *dir = NULL;
1009   int list_mode;
1010   int opt_data, opt_ssh_fpr, opt_with_ssh;
1011   ssh_control_file_t cf = NULL;
1012   char hexgrip[41];
1013   int disabled, ttl, confirm, is_ssh;
1014
1015   if (has_option (line, "--ssh-list"))
1016     list_mode = 2;
1017   else
1018     list_mode = has_option (line, "--list");
1019   opt_data = has_option (line, "--data");
1020   opt_ssh_fpr = has_option (line, "--ssh-fpr");
1021   opt_with_ssh = has_option (line, "--with-ssh");
1022   line = skip_options (line);
1023
1024   if (opt_with_ssh || list_mode == 2)
1025     cf = ssh_open_control_file ();
1026
1027   if (list_mode == 2)
1028     {
1029       if (cf)
1030         {
1031           while (!ssh_read_control_file (cf, hexgrip,
1032                                          &disabled, &ttl, &confirm))
1033             {
1034               if (hex2bin (hexgrip, grip, 20) < 0 )
1035                 continue; /* Bad hex string.  */
1036               err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, 1,
1037                                     ttl, disabled, confirm);
1038               if (err)
1039                 goto leave;
1040             }
1041         }
1042       err = 0;
1043     }
1044   else if (list_mode)
1045     {
1046       char *dirname;
1047       struct dirent *dir_entry;
1048
1049       dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1050       if (!dirname)
1051         {
1052           err = gpg_error_from_syserror ();
1053           goto leave;
1054         }
1055       dir = opendir (dirname);
1056       if (!dir)
1057         {
1058           err = gpg_error_from_syserror ();
1059           xfree (dirname);
1060           goto leave;
1061         }
1062       xfree (dirname);
1063
1064       while ( (dir_entry = readdir (dir)) )
1065         {
1066           if (strlen (dir_entry->d_name) != 44
1067               || strcmp (dir_entry->d_name + 40, ".key"))
1068             continue;
1069           strncpy (hexgrip, dir_entry->d_name, 40);
1070           hexgrip[40] = 0;
1071
1072           if ( hex2bin (hexgrip, grip, 20) < 0 )
1073             continue; /* Bad hex string.  */
1074
1075           disabled = ttl = confirm = is_ssh = 0;
1076           if (opt_with_ssh)
1077             {
1078               err = ssh_search_control_file (cf, hexgrip,
1079                                              &disabled, &ttl, &confirm);
1080               if (!err)
1081                 is_ssh = 1;
1082               else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1083                 goto leave;
1084             }
1085
1086           err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
1087                                 ttl, disabled, confirm);
1088           if (err)
1089             goto leave;
1090         }
1091       err = 0;
1092     }
1093   else
1094     {
1095       err = parse_keygrip (ctx, line, grip);
1096       if (err)
1097         goto leave;
1098       disabled = ttl = confirm = is_ssh = 0;
1099       if (opt_with_ssh)
1100         {
1101           err = ssh_search_control_file (cf, line,
1102                                          &disabled, &ttl, &confirm);
1103           if (!err)
1104             is_ssh = 1;
1105           else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1106             goto leave;
1107         }
1108
1109       err = do_one_keyinfo (ctrl, grip, ctx, opt_data, opt_ssh_fpr, is_ssh,
1110                             ttl, disabled, confirm);
1111     }
1112
1113  leave:
1114   ssh_close_control_file (cf);
1115   if (dir)
1116     closedir (dir);
1117   if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1118     log_error ("command keyinfo failed: %s\n", gpg_strerror (err));
1119   return err;
1120 }
1121
1122
1123 \f
1124 static int
1125 send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
1126 {
1127   size_t n;
1128   int rc;
1129
1130   assuan_begin_confidential (ctx);
1131   n = strlen (pw);
1132   if (via_data)
1133     rc = assuan_send_data (ctx, pw, n);
1134   else
1135     {
1136       char *p = xtrymalloc_secure (n*2+1);
1137       if (!p)
1138         rc = gpg_error_from_syserror ();
1139       else
1140         {
1141           bin2hex (pw, n, p);
1142           rc = assuan_set_okay_line (ctx, p);
1143           xfree (p);
1144         }
1145     }
1146   return rc;
1147 }
1148
1149
1150 static const char hlp_get_passphrase[] =
1151   "GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]\n"
1152   "               [--qualitybar] <cache_id>\n"
1153   "               [<error_message> <prompt> <description>]\n"
1154   "\n"
1155   "This function is usually used to ask for a passphrase to be used\n"
1156   "for conventional encryption, but may also be used by programs which\n"
1157   "need specal handling of passphrases.  This command uses a syntax\n"
1158   "which helps clients to use the agent with minimum effort.  The\n"
1159   "agent either returns with an error or with a OK followed by the hex\n"
1160   "encoded passphrase.  Note that the length of the strings is\n"
1161   "implicitly limited by the maximum length of a command.\n"
1162   "\n"
1163   "If the option \"--data\" is used the passphrase is returned by usual\n"
1164   "data lines and not on the okay line.\n"
1165   "\n"
1166   "If the option \"--check\" is used the passphrase constraints checks as\n"
1167   "implemented by gpg-agent are applied.  A check is not done if the\n"
1168   "passphrase has been found in the cache.\n"
1169   "\n"
1170   "If the option \"--no-ask\" is used and the passphrase is not in the\n"
1171   "cache the user will not be asked to enter a passphrase but the error\n"
1172   "code GPG_ERR_NO_DATA is returned.  \n"
1173   "\n"
1174   "If the option \"--qualitybar\" is used a visual indication of the\n"
1175   "entered passphrase quality is shown.  (Unless no minimum passphrase\n"
1176   "length has been configured.)";
1177 static gpg_error_t
1178 cmd_get_passphrase (assuan_context_t ctx, char *line)
1179 {
1180   ctrl_t ctrl = assuan_get_pointer (ctx);
1181   int rc;
1182   const char *pw;
1183   char *response;
1184   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
1185   const char *desc2 = _("Please re-enter this passphrase");
1186   char *p;
1187   void *cache_marker;
1188   int opt_data, opt_check, opt_no_ask, opt_qualbar;
1189   int opt_repeat = 0;
1190   char *repeat_errtext = NULL;
1191
1192   opt_data = has_option (line, "--data");
1193   opt_check = has_option (line, "--check");
1194   opt_no_ask = has_option (line, "--no-ask");
1195   if (has_option_name (line, "--repeat"))
1196     {
1197       p = option_value (line, "--repeat");
1198       if (p)
1199         opt_repeat = atoi (p);
1200       else
1201         opt_repeat = 1;
1202     }
1203   opt_qualbar = has_option (line, "--qualitybar");
1204   line = skip_options (line);
1205
1206   cacheid = line;
1207   p = strchr (cacheid, ' ');
1208   if (p)
1209     {
1210       *p++ = 0;
1211       while (*p == ' ')
1212         p++;
1213       errtext = p;
1214       p = strchr (errtext, ' ');
1215       if (p)
1216         {
1217           *p++ = 0;
1218           while (*p == ' ')
1219             p++;
1220           prompt = p;
1221           p = strchr (prompt, ' ');
1222           if (p)
1223             {
1224               *p++ = 0;
1225               while (*p == ' ')
1226                 p++;
1227               desc = p;
1228               p = strchr (desc, ' ');
1229               if (p)
1230                 *p = 0; /* Ignore trailing garbage. */
1231             }
1232         }
1233     }
1234   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1235     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1236   if (!desc)
1237     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1238
1239   if (!strcmp (cacheid, "X"))
1240     cacheid = NULL;
1241   if (!strcmp (errtext, "X"))
1242     errtext = NULL;
1243   if (!strcmp (prompt, "X"))
1244     prompt = NULL;
1245   if (!strcmp (desc, "X"))
1246     desc = NULL;
1247
1248   pw = cacheid ? agent_get_cache (cacheid, CACHE_MODE_USER, &cache_marker)
1249                : NULL;
1250   if (pw)
1251     {
1252       rc = send_back_passphrase (ctx, opt_data, pw);
1253       agent_unlock_cache_entry (&cache_marker);
1254     }
1255   else if (opt_no_ask)
1256     rc = gpg_error (GPG_ERR_NO_DATA);
1257   else
1258     {
1259       /* Note, that we only need to replace the + characters and
1260          should leave the other escaping in place because the escaped
1261          string is send verbatim to the pinentry which does the
1262          unescaping (but not the + replacing) */
1263       if (errtext)
1264         plus_to_blank (errtext);
1265       if (prompt)
1266         plus_to_blank (prompt);
1267       if (desc)
1268         plus_to_blank (desc);
1269
1270     next_try:
1271       rc = agent_get_passphrase (ctrl, &response, desc, prompt,
1272                                  repeat_errtext? repeat_errtext:errtext,
1273                                  opt_qualbar, cacheid, CACHE_MODE_USER);
1274       xfree (repeat_errtext);
1275       repeat_errtext = NULL;
1276       if (!rc)
1277         {
1278           int i;
1279
1280           if (opt_check && check_passphrase_constraints (ctrl, response, 0))
1281             {
1282               xfree (response);
1283               goto next_try;
1284             }
1285           for (i = 0; i < opt_repeat; i++)
1286             {
1287               char *response2;
1288
1289               rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
1290                                          errtext, 0,
1291                                          cacheid, CACHE_MODE_USER);
1292               if (rc)
1293                 break;
1294               if (strcmp (response2, response))
1295                 {
1296                   xfree (response2);
1297                   xfree (response);
1298                   repeat_errtext = try_percent_escape
1299                     (_("does not match - try again"), NULL);
1300                   if (!repeat_errtext)
1301                     {
1302                       rc = gpg_error_from_syserror ();
1303                       break;
1304                     }
1305                   goto next_try;
1306                 }
1307               xfree (response2);
1308             }
1309           if (!rc)
1310             {
1311               if (cacheid)
1312                 agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
1313               rc = send_back_passphrase (ctx, opt_data, response);
1314             }
1315           xfree (response);
1316         }
1317     }
1318
1319   if (rc)
1320     log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc));
1321   return rc;
1322 }
1323
1324
1325 static const char hlp_clear_passphrase[] =
1326   "CLEAR_PASSPHRASE <cache_id>\n"
1327   "\n"
1328   "may be used to invalidate the cache entry for a passphrase.  The\n"
1329   "function returns with OK even when there is no cached passphrase.";
1330 static gpg_error_t
1331 cmd_clear_passphrase (assuan_context_t ctx, char *line)
1332 {
1333   ctrl_t ctrl = assuan_get_pointer (ctx);
1334   char *cacheid = NULL;
1335   char *p;
1336
1337   /* parse the stuff */
1338   for (p=line; *p == ' '; p++)
1339     ;
1340   cacheid = p;
1341   p = strchr (cacheid, ' ');
1342   if (p)
1343     *p = 0; /* ignore garbage */
1344   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
1345     return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID");
1346
1347   agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0);
1348
1349   agent_clear_passphrase (ctrl, cacheid, CACHE_MODE_USER);
1350
1351   return 0;
1352 }
1353
1354
1355 static const char hlp_get_confirmation[] =
1356   "GET_CONFIRMATION <description>\n"
1357   "\n"
1358   "This command may be used to ask for a simple confirmation.\n"
1359   "DESCRIPTION is displayed along with a Okay and Cancel button.  This\n"
1360   "command uses a syntax which helps clients to use the agent with\n"
1361   "minimum effort.  The agent either returns with an error or with a\n"
1362   "OK.  Note, that the length of DESCRIPTION is implicitly limited by\n"
1363   "the maximum length of a command. DESCRIPTION should not contain\n"
1364   "any spaces, those must be encoded either percent escaped or simply\n"
1365   "as '+'.";
1366 static gpg_error_t
1367 cmd_get_confirmation (assuan_context_t ctx, char *line)
1368 {
1369   ctrl_t ctrl = assuan_get_pointer (ctx);
1370   int rc;
1371   char *desc = NULL;
1372   char *p;
1373
1374   /* parse the stuff */
1375   for (p=line; *p == ' '; p++)
1376     ;
1377   desc = p;
1378   p = strchr (desc, ' ');
1379   if (p)
1380     *p = 0; /* We ignore any garbage -may be later used for other args. */
1381
1382   if (!desc || !*desc)
1383     return set_error (GPG_ERR_ASS_PARAMETER, "no description given");
1384
1385   if (!strcmp (desc, "X"))
1386     desc = NULL;
1387
1388   /* Note, that we only need to replace the + characters and should
1389      leave the other escaping in place because the escaped string is
1390      send verbatim to the pinentry which does the unescaping (but not
1391      the + replacing) */
1392   if (desc)
1393     plus_to_blank (desc);
1394
1395   rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1396   if (rc)
1397     log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
1398   return rc;
1399 }
1400
1401
1402 \f
1403 static const char hlp_learn[] =
1404   "LEARN [--send]\n"
1405   "\n"
1406   "Learn something about the currently inserted smartcard.  With\n"
1407   "--send the new certificates are send back.";
1408 static gpg_error_t
1409 cmd_learn (assuan_context_t ctx, char *line)
1410 {
1411   ctrl_t ctrl = assuan_get_pointer (ctx);
1412   int rc;
1413
1414   rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
1415   if (rc)
1416     log_error ("command learn failed: %s\n", gpg_strerror (rc));
1417   return rc;
1418 }
1419
1420
1421 \f
1422 static const char hlp_passwd[] =
1423   "PASSWD <hexstring_with_keygrip>\n"
1424   "\n"
1425   "Change the passphrase/PIN for the key identified by keygrip in LINE.";
1426 static gpg_error_t
1427 cmd_passwd (assuan_context_t ctx, char *line)
1428 {
1429   ctrl_t ctrl = assuan_get_pointer (ctx);
1430   int rc;
1431   unsigned char grip[20];
1432   gcry_sexp_t s_skey = NULL;
1433   unsigned char *shadow_info = NULL;
1434
1435   rc = parse_keygrip (ctx, line, grip);
1436   if (rc)
1437     goto leave;
1438
1439   ctrl->in_passwd++;
1440   rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
1441                             grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
1442                             &s_skey);
1443   if (rc)
1444     ;
1445   else if (!s_skey)
1446     {
1447       log_error ("changing a smartcard PIN is not yet supported\n");
1448       rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1449     }
1450   else
1451     rc = agent_protect_and_store (ctrl, s_skey);
1452   ctrl->in_passwd--;
1453
1454   xfree (ctrl->server_local->keydesc);
1455   ctrl->server_local->keydesc = NULL;
1456
1457  leave:
1458   gcry_sexp_release (s_skey);
1459   xfree (shadow_info);
1460   if (rc)
1461     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1462   return rc;
1463 }
1464
1465
1466 static const char hlp_preset_passphrase[] =
1467   "PRESET_PASSPHRASE <string_or_keygrip> <timeout> <hexstring>\n"
1468   "\n"
1469   "Set the cached passphrase/PIN for the key identified by the keygrip\n"
1470   "to passwd for the given time, where -1 means infinite and 0 means\n"
1471   "the default (currently only a timeout of -1 is allowed, which means\n"
1472   "to never expire it).  If passwd is not provided, ask for it via the\n"
1473   "pinentry module.";
1474 static gpg_error_t
1475 cmd_preset_passphrase (assuan_context_t ctx, char *line)
1476 {
1477   int rc;
1478   char *grip_clear = NULL;
1479   char *passphrase = NULL;
1480   int ttl;
1481   size_t len;
1482
1483   if (!opt.allow_preset_passphrase)
1484     return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase");
1485
1486   grip_clear = line;
1487   while (*line && (*line != ' ' && *line != '\t'))
1488     line++;
1489   if (!*line)
1490     return gpg_error (GPG_ERR_MISSING_VALUE);
1491   *line = '\0';
1492   line++;
1493   while (*line && (*line == ' ' || *line == '\t'))
1494     line++;
1495
1496   /* Currently, only infinite timeouts are allowed.  */
1497   ttl = -1;
1498   if (line[0] != '-' || line[1] != '1')
1499     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1500   line++;
1501   line++;
1502   while (!(*line != ' ' && *line != '\t'))
1503     line++;
1504
1505   /* Syntax check the hexstring.  */
1506   len = 0;
1507   rc = parse_hexstring (ctx, line, &len);
1508   if (rc)
1509     return rc;
1510   line[len] = '\0';
1511
1512   /* If there is a passphrase, use it.  Currently, a passphrase is
1513      required.  */
1514   if (*line)
1515     {
1516       /* Do in-place conversion.  */
1517       passphrase = line;
1518       if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL))
1519         rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
1520     }
1521   else
1522     rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required");
1523
1524   if (!rc)
1525     rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl);
1526
1527   if (rc)
1528     log_error ("command preset_passphrase failed: %s\n", gpg_strerror (rc));
1529
1530   return rc;
1531 }
1532
1533
1534 \f
1535 static const char hlp_scd[] =
1536   "SCD <commands to pass to the scdaemon>\n"
1537   " \n"
1538   "This is a general quote command to redirect everything to the\n"
1539   "SCdaemon.";
1540 static gpg_error_t
1541 cmd_scd (assuan_context_t ctx, char *line)
1542 {
1543   ctrl_t ctrl = assuan_get_pointer (ctx);
1544   int rc;
1545
1546   rc = divert_generic_cmd (ctrl, line, ctx);
1547
1548   return rc;
1549 }
1550
1551
1552 \f
1553 static const char hlp_getval[] =
1554   "GETVAL <key>\n"
1555   "\n"
1556   "Return the value for KEY from the special environment as created by\n"
1557   "PUTVAL.";
1558 static gpg_error_t
1559 cmd_getval (assuan_context_t ctx, char *line)
1560 {
1561   int rc = 0;
1562   char *key = NULL;
1563   char *p;
1564   struct putval_item_s *vl;
1565
1566   for (p=line; *p == ' '; p++)
1567     ;
1568   key = p;
1569   p = strchr (key, ' ');
1570   if (p)
1571     {
1572       *p++ = 0;
1573       for (; *p == ' '; p++)
1574         ;
1575       if (*p)
1576         return set_error (GPG_ERR_ASS_PARAMETER, "too many arguments");
1577     }
1578   if (!key || !*key)
1579     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
1580
1581
1582   for (vl=putval_list; vl; vl = vl->next)
1583     if ( !strcmp (vl->d, key) )
1584       break;
1585
1586   if (vl) /* Got an entry. */
1587     rc = assuan_send_data (ctx, vl->d+vl->off, vl->len);
1588   else
1589     return gpg_error (GPG_ERR_NO_DATA);
1590
1591   if (rc)
1592     log_error ("command getval failed: %s\n", gpg_strerror (rc));
1593   return rc;
1594 }
1595
1596
1597 static const char hlp_putval[] =
1598   "PUTVAL <key> [<percent_escaped_value>]\n"
1599   "\n"
1600   "The gpg-agent maintains a kind of environment which may be used to\n"
1601   "store key/value pairs in it, so that they can be retrieved later.\n"
1602   "This may be used by helper daemons to daemonize themself on\n"
1603   "invocation and register them with gpg-agent.  Callers of the\n"
1604   "daemon's service may now first try connect to get the information\n"
1605   "for that service from gpg-agent through the GETVAL command and then\n"
1606   "try to connect to that daemon.  Only if that fails they may start\n"
1607   "an own instance of the service daemon. \n"
1608   "\n"
1609   "KEY is an an arbitrary symbol with the same syntax rules as keys\n"
1610   "for shell environment variables.  PERCENT_ESCAPED_VALUE is the\n"
1611   "corresponsing value; they should be similar to the values of\n"
1612   "envronment variables but gpg-agent does not enforce any\n"
1613   "restrictions.  If that value is not given any value under that KEY\n"
1614   "is removed from this special environment.";
1615 static gpg_error_t
1616 cmd_putval (assuan_context_t ctx, char *line)
1617 {
1618   int rc = 0;
1619   char *key = NULL;
1620   char *value = NULL;
1621   size_t valuelen = 0;
1622   char *p;
1623   struct putval_item_s *vl, *vlprev;
1624
1625   for (p=line; *p == ' '; p++)
1626     ;
1627   key = p;
1628   p = strchr (key, ' ');
1629   if (p)
1630     {
1631       *p++ = 0;
1632       for (; *p == ' '; p++)
1633         ;
1634       if (*p)
1635         {
1636           value = p;
1637           p = strchr (value, ' ');
1638           if (p)
1639             *p = 0;
1640           valuelen = percent_plus_unescape_inplace (value, 0);
1641         }
1642     }
1643   if (!key || !*key)
1644     return set_error (GPG_ERR_ASS_PARAMETER, "no key given");
1645
1646
1647   for (vl=putval_list,vlprev=NULL; vl; vlprev=vl, vl = vl->next)
1648     if ( !strcmp (vl->d, key) )
1649       break;
1650
1651   if (vl) /* Delete old entry. */
1652     {
1653       if (vlprev)
1654         vlprev->next = vl->next;
1655       else
1656         putval_list = vl->next;
1657       xfree (vl);
1658     }
1659
1660   if (valuelen) /* Add entry. */
1661     {
1662       vl = xtrymalloc (sizeof *vl + strlen (key) + valuelen);
1663       if (!vl)
1664         rc = gpg_error_from_syserror ();
1665       else
1666         {
1667           vl->len = valuelen;
1668           vl->off = strlen (key) + 1;
1669           strcpy (vl->d, key);
1670           memcpy (vl->d + vl->off, value, valuelen);
1671           vl->next = putval_list;
1672           putval_list = vl;
1673         }
1674     }
1675
1676   if (rc)
1677     log_error ("command putval failed: %s\n", gpg_strerror (rc));
1678   return rc;
1679 }
1680
1681
1682
1683 \f
1684 static const char hlp_updatestartuptty[] =
1685   "UPDATESTARTUPTTY\n"
1686   "\n"
1687   "Set startup TTY and X11 DISPLAY variables to the values of this\n"
1688   "session.  This command is useful to pull future pinentries to\n"
1689   "another screen.  It is only required because there is no way in the\n"
1690   "ssh-agent protocol to convey this information.";
1691 static gpg_error_t
1692 cmd_updatestartuptty (assuan_context_t ctx, char *line)
1693 {
1694   static const char *names[] =
1695     { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL };
1696   ctrl_t ctrl = assuan_get_pointer (ctx);
1697   gpg_error_t err = 0;
1698   session_env_t se;
1699   int idx;
1700   char *lc_ctype = NULL;
1701   char *lc_messages = NULL;
1702
1703   (void)line;
1704
1705   se = session_env_new ();
1706   if (!se)
1707     err = gpg_error_from_syserror ();
1708
1709   for (idx=0; !err && names[idx]; idx++)
1710     {
1711       const char *value = session_env_getenv (ctrl->session_env, names[idx]);
1712       if (value)
1713         err = session_env_setenv (se, names[idx], value);
1714     }
1715
1716   if (!err && ctrl->lc_ctype)
1717     if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype)))
1718       err = gpg_error_from_syserror ();
1719
1720   if (!err && ctrl->lc_messages)
1721     if (!(lc_messages = xtrystrdup (ctrl->lc_messages)))
1722       err = gpg_error_from_syserror ();
1723
1724   if (err)
1725     {
1726       session_env_release (se);
1727       xfree (lc_ctype);
1728       xfree (lc_messages);
1729     }
1730   else
1731     {
1732       session_env_release (opt.startup_env);
1733       opt.startup_env = se;
1734       xfree (opt.startup_lc_ctype);
1735       opt.startup_lc_ctype = lc_ctype;
1736       xfree (opt.startup_lc_messages);
1737       opt.startup_lc_messages = lc_messages;
1738     }
1739
1740   return err;
1741 }
1742
1743
1744 \f
1745 static const char hlp_killagent[] =
1746   "KILLAGENT\n"
1747   "\n"
1748   "If the agent has been started using a standard socket\n"
1749   "we allow a client to stop the agent.";
1750 static gpg_error_t
1751 cmd_killagent (assuan_context_t ctx, char *line)
1752 {
1753   ctrl_t ctrl = assuan_get_pointer (ctx);
1754
1755   (void)line;
1756
1757   if (!opt.use_standard_socket)
1758     return set_error (GPG_ERR_NOT_SUPPORTED, "no --use-standard-socket");
1759
1760   ctrl->server_local->stopme = 1;
1761   return gpg_error (GPG_ERR_EOF);
1762 }
1763
1764
1765 static const char hlp_reloadagent[] =
1766   "RELOADAGENT\n"
1767   "\n"
1768   "This command is an alternative to SIGHUP\n"
1769   "to reload the configuration.";
1770 static gpg_error_t
1771 cmd_reloadagent (assuan_context_t ctx, char *line)
1772 {
1773   (void)ctx;
1774   (void)line;
1775
1776   agent_sighup_action ();
1777   return 0;
1778 }
1779
1780
1781 \f
1782 static const char hlp_getinfo[] =
1783   "GETINFO <what>\n"
1784   "\n"
1785   "Multipurpose function to return a variety of information.\n"
1786   "Supported values for WHAT are:\n"
1787   "\n"
1788   "  version     - Return the version of the program.\n"
1789   "  pid         - Return the process id of the server.\n"
1790   "  socket_name - Return the name of the socket.\n"
1791   "  ssh_socket_name - Return the name of the ssh socket.\n"
1792   "  scd_running - Return OK if the SCdaemon is already running.\n"
1793   "  std_session_env - List the standard session environment.\n"
1794   "  std_startup_env - List the standard startup environment.\n"
1795   "  cmd_has_option\n"
1796   "              - Returns OK if the command CMD implements the option OPT.";
1797 static gpg_error_t
1798 cmd_getinfo (assuan_context_t ctx, char *line)
1799 {
1800   ctrl_t ctrl = assuan_get_pointer (ctx);
1801   int rc = 0;
1802
1803   if (!strcmp (line, "version"))
1804     {
1805       const char *s = VERSION;
1806       rc = assuan_send_data (ctx, s, strlen (s));
1807     }
1808   else if (!strcmp (line, "pid"))
1809     {
1810       char numbuf[50];
1811
1812       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1813       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1814     }
1815   else if (!strcmp (line, "socket_name"))
1816     {
1817       const char *s = get_agent_socket_name ();
1818
1819       if (s)
1820         rc = assuan_send_data (ctx, s, strlen (s));
1821       else
1822         rc = gpg_error (GPG_ERR_NO_DATA);
1823     }
1824   else if (!strcmp (line, "ssh_socket_name"))
1825     {
1826       const char *s = get_agent_ssh_socket_name ();
1827
1828       if (s)
1829         rc = assuan_send_data (ctx, s, strlen (s));
1830       else
1831         rc = gpg_error (GPG_ERR_NO_DATA);
1832     }
1833   else if (!strcmp (line, "scd_running"))
1834     {
1835       rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
1836     }
1837   else if (!strcmp (line, "s2k_count"))
1838     {
1839       char numbuf[50];
1840
1841       snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ());
1842       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1843     }
1844   else if (!strcmp (line, "std_session_env")
1845            || !strcmp (line, "std_startup_env"))
1846     {
1847       int iterator;
1848       const char *name, *value;
1849       char *string;
1850
1851       iterator = 0;
1852       while ((name = session_env_list_stdenvnames (&iterator, NULL)))
1853         {
1854           value = session_env_getenv_or_default
1855             (line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
1856           if (value)
1857             {
1858               string = xtryasprintf ("%s=%s", name, value);
1859               if (!string)
1860                 rc = gpg_error_from_syserror ();
1861               else
1862                 {
1863                   rc = assuan_send_data (ctx, string, strlen (string)+1);
1864                   if (!rc)
1865                     rc = assuan_send_data (ctx, NULL, 0);
1866                 }
1867               if (rc)
1868                 break;
1869             }
1870         }
1871     }
1872   else if (!strncmp (line, "cmd_has_option", 14)
1873            && (line[14] == ' ' || line[14] == '\t' || !line[14]))
1874     {
1875       char *cmd, *cmdopt;
1876       line += 14;
1877       while (*line == ' ' || *line == '\t')
1878         line++;
1879       if (!*line)
1880         rc = gpg_error (GPG_ERR_MISSING_VALUE);
1881       else
1882         {
1883           cmd = line;
1884           while (*line && (*line != ' ' && *line != '\t'))
1885             line++;
1886           if (!*line)
1887             rc = gpg_error (GPG_ERR_MISSING_VALUE);
1888           else
1889             {
1890               *line++ = 0;
1891               while (*line == ' ' || *line == '\t')
1892                 line++;
1893               if (!*line)
1894                 rc = gpg_error (GPG_ERR_MISSING_VALUE);
1895               else
1896                 {
1897                   cmdopt = line;
1898                   if (!command_has_option (cmd, cmdopt))
1899                     rc = gpg_error (GPG_ERR_GENERAL);
1900                 }
1901             }
1902         }
1903     }
1904   else
1905     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1906   return rc;
1907 }
1908
1909
1910 \f
1911 static gpg_error_t
1912 option_handler (assuan_context_t ctx, const char *key, const char *value)
1913 {
1914   ctrl_t ctrl = assuan_get_pointer (ctx);
1915   gpg_error_t err = 0;
1916
1917   if (!strcmp (key, "putenv"))
1918     {
1919       /* Change the session's environment to be used for the
1920          Pinentry.  Valid values are:
1921           <NAME>            Delete envvar NAME
1922           <KEY>=            Set envvar NAME to the empty string
1923           <KEY>=<VALUE>     Set envvar NAME to VALUE
1924       */
1925       err = session_env_putenv (ctrl->session_env, value);
1926     }
1927   else if (!strcmp (key, "display"))
1928     {
1929       err = session_env_setenv (ctrl->session_env, "DISPLAY", value);
1930     }
1931   else if (!strcmp (key, "ttyname"))
1932     {
1933       if (!opt.keep_tty)
1934         err = session_env_setenv (ctrl->session_env, "GPG_TTY", value);
1935     }
1936   else if (!strcmp (key, "ttytype"))
1937     {
1938       if (!opt.keep_tty)
1939         err = session_env_setenv (ctrl->session_env, "TERM", value);
1940     }
1941   else if (!strcmp (key, "lc-ctype"))
1942     {
1943       if (ctrl->lc_ctype)
1944         xfree (ctrl->lc_ctype);
1945       ctrl->lc_ctype = xtrystrdup (value);
1946       if (!ctrl->lc_ctype)
1947         return out_of_core ();
1948     }
1949   else if (!strcmp (key, "lc-messages"))
1950     {
1951       if (ctrl->lc_messages)
1952         xfree (ctrl->lc_messages);
1953       ctrl->lc_messages = xtrystrdup (value);
1954       if (!ctrl->lc_messages)
1955         return out_of_core ();
1956     }
1957   else if (!strcmp (key, "xauthority"))
1958     {
1959       err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value);
1960     }
1961   else if (!strcmp (key, "pinentry-user-data"))
1962     {
1963       err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value);
1964     }
1965   else if (!strcmp (key, "use-cache-for-signing"))
1966     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
1967   else if (!strcmp (key, "allow-pinentry-notify"))
1968     ctrl->server_local->allow_pinentry_notify = 1;
1969   else
1970     err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
1971
1972   return err;
1973 }
1974
1975
1976
1977 \f
1978 /* Called by libassuan after all commands. ERR is the error from the
1979    last assuan operation and not the one returned from the command. */
1980 static void
1981 post_cmd_notify (assuan_context_t ctx, gpg_error_t err)
1982 {
1983   ctrl_t ctrl = assuan_get_pointer (ctx);
1984
1985   (void)err;
1986
1987   /* Switch off any I/O monitor controlled logging pausing. */
1988   ctrl->server_local->pause_io_logging = 0;
1989 }
1990
1991
1992 /* This function is called by libassuan for all I/O.  We use it here
1993    to disable logging for the GETEVENTCOUNTER commands.  This is so
1994    that the debug output won't get cluttered by this primitive
1995    command.  */
1996 static unsigned int
1997 io_monitor (assuan_context_t ctx, void *hook, int direction,
1998             const char *line, size_t linelen)
1999 {
2000   ctrl_t ctrl = assuan_get_pointer (ctx);
2001
2002   (void) hook;
2003
2004   /* Note that we only check for the uppercase name.  This allows to
2005      see the logging for debugging if using a non-upercase command
2006      name. */
2007   if (ctx && direction == ASSUAN_IO_FROM_PEER
2008       && linelen >= 15
2009       && !strncmp (line, "GETEVENTCOUNTER", 15)
2010       && (linelen == 15 || spacep (line+15)))
2011     {
2012       ctrl->server_local->pause_io_logging = 1;
2013     }
2014
2015   return ctrl->server_local->pause_io_logging? ASSUAN_IO_MONITOR_NOLOG : 0;
2016 }
2017
2018
2019 /* Return true if the command CMD implements the option OPT.  */
2020 static int
2021 command_has_option (const char *cmd, const char *cmdopt)
2022 {
2023   if (!strcmp (cmd, "GET_PASSPHRASE"))
2024     {
2025       if (!strcmp (cmdopt, "repeat"))
2026           return 1;
2027     }
2028
2029   return 0;
2030 }
2031
2032
2033 /* Tell the assuan library about our commands */
2034 static int
2035 register_commands (assuan_context_t ctx)
2036 {
2037   static struct {
2038     const char *name;
2039     assuan_handler_t handler;
2040     const char * const help;
2041   } table[] = {
2042     { "GETEVENTCOUNTER",cmd_geteventcounter, hlp_geteventcounter },
2043     { "ISTRUSTED",      cmd_istrusted, hlp_istrusted },
2044     { "HAVEKEY",        cmd_havekey,   hlp_havekey },
2045     { "KEYINFO",        cmd_keyinfo,   hlp_keyinfo },
2046     { "SIGKEY",         cmd_sigkey,    hlp_sigkey },
2047     { "SETKEY",         cmd_sigkey,    hlp_sigkey },
2048     { "SETKEYDESC",     cmd_setkeydesc,hlp_setkeydesc },
2049     { "SETHASH",        cmd_sethash,   hlp_sethash },
2050     { "PKSIGN",         cmd_pksign,    hlp_pksign },
2051     { "PKDECRYPT",      cmd_pkdecrypt, hlp_pkdecrypt },
2052     { "GENKEY",         cmd_genkey,    hlp_genkey },
2053     { "READKEY",        cmd_readkey,   hlp_readkey },
2054     { "GET_PASSPHRASE", cmd_get_passphrase, hlp_get_passphrase },
2055     { "PRESET_PASSPHRASE", cmd_preset_passphrase, hlp_preset_passphrase },
2056     { "CLEAR_PASSPHRASE", cmd_clear_passphrase,   hlp_clear_passphrase },
2057     { "GET_CONFIRMATION", cmd_get_confirmation,   hlp_get_confirmation },
2058     { "LISTTRUSTED",    cmd_listtrusted, hlp_listtrusted },
2059     { "MARKTRUSTED",    cmd_marktrusted, hlp_martrusted },
2060     { "LEARN",          cmd_learn,     hlp_learn },
2061     { "PASSWD",         cmd_passwd,    hlp_passwd },
2062     { "INPUT",          NULL },
2063     { "OUTPUT",         NULL },
2064     { "SCD",            cmd_scd,       hlp_scd },
2065     { "GETVAL",         cmd_getval,    hlp_getval },
2066     { "PUTVAL",         cmd_putval,    hlp_putval },
2067     { "UPDATESTARTUPTTY",  cmd_updatestartuptty, hlp_updatestartuptty },
2068     { "KILLAGENT",      cmd_killagent,  hlp_killagent },
2069     { "RELOADAGENT",    cmd_reloadagent,hlp_reloadagent },
2070     { "GETINFO",        cmd_getinfo,   hlp_getinfo },
2071     { NULL }
2072   };
2073   int i, rc;
2074
2075   for (i=0; table[i].name; i++)
2076     {
2077       rc = assuan_register_command (ctx, table[i].name, table[i].handler,
2078                                     table[i].help);
2079       if (rc)
2080         return rc;
2081     }
2082   assuan_register_post_cmd_notify (ctx, post_cmd_notify);
2083   assuan_register_reset_notify (ctx, reset_notify);
2084   assuan_register_option_handler (ctx, option_handler);
2085   return 0;
2086 }
2087
2088
2089 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a
2090    simple piper server, otherwise it is a regular server.  CTRL is the
2091    control structure for this connection; it has only the basic
2092    intialization. */
2093 void
2094 start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
2095 {
2096   int rc;
2097   assuan_context_t ctx = NULL;
2098
2099   rc = assuan_new (&ctx);
2100   if (rc)
2101     {
2102       log_error ("failed to allocate assuan context: %s\n", gpg_strerror (rc));
2103       agent_exit (2);
2104     }
2105
2106   if (listen_fd == GNUPG_INVALID_FD && fd == GNUPG_INVALID_FD)
2107     {
2108       assuan_fd_t filedes[2];
2109
2110       filedes[0] = assuan_fdopen (0);
2111       filedes[1] = assuan_fdopen (1);
2112       rc = assuan_init_pipe_server (ctx, filedes);
2113     }
2114   else if (listen_fd != GNUPG_INVALID_FD)
2115     {
2116       rc = assuan_init_socket_server (ctx, listen_fd, 0);
2117       /* FIXME: Need to call assuan_sock_set_nonce for Windows.  But
2118          this branch is currently not used.  */
2119     }
2120   else
2121     {
2122       rc = assuan_init_socket_server (ctx, fd, ASSUAN_SOCKET_SERVER_ACCEPTED);
2123     }
2124   if (rc)
2125     {
2126       log_error ("failed to initialize the server: %s\n",
2127                  gpg_strerror(rc));
2128       agent_exit (2);
2129     }
2130   rc = register_commands (ctx);
2131   if (rc)
2132     {
2133       log_error ("failed to register commands with Assuan: %s\n",
2134                  gpg_strerror(rc));
2135       agent_exit (2);
2136     }
2137
2138   assuan_set_pointer (ctx, ctrl);
2139   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
2140   ctrl->server_local->assuan_ctx = ctx;
2141   ctrl->server_local->message_fd = -1;
2142   ctrl->server_local->use_cache_for_signing = 1;
2143   ctrl->digest.raw_value = 0;
2144
2145   assuan_set_io_monitor (ctx, io_monitor, NULL);
2146
2147   for (;;)
2148     {
2149       rc = assuan_accept (ctx);
2150       if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1)
2151         {
2152           break;
2153         }
2154       else if (rc)
2155         {
2156           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
2157           break;
2158         }
2159
2160       rc = assuan_process (ctx);
2161       if (rc)
2162         {
2163           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
2164           continue;
2165         }
2166     }
2167
2168   /* Reset the SCD if needed. */
2169   agent_reset_scd (ctrl);
2170
2171   /* Reset the pinentry (in case of popup messages). */
2172   agent_reset_query (ctrl);
2173
2174   /* Cleanup.  */
2175   assuan_release (ctx);
2176   if (ctrl->server_local->stopme)
2177     agent_exit (0);
2178   xfree (ctrl->server_local);
2179   ctrl->server_local = NULL;
2180 }
2181