* 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.
This commit is contained in:
Werner Koch 2004-04-20 16:42:55 +00:00
parent 2c9aac608b
commit 78f797d11d
6 changed files with 68 additions and 11 deletions

5
NEWS
View File

@ -1,6 +1,11 @@
Noteworthy changes in version 1.9.8 Noteworthy changes in version 1.9.8
------------------------------------------------ ------------------------------------------------
* [scdaemon] Overhauled the internal CCID driver.
* [scdaemon] Status files named ~/.gnupg/reader_<n>.status are now
written when using the internal CCID driver.
Noteworthy changes in version 1.9.7 (2004-04-06) Noteworthy changes in version 1.9.7 (2004-04-06)
------------------------------------------------ ------------------------------------------------

View File

@ -1,10 +1,17 @@
2004-04-20 Werner Koch <wk@gnupg.org> 2004-04-20 Werner Koch <wk@gnupg.org>
* 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. * pcsc-wrapper.c: New.
* Makefile.am (pkglib_PROGRAMS): Install it here. * Makefile.am (pkglib_PROGRAMS): Install it here.
* apdu.c (writen, readn): New. * apdu.c (writen, readn): New.
(open_pcsc_reader, pcsc_send_apdu, close_pcsc_reader): Use the (open_pcsc_reader, pcsc_send_apdu, close_pcsc_reader): Use the
pcsc-wrapper if we are using Pth. pcsc-wrapper if we are using Pth.
(apdu_send_le): Reinitialize RESULTLEN. Handle SW_EOF_REACHED
like SW_SUCCESS.
2004-04-19 Werner Koch <wk@gnupg.org> 2004-04-19 Werner Koch <wk@gnupg.org>

View File

@ -913,7 +913,7 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
} }
full_len = len; full_len = len;
n = *buflen < len ? *buflen : len; n = *buflen < len ? *buflen : len;
if ((i=readn (slotp->pcsc.rsp_fd, buffer, n, &len)) || len != n) 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; goto command_failed;
} }
*buflen = n; *buflen = n;
full_len -= len; full_len -= len;
if (full_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, int lc, const char *data, int le,
unsigned char **retbuf, size_t *retbuflen) unsigned char **retbuf, size_t *retbuflen)
{ {
unsigned char result[256+10]; /* 10 extra in case of bugs in the driver. */ #define RESULTLEN 256
size_t 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]; unsigned char apdu[5+256+1];
size_t apdulen; size_t apdulen;
int sw; int sw;
@ -1811,6 +1814,7 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1,
assert (sizeof (apdu) >= apdulen); assert (sizeof (apdu) >= apdulen);
/* As safeguard don't pass any garbage from the stack to the driver. */ /* As safeguard don't pass any garbage from the stack to the driver. */
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
resultlen = RESULTLEN;
rc = send_apdu (slot, apdu, apdulen, result, &resultlen); rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
if (rc || resultlen < 2) 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); int len = (sw & 0x00ff);
log_debug ("apdu_send_simple(%d): %d more bytes available\n", if (DBG_CARD_IO)
slot, len); log_debug ("apdu_send_simple(%d): %d more bytes available\n",
slot, len);
apdulen = 0; apdulen = 0;
apdu[apdulen++] = class; apdu[apdulen++] = class;
apdu[apdulen++] = 0xC0; 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++] = 0;
apdu[apdulen++] = len; apdu[apdulen++] = len;
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
resultlen = RESULTLEN;
rc = send_apdu (slot, apdu, apdulen, result, &resultlen); rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
if (rc || resultlen < 2) 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); 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) 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); log_printhex (" dump: ", *retbuf, *retbuflen);
return sw; return sw;
#undef RESULTLEN
} }
/* Send an APDU to the card in SLOT. The APDU is created from all /* Send an APDU to the card in SLOT. The APDU is created from all

View File

@ -147,8 +147,13 @@ app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff)
is the certificate. */ is the certificate. */
*r_certoff += hdrlen + objlen; *r_certoff += hdrlen + objlen;
if (*r_certoff > resultlen) 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; return resultlen;

View File

@ -108,7 +108,7 @@
/* Disable all debugging output for now. */ /* Disable all debugging output for now. */
#undef DBG_CARD_IO #undef DBG_CARD_IO
#define DBG_CARD_IO 1 #define DBG_CARD_IO 0
/* Define to print information pertaining the T=1 protocol. */ /* Define to print information pertaining the T=1 protocol. */
#undef DEBUG_T1 #undef DEBUG_T1

View File

@ -1179,6 +1179,11 @@ send_status_info (CTRL ctrl, const char *keyword, ...)
void void
scd_update_reader_status_file (void) scd_update_reader_status_file (void)
{ {
static struct {
int any;
unsigned int status;
unsigned int changed;
} last[10];
int slot; int slot;
int used; int used;
unsigned int status, changed; 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 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 so busy working with the card, delays in the status file updated
are should be acceptable. */ 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)) 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);
}
} }
} }