diff --git a/scd/apdu.c b/scd/apdu.c index b68cd71fa..b8bfceca0 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2596,11 +2596,14 @@ apdu_enum_reader (int slot, int *used) /* Connect a card. This is used to power up the card and make sure - that an ATR is available. */ + that an ATR is available. Depending on the reader backend it may + return an error for an inactive card or if no card is + available. */ int apdu_connect (int slot) { int sw; + unsigned int status; if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -2625,7 +2628,15 @@ apdu_connect (int slot) scdaemon is fired up and apdu_get_status has not yet been called. Without that we would force a reset of the card with the next call to apdu_get_status. */ - apdu_get_status_internal (slot, 1, 1, NULL, NULL); + apdu_get_status_internal (slot, 1, 1, &status, NULL); + if (sw) + ; + else if (!(status & APDU_CARD_PRESENT)) + sw = SW_HOST_NO_CARD; + else if (((status & APDU_CARD_PRESENT) && !(status & APDU_CARD_ACTIVE)) + || !reader_table[slot].atrlen) + sw = SW_HOST_CARD_INACTIVE; + return sw; } diff --git a/scd/command.c b/scd/command.c index 52b22c6a0..0a1f7856d 100644 --- a/scd/command.c +++ b/scd/command.c @@ -60,6 +60,7 @@ int _r = (r); \ if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \ || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \ + || gpg_err_code (_r) == GPG_ERR_CARD_RESET \ || gpg_err_code (_r) == GPG_ERR_ENODEV ) \ update_card_removed ((c)->reader_slot, 1); \ } while (0) @@ -420,9 +421,8 @@ get_reader_slot (void) return 0; } -/* If the card has not yet been opened, do it. Note that this - function returns an Assuan error, so don't map the error a second - time. */ + +/* If the card has not yet been opened, do it. */ static gpg_error_t open_card (ctrl_t ctrl, const char *apptype) { @@ -477,6 +477,8 @@ open_card (ctrl_t ctrl, const char *apptype) { if (sw == SW_HOST_NO_CARD) err = gpg_error (GPG_ERR_CARD_NOT_PRESENT); + else if (sw == SW_HOST_CARD_INACTIVE) + err = gpg_error (GPG_ERR_CARD_RESET); else err = gpg_error (GPG_ERR_CARD); }