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