"not yet implemented",
"checksum mismatch",
"operation would block",
- "invalid command for operation"
+ "invalid command for operation",
+ "expected only one YubiKey but several present",
};
const char *yk_strerror(int errnum)
{
#define YK_ECHECKSUM 0x0a /* checksum validation failed */
#define YK_EWOULDBLOCK 0x0b /* operation would block */
#define YK_EINVALIDCMD 0x0c /* supplied command is invalid for this operation */
+#define YK_EMORETHANONE 0x0d /* expected to find only one key but found more */
/* Flags for response reading. Use high numbers to not exclude the possibility
* to combine these with for example SLOT commands from ykdef.h in the future.
void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
{
- libusb_device *dev;
+ libusb_device *dev = NULL;
libusb_device_handle *h = NULL;
struct libusb_device_descriptor desc;
libusb_device **list;
int rc = YK_ENOKEY;
for (i = 0; i < cnt; i++) {
- dev = list[i];
- ykl_errno = libusb_get_device_descriptor(dev, &desc);
+ ykl_errno = libusb_get_device_descriptor(list[i], &desc);
if (ykl_errno != 0)
goto done;
size_t j;
for(j = 0; j < pids_len; j++) {
if (desc.idProduct == product_ids[j]) {
- break;
+ if(dev == NULL) {
+ dev = list[i];
+ break;
+ } else {
+ rc = YK_EMORETHANONE;
+ goto done;
+ }
}
}
- if (j != pids_len) {
- rc = YK_EUSBERR;
- ykl_errno = libusb_open(dev, &h);
- if (ykl_errno != 0)
- goto done;
- ykl_errno = libusb_detach_kernel_driver(h, 0);
- if (ykl_errno != 0)
- goto done;
- /* This is needed for yubikey-personalization to work inside virtualbox virtualization. */
- ykl_errno = libusb_set_configuration(h, 1);
- goto done;
- }
}
}
+
+ if (dev) {
+ rc = YK_EUSBERR;
+ ykl_errno = libusb_open(dev, &h);
+ if (ykl_errno != 0)
+ goto done;
+ ykl_errno = libusb_detach_kernel_driver(h, 0);
+ if (ykl_errno != 0)
+ goto done;
+ /* This is needed for yubikey-personalization to work inside virtualbox virtualization. */
+ ykl_errno = libusb_set_configuration(h, 1);
+ goto done;
+ }
done:
libusb_free_device_list(list, 1);
if (h == NULL)
struct usb_device *dev;
struct usb_dev_handle *h = NULL;
int rc = YK_EUSBERR;
+ int found = 0;
for (bus = usb_get_busses(); bus; bus = bus->next) {
rc = YK_ENOKEY;
- for (dev = bus->devices; dev; dev = dev->next)
+ for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor == vendor_id) {
size_t j;
for (j = 0; j < pids_len; j++) {
if (dev->descriptor.idProduct == product_ids[j]) {
- break;
+ if(found == 0) {
+ found = 1;
+ break;
+ } else {
+ rc = YK_EMORETHANONE;
+ goto done;
+ }
}
}
- if(j != pids_len) {
- rc = YK_EUSBERR;
- h = usb_open(dev);
+ }
+ }
+ }
+ if(found == 1) {
+ rc = YK_EUSBERR;
+ h = usb_open(dev);
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
- if (h != NULL)
- usb_detach_kernel_driver_np(h, 0);
+ if (h != NULL)
+ usb_detach_kernel_driver_np(h, 0);
#endif
- /* This is needed for yubikey-personalization to work inside virtualbox virtualization. */
- if (h != NULL)
- usb_set_configuration(h, 1);
- goto done;
- }
- }
+ /* This is needed for yubikey-personalization to work inside virtualbox virtualization. */
+ if (h != NULL)
+ usb_set_configuration(h, 1);
+ goto done;
}
done:
if (h == NULL)
CFIndex cnt = CFArrayGetCount( array );
- if (cnt > 0) {
+ if (cnt == 1) {
yk = (void *) CFArrayGetValueAtIndex( array, 0 );
CFRetain(yk);
+ } else if(cnt > 1) {
+ rc = YK_EMORETHANONE;
}
else {
rc = YK_ENOKEY;
size_t j;
for (j = 0; j < pids_len; j++) {
if (devInfo.ProductID == product_ids[j]) {
- break;
+ if(ret_handle == NULL) {
+ ret_handle = m_handle;
+ break;
+ } else {
+ rc = YK_EMORETHANONE;
+ goto done;
+ }
}
}
- if (j != pids_len) {
- ret_handle = m_handle;
- free (pi);
- goto done;
- }
}
}
}
- CloseHandle (m_handle);
+ if(ret_handle == NULL) {
+ CloseHandle (m_handle);
+ }
}
free (pi);
-
- if (!rc)
- break;
}
yk_errno = YK_ENOKEY;