mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-30 16:17:02 +01:00
Detect non operational readers.
Backport from 2.0.
This commit is contained in:
parent
05a3f56391
commit
ca2d315765
@ -1,3 +1,16 @@
|
||||
2011-01-25 Werner Koch <wk@g10code.com>
|
||||
|
||||
From 2.0 branch, 2010-03-17:
|
||||
|
||||
* command.c (open_card): Return GPG_ERR_NOT_OPERATIONAL if no
|
||||
card services are available.
|
||||
(get_reader_slot): Detect no services status.
|
||||
(cmd_serialno): No reset if there are no services.
|
||||
(scd_command_handler): Stop scdaemon in that case.
|
||||
* apdu.c (pcsc_no_service): New.
|
||||
(open_pcsc_reader_direct): Set it.
|
||||
(apdu_open_reader): Add arg R_NO_SERVICE.
|
||||
|
||||
2011-01-05 Werner Koch <wk@g10code.com>
|
||||
|
||||
* ccid-driver.c (ccid_transceive_secure): Support the gnuk token.
|
||||
|
20
scd/apdu.c
20
scd/apdu.c
@ -304,6 +304,9 @@ long (* DLSTDCALL pcsc_transmit) (unsigned long card,
|
||||
long (* DLSTDCALL pcsc_set_timeout) (unsigned long context,
|
||||
unsigned long timeout);
|
||||
|
||||
/* Flag set if PC/SC returned the no-service error. */
|
||||
static int pcsc_no_service;
|
||||
|
||||
|
||||
/* Prototypes. */
|
||||
static int pcsc_get_status (int slot, unsigned int *status);
|
||||
@ -1504,8 +1507,11 @@ open_pcsc_reader_direct (const char *portstr)
|
||||
log_error ("pcsc_establish_context failed: %s (0x%lx)\n",
|
||||
pcsc_error_string (err), err);
|
||||
reader_table[slot].used = 0;
|
||||
if (err == 0x8010001d)
|
||||
pcsc_no_service = 1;
|
||||
return -1;
|
||||
}
|
||||
pcsc_no_service = 0;
|
||||
|
||||
err = pcsc_list_readers (reader_table[slot].pcsc.context,
|
||||
NULL, NULL, &nreader);
|
||||
@ -2338,14 +2344,18 @@ unlock_slot (int slot)
|
||||
error. If PORTSTR is NULL we default to a suitable port (for ctAPI:
|
||||
the first USB reader. For PC/SC the first listed reader). */
|
||||
int
|
||||
apdu_open_reader (const char *portstr)
|
||||
apdu_open_reader (const char *portstr, int *r_no_service)
|
||||
{
|
||||
static int pcsc_api_loaded, ct_api_loaded;
|
||||
int slot;
|
||||
|
||||
if (r_no_service)
|
||||
*r_no_service = 0;
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
if (!opt.disable_ccid)
|
||||
{
|
||||
int slot, i;
|
||||
int i;
|
||||
const char *s;
|
||||
|
||||
slot = open_ccid_reader (portstr);
|
||||
@ -2475,7 +2485,11 @@ apdu_open_reader (const char *portstr)
|
||||
pcsc_api_loaded = 1;
|
||||
}
|
||||
|
||||
return open_pcsc_reader (portstr);
|
||||
slot = open_pcsc_reader (portstr);
|
||||
if (slot == -1 && r_no_service && pcsc_no_service)
|
||||
*r_no_service = 1;
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,8 +80,8 @@ enum {
|
||||
#define APDU_CARD_ACTIVE (4) /* Card is active. */
|
||||
|
||||
|
||||
/* Note , that apdu_open_reader returns no status word but -1 on error. */
|
||||
int apdu_open_reader (const char *portstr);
|
||||
/* Note, that apdu_open_reader returns no status word but -1 on error. */
|
||||
int apdu_open_reader (const char *portstr, int *r_no_service);
|
||||
int apdu_open_remote_reader (const char *portstr,
|
||||
const unsigned char *cookie, size_t length,
|
||||
int (*readfnc) (void *opaque,
|
||||
|
@ -70,6 +70,10 @@
|
||||
&& (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
|
||||
|
||||
|
||||
/* Flag indicating that the reader has been disabled. */
|
||||
static int reader_disabled;
|
||||
|
||||
|
||||
/* This structure is used to keep track of open readers (slots). */
|
||||
struct slot_status_s
|
||||
{
|
||||
@ -394,7 +398,15 @@ get_reader_slot (void)
|
||||
|
||||
/* Try to open the reader. */
|
||||
if (ss->slot == -1)
|
||||
ss->slot = apdu_open_reader (opt.reader_port);
|
||||
{
|
||||
int no_service_flag;
|
||||
ss->slot = apdu_open_reader (opt.reader_port, &no_service_flag);
|
||||
if (no_service_flag)
|
||||
{
|
||||
log_info ("no card services - disabling scdaemon\n");
|
||||
reader_disabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the slot_table index. */
|
||||
return 0;
|
||||
@ -409,6 +421,9 @@ open_card (ctrl_t ctrl, const char *apptype)
|
||||
gpg_error_t err;
|
||||
int slot;
|
||||
|
||||
if (reader_disabled)
|
||||
return gpg_error (GPG_ERR_NOT_OPERATIONAL);
|
||||
|
||||
/* If we ever got a card not present error code, return that. Only
|
||||
the SERIALNO command and a reset are able to clear from that
|
||||
state. */
|
||||
@ -441,7 +456,7 @@ open_card (ctrl_t ctrl, const char *apptype)
|
||||
slot = get_reader_slot ();
|
||||
ctrl->reader_slot = slot;
|
||||
if (slot == -1)
|
||||
err = gpg_error (GPG_ERR_CARD);
|
||||
err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD);
|
||||
else
|
||||
{
|
||||
/* Fixme: We should move the apdu_connect call to
|
||||
@ -495,7 +510,7 @@ cmd_serialno (assuan_context_t ctx, char *line)
|
||||
time_t stamp;
|
||||
|
||||
/* Clear the remove flag so that the open_card is able to reread it. */
|
||||
if (ctrl->server_local->card_removed)
|
||||
if (!reader_disabled && ctrl->server_local->card_removed)
|
||||
{
|
||||
if ( IS_LOCKED (ctrl) )
|
||||
return gpg_error (GPG_ERR_LOCKED);
|
||||
@ -1993,7 +2008,7 @@ scd_command_handler (ctrl_t ctrl, int fd)
|
||||
BUG ();
|
||||
sl->next_session = ctrl->server_local->next_session;
|
||||
}
|
||||
stopme = ctrl->server_local->stopme;
|
||||
stopme = ctrl->server_local->stopme || reader_disabled;
|
||||
xfree (ctrl->server_local);
|
||||
ctrl->server_local = NULL;
|
||||
|
||||
|
@ -139,7 +139,7 @@ main (int argc, char **argv )
|
||||
if (argc != 1)
|
||||
usage (1);
|
||||
|
||||
slot = apdu_open_reader (reader_port);
|
||||
slot = apdu_open_reader (reader_port, NULL);
|
||||
if (slot == -1)
|
||||
exit (1);
|
||||
if (apdu_connect (slot))
|
||||
|
Loading…
x
Reference in New Issue
Block a user