]> err.no Git - yubikey-personalization.old/commitdiff
Add libusb-1.0 support from Tollef Fog Heen.
authorSimon Josefsson <simon@josefsson.org>
Tue, 4 Aug 2009 09:32:59 +0000 (09:32 +0000)
committerSimon Josefsson <simon@josefsson.org>
Tue, 4 Aug 2009 09:32:59 +0000 (09:32 +0000)
AUTHORS
NEWS
configure.ac
ykcore/Makefile.am
ykcore/ykcore_libusb-1.0.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index b6290ed575baa16787ac650f0bbd8d288ebcf33b..c08798dee4976704ce2375b887bfcd11c1b7f2a3 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,3 +17,6 @@ Added ykp_AES_key_from_hex and ykpersonalize -a parameter.
 
 Christer Kaivo-oja <christer.kaivooja@gmail.com>
 Mac OS X port.
+
+Tollef Fog Heen <tfheen@err.no>
+Support for libusb-1.0 backend.
diff --git a/NEWS b/NEWS
index 0cd62ad5271b182c47a80caa6047df2c5d06cb1e..7402aefa85175e33b678b0a67c7b662c3a4c6c8c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ Yubikey-personalize NEWS -- History of user-visible changes.     -*- outline -*-
 
 * Version 0.93 (unreleased)
 
+** Support for libusb-1.0 through --with-backend=libusb-1.0.
+Thanks to Tollef Fog Heen.
+
 ** Clarify -a parameter.
 Thanks to Alphonse R.M. Hoge.
 
index dd18a272b306aa3f03c86e14802f3a635126bbac..f66ad51d110f966423f650aa2bb2c15f7df1e6c9 100644 (file)
@@ -62,7 +62,7 @@ AC_ARG_WITH([backend],
   [AS_HELP_STRING([--with-backend=ARG],
     [use specific backend; 'libusb' or 'osx'])])
 AC_MSG_CHECKING([for backend])
-if test x$with_backend != xosx && test x$with_backend != xlibusb; then
+if test x$with_backend != xosx && test x$with_backend != xlibusb && test x$with_backend != xlibusb-1.0; then
   AC_CANONICAL_HOST
   case "$host" in
     *-darwin*) with_backend=osx ;;
@@ -71,8 +71,13 @@ if test x$with_backend != xosx && test x$with_backend != xlibusb; then
 fi
 AC_MSG_RESULT([$with_backend])
 AM_CONDITIONAL([BACKEND_LIBUSB], test x$with_backend = xlibusb)
+AM_CONDITIONAL([BACKEND_LIBUSB_1_0], test x$with_backend = xlibusb-1.0)
 AM_CONDITIONAL([BACKEND_OSX], test x$with_backend = xosx)
 
