]> err.no Git - yubikey-personalization/commitdiff
let _ykusb_open_device() error on several keys present
authorKlas Lindfors <klas@yubico.com>
Sun, 6 Jan 2013 10:58:04 +0000 (11:58 +0100)
committerKlas Lindfors <klas@yubico.com>
Sun, 6 Jan 2013 10:58:04 +0000 (11:58 +0100)
if more than one YubiKey is present _ykusb_open_device()
will return YK_EMORETHANONE.

ykcore/ykcore.c
ykcore/ykcore.h
ykcore/ykcore_libusb-1.0.c
ykcore/ykcore_libusb.c
ykcore/ykcore_osx.c
ykcore/ykcore_windows.c

index bd70a663e512852301e8594da13b90326ee6efd6..9694c711db855f8d7041de1c110779f2074074fd 100644 (file)
@@ -394,7 +394,8 @@ static const char *errtext[] = {
        "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)
 {
index 40c6f02723df27d5fa18b21713dcd57478e74584..8d032a56b7c77c43cd56f1bdcf5061c4a4feb363 100644 (file)
@@ -159,6 +159,7 @@ const char *yk_usb_strerror(void);
 #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.
index 8c6e9744f7921a408506398776eecca1dfa47280..513fb8a84ad11f4fa287e0b8b5541e2048a27c55 100644 (file)
@@ -159,7 +159,7 @@ extern int _ykusb_stop(void)
 
 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;
@@ -168,8 +168,7 @@ void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
        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;
 
@@ -177,23 +176,30 @@ void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
                        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)
index 0141a88366da12564c5e139608d35cda07fcf5b2..35cd68083653f014f3e50c35f1bbb032822b322e 100644 (file)
@@ -151,30 +151,38 @@ void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
        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)
index c59f4842ae4463b7125d83eee1f9006f0af2a0f5..003802ec14651fb0a967162e542bb05efc7be3a1 100644 (file)
@@ -109,9 +109,11 @@ void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
 
                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;
index d91ef45045521545041c1910b84f2812448e2924..4f437ff93aae4cbf9d2dd99c1bc3d5f4b65cf97f 100644 (file)
@@ -96,24 +96,24 @@ void * _ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
                                                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;