From 7542524804c941a34863bee49446922ce635e308 Mon Sep 17 00:00:00 2001 From: Michael Gmelin Date: Fri, 27 May 2022 13:13:56 +0000 Subject: [PATCH] security/py-yubikey-manager: Add OTP HID support for FreeBSD This makes yubikey-manager usable on FreeBSD again. FreeBSD support was broken since reliance on libusb and libykpersonalize was dropped in 4.0.0. This supports the classic uhid(4) driver and the more modern hidraw(4) driver. See: https://github.com/Yubico/yubikey-manager/pull/504 --- security/py-yubikey-manager/Makefile | 5 +- .../files/patch-README.adoc | 47 +++ .../files/patch-ykman_hid_____init____.py | 20 ++ .../files/patch-ykman_hid_freebsd.py | 301 ++++++++++++++++++ security/py-yubikey-manager/pkg-message | 34 ++ 5 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 security/py-yubikey-manager/files/patch-README.adoc create mode 100644 security/py-yubikey-manager/files/patch-ykman_hid_____init____.py create mode 100644 security/py-yubikey-manager/files/patch-ykman_hid_freebsd.py create mode 100644 security/py-yubikey-manager/pkg-message diff --git a/security/py-yubikey-manager/Makefile b/security/py-yubikey-manager/Makefile index d5f76fe26e..770c47258e 100644 --- a/security/py-yubikey-manager/Makefile +++ b/security/py-yubikey-manager/Makefile @@ -1,5 +1,6 @@ PORTNAME= yubikey-manager PORTVERSION= 4.0.8 +PORTREVISION= 1 CATEGORIES= security python MASTER_SITES= CHEESESHOP PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} @@ -22,9 +23,11 @@ RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}click>0:devel/py-click@${PY_FLAVOR} \ u2f-host:security/libu2f-host \ ykpersonalize:security/ykpers -USES= python:3.6+ +USES= dos2unix python:3.6+ USE_PYTHON= autoplist concurrent distutils +DOS2UNIX_GLOB= *.adoc *.py + NO_ARCH= yes .include diff --git a/security/py-yubikey-manager/files/patch-README.adoc b/security/py-yubikey-manager/files/patch-README.adoc new file mode 100644 index 0000000000..2c7ab76bfd --- /dev/null +++ b/security/py-yubikey-manager/files/patch-README.adoc @@ -0,0 +1,47 @@ +See https://github.com/Yubico/yubikey-manager/commit/ecd7897b3f02054 +--- README.adoc.orig 2022-05-27 13:02:44 UTC ++++ README.adoc +@@ -106,8 +106,43 @@ installed on FreeBSD. It's available via its ports tre + Should you opt to install and use YubiKey Manager on this platform, please be aware + that it's **NOT** maintained by Yubico. + ++To install the binary package, use `pkg install pyXY-yubikey-manager`, with `pyXY` ++specifying the version of Python the package was built for, so in order to install ++YubiKey Manager for Python 3.8, use: ++ ++ # pkg install py38-yubikey-manager ++ + For more information about how to install packages or ports on FreeBSD, please refer + to its official documentation: https://docs.freebsd.org/en/books/handbook/ports[FreeBSD Handbook]. ++ ++In order to use `ykman otp` commands, you need to make sure the _uhid(4)_ driver ++attaches to the USB device: ++ ++ # usbconfig ugenX.Y add_quirk UQ_KBD_IGNORE ++ # usbconfig ugenX.Y reset ++ ++The correct device to operate on _(ugenX.Y)_ can be determined using ++`usbconfig list`. ++ ++When using FreeBSD 13 or higher, you can switch to the more modern _hidraw(4)_ ++driver. This allows YubiKey Manager to access OTP HID in a non-exclusive way, ++so that the key will still function as a USB keyboard: ++ ++ # sysrc kld_list+="hidraw hkbd" ++ # cat >>/boot/loader.conf<>/boot/loader.conf< ++HIDIOCGRAWINFO = 0x40085520 ++HIDIOCGRDESC = 0x2000551F ++HIDIOCGRDESCSIZE = 0x4004551E ++HIDIOCGFEATURE_9 = 0xC0095524 ++HIDIOCSFEATURE_9 = 0x80095523 ++ ++ ++class HidrawConnection(OtpConnection): ++ """ ++ hidraw(4) is FreeBSD's modern raw access driver, based on usbhid(4). ++ It is available since FreeBSD 13 and can be activated by adding ++ `hw.usb.usbhid.enable="1"` to `/boot/loader.conf`. The actual kernel ++ module is loaded with `kldload hidraw`. ++ """ ++ ++ def __init__(self, path): ++ self.fd = os.open(path, os.O_RDWR) ++ ++ def close(self): ++ os.close(self.fd) ++ ++ def receive(self): ++ buf = bytearray(1 + 8) ++ fcntl.ioctl(self.fd, HIDIOCGFEATURE_9, buf, True) ++ return buf[1:] ++ ++ def send(self, data): ++ buf = bytes([0]) + data ++ fcntl.ioctl(self.fd, HIDIOCSFEATURE_9, buf) ++ ++ @staticmethod ++ def get_info(dev): ++ buf = bytearray(4 + 2 + 2) ++ fcntl.ioctl(dev, HIDIOCGRAWINFO, buf, True) ++ return struct.unpack("B", data)[0], data[1:] ++ key, size = REPORT_DESCRIPTOR_KEY_MASK & head, SIZE_MASK & head ++ value = struct.unpack_from(">/boot/loader.conf<