mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-07 22:01:07 +01:00
scd: Internal CCID reader cleanup.
* scd/ccid-reader.c (scan_usb_device): Only for scan mode, so, rename from scan_or_find_usb_device. (scan_devices): Likewise. Remove support of special transport types. (ccid_get_reader_list): Simplify. (abort_cmd): Fix error return. (send_escape_cmd): Fix for RESULTLEN == NULL. (ccid_transceive_secure): Remove unnecessary var updates. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
3c93595d70
commit
cc420d3488
@ -1129,21 +1129,11 @@ find_endpoint (const struct libusb_interface_descriptor *ifcdesc, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Helper for scan_or_find_devices. This function returns true if a
|
/* Helper for scan_devices. This function returns true if a
|
||||||
requested device has been found or the caller should stop scanning
|
requested device has been found or the caller should stop scanning
|
||||||
for other reasons. */
|
for other reasons. */
|
||||||
static int
|
static void
|
||||||
scan_or_find_usb_device (int scan_mode,
|
scan_usb_device (int *count, char **rid_list, struct libusb_device *dev)
|
||||||
int readerno, int *count, char **rid_list,
|
|
||||||
const char *readerid,
|
|
||||||
struct libusb_device *dev,
|
|
||||||
char **r_rid,
|
|
||||||
struct libusb_device_descriptor *desc,
|
|
||||||
libusb_device_handle **r_idev,
|
|
||||||
unsigned char **ifcdesc_extra,
|
|
||||||
size_t *ifcdesc_extra_len,
|
|
||||||
int *interface_number, int *setting_number,
|
|
||||||
int *ep_bulk_out, int *ep_bulk_in, int *ep_intr)
|
|
||||||
{
|
{
|
||||||
int ifc_no;
|
int ifc_no;
|
||||||
int set_no;
|
int set_no;
|
||||||
@ -1152,16 +1142,16 @@ scan_or_find_usb_device (int scan_mode,
|
|||||||
libusb_device_handle *idev = NULL;
|
libusb_device_handle *idev = NULL;
|
||||||
int err;
|
int err;
|
||||||
struct libusb_config_descriptor *config;
|
struct libusb_config_descriptor *config;
|
||||||
|
struct libusb_device_descriptor desc;
|
||||||
|
char *p;
|
||||||
|
|
||||||
err = libusb_get_device_descriptor (dev, desc);
|
err = libusb_get_device_descriptor (dev, &desc);
|
||||||
if (err)
|
if (err)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
*r_idev = NULL;
|
|
||||||
|
|
||||||
err = libusb_get_active_config_descriptor (dev, &config);
|
err = libusb_get_active_config_descriptor (dev, &config);
|
||||||
if (err)
|
if (err)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++)
|
for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++)
|
||||||
for (set_no=0; set_no < config->interface[ifc_no].num_altsetting; set_no++)
|
for (set_no=0; set_no < config->interface[ifc_no].num_altsetting; set_no++)
|
||||||
@ -1177,15 +1167,13 @@ scan_or_find_usb_device (int scan_mode,
|
|||||||
&& ifcdesc->bInterfaceSubClass == 0
|
&& ifcdesc->bInterfaceSubClass == 0
|
||||||
&& ifcdesc->bInterfaceProtocol == 0)
|
&& ifcdesc->bInterfaceProtocol == 0)
|
||||||
|| (ifcdesc->bInterfaceClass == 255
|
|| (ifcdesc->bInterfaceClass == 255
|
||||||
&& desc->idVendor == VENDOR_SCM
|
&& desc.idVendor == VENDOR_SCM
|
||||||
&& desc->idProduct == SCM_SPR532)
|
&& desc.idProduct == SCM_SPR532)
|
||||||
|| (ifcdesc->bInterfaceClass == 255
|
|| (ifcdesc->bInterfaceClass == 255
|
||||||
&& desc->idVendor == VENDOR_CHERRY
|
&& desc.idVendor == VENDOR_CHERRY
|
||||||
&& desc->idProduct == CHERRY_ST2000)))
|
&& desc.idProduct == CHERRY_ST2000)))
|
||||||
{
|
{
|
||||||
++*count;
|
++*count;
|
||||||
if (!scan_mode && ((readerno > 0 && readerno != *count - 1)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
err = libusb_open (dev, &idev);
|
err = libusb_open (dev, &idev);
|
||||||
if (err)
|
if (err)
|
||||||
@ -1194,89 +1182,36 @@ scan_or_find_usb_device (int scan_mode,
|
|||||||
continue; /* with next setting. */
|
continue; /* with next setting. */
|
||||||
}
|
}
|
||||||
|
|
||||||
rid = make_reader_id (idev, desc->idVendor, desc->idProduct,
|
rid = make_reader_id (idev, desc.idVendor, desc.idProduct,
|
||||||
desc->iSerialNumber);
|
desc.iSerialNumber);
|
||||||
if (!rid)
|
if (!rid)
|
||||||
{
|
{
|
||||||
libusb_free_config_descriptor (config);
|
libusb_free_config_descriptor (config);
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scan_mode && readerno == -1 && readerid
|
/* We are collecting infos about all available CCID
|
||||||
&& strncmp (rid, readerid, strlen (readerid)))
|
readers. Store them and continue. */
|
||||||
continue;
|
DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n", *count, rid);
|
||||||
|
p = malloc ((*rid_list? strlen (*rid_list):0) + 1
|
||||||
if (scan_mode)
|
+ strlen (rid) + 1);
|
||||||
|
if (p)
|
||||||
{
|
{
|
||||||
char *p;
|
*p = 0;
|
||||||
|
if (*rid_list)
|
||||||
/* We are collecting infos about all
|
|
||||||
available CCID readers. Store them and
|
|
||||||
continue. */
|
|
||||||
DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n", *count, rid);
|
|
||||||
p = malloc ((*rid_list? strlen (*rid_list):0) + 1
|
|
||||||
+ strlen (rid) + 1);
|
|
||||||
if (p)
|
|
||||||
{
|
{
|
||||||
*p = 0;
|
strcat (p, *rid_list);
|
||||||
if (*rid_list)
|
free (*rid_list);
|
||||||
{
|
|
||||||
strcat (p, *rid_list);
|
|
||||||
free (*rid_list);
|
|
||||||
}
|
|
||||||
strcat (p, rid);
|
|
||||||
strcat (p, "\n");
|
|
||||||
*rid_list = p;
|
|
||||||
}
|
|
||||||
else /* Out of memory. */
|
|
||||||
{
|
|
||||||
libusb_free_config_descriptor (config);
|
|
||||||
free (rid);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
strcat (p, rid);
|
||||||
|
strcat (p, "\n");
|
||||||
|
*rid_list = p;
|
||||||
}
|
}
|
||||||
else
|
else /* Out of memory. */
|
||||||
{
|
{
|
||||||
/* We found the requested reader. */
|
|
||||||
if (ifcdesc_extra && ifcdesc_extra_len)
|
|
||||||
{
|
|
||||||
*ifcdesc_extra = malloc (ifcdesc->extra_length);
|
|
||||||
if (!*ifcdesc_extra)
|
|
||||||
{
|
|
||||||
libusb_close (idev);
|
|
||||||
free (rid);
|
|
||||||
libusb_free_config_descriptor (config);
|
|
||||||
return 1; /* Out of core. */
|
|
||||||
}
|
|
||||||
memcpy (*ifcdesc_extra, ifcdesc->extra,
|
|
||||||
ifcdesc->extra_length);
|
|
||||||
*ifcdesc_extra_len = ifcdesc->extra_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interface_number)
|
|
||||||
*interface_number = ifc_no;
|
|
||||||
|
|
||||||
if (setting_number)
|
|
||||||
*setting_number = set_no;
|
|
||||||
|
|
||||||
if (ep_bulk_out)
|
|
||||||
*ep_bulk_out = find_endpoint (ifcdesc, 0);
|
|
||||||
if (ep_bulk_in)
|
|
||||||
*ep_bulk_in = find_endpoint (ifcdesc, 1);
|
|
||||||
if (ep_intr)
|
|
||||||
*ep_intr = find_endpoint (ifcdesc, 2);
|
|
||||||
|
|
||||||
if (r_rid)
|
|
||||||
{
|
|
||||||
*r_rid = rid;
|
|
||||||
rid = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
free (rid);
|
|
||||||
|
|
||||||
*r_idev = idev;
|
|
||||||
libusb_free_config_descriptor (config);
|
libusb_free_config_descriptor (config);
|
||||||
return 1; /* Found requested device. */
|
free (rid);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
free (rid);
|
free (rid);
|
||||||
@ -1286,205 +1221,44 @@ scan_or_find_usb_device (int scan_mode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
libusb_free_config_descriptor (config);
|
libusb_free_config_descriptor (config);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Combination function to either scan all CCID devices or to find and
|
/* Scan all CCID devices.
|
||||||
open one specific device.
|
|
||||||
|
|
||||||
The function returns 0 if a reader has been found or when a scan
|
The function returns 0 if a reader has been found or when a scan
|
||||||
returned without error.
|
returned without error.
|
||||||
|
|
||||||
With READERNO = -1 and READERID is NULL, scan mode is used and
|
|
||||||
R_RID should be the address where to store the list of reader_ids
|
R_RID should be the address where to store the list of reader_ids
|
||||||
we found. If on return this list is empty, no CCID device has been
|
we found. If on return this list is empty, no CCID device has been
|
||||||
found; otherwise it points to an allocated linked list of reader
|
found; otherwise it points to an allocated linked list of reader
|
||||||
IDs. Note that in this mode the function always returns NULL.
|
IDs.
|
||||||
|
|
||||||
With READERNO >= 0 or READERID is not NULL find mode is used. This
|
|
||||||
uses the same algorithm as the scan mode but stops and returns at
|
|
||||||
the entry number READERNO and return the handle for the opened
|
|
||||||
USB device. If R_RID is not NULL it will receive the reader ID of
|
|
||||||
that device. If R_DEV is not NULL it will the device pointer of
|
|
||||||
that device. If IFCDESC_EXTRA is NOT NULL it will receive a
|
|
||||||
malloced copy of the interfaces "extra: data filed;
|
|
||||||
IFCDESC_EXTRA_LEN receive the length of this field. If there is
|
|
||||||
no reader with number READERNO or that reader is not usable by our
|
|
||||||
implementation NULL will be returned. The caller must close a
|
|
||||||
returned USB device handle and free (if not passed as NULL) the
|
|
||||||
returned reader ID info as well as the IFCDESC_EXTRA. On error
|
|
||||||
NULL will get stored at R_RID, R_DEV, IFCDESC_EXTRA and
|
|
||||||
IFCDESC_EXTRA_LEN. With READERID being -1 the function stops if
|
|
||||||
the READERID was found.
|
|
||||||
|
|
||||||
If R_FD is not -1 on return the device is not using USB for
|
|
||||||
transport but the device associated with that file descriptor. In
|
|
||||||
this case INTERFACE will receive the transport type and the other
|
|
||||||
USB specific return values are not used; the return value is
|
|
||||||
(void*)(1).
|
|
||||||
|
|
||||||
Note that the first entry of the returned reader ID list in scan mode
|
|
||||||
corresponds with a READERNO of 0 in find mode.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
scan_or_find_devices (int readerno, const char *readerid,
|
scan_devices (char **r_rid)
|
||||||
char **r_rid,
|
|
||||||
struct libusb_device_descriptor *r_desc,
|
|
||||||
unsigned char **ifcdesc_extra,
|
|
||||||
size_t *ifcdesc_extra_len,
|
|
||||||
int *interface_number, int *setting_number,
|
|
||||||
int *ep_bulk_out, int *ep_bulk_in, int *ep_intr,
|
|
||||||
libusb_device_handle **r_idev,
|
|
||||||
int *r_fd)
|
|
||||||
{
|
{
|
||||||
char *rid_list = NULL;
|
char *rid_list = NULL;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
libusb_device **dev_list = NULL;
|
libusb_device **dev_list = NULL;
|
||||||
libusb_device *dev;
|
libusb_device *dev;
|
||||||
libusb_device_handle *idev = NULL;
|
|
||||||
int scan_mode = (readerno == -1 && !readerid);
|
|
||||||
int i;
|
int i;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
struct libusb_device_descriptor desc;
|
|
||||||
|
|
||||||
/* Set return values to a default. */
|
/* Set return values to a default. */
|
||||||
if (r_rid)
|
if (r_rid)
|
||||||
*r_rid = NULL;
|
*r_rid = NULL;
|
||||||
if (ifcdesc_extra)
|
|
||||||
*ifcdesc_extra = NULL;
|
|
||||||
if (ifcdesc_extra_len)
|
|
||||||
*ifcdesc_extra_len = 0;
|
|
||||||
if (interface_number)
|
|
||||||
*interface_number = 0;
|
|
||||||
if (setting_number)
|
|
||||||
*setting_number = 0;
|
|
||||||
if (r_idev)
|
|
||||||
*r_idev = NULL;
|
|
||||||
if (r_fd)
|
|
||||||
*r_fd = -1;
|
|
||||||
|
|
||||||
/* See whether we want scan or find mode. */
|
|
||||||
if (scan_mode)
|
|
||||||
{
|
|
||||||
assert (r_rid);
|
|
||||||
}
|
|
||||||
|
|
||||||
n = libusb_get_device_list (NULL, &dev_list);
|
n = libusb_get_device_list (NULL, &dev_list);
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
dev = dev_list[i];
|
dev = dev_list[i];
|
||||||
if (scan_or_find_usb_device (scan_mode, readerno, &count, &rid_list,
|
scan_usb_device (&count, &rid_list, dev);
|
||||||
readerid,
|
|
||||||
dev,
|
|
||||||
r_rid,
|
|
||||||
&desc,
|
|
||||||
&idev,
|
|
||||||
ifcdesc_extra,
|
|
||||||
ifcdesc_extra_len,
|
|
||||||
interface_number, setting_number,
|
|
||||||
ep_bulk_out, ep_bulk_in, ep_intr))
|
|
||||||
{
|
|
||||||
libusb_free_device_list (dev_list, 1);
|
|
||||||
/* Found requested device or out of core. */
|
|
||||||
if (!idev)
|
|
||||||
{
|
|
||||||
free (rid_list);
|
|
||||||
return -1; /* error */
|
|
||||||
}
|
|
||||||
*r_idev = idev;
|
|
||||||
if (r_desc)
|
|
||||||
memcpy (r_desc, &desc, sizeof (struct libusb_device_descriptor));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_free_device_list (dev_list, 1);
|
libusb_free_device_list (dev_list, 1);
|
||||||
|
|
||||||
/* Now check whether there are any devices with special transport types. */
|
*r_rid = rid_list;
|
||||||
for (i=0; transports[i].name; i++)
|
return 0;
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
char *rid, *p;
|
|
||||||
|
|
||||||
fd = open (transports[i].name, O_RDWR);
|
|
||||||
if (fd == -1 && scan_mode && errno == EBUSY)
|
|
||||||
{
|
|
||||||
/* Ignore this error in scan mode because it indicates that
|
|
||||||
the device exists but is already open (most likely by us)
|
|
||||||
and thus in general suitable as a reader. */
|
|
||||||
}
|
|
||||||
else if (fd == -1)
|
|
||||||
{
|
|
||||||
DEBUGOUT_2 ("failed to open '%s': %s\n",
|
|
||||||
transports[i].name, strerror (errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rid = malloc (strlen (transports[i].name) + 30 + 10);
|
|
||||||
if (!rid)
|
|
||||||
{
|
|
||||||
if (fd != -1)
|
|
||||||
close (fd);
|
|
||||||
free (rid_list);
|
|
||||||
return -1; /* Error. */
|
|
||||||
}
|
|
||||||
sprintf (rid, "0000:%04X:%s:0", transports[i].type, transports[i].name);
|
|
||||||
if (scan_mode)
|
|
||||||
{
|
|
||||||
DEBUGOUT_2 ("found CCID reader %d (ID=%s)\n", count, rid);
|
|
||||||
p = malloc ((rid_list? strlen (rid_list):0) + 1 + strlen (rid) + 1);
|
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
if (fd != -1)
|
|
||||||
close (fd);
|
|
||||||
free (rid_list);
|
|
||||||
free (rid);
|
|
||||||
return -1; /* Error. */
|
|
||||||
}
|
|
||||||
*p = 0;
|
|
||||||
if (rid_list)
|
|
||||||
{
|
|
||||||
strcat (p, rid_list);
|
|
||||||
free (rid_list);
|
|
||||||
}
|
|
||||||
strcat (p, rid);
|
|
||||||
strcat (p, "\n");
|
|
||||||
rid_list = p;
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
else if (!readerno ||
|
|
||||||
(readerno < 0 && readerid && !strcmp (readerid, rid)))
|
|
||||||
{
|
|
||||||
/* Found requested device. */
|
|
||||||
if (interface_number)
|
|
||||||
*interface_number = transports[i].type;
|
|
||||||
if (r_rid)
|
|
||||||
*r_rid = rid;
|
|
||||||
else
|
|
||||||
free (rid);
|
|
||||||
if (r_fd)
|
|
||||||
*r_fd = fd;
|
|
||||||
return 0; /* Okay, found device */
|
|
||||||
}
|
|
||||||
else /* This is not yet the reader we want. */
|
|
||||||
{
|
|
||||||
if (readerno >= 0)
|
|
||||||
--readerno;
|
|
||||||
}
|
|
||||||
free (rid);
|
|
||||||
if (fd != -1)
|
|
||||||
close (fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scan_mode)
|
|
||||||
{
|
|
||||||
*r_rid = rid_list;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1517,8 +1291,7 @@ ccid_get_reader_list (void)
|
|||||||
initialized_usb = 1;
|
initialized_usb = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scan_or_find_devices (-1, NULL, &reader_list, NULL, NULL, NULL, NULL,
|
if (scan_devices (&reader_list))
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL))
|
|
||||||
return NULL; /* Error. */
|
return NULL; /* Error. */
|
||||||
return reader_list;
|
return reader_list;
|
||||||
}
|
}
|
||||||
@ -2484,7 +2257,7 @@ abort_cmd (ccid_driver_t handle, int seqno)
|
|||||||
if (!handle->idev)
|
if (!handle->idev)
|
||||||
{
|
{
|
||||||
/* I don't know how to send an abort to non-USB devices. */
|
/* I don't know how to send an abort to non-USB devices. */
|
||||||
rc = CCID_DRIVER_ERR_NOT_SUPPORTED;
|
return CCID_DRIVER_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
seqno &= 0xff;
|
seqno &= 0xff;
|
||||||
@ -2639,7 +2412,8 @@ send_escape_cmd (ccid_driver_t handle,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (result, msg, msglen);
|
memcpy (result, msg, msglen);
|
||||||
*resultlen = msglen;
|
if (resultlen)
|
||||||
|
*resultlen = msglen;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4006,9 +3780,7 @@ ccid_transceive_secure (ccid_driver_t handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
memcpy (resp, p, n);
|
memcpy (resp, p, n);
|
||||||
resp += n;
|
|
||||||
*nresp += n;
|
*nresp += n;
|
||||||
maxresplen -= n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(tpdu[1] & 0x20))
|
if (!(tpdu[1] & 0x20))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user