Signing using Netkey 3 cards does now work.
[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 (e.g. DINSIG)
600
601    For certain cards, more information will be returned:
602
603      S KEY-FPR <no> <hexstring>
604
605    For OpenPGP cards this returns the stored fingerprints of the
606    keys. This can be used check whether a key is available on the
607    card.  NO may be 1, 2 or 3.
608
609      S CA-FPR <no> <hexstring>
610
611    Similar to above, these are the fingerprints of keys assumed to be
612    ultimately trusted.
613
614      S DISP-NAME <name_of_card_holder>
615
616    The name of the card holder as stored on the card; percent
617    escaping takes place, spaces are encoded as '+'
618
619      S PUBKEY-URL <url>
620
621    The URL to be used for locating the entire public key.
622      
623    Note, that this function may even be used on a locked card.
624 */
625 static int
626 cmd_learn (assuan_context_t ctx, char *line)
627 {
628   ctrl_t ctrl = assuan_get_pointer (ctx);
629   int rc = 0;
630   int only_keypairinfo = has_option (line, "--keypairinfo");
631
632   if ((rc = open_card (ctrl, NULL)))
633     return rc;
634
635   /* Unless the force option is used we try a shortcut by identifying
636      the card using a serial number and inquiring the client with
637      that. The client may choose to cancel the operation if he already
638      knows about this card */
639   if (!only_keypairinfo)
640     {
641       char *serial_and_stamp;
642       char *serial;
643       time_t stamp;
644       
645       rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
646       if (rc)
647         return rc;
648       rc = estream_asprintf (&serial_and_stamp, "%s %lu",
649                              serial, (unsigned long)stamp);
650       xfree (serial);
651       if (rc < 0)
652         return out_of_core ();
653       rc = 0;
654       assuan_write_status (ctx, "SERIALNO", serial_and_stamp);
655       
656       if (!has_option (line, "--force"))
657         {
658           char *command;
659           
660           rc = estream_asprintf (&command, "KNOWNCARDP %s", serial_and_stamp);
661           if (rc < 0)
662             {
663               xfree (serial_and_stamp);
664               return out_of_core ();
665             }
666           rc = 0;
667           rc = assuan_inquire (ctx, command, NULL, NULL, 0); 
668           xfree (command);
669           if (rc)
670             {
671               if (gpg_err_code (rc) != GPG_ERR_ASS_CANCELED)
672                 log_error ("inquire KNOWNCARDP failed: %s\n",
673                            gpg_strerror (rc));
674               xfree (serial_and_stamp);
675               return rc; 
676             }
677           /* Not canceled, so we have to proceeed.  */
678         }
679       xfree (serial_and_stamp);
680     }
681   
682   /* Let the application print out its collection of useful status
683      information. */
684   if (!rc)
685     rc = app_write_learn_status (ctrl->app_ctx, ctrl, only_keypairinfo);
686
687   TEST_CARD_REMOVAL (ctrl, rc);
688   return rc;
689 }
690
691
692 \f
693 /* READCERT <hexified_certid>|<keyid>
694
695    Note, that this function may even be used on a locked card.
696  */
697 static int
698 cmd_readcert (assuan_context_t ctx, char *line)
699 {
700   ctrl_t ctrl = assuan_get_pointer (ctx);
701   int rc;
702   unsigned char *cert;
703   size_t ncert;
704
705   if ((rc = open_card (ctrl, NULL)))
706     return rc;
707
708   line = xstrdup (line); /* Need a copy of the line. */
709   rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
710   if (rc)
711     log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
712   xfree (line);
713   line = NULL;
714   if (!rc)
715     {
716       rc = assuan_send_data (ctx, cert, ncert);
717       xfree (cert);
718       if (rc)
719         return rc;
720     }
721
722   TEST_CARD_REMOVAL (ctrl, rc);
723   return rc;
724 }
725
726
727 /* READKEY <keyid>
728
729    Return the public key for the given cert or key ID as an standard
730    S-Expression.
731
732    Note, that this function may even be used on a locked card.
733   */
734 static int
735 cmd_readkey (assuan_context_t ctx, char *line)
736 {
737   ctrl_t ctrl = assuan_get_pointer (ctx);
738   int rc;
739   unsigned char *cert = NULL;
740   size_t ncert, n;
741   ksba_cert_t kc = NULL;
742   ksba_sexp_t p;
743   unsigned char *pk;
744   size_t pklen;
745
746   if ((rc = open_card (ctrl, NULL)))
747     return rc;
748
749   line = xstrdup (line); /* Need a copy of the line. */
750   /* If the application supports the READKEY function we use that.
751      Otherwise we use the old way by extracting it from the
752      certificate.  */
753   rc = app_readkey (ctrl->app_ctx, line, &pk, &pklen);
754   if (!rc)
755     { /* Yeah, got that key - send it back.  */
756       rc = assuan_send_data (ctx, pk, pklen);
757       xfree (pk);
758       xfree (line);
759       line = NULL;
760       goto leave;
761     }
762
763   if (gpg_err_code (rc) != GPG_ERR_UNSUPPORTED_OPERATION)
764     log_error ("app_readkey failed: %s\n", gpg_strerror (rc));
765   else  
766     {
767       rc = app_readcert (ctrl->app_ctx, line, &cert, &ncert);
768       if (rc)
769         log_error ("app_readcert failed: %s\n", gpg_strerror (rc));
770     }
771   xfree (line);
772   line = NULL;
773   if (rc)
774     goto leave;
775       
776   rc = ksba_cert_new (&kc);
777   if (rc)
778     {
779       xfree (cert);
780       goto leave;
781     }
782   rc = ksba_cert_init_from_mem (kc, cert, ncert);
783   if (rc)
784     {
785       log_error ("failed to parse the certificate: %s\n", gpg_strerror (rc));
786       goto leave;
787     }
788
789   p = ksba_cert_get_public_key (kc);
790   if (!p)
791     {
792       rc = gpg_error (GPG_ERR_NO_PUBKEY);
793       goto leave;
794     }
795
796   n = gcry_sexp_canon_len (p, 0, NULL, NULL);
797   rc = assuan_send_data (ctx, p, n);
798   xfree (p);
799
800
801  leave:
802   ksba_cert_release (kc);
803   xfree (cert);
804   TEST_CARD_REMOVAL (ctrl, rc);
805   return rc;
806 }
807
808
809 \f
810
811 /* SETDATA <hexstring> 
812
813    The client should use this command to tell us the data he want to
814    sign.  */
815 static int
816 cmd_setdata (assuan_context_t ctx, char *line)
817 {
818   ctrl_t ctrl = assuan_get_pointer (ctx);
819   int n;
820   char *p;
821   unsigned char *buf;
822
823   if (locked_session && locked_session != ctrl->server_local)
824     return gpg_error (GPG_ERR_LOCKED);
825
826   /* Parse the hexstring. */
827   for (p=line,n=0; hexdigitp (p); p++, n++)
828     ;
829   if (*p)
830     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring");
831   if (!n)
832     return set_error (GPG_ERR_ASS_PARAMETER, "no data given");
833   if ((n&1))
834     return set_error (GPG_ERR_ASS_PARAMETER, "odd number of digits");
835   n /= 2;
836   buf = xtrymalloc (n);
837   if (!buf)
838     return out_of_core ();
839
840   ctrl->in_data.value = buf;
841   ctrl->in_data.valuelen = n;
842   for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++)
843     buf[n] = xtoi_2 (p);
844   return 0;
845 }
846
847
848
849 static gpg_error_t 
850 pin_cb (void *opaque, const char *info, char **retstr)
851 {
852   assuan_context_t ctx = opaque;
853   char *command;
854   int rc;
855   unsigned char *value;
856   size_t valuelen;
857
858   if (!retstr)
859     {
860       /* We prompt for keypad entry.  To make sure that the popup has
861          been show we use an inquire and not just a status message.
862          We ignore any value returned.  */
863       if (info)
864         {
865           log_debug ("prompting for keypad entry '%s'\n", info);
866           rc = estream_asprintf (&command, "POPUPKEYPADPROMPT %s", info);
867           if (rc < 0)
868             return gpg_error (gpg_err_code_from_errno (errno));
869           rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); 
870           xfree (command);  
871         }
872       else
873         {
874           log_debug ("dismiss keypad entry prompt\n");
875           rc = assuan_inquire (ctx, "DISMISSKEYPADPROMPT",
876                                &value, &valuelen, MAXLEN_PIN); 
877         }
878       if (!rc)
879         xfree (value);
880       return rc;
881     }
882
883   *retstr = NULL;
884   log_debug ("asking for PIN '%s'\n", info);
885
886   rc = estream_asprintf (&command, "NEEDPIN %s", info);
887   if (rc < 0)
888     return gpg_error (gpg_err_code_from_errno (errno));
889
890   /* Fixme: Write an inquire function which returns the result in
891      secure memory and check all further handling of the PIN. */
892   rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); 
893   xfree (command);  
894   if (rc)
895     return rc;
896
897   if (!valuelen || value[valuelen-1])
898     {
899       /* We require that the returned value is an UTF-8 string */
900       xfree (value);
901       return gpg_error (GPG_ERR_INV_RESPONSE);
902     }
903   *retstr = (char*)value;
904   return 0;
905 }
906
907
908 /* PKSIGN [--hash=[rmd160|sha{1,224,256,384,512}|md5]] <hexified_id>
909
910    The --hash option is optional; the default is SHA1.
911
912  */
913 static int
914 cmd_pksign (assuan_context_t ctx, char *line)
915 {
916   ctrl_t ctrl = assuan_get_pointer (ctx);
917   int rc;
918   unsigned char *outdata;
919   size_t outdatalen;
920   char *keyidstr;
921   int hash_algo;
922
923   if (has_option (line, "--hash=rmd160"))
924     hash_algo = GCRY_MD_RMD160;
925   else if (has_option (line, "--hash=sha1"))
926     hash_algo = GCRY_MD_SHA1;
927   else if (has_option (line, "--hash=sha224"))
928     hash_algo = GCRY_MD_SHA224;
929   else if (has_option (line, "--hash=sha256"))
930     hash_algo = GCRY_MD_SHA256;
931   else if (has_option (line, "--hash=sha384"))
932     hash_algo = GCRY_MD_SHA384;
933   else if (has_option (line, "--hash=sha512"))
934     hash_algo = GCRY_MD_SHA512;
935   else if (has_option (line, "--hash=md5"))
936     hash_algo = GCRY_MD_MD5;
937   else if (!strstr (line, "--"))
938     hash_algo = GCRY_MD_SHA1; 
939   else
940     return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm");
941
942   line = skip_options (line);
943
944   if ( IS_LOCKED (ctrl) )
945     return gpg_error (GPG_ERR_LOCKED);
946
947   if ((rc = open_card (ctrl, NULL)))
948     return rc;
949
950   /* We have to use a copy of the key ID because the function may use
951      the pin_cb which in turn uses the assuan line buffer and thus
952      overwriting the original line with the keyid */
953   keyidstr = xtrystrdup (line);
954   if (!keyidstr)
955     return out_of_core ();
956   
957   rc = app_sign (ctrl->app_ctx,
958                  keyidstr, hash_algo,
959                  pin_cb, ctx,
960                  ctrl->in_data.value, ctrl->in_data.valuelen,
961                  &outdata, &outdatalen);
962
963   xfree (keyidstr);
964   if (rc)
965     {
966       log_error ("card_sign failed: %s\n", gpg_strerror (rc));
967     }
968   else
969     {
970       rc = assuan_send_data (ctx, outdata, outdatalen);
971       xfree (outdata);
972       if (rc)
973         return rc; /* that is already an assuan error code */
974     }
975
976   TEST_CARD_REMOVAL (ctrl, rc);
977   return rc;
978 }
979
980 /* PKAUTH <hexified_id>
981
982  */
983 static int
984 cmd_pkauth (assuan_context_t ctx, char *line)
985 {
986   ctrl_t ctrl = assuan_get_pointer (ctx);
987   int rc;
988   unsigned char *outdata;
989   size_t outdatalen;
990   char *keyidstr;
991
992   if ( IS_LOCKED (ctrl) )
993     return gpg_error (GPG_ERR_LOCKED);
994
995   if ((rc = open_card (ctrl, NULL)))
996     return rc;
997
998   if (!ctrl->app_ctx)
999     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1000
1001  /* We have to use a copy of the key ID because the function may use
1002      the pin_cb which in turn uses the assuan line buffer and thus
1003      overwriting the original line with the keyid */
1004   keyidstr = xtrystrdup (line);
1005   if (!keyidstr)
1006     return out_of_core ();
1007   
1008   rc = app_auth (ctrl->app_ctx,
1009                  keyidstr,
1010                  pin_cb, ctx,
1011                  ctrl->in_data.value, ctrl->in_data.valuelen,
1012                  &outdata, &outdatalen);
1013   xfree (keyidstr);
1014   if (rc)
1015     {
1016       log_error ("app_auth_sign failed: %s\n", gpg_strerror (rc));
1017     }
1018   else
1019     {
1020       rc = assuan_send_data (ctx, outdata, outdatalen);
1021       xfree (outdata);
1022       if (rc)
1023         return rc; /* that is already an assuan error code */
1024     }
1025
1026   TEST_CARD_REMOVAL (ctrl, rc);
1027   return rc;
1028 }
1029
1030 /* PKDECRYPT <hexified_id>
1031
1032  */
1033 static int
1034 cmd_pkdecrypt (assuan_context_t ctx, char *line)
1035 {
1036   ctrl_t ctrl = assuan_get_pointer (ctx);
1037   int rc;
1038   unsigned char *outdata;
1039   size_t outdatalen;
1040   char *keyidstr;
1041
1042   if ( IS_LOCKED (ctrl) )
1043     return gpg_error (GPG_ERR_LOCKED);
1044
1045   if ((rc = open_card (ctrl, NULL)))
1046     return rc;
1047
1048   keyidstr = xtrystrdup (line);
1049   if (!keyidstr)
1050     return out_of_core ();
1051   rc = app_decipher (ctrl->app_ctx,
1052                      keyidstr, 
1053                      pin_cb, ctx,
1054                      ctrl->in_data.value, ctrl->in_data.valuelen,
1055                      &outdata, &outdatalen);
1056
1057   xfree (keyidstr);
1058   if (rc)
1059     {
1060       log_error ("card_create_signature failed: %s\n", gpg_strerror (rc));
1061     }
1062   else
1063     {
1064       rc = assuan_send_data (ctx, outdata, outdatalen);
1065       xfree (outdata);
1066       if (rc)
1067         return rc; /* that is already an assuan error code */
1068     }
1069
1070   TEST_CARD_REMOVAL (ctrl, rc);
1071   return rc;
1072 }
1073
1074
1075 /* GETATTR <name>
1076
1077    This command is used to retrieve data from a smartcard.  The
1078    allowed names depend on the currently selected smartcard
1079    application.  NAME must be percent and '+' escaped.  The value is
1080    returned through status message, see the LEARN command for details.
1081
1082    However, the current implementation assumes that Name is not escaped;
1083    this works as long as noone uses arbitrary escaping. 
1084  
1085    Note, that this function may even be used on a locked card.
1086 */
1087 static int
1088 cmd_getattr (assuan_context_t ctx, char *line)
1089 {
1090   ctrl_t ctrl = assuan_get_pointer (ctx);
1091   int rc;
1092   const char *keyword;
1093
1094   if ((rc = open_card (ctrl, NULL)))
1095     return rc;
1096
1097   keyword = line;
1098   for (; *line && !spacep (line); line++)
1099     ;
1100   if (*line)
1101       *line++ = 0;
1102
1103   /* (We ignore any garbage for now.) */
1104
1105   /* FIXME: Applications should not return sensitive data if the card
1106      is locked.  */
1107   rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
1108
1109   TEST_CARD_REMOVAL (ctrl, rc);
1110   return rc;
1111 }
1112
1113
1114 /* SETATTR <name> <value> 
1115
1116    This command is used to store data on a a smartcard.  The allowed
1117    names and values are depend on the currently selected smartcard
1118    application.  NAME and VALUE must be percent and '+' escaped.
1119
1120    However, the current implementation assumes that NAME is not
1121    escaped; this works as long as noone uses arbitrary escaping.
1122  
1123    A PIN will be requested for most NAMEs.  See the corresponding
1124    setattr function of the actually used application (app-*.c) for
1125    details.  */
1126 static int
1127 cmd_setattr (assuan_context_t ctx, char *orig_line)
1128 {
1129   ctrl_t ctrl = assuan_get_pointer (ctx);
1130   int rc;
1131   char *keyword;
1132   int keywordlen;
1133   size_t nbytes;
1134   char *line, *linebuf;
1135
1136   if ( IS_LOCKED (ctrl) )
1137     return gpg_error (GPG_ERR_LOCKED);
1138
1139   if ((rc = open_card (ctrl, NULL)))
1140     return rc;
1141
1142   /* We need to use a copy of LINE, because PIN_CB uses the same
1143      context and thus reuses the Assuan provided LINE. */
1144   line = linebuf = xtrystrdup (orig_line);
1145   if (!line)
1146     return out_of_core ();
1147
1148   keyword = line;
1149   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1150     ;
1151   if (*line)
1152       *line++ = 0;
1153   while (spacep (line))
1154     line++;
1155   nbytes = percent_plus_unescape ((unsigned char*)line);
1156
1157   rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx,
1158                     (const unsigned char*)line, nbytes);
1159   xfree (linebuf);
1160
1161   TEST_CARD_REMOVAL (ctrl, rc);
1162   return rc;
1163 }
1164
1165
1166
1167 /* WRITECERT <hexified_certid>
1168
1169    This command is used to store a certifciate on a smartcard.  The
1170    allowed certids depend on the currently selected smartcard
1171    application. The actual certifciate is requested using the inquiry
1172    "CERTDATA" and needs to be provided in its raw (e.g. DER) form.
1173
1174    In almost all cases a a PIN will be requested.  See the related
1175    writecert function of the actually used application (app-*.c) for
1176    details.  */
1177 static int
1178 cmd_writecert (assuan_context_t ctx, char *line)
1179 {
1180   ctrl_t ctrl = assuan_get_pointer (ctx);
1181   int rc;
1182   char *certid;
1183   unsigned char *certdata;
1184   size_t certdatalen;
1185
1186   if ( IS_LOCKED (ctrl) )
1187     return gpg_error (GPG_ERR_LOCKED);
1188
1189   line = skip_options (line);
1190
1191   if (!*line)
1192     return set_error (GPG_ERR_ASS_PARAMETER, "no certid given");
1193   certid = line;
1194   while (*line && !spacep (line))
1195     line++;
1196   *line = 0;
1197
1198   if ((rc = open_card (ctrl, NULL)))
1199     return rc;
1200
1201   if (!ctrl->app_ctx)
1202     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1203
1204   certid = xtrystrdup (certid);
1205   if (!certid)
1206     return out_of_core ();
1207
1208   /* Now get the actual keydata. */
1209   rc = assuan_inquire (ctx, "CERTDATA",
1210                        &certdata, &certdatalen, MAXLEN_CERTDATA);
1211   if (rc)
1212     {
1213       xfree (certid);
1214       return rc;
1215     }
1216
1217   /* Write the certificate to the card. */
1218   rc = app_writecert (ctrl->app_ctx, ctrl, certid, 
1219                       pin_cb, ctx, certdata, certdatalen);
1220   xfree (certid);
1221   xfree (certdata);
1222
1223   TEST_CARD_REMOVAL (ctrl, rc);
1224   return rc;
1225 }
1226
1227
1228
1229 /* WRITEKEY [--force] <keyid> 
1230
1231    This command is used to store a secret key on a a smartcard.  The
1232    allowed keyids depend on the currently selected smartcard
1233    application. The actual keydata is requested using the inquiry
1234    "KEYDATA" and need to be provided without any protection.  With
1235    --force set an existing key under this KEYID will get overwritten.
1236    The keydata is expected to be the usual canonical encoded
1237    S-expression.
1238
1239    A PIN will be requested for most NAMEs.  See the corresponding
1240    writekey function of the actually used application (app-*.c) for
1241    details.  */
1242 static int
1243 cmd_writekey (assuan_context_t ctx, char *line)
1244 {
1245   ctrl_t ctrl = assuan_get_pointer (ctx);
1246   int rc;
1247   char *keyid;
1248   int force = has_option (line, "--force");
1249   unsigned char *keydata;
1250   size_t keydatalen;
1251
1252   if ( IS_LOCKED (ctrl) )
1253     return gpg_error (GPG_ERR_LOCKED);
1254
1255   line = skip_options (line);
1256
1257   if (!*line)
1258     return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given");
1259   keyid = line;
1260   while (*line && !spacep (line))
1261     line++;
1262   *line = 0;
1263
1264   if ((rc = open_card (ctrl, NULL)))
1265     return rc;
1266
1267   if (!ctrl->app_ctx)
1268     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1269
1270   keyid = xtrystrdup (keyid);
1271   if (!keyid)
1272     return out_of_core ();
1273
1274   /* Now get the actual keydata. */
1275   assuan_begin_confidential (ctx);
1276   rc = assuan_inquire (ctx, "KEYDATA", &keydata, &keydatalen, MAXLEN_KEYDATA);
1277   assuan_end_confidential (ctx);
1278   if (rc)
1279     {
1280       xfree (keyid);
1281       return rc;
1282     }
1283
1284   /* Write the key to the card. */
1285   rc = app_writekey (ctrl->app_ctx, ctrl, keyid, force? 1:0,
1286                      pin_cb, ctx, keydata, keydatalen);
1287   xfree (keyid);
1288   xfree (keydata);
1289
1290   TEST_CARD_REMOVAL (ctrl, rc);
1291   return rc;
1292 }
1293
1294
1295
1296 /* GENKEY [--force] [--timestamp=<isodate>] <no>
1297
1298    Generate a key on-card identified by NO, which is application
1299    specific.  Return values are application specific.  For OpenPGP
1300    cards 2 status lines are returned:
1301
1302      S KEY-FPR  <hexstring>
1303      S KEY-CREATED-AT <seconds_since_epoch>
1304      S KEY-DATA [p|n] <hexdata>
1305      
1306    --force is required to overwrite an already existing key.  The
1307    KEY-CREATED-AT is required for further processing because it is
1308    part of the hashed key material for the fingerprint.
1309
1310    If --timestamp is given an OpenPGP key will be created using this
1311    value.  The value needs to be in ISO Format; e.g.
1312    "--timestamp=20030316T120000" and after 1970-01-01 00:00:00.
1313
1314    The public part of the key can also later be retrieved using the
1315    READKEY command.
1316
1317  */
1318 static int
1319 cmd_genkey (assuan_context_t ctx, char *line)
1320 {
1321   ctrl_t ctrl = assuan_get_pointer (ctx);
1322   int rc;
1323   char *keyno;
1324   int force;
1325   const char *s;
1326   time_t timestamp;
1327
1328   if ( IS_LOCKED (ctrl) )
1329     return gpg_error (GPG_ERR_LOCKED);
1330
1331   force = has_option (line, "--force");
1332
1333   if ((s=has_option_name (line, "--timestamp")))
1334     {
1335       if (*s != '=')
1336         return set_error (GPG_ERR_ASS_PARAMETER, "missing value for option");
1337       timestamp = isotime2epoch (s+1);
1338       if (timestamp < 1)
1339         return set_error (GPG_ERR_ASS_PARAMETER, "invalid time value");
1340     }
1341   else
1342     timestamp = 0;
1343
1344
1345   line = skip_options (line);
1346   if (!*line)
1347     return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
1348   keyno = line;
1349   while (*line && !spacep (line))
1350     line++;
1351   *line = 0;
1352
1353   if ((rc = open_card (ctrl, NULL)))
1354     return rc;
1355
1356   if (!ctrl->app_ctx)
1357     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1358
1359   keyno = xtrystrdup (keyno);
1360   if (!keyno)
1361     return out_of_core ();
1362   rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0,
1363                    timestamp, pin_cb, ctx);
1364   xfree (keyno);
1365
1366   TEST_CARD_REMOVAL (ctrl, rc);
1367   return rc;
1368 }
1369
1370
1371 /* RANDOM <nbytes>
1372
1373    Get NBYTES of random from the card and send them back as data. 
1374
1375    Note, that this function may be even be used on a locked card.
1376 */
1377 static int
1378 cmd_random (assuan_context_t ctx, char *line)
1379 {
1380   ctrl_t ctrl = assuan_get_pointer (ctx);
1381   int rc;
1382   size_t nbytes;
1383   unsigned char *buffer;
1384
1385   if (!*line)
1386     return set_error (GPG_ERR_ASS_PARAMETER, "number of requested bytes missing");
1387   nbytes = strtoul (line, NULL, 0);
1388
1389   if ((rc = open_card (ctrl, NULL)))
1390     return rc;
1391
1392   if (!ctrl->app_ctx)
1393     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1394
1395   buffer = xtrymalloc (nbytes);
1396   if (!buffer)
1397     return out_of_core ();
1398
1399   rc = app_get_challenge (ctrl->app_ctx, nbytes, buffer);
1400   if (!rc)
1401     {
1402       rc = assuan_send_data (ctx, buffer, nbytes);
1403       xfree (buffer);
1404       return rc; /* that is already an assuan error code */
1405     }
1406   xfree (buffer);
1407
1408   TEST_CARD_REMOVAL (ctrl, rc);
1409   return rc;
1410 }
1411
1412 \f
1413 /* PASSWD [--reset] [--nullpin] <chvno>
1414   
1415    Change the PIN or, if --reset is given, reset the retry counter of
1416    the card holder verfication vector CHVNO.  The option --nullpin is
1417    used for TCOS cards to set the initial PIN.  The format of CHVNO
1418    depends on the card application.  */
1419 static int
1420 cmd_passwd (assuan_context_t ctx, char *line)
1421 {
1422   ctrl_t ctrl = assuan_get_pointer (ctx);
1423   int rc;
1424   char *chvnostr;
1425   unsigned int flags = 0;
1426
1427   if (has_option (line, "--reset"))
1428     flags |= APP_CHANGE_FLAG_RESET;
1429   if (has_option (line, "--nullpin"))
1430     flags |= APP_CHANGE_FLAG_NULLPIN;
1431
1432   if ( IS_LOCKED (ctrl) )
1433     return gpg_error (GPG_ERR_LOCKED);
1434
1435   line = skip_options (line);
1436
1437   if (!*line)
1438     return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given");
1439   chvnostr = line;
1440   while (*line && !spacep (line))
1441     line++;
1442   *line = 0;
1443
1444   if ((rc = open_card (ctrl, NULL)))
1445     return rc;
1446
1447   if (!ctrl->app_ctx)
1448     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1449   
1450   chvnostr = xtrystrdup (chvnostr);
1451   if (!chvnostr)
1452     return out_of_core ();
1453   rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx);
1454   if (rc)
1455     log_error ("command passwd failed: %s\n", gpg_strerror (rc));
1456   xfree (chvnostr);
1457
1458   TEST_CARD_REMOVAL (ctrl, rc);
1459   return rc;
1460 }
1461
1462
1463 /* CHECKPIN <idstr>
1464
1465    Perform a VERIFY operation without doing anything else.  This may
1466    be used to initialize a the PIN cache earlier to long lasting
1467    operations.  Its use is highly application dependent.
1468
1469    For OpenPGP:
1470
1471       Perform a simple verify operation for CHV1 and CHV2, so that
1472       further operations won't ask for CHV2 and it is possible to do a
1473       cheap check on the PIN: If there is something wrong with the PIN
1474       entry system, only the regular CHV will get blocked and not the
1475       dangerous CHV3.  IDSTR is the usual card's serial number in hex
1476       notation; an optional fingerprint part will get ignored.  There
1477       is however a special mode if the IDSTR is sffixed with the
1478       literal string "[CHV3]": In this case the Admin PIN is checked
1479       if and only if the retry counter is still at 3.
1480
1481    For Netkey:
1482
1483       Any of the valid PIN Ids may be used.  These are the strings:
1484
1485         PW1.CH       - Global password 1
1486         PW2.CH       - Global password 2
1487         PW1.CH.SIG   - SigG password 1
1488         PW2.CH.SIG   - SigG password 2
1489
1490       For a definitive list, see the implementation in app-nks.c.
1491       Note that we call a PW2.* PIN a "PUK" despite that since TCOS
1492       3.0 they are technically alternative PINs used to mutally
1493       unblock each other.
1494
1495  */
1496 static int
1497 cmd_checkpin (assuan_context_t ctx, char *line)
1498 {
1499   ctrl_t ctrl = assuan_get_pointer (ctx);
1500   int rc;
1501   char *idstr;
1502
1503   if ( IS_LOCKED (ctrl) )
1504     return gpg_error (GPG_ERR_LOCKED);
1505
1506   if ((rc = open_card (ctrl, NULL)))
1507     return rc;
1508
1509   if (!ctrl->app_ctx)
1510     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1511
1512   /* We have to use a copy of the key ID because the function may use
1513      the pin_cb which in turn uses the assuan line buffer and thus
1514      overwriting the original line with the keyid. */
1515   idstr = xtrystrdup (line);
1516   if (!idstr)
1517     return out_of_core ();
1518   
1519   rc = app_check_pin (ctrl->app_ctx, idstr, pin_cb, ctx);
1520   xfree (idstr);
1521   if (rc)
1522     log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
1523
1524   TEST_CARD_REMOVAL (ctrl, rc);
1525   return rc;
1526 }
1527
1528
1529 /* LOCK [--wait]
1530
1531    Grant exclusive card access to this session.  Note that there is
1532    no lock counter used and a second lock from the same session will
1533    be ignored.  A single unlock (or RESET) unlocks the session.
1534    Return GPG_ERR_LOCKED if another session has locked the reader.
1535
1536    If the option --wait is given the command will wait until a
1537    lock has been released.
1538  */
1539 static int
1540 cmd_lock (assuan_context_t ctx, char *line)
1541 {
1542   ctrl_t ctrl = assuan_get_pointer (ctx);
1543   int rc = 0;
1544
1545  retry:
1546   if (locked_session)
1547     {
1548       if (locked_session != ctrl->server_local)
1549         rc = gpg_error (GPG_ERR_LOCKED);
1550     }
1551   else
1552     locked_session = ctrl->server_local;
1553
1554 #ifdef USE_GNU_PTH
1555   if (rc && has_option (line, "--wait"))
1556     {
1557       rc = 0;
1558       pth_sleep (1); /* Better implement an event mechanism. However,
1559                         for card operations this should be
1560                         sufficient. */
1561       /* FIXME: Need to check that the connection is still alive.
1562          This can be done by issuing status messages. */
1563       goto retry;
1564     }
1565 #endif /*USE_GNU_PTH*/
1566   
1567   if (rc)
1568     log_error ("cmd_lock failed: %s\n", gpg_strerror (rc));
1569   return rc;
1570 }
1571
1572
1573 /* UNLOCK
1574
1575    Release exclusive card access.
1576  */
1577 static int
1578 cmd_unlock (assuan_context_t ctx, char *line)
1579 {
1580   ctrl_t ctrl = assuan_get_pointer (ctx);
1581   int rc = 0;
1582
1583   (void)line;
1584
1585   if (locked_session)
1586     {
1587       if (locked_session != ctrl->server_local)
1588         rc = gpg_error (GPG_ERR_LOCKED);
1589       else
1590         locked_session = NULL;
1591     }
1592   else
1593     rc = gpg_error (GPG_ERR_NOT_LOCKED);
1594
1595   if (rc)
1596     log_error ("cmd_unlock failed: %s\n", gpg_strerror (rc));
1597   return rc;
1598 }
1599
1600
1601 /* GETINFO <what>
1602
1603    Multi purpose command to return certain information.  
1604    Supported values of WHAT are:
1605
1606    version     - Return the version of the program.
1607    pid         - Return the process id of the server.
1608
1609    socket_name - Return the name of the socket.
1610
1611    status - Return the status of the current slot (in the future, may
1612    also return the status of all slots).  The status is a list of
1613    one-character flags.  The following flags are currently defined:
1614      'u'  Usable card present.  This is the normal state during operation.
1615      'r'  Card removed.  A reset is necessary.
1616    These flags are exclusive.
1617
1618    reader_list - Return a list of detected card readers.  Does
1619                  currently only work with the internal CCID driver.
1620
1621    deny_admin  - Returns OK if admin commands are not allowed or
1622                  GPG_ERR_GENERAL if admin commands are allowed.
1623
1624    app_list    - Return a list of supported applications.  One
1625                  application per line, fields delimited by colons,
1626                  first field is the name.
1627 */
1628
1629 static int
1630 cmd_getinfo (assuan_context_t ctx, char *line)
1631 {
1632   int rc = 0;
1633
1634   if (!strcmp (line, "version"))
1635     {
1636       const char *s = VERSION;
1637       rc = assuan_send_data (ctx, s, strlen (s));
1638     }
1639   else if (!strcmp (line, "pid"))
1640     {
1641       char numbuf[50];
1642
1643       snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
1644       rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
1645     }
1646   else if (!strcmp (line, "socket_name"))
1647     {
1648       const char *s = scd_get_socket_name ();
1649
1650       if (s)
1651         rc = assuan_send_data (ctx, s, strlen (s));
1652       else
1653         rc = gpg_error (GPG_ERR_NO_DATA);
1654     }
1655   else if (!strcmp (line, "status"))
1656     {
1657       ctrl_t ctrl = assuan_get_pointer (ctx);
1658       int slot = ctrl->reader_slot;
1659       char flag = 'r';
1660
1661       if (!ctrl->server_local->card_removed && slot != -1)
1662         {
1663           struct slot_status_s *ss;
1664           
1665           if (!(slot >= 0 && slot < DIM(slot_table)))
1666             BUG ();
1667
1668           ss = &slot_table[slot];
1669
1670           if (!ss->valid)
1671             BUG ();
1672
1673           if (ss->any && (ss->status & 1))
1674             flag = 'u';
1675         }
1676       rc = assuan_send_data (ctx, &flag, 1);
1677     }
1678   else if (!strcmp (line, "reader_list"))
1679     {
1680 #ifdef HAVE_LIBUSB
1681       char *s = ccid_get_reader_list ();
1682 #else
1683       char *s = NULL;
1684 #endif
1685       
1686       if (s)
1687         rc = assuan_send_data (ctx, s, strlen (s));
1688       else
1689         rc = gpg_error (GPG_ERR_NO_DATA);
1690       xfree (s);
1691     }
1692   else if (!strcmp (line, "deny_admin"))
1693     rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
1694   else if (!strcmp (line, "app_list"))
1695     {
1696       char *s = get_supported_applications ();
1697       if (s)
1698         rc = assuan_send_data (ctx, s, strlen (s));
1699       else
1700         rc = 0;
1701       xfree (s);
1702     }
1703   else
1704     rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1705   return rc;
1706 }
1707
1708
1709 /* RESTART
1710
1711    Restart the current connection; this is a kind of warm reset.  It
1712    deletes the context used by this connection but does not send a
1713    RESET to the card.  Thus the card itself won't get reset. 
1714
1715    This is used by gpg-agent to reuse a primary pipe connection and
1716    may be used by clients to backup from a conflict in the serial
1717    command; i.e. to select another application. 
1718 */
1719
1720 static int
1721 cmd_restart (assuan_context_t ctx, char *line)
1722 {
1723   ctrl_t ctrl = assuan_get_pointer (ctx);
1724
1725   (void)line;
1726
1727   if (ctrl->app_ctx)
1728     {
1729       release_application (ctrl->app_ctx);
1730       ctrl->app_ctx = NULL;
1731     }
1732   if (locked_session && ctrl->server_local == locked_session)
1733     {
1734       locked_session = NULL;
1735       log_info ("implicitly unlocking due to RESTART\n");
1736     }
1737   return 0;
1738 }
1739
1740
1741 /* DISCONNECT
1742
1743    Disconnect the card if it is not any longer used by other
1744    connections and the backend supports a disconnect operation. 
1745  */
1746 static int
1747 cmd_disconnect (assuan_context_t ctx, char *line)
1748 {
1749   ctrl_t ctrl = assuan_get_pointer (ctx);
1750
1751   (void)line;
1752   
1753   ctrl->server_local->disconnect_allowed = 1;
1754   return 0;
1755 }
1756
1757
1758
1759 /* APDU [--atr] [--more] [hexstring]
1760
1761    Send an APDU to the current reader.  This command bypasses the high
1762    level functions and sends the data directly to the card.  HEXSTRING
1763    is expected to be a proper APDU.  If HEXSTRING is not given no
1764    commands are set to the card but the command will implictly check
1765    whether the card is ready for use. 
1766
1767    Using the option "--atr" returns the ATR of the card as a status
1768    message before any data like this:
1769      S CARD-ATR 3BFA1300FF813180450031C173C00100009000B1
1770
1771    Using the option --more handles the card status word MORE_DATA
1772    (61xx) and concatenate all reponses to one block.
1773
1774  */
1775 static int
1776 cmd_apdu (assuan_context_t ctx, char *line)
1777 {
1778   ctrl_t ctrl = assuan_get_pointer (ctx);
1779   int rc;
1780   unsigned char *apdu;
1781   size_t apdulen;
1782   int with_atr;
1783   int handle_more;
1784
1785   with_atr = has_option (line, "--atr");
1786   handle_more = has_option (line, "--more");
1787
1788   line = skip_options (line);
1789
1790   if ( IS_LOCKED (ctrl) )
1791     return gpg_error (GPG_ERR_LOCKED);
1792
1793   if ((rc = open_card (ctrl, NULL)))
1794     return rc;
1795
1796   if (with_atr)
1797     {
1798       unsigned char *atr;
1799       size_t atrlen;
1800       char hexbuf[400];
1801       
1802       atr = apdu_get_atr (ctrl->reader_slot, &atrlen);
1803       if (!atr || atrlen > sizeof hexbuf - 2 )
1804         {
1805           rc = gpg_error (GPG_ERR_INV_CARD);
1806           goto leave;
1807         }
1808       bin2hex (atr, atrlen, hexbuf);
1809       xfree (atr);
1810       send_status_info (ctrl, "CARD-ATR", hexbuf, strlen (hexbuf), NULL, 0);
1811     }
1812
1813   apdu = hex_to_buffer (line, &apdulen);
1814   if (!apdu)
1815     {
1816       rc = gpg_error_from_syserror ();
1817       goto leave;
1818     }
1819   if (apdulen)
1820     {
1821       unsigned char *result = NULL;
1822       size_t resultlen;
1823
1824       rc = apdu_send_direct (ctrl->reader_slot, apdu, apdulen, handle_more,
1825                              &result, &resultlen);
1826       if (rc)
1827         log_error ("apdu_send_direct failed: %s\n", gpg_strerror (rc));
1828       else
1829         {
1830           rc = assuan_send_data (ctx, result, resultlen);
1831           xfree (result);
1832         }
1833     }
1834   xfree (apdu);
1835
1836  leave:
1837   TEST_CARD_REMOVAL (ctrl, rc);
1838   return rc;
1839 }
1840
1841
1842 /* KILLSCD - Commit suicide. */
1843 static int
1844 cmd_killscd (assuan_context_t ctx, char *line)
1845 {
1846   ctrl_t ctrl = assuan_get_pointer (ctx);
1847
1848   (void)line;
1849
1850   ctrl->server_local->stopme = 1;
1851   return gpg_error (GPG_ERR_EOF);
1852 }
1853
1854
1855 \f
1856 /* Tell the assuan library about our commands */
1857 static int
1858 register_commands (assuan_context_t ctx)
1859 {
1860   static struct {
1861     const char *name;
1862     int (*handler)(assuan_context_t, char *line);
1863   } table[] = {
1864     { "SERIALNO",     cmd_serialno },
1865     { "LEARN",        cmd_learn },
1866     { "READCERT",     cmd_readcert },
1867     { "READKEY",      cmd_readkey },
1868     { "SETDATA",      cmd_setdata },
1869     { "PKSIGN",       cmd_pksign },
1870     { "PKAUTH",       cmd_pkauth },
1871     { "PKDECRYPT",    cmd_pkdecrypt },
1872     { "INPUT",        NULL }, 
1873     { "OUTPUT",       NULL }, 
1874     { "GETATTR",      cmd_getattr },
1875     { "SETATTR",      cmd_setattr },
1876     { "WRITECERT",    cmd_writecert },
1877     { "WRITEKEY",     cmd_writekey },
1878     { "GENKEY",       cmd_genkey },
1879     { "RANDOM",       cmd_random },
1880     { "PASSWD",       cmd_passwd },
1881     { "CHECKPIN",     cmd_checkpin },
1882     { "LOCK",         cmd_lock },
1883     { "UNLOCK",       cmd_unlock },
1884     { "GETINFO",      cmd_getinfo },
1885     { "RESTART",      cmd_restart },
1886     { "DISCONNECT",   cmd_disconnect },
1887     { "APDU",         cmd_apdu },
1888     { "KILLSCD",      cmd_killscd },
1889     { NULL }
1890   };
1891   int i, rc;
1892
1893   for (i=0; table[i].name; i++)
1894     {
1895       rc = assuan_register_command (ctx, table[i].name, table[i].handler);
1896       if (rc)
1897         return rc;
1898     } 
1899   assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready");
1900
1901   assuan_register_reset_notify (ctx, reset_notify);
1902   assuan_register_option_handler (ctx, option_handler);
1903   return 0;
1904 }
1905
1906
1907 /* Startup the server.  If FD is given as -1 this is simple pipe
1908    server, otherwise it is a regular server.  Returns true if there
1909    are no more active asessions.  */
1910 int
1911 scd_command_handler (ctrl_t ctrl, int fd)
1912 {
1913   int rc;
1914   assuan_context_t ctx;
1915   int stopme;
1916   
1917   if (fd == -1)
1918     {
1919       int filedes[2];
1920
1921       filedes[0] = 0;
1922       filedes[1] = 1;
1923       rc = assuan_init_pipe_server (&ctx, filedes);
1924     }
1925   else
1926     {
1927       rc = assuan_init_socket_server_ext (&ctx, INT2FD(fd), 2);
1928     }
1929   if (rc)
1930     {
1931       log_error ("failed to initialize the server: %s\n",
1932                  gpg_strerror(rc));
1933       scd_exit (2);
1934     }
1935   rc = register_commands (ctx);
1936   if (rc)
1937     {
1938       log_error ("failed to register commands with Assuan: %s\n",
1939                  gpg_strerror(rc));
1940       scd_exit (2);
1941     }
1942   assuan_set_pointer (ctx, ctrl);
1943
1944   /* Allocate and initialize the server object.  Put it into the list
1945      of active sessions. */
1946   ctrl->server_local = xcalloc (1, sizeof *ctrl->server_local);
1947   ctrl->server_local->next_session = session_list;
1948   session_list = ctrl->server_local;
1949   ctrl->server_local->ctrl_backlink = ctrl;
1950   ctrl->server_local->assuan_ctx = ctx;
1951
1952   if (DBG_ASSUAN)
1953     assuan_set_log_stream (ctx, log_get_stream ());
1954
1955   /* We open the reader right at startup so that the ticker is able to
1956      update the status file. */
1957   if (ctrl->reader_slot == -1)
1958     {
1959       ctrl->reader_slot = get_reader_slot ();
1960     }
1961
1962   /* Command processing loop. */
1963   for (;;)
1964     {
1965       rc = assuan_accept (ctx);
1966       if (rc == -1)
1967         {
1968           break;
1969         }
1970       else if (rc)
1971         {
1972           log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
1973           break;
1974         }
1975       
1976       rc = assuan_process (ctx);
1977       if (rc)
1978         {
1979           log_info ("Assuan processing failed: %s\n", gpg_strerror (rc));
1980           continue;
1981         }
1982     }
1983
1984   /* Cleanup.  We don't send an explicit reset to the card.  */
1985   do_reset (ctrl, 0); 
1986
1987   /* Release the server object.  */
1988   if (session_list == ctrl->server_local)
1989     session_list = ctrl->server_local->next_session;
1990   else
1991     {
1992       struct server_local_s *sl;
1993       
1994       for (sl=session_list; sl->next_session; sl = sl->next_session)
1995         if (sl->next_session == ctrl->server_local)
1996           break;
1997       if (!sl->next_session)
1998           BUG ();
1999       sl->next_session = ctrl->server_local->next_session;
2000     }
2001   stopme = ctrl->server_local->stopme;
2002   xfree (ctrl->server_local);
2003   ctrl->server_local = NULL;
2004
2005   /* Release the Assuan context.  */
2006   assuan_deinit_server (ctx);
2007
2008   if (stopme)
2009     scd_exit (0);
2010
2011   /* If there are no more sessions return true.  */
2012   return !session_list;
2013 }
2014
2015
2016 /* Send a line with status information via assuan and escape all given
2017    buffers. The variable elements are pairs of (char *, size_t),
2018    terminated with a (NULL, 0). */
2019 void
2020 send_status_info (ctrl_t ctrl, const char *keyword, ...)
2021 {
2022   va_list arg_ptr;
2023   const unsigned char *value;
2024   size_t valuelen;
2025   char buf[950], *p;
2026   size_t n;
2027   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2028   
2029   va_start (arg_ptr, keyword);
2030
2031   p = buf; 
2032   n = 0;
2033   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
2034     {
2035       valuelen = va_arg (arg_ptr, size_t);
2036       if (!valuelen)
2037         continue; /* empty buffer */
2038       if (n)
2039         {
2040           *p++ = ' ';
2041           n++;
2042         }
2043       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
2044         {
2045           if (*value < ' ' || *value == '+')
2046             {
2047               sprintf (p, "%%%02X", *value);
2048               p += 3;
2049             }
2050           else if (*value == ' ')
2051             *p++ = '+';
2052           else
2053             *p++ = *value;
2054         }
2055     }
2056   *p = 0;
2057   assuan_write_status (ctx, keyword, buf);
2058
2059   va_end (arg_ptr);
2060 }
2061
2062
2063 /* Send a ready formatted status line via assuan.  */
2064 void
2065 send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
2066 {
2067   assuan_context_t ctx = ctrl->server_local->assuan_ctx;
2068
2069   if (strchr (args, '\n'))
2070     log_error ("error: LF detected in status line - not sending\n");
2071   else
2072     assuan_write_status (ctx, keyword, args);
2073 }
2074
2075
2076 /* Helper to send the clients a status change notification.  */
2077 static void
2078 send_client_notifications (void)
2079 {
2080   struct {
2081     pid_t pid; 
2082 #ifdef HAVE_W32_SYSTEM
2083     HANDLE handle;
2084 #else
2085     int signo; 
2086 #endif
2087   } killed[50];
2088   int killidx = 0;
2089   int kidx;
2090   struct server_local_s *sl;
2091   
2092   for (sl=session_list; sl; sl = sl->next_session)
2093     {
2094       if (sl->event_signal && sl->assuan_ctx)
2095         {
2096           pid_t pid = assuan_get_pid (sl->assuan_ctx);
2097 #ifdef HAVE_W32_SYSTEM
2098           HANDLE handle = (void *)sl->event_signal;
2099           
2100           for (kidx=0; kidx < killidx; kidx++)
2101             if (killed[kidx].pid == pid 
2102                 && killed[kidx].handle == handle)
2103               break;
2104           if (kidx < killidx)
2105             log_info ("event %lx (%p) already triggered for client %d\n",
2106                       sl->event_signal, handle, (int)pid);
2107           else
2108             {
2109               log_info ("triggering event %lx (%p) for client %d\n",
2110                         sl->event_signal, handle, (int)pid);
2111               if (!SetEvent (handle))
2112                 log_error ("SetEvent(%lx) failed: %s\n",
2113                            sl->event_signal, w32_strerror (-1));
2114               if (killidx < DIM (killed))
2115                 {
2116                   killed[killidx].pid = pid;
2117                   killed[killidx].handle = handle;
2118                   killidx++;
2119                 }
2120             }
2121 #else /*!HAVE_W32_SYSTEM*/
2122           int signo = sl->event_signal;
2123           
2124           if (pid != (pid_t)(-1) && pid && signo > 0)
2125             {
2126               for (kidx=0; kidx < killidx; kidx++)
2127                 if (killed[kidx].pid == pid 
2128                     && killed[kidx].signo == signo)
2129                   break;
2130               if (kidx < killidx)
2131                 log_info ("signal %d already sent to client %d\n",
2132                           signo, (int)pid);
2133               else
2134                 {
2135                   log_info ("sending signal %d to client %d\n",
2136                             signo, (int)pid);
2137                   kill (pid, signo);
2138                   if (killidx < DIM (killed))
2139                     {
2140                       killed[killidx].pid = pid;
2141                       killed[killidx].signo = signo;
2142                       killidx++;
2143                     }
2144                 }
2145             }
2146 #endif /*!HAVE_W32_SYSTEM*/
2147         }
2148     }
2149 }
2150
2151
2152
2153 /* This is the core of scd_update_reader_status_file but the caller
2154    needs to take care of the locking.  */
2155 static void
2156 update_reader_status_file (int set_card_removed_flag)
2157 {
2158   int idx;
2159   unsigned int status, changed;
2160
2161   /* Make sure that the reader has been opened.  Like get_reader_slot,
2162      this part of the code assumes that there is only one reader.  */
2163   if (!slot_table[0].valid)
2164     (void)get_reader_slot ();
2165
2166   /* Note, that we only try to get the status, because it does not
2167      make sense to wait here for a operation to complete.  If we are
2168      busy working with a card, delays in the status file update should
2169      be acceptable. */
2170   for (idx=0; idx < DIM(slot_table); idx++)
2171     {
2172       struct slot_status_s *ss = slot_table + idx;
2173       struct server_local_s *sl;
2174       int sw_apdu;
2175
2176       if (!ss->valid || ss->slot == -1)
2177         continue; /* Not valid or reader not yet open. */
2178       
2179       sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed);
2180       if (sw_apdu)
2181         {
2182           /* Get status failed.  Ignore that.  */
2183           continue; 
2184         }
2185
2186       if (!ss->any || ss->status != status || ss->changed != changed )
2187         {
2188           char *fname;
2189           char templ[50];
2190           FILE *fp;
2191
2192           log_info ("updating slot %d status: 0x%04X->0x%04X (%u->%u)\n",
2193                     ss->slot, ss->status, status, ss->changed, changed);
2194           ss->status = status;
2195           ss->changed = changed;
2196
2197           /* FIXME: Should this be IDX instead of ss->slot?  This
2198              depends on how client sessions will associate the reader
2199              status with their session.  */
2200           snprintf (templ, sizeof templ, "reader_%d.status", ss->slot);
2201           fname = make_filename (opt.homedir, templ, NULL );
2202           fp = fopen (fname, "w");
2203           if (fp)
2204             {
2205               fprintf (fp, "%s\n",
2206                        (status & 1)? "USABLE":
2207                        (status & 4)? "ACTIVE":
2208                        (status & 2)? "PRESENT": "NOCARD");
2209               fclose (fp);
2210             }
2211           xfree (fname);
2212             
2213           /* If a status script is executable, run it. */
2214           {
2215             const char *args[9], *envs[2];
2216             char numbuf1[30], numbuf2[30], numbuf3[30];
2217             char *homestr, *envstr;
2218             gpg_error_t err;
2219             
2220             homestr = make_filename (opt.homedir, NULL);
2221             if (estream_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
2222               log_error ("out of core while building environment\n");
2223             else
2224               {
2225                 envs[0] = envstr;
2226                 envs[1] = NULL;
2227
2228                 sprintf (numbuf1, "%d", ss->slot);
2229                 sprintf (numbuf2, "0x%04X", ss->status);
2230                 sprintf (numbuf3, "0x%04X", status);
2231                 args[0] = "--reader-port";
2232                 args[1] = numbuf1; 
2233                 args[2] = "--old-code";
2234                 args[3] = numbuf2;  
2235                 args[4] = "--new-code";
2236                 args[5] = numbuf3; 
2237                 args[6] = "--status";
2238                 args[7] = ((status & 1)? "USABLE":
2239                            (status & 4)? "ACTIVE":
2240                            (status & 2)? "PRESENT": "NOCARD");
2241                 args[8] = NULL;  
2242
2243                 fname = make_filename (opt.homedir, "scd-event", NULL);
2244                 err = gnupg_spawn_process_detached (fname, args, envs);
2245                 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
2246                   log_error ("failed to run event handler `%s': %s\n",
2247                              fname, gpg_strerror (err));
2248                 xfree (fname);
2249                 xfree (envstr);
2250               }
2251             xfree (homestr);
2252           }
2253
2254           /* Set the card removed flag for all current sessions.  We
2255              will set this on any card change because a reset or
2256              SERIALNO request must be done in any case.  */
2257           if (ss->any && set_card_removed_flag)
2258             update_card_removed (idx, 1);
2259           
2260           ss->any = 1;
2261
2262           /* Send a signal to all clients who applied for it.  */
2263           send_client_notifications ();
2264         }
2265       
2266       /* Check whether a disconnect is pending.  */
2267       if (opt.card_timeout)
2268         {
2269           for (sl=session_list; sl; sl = sl->next_session)
2270             if (!sl->disconnect_allowed)
2271               break; 
2272           if (session_list && !sl)
2273             {
2274               /* FIXME: Use a real timeout.  */
2275               /* At least one connection and all allow a disconnect.  */
2276               log_info ("disconnecting card in slot %d\n", ss->slot);
2277               apdu_disconnect (ss->slot);
2278             }
2279         }
2280       
2281     }
2282 }
2283
2284 /* This function is called by the ticker thread to check for changes
2285    of the reader stati.  It updates the reader status files and if
2286    requested by the caller also send a signal to the caller.  */
2287 void
2288 scd_update_reader_status_file (void)
2289 {
2290   if (!pth_mutex_acquire (&status_file_update_lock, 1, NULL))
2291     return; /* locked - give up. */
2292   update_reader_status_file (1);
2293   if (!pth_mutex_release (&status_file_update_lock))
2294     log_error ("failed to release status_file_update lock\n");
2295 }