Mainly changes to adjust for the changed KSBA API.
[gnupg.git] / agent / command.c
1 /* command.c - gpg-agent command handler
2  *      Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
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 #include <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <unistd.h>
31
32 #include <assuan.h>
33
34 #include "agent.h"
35
36 /* maximum allowed size of the inquired ciphertext */
37 #define MAXLEN_CIPHERTEXT 4096
38 /* maximum allowed size of the key parameters */
39 #define MAXLEN_KEYPARAM 1024
40
41 #define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
42
43
44 #if MAX_DIGEST_LEN < 20
45 #error MAX_DIGEST_LEN shorter than keygrip
46 #endif
47
48 /* Data used to associate an Assuan context with local server data */
49 struct server_local_s {
50   ASSUAN_CONTEXT assuan_ctx;
51   int message_fd;
52   int use_cache_for_signing;
53 };
54
55
56
57
58 \f
59 static void
60 reset_notify (ASSUAN_CONTEXT ctx)
61 {
62   CTRL ctrl = assuan_get_pointer (ctx);
63
64   memset (ctrl->keygrip, 0, 20);
65   ctrl->have_keygrip = 0;
66   ctrl->digest.valuelen = 0;
67 }
68
69
70 /* Check whether the option NAME appears in LINE */
71 static int
72 has_option (const char *line, const char *name)
73 {
74   const char *s;
75   int n = strlen (name);
76
77   s = strstr (line, name);
78   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
79 }
80
81 /* Parse a hex string.  Return an Assuan error code or 0 on success and the
82    length of the parsed string in LEN. */
83 static int
84 parse_hexstring (ASSUAN_CONTEXT ctx, const char *string, size_t *len)
85 {
86   const char *p;
87   size_t n;
88
89   /* parse the hash value */
90   for (p=string, n=0; hexdigitp (p); p++, n++)
91     ;
92   if (*p)
93     return set_error (Parameter_Error, "invalid hexstring");
94   if ((n&1))
95     return set_error (Parameter_Error, "odd number of digits");
96   *len = n;
97   return 0;
98 }
99
100 /* Parse the keygrip in STRING into the provided buffer BUF.  BUF must
101    provide space for 20 bytes. BUF is not changed if the fucntions
102    returns an error. */
103 static int
104 parse_keygrip (ASSUAN_CONTEXT ctx, const char *string, unsigned char *buf)
105 {
106   int rc;
107   size_t n;
108   const unsigned char *p;
109
110   rc = parse_hexstring (ctx, string, &n);
111   if (rc)
112     return rc;
113   n /= 2;
114   if (n != 20)
115     return set_error (Parameter_Error, "invalid length of keygrip");
116
117   for (p=string, n=0; n < 20; p += 2, n++)
118     buf[n] = xtoi_2 (p);
119
120   return 0;
121 }
122
123
124
125
126 /* ISTRUSTED <hexstring_with_fingerprint>
127
128    Return OK when we have an entry with this fingerprint in our
129    trustlist */
130 static int
131 cmd_istrusted (ASSUAN_CONTEXT ctx, char *line)
132 {
133   int rc, n, i;
134   char *p;
135   char fpr[41];
136
137   /* parse the fingerprint value */
138   for (p=line,n=0; hexdigitp (p); p++, n++)
139     ;
140   if (*p || !(n == 40 || n == 32))
141     return set_error (Parameter_Error, "invalid fingerprint");
142   i = 0;
143   if (n==32)
144     {
145       strcpy (fpr, "00000000");
146       i += 8;
147     }
148   for (p=line; i < 40; p++, i++)
149     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
150   fpr[i] = 0;
151   rc = agent_istrusted (fpr);
152   if (!rc)
153     return 0;
154   else if (rc == -1)
155     return ASSUAN_Not_Trusted;
156   else
157     {
158       log_error ("command is_trusted failed: %s\n", gpg_strerror (rc));
159       return map_to_assuan_status (rc);
160     }
161 }
162
163 /* LISTTRUSTED 
164
165    List all entries from the trustlist */
166 static int
167 cmd_listtrusted (ASSUAN_CONTEXT ctx, char *line)
168 {
169   int rc = agent_listtrusted (ctx);
170   if (rc)
171     log_error ("command listtrusted failed: %s\n", gpg_strerror (rc));
172   return map_to_assuan_status (rc);
173 }
174
175
176 /* MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>
177
178    Store a new key in into the trustlist*/
179 static int
180 cmd_marktrusted (ASSUAN_CONTEXT ctx, char *line)
181 {
182   CTRL ctrl = assuan_get_pointer (ctx);
183   int rc, n, i;
184   char *p;
185   char fpr[41];
186   int flag;
187
188   /* parse the fingerprint value */
189   for (p=line,n=0; hexdigitp (p); p++, n++)
190     ;
191   if (!spacep (p) || !(n == 40 || n == 32))
192     return set_error (Parameter_Error, "invalid fingerprint");
193   i = 0;
194   if (n==32)
195     {
196       strcpy (fpr, "00000000");
197       i += 8;
198     }
199   for (p=line; i < 40; p++, i++)
200     fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
201   fpr[i] = 0;
202   
203   while (spacep (p))
204     p++;
205   flag = *p++;
206   if ( (flag != 'S' && flag != 'P') || !spacep (p) )
207     return set_error (Parameter_Error, "invalid flag - must be P or S");
208   while (spacep (p))
209     p++;
210
211   rc = agent_marktrusted (ctrl, p, fpr, flag);
212   if (rc)
213     log_error ("command marktrusted failed: %s\n", gpg_strerror (rc));
214   return map_to_assuan_status (rc);
215 }
216
217
218
219 \f
220 /* HAVEKEY <hexstring_with_keygrip>
221   
222    Return success when the secret key is available */
223 static int
224 cmd_havekey (ASSUAN_CONTEXT ctx, char *line)
225 {
226   int rc;
227   unsigned char buf[20];
228
229   rc = parse_keygrip (ctx, line, buf);
230   if (rc)
231     return rc;
232
233   if (agent_key_available (buf))
234     return ASSUAN_No_Secret_Key;
235
236   return 0;
237 }
238
239
240 /* SIGKEY <hexstring_with_keygrip>
241    SETKEY <hexstring_with_keygrip>
242   
243    Set the  key used for a sign or decrypt operation */
244 static int
245 cmd_sigkey (ASSUAN_CONTEXT ctx, char *line)
246 {
247   int rc;
248   CTRL ctrl = assuan_get_pointer (ctx);
249
250   rc = parse_keygrip (ctx, line, ctrl->keygrip);
251   if (rc)
252     return rc;
253   ctrl->have_keygrip = 1;
254   return 0;
255 }
256
257
258 /* SETHASH <algonumber> <hexstring> 
259
260   The client can use this command to tell the server about the data
261   (which usually is a hash) to be signed. */
262 static int
263 cmd_sethash (ASSUAN_CONTEXT ctx, char *line)
264 {
265   int rc;
266   size_t n;
267   char *p;
268   CTRL ctrl = assuan_get_pointer (ctx);
269   unsigned char *buf;
270   char *endp;
271   int algo;
272
273   /* parse the algo number and check it */
274   algo = (int)strtoul (line, &endp, 10);
275   for (line = endp; *line == ' ' || *line == '\t'; line++)
276     ;
277   if (!algo || gcry_md_test_algo (algo))
278     return set_error (Unsupported_Algorithm, NULL);
279   ctrl->digest.algo = algo;
280
281   /* parse the hash value */
282   rc = parse_hexstring (ctx, line, &n);
283   if (rc)
284     return rc;
285   n /= 2;
286   if (n != 16 && n != 20 && n != 24 && n != 32)
287     return set_error (Parameter_Error, "unsupported length of hash");
288   if (n > MAX_DIGEST_LEN)
289     return set_error (Parameter_Error, "hash value to long");
290
291   buf = ctrl->digest.value;
292   ctrl->digest.valuelen = n;
293   for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++)
294     buf[n] = xtoi_2 (p);
295   for (; n < ctrl->digest.valuelen; n++)
296     buf[n] = 0;
297   return 0;
298 }
299
300
301 /* PKSIGN <options>
302
303    Perform the actual sign operation. Neither input nor output are
304    sensitive to eavesdropping */
305 static int
306 cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
307 {
308   int rc;
309   int ignore_cache = 0;
310   CTRL ctrl = assuan_get_pointer (ctx);
311
312   if (opt.ignore_cache_for_signing)
313     ignore_cache = 1;
314   else if (!ctrl->server_local->use_cache_for_signing)
315     ignore_cache = 1;
316
317   rc = agent_pksign (ctrl, assuan_get_data_fp (ctx), ignore_cache);
318   if (rc)
319     log_error ("command pksign failed: %s\n", gpg_strerror (rc));
320   return map_to_assuan_status (rc);
321 }
322
323 /* PKDECRYPT <options>
324
325    Perform the actual decrypt operation.  Input is not 
326    sensitive to eavesdropping */
327 static int
328 cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
329 {
330   int rc;
331   CTRL ctrl = assuan_get_pointer (ctx);
332   unsigned char *value;
333   size_t valuelen;
334
335   /* First inquire the data to decrypt */
336   rc = assuan_inquire (ctx, "CIPHERTEXT",
337                        &value, &valuelen, MAXLEN_CIPHERTEXT);
338   if (rc)
339     return rc;
340
341   rc = agent_pkdecrypt (ctrl, value, valuelen, assuan_get_data_fp (ctx));
342   xfree (value);
343   if (rc)
344     log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc));
345   return map_to_assuan_status (rc);
346 }
347
348
349 /* GENKEY
350
351    Generate a new key, store the secret part and return the public
352    part.  Here is an example transaction:
353
354    C: GENKEY
355    S: INQUIRE KEYPARM
356    C: D (genkey (rsa (nbits  1024)))
357    C: END
358    S: D (public-key
359    S: D   (rsa (n 326487324683264) (e 10001)))
360    S  OK key created
361 */
362
363 static int
364 cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
365 {
366   CTRL ctrl = assuan_get_pointer (ctx);
367   int rc;
368   unsigned char *value;
369   size_t valuelen;
370
371   /* First inquire the parameters */
372   rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
373   if (rc)
374     return rc;
375
376   rc = agent_genkey (ctrl, value, valuelen, assuan_get_data_fp (ctx));
377   xfree (value);
378   if (rc)
379     log_error ("command genkey failed: %s\n", gpg_strerror (rc));
380   return map_to_assuan_status (rc);
381 }
382
383
384 static void
385 plus_to_blank (char *s)
386 {
387   for (; *s; s++)
388     {
389       if (*s == '+')
390         *s = ' ';
391     }
392 }
393
394 /* GET_PASSPHRASE <cache_id> [<error_message> <prompt> <description>]
395
396    This function is usually used to ask for a passphrase to be used
397    for conventional encryption, but may also be used by programs which
398    need specal handling of passphrases.  This command uses a syntax
399    which helps clients to use the agent with minimum effort.  The
400    agent either returns with an error or with a OK followed by the hex
401    encoded passphrase.  Note that the length of the strings is
402    implicitly limited by the maximum length of a command.
403 */
404
405 static int
406 cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line)
407 {
408   CTRL ctrl = assuan_get_pointer (ctx);
409   int rc;
410   const char *pw;
411   char *response;
412   char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
413   char *p;
414   void *cache_marker;
415
416   /* parse the stuff */
417   for (p=line; *p == ' '; p++)
418     ;
419   cacheid = p;
420   p = strchr (cacheid, ' ');
421   if (p)
422     {
423       *p++ = 0;
424       while (*p == ' ')
425         p++;
426       errtext = p;
427       p = strchr (errtext, ' ');
428       if (p)
429         {
430           *p++ = 0;
431           while (*p == ' ')
432             p++;
433           prompt = p;
434           p = strchr (prompt, ' ');
435           if (p)
436             {
437               *p++ = 0;
438               while (*p == ' ')
439                 p++;
440               desc = p;
441               p = strchr (desc, ' ');
442               if (p)
443                 *p = 0; /* ignore garbage */
444             }
445         }
446     }
447   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
448     return set_error (Parameter_Error, "invalid length of cacheID");
449   if (!desc)
450     return set_error (Parameter_Error, "no description given");
451
452   if (!strcmp (cacheid, "X"))
453     cacheid = NULL;
454   if (!strcmp (errtext, "X"))
455     errtext = NULL;
456   if (!strcmp (prompt, "X"))
457     prompt = NULL;
458   if (!strcmp (desc, "X"))
459     desc = NULL;
460
461   /* Note: we store the hexified versions in the cache. */
462   pw = cacheid ? agent_get_cache (cacheid, &cache_marker) : NULL;
463   if (pw)
464     {
465       assuan_begin_confidential (ctx);
466       rc = assuan_set_okay_line (ctx, pw);
467       agent_unlock_cache_entry (&cache_marker);
468     }
469   else
470     {
471       /* Note, that we only need to replace the + characters and
472          should leave the other escaping in place because the escaped
473          string is send verbatim to the pinentry which does the
474          unescaping (but not the + replacing) */
475       if (errtext)
476         plus_to_blank (errtext);
477       if (prompt)
478         plus_to_blank (prompt);
479       if (desc)
480         plus_to_blank (desc);
481
482       rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext);
483       if (!rc)
484         {
485           if (cacheid)
486             agent_put_cache (cacheid, response, 0);
487           assuan_begin_confidential (ctx);
488           rc = assuan_set_okay_line (ctx, response);
489           xfree (response);
490         }
491     }
492
493   if (rc)
494     log_error ("command get_passphrase failed: %s\n", gpg_strerror (rc));
495   return map_to_assuan_status (rc);
496 }
497
498
499 /* CLEAR_PASSPHRASE <cache_id>
500
501    may be used to invalidate the cache entry for a passphrase.  The
502    function returns with OK even when there is no cached passphrase.
503 */
504
505 static int
506 cmd_clear_passphrase (ASSUAN_CONTEXT ctx, char *line)
507 {
508   char *cacheid = NULL;
509   char *p;
510
511   /* parse the stuff */
512   for (p=line; *p == ' '; p++)
513     ;
514   cacheid = p;
515   p = strchr (cacheid, ' ');
516   if (p)
517     *p = 0; /* ignore garbage */
518   if (!cacheid || !*cacheid || strlen (cacheid) > 50)
519     return set_error (Parameter_Error, "invalid length of cacheID");
520
521   agent_put_cache (cacheid, NULL, 0);
522   return 0;
523 }
524
525
526 /* GET_CONFIRMATION <description>
527
528    This command may be used to ask for a simple confirmation.
529    DESCRIPTION is displayed along with a Okay and Cancel button.  This
530    command uses a syntax which helps clients to use the agent with
531    minimum effort.  The agent either returns with an error or with a
532    OK.  Note, that the length of DESCRIPTION is implicitly limited by
533    the maximum length of a command. DESCRIPTION should not conmtain
534    ant spaces, those must be encoded either percent escaped or simply
535    as '+'.
536 */
537
538 static int
539 cmd_get_confirmation (ASSUAN_CONTEXT ctx, char *line)
540 {
541   CTRL ctrl = assuan_get_pointer (ctx);
542   int rc;
543   char *desc = NULL;
544   char *p;
545
546   /* parse the stuff */
547   for (p=line; *p == ' '; p++)
548     ;
549   desc = p;
550   p = strchr (desc, ' ');
551   if (p)
552     *p = 0; /* We ignore any garbage -may be later used for other args. */
553
554   if (!desc || !*desc)
555     return set_error (Parameter_Error, "no description given");
556
557   if (!strcmp (desc, "X"))
558     desc = NULL;
559
560   /* Note, that we only need to replace the + characters and should
561      leave the other escaping in place because the escaped string is
562      send verbatim to the pinentry which does the unescaping (but not
563      the + replacing) */
564   if (desc)
565     plus_to_blank (desc);
566
567   rc = agent_get_confirmation (ctrl, desc, NULL, NULL);
568   if (rc)
569     log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
570   return map_to_assuan_status (rc);
571 }
572
573
574 \f
575 /* LEARN [--send]
576
577    Learn something about the currently inserted smartcard.  With
578    --send the new certificates are send back.  */
579 static int
580 cmd_learn (ASSUAN_CONTEXT ctx, char *line)
581 {
582   int rc;
583
584   rc = agent_handle_learn (has_option (line, "--send")? ctx : NULL);
585   if (rc)
586     log_error ("command learn failed: %s\n", gpg_strerror (rc));
587   return map_to_assuan_status (rc);
588 }
589
590
591 \f
592 /* PASSWD <hexstring_with_keygrip>
593   
594    Change the passphrase/PID for the key identified by keygrip in LINE. */
595 static int
596 cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
597 {
598   CTRL ctrl = assuan_get_pointer (ctx);
599   int rc;
600   unsigned char grip[20];
601   gcry_sexp_t s_skey = NULL;
602   unsigned char *shadow_info = NULL;
603
604   rc = parse_keygrip (ctx, line, grip);
605   if (rc)
606     return rc; /* we can't jump to leave because this is already an
607                   Assuan error code. */
608
609   s_skey = agent_key_from_file (ctrl, grip, &shadow_info, 1);
610   if (!s_skey && !shadow_info)
611     rc = gpg_error (GPG_ERR_NO_SECKEY);
612   else if (!s_skey)
613     {
614       log_error ("changing a smartcard PIN is not yet supported\n");
615       rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
616     }
617   else
618     rc = agent_protect_and_store (ctrl, s_skey);
619
620   gcry_sexp_release (s_skey);
621   xfree (shadow_info);
622   if (rc)
623     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
624   return map_to_assuan_status (rc);
625 }
626
627 \f
628 /* SCD <commands to pass to the scdaemon>
629   
630    This is a general quote command to redirect everything to the
631    SCDAEMON. */
632 static int
633 cmd_scd (ASSUAN_CONTEXT ctx, char *line)
634 {
635   CTRL ctrl = assuan_get_pointer (ctx);
636   int rc;
637
638   rc = divert_generic_cmd (ctrl, line, ctx);
639
640   return map_to_assuan_status (rc);
641 }
642
643
644 \f
645 static int
646 option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
647 {
648    CTRL ctrl = assuan_get_pointer (ctx);
649
650   if (!strcmp (key, "display"))
651     {
652       if (ctrl->display)
653         free (ctrl->display);
654       ctrl->display = strdup (value);
655       if (!ctrl->display)
656         return ASSUAN_Out_Of_Core;
657     }
658   else if (!strcmp (key, "ttyname"))
659     {
660       if (!opt.keep_tty)
661         {
662           if (ctrl->ttyname)
663             free (ctrl->ttyname);
664           ctrl->ttyname = strdup (value);
665           if (!ctrl->ttyname)
666             return ASSUAN_Out_Of_Core;
667         }
668     }
669   else if (!strcmp (key, "ttytype"))
670     {
671       if (!opt.keep_tty)
672         {
673           if (ctrl->ttytype)
674             free (ctrl->ttytype);
675           ctrl->ttytype = strdup (value);
676           if (!ctrl->ttytype)
677             return ASSUAN_Out_Of_Core;
678         }
679     }
680   else if (!strcmp (key, "lc-ctype"))
681     {
682       if (ctrl->lc_ctype)
683         free (ctrl->lc_ctype);
684       ctrl->lc_ctype = strdup (value);
685       if (!ctrl->lc_ctype)
686         return ASSUAN_Out_Of_Core;
687     }
688   else if (!strcmp (key, "lc-messages"))
689     {
690       if (ctrl->lc_messages)
691         free (ctrl->lc_messages);
692       ctrl->lc_messages = strdup (value);
693       if (!ctrl->lc_messages)
694         return ASSUAN_Out_Of_Core;
695     }
696   else if (!strcmp (key, "use-cache-for-signing"))
697     ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
698   else
699     return ASSUAN_Invalid_Option;
700
701   return 0;
702 }
703
704 \f
705 /* Tell the assuan library about our commands */
706 static int
707 register_commands (ASSUAN_CONTEXT ctx)
708 {
709   static struct {
710     const char *name;
711     int (*handler)(ASSUAN_CONTEXT, char *line);
712   } table[] = {
713     { "ISTRUSTED",      cmd_istrusted },
714     { "HAVEKEY",        cmd_havekey },
715     { "SIGKEY",         cmd_sigkey },
716     { "SETKEY",         cmd_sigkey },
717     { "SETHASH",        cmd_sethash },
718     { "PKSIGN",         cmd_pksign },
719     { "PKDECRYPT",      cmd_pkdecrypt },
720     { "GENKEY",         cmd_genkey },
721     { "GET_PASSPHRASE", cmd_get_passphrase },
722     { "CLEAR_PASSPHRASE", cmd_clear_passphrase },
723     { "GET_CONFIRMATION", cmd_get_confirmation },
724     { "LISTTRUSTED",    cmd_listtrusted },
725     { "MARKTRUSTED",    cmd_marktrusted },
726     { "LEARN",          cmd_learn },
727     { "PASSWD",         cmd_passwd },
728     { "INPUT",          NULL }, 
729     { "OUTPUT",         NULL }, 
730     { "SCD",            cmd_scd },
731     { NULL }
732   };
733   int i, rc;
734
735   for (i=0; table[i].name; i++)
736     {
737       rc = assuan_register_command (ctx, table[i].name, table[i].handler);
738       if (rc)
739         return rc;
740     } 
741   assuan_register_reset_notify (ctx, reset_notify);
742   assuan_register_option_handler (ctx, option_handler);
743   return 0;
744 }
745
746
747 /* Startup the server.  If LISTEN_FD and FD is given as -1, this is a simple
748    piper server, otherwise it is a regular server */
749 void
750 start_command_handler (int listen_fd, int fd)
751 {
752   int rc;
753   ASSUAN_CONTEXT ctx;
754   struct server_control_s ctrl;
755
756   memset (&ctrl, 0, sizeof ctrl);
757   agent_init_default_ctrl (&ctrl);
758   
759   if (listen_fd == -1 && fd == -1)
760     {
761       int filedes[2];
762
763       filedes[0] = 0;
764       filedes[1] = 1;
765       rc = assuan_init_pipe_server (&ctx, filedes);
766     }
767   else if (listen_fd != -1)
768     {
769       rc = assuan_init_socket_server (&ctx, listen_fd);
770     }
771   else 
772     {
773       rc = assuan_init_connected_socket_server (&ctx, fd);
774     }
775   if (rc)
776     {
777       log_error ("failed to initialize the server: %s\n",
778                  assuan_strerror(rc));
779       agent_exit (2);
780     }
781   rc = register_commands (ctx);
782   if (rc)
783     {
784       log_error ("failed to register commands with Assuan: %s\n",
785                  assuan_strerror(rc));
786       agent_exit (2);
787     }
788
789   assuan_set_pointer (ctx, &ctrl);
790   ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
791   ctrl.server_local->assuan_ctx = ctx;
792   ctrl.server_local->message_fd = -1;
793   ctrl.server_local->use_cache_for_signing = 1;
794
795   if (DBG_ASSUAN)
796     assuan_set_log_stream (ctx, log_get_stream ());
797
798   for (;;)
799     {
800       rc = assuan_accept (ctx);
801       if (rc == -1)
802         {
803           break;
804         }
805       else if (rc)
806         {
807           log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
808           break;
809         }
810       
811       rc = assuan_process (ctx);
812       if (rc)
813         {
814           log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
815           continue;
816         }
817     }
818
819
820   assuan_deinit_server (ctx);
821   if (ctrl.display)
822     free (ctrl.display);
823   if (ctrl.ttyname)
824     free (ctrl.ttyname);
825   if (ctrl.ttytype)
826     free (ctrl.ttytype);
827   if (ctrl.lc_ctype)
828     free (ctrl.lc_ctype);
829   if (ctrl.lc_messages)
830     free (ctrl.lc_messages);
831 }
832