(retrieve_key_material): Rewritten. Return a
[gnupg.git] / scd / command.c
1 /* command.c - SCdaemon command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005 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 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #ifdef USE_GNU_PTH
30 # include <pth.h>
31 #endif
32
33 #include <assuan.h>
34
35 #include "scdaemon.h"
36 #include <ksba.h>
37 #include "app-common.h"
38 #include "apdu.h" /* Required for apdu_*_reader (). */
39
40 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
41 #define MAXLEN_PIN 100
42
43
44 #define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
45
46
47 /* Macro to flag a a removed card.  */
48 #define TEST_CARD_REMOVAL(c,r)                              \
49        do {                                                 \
50           int _r = (r);                                     \
51           if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
52               || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED) \
53             update_card_removed ((c)->reader_slot, 1);      \
54        } while (0)
55
56 #define IS_LOCKED(c)                                                     \
57      (locked_session && locked_session != (c)->server_local              \
58       && (c)->reader_slot != -1 && locked_session->ctrl_backlink         \
59       && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
60
61
62 /* Data used to associate an Assuan context with local server data.
63    This object describes the local properties of one session.  */
64 struct server_local_s {
65   /* We keep a list of all active sessions with the anchor at
66      SESSION_LIST (see below).  This field is used for linking. */
67   struct server_local_s *next_session; 
68
69   /* This object is usually assigned to a CTRL object (which is
70      globally visible).  While enumeratin all sessions we sometimes
71      need to access data of the CTRL object; thus we keep a
72      backpointer here. */
73   ctrl_t ctrl_backlink;
74
75   /* The Assuan context used by this session/server. */
76   assuan_context_t assuan_ctx;
77
78   int event_signal;        /* Or 0 if not used. */
79
80   /* True if the card has been removed and a reset is required to
81      continue operation. */
82   int card_removed;        
83 };
84
85
86 /* To keep track of all running sessions, we link all active server
87    contexts and the anchor in this variable.  */
88 static struct server_local_s *session_list;
89
90 /* If a session has been locked we store a link to its server object
91    in this variable. */
92 static struct server_local_s *locked_session;
93
94
95
96 \f
97 /* Update the CARD_REMOVED element of all sessions using the reader
98    given by SLOT to VALUE  */
99 static void
100 update_card_removed (int slot, int value)
101 {
102   struct server_local_s *sl;
103
104   for (sl=session_list; sl; sl = sl->next_session)
105     if (sl->ctrl_backlink
106         && sl->ctrl_backlink->reader_slot == slot)
107       sl->card_removed = value;
108 }
109
110
111
112 /* Check whether the option NAME appears in LINE */
113 static int
114 has_option (const char *line, const char *name)
115 {
116   const char *s;
117   int n = strlen (name);
118
119   s = strstr (line, name);
120   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
121 }
122
123
124 /* Reset the card and free the application context.  With DO_CLOSE set
125    to true and this is the last session with a reference to teh
126    reader, close the reader and don't do just a reset. */
127 static void
128 do_reset (ctrl_t ctrl, int do_close)
129 {
130   int slot = ctrl->reader_slot;
131
132   if (ctrl->card_ctx)
133     {
134       card_close (ctrl->card_ctx);
135       ctrl->card_ctx = NULL;
136       xfree (ctrl->in_data.value);
137       ctrl->in_data.value = NULL;
138     }
139   if (ctrl->app_ctx)
140     {
141       release_application (ctrl->app_ctx);
142       ctrl->app_ctx = NULL;
143     }
144   if (ctrl->reader_slot != -1)
145     {
146       struct server_local_s *sl;
147
148       /* If we are the only session with the reader open we may close
149          it.  If not, do a reset unless the a lock is held on the
150          reader.  */
151       for (sl=session_list; sl; sl = sl->next_session)
152         if (sl != ctrl->server_local
153             && sl->ctrl_backlink->reader_slot == ctrl->reader_slot)
154           break;
155       if (sl) /* There is another session with the reader open. */
156         {
157           if ( IS_LOCKED (ctrl) ) /* If it is locked, release it. */
158             ctrl->reader_slot = -1;
159           else
160             {
161               if (do_close) /* Always mark reader unused. */
162                 ctrl->reader_slot = -1;
163               else if (apdu_reset (ctrl->reader_slot)) /* Reset only if
164                                                           not locked */
165                 {
166                   /* The reset failed.  Mark the reader as closed. */
167                   ctrl->reader_slot = -1;
168                 }
169
170               if (locked_session && ctrl->server_local == locked_session)
171                 {
172                   locked_session = NULL;
173                   log_debug ("implicitly unlocking due to RESET\n");
174                 }
175             }
176         }
177       else /* No other session has the reader open.  */
178         {
179           if (do_close || apdu_reset (ctrl->reader_slot))
180             {
181               apdu_close_reader (ctrl->reader_slot);
182               ctrl->reader_slot = -1;
183             }
184           if ( IS_LOCKED (ctrl) )
185             {
186               log_debug ("WARNING: cleaning up stale session lock\n");
187               locked_session =  NULL;
188             }
189         }
190     }
191
192   /* Reset card removed flag for the current reader.  */
193   update_card_removed (slot, 0);
194 }
195
196 \f
197 static void
198 reset_notify (assuan_context_t ctx)
199 {
200   ctrl_t ctrl = assuan_get_pointer (ctx); 
201
202   do_reset (ctrl, 0);
203 }
204
205
206 static int
207 option_handler (assuan_context_t ctx, const char *key, const char *value)
208 {
209   ctrl_t ctrl = assuan_get_pointer (ctx);
210
211   if (!strcmp (key, "event-signal"))
212     {
213       /* A value of 0 is allowed to reset the event signal. */
214       int i = *value? atoi (value) : -1;
215       if (i < 0)
216         return ASSUAN_Parameter_Error;
217       ctrl->server_local->event_signal = i;
218     }
219
220  return 0;
221 }
222
223
224 /* Return the slot of the current reader or open the reader if no
225    other sessions are using a reader.  Note, that we currently support
226    only one reader but most of the code (except for this function)
227    should be able to cope with several readers.  */
228 static int
229 get_reader_slot (void)
230 {
231   struct server_local_s *sl;
232   int slot= -1;
233
234   for (sl=session_list; sl; sl = sl->next_session)
235     if (sl->ctrl_backlink
236         && (slot = sl->ctrl_backlink->reader_slot) != -1)
237       break;
238
239   if (slot == -1)
240     slot = apdu_open_reader (opt.reader_port);
241
242   return slot;
243 }
244
245 /* If the card has not yet been opened, do it.  Note that this
246    function returns an Assuan error, so don't map the error a second
247    time */
248 static assuan_error_t
249 open_card (ctrl_t ctrl, const char *apptype)
250 {
251   gpg_error_t err;
252   int slot;
253
254   /* If we ever got a card not present error code, return that.  Only
255      the SERIALNO command and a reset are able to clear from that
256      state. */
257   if (ctrl->server_local->card_removed)
258     return map_to_assuan_status (gpg_error (GPG_ERR_CARD_REMOVED));
259
260   if (ctrl->app_ctx)
261     return 0; /* Already initialized for one specific application. */
262   if (ctrl->card_ctx)
263     return 0; /* Already initialized using a card context. */
264
265   if ( IS_LOCKED (ctrl) )
266     return gpg_error (GPG_ERR_EBUSY);
267
268   if (ctrl->reader_slot != -1)
269     slot = ctrl->reader_slot;
270   else
271     slot = get_reader_slot ();
272   ctrl->reader_slot = slot;
273   if (slot == -1)
274     err = gpg_error (GPG_ERR_CARD);
275   else
276     err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
277   if (!ctrl->app_ctx
278       && gpg_err_code (err) != GPG_ERR_CARD_NOT_PRESENT)
279     { 
280       /* No application found - fall back to old mode. */
281       /* Note that we should rework the old code to use the
282          application paradigma too. */
283       /* If an APPTYPE was requested and it is not pkcs#15, we return
284          an error here. */
285       if (apptype && !(!strcmp (apptype, "P15") || !strcmp (apptype, "p15")))
286         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
287       else 
288         err = card_open (&ctrl->card_ctx);
289     }
290
291   TEST_CARD_REMOVAL (ctrl, err);
292   return map_to_assuan_status (err);
293 }
294
295
296 /* Do the percent and plus/space unescaping in place and return the
297    length of the valid buffer. */
298 static size_t
299 percent_plus_unescape (unsigned char *string)
300 {
301   unsigned char *p = string;
302   size_t n = 0;
303
304   while (*string)
305     {
306       if (*string == '%' && string[1] && string[2])
307         { 
308           string++;
309           *p++ = xtoi_2 (string);
310           n++;
311           string+= 2;
312         }
313       else if (*string == '+')
314         {
315           *p++ = ' ';
316           n++;
317           string++;
318         }
319       else
320         {
321           *p++ = *string++;
322           n++;
323         }
324     }
325
326   return n;
327 }
328
329
330
331 /* SERIALNO [APPTYPE] 
332
333    Return the serial number of the card using a status reponse.  This
334    functon should be used to check for the presence of a card.
335
336    If APPTYPE is given, an application of that type is selected and an
337    error is returned if the application is not supported or available.
338    The default is to auto-select the application using a hardwired
339    preference system.  Note, that a future extension to this function
340    may allow to specify a list and order of applications to try.
341
342    This function is special in that it can be used to reset the card.
343    Most other functions will return an error when a card change has
344    been detected and the use of this function is therefore required.
345
346    Background: We want to keep the client clear of handling card
347    changes between operations; i.e. the client can assume that all
348    operations are done on the same card unless he calls this function.
349  */
350 static int
351 cmd_serialno (assuan_context_t ctx, char *line)
352 {
353   ctrl_t ctrl = assuan_get_pointer (ctx);
354   int rc = 0;
355   char *serial_and_stamp;
356   char *serial;
357   time_t stamp;
358
359   /* Clear the remove flag so that the open_card is able to reread it.  */
360   if (ctrl->server_local->card_removed)
361     {
362       if ( IS_LOCKED (ctrl) )
363         return gpg_error (GPG_ERR_EBUSY);
364       do_reset (ctrl, 0);
365     }
366
367   if ((rc = open_card (ctrl, *line? line:NULL)))
368     return rc;
369
370   if (ctrl->app_ctx)
371     rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
372   else
373     rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
374   if (rc)
375     return map_to_assuan_status (rc);
376   rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
377   xfree (serial);
378   if (rc < 0)
379     return ASSUAN_Out_Of_Core;
380   rc = 0;
381   assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
382   free (serial_and_stamp);
383   return 0;
384 }
385
386
387
388
389 /* LEARN [--force]
390
391    Learn all useful information of the currently inserted card.  When
392    used without the force options, the command might do an INQUIRE
393    like this:
394
395       INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
396
397    The client should just send an "END" if the processing should go on
398    or a "CANCEL" to force the function to terminate with a Cancel
399    error message.  The response of this command is a list of status
400    lines formatted as this:
401
402      S APPTYPE <apptype>
403
404    This returns the type of the application, currently the strings:
405
406        P15     = PKCS-15 structure used
407        DINSIG  = DIN SIG
408        OPENPGP = OpenPGP card
409  
410    are implemented.  These strings are aliases for the AID
411
412      S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
413
414    If there is no certificate yet stored on the card a single "X" is
415    returned as the keygrip.  In addition to the keypair info, information
416    about all certificates stored on the card is also returned:
417
418      S CERTINFO <certtype> <hexstring_with_id>
419
420    Where CERTTYPE is a number indicating the type of certificate:
421       0   := Unknown
422       100 := Regular X.509 cert
423       101 := Trusted X.509 cert
424       102 := Useful X.509 cert
425       110 := Root CA cert (DINSIG)
426
427    For certain cards, more information will be returned:
428
429      S KEY-FPR <no> <hexstring>
430
431    For OpenPGP cards this returns the stored fingerprints of the
432    keys. This can be used check whether a key is available on the
433    card.  NO may be 1, 2 or 3.
434
435      S CA-FPR <no> <hexstring>
436
437    Similar to above, these are the fingerprints of keys assumed to be
438    ultimately trusted.
439
440      S DISP-NAME <name_of_card_holder>
441
442    The name of the card holder as stored on the card; percent
443    escaping takes place, spaces are encoded as '+'
444
445      S PUBKEY-URL <url>
446
447    The URL to be used for locating the entire public key.
448      
449    Note, that this function may be even be used on a locked card.
450 */
451 static int
452 cmd_learn (assuan_context_t ctx, char *line)
453 {
454   ctrl_t ctrl = assuan_get_pointer (ctx);
455   int rc = 0;
456   int idx;
457
458   if ((rc = open_card (ctrl, NULL)))
459     return rc;
460
461   /* Unless the force option is used we try a shortcut by identifying
462      the card using a serial number and inquiring the client with
463      that. The client may choose to cancel the operation if he already
464      knows about this card */
465   {
466     char *serial_and_stamp;
467     char *serial;
468     time_t stamp;
469
470     if (ctrl->app_ctx)
471       rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
472     else
473       rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp);
474     if (rc)
475       return map_to_assuan_status (rc);
476     rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp);
477     xfree (serial);
478     if (rc < 0)
479       return ASSUAN_Out_Of_Core;
480     rc = 0;
481     assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
482
483     if (!has_option (line, "--force"))
484       {
485         char *command;
486
487         rc = asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
488         if (rc < 0)
489           {
490             free (serial_and_stamp);
491             return ASSUAN_Out_Of_Core;
492           }
493         rc = 0;
494         rc = assuan_inquire (ctx, command, NULL, NULL, 0); 
495         free (command);  /* (must use standard free here) */
496         if (rc)
497           {
498             if (rc != ASSUAN_Canceled)
499               log_error ("inquire KNOWNCARDP failed: %s\n",
500                          assuan_strerror (rc));
501             free (serial_and_stamp);
502             return rc; 
503           }
504         /* not canceled, so we have to proceeed */
505       }
506     free (serial_and_stamp);
507   }
508
509   /* If we are using the modern application paradigma, let the
510      application print out its collection of useful status
511      information. */
512   if (!rc && ctrl->app_ctx)
513     rc = app_write_learn_status (ctrl->app_ctx, ctrl);
514
515   /* Return information about the certificates.  FIXME: Move this into
516      an app-p15.c*/
517   for (idx=0; !rc && !ctrl->app_ctx; idx++)
518     {
519       char *certid;
520       int certtype;
521
522       rc = card_enum_certs (ctrl->card_ctx, idx, &certid, &certtype);
523       if (!rc)
524         {
525           char *buf;
526
527           buf = xtrymalloc (40 + 1 + strlen (certid) + 1);
528           if (!buf)
529             rc = gpg_error (gpg_err_code_from_errno (errno));
530           else
531             {
532               sprintf (buf, "%d %s", certtype, certid);
533               assuan_write_status (ctx, "CERTINFO", buf);
534               xfree (buf);
535             }
536         }
537       xfree (certid);
538     }
539   if (rc == -1)
540     rc = 0;
541
542   /* Return information about the keys. FIXME: Move this into an
543      app-p15.c */
544   for (idx=0; !rc && !ctrl->app_ctx; idx++)
545     {
546       unsigned char keygrip[20];
547       char *keyid;
548       int no_cert = 0;
549
550       rc = card_enum_keypairs (ctrl->card_ctx, idx, keygrip, &keyid);
551       if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT && keyid)
552         {
553           /* This does happen with an incomplete personalized
554              card; i.e. during the time we have stored the key on the
555              card but not stored the certificate; probably becuase it
556              has not yet been received back from the CA.  Note that we
557              must release KEYID in this case. */
558           rc = 0; 
559           no_cert = 1;
560         }
561       if (!rc)
562         {
563           char *buf, *p;
564
565           buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1);
566           if (!buf)
567             rc = gpg_error (gpg_err_code_from_errno (errno));
568           else
569             {
570               int i;
571               
572               if (no_cert)
573                 *p++ = 'X';
574               else
575                 {
576                   for (i=0; i < 20; i++, p += 2)
577                     sprintf (p, "%02X", keygrip[i]);
578                 }
579               *p++ = ' ';
580               strcpy (p, keyid);
581               assuan_write_status (ctx, "KEYPAIRINFO", buf);
582               xfree (buf);
583             }
584         }
585       xfree (keyid);
586     }
587   if (rc == -1)
588     rc = 0;
589
590   TEST_CARD_REMOVAL (ctrl, rc);
591   return map_to_assuan_status (rc);
592 }
593
594
595 \f
596 /* READCERT <hexified_certid>
597
598    Note, that this function may be even be used on a locked card.
599  */
600 static int
601 cmd_readcert (assuan_context_t ctx, char *line)
602 {
603   ctrl_t ctrl = assuan_get_pointer (ctx);
604   int rc;
605   unsigned char *cert;
606   size_t ncert;
607
608   if ((rc = open_card (ctrl, NULL)))
609     return rc;
610
611   line = xstrdup (line); /* Need a copy of the line. */
612   if (ctrl->app_ctx)
613     {
614       rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
615       if (rc)
616         log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
617     }
618   else
619     {
620       rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
621       if (rc)
622         log_error ("card_read_cert failed: %s\n", gpg_strerror (rc));
623     }
624   xfree (line);
625   line = NULL;
626   if (!rc)
627     {
628       rc = assuan_send_data (ctx, cert, ncert);
629       xfree (cert);
630       if (rc)
631         return rc;
632     }
633
634   TEST_CARD_REMOVAL (ctrl, rc);
635   return map_to_assuan_status (rc);
636 }
637
638
639 /* READKEY <hexified_certid>
640
641    Return the public key for the given cert or key ID as an standard
642    S-Expression.
643
644    Note, that this function may be even be used on a locked card.
645   */
646 static int
647 cmd_readkey (assuan_context_t ctx, char *line)
648 {
649   ctrl_t ctrl = assuan_get_pointer (ctx);
650   int rc;
651   unsigned char *cert = NULL;
652   size_t ncert, n;
653   ksba_cert_t kc = NULL;
654   ksba_sexp_t p;
655
656   if ((rc = open_card (ctrl, NULL)))
657     return rc;
658
659   line = xstrdup (line); /* Need a copy of the line. */
660   if (ctrl->app_ctx)
661     {
662       unsigned char *pk;
663       size_t pklen;
664
665       /* If the application supports the READKEY function we use that.
666          Otherwise we use the old way by extracting it from the
667          certificate.  */
668       rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
669       if (!rc)
670         { /* Yeah, got that key - send it back.  */
671           rc = assuan_send_data (ctx, pk, pklen);
672           xfree (pk);
673           rc = map_assuan_err (rc);
674           xfree (line);
675           line = NULL;
676           goto leave;
677         }
678
679       if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
680         log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
681       else  
682         {
683           rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
684           if (rc)
685             log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
686         }
687     }
688   else
689     {
690       rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert);
691       if (rc)
692         log_error ("card_read_cert failed: %s\n", gpg_strerror (rc));
693     }
694   xfree (line);
695   line = NULL;
696   if (rc)
697     goto leave;
698       
699   rc = ksba_cert_new (&kc);
700   if (rc)
701     {
702       xfree (cert);
703       goto leave;
704     }
705   rc = ksba_cert_init_from_mem (kc, cert, ncert);
706   if (rc)
707     {
708       log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
709       goto leave;
710     }
711
712   p = ksba_cert_get_public_key (kc);
713   if (!p)
714     {
715       rc = gpg_error (GPG_ERR_NO_PUBKEY);
716       goto leave;
717     }
718
719   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
720   rc = assuan_send_data (ctx, p, n);
721   rc = map_assuan_err (rc);
722   xfree (p);
723
724
725  leave:
726   ksba_cert_release (kc);
727   xfree (cert);
728   TEST_CARD_REMOVAL (ctrl, rc);
729   return map_to_assuan_status (rc);
730 }
731
732
733 \f
734
735 /* SETDATA <hexstring> 
736
737    The client should use this command to tell us the data he want to
738    sign.  */
739 static int
740 cmd_setdata (assuan_context_t ctx, char *line)
741 {
742   ctrl_t ctrl = assuan_get_pointer (ctx);
743   int n;
744   char *p;
745   unsigned char *buf;
746
747   if (locked_session && locked_session != ctrl->server_local)
748     return gpg_error (GPG_ERR_EBUSY);
749
750   /* Parse the hexstring. */
751   for (p=line,n=0; hexdigitp (p); p++, n++)
752     ;
753   if (*p)
754     return set_error (Parameter_Error, "invalid hexstring");
755   if (!n)
756     return set_error (Parameter_Error, "no data given");
757   if ((n&1))
758     return set_error (Parameter_Error, "odd number of digits");
759   n /= 2;
760   buf = xtrymalloc (n);
761   if (!buf)
762     return ASSUAN_Out_Of_Core;
763
764   ctrl->in_data.value = buf;
765   ctrl->in_data.valuelen = n;
766   for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++)
767     buf[n] = xtoi_2 (p);
768   return 0;
769 }
770
771
772
773 static int 
774 pin_cb (void *opaque, const char *info, char **retstr)
775 {
776   assuan_context_t ctx = opaque;
777   char *command;
778   int rc;
779   unsigned char *value;
780   size_t valuelen;
781
782   *retstr = NULL;
783   log_debug ("asking for PIN '%s'\n", info);
784
785   rc = asprintf (&command, "NEEDPIN %s", info);
786   if (rc < 0)
787     return gpg_error (gpg_err_code_from_errno (errno));
788
789   /* FIXME: Write an inquire function which returns the result in
790      secure memory */
791   rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); 
792   free (command);  
793   if (rc)
794     return map_assuan_err (rc);
795
796   if (!valuelen || value[valuelen-1])
797     {
798       /* We require that the returned value is an UTF-8 string */
799       xfree (value);
800       return gpg_error (GPG_ERR_INV_RESPONSE);
801     }
802   *retstr = value;
803   return 0;
804 }
805
806
807 /* PKSIGN <hexified_id>
808
809  */
810 static int
811 cmd_pksign (assuan_context_t ctx, char *line)
812 {
813   ctrl_t ctrl = assuan_get_pointer (ctx);
814   int rc;
815   unsigned char *outdata;
816   size_t outdatalen;
817   char *keyidstr;
818
819   if ( IS_LOCKED (ctrl) )
820     return gpg_error (GPG_ERR_EBUSY);
821
822   if ((rc = open_card (ctrl, NULL)))
823     return rc;
824
825   /* We have to use a copy of the key ID because the function may use
826      the pin_cb which in turn uses the assuan line buffer and thus
827      overwriting the original line with the keyid */
828   keyidstr = xtrystrdup (line);
829   if (!keyidstr)
830     return ASSUAN_Out_Of_Core;
831   
832   if (ctrl->app_ctx)
833     rc = app_sign (ctrl->app_ctx,
834                     keyidstr, GCRY_MD_SHA1,
835                     pin_cb, ctx,
836                     ctrl->in_data.value, ctrl->in_data.valuelen,
837                     &outdata, &outdatalen);
838   else  
839     rc = card_sign (ctrl->card_ctx,
840                     keyidstr, GCRY_MD_SHA1,
841                     pin_cb, ctx,
842                     ctrl->in_data.value, ctrl->in_data.valuelen,
843                     &outdata, &outdatalen);
844   xfree (keyidstr);
845   if (rc)
846     {
847       log_error ("card_sign failed: %s\n", gpg_strerror (rc));
848     }
849   else
850     {
851       rc = assuan_send_data (ctx, outdata, outdatalen);
852       xfree (outdata);
853       if (rc)
854         return rc; /* that is already an assuan error code */
855     }
856
857   TEST_CARD_REMOVAL (ctrl, rc);
858   return map_to_assuan_status (rc);
859 }
860
861 /* PKAUTH <hexified_id>
862
863  */
864 static int
865 cmd_pkauth (assuan_context_t ctx, char *line)
866 {
867   ctrl_t ctrl = assuan_get_pointer (ctx);
868   int rc;
869   unsigned char *outdata;
870   size_t outdatalen;
871   char *keyidstr;
872
873   if ( IS_LOCKED (ctrl) )
874     return gpg_error (GPG_ERR_EBUSY);
875
876   if ((rc = open_card (ctrl, NULL)))
877     return rc;
878
879   if (!ctrl->app_ctx)
880     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
881
882   /* We have to use a copy of the key ID because the function may use
883      the pin_cb which in turn uses the assuan line buffer and thus
884      overwriting the original line with the keyid */
885   keyidstr = xtrystrdup (line);
886   if (!keyidstr)
887     return ASSUAN_Out_Of_Core;
888   
889   rc = app_auth (ctrl->app_ctx,
890                  keyidstr,
891                  pin_cb, ctx,
892                  ctrl->in_data.value, ctrl->in_data.valuelen,
893                  &outdata, &outdatalen);
894   xfree (keyidstr);
895   if (rc)
896     {
897       log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc));
898     }
899   else
900     {
901       rc = assuan_send_data (ctx, outdata, outdatalen);
902       xfree (outdata);
903       if (rc)
904         return rc; /* that is already an assuan error code */
905     }
906
907   TEST_CARD_REMOVAL (ctrl, rc);
908   return map_to_assuan_status (rc);
909 }
910
911 /* PKDECRYPT <hexified_id>
912
913  */
914 static int
915 cmd_pkdecrypt (assuan_context_t ctx, char *line)
916 {
917   ctrl_t ctrl = assuan_get_pointer (ctx);
918   int rc;
919   unsigned char *outdata;
920   size_t outdatalen;
921   char *keyidstr;
922
923   if ( IS_LOCKED (ctrl) )
924     return gpg_error (GPG_ERR_EBUSY);
925
926   if ((rc = open_card (ctrl, NULL)))
927     return rc;
928
929   keyidstr = xtrystrdup (line);
930   if (!keyidstr)
931     return ASSUAN_Out_Of_Core;
932   if (ctrl->app_ctx)
933     rc = app_decipher (ctrl->app_ctx,
934                         keyidstr, 
935                         pin_cb, ctx,
936                         ctrl->in_data.value, ctrl->in_data.valuelen,
937                         &outdata, &outdatalen);
938   else
939     rc = card_decipher (ctrl->card_ctx,
940                         keyidstr, 
941                         pin_cb, ctx,
942                         ctrl->in_data.value, ctrl->in_data.valuelen,
943                         &outdata, &outdatalen);
944   xfree (keyidstr);
945   if (rc)
946     {
947       log_error ("card_create_signature failed: %s\n", gpg_strerror (rc));
948     }
949   else
950     {
951       rc = assuan_send_data (ctx, outdata, outdatalen);
952       xfree (outdata);
953       if (rc)
954         return rc; /* that is already an assuan error code */
955     }
956
957   TEST_CARD_REMOVAL (ctrl, rc);
958   return map_to_assuan_status (rc);
959 }
960
961
962 /* GETATTR <name>
963
964    This command is used to retrieve data from a smartcard.  The
965    allowed names depend on the currently selected smartcard
966    application.  NAME must be percent and '+' escaped.  The value is
967    returned through status message, see the LEARN command for details.
968
969    However, the current implementation assumes that Name is not escaped;
970    this works as long as noone uses arbitrary escaping. 
971  
972    Note, that this function may even be used on a locked card.
973 */
974 static int
975 cmd_getattr (assuan_context_t ctx, char *line)
976 {
977   ctrl_t ctrl = assuan_get_pointer (ctx);
978   int rc;
979   char *keyword;
980
981   if ((rc = open_card (ctrl, NULL)))
982     return rc;
983
984   keyword = line;
985   for (; *line && !spacep (line); line++)
986     ;
987   if (*line)
988       *line++ = 0;
989
990   /* (We ignore any garbage for now.) */
991
992   /* FIXME: Applications should not return sensistive data if the card
993      is locked.  */
994   rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
995
996   TEST_CARD_REMOVAL (ctrl, rc);
997   return map_to_assuan_status (rc);
998 }
999
1000
1001 /* SETATTR <name> <value> 
1002
1003    This command is used to store data on a a smartcard.  The allowed
1004    names and values are depend on the currently selected smartcard
1005    application.  NAME and VALUE must be percent and '+' escaped.
1006
1007    However, the curent implementation assumes that Name is not escaped;
1008    this works as long as noone uses arbitrary escaping. 
1009  
1010    A PIN will be requested for most NAMEs.  See the corresponding
1011    setattr function of the actually used application (app-*.c) for
1012    details.  */
1013 static int
1014 cmd_setattr (assuan_context_t ctx, char *orig_line)
1015 {
1016   ctrl_t ctrl = assuan_get_pointer (ctx);
1017   int rc;
1018   char *keyword;
1019   int keywordlen;
1020   size_t nbytes;
1021   char *line, *linebuf;
1022
1023   if ( IS_LOCKED (ctrl) )
1024     return gpg_error (GPG_ERR_EBUSY);
1025
1026   if ((rc = open_card (ctrl, NULL)))
1027     return rc;
1028
1029   /* We need to use a copy of LINE, because PIN_CB uses the same
1030      context and thus reuses the Assuan provided LINE. */
1031   line = linebuf = xtrystrdup (orig_line);
1032   if (!line)
1033     return ASSUAN_Out_Of_Core;
1034
1035   keyword = line;
1036   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1037     ;
1038   if (*line)
1039       *line++ = 0;
1040   while (spacep (line))
1041     line++;
1042   nbytes = percent_plus_unescape (line);
1043
1044   rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes);
1045   xfree (linebuf);
1046
1047   TEST_CARD_REMOVAL (ctrl, rc);
1048   return map_to_assuan_status (rc);
1049 }
1050
1051 /* GENKEY [--force] <no>
1052
1053    Generate a key on-card identified by NO, which is application
1054    specific.  Return values are application specific.  For OpenPGP
1055    cards 2 status lines are returned:
1056
1057      S KEY-FPR  <hexstring>
1058      S KEY-CREATED-AT <seconds_since_epoch>
1059      S KEY-DATA [p|n] <hexdata>
1060      
1061
1062    --force is required to overwriet an already existing key.  The
1063    KEY-CREATED-AT is required for further processing because it is
1064    part of the hashed key material for the fingerprint.
1065
1066    The public part of the key can also later be retrieved using the
1067    READKEY command.
1068
1069  */
1070 static int
1071 cmd_genkey (assuan_context_t ctx, char *line)
1072 {
1073   ctrl_t ctrl = assuan_get_pointer (ctx);
1074   int rc;
1075   char *keyno;
1076   int force = has_option (line, "--force");
1077
1078   if ( IS_LOCKED (ctrl) )
1079     return gpg_error (GPG_ERR_EBUSY);
1080
1081   /* Skip over options. */
1082   while ( *line == '-' && line[1] == '-' )
1083     {
1084       while (*line && !spacep (line))
1085         line++;
1086       while (spacep (line))
1087         line++;
1088     }
1089   if (!*line)
1090     return set_error (Parameter_Error, "no key number given");
1091   keyno = line;
1092   while (*line && !spacep (line))
1093     line++;
1094   *line = 0;
1095
1096   if ((rc = open_card (ctrl, NULL)))
1097     return rc;
1098
1099   if (!ctrl->app_ctx)
1100     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1101
1102   keyno = xtrystrdup (keyno);
1103   if (!keyno)
1104     return ASSUAN_Out_Of_Core;
1105   rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
1106   xfree (keyno);
1107
1108   TEST_CARD_REMOVAL (ctrl, rc);
1109   return map_to_assuan_status (rc);
1110 }
1111
1112
1113 /* RANDOM <nbytes>
1114
1115    Get NBYTES of random from the card and send them back as data. 
1116
1117    Note, that this function may be even be used on a locked card.
1118 */
1119 static int
1120 cmd_random (assuan_context_t ctx, char *line)
1121 {
1122   ctrl_t ctrl = assuan_get_pointer (ctx);
1123   int rc;
1124   size_t nbytes;
1125   unsigned char *buffer;
1126
1127   if (!*line)
1128     return set_error (Parameter_Error, "number of requested bytes missing");
1129   nbytes = strtoul (line, NULL, 0);
1130
1131   if ((rc = open_card (ctrl, NULL)))
1132     return rc;
1133
1134   if (!ctrl->app_ctx)
1135     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1136
1137   buffer = xtrymalloc (nbytes);
1138   if (!buffer)
1139     return ASSUAN_Out_Of_Core;
1140
1141   rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1142   if (!rc)
1143     {
1144       rc = assuan_send_data (ctx, buffer, nbytes);
1145       xfree (buffer);
1146       return rc; /* that is already an assuan error code */
1147     }
1148   xfree (buffer);
1149
1150   TEST_CARD_REMOVAL (ctrl, rc);
1151   return map_to_assuan_status (rc);
1152 }
1153
1154 \f
1155 /* PASSWD [--reset] <chvno>
1156   
1157    Change the PIN or reset thye retry counter of the card holder
1158    verfication vector CHVNO. */
1159 static int
1160 cmd_passwd (assuan_context_t ctx, char *line)
1161 {
1162   ctrl_t ctrl = assuan_get_pointer (ctx);
1163   int rc;
1164   char *chvnostr;
1165   int reset_mode = has_option (line, "--reset");
1166
1167   if ( IS_LOCKED (ctrl) )
1168     return gpg_error (GPG_ERR_EBUSY);
1169
1170   /* Skip over options. */
1171   while (*line == '-' && line[1] == '-')
1172     {
1173       while (*line && !spacep (line))
1174         line++;
1175       while (spacep (line))
1176         line++;
1177     }
1178   if (!*line)
1179     return set_error (Parameter_Error, "no CHV number given");
1180   chvnostr = line;
1181   while (*line && !spacep (line))
1182     line++;
1183   *line = 0;
1184
1185   if ((rc = open_card (ctrl, NULL)))
1186     return rc;
1187
1188   if (!ctrl->app_ctx)
1189     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1190   
1191   chvnostr = xtrystrdup (chvnostr);
1192   if (!chvnostr)
1193     return ASSUAN_Out_Of_Core;
1194   rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx);
1195   if (rc)
1196     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1197   xfree (chvnostr);
1198
1199   TEST_CARD_REMOVAL (ctrl, rc);
1200   return map_to_assuan_status (rc);
1201 }
1202
1203
1204 /* CHECKPIN <hexified_id>
1205
1206  */
1207 static int
1208 cmd_checkpin (assuan_context_t ctx, char *line)
1209 {
1210   ctrl_t ctrl = assuan_get_pointer (ctx);
1211   int rc;
1212   char *keyidstr;
1213
1214   if ( IS_LOCKED (ctrl) )
1215     return gpg_error (GPG_ERR_EBUSY);
1216
1217   if ((rc = open_card (ctrl, NULL)))
1218     return rc;
1219
1220   if (!ctrl->app_ctx)
1221     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1222
1223   /* We have to use a copy of the key ID because the function may use
1224      the pin_cb which in turn uses the assuan line buffer and thus
1225      overwriting the original line with the keyid. */
1226   keyidstr = xtrystrdup (line);
1227   if (!keyidstr)
1228     return ASSUAN_Out_Of_Core;
1229   
1230   rc = app_check_pin (ctrl->app_ctx,
1231                       keyidstr,
1232                       pin_cb, ctx);
1233   xfree (keyidstr);
1234   if (rc)
1235     log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1236
1237   TEST_CARD_REMOVAL (ctrl, rc);
1238   return map_to_assuan_status (rc);
1239 }
1240
1241
1242 /* LOCK [--wait]
1243
1244    Grant exclusive card access to this session.  Note that there is
1245    no lock counter used and a second lock from the same session will
1246    get ignore.  A single unlock (or RESET) unlocks the session.
1247    Return GPG_ERR_EBUSY if another session has locked the reader.
1248
1249    If the option --wait is given the command will wait until a
1250    lock has been released.
1251  */
1252 static int
1253 cmd_lock (assuan_context_t ctx, char *line)
1254 {
1255   ctrl_t ctrl = assuan_get_pointer (ctx);
1256   int rc = 0;
1257
1258  retry:
1259   if (locked_session)
1260     {
1261       if (locked_session != ctrl->server_local)
1262         rc = gpg_error (GPG_ERR_EBUSY);
1263     }
1264   else
1265     locked_session = ctrl->server_local;
1266
1267 #ifdef USE_GNU_PTH
1268   if (rc && has_option (line, "--wait"))
1269     {
1270       pth_sleep (1); /* Better implement an event mechanism. However,
1271                         for card operations this should be
1272                         sufficient. */
1273       goto retry;
1274     }
1275 #endif /*USE_GNU_PTH*/
1276   
1277   if (rc)
1278     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1279   return map_to_assuan_status (rc);
1280 }
1281
1282
1283 /* UNLOCK
1284
1285    Release exclusive card access.
1286  */
1287 static int
1288 cmd_unlock (assuan_context_t ctx, char *line)
1289 {
1290   ctrl_t ctrl = assuan_get_pointer (ctx);
1291   int rc = 0;
1292
1293   if (locked_session)
1294     {
1295       if (locked_session != ctrl->server_local)
1296         rc = gpg_error (GPG_ERR_EBUSY);
1297       else
1298         locked_session = NULL;
1299     }
1300   else
1301     rc = gpg_error (GPG_ERR_NOT_LOCKED);
1302
1303   if (rc)
1304     log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1305   return map_to_assuan_status (rc);
1306 }
1307
1308
1309
1310
1311 \f
1312 /* Tell the assuan library about our commands */
1313 static int
1314 register_commands (assuan_context_t ctx)
1315 {
1316   static struct {
1317     const char *name;
1318     int (*handler)(assuan_context_t, char *line);
1319   } table[] = {
1320     { "SERIALNO",     cmd_serialno },
1321     { "LEARN",        cmd_learn },
1322     { "READCERT",     cmd_readcert },
1323     { "READKEY",      cmd_readkey },
1324     { "SETDATA",      cmd_setdata },
1325     { "PKSIGN",       cmd_pksign },
1326     { "PKAUTH",       cmd_pkauth },
1327     { "PKDECRYPT",    cmd_pkdecrypt },
1328     { "INPUT",        NULL }, 
1329     { "OUTPUT",       NULL }, 
1330     { "GETATTR",      cmd_getattr },
1331     { "SETATTR",      cmd_setattr },
1332     { "GENKEY",       cmd_genkey },
1333     { "RANDOM",       cmd_random },
1334     { "PASSWD",       cmd_passwd },
1335     { "CHECKPIN",     cmd_checkpin },
1336     { "LOCK",         cmd_lock },
1337     { "UNLOCK",       cmd_unlock },
1338     { NULL }
1339   };
1340   int i, rc;
1341
1342   for (i=0; table[i].name; i++)
1343     {
1344       rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1345       if (rc)
1346         return rc;
1347     } 
1348   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1349
1350   assuan_register_reset_notify (ctx, reset_notify);
1351   assuan_register_option_handler (ctx, option_handler);
1352   return 0;
1353 }
1354
1355
1356 /* Startup the server.  If LISTEN_FD is given as -1, this is simple
1357    piper server, otherwise it is a regular server */
1358 void
1359 scd_command_handler (int listen_fd)
1360 {
1361   int rc;
1362   assuan_context_t ctx;
1363   struct server_control_s ctrl;
1364
1365   memset (&ctrl, 0, sizeof ctrl);
1366   scd_init_default_ctrl (&ctrl);
1367   
1368   if (listen_fd == -1)
1369     {
1370       int filedes[2];
1371
1372       filedes[0] = 0;
1373       filedes[1] = 1;
1374       rc = assuan_init_pipe_server (&ctx, filedes);
1375     }
1376   else
1377     {
1378       rc = assuan_init_socket_server (&ctx, listen_fd);
1379     }
1380   if (rc)
1381     {
1382       log_error ("failed to initialize the server: %s\n",
1383                  assuan_strerror(rc));
1384       scd_exit (2);
1385     }
1386   rc = register_commands (ctx);
1387   if (rc)
1388     {
1389       log_error ("failed to register commands with Assuan: %s\n",
1390                  assuan_strerror(rc));
1391       scd_exit (2);
1392     }
1393   assuan_set_pointer (ctx, &ctrl);
1394
1395   /* Allocate and initialize the server object.  Put it into the list
1396      of active sessions. */
1397   ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
1398   ctrl.server_local->next_session = session_list;
1399   session_list = ctrl.server_local;
1400   ctrl.server_local->ctrl_backlink = &ctrl;
1401   ctrl.server_local->assuan_ctx = ctx;
1402
1403   if (DBG_ASSUAN)
1404     assuan_set_log_stream (ctx, log_get_stream ());
1405
1406   /* We open the reader right at startup so that the ticker is able to
1407      update the status file. */
1408   if (ctrl.reader_slot == -1)
1409     {
1410       ctrl.reader_slot = get_reader_slot ();
1411     }
1412
1413   /* Command processing loop. */
1414   for (;;)
1415     {
1416       rc = assuan_accept (ctx);
1417       if (rc == -1)
1418         {
1419           break;
1420         }
1421       else if (rc)
1422         {
1423           log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
1424           break;
1425         }
1426       
1427       rc = assuan_process (ctx);
1428       if (rc)
1429         {
1430           log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
1431           continue;
1432         }
1433     }
1434
1435   /* Cleanup.  */
1436   do_reset (&ctrl, 1); 
1437
1438   /* Release the server object.  */
1439   if (session_list == ctrl.server_local)
1440     session_list = ctrl.server_local->next_session;
1441   else
1442     {
1443       struct server_local_s *sl;
1444       
1445       for (sl=session_list; sl->next_session; sl = sl->next_session)
1446         if (sl->next_session == ctrl.server_local)
1447           break;
1448       if (!sl->next_session)
1449           BUG ();
1450       sl->next_session = ctrl.server_local->next_session;
1451     }
1452   xfree (ctrl.server_local);
1453
1454   /* Release the Assuan context.  */
1455   assuan_deinit_server (ctx);
1456 }
1457
1458
1459 /* Send a line with status information via assuan and escape all given
1460    buffers. The variable elements are pairs of (char *, size_t),
1461    terminated with a (NULL, 0). */
1462 void
1463 send_status_info (ctrl_t ctrl, const char *keyword, ...)
1464 {
1465   va_list arg_ptr;
1466   const unsigned char *value;
1467   size_t valuelen;
1468   char buf[950], *p;
1469   size_t n;
1470   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
1471   
1472   va_start (arg_ptr, keyword);
1473
1474   p = buf; 
1475   n = 0;
1476   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
1477     {
1478       valuelen = va_arg (arg_ptr, size_t);
1479       if (!valuelen)
1480         continue; /* empty buffer */
1481       if (n)
1482         {
1483           *p++ = ' ';
1484           n++;
1485         }
1486       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
1487         {
1488           if (*value < ' ' || *value == '+')
1489             {
1490               sprintf (p, "%%%02X", *value);
1491               p += 3;
1492             }
1493           else if (*value == ' ')
1494             *p++ = '+';
1495           else
1496             *p++ = *value;
1497         }
1498     }
1499   *p = 0;
1500   assuan_write_status (ctx, keyword, buf);
1501
1502   va_end (arg_ptr);
1503 }
1504
1505
1506 /* This function is called by the ticker thread to check for changes
1507    of the reader stati.  It updates the reader status files and if
1508    requested by the caller also send a signal to the caller.  */
1509 void
1510 scd_update_reader_status_file (void)
1511 {
1512   static struct {
1513     int any;
1514     unsigned int status;
1515     unsigned int changed;
1516   } last[10];
1517   int slot;
1518   int used;
1519   unsigned int status, changed;
1520
1521   /* Note, that we only try to get the status, because it does not
1522      make sense to wait here for a operation to complete.  If we are
1523      busy working with a card, delays in the status file update should
1524      be acceptable. */
1525   for (slot=0; (slot < DIM(last)
1526                 &&!apdu_enum_reader (slot, &used)); slot++)
1527     if (used && !apdu_get_status (slot, 0, &status, &changed))
1528       {
1529         if (!last[slot].any || last[slot].status != status
1530             || last[slot].changed != changed )
1531           {
1532             char *fname;
1533             char templ[50];
1534             FILE *fp;
1535             struct server_local_s *sl;
1536
1537             log_info ("updating status of slot %d to 0x%04X\n", slot, status);
1538             
1539             sprintf (templ, "reader_%d.status", slot);
1540             fname = make_filename (opt.homedir, templ, NULL );
1541             fp = fopen (fname, "w");
1542             if (fp)
1543               {
1544                 fprintf (fp, "%s\n",
1545                          (status & 1)? "USABLE":
1546                          (status & 4)? "ACTIVE":
1547                          (status & 2)? "PRESENT": "NOCARD");
1548                 fclose (fp);
1549               }
1550             xfree (fname);
1551
1552             /* Set the card removed flag for all current sessions.  We
1553                will set this on any card change because a reset or
1554                SERIALNO request must be done in any case.  */
1555             if (last[slot].any)
1556               update_card_removed (slot, 1);
1557
1558             last[slot].any = 1;
1559             last[slot].status = status;
1560             last[slot].changed = changed;
1561
1562
1563             /* Send a signal to all clients who applied for it.  */
1564             for (sl=session_list; sl; sl = sl->next_session)
1565               if (sl->event_signal && sl->assuan_ctx)
1566                 {
1567                   pid_t pid = assuan_get_pid (sl->assuan_ctx);
1568                   int signo = sl->event_signal;
1569
1570                   log_info ("client pid is %d, sending signal %d\n",
1571                             pid, signo);
1572 #ifndef HAVE_W32_SYSTEM
1573                   if (pid != (pid_t)(-1) && pid && signo > 0)
1574                     kill (pid, signo);
1575 #endif
1576                 }
1577           }
1578       }
1579 }