71081b26f9e34780d7f834d5540b868b919105c1
[gnupg.git] / scd / command.c
1 /* command.c - SCdaemon command handler
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3  *               2007, 2008, 2009  Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #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 #include "exechelp.h"
40 #ifdef HAVE_LIBUSB
41 #include "ccid-driver.h"
42 #endif
43
44 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
45 #define MAXLEN_PIN 100
46
47 /* Maximum allowed size of key data as used in inquiries. */
48 #define MAXLEN_KEYDATA 4096
49
50 /* Maximum allowed size of certificate data as used in inquiries. */
51 #define MAXLEN_CERTDATA 16384
52
53
54 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
55
56
57 /* Macro to flag a removed card.  */
58 #define TEST_CARD_REMOVAL(c,r)                              \
59        do {                                                 \
60           int _r = (r);                                     \
61           if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
62               || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED) \
63             update_card_removed ((c)->reader_slot, 1);      \
64        } while (0)
65
66 #define IS_LOCKED(c)                                                     \
67      (locked_session && locked_session != (c)->server_local              \
68       && (c)->reader_slot != -1 && locked_session->ctrl_backlink         \
69       && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
70
71
72 /* This structure is used to keep track of open readers (slots). */
73 struct slot_status_s 
74 {
75   int valid;  /* True if the other objects are valid. */
76   int slot;   /* Slot number of the reader or -1 if not open. */
77
78   int reset_failed; /* A reset failed. */
79
80   int any;    /* Flag indicating whether any status check has been
81                  done.  This is set once to indicate that the status
82                  tracking for the slot has been initialized.  */
83   unsigned int status;  /* Last status of the slot. */
84   unsigned int changed; /* Last change counter of the slot. */
85 };
86
87
88 /* Data used to associate an Assuan context with local server data.
89    This object describes the local properties of one session.  */
90 struct server_local_s 
91 {
92   /* We keep a list of all active sessions with the anchor at
93      SESSION_LIST (see below).  This field is used for linking. */
94   struct server_local_s *next_session; 
95
96   /* This object is usually assigned to a CTRL object (which is
97      globally visible).  While enumerating all sessions we sometimes
98      need to access data of the CTRL object; thus we keep a
99      backpointer here. */
100   ctrl_t ctrl_backlink;
101
102   /* The Assuan context used by this session/server. */
103   assuan_context_t assuan_ctx;
104
105 #ifdef HAVE_W32_SYSTEM
106   unsigned long event_signal;   /* Or 0 if not used. */
107 #else
108   int event_signal;             /* Or 0 if not used. */
109 #endif
110   
111   /* True if the card has been removed and a reset is required to
112      continue operation. */
113   int card_removed;        
114
115   /* Flag indicating that the application context needs to be released
116      at the next opportunity.  */
117   int app_ctx_marked_for_release;
118
119   /* A disconnect command has been sent.  */
120   int disconnect_allowed;
121
122   /* If set to true we will be terminate ourself at the end of the
123      this session.  */
124   int stopme;  
125
126 };
127
128
129 /* The table with information on all used slots.  FIXME: This is a
130    different slot number than the one used by the APDU layer, and
131    should be renamed.  */
132 static struct slot_status_s slot_table[10];
133
134
135 /* To keep track of all running sessions, we link all active server
136    contexts and the anchor in this variable.  */
137 static struct server_local_s *session_list;
138
139 /* If a session has been locked we store a link to its server object
140    in this variable. */
141 static struct server_local_s *locked_session;
142
143 /* While doing a reset we need to make sure that the ticker does not
144    call scd_update_reader_status_file while we are using it. */
145 static pth_mutex_t status_file_update_lock;
146
147 \f
148 /*-- Local prototypes --*/
149 static void update_reader_status_file (int set_card_removed_flag);
150
151
152 \f
153
154 /* This function must be called once to initialize this module.  This
155    has to be done before a second thread is spawned.  We can't do the
156    static initialization because Pth emulation code might not be able
157    to do a static init; in particular, it is not possible for W32. */
158 void
159 initialize_module_command (void)
160 {
161   static int initialized;
162
163   if (!initialized)
164     {
165       if (pth_mutex_init (&status_file_update_lock))
166         initialized = 1;
167     }
168 }
169
170
171 /* Update the CARD_REMOVED element of all sessions using the reader
172    given by SLOT to VALUE.  */
173 static void
174 update_card_removed (int slot, int value)
175 {
176   struct server_local_s *sl;
177
178   for (sl=session_list; sl; sl = sl->next_session)
179     if (sl->ctrl_backlink
180         && sl->ctrl_backlink->reader_slot == slot)
181       {
182         sl->card_removed = value;
183       }
184   /* Let the card application layer know about the removal.  */
185   if (value)
186     application_notify_card_reset (slot);
187 }
188
189
190
191 /* Check whether the option NAME appears in LINE.  Returns 1 or 0. */
192 static int
193 has_option (const char *line, const char *name)
194 {
195   const char *s;
196   int n = strlen (name);
197
198   s = strstr (line, name);
199   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
200 }
201
202 /* Same as has_option but does only test for the name of the option
203    and ignores an argument, i.e. with NAME being "--hash" it would
204    return a pointer for "--hash" as well as for "--hash=foo".  If
205    thhere is no such option NULL is returned.  The pointer returned
206    points right behind the option name, this may be an equal sign, Nul
207    or a space.  */
208 static const char *
209 has_option_name (const char *line, const char *name)
210 {
211   const char *s;
212   int n = strlen (name);
213
214   s = strstr (line, name);
215   return (s && (s == line || spacep (s-1))
216           && (!s[n] || spacep (s+n) || s[n] == '=')) ? (s+n) : NULL;
217 }
218
219
220 /* Skip over options.  It is assumed that leading spaces have been
221    removed (this is the case for lines passed to a handler from
222    assuan).  Blanks after the options are also removed. */
223 static char *
224 skip_options (char *line)
225 {
226   while ( *line == '-' && line[1] == '-' )
227     {
228       while (*line && !spacep (line))
229         line++;
230       while (spacep (line))
231         line++;
232     }
233   return line;
234 }
235
236
237
238 /* Convert the STRING into a newly allocated buffer while translating
239    the hex numbers.  Stops at the first invalid character.  Blanks and
240    colons are allowed to separate the hex digits.  Returns NULL on
241    error or a newly malloced buffer and its length in LENGTH.  */
242 static unsigned char *
243 hex_to_buffer (const char *string, size_t *r_length)
244 {
245   unsigned char *buffer;
246   const char *s;
247   size_t n;
248
249   buffer = xtrymalloc (strlen (string)+1);
250   if (!buffer)
251     return NULL;
252   for (s=string, n=0; *s; s++)
253     {
254       if (spacep (s) || *s == ':') 
255         continue;
256       if (hexdigitp (s) && hexdigitp (s+1))
257         {
258           buffer[n++] = xtoi_2 (s);
259           s++;
260         }
261       else
262         break;
263     }
264   *r_length = n;
265   return buffer;
266 }
267
268
269
270 /* Reset the card and free the application context.  With SEND_RESET
271    set to true actually send a RESET to the reader; this is the normal
272    way of calling the function.  */
273 static void
274 do_reset (ctrl_t ctrl, int send_reset)
275 {
276   int slot = ctrl->reader_slot;
277
278   if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table))))
279     BUG ();
280
281   /* If there is an active application, release it.  Tell all other
282      sessions using the same application to release the
283      application.  */
284   if (ctrl->app_ctx)
285     {
286       release_application (ctrl->app_ctx);
287       ctrl->app_ctx = NULL;
288       if (send_reset)
289         {
290           struct server_local_s *sl;
291           
292           for (sl=session_list; sl; sl = sl->next_session)
293             if (sl->ctrl_backlink
294                 && sl->ctrl_backlink->reader_slot == slot)
295               {
296                 sl->app_ctx_marked_for_release = 1;
297               }
298         }
299     }
300
301   /* If we want a real reset for the card, send the reset APDU and
302      tell the application layer about it.  */
303   if (slot != -1 && send_reset && !IS_LOCKED (ctrl) )
304     {
305       if (apdu_reset (slot)) 
306         {
307           slot_table[slot].reset_failed = 1;
308         }
309       application_notify_card_reset (slot);
310     }
311
312   /* If we hold a lock, unlock now. */
313   if (locked_session && ctrl->server_local == locked_session)
314     {
315       locked_session = NULL;
316       log_info ("implicitly unlocking due to RESET\n");
317     }
318
319   /* Reset the card removed flag for the current reader.  We need to
320      take the lock here so that the ticker thread won't concurrently
321      try to update the file.  Calling update_reader_status_file is
322      required to get hold of the new status of the card in the slot
323      table.  */
324   if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL))
325     {
326       log_error ("failed to acquire status_fle_update lock\n");
327       ctrl->reader_slot = -1;
328       return;
329     }
330   update_reader_status_file (0);  /* Update slot status table.  */
331   update_card_removed (slot, 0);  /* Clear card_removed flag.  */
332   if (!pth_mutex_release (&status_file_update_lock))
333     log_error ("failed to release status_file_update lock\n");
334
335   /* Do this last, so that the update_card_removed above does its job.  */
336   ctrl->reader_slot = -1;
337 }
338
339 \f
340 static void
341 reset_notify (assuan_context_t ctx)
342 {
343   ctrl_t ctrl = assuan_get_pointer (ctx); 
344
345   do_reset (ctrl, 1);
346 }
347
348
349 static int
350 option_handler (assuan_context_t ctx, const char *key, const char *value)
351 {
352   ctrl_t ctrl = assuan_get_pointer (ctx);
353
354   if (!strcmp (key, "event-signal"))
355     {
356       /* A value of 0 is allowed to reset the event signal. */
357 #ifdef HAVE_W32_SYSTEM
358       if (!*value)
359         return gpg_error (GPG_ERR_ASS_PARAMETER);
360       ctrl->server_local->event_signal = strtoul (value, NULL, 16);
361 #else
362       int i = *value? atoi (value) : -1;
363       if (i < 0)
364         return gpg_error (GPG_ERR_ASS_PARAMETER);
365       ctrl->server_local->event_signal = i;
366 #endif
367     }
368
369  return 0;
370 }
371
372
373 /* Return the slot of the current reader or open the reader if no
374    other sessions are using a reader.  Note, that we currently support
375    only one reader but most of the code (except for this function)
376    should be able to cope with several readers.  */
377 static int
378 get_reader_slot (void)
379 {
380   struct slot_status_s *ss;
381
382   ss = &slot_table[0]; /* One reader for now. */
383
384   /* Initialize the item if needed. */
385   if (!ss->valid)
386     {
387       ss->slot = -1;
388       ss->valid = 1;
389     }
390
391   /* Try to open the reader. */
392   if (ss->slot == -1)
393     ss->slot = apdu_open_reader (opt.reader_port);
394
395   /* Return the slot_table index.  */
396   return 0;
397 }
398
399 /* If the card has not yet been opened, do it.  Note that this
400    function returns an Assuan error, so don't map the error a second
401    time.  */
402 static assuan_error_t
403 open_card (ctrl_t ctrl, const char *apptype)
404 {
405   gpg_error_t err;
406   int slot;
407
408   /* If we ever got a card not present error code, return that.  Only
409      the SERIALNO command and a reset are able to clear from that
410      state. */
411   if (ctrl->server_local->card_removed)
412     return gpg_error (GPG_ERR_CARD_REMOVED);
413
414   if ( IS_LOCKED (ctrl) )
415     return gpg_error (GPG_ERR_LOCKED);
416
417   /* If the application has been marked for release do it now.  We
418      can't do it immediately in do_reset because the application may
419      still be in use.  */
420   if (ctrl->server_local->app_ctx_marked_for_release)
421     {
422       ctrl->server_local->app_ctx_marked_for_release = 0;
423       release_application (ctrl->app_ctx);
424       ctrl->app_ctx = NULL;
425     }
426
427   /* If we are already initialized for one specific application we
428      need to check that the client didn't requested a specific
429      application different from the one in use before we continue. */
430   if (ctrl->app_ctx)
431     return check_application_conflict (ctrl, apptype);
432
433   /* Setup the slot and select the application.  */
434   if (ctrl->reader_slot != -1)
435     slot = ctrl->reader_slot;
436   else
437     slot = get_reader_slot ();
438   ctrl->reader_slot = slot;
439   if (slot == -1)
440     err = gpg_error (GPG_ERR_CARD);
441   else
442     {
443       /* Fixme: We should move the apdu_connect call to
444          select_application.  */
445       int sw;
446
447       ctrl->server_local->disconnect_allowed = 0;
448       sw = apdu_connect (slot);
449       if (sw && sw != SW_HOST_ALREADY_CONNECTED)
450         {
451           if (sw == SW_HOST_NO_CARD)
452             err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
453           else
454             err = gpg_error (GPG_ERR_CARD);
455         }
456       else
457         err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
458     }
459
460   TEST_CARD_REMOVAL (ctrl, err);
461   return err;
462 }
463
464
465 /* Do the percent and plus/space unescaping in place and return the
466    length of the valid buffer. */
467 static size_t
468 percent_plus_unescape (unsigned char *string)
469 {
470   unsigned char *p = string;
471   size_t n = 0;
472
473   while (*string)
474     {
475       if (*string == '%' && string[1] && string[2])
476         { 
477           string++;
478           *p++ = xtoi_2 (string);
479           n++;
480           string+= 2;
481         }
482       else if (*string == '+')
483         {
484           *p++ = ' ';
485           n++;
486           string++;
487         }
488       else
489         {
490           *p++ = *string++;
491           n++;
492         }
493     }
494
495   return n;
496 }
497
498
499
500 /* SERIALNO [APPTYPE] 
501
502    Return the serial number of the card using a status reponse.  This
503    function should be used to check for the presence of a card.
504
505    If APPTYPE is given, an application of that type is selected and an
506    error is returned if the application is not supported or available.
507    The default is to auto-select the application using a hardwired
508    preference system.  Note, that a future extension to this function
509    may allow to specify a list and order of applications to try.
510
511    This function is special in that it can be used to reset the card.
512    Most other functions will return an error when a card change has
513    been detected and the use of this function is therefore required.
514
515    Background: We want to keep the client clear of handling card
516    changes between operations; i.e. the client can assume that all
517    operations are done on the same card unless he calls this function.
518  */
519 static int
520 cmd_serialno (assuan_context_t ctx, char *line)
521 {
522   ctrl_t ctrl = assuan_get_pointer (ctx);
523   int rc = 0;
524   char *serial_and_stamp;
525   char *serial;
526   time_t stamp;
527
528   /* Clear the remove flag so that the open_card is able to reread it.  */
529   if (ctrl->server_local->card_removed)
530     {
531       if ( IS_LOCKED (ctrl) )
532         return gpg_error (GPG_ERR_LOCKED);
533       do_reset (ctrl, 1);
534     }
535
536   if ((rc = open_card (ctrl, *line? line:NULL)))
537     return rc;
538
539   rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
540   if (rc)
541     return rc;
542
543   rc = estream_asprintf (&serial_and_stamp, "%s %lu",
544                          serial, (unsigned long)stamp);
545   xfree (serial);
546   if (rc < 0)
547     return out_of_core ();
548   rc = 0;
549   assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
550   xfree (serial_and_stamp);
551   return 0;
552 }
553
554
555
556
557 /* LEARN [--force] [--keypairinfo]
558
559    Learn all useful information of the currently inserted card.  When
560    used without the force options, the command might do an INQUIRE
561    like this:
562
563       INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>
564
565    The client should just send an "END" if the processing should go on
566    or a "CANCEL" to force the function to terminate with a Cancel
567    error message.  
568
569    With the option --keypairinfo only KEYPARIINFO lstatus lines are
570    returned.
571
572    The response of this command is a list of status lines formatted as
573    this:
574
575      S APPTYPE <apptype>
576
577    This returns the type of the application, currently the strings:
578
579        P15     = PKCS-15 structure used
580        DINSIG  = DIN SIG
581        OPENPGP = OpenPGP card
582        NKS     = NetKey card
583
584    are implemented.  These strings are aliases for the AID
585
586      S KEYPAIRINFO <hexstring_with_keygrip> <hexstring_with_id>
587
588    If there is no certificate yet stored on the card a single "X" is
589    returned as the keygrip.  In addition to the keypair info, information
590    about all certificates stored on the card is also returned:
591
592      S CERTINFO <certtype> <hexstring_with_id>
593
594    Where CERTTYPE is a number indicating the type of certificate:
595       0   := Unknown
596       100 := Regular X.509 cert
597       101 := Trusted X.509 cert
598       102 := Useful X.509 cert
599       110 := Root CA cert in a special format (e.g. DINSIG)
600       111 := Root CA cert as standard X509 cert.
601
602    For certain cards, more information will be returned:
603
604      S KEY-FPR <no> <hexstring>
605
606    For OpenPGP cards this returns the stored fingerprints of the
607    keys. This can be used check whether a key is available on the
608    card.  NO may be 1, 2 or 3.
609
610      S CA-FPR <no> <hexstring>
611
612    Similar to above, these are the fingerprints of keys assumed to be
613    ultimately trusted.
614
615      S DISP-NAME <name_of_card_holder>
616
617    The name of the card holder as stored on the card; percent
618    escaping takes place, spaces are encoded as '+'
619
620      S PUBKEY-URL <url>
621
622    The URL to be used for locating the entire public key.
623      
624    Note, that this function may even be used on a locked card.
625 */
626 static int
627 cmd_learn (assuan_context_t ctx, char *line)
628 {
629   ctrl_t ctrl = assuan_get_pointer (ctx);
630   int rc = 0;
631   int only_keypairinfo = has_option (line, "--keypairinfo");
632
633   if ((rc = open_card (ctrl, NULL)))
634     return rc;
635
636   /* Unless the force option is used we try a shortcut by identifying
637      the card using a serial number and inquiring the client with
638      that. The client may choose to cancel the operation if he already
639      knows about this card */
640   if (!only_keypairinfo)
641     {
642       char *serial_and_stamp;
643       char *serial;
644       time_t stamp;
645       
646       rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
647       if (rc)
648         return rc;
649       rc = estream_asprintf (&serial_and_stamp, "%s %lu",
650                              serial, (unsigned long)stamp);
651       xfree (serial);
652       if (rc < 0)
653         return out_of_core ();
654       rc = 0;
655       assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
656       
657       if (!has_option (line, "--force"))
658         {
659           char *command;
660           
661           rc = estream_asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
662           if (rc < 0)
663             {
664               xfree (serial_and_stamp);
665               return out_of_core ();
666             }
667           rc = 0;
668           rc = assuan_inquire (ctx, command, NULL, NULL, 0); 
669           xfree (command);
670           if (rc)
671             {
672               if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
673                 log_error ("inquire KNOWNCARDP failed: %s\n",
674                            gpg_strerror (rc));
675               xfree (serial_and_stamp);
676               return rc; 
677             }
678           /* Not canceled, so we have to proceeed.  */
679         }
680       xfree (serial_and_stamp);
681     }
682   
683   /* Let the application print out its collection of useful status
684      information. */
685   if (!rc)
686     rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
687
688   TEST_CARD_REMOVAL (ctrl, rc);
689   return rc;
690 }
691
692
693 \f
694 /* READCERT <hexified_certid>|<keyid>
695
696    Note, that this function may even be used on a locked card.
697  */
698 static int
699 cmd_readcert (assuan_context_t ctx, char *line)
700 {
701   ctrl_t ctrl = assuan_get_pointer (ctx);
702   int rc;
703   unsigned char *cert;
704   size_t ncert;
705
706   if ((rc = open_card (ctrl, NULL)))
707     return rc;
708
709   line = xstrdup (line); /* Need a copy of the line. */
710   rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
711   if (rc)
712     log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
713   xfree (line);
714   line = NULL;
715   if (!rc)
716     {
717       rc = assuan_send_data (ctx, cert, ncert);
718       xfree (cert);
719       if (rc)
720         return rc;
721     }
722
723   TEST_CARD_REMOVAL (ctrl, rc);
724   return rc;
725 }
726
727
728 /* READKEY <keyid>
729
730    Return the public key for the given cert or key ID as an standard
731    S-Expression.
732
733    Note, that this function may even be used on a locked card.
734   */
735 static int
736 cmd_readkey (assuan_context_t ctx, char *line)
737 {
738   ctrl_t ctrl = assuan_get_pointer (ctx);
739   int rc;
740   unsigned char *cert = NULL;
741   size_t ncert, n;
742   ksba_cert_t kc = NULL;
743   ksba_sexp_t p;
744   unsigned char *pk;
745   size_t pklen;
746
747   if ((rc = open_card (ctrl, NULL)))
748     return rc;
749
750   line = xstrdup (line); /* Need a copy of the line. */
751   /* If the application supports the READKEY function we use that.
752      Otherwise we use the old way by extracting it from the
753      certificate.  */
754   rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
755   if (!rc)
756     { /* Yeah, got that key - send it back.  */
757       rc = assuan_send_data (ctx, pk, pklen);
758       xfree (pk);
759       xfree (line);
760       line = NULL;
761       goto leave;
762     }
763
764   if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
765     log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
766   else  
767     {
768       rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
769       if (rc)
770         log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
771     }
772   xfree (line);
773   line = NULL;
774   if (rc)
775     goto leave;
776       
777   rc = ksba_cert_new (&kc);
778   if (rc)
779     {
780       xfree (cert);
781       goto leave;
782     }
783   rc = ksba_cert_init_from_mem (kc, cert, ncert);
784   if (rc)
785     {
786       log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
787       goto leave;
788     }
789
790   p = ksba_cert_get_public_key (kc);
791   if (!p)
792     {
793       rc = gpg_error (GPG_ERR_NO_PUBKEY);
794       goto leave;
795     }
796
797   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
798   rc = assuan_send_data (ctx, p, n);
799   xfree (p);
800
801
802  leave:
803   ksba_cert_release (kc);
804   xfree (cert);
805   TEST_CARD_REMOVAL (ctrl, rc);
806   return rc;
807 }
808
809
810 \f
811
812 /* SETDATA <hexstring> 
813
814    The client should use this command to tell us the data he want to
815    sign.  */
816 static int
817 cmd_setdata (assuan_context_t ctx, char *line)
818 {
819   ctrl_t ctrl = assuan_get_pointer (ctx);
820   int n;
821   char *p;
822   unsigned char *buf;
823
824   if (locked_session && locked_session != ctrl->server_local)
825     return gpg_error (GPG_ERR_LOCKED);
826
827   /* Parse the hexstring. */
828   for (p=line,n=0; hexdigitp (p); p++, n++)
829     ;
830   if (*p)
831     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
832   if (!n)
833     return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
834   if ((n&1))
835     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
836   n /= 2;
837   buf = xtrymalloc (n);
838   if (!buf)
839     return out_of_core ();
840
841   ctrl->in_data.value = buf;
842   ctrl->in_data.valuelen = n;
843   for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++)
844     buf[n] = xtoi_2 (p);
845   return 0;
846 }
847
848
849
850 static gpg_error_t 
851 pin_cb (void *opaque, const char *info, char **retstr)
852 {
853   assuan_context_t ctx = opaque;
854   char *command;
855   int rc;
856   unsigned char *value;
857   size_t valuelen;
858
859   if (!retstr)
860     {
861       /* We prompt for keypad entry.  To make sure that the popup has
862          been show we use an inquire and not just a status message.
863          We ignore any value returned.  */
864       if (info)
865         {
866           log_debug ("prompting for keypad entry '%s'\n", info);
867           rc = estream_asprintf (&command, "POPUPKEYPADPROMPT %s", info);
868           if (rc < 0)
869             return gpg_error (gpg_err_code_from_errno (errno));
870           rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); 
871           xfree (command);  
872         }
873       else
874         {
875           log_debug ("dismiss keypad entry prompt\n");
876           rc = assuan_inquire (ctx, "DISMISSKEYPADPROMPT",
877                                &value, &valuelen, MAXLEN_PIN); 
878         }
879       if (!rc)
880         xfree (value);
881       return rc;
882     }
883
884   *retstr = NULL;
885   log_debug ("asking for PIN '%s'\n", info);
886
887   rc = estream_asprintf (&command, "NEEDPIN %s", info);
888   if (rc < 0)
889     return gpg_error (gpg_err_code_from_errno (errno));
890
891   /* Fixme: Write an inquire function which returns the result in
892      secure memory and check all further handling of the PIN. */
893   rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); 
894   xfree (command);  
895   if (rc)
896     return rc;
897
898   if (!valuelen || value[valuelen-1])
899     {
900       /* We require that the returned value is an UTF-8 string */
901       xfree (value);
902       return gpg_error (GPG_ERR_INV_RESPONSE);
903     }
904   *retstr = (char*)value;
905   return 0;
906 }
907
908
909 /* PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>
910
911    The --hash option is optional; the default is SHA1.
912
913  */
914 static int
915 cmd_pksign (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   int hash_algo;
923
924   if (has_option (line, "--hash=rmd160"))
925     hash_algo = GCRY_MD_RMD160;
926   else if (has_option (line, "--hash=sha1"))
927     hash_algo = GCRY_MD_SHA1;
928   else if (has_option (line, "--hash=sha224"))
929     hash_algo = GCRY_MD_SHA224;
930   else if (has_option (line, "--hash=sha256"))
931     hash_algo = GCRY_MD_SHA256;
932   else if (has_option (line, "--hash=sha384"))
933     hash_algo = GCRY_MD_SHA384;
934   else if (has_option (line, "--hash=sha512"))
935     hash_algo = GCRY_MD_SHA512;
936   else if (has_option (line, "--hash=md5"))
937     hash_algo = GCRY_MD_MD5;
938   else if (!strstr (line, "--"))
939     hash_algo = GCRY_MD_SHA1; 
940   else
941     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
942
943   line = skip_options (line);
944
945   if ( IS_LOCKED (ctrl) )
946     return gpg_error (GPG_ERR_LOCKED);
947
948   if ((rc = open_card (ctrl, NULL)))
949     return rc;
950
951   /* We have to use a copy of the key ID because the function may use
952      the pin_cb which in turn uses the assuan line buffer and thus
953      overwriting the original line with the keyid */
954   keyidstr = xtrystrdup (line);
955   if (!keyidstr)
956     return out_of_core ();
957   
958   rc = app_sign (ctrl->app_ctx,
959                  keyidstr, hash_algo,
960                  pin_cb, ctx,
961                  ctrl->in_data.value, ctrl->in_data.valuelen,
962                  &outdata, &outdatalen);
963
964   xfree (keyidstr);
965   if (rc)
966     {
967       log_error ("app_sign failed: %s\n", gpg_strerror (rc));
968     }
969   else
970     {
971       rc = assuan_send_data (ctx, outdata, outdatalen);
972       xfree (outdata);
973       if (rc)
974         return rc; /* that is already an assuan error code */
975     }
976
977   TEST_CARD_REMOVAL (ctrl, rc);
978   return rc;
979 }
980
981 /* PKAUTH <hexified_id>
982
983  */
984 static int
985 cmd_pkauth (assuan_context_t ctx, char *line)
986 {
987   ctrl_t ctrl = assuan_get_pointer (ctx);
988   int rc;
989   unsigned char *outdata;
990   size_t outdatalen;
991   char *keyidstr;
992
993   if ( IS_LOCKED (ctrl) )
994     return gpg_error (GPG_ERR_LOCKED);
995
996   if ((rc = open_card (ctrl, NULL)))
997     return rc;
998
999   if (!ctrl->app_ctx)
1000     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1001
1002  /* We have to use a copy of the key ID because the function may use
1003      the pin_cb which in turn uses the assuan line buffer and thus
1004      overwriting the original line with the keyid */
1005   keyidstr = xtrystrdup (line);
1006   if (!keyidstr)
1007     return out_of_core ();
1008   
1009   rc = app_auth (ctrl->app_ctx,
1010                  keyidstr,
1011                  pin_cb, ctx,
1012                  ctrl->in_data.value, ctrl->in_data.valuelen,
1013                  &outdata, &outdatalen);
1014   xfree (keyidstr);
1015   if (rc)
1016     {
1017       log_error ("app_auth failed: %s\n", gpg_strerror (rc));
1018     }
1019   else
1020     {
1021       rc = assuan_send_data (ctx, outdata, outdatalen);
1022       xfree (outdata);
1023       if (rc)
1024         return rc; /* that is already an assuan error code */
1025     }
1026
1027   TEST_CARD_REMOVAL (ctrl, rc);
1028   return rc;
1029 }
1030
1031 /* PKDECRYPT <hexified_id>
1032
1033  */
1034 static int
1035 cmd_pkdecrypt (assuan_context_t ctx, char *line)
1036 {
1037   ctrl_t ctrl = assuan_get_pointer (ctx);
1038   int rc;
1039   unsigned char *outdata;
1040   size_t outdatalen;
1041   char *keyidstr;
1042
1043   if ( IS_LOCKED (ctrl) )
1044     return gpg_error (GPG_ERR_LOCKED);
1045
1046   if ((rc = open_card (ctrl, NULL)))
1047     return rc;
1048
1049   keyidstr = xtrystrdup (line);
1050   if (!keyidstr)
1051     return out_of_core ();
1052   rc = app_decipher (ctrl->app_ctx,
1053                      keyidstr, 
1054                      pin_cb, ctx,
1055                      ctrl->in_data.value, ctrl->in_data.valuelen,
1056                      &outdata, &outdatalen);
1057
1058   xfree (keyidstr);
1059   if (rc)
1060     {
1061       log_error ("app_decipher failed: %s\n", gpg_strerror (rc));
1062     }
1063   else
1064     {
1065       rc = assuan_send_data (ctx, outdata, outdatalen);
1066       xfree (outdata);
1067       if (rc)
1068         return rc; /* that is already an assuan error code */
1069     }
1070
1071   TEST_CARD_REMOVAL (ctrl, rc);
1072   return rc;
1073 }
1074
1075
1076 /* GETATTR <name>
1077
1078    This command is used to retrieve data from a smartcard.  The
1079    allowed names depend on the currently selected smartcard
1080    application.  NAME must be percent and '+' escaped.  The value is
1081    returned through status message, see the LEARN command for details.
1082
1083    However, the current implementation assumes that Name is not escaped;
1084    this works as long as noone uses arbitrary escaping. 
1085  
1086    Note, that this function may even be used on a locked card.
1087 */
1088 static int
1089 cmd_getattr (assuan_context_t ctx, char *line)
1090 {
1091   ctrl_t ctrl = assuan_get_pointer (ctx);
1092   int rc;
1093   const char *keyword;
1094
1095   if ((rc = open_card (ctrl, NULL)))
1096     return rc;
1097
1098   keyword = line;
1099   for (; *line && !spacep (line); line++)
1100     ;
1101   if (*line)
1102       *line++ = 0;
1103
1104   /* (We ignore any garbage for now.) */
1105
1106   /* FIXME: Applications should not return sensitive data if the card
1107      is locked.  */
1108   rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
1109
1110   TEST_CARD_REMOVAL (ctrl, rc);
1111   return rc;
1112 }
1113
1114
1115 /* SETATTR <name> <value> 
1116
1117    This command is used to store data on a a smartcard.  The allowed
1118    names and values are depend on the currently selected smartcard
1119    application.  NAME and VALUE must be percent and '+' escaped.
1120
1121    However, the current implementation assumes that NAME is not
1122    escaped; this works as long as noone uses arbitrary escaping.
1123  
1124    A PIN will be requested for most NAMEs.  See the corresponding
1125    setattr function of the actually used application (app-*.c) for
1126    details.  */
1127 static int
1128 cmd_setattr (assuan_context_t ctx, char *orig_line)
1129 {
1130   ctrl_t ctrl = assuan_get_pointer (ctx);
1131   int rc;
1132   char *keyword;
1133   int keywordlen;
1134   size_t nbytes;
1135   char *line, *linebuf;
1136
1137   if ( IS_LOCKED (ctrl) )
1138     return gpg_error (GPG_ERR_LOCKED);
1139
1140   if ((rc = open_card (ctrl, NULL)))
1141     return rc;
1142
1143   /* We need to use a copy of LINE, because PIN_CB uses the same
1144      context and thus reuses the Assuan provided LINE. */
1145   line = linebuf = xtrystrdup (orig_line);
1146   if (!line)
1147     return out_of_core ();
1148
1149   keyword = line;
1150   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1151     ;
1152   if (*line)
1153       *line++ = 0;
1154   while (spacep (line))
1155     line++;
1156   nbytes = percent_plus_unescape ((unsigned char*)line);
1157
1158   rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx,
1159                     (const unsigned char*)line, nbytes);
1160   xfree (linebuf);
1161
1162   TEST_CARD_REMOVAL (ctrl, rc);
1163   return rc;
1164 }
1165
1166
1167
1168 /* WRITECERT <hexified_certid>
1169
1170    This command is used to store a certifciate on a smartcard.  The
1171    allowed certids depend on the currently selected smartcard
1172    application. The actual certifciate is requested using the inquiry
1173    "CERTDATA" and needs to be provided in its raw (e.g. DER) form.
1174
1175    In almost all cases a a PIN will be requested.  See the related
1176    writecert function of the actually used application (app-*.c) for
1177    details.  */
1178 static int
1179 cmd_writecert (assuan_context_t ctx, char *line)
1180 {
1181   ctrl_t ctrl = assuan_get_pointer (ctx);
1182   int rc;
1183   char *certid;
1184   unsigned char *certdata;
1185   size_t certdatalen;
1186
1187   if ( IS_LOCKED (ctrl) )
1188     return gpg_error (GPG_ERR_LOCKED);
1189
1190   line = skip_options (line);
1191
1192   if (!*line)
1193     return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1194   certid = line;
1195   while (*line && !spacep (line))
1196     line++;
1197   *line = 0;
1198
1199   if ((rc = open_card (ctrl, NULL)))
1200     return rc;
1201
1202   if (!ctrl->app_ctx)
1203     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1204
1205   certid = xtrystrdup (certid);
1206   if (!certid)
1207     return out_of_core ();
1208
1209   /* Now get the actual keydata. */
1210   rc = assuan_inquire (ctx, "CERTDATA",
1211                        &certdata, &certdatalen, MAXLEN_CERTDATA);
1212   if (rc)
1213     {
1214       xfree (certid);
1215       return rc;
1216     }
1217
1218   /* Write the certificate to the card. */
1219   rc = app_writecert (ctrl->app_ctx, ctrl, certid, 
1220                       pin_cb, ctx, certdata, certdatalen);
1221   xfree (certid);
1222   xfree (certdata);
1223
1224   TEST_CARD_REMOVAL (ctrl, rc);
1225   return rc;
1226 }
1227
1228
1229
1230 /* WRITEKEY [--force] <keyid> 
1231
1232    This command is used to store a secret key on a a smartcard.  The
1233    allowed keyids depend on the currently selected smartcard
1234    application. The actual keydata is requested using the inquiry
1235    "KEYDATA" and need to be provided without any protection.  With
1236    --force set an existing key under this KEYID will get overwritten.
1237    The keydata is expected to be the usual canonical encoded
1238    S-expression.
1239
1240    A PIN will be requested for most NAMEs.  See the corresponding
1241    writekey function of the actually used application (app-*.c) for
1242    details.  */
1243 static int
1244 cmd_writekey (assuan_context_t ctx, char *line)
1245 {
1246   ctrl_t ctrl = assuan_get_pointer (ctx);
1247   int rc;
1248   char *keyid;
1249   int force = has_option (line, "--force");
1250   unsigned char *keydata;
1251   size_t keydatalen;
1252
1253   if ( IS_LOCKED (ctrl) )
1254     return gpg_error (GPG_ERR_LOCKED);
1255
1256   line = skip_options (line);
1257
1258   if (!*line)
1259     return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1260   keyid = line;
1261   while (*line && !spacep (line))
1262     line++;
1263   *line = 0;
1264
1265   if ((rc = open_card (ctrl, NULL)))
1266     return rc;
1267
1268   if (!ctrl->app_ctx)
1269     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1270
1271   keyid = xtrystrdup (keyid);
1272   if (!keyid)
1273     return out_of_core ();
1274
1275   /* Now get the actual keydata. */
1276   assuan_begin_confidential (ctx);
1277   rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1278   assuan_end_confidential (ctx);
1279   if (rc)
1280     {
1281       xfree (keyid);
1282       return rc;
1283     }
1284
1285   /* Write the key to the card. */
1286   rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1287                      pin_cb, ctx, keydata, keydatalen);
1288   xfree (keyid);
1289   xfree (keydata);
1290
1291   TEST_CARD_REMOVAL (ctrl, rc);
1292   return rc;
1293 }
1294
1295
1296
1297 /* GENKEY [--force] [--timestamp=<isodate>] <no>
1298
1299    Generate a key on-card identified by NO, which is application
1300    specific.  Return values are application specific.  For OpenPGP
1301    cards 2 status lines are returned:
1302
1303      S KEY-FPR  <hexstring>
1304      S KEY-CREATED-AT <seconds_since_epoch>
1305      S KEY-DATA [p|n] <hexdata>
1306      
1307    --force is required to overwrite an already existing key.  The
1308    KEY-CREATED-AT is required for further processing because it is
1309    part of the hashed key material for the fingerprint.
1310
1311    If --timestamp is given an OpenPGP key will be created using this
1312    value.  The value needs to be in ISO Format; e.g.
1313    "--timestamp=20030316T120000" and after 1970-01-01 00:00:00.
1314
1315    The public part of the key can also later be retrieved using the
1316    READKEY command.
1317
1318  */
1319 static int
1320 cmd_genkey (assuan_context_t ctx, char *line)
1321 {
1322   ctrl_t ctrl = assuan_get_pointer (ctx);
1323   int rc;
1324   char *keyno;
1325   int force;
1326   const char *s;
1327   time_t timestamp;
1328
1329   if ( IS_LOCKED (ctrl) )
1330     return gpg_error (GPG_ERR_LOCKED);
1331
1332   force = has_option (line, "--force");
1333
1334   if ((s=has_option_name (line, "--timestamp")))
1335     {
1336       if (*s != '=')
1337         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1338       timestamp = isotime2epoch (s+1);
1339       if (timestamp < 1)
1340         return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1341     }
1342   else
1343     timestamp = 0;
1344
1345
1346   line = skip_options (line);
1347   if (!*line)
1348     return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1349   keyno = line;
1350   while (*line && !spacep (line))
1351     line++;
1352   *line = 0;
1353
1354   if ((rc = open_card (ctrl, NULL)))
1355     return rc;
1356
1357   if (!ctrl->app_ctx)
1358     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1359
1360   keyno = xtrystrdup (keyno);
1361   if (!keyno)
1362     return out_of_core ();
1363   rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1364                    timestamp, pin_cb, ctx);
1365   xfree (keyno);
1366
1367   TEST_CARD_REMOVAL (ctrl, rc);
1368   return rc;
1369 }
1370
1371
1372 /* RANDOM <nbytes>
1373
1374    Get NBYTES of random from the card and send them back as data. 
1375
1376    Note, that this function may be even be used on a locked card.
1377 */
1378 static int
1379 cmd_random (assuan_context_t ctx, char *line)
1380 {
1381   ctrl_t ctrl = assuan_get_pointer (ctx);
1382   int rc;
1383   size_t nbytes;
1384   unsigned char *buffer;
1385
1386   if (!*line)
1387     return set_error (GPG_ERR_ASS_PARAMETER, "number of requested bytes missing");
1388   nbytes = strtoul (line, NULL, 0);
1389
1390   if ((rc = open_card (ctrl, NULL)))
1391     return rc;
1392
1393   if (!ctrl->app_ctx)
1394     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1395
1396   buffer = xtrymalloc (nbytes);
1397   if (!buffer)
1398     return out_of_core ();
1399
1400   rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1401   if (!rc)
1402     {
1403       rc = assuan_send_data (ctx, buffer, nbytes);
1404       xfree (buffer);
1405       return rc; /* that is already an assuan error code */
1406     }
1407   xfree (buffer);
1408
1409   TEST_CARD_REMOVAL (ctrl, rc);
1410   return rc;
1411 }
1412
1413 \f
1414 /* PASSWD [--reset] [--nullpin] <chvno>
1415   
1416    Change the PIN or, if --reset is given, reset the retry counter of
1417    the card holder verfication vector CHVNO.  The option --nullpin is
1418    used for TCOS cards to set the initial PIN.  The format of CHVNO
1419    depends on the card application.  */
1420 static int
1421 cmd_passwd (assuan_context_t ctx, char *line)
1422 {
1423   ctrl_t ctrl = assuan_get_pointer (ctx);
1424   int rc;
1425   char *chvnostr;
1426   unsigned int flags = 0;
1427
1428   if (has_option (line, "--reset"))
1429     flags |= APP_CHANGE_FLAG_RESET;
1430   if (has_option (line, "--nullpin"))
1431     flags |= APP_CHANGE_FLAG_NULLPIN;
1432
1433   if ( IS_LOCKED (ctrl) )
1434     return gpg_error (GPG_ERR_LOCKED);
1435
1436   line = skip_options (line);
1437
1438   if (!*line)
1439     return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1440   chvnostr = line;
1441   while (*line && !spacep (line))
1442     line++;
1443   *line = 0;
1444
1445   if ((rc = open_card (ctrl, NULL)))
1446     return rc;
1447
1448   if (!ctrl->app_ctx)
1449     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1450   
1451   chvnostr = xtrystrdup (chvnostr);
1452   if (!chvnostr)
1453     return out_of_core ();
1454   rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1455   if (rc)
1456     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1457   xfree (chvnostr);
1458
1459   TEST_CARD_REMOVAL (ctrl, rc);
1460   return rc;
1461 }
1462
1463
1464 /* CHECKPIN <idstr>
1465
1466    Perform a VERIFY operation without doing anything else.  This may
1467    be used to initialize a the PIN cache earlier to long lasting
1468    operations.  Its use is highly application dependent.
1469
1470    For OpenPGP:
1471
1472       Perform a simple verify operation for CHV1 and CHV2, so that
1473       further operations won't ask for CHV2 and it is possible to do a
1474       cheap check on the PIN: If there is something wrong with the PIN
1475       entry system, only the regular CHV will get blocked and not the
1476       dangerous CHV3.  IDSTR is the usual card's serial number in hex
1477       notation; an optional fingerprint part will get ignored.  There
1478       is however a special mode if the IDSTR is sffixed with the
1479       literal string "[CHV3]": In this case the Admin PIN is checked
1480       if and only if the retry counter is still at 3.
1481
1482    For Netkey:
1483
1484       Any of the valid PIN Ids may be used.  These are the strings:
1485
1486         PW1.CH       - Global password 1
1487         PW2.CH       - Global password 2
1488         PW1.CH.SIG   - SigG password 1
1489         PW2.CH.SIG   - SigG password 2
1490
1491       For a definitive list, see the implementation in app-nks.c.
1492       Note that we call a PW2.* PIN a "PUK" despite that since TCOS
1493       3.0 they are technically alternative PINs used to mutally
1494       unblock each other.
1495
1496  */
1497 static int
1498 cmd_checkpin (assuan_context_t ctx, char *line)
1499 {
1500   ctrl_t ctrl = assuan_get_pointer (ctx);
1501   int rc;
1502   char *idstr;
1503
1504   if ( IS_LOCKED (ctrl) )
1505     return gpg_error (GPG_ERR_LOCKED);
1506
1507   if ((rc = open_card (ctrl, NULL)))
1508     return rc;
1509
1510   if (!ctrl->app_ctx)
1511     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1512
1513   /* We have to use a copy of the key ID because the function may use
1514      the pin_cb which in turn uses the assuan line buffer and thus
1515      overwriting the original line with the keyid. */
1516   idstr = xtrystrdup (line);
1517   if (!idstr)
1518     return out_of_core ();
1519   
1520   rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx);
1521   xfree (idstr);
1522   if (rc)
1523     log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1524
1525   TEST_CARD_REMOVAL (ctrl, rc);
1526   return rc;
1527 }
1528
1529
1530 /* LOCK [--wait]
1531
1532    Grant exclusive card access to this session.  Note that there is
1533    no lock counter used and a second lock from the same session will
1534    be ignored.  A single unlock (or RESET) unlocks the session.
1535    Return GPG_ERR_LOCKED if another session has locked the reader.
1536
1537    If the option --wait is given the command will wait until a
1538    lock has been released.
1539  */
1540 static int
1541 cmd_lock (assuan_context_t ctx, char *line)
1542 {
1543   ctrl_t ctrl = assuan_get_pointer (ctx);
1544   int rc = 0;
1545
1546  retry:
1547   if (locked_session)
1548     {
1549       if (locked_session != ctrl->server_local)
1550         rc = gpg_error (GPG_ERR_LOCKED);
1551     }
1552   else
1553     locked_session = ctrl->server_local;
1554
1555 #ifdef USE_GNU_PTH
1556   if (rc && has_option (line, "--wait"))
1557     {
1558       rc = 0;
1559       pth_sleep (1); /* Better implement an event mechanism. However,
1560                         for card operations this should be
1561                         sufficient. */
1562       /* FIXME: Need to check that the connection is still alive.
1563          This can be done by issuing status messages. */
1564       goto retry;
1565     }
1566 #endif /*USE_GNU_PTH*/
1567   
1568   if (rc)
1569     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1570   return rc;
1571 }
1572
1573
1574 /* UNLOCK
1575
1576    Release exclusive card access.
1577  */
1578 static int
1579 cmd_unlock (assuan_context_t ctx, char *line)
1580 {
1581   ctrl_t ctrl = assuan_get_pointer (ctx);
1582   int rc = 0;
1583
1584   (void)line;
1585
1586   if (locked_session)
1587     {
1588       if (locked_session != ctrl->server_local)
1589         rc = gpg_error (GPG_ERR_LOCKED);
1590       else
1591         locked_session = NULL;
1592     }
1593   else
1594     rc = gpg_error (GPG_ERR_NOT_LOCKED);
1595
1596   if (rc)
1597     log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1598   return rc;
1599 }
1600
1601
1602 /* GETINFO <what>
1603
1604    Multi purpose command to return certain information.  
1605    Supported values of WHAT are:
1606
1607    version     - Return the version of the program.
1608    pid         - Return the process id of the server.
1609
1610    socket_name - Return the name of the socket.
1611
1612    status - Return the status of the current slot (in the future, may
1613    also return the status of all slots).  The status is a list of
1614    one-character flags.  The following flags are currently defined:
1615      'u'  Usable card present.  This is the normal state during operation.
1616      'r'  Card removed.  A reset is necessary.
1617    These flags are exclusive.
1618
1619    reader_list - Return a list of detected card readers.  Does
1620                  currently only work with the internal CCID driver.
1621
1622    deny_admin  - Returns OK if admin commands are not allowed or
1623                  GPG_ERR_GENERAL if admin commands are allowed.
1624
1625    app_list    - Return a list of supported applications.  One
1626                  application per line, fields delimited by colons,
1627                  first field is the name.
1628 */
1629
1630 static int
1631 cmd_getinfo (assuan_context_t ctx, char *line)
1632 {
1633   int rc = 0;
1634
1635   if (!strcmp (line, "version"))
1636     {
1637       const char *s = VERSION;
1638       rc = assuan_send_data (ctx, s, strlen (s));
1639     }
1640   else if (!strcmp (line, "pid"))
1641     {
1642       char numbuf[50];
1643
1644       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1645       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1646     }
1647   else if (!strcmp (line, "socket_name"))
1648     {
1649       const char *s = scd_get_socket_name ();
1650
1651       if (s)
1652         rc = assuan_send_data (ctx, s, strlen (s));
1653       else
1654         rc = gpg_error (GPG_ERR_NO_DATA);
1655     }
1656   else if (!strcmp (line, "status"))
1657     {
1658       ctrl_t ctrl = assuan_get_pointer (ctx);
1659       int slot = ctrl->reader_slot;
1660       char flag = 'r';
1661
1662       if (!ctrl->server_local->card_removed && slot != -1)
1663         {
1664           struct slot_status_s *ss;
1665           
1666           if (!(slot >= 0 && slot < DIM(slot_table)))
1667             BUG ();
1668
1669           ss = &slot_table[slot];
1670
1671           if (!ss->valid)
1672             BUG ();
1673
1674           if (ss->any && (ss->status & 1))
1675             flag = 'u';
1676         }
1677       rc = assuan_send_data (ctx, &flag, 1);
1678     }
1679   else if (!strcmp (line, "reader_list"))
1680     {
1681 #ifdef HAVE_LIBUSB
1682       char *s = ccid_get_reader_list ();
1683 #else
1684       char *s = NULL;
1685 #endif
1686       
1687       if (s)
1688         rc = assuan_send_data (ctx, s, strlen (s));
1689       else
1690         rc = gpg_error (GPG_ERR_NO_DATA);
1691       xfree (s);
1692     }
1693   else if (!strcmp (line, "deny_admin"))
1694     rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1695   else if (!strcmp (line, "app_list"))
1696     {
1697       char *s = get_supported_applications ();
1698       if (s)
1699         rc = assuan_send_data (ctx, s, strlen (s));
1700       else
1701         rc = 0;
1702       xfree (s);
1703     }
1704   else
1705     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1706   return rc;
1707 }
1708
1709
1710 /* RESTART
1711
1712    Restart the current connection; this is a kind of warm reset.  It
1713    deletes the context used by this connection but does not send a
1714    RESET to the card.  Thus the card itself won't get reset. 
1715
1716    This is used by gpg-agent to reuse a primary pipe connection and
1717    may be used by clients to backup from a conflict in the serial
1718    command; i.e. to select another application. 
1719 */
1720
1721 static int
1722 cmd_restart (assuan_context_t ctx, char *line)
1723 {
1724   ctrl_t ctrl = assuan_get_pointer (ctx);
1725
1726   (void)line;
1727
1728   if (ctrl->app_ctx)
1729     {
1730       release_application (ctrl->app_ctx);
1731       ctrl->app_ctx = NULL;
1732     }
1733   if (locked_session && ctrl->server_local == locked_session)
1734     {
1735       locked_session = NULL;
1736       log_info ("implicitly unlocking due to RESTART\n");
1737     }
1738   return 0;
1739 }
1740
1741
1742 /* DISCONNECT
1743
1744    Disconnect the card if it is not any longer used by other
1745    connections and the backend supports a disconnect operation. 
1746  */
1747 static int
1748 cmd_disconnect (assuan_context_t ctx, char *line)
1749 {
1750   ctrl_t ctrl = assuan_get_pointer (ctx);
1751
1752   (void)line;
1753   
1754   ctrl->server_local->disconnect_allowed = 1;
1755   return 0;
1756 }
1757
1758
1759
1760 /* APDU [--atr] [--more] [hexstring]
1761
1762    Send an APDU to the current reader.  This command bypasses the high
1763    level functions and sends the data directly to the card.  HEXSTRING
1764    is expected to be a proper APDU.  If HEXSTRING is not given no
1765    commands are set to the card but the command will implictly check
1766    whether the card is ready for use. 
1767
1768    Using the option "--atr" returns the ATR of the card as a status
1769    message before any data like this:
1770      S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1
1771
1772    Using the option --more handles the card status word MORE_DATA
1773    (61xx) and concatenate all reponses to one block.
1774
1775  */
1776 static int
1777 cmd_apdu (assuan_context_t ctx, char *line)
1778 {
1779   ctrl_t ctrl = assuan_get_pointer (ctx);
1780   int rc;
1781   unsigned char *apdu;
1782   size_t apdulen;
1783   int with_atr;
1784   int handle_more;
1785
1786   with_atr = has_option (line, "--atr");
1787   handle_more = has_option (line, "--more");
1788
1789   line = skip_options (line);
1790
1791   if ( IS_LOCKED (ctrl) )
1792     return gpg_error (GPG_ERR_LOCKED);
1793
1794   if ((rc = open_card (ctrl, NULL)))
1795     return rc;
1796
1797   if (with_atr)
1798     {
1799       unsigned char *atr;
1800       size_t atrlen;
1801       char hexbuf[400];
1802       
1803       atr = apdu_get_atr (ctrl->reader_slot, &atrlen);
1804       if (!atr || atrlen > sizeof hexbuf - 2 )
1805         {
1806           rc = gpg_error (GPG_ERR_INV_CARD);
1807           goto leave;
1808         }
1809       bin2hex (atr, atrlen, hexbuf);
1810       xfree (atr);
1811       send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1812     }
1813
1814   apdu = hex_to_buffer (line, &apdulen);
1815   if (!apdu)
1816     {
1817       rc = gpg_error_from_syserror ();
1818       goto leave;
1819     }
1820   if (apdulen)
1821     {
1822       unsigned char *result = NULL;
1823       size_t resultlen;
1824
1825       rc = apdu_send_direct (ctrl->reader_slot, 0, apdu, apdulen, handle_more,
1826                              &result, &resultlen);
1827       if (rc)
1828         log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1829       else
1830         {
1831           rc = assuan_send_data (ctx, result, resultlen);
1832           xfree (result);
1833         }
1834     }
1835   xfree (apdu);
1836
1837  leave:
1838   TEST_CARD_REMOVAL (ctrl, rc);
1839   return rc;
1840 }
1841
1842
1843 /* KILLSCD - Commit suicide. */
1844 static int
1845 cmd_killscd (assuan_context_t ctx, char *line)
1846 {
1847   ctrl_t ctrl = assuan_get_pointer (ctx);
1848
1849   (void)line;
1850
1851   ctrl->server_local->stopme = 1;
1852   return gpg_error (GPG_ERR_EOF);
1853 }
1854
1855
1856 \f
1857 /* Tell the assuan library about our commands */
1858 static int
1859 register_commands (assuan_context_t ctx)
1860 {
1861   static struct {
1862     const char *name;
1863     int (*handler)(assuan_context_t, char *line);
1864   } table[] = {
1865     { "SERIALNO",     cmd_serialno },
1866     { "LEARN",        cmd_learn },
1867     { "READCERT",     cmd_readcert },
1868     { "READKEY",      cmd_readkey },
1869     { "SETDATA",      cmd_setdata },
1870     { "PKSIGN",       cmd_pksign },
1871     { "PKAUTH",       cmd_pkauth },
1872     { "PKDECRYPT",    cmd_pkdecrypt },
1873     { "INPUT",        NULL }, 
1874     { "OUTPUT",       NULL }, 
1875     { "GETATTR",      cmd_getattr },
1876     { "SETATTR",      cmd_setattr },
1877     { "WRITECERT",    cmd_writecert },
1878     { "WRITEKEY",     cmd_writekey },
1879     { "GENKEY",       cmd_genkey },
1880     { "RANDOM",       cmd_random },
1881     { "PASSWD",       cmd_passwd },
1882     { "CHECKPIN",     cmd_checkpin },
1883     { "LOCK",         cmd_lock },
1884     { "UNLOCK",       cmd_unlock },
1885     { "GETINFO",      cmd_getinfo },
1886     { "RESTART",      cmd_restart },
1887     { "DISCONNECT",   cmd_disconnect },
1888     { "APDU",         cmd_apdu },
1889     { "KILLSCD",      cmd_killscd },
1890     { NULL }
1891   };
1892   int i, rc;
1893
1894   for (i=0; table[i].name; i++)
1895     {
1896       rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1897       if (rc)
1898         return rc;
1899     } 
1900   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1901
1902   assuan_register_reset_notify (ctx, reset_notify);
1903   assuan_register_option_handler (ctx, option_handler);
1904   return 0;
1905 }
1906
1907
1908 /* Startup the server.  If FD is given as -1 this is simple pipe
1909    server, otherwise it is a regular server.  Returns true if there
1910    are no more active asessions.  */
1911 int
1912 scd_command_handler (ctrl_t ctrl, int fd)
1913 {
1914   int rc;
1915   assuan_context_t ctx;
1916   int stopme;
1917   
1918   if (fd == -1)
1919     {
1920       int filedes[2];
1921
1922       filedes[0] = 0;
1923       filedes[1] = 1;
1924       rc = assuan_init_pipe_server (&ctx, filedes);
1925     }
1926   else
1927     {
1928       rc = assuan_init_socket_server_ext (&ctx, INT2FD(fd), 2);
1929     }
1930   if (rc)
1931     {
1932       log_error ("failed to initialize the server: %s\n",
1933                  gpg_strerror(rc));
1934       scd_exit (2);
1935     }
1936   rc = register_commands (ctx);
1937   if (rc)
1938     {
1939       log_error ("failed to register commands with Assuan: %s\n",
1940                  gpg_strerror(rc));
1941       scd_exit (2);
1942     }
1943   assuan_set_pointer (ctx, ctrl);
1944
1945   /* Allocate and initialize the server object.  Put it into the list
1946      of active sessions. */
1947   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1948   ctrl->server_local->next_session = session_list;
1949   session_list = ctrl->server_local;
1950   ctrl->server_local->ctrl_backlink = ctrl;
1951   ctrl->server_local->assuan_ctx = ctx;
1952
1953   if (DBG_ASSUAN)
1954     assuan_set_log_stream (ctx, log_get_stream ());
1955
1956   /* We open the reader right at startup so that the ticker is able to
1957      update the status file. */
1958   if (ctrl->reader_slot == -1)
1959     {
1960       ctrl->reader_slot = get_reader_slot ();
1961     }
1962
1963   /* Command processing loop. */
1964   for (;;)
1965     {
1966       rc = assuan_accept (ctx);
1967       if (rc == -1)
1968         {
1969           break;
1970         }
1971       else if (rc)
1972         {
1973           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1974           break;
1975         }
1976       
1977       rc = assuan_process (ctx);
1978       if (rc)
1979         {
1980           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1981           continue;
1982         }
1983     }
1984
1985   /* Cleanup.  We don't send an explicit reset to the card.  */
1986   do_reset (ctrl, 0); 
1987
1988   /* Release the server object.  */
1989   if (session_list == ctrl->server_local)
1990     session_list = ctrl->server_local->next_session;
1991   else
1992     {
1993       struct server_local_s *sl;
1994       
1995       for (sl=session_list; sl->next_session; sl = sl->next_session)
1996         if (sl->next_session == ctrl->server_local)
1997           break;
1998       if (!sl->next_session)
1999           BUG ();
2000       sl->next_session = ctrl->server_local->next_session;
2001     }
2002   stopme = ctrl->server_local->stopme;
2003   xfree (ctrl->server_local);
2004   ctrl->server_local = NULL;
2005
2006   /* Release the Assuan context.  */
2007   assuan_deinit_server (ctx);
2008
2009   if (stopme)
2010     scd_exit (0);
2011
2012   /* If there are no more sessions return true.  */
2013   return !session_list;
2014 }
2015
2016
2017 /* Send a line with status information via assuan and escape all given
2018    buffers. The variable elements are pairs of (char *, size_t),
2019    terminated with a (NULL, 0). */
2020 void
2021 send_status_info (ctrl_t ctrl, const char *keyword, ...)
2022 {
2023   va_list arg_ptr;
2024   const unsigned char *value;
2025   size_t valuelen;
2026   char buf[950], *p;
2027   size_t n;
2028   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2029   
2030   va_start (arg_ptr, keyword);
2031
2032   p = buf; 
2033   n = 0;
2034   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
2035     {
2036       valuelen = va_arg (arg_ptr, size_t);
2037       if (!valuelen)
2038         continue; /* empty buffer */
2039       if (n)
2040         {
2041           *p++ = ' ';
2042           n++;
2043         }
2044       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2045         {
2046           if (*value < ' ' || *value == '+')
2047             {
2048               sprintf (p, "%%%02X", *value);
2049               p += 3;
2050             }
2051           else if (*value == ' ')
2052             *p++ = '+';
2053           else
2054             *p++ = *value;
2055         }
2056     }
2057   *p = 0;
2058   assuan_write_status (ctx, keyword, buf);
2059
2060   va_end (arg_ptr);
2061 }
2062
2063
2064 /* Send a ready formatted status line via assuan.  */
2065 void
2066 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2067 {
2068   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2069
2070   if (strchr (args, '\n'))
2071     log_error ("error: LF detected in status line - not sending\n");
2072   else
2073     assuan_write_status (ctx, keyword, args);
2074 }
2075
2076
2077 /* Helper to send the clients a status change notification.  */
2078 static void
2079 send_client_notifications (void)
2080 {
2081   struct {
2082     pid_t pid; 
2083 #ifdef HAVE_W32_SYSTEM
2084     HANDLE handle;
2085 #else
2086     int signo; 
2087 #endif
2088   } killed[50];
2089   int killidx = 0;
2090   int kidx;
2091   struct server_local_s *sl;
2092   
2093   for (sl=session_list; sl; sl = sl->next_session)
2094     {
2095       if (sl->event_signal && sl->assuan_ctx)
2096         {
2097           pid_t pid = assuan_get_pid (sl->assuan_ctx);
2098 #ifdef HAVE_W32_SYSTEM
2099           HANDLE handle = (void *)sl->event_signal;
2100           
2101           for (kidx=0; kidx < killidx; kidx++)
2102             if (killed[kidx].pid == pid 
2103                 && killed[kidx].handle == handle)
2104               break;
2105           if (kidx < killidx)
2106             log_info ("event %lx (%p) already triggered for client %d\n",
2107                       sl->event_signal, handle, (int)pid);
2108           else
2109             {
2110               log_info ("triggering event %lx (%p) for client %d\n",
2111                         sl->event_signal, handle, (int)pid);
2112               if (!SetEvent (handle))
2113                 log_error ("SetEvent(%lx) failed: %s\n",
2114                            sl->event_signal, w32_strerror (-1));
2115               if (killidx < DIM (killed))
2116                 {
2117                   killed[killidx].pid = pid;
2118                   killed[killidx].handle = handle;
2119                   killidx++;
2120                 }
2121             }
2122 #else /*!HAVE_W32_SYSTEM*/
2123           int signo = sl->event_signal;
2124           
2125           if (pid != (pid_t)(-1) && pid && signo > 0)
2126             {
2127               for (kidx=0; kidx < killidx; kidx++)
2128                 if (killed[kidx].pid == pid 
2129                     && killed[kidx].signo == signo)
2130                   break;
2131               if (kidx < killidx)
2132                 log_info ("signal %d already sent to client %d\n",
2133                           signo, (int)pid);
2134               else
2135                 {
2136                   log_info ("sending signal %d to client %d\n",
2137                             signo, (int)pid);
2138                   kill (pid, signo);
2139                   if (killidx < DIM (killed))
2140                     {
2141                       killed[killidx].pid = pid;
2142                       killed[killidx].signo = signo;
2143                       killidx++;
2144                     }
2145                 }
2146             }
2147 #endif /*!HAVE_W32_SYSTEM*/
2148         }
2149     }
2150 }
2151
2152
2153
2154 /* This is the core of scd_update_reader_status_file but the caller
2155    needs to take care of the locking.  */
2156 static void
2157 update_reader_status_file (int set_card_removed_flag)
2158 {
2159   int idx;
2160   unsigned int status, changed;
2161
2162   /* Make sure that the reader has been opened.  Like get_reader_slot,
2163      this part of the code assumes that there is only one reader.  */
2164   if (!slot_table[0].valid)
2165     (void)get_reader_slot ();
2166
2167   /* Note, that we only try to get the status, because it does not
2168      make sense to wait here for a operation to complete.  If we are
2169      busy working with a card, delays in the status file update should
2170      be acceptable. */
2171   for (idx=0; idx < DIM(slot_table); idx++)
2172     {
2173       struct slot_status_s *ss = slot_table + idx;
2174       struct server_local_s *sl;
2175       int sw_apdu;
2176
2177       if (!ss->valid || ss->slot == -1)
2178         continue; /* Not valid or reader not yet open. */
2179       
2180       sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed);
2181       if (sw_apdu)
2182         {
2183           /* Get status failed.  Ignore that.  */
2184           continue; 
2185         }
2186
2187       if (!ss->any || ss->status != status || ss->changed != changed )
2188         {
2189           char *fname;
2190           char templ[50];
2191           FILE *fp;
2192
2193           log_info ("updating slot %d status: 0x%04X->0x%04X (%u->%u)\n",
2194                     ss->slot, ss->status, status, ss->changed, changed);
2195           ss->status = status;
2196           ss->changed = changed;
2197
2198           /* FIXME: Should this be IDX instead of ss->slot?  This
2199              depends on how client sessions will associate the reader
2200              status with their session.  */
2201           snprintf (templ, sizeof templ, "reader_%d.status", ss->slot);
2202           fname = make_filename (opt.homedir, templ, NULL );
2203           fp = fopen (fname, "w");
2204           if (fp)
2205             {
2206               fprintf (fp, "%s\n",
2207                        (status & 1)? "USABLE":
2208                        (status & 4)? "ACTIVE":
2209                        (status & 2)? "PRESENT": "NOCARD");
2210               fclose (fp);
2211             }
2212           xfree (fname);
2213             
2214           /* If a status script is executable, run it. */
2215           {
2216             const char *args[9], *envs[2];
2217             char numbuf1[30], numbuf2[30], numbuf3[30];
2218             char *homestr, *envstr;
2219             gpg_error_t err;
2220             
2221             homestr = make_filename (opt.homedir, NULL);
2222             if (estream_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
2223               log_error ("out of core while building environment\n");
2224             else
2225               {
2226                 envs[0] = envstr;
2227                 envs[1] = NULL;
2228
2229                 sprintf (numbuf1, "%d", ss->slot);
2230                 sprintf (numbuf2, "0x%04X", ss->status);
2231                 sprintf (numbuf3, "0x%04X", status);
2232                 args[0] = "--reader-port";
2233                 args[1] = numbuf1; 
2234                 args[2] = "--old-code";
2235                 args[3] = numbuf2;  
2236                 args[4] = "--new-code";
2237                 args[5] = numbuf3; 
2238                 args[6] = "--status";
2239                 args[7] = ((status & 1)? "USABLE":
2240                            (status & 4)? "ACTIVE":
2241                            (status & 2)? "PRESENT": "NOCARD");
2242                 args[8] = NULL;  
2243
2244                 fname = make_filename (opt.homedir, "scd-event", NULL);
2245                 err = gnupg_spawn_process_detached (fname, args, envs);
2246                 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
2247                   log_error ("failed to run event handler `%s': %s\n",
2248                              fname, gpg_strerror (err));
2249                 xfree (fname);
2250                 xfree (envstr);
2251               }
2252             xfree (homestr);
2253           }
2254
2255           /* Set the card removed flag for all current sessions.  We
2256              will set this on any card change because a reset or
2257              SERIALNO request must be done in any case.  */
2258           if (ss->any && set_card_removed_flag)
2259             update_card_removed (idx, 1);
2260           
2261           ss->any = 1;
2262
2263           /* Send a signal to all clients who applied for it.  */
2264           send_client_notifications ();
2265         }
2266       
2267       /* Check whether a disconnect is pending.  */
2268       if (opt.card_timeout)
2269         {
2270           for (sl=session_list; sl; sl = sl->next_session)
2271             if (!sl->disconnect_allowed)
2272               break; 
2273           if (session_list && !sl)
2274             {
2275               /* FIXME: Use a real timeout.  */
2276               /* At least one connection and all allow a disconnect.  */
2277               log_info ("disconnecting card in slot %d\n", ss->slot);
2278               apdu_disconnect (ss->slot);
2279             }
2280         }
2281       
2282     }
2283 }
2284
2285 /* This function is called by the ticker thread to check for changes
2286    of the reader stati.  It updates the reader status files and if
2287    requested by the caller also send a signal to the caller.  */
2288 void
2289 scd_update_reader_status_file (void)
2290 {
2291   if (!pth_mutex_acquire (&status_file_update_lock, 1, NULL))
2292     return; /* locked - give up. */
2293   update_reader_status_file (1);
2294   if (!pth_mutex_release (&status_file_update_lock))
2295     log_error ("failed to release status_file_update lock\n");
2296 }