diff --git a/NEWS b/NEWS index dc1122846..31f76b6c8 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,11 @@ Noteworthy changes in version 1.9.8 ------------------------------------------------ + * [scdaemon] Overhauled the internal CCID driver. + + * [scdaemon] Status files named ~/.gnupg/reader_.status are now + written when using the internal CCID driver. + Noteworthy changes in version 1.9.7 (2004-04-06) ------------------------------------------------ diff --git a/scd/ChangeLog b/scd/ChangeLog index 9b04d5e78..bf5c36cbc 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,10 +1,17 @@ 2004-04-20 Werner Koch + * command.c (scd_update_reader_status_file): Write status files. + + * app-help.c (app_help_read_length_of_cert): Fixed calculation of + R_CERTOFF. + * pcsc-wrapper.c: New. * Makefile.am (pkglib_PROGRAMS): Install it here. * apdu.c (writen, readn): New. (open_pcsc_reader, pcsc_send_apdu, close_pcsc_reader): Use the pcsc-wrapper if we are using Pth. + (apdu_send_le): Reinitialize RESULTLEN. Handle SW_EOF_REACHED + like SW_SUCCESS. 2004-04-19 Werner Koch diff --git a/scd/apdu.c b/scd/apdu.c index 1b5ebc375..42b337238 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -913,7 +913,7 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, } full_len = len; - + n = *buflen < len ? *buflen : len; if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n) { @@ -922,6 +922,7 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, goto command_failed; } *buflen = n; + full_len -= len; if (full_len) { @@ -1771,8 +1772,10 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, int lc, const char *data, int le, unsigned char **retbuf, size_t *retbuflen) { - unsigned char result[256+10]; /* 10 extra in case of bugs in the driver. */ - size_t resultlen = 256; +#define RESULTLEN 256 + unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in + the driver. */ + size_t resultlen; unsigned char apdu[5+256+1]; size_t apdulen; int sw; @@ -1811,6 +1814,7 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, assert (sizeof (apdu) >= apdulen); /* As safeguard don't pass any garbage from the stack to the driver. */ memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); + resultlen = RESULTLEN; rc = send_apdu (slot, apdu, apdulen, result, &resultlen); if (rc || resultlen < 2) { @@ -1867,8 +1871,9 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, { int len = (sw & 0x00ff); - log_debug ("apdu_send_simple(%d): %d more bytes available\n", - slot, len); + if (DBG_CARD_IO) + log_debug ("apdu_send_simple(%d): %d more bytes available\n", + slot, len); apdulen = 0; apdu[apdulen++] = class; apdu[apdulen++] = 0xC0; @@ -1876,6 +1881,7 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, apdu[apdulen++] = 0; apdu[apdulen++] = len; memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); + resultlen = RESULTLEN; rc = send_apdu (slot, apdu, apdulen, result, &resultlen); if (rc || resultlen < 2) { @@ -1893,9 +1899,11 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, log_printhex (" dump: ", result, resultlen); } - if ((sw & 0xff00) == SW_MORE_DATA || sw == SW_SUCCESS) + if ((sw & 0xff00) == SW_MORE_DATA + || sw == SW_SUCCESS + || sw == SW_EOF_REACHED ) { - if (retbuf) + if (retbuf && resultlen) { if (p - *retbuf + resultlen > bufsize) { @@ -1935,6 +1943,7 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, log_printhex (" dump: ", *retbuf, *retbuflen); return sw; +#undef RESULTLEN } /* Send an APDU to the card in SLOT. The APDU is created from all diff --git a/scd/app-help.c b/scd/app-help.c index c6695635f..1c3c52b15 100644 --- a/scd/app-help.c +++ b/scd/app-help.c @@ -147,8 +147,13 @@ app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff) is the certificate. */ *r_certoff += hdrlen + objlen; if (*r_certoff > resultlen) - return 0; /* That should never happen. */ + { + *r_certoff = 0; + return 0; /* That should never happen. */ + } } + else + *r_certoff = 0; } return resultlen; diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 1c8167869..cd0bee6ef 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -108,7 +108,7 @@ /* Disable all debugging output for now. */ #undef DBG_CARD_IO -#define DBG_CARD_IO 1 +#define DBG_CARD_IO 0 /* Define to print information pertaining the T=1 protocol. */ #undef DEBUG_T1 diff --git a/scd/command.c b/scd/command.c index 06ff6d2e2..9e77cbe0f 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1179,6 +1179,11 @@ send_status_info (CTRL ctrl, const char *keyword, ...) void scd_update_reader_status_file (void) { + static struct { + int any; + unsigned int status; + unsigned int changed; + } last[10]; int slot; int used; unsigned int status, changed; @@ -1187,9 +1192,35 @@ scd_update_reader_status_file (void) make sense to wait here for a operation to complete. If we are so busy working with the card, delays in the status file updated are should be acceptable. */ - for (slot=0; !apdu_enum_reader (slot, &used); slot++) + for (slot=0; (slot < DIM(last) + &&!apdu_enum_reader (slot, &used)); slot++) if (used && !apdu_get_status (slot, 0, &status, &changed)) { - log_info ("status of slot %d is %u\n", slot, status); + if (!last[slot].any || last[slot].status != status + || last[slot].changed != changed ) + { + char *fname; + char templ[50]; + FILE *fp; + + last[slot].any = 1; + last[slot].status = status; + last[slot].changed = changed; + + log_info ("updating status of slot %d to 0x%04X\n", slot, status); + + sprintf (templ, "reader_%d.status", slot); + fname = make_filename (opt.homedir, templ, NULL ); + fp = fopen (fname, "w"); + if (fp) + { + fprintf (fp, "%s\n", + (status & 1)? "USABLE": + (status & 4)? "ACTIVE": + (status & 2)? "PRESENT": "NOCARD"); + fclose (fp); + } + xfree (fname); + } } }