1 /* app.c - Application selection.
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <https://www.gnu.org/licenses/>.
29 #include "app-common.h"
34 static npth_mutex_t app_list_lock;
38 print_progress_line (void *opaque, const char *what, int pc, int cur, int tot)
45 snprintf (line, sizeof line, "%s %c %d %d", what, pc, cur, tot);
46 send_status_direct (ctrl, "PROGRESS", line);
51 /* Lock the reader SLOT. This function shall be used right before
52 calling any of the actual application functions to serialize access
53 to the reader. We do this always even if the reader is not
54 actually used. This allows an actual connection to assume that it
55 never shares a reader (while performing one command). Returns 0 on
56 success; only then the unlock_reader function must be called after
57 returning from the handler. */
59 lock_app (app_t app, ctrl_t ctrl)
61 if (npth_mutex_lock (&app->lock))
63 gpg_error_t err = gpg_error_from_syserror ();
64 log_error ("failed to acquire APP lock for %p: %s\n",
65 app, gpg_strerror (err));
69 apdu_set_progress_cb (app->slot, print_progress_line, ctrl);
74 /* Release a lock on the reader. See lock_reader(). */
76 unlock_app (app_t app)
78 apdu_set_progress_cb (app->slot, NULL, NULL);
80 if (npth_mutex_unlock (&app->lock))
82 gpg_error_t err = gpg_error_from_syserror ();
83 log_error ("failed to release APP lock for %p: %s\n",
84 app, gpg_strerror (err));
89 /* This function may be called to print information pertaining to the
90 current state of this module to the log. */
96 npth_mutex_lock (&app_list_lock);
97 for (a = app_top; a; a = a->next)
98 log_info ("app_dump_state: app=%p type='%s'\n", a, a->apptype);
99 npth_mutex_unlock (&app_list_lock);
102 /* Check wether the application NAME is allowed. This does not mean
103 we have support for it though. */
105 is_app_allowed (const char *name)
109 for (l=opt.disabled_applications; l; l = l->next)
110 if (!strcmp (l->d, name))
117 check_conflict (app_t app, const char *name)
119 if (!app || !name || (app->apptype && !ascii_strcasecmp (app->apptype, name)))
122 log_info ("application '%s' in use - can't switch\n",
123 app->apptype? app->apptype : "<null>");
125 return gpg_error (GPG_ERR_CONFLICT);
128 /* This function is used by the serialno command to check for an
129 application conflict which may appear if the serialno command is
130 used to request a specific application and the connection has
131 already done a select_application. */
133 check_application_conflict (const char *name, app_t app)
135 return check_conflict (app, name);
140 release_application_internal (app_t app)
143 log_bug ("trying to release an already released context\n");
149 app_reset (app_t app, ctrl_t ctrl, int send_reset)
153 err = lock_app (app, ctrl);
159 int sw = apdu_reset (app->slot);
161 err = gpg_error (GPG_ERR_CARD_RESET);
163 /* Release the same application which is used by other sessions. */
164 send_client_notifications (app, 1);
168 ctrl->app_ctx = NULL;
169 release_application_internal (app);
177 app_new_register (int slot, ctrl_t ctrl, const char *name)
181 unsigned char *result = NULL;
185 /* Need to allocate a new one. */
186 app = xtrycalloc (1, sizeof *app);
189 err = gpg_error_from_syserror ();
190 log_info ("error allocating context: %s\n", gpg_strerror (err));
196 if (npth_mutex_init (&app->lock, NULL))
198 err = gpg_error_from_syserror ();
199 log_error ("error initializing mutex: %s\n", gpg_strerror (err));
204 err = lock_app (app, ctrl);
211 want_undefined = (name && !strcmp (name, "undefined"));
213 /* Try to read the GDO file first to get a default serial number.
214 We skip this if the undefined application has been requested. */
217 err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
219 err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
221 err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
225 const unsigned char *p;
227 p = find_tlv_unchecked (result, resultlen, 0x5A, &n);
229 resultlen -= (p-result);
230 if (p && n > resultlen && n == 0x0d && resultlen+1 == n)
232 /* The object it does not fit into the buffer. This is an
233 invalid encoding (or the buffer is too short. However, I
234 have some test cards with such an invalid encoding and
235 therefore I use this ugly workaround to return something
236 I can further experiment with. */
237 log_info ("enabling BMI testcard workaround\n");
241 if (p && n <= resultlen)
243 /* The GDO file is pretty short, thus we simply reuse it for
244 storing the serial number. */
245 memmove (result, p, n);
246 app->serialno = result;
247 app->serialnolen = n;
248 err = app_munge_serialno (app);
258 /* For certain error codes, there is no need to try more. */
259 if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT
260 || gpg_err_code (err) == GPG_ERR_ENODEV)
263 /* Figure out the application to use. */
266 /* We switch to the "undefined" application only if explicitly
268 app->apptype = "UNDEFINED";
272 err = gpg_error (GPG_ERR_NOT_FOUND);
274 if (err && is_app_allowed ("openpgp")
275 && (!name || !strcmp (name, "openpgp")))
276 err = app_select_openpgp (app);
277 if (err && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
278 err = app_select_nks (app);
279 if (err && is_app_allowed ("p15") && (!name || !strcmp (name, "p15")))
280 err = app_select_p15 (app);
281 if (err && is_app_allowed ("geldkarte")
282 && (!name || !strcmp (name, "geldkarte")))
283 err = app_select_geldkarte (app);
284 if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
285 err = app_select_dinsig (app);
286 if (err && is_app_allowed ("sc-hsm") && (!name || !strcmp (name, "sc-hsm")))
287 err = app_select_sc_hsm (app);
288 if (err && name && gpg_err_code (err) != GPG_ERR_OBJ_TERM_STATE)
289 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
295 log_info ("can't select application '%s': %s\n",
296 name, gpg_strerror (err));
298 log_info ("no supported card application found: %s\n",
305 app->require_get_status = 1; /* For token, this can be 0. */
307 npth_mutex_lock (&app_list_lock);
310 npth_mutex_unlock (&app_list_lock);
315 /* If called with NAME as NULL, select the best fitting application
316 and return a context; otherwise select the application with NAME
317 and return a context. Returns an error code and stores NULL at
318 R_APP if no application was found or no card is present. */
320 select_application (ctrl_t ctrl, const char *name, app_t *r_app,
321 int scan, const unsigned char *serialno_bin,
322 size_t serialno_bin_len)
329 if (scan || !app_top)
333 err = apdu_dev_list_start (opt.reader_port, &l);
342 slot = apdu_open_reader (l);
347 sw = apdu_connect (slot);
349 if (sw == SW_HOST_CARD_INACTIVE)
352 sw = apdu_reset (slot);
355 if (!sw || sw == SW_HOST_ALREADY_CONNECTED)
357 else if (sw == SW_HOST_NO_CARD)
358 err = gpg_error (GPG_ERR_CARD_NOT_PRESENT);
360 err = gpg_error (GPG_ERR_ENODEV);
363 err = app_new_register (slot, ctrl, name);
366 /* We close a reader with no card. */
367 apdu_close_reader (slot);
371 apdu_dev_list_finish (l);
374 npth_mutex_lock (&app_list_lock);
375 for (a = app_top; a; a = a->next)
378 if (serialno_bin == NULL)
380 if (a->serialnolen == serialno_bin_len
381 && !memcmp (a->serialno, serialno_bin, a->serialnolen))
388 err = check_conflict (a, name);
397 err = gpg_error (GPG_ERR_ENODEV);
399 npth_mutex_unlock (&app_list_lock);
406 get_supported_applications (void)
408 const char *list[] = {
415 /* Note: "undefined" is not listed here because it needs special
416 treatment by the client. */
423 for (nbytes=1, idx=0; list[idx]; idx++)
424 nbytes += strlen (list[idx]) + 1 + 1;
426 buffer = xtrymalloc (nbytes);
430 for (p=buffer, idx=0; list[idx]; idx++)
431 if (is_app_allowed (list[idx]))
432 p = stpcpy (stpcpy (p, list[idx]), ":\n");
439 /* Deallocate the application. */
441 deallocate_app (app_t app)
443 app_t a, a_prev = NULL;
445 for (a = app_top; a; a = a->next)
451 a_prev->next = a->next;
458 log_error ("trying to release context used yet (%d)\n", app->ref_count);
462 app->fnc.deinit (app);
463 app->fnc.deinit = NULL;
466 xfree (app->serialno);
470 /* Free the resources associated with the application APP. APP is
471 allowed to be NULL in which case this is a no-op. Note that we are
472 using reference counting to track the users of the application and
473 actually deferring the deallocation to allow for a later reuse by
476 release_application (app_t app)
481 /* We don't deallocate app here. Instead, we keep it. This is
482 useful so that a card does not get reset even if only one session
483 is using the card - this way the PIN cache and other cached data
486 lock_app (app, NULL);
487 release_application_internal (app);
493 /* The serial number may need some cosmetics. Do it here. This
494 function shall only be called once after a new serial number has
495 been put into APP->serialno.
499 FF 00 00 = For serial numbers starting with an FF
500 FF 01 00 = Some german p15 cards return an empty serial number so the
501 serial number from the EF(TokenInfo) is used instead.
502 FF 7F 00 = No serialno.
504 All other serial number not starting with FF are used as they are.
507 app_munge_serialno (app_t app)
509 if (app->serialnolen && app->serialno[0] == 0xff)
511 /* The serial number starts with our special prefix. This
512 requires that we put our default prefix "FF0000" in front. */
513 unsigned char *p = xtrymalloc (app->serialnolen + 3);
515 return gpg_error_from_syserror ();
516 memcpy (p, "\xff\0", 3);
517 memcpy (p+3, app->serialno, app->serialnolen);
518 app->serialnolen += 3;
519 xfree (app->serialno);
522 else if (!app->serialnolen)
524 unsigned char *p = xtrymalloc (3);
526 return gpg_error_from_syserror ();
527 memcpy (p, "\xff\x7f", 3);
528 app->serialnolen = 3;
529 xfree (app->serialno);
537 /* Retrieve the serial number of the card. The serial number is
538 returned as a malloced string (hex encoded) in SERIAL. Caller must
539 free SERIAL unless the function returns an error. */
541 app_get_serialno (app_t app)
548 if (!app->serialnolen)
549 serial = xtrystrdup ("FF7F00");
551 serial = bin2hex (app->serialno, app->serialnolen, NULL);
557 /* Write out the application specifig status lines for the LEARN
560 app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
565 return gpg_error (GPG_ERR_INV_VALUE);
566 if (!app->fnc.learn_status)
567 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
569 /* We do not send APPTYPE if only keypairinfo is requested. */
570 if (app->apptype && !(flags & 1))
571 send_status_direct (ctrl, "APPTYPE", app->apptype);
572 err = lock_app (app, ctrl);
575 err = app->fnc.learn_status (app, ctrl, flags);
581 /* Read the certificate with id CERTID (as returned by learn_status in
582 the CERTINFO status lines) and return it in the freshly allocated
583 buffer put into CERT and the length of the certificate put into
586 app_readcert (app_t app, ctrl_t ctrl, const char *certid,
587 unsigned char **cert, size_t *certlen)
592 return gpg_error (GPG_ERR_INV_VALUE);
594 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
595 if (!app->fnc.readcert)
596 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
597 err = lock_app (app, ctrl);
600 err = app->fnc.readcert (app, certid, cert, certlen);
606 /* Read the key with ID KEYID. On success a canonical encoded
607 S-expression with the public key will get stored at PK and its
608 length (for assertions) at PKLEN; the caller must release that
609 buffer. On error NULL will be stored at PK and PKLEN and an error
612 This function might not be supported by all applications. */
614 app_readkey (app_t app, ctrl_t ctrl, int advanced, const char *keyid,
615 unsigned char **pk, size_t *pklen)
624 if (!app || !keyid || !pk || !pklen)
625 return gpg_error (GPG_ERR_INV_VALUE);
627 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
628 if (!app->fnc.readkey)
629 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
630 err = lock_app (app, ctrl);
633 err= app->fnc.readkey (app, advanced, keyid, pk, pklen);
639 /* Perform a GETATTR operation. */
641 app_getattr (app_t app, ctrl_t ctrl, const char *name)
645 if (!app || !name || !*name)
646 return gpg_error (GPG_ERR_INV_VALUE);
648 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
650 if (app->apptype && name && !strcmp (name, "APPTYPE"))
652 send_status_direct (ctrl, "APPTYPE", app->apptype);
655 if (name && !strcmp (name, "SERIALNO"))
659 serial = app_get_serialno (app);
661 return gpg_error (GPG_ERR_INV_VALUE);
663 send_status_direct (ctrl, "SERIALNO", serial);
668 if (!app->fnc.getattr)
669 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
670 err = lock_app (app, ctrl);
673 err = app->fnc.getattr (app, ctrl, name);
678 /* Perform a SETATTR operation. */
680 app_setattr (app_t app, ctrl_t ctrl, const char *name,
681 gpg_error_t (*pincb)(void*, const char *, char **),
683 const unsigned char *value, size_t valuelen)
687 if (!app || !name || !*name || !value)
688 return gpg_error (GPG_ERR_INV_VALUE);
690 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
691 if (!app->fnc.setattr)
692 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
693 err = lock_app (app, ctrl);
696 err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
701 /* Create the signature and return the allocated result in OUTDATA.
702 If a PIN is required the PINCB will be used to ask for the PIN; it
703 should return the PIN in an allocated buffer and put it into PIN. */
705 app_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
706 gpg_error_t (*pincb)(void*, const char *, char **),
708 const void *indata, size_t indatalen,
709 unsigned char **outdata, size_t *outdatalen )
713 if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
714 return gpg_error (GPG_ERR_INV_VALUE);
716 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
718 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
719 err = lock_app (app, ctrl);
722 err = app->fnc.sign (app, keyidstr, hashalgo,
725 outdata, outdatalen);
728 log_info ("operation sign result: %s\n", gpg_strerror (err));
732 /* Create the signature using the INTERNAL AUTHENTICATE command and
733 return the allocated result in OUTDATA. If a PIN is required the
734 PINCB will be used to ask for the PIN; it should return the PIN in
735 an allocated buffer and put it into PIN. */
737 app_auth (app_t app, ctrl_t ctrl, const char *keyidstr,
738 gpg_error_t (*pincb)(void*, const char *, char **),
740 const void *indata, size_t indatalen,
741 unsigned char **outdata, size_t *outdatalen )
745 if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
746 return gpg_error (GPG_ERR_INV_VALUE);
748 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
750 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
751 err = lock_app (app, ctrl);
754 err = app->fnc.auth (app, keyidstr,
757 outdata, outdatalen);
760 log_info ("operation auth result: %s\n", gpg_strerror (err));
765 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
766 If a PIN is required the PINCB will be used to ask for the PIN; it
767 should return the PIN in an allocated buffer and put it into PIN. */
769 app_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
770 gpg_error_t (*pincb)(void*, const char *, char **),
772 const void *indata, size_t indatalen,
773 unsigned char **outdata, size_t *outdatalen,
774 unsigned int *r_info)
780 if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
781 return gpg_error (GPG_ERR_INV_VALUE);
783 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
784 if (!app->fnc.decipher)
785 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
786 err = lock_app (app, ctrl);
789 err = app->fnc.decipher (app, keyidstr,
796 log_info ("operation decipher result: %s\n", gpg_strerror (err));
801 /* Perform the WRITECERT operation. */
803 app_writecert (app_t app, ctrl_t ctrl,
804 const char *certidstr,
805 gpg_error_t (*pincb)(void*, const char *, char **),
807 const unsigned char *data, size_t datalen)
811 if (!app || !certidstr || !*certidstr || !pincb)
812 return gpg_error (GPG_ERR_INV_VALUE);
814 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
815 if (!app->fnc.writecert)
816 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
817 err = lock_app (app, ctrl);
820 err = app->fnc.writecert (app, ctrl, certidstr,
821 pincb, pincb_arg, data, datalen);
824 log_info ("operation writecert result: %s\n", gpg_strerror (err));
829 /* Perform the WRITEKEY operation. */
831 app_writekey (app_t app, ctrl_t ctrl,
832 const char *keyidstr, unsigned int flags,
833 gpg_error_t (*pincb)(void*, const char *, char **),
835 const unsigned char *keydata, size_t keydatalen)
839 if (!app || !keyidstr || !*keyidstr || !pincb)
840 return gpg_error (GPG_ERR_INV_VALUE);
842 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
843 if (!app->fnc.writekey)
844 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
845 err = lock_app (app, ctrl);
848 err = app->fnc.writekey (app, ctrl, keyidstr, flags,
849 pincb, pincb_arg, keydata, keydatalen);
852 log_info ("operation writekey result: %s\n", gpg_strerror (err));
857 /* Perform a SETATTR operation. */
859 app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
861 gpg_error_t (*pincb)(void*, const char *, char **),
866 if (!app || !keynostr || !*keynostr || !pincb)
867 return gpg_error (GPG_ERR_INV_VALUE);
869 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
870 if (!app->fnc.genkey)
871 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
872 err = lock_app (app, ctrl);
875 err = app->fnc.genkey (app, ctrl, keynostr, flags,
876 createtime, pincb, pincb_arg);
879 log_info ("operation genkey result: %s\n", gpg_strerror (err));
884 /* Perform a GET CHALLENGE operation. This function is special as it
885 directly accesses the card without any application specific
888 app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer)
892 if (!app || !nbytes || !buffer)
893 return gpg_error (GPG_ERR_INV_VALUE);
895 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
896 err = lock_app (app, ctrl);
899 err = iso7816_get_challenge (app->slot, nbytes, buffer);
906 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation. */
908 app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
909 gpg_error_t (*pincb)(void*, const char *, char **),
914 if (!app || !chvnostr || !*chvnostr || !pincb)
915 return gpg_error (GPG_ERR_INV_VALUE);
917 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
918 if (!app->fnc.change_pin)
919 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
920 err = lock_app (app, ctrl);
923 err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode,
927 log_info ("operation change_pin result: %s\n", gpg_strerror (err));
932 /* Perform a VERIFY operation without doing anything lese. This may
933 be used to initialze a the PIN cache for long lasting other
934 operations. Its use is highly application dependent. */
936 app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr,
937 gpg_error_t (*pincb)(void*, const char *, char **),
942 if (!app || !keyidstr || !*keyidstr || !pincb)
943 return gpg_error (GPG_ERR_INV_VALUE);
945 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
946 if (!app->fnc.check_pin)
947 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
948 err = lock_app (app, ctrl);
951 err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);
954 log_info ("operation check_pin result: %s\n", gpg_strerror (err));
959 report_change (int slot, int old_status, int cur_status)
961 char *homestr, *envstr;
966 snprintf (templ, sizeof templ, "reader_%d.status", slot);
967 fname = make_filename (gnupg_homedir (), templ, NULL );
968 fp = fopen (fname, "w");
972 (cur_status & 1)? "USABLE":
973 (cur_status & 4)? "ACTIVE":
974 (cur_status & 2)? "PRESENT": "NOCARD");
979 homestr = make_filename (gnupg_homedir (), NULL);
980 if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
981 log_error ("out of core while building environment\n");
985 const char *args[9], *envs[2];
986 char numbuf1[30], numbuf2[30], numbuf3[30];
991 sprintf (numbuf1, "%d", slot);
992 sprintf (numbuf2, "0x%04X", old_status);
993 sprintf (numbuf3, "0x%04X", cur_status);
994 args[0] = "--reader-port";
996 args[2] = "--old-code";
998 args[4] = "--new-code";
1000 args[6] = "--status";
1001 args[7] = ((cur_status & 1)? "USABLE":
1002 (cur_status & 4)? "ACTIVE":
1003 (cur_status & 2)? "PRESENT": "NOCARD");
1006 fname = make_filename (gnupg_homedir (), "scd-event", NULL);
1007 err = gnupg_spawn_process_detached (fname, args, envs);
1008 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
1009 log_error ("failed to run event handler '%s': %s\n",
1010 fname, gpg_strerror (err));
1018 scd_update_reader_status_file (void)
1022 npth_mutex_lock (&app_list_lock);
1023 for (a = app_top; a; a = app_next)
1026 if (a->require_get_status)
1029 unsigned int status;
1030 sw = apdu_get_status (a->slot, 0, &status);
1032 if (sw == SW_HOST_NO_READER)
1034 /* Most likely the _reader_ has been unplugged. */
1039 /* Get status failed. Ignore that. */
1043 if (a->card_status != status)
1045 report_change (a->slot, a->card_status, status);
1046 send_client_notifications (a, status == 0);
1050 log_debug ("Removal of a card: %d\n", a->slot);
1051 apdu_close_reader (a->slot);
1055 a->card_status = status;
1059 npth_mutex_unlock (&app_list_lock);
1062 /* This function must be called once to initialize this module. This
1063 has to be done before a second thread is spawned. We can't do the
1064 static initialization because Pth emulation code might not be able
1065 to do a static init; in particular, it is not possible for W32. */
1067 initialize_module_command (void)
1071 if (npth_mutex_init (&app_list_lock, NULL))
1073 err = gpg_error_from_syserror ();
1074 log_error ("app: error initializing mutex: %s\n", gpg_strerror (err));
1078 return apdu_init ();
1082 app_list_start (void)
1084 npth_mutex_lock (&app_list_lock);
1089 app_list_finish (void)
1091 npth_mutex_unlock (&app_list_lock);
1095 app_send_card_list (ctrl_t ctrl)
1100 npth_mutex_lock (&app_list_lock);
1101 for (a = app_top; a; a = a->next)
1103 if (DIM (buf) < 2 * a->serialnolen + 1)
1106 bin2hex (a->serialno, a->serialnolen, buf);
1107 send_status_direct (ctrl, "SERIALNO", buf);
1109 npth_mutex_unlock (&app_list_lock);