+if test x$with_backend = xlibusb-1.0; then
+   PKG_CHECK_MODULES([LIBUSB], [libusb-1.0])
+fi
+
 if test x$with_backend = xlibusb; then
   AC_LIB_HAVE_LINKFLAGS(usb,, [#include <usb.h>], [usb_init()])
   if test "$ac_cv_libusb" != yes; then
index 3b595a3d12cf25ece0f07ad235d5e3d79072c2d6..c5ddc52d90ad61b152e8ea0eeec303b6289fb786 100644 (file)
 noinst_LTLIBRARIES = libykcore.la
 libykcore_la_SOURCES = ykdef.h ykcore.h ykcore_lcl.h ykcore_backend.h  \
        ykcore.c ykstatus.h ykstatus.c yktsd.h
-libykcore_la_LIBADD = $(LTLIBYUBIKEY) $(LTLIBUSB)
+libykcore_la_LIBADD = $(LTLIBYUBIKEY) $(LTLIBUSB) @LIBUSB_LIBS@
+
+if BACKEND_LIBUSB_1_0
+libykcore_la_SOURCES += ykcore_libusb-1.0.c
+AM_CFLAGS = @LIBUSB_CFLAGS@
+endif
 
 if BACKEND_LIBUSB
 libykcore_la_SOURCES += ykcore_libusb.c
diff --git a/ykcore/ykcore_libusb-1.0.c b/ykcore/ykcore_libusb-1.0.c
new file mode 100644 (file)
index 0000000..ec944f1
--- /dev/null
@@ -0,0 +1,192 @@
+/* -*- mode:C; c-file-style: "bsd" -*- */
+/*
+ * Copyright (c) 2009, Tollef Fog Heen <tfheen@err.no>
+ * Copyright (c) 2008, 2009, Yubico AB
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <libusb.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ykcore.h"
+#include "ykdef.h"
+#include "ykcore_backend.h"
+
+#define HID_GET_REPORT                 0x01
+#define HID_SET_REPORT                 0x09
+
+static int ykl_errno;
+
+/*************************************************************************
+ **  function _ykusb_write                                             **
+ **  Set HID report                                                    **
+ **                                                                    **
+ **  int _ykusb_write(YUBIKEY *yk, int report_type, int report_number, **
+ **                    char *buffer, int size)                         **
+ **                                                                    **
+ **  Where:                                                            **
+ **  "yk" is handle to open Yubikey                                    **
+ **  "report_type" is HID report type (in, out or feature)             **
+ **  "report_number" is report identifier                              **
+ **  "buffer" is pointer to in buffer                                  **
+ **  "size" is size of the buffer                                      **
+ **                                                                    **
+ **  Returns: Nonzero if successful, zero otherwise                    **
+ **                                                                    **
+ *************************************************************************/
+
+int _ykusb_write(void *dev, int report_type, int report_number,
+                char *buffer, int size)
+{
+       ykl_errno = libusb_claim_interface((libusb_device_handle *)dev, 0);
+
+       if (ykl_errno == 0) {
+               int rc2;
+               ykl_errno = libusb_control_transfer((libusb_device_handle *)dev,
+                                            LIBUSB_REQUEST_TYPE_CLASS |
+                                            LIBUSB_RECIPIENT_INTERFACE |
+                                            LIBUSB_ENDPOINT_OUT,
+                                            HID_SET_REPORT,
+                                            report_type << 8 | report_number, 0,
+                                            buffer, size,
+                                            1000);
+               /* preserve a control message error over an interface
+                  release one */
+               rc2 = libusb_release_interface((libusb_device_handle *)dev, 0);
+               if (ykl_errno > 0 && rc2 < 0)
+                       ykl_errno = rc2;
+       }
+       if (ykl_errno > 0)
+               return 1;
+       yk_errno = YK_EUSBERR;
+       return 0;
+}
+
+/*************************************************************************
+**  function _ykusb_read                                               **
+**  Get HID report                                                     **
+**                                                                      **
+**  int _ykusb_read(YUBIKEY *dev, int report_type, int report_number,  **
+**                    char *buffer, int size)                          **
+**                                                                      **
+**  Where:                                                              **
+**  "dev" is handle to open Yubikey                                    **
+**  "report_type" is HID report type (in, out or feature)              **
+**  "report_number" is report identifier                                       **
+**  "buffer" is pointer to in buffer                                   **
+**  "size" is size of the buffer                                       **
+**                                                                     **
+**  Returns: Number of bytes read. Zero if failure                     **
+**                                                                      **
+*************************************************************************/
+
+int _ykusb_read(void *dev, int report_type, int report_number,
+               char *buffer, int size)
+{
+       ykl_errno = libusb_claim_interface((libusb_device_handle *)dev, 0);
+
+       if (ykl_errno == 0) {
+               int rc2;
+               ykl_errno = libusb_control_transfer((libusb_device_handle *)dev,
+                                            LIBUSB_REQUEST_TYPE_CLASS |
+                                            LIBUSB_RECIPIENT_INTERFACE | 
+                                            LIBUSB_ENDPOINT_IN,
+                                            HID_GET_REPORT,
+                                            report_type << 8 | report_number, 0,
+                                    buffer, size,
+                                    1000);
+               /* preserve a control message error over an interface
+                  release one */
+               rc2 = libusb_release_interface((libusb_device_handle *)dev, 0);
+               if (ykl_errno > 0 && rc2 < 0)
+                       ykl_errno = rc2;
+       }
+       if (ykl_errno > 0)
+               return ykl_errno;
+       yk_errno = YK_EUSBERR;
+       return 0;
+}
+
+int _ykusb_start(void)
+{
+       int rc;
+       libusb_init(NULL);
+       return 1;
+}
+
+extern int _ykusb_stop(void)
+{
+       libusb_exit(NULL);
+       return 1;
+}
+
+void *_ykusb_open_device(int vendor_id, int product_id)
+{
+       libusb_device *dev;
+       libusb_device_handle *h = NULL;
+       struct libusb_device_descriptor desc;
+       libusb_device **list;
+       size_t cnt = libusb_get_device_list(NULL, &list);
+       size_t i = 0;
+       int rc = YK_ENOKEY;
+
+       for (i = 0; i < cnt; i++) {
+               dev = list[i];
+               ykl_errno = libusb_get_device_descriptor(dev, &desc);
+               if (ykl_errno != 0)
+                       goto done;
+
+               if (desc.idVendor == YUBICO_VID && desc.idProduct == YUBIKEY_PID) {
+                       rc = YK_EUSBERR;
+                       ykl_errno = libusb_open(dev, &h);
+                       if (ykl_errno != 0)
+                               goto done;
+                       ykl_errno = libusb_detach_kernel_driver(h, 0);
+                       goto done;
+               }
+       }
+ done:
+       libusb_free_device_list(list, 1);
+       if (h == NULL)
+               yk_errno = rc;
+       return h;
+}
+
+int _ykusb_close_device(void *yk)
+{
+       libusb_attach_kernel_driver(yk, 0);
+       libusb_close((libusb_device_handle *) yk);
+       return 1;
+}
+
+const char *_ykusb_strerror()
+{
+       static char buf[512];
+       snprintf(buf, sizeof(buf), "%s %d", "NOT IMPLEMENTED", ykl_errno);
+       return buf;
+}