mirror of https://github.com/Yubico/python-fido2
FreeBSD: remove dependency on uhid-freebsd.
This commit is contained in:
parent
142587b3e6
commit
bd36cbcf35
|
@ -18,8 +18,10 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from ctypes.util import find_library
|
||||
import ctypes
|
||||
import re
|
||||
import os
|
||||
import uhid_freebsd
|
||||
|
||||
from .base import HidDescriptor, parse_report_descriptor, FileCtapHidConnection
|
||||
|
||||
|
@ -28,20 +30,105 @@ import logging
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
devdir = "/dev/"
|
||||
|
||||
device_re = re.compile("^uhid([0-9]+)$")
|
||||
vendor_re = re.compile("vendor=(0x[0-9a-fA-F]+)")
|
||||
product_re = re.compile("product=(0x[0-9a-fA-F]+)")
|
||||
sernum_re = re.compile('sernum="([^"]+)')
|
||||
|
||||
libc = ctypes.CDLL(find_library("c"))
|
||||
|
||||
USB_GET_REPORT_DESC = 0xC0205515
|
||||
|
||||
|
||||
class usb_gen_descriptor(ctypes.Structure):
|
||||
_fields_ = [
|
||||
(
|
||||
"ugd_data",
|
||||
ctypes.c_void_p,
|
||||
), # TODO: check what COMPAT_32BIT in C header means
|
||||
("ugd_lang_id", ctypes.c_uint16),
|
||||
("ugd_maxlen", ctypes.c_uint16),
|
||||
("ugd_actlen", ctypes.c_uint16),
|
||||
("ugd_offset", ctypes.c_uint16),
|
||||
("ugd_config_index", ctypes.c_uint8),
|
||||
("ugd_string_index", ctypes.c_uint8),
|
||||
("ugd_iface_index", ctypes.c_uint8),
|
||||
("ugd_altif_index", ctypes.c_uint8),
|
||||
("ugd_endpt_index", ctypes.c_uint8),
|
||||
("ugd_report_type", ctypes.c_uint8),
|
||||
("reserved", ctypes.c_uint8 * 8),
|
||||
]
|
||||
|
||||
|
||||
def open_connection(descriptor):
|
||||
return FileCtapHidConnection(descriptor)
|
||||
|
||||
|
||||
def _get_report_data(fd, report_type):
|
||||
data = ctypes.create_string_buffer(b"\000" * 4096)
|
||||
desc = usb_gen_descriptor(
|
||||
ugd_data=ctypes.addressof(data),
|
||||
ugd_maxlen=ctypes.sizeof(data),
|
||||
report_type=report_type,
|
||||
)
|
||||
ret = libc.ioctl(fd, USB_GET_REPORT_DESC, ctypes.byref(desc))
|
||||
if ret != 0:
|
||||
raise ValueError("ioctl failed")
|
||||
return data.raw[: desc.ugd_actlen]
|
||||
|
||||
|
||||
def _read_descriptor(vid, pid, name, serial, path):
|
||||
fd = os.open(path, os.O_RDONLY)
|
||||
data = uhid_freebsd.get_report_data(fd, 3)
|
||||
data = _get_report_data(fd, 3)
|
||||
os.close(fd)
|
||||
max_in_size, max_out_size = parse_report_descriptor(data)
|
||||
return HidDescriptor(path, vid, pid, max_in_size, max_out_size, name, serial)
|
||||
|
||||
|
||||
def _enumerate():
|
||||
for uhid in os.listdir(devdir):
|
||||
|
||||
m = device_re.search(uhid)
|
||||
if m is None:
|
||||
continue
|
||||
|
||||
index = m.group(1)
|
||||
pnpinfo = ("dev.uhid." + index + ".%pnpinfo").encode()
|
||||
desc = ("dev.uhid." + index + ".%desc").encode()
|
||||
|
||||
ovalue = ctypes.create_string_buffer(b"\000" * 1024)
|
||||
olen = ctypes.c_size_t(ctypes.sizeof(ovalue))
|
||||
key = ctypes.c_char_p(pnpinfo)
|
||||
retval = libc.sysctlbyname(key, ovalue, ctypes.byref(olen), None, None)
|
||||
if retval != 0:
|
||||
continue
|
||||
|
||||
dev = {}
|
||||
dev["name"] = uhid
|
||||
dev["path"] = devdir + uhid
|
||||
|
||||
value = ovalue.value.decode()
|
||||
m = vendor_re.search(value)
|
||||
dev["vendor_id"] = m.group(1) if m else None
|
||||
|
||||
m = product_re.search(value)
|
||||
dev["product_id"] = m.group(1) if m else None
|
||||
|
||||
m = sernum_re.search(value)
|
||||
dev["serial_number"] = m.group(1) if m else None
|
||||
|
||||
key = ctypes.c_char_p(desc)
|
||||
retval = libc.sysctlbyname(key, ovalue, ctypes.byref(olen), None, None)
|
||||
if retval == 0:
|
||||
dev["product_desc"] = ovalue.value.decode() or None
|
||||
|
||||
yield dev
|
||||
|
||||
|
||||
def get_descriptor(path):
|
||||
for dev in uhid_freebsd.enumerate():
|
||||
for dev in _enumerate():
|
||||
if dev["path"] == path:
|
||||
vid = dev["vendor_id"]
|
||||
pid = dev["product_id"]
|
||||
|
@ -53,7 +140,7 @@ def get_descriptor(path):
|
|||
|
||||
def list_descriptors():
|
||||
descriptors = []
|
||||
for dev in uhid_freebsd.enumerate():
|
||||
for dev in _enumerate():
|
||||
try:
|
||||
name = dev["product_desc"] or None
|
||||
serial = (dev["serial_number"] if "serial_number" in dev else None) or None
|
||||
|
|
6
setup.py
6
setup.py
|
@ -53,11 +53,7 @@ setup(
|
|||
description="Python based FIDO 2.0 library",
|
||||
url="https://github.com/Yubico/python-fido2",
|
||||
python_requires=">=2.7.6,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*",
|
||||
install_requires=[
|
||||
"six",
|
||||
"cryptography>=1.5",
|
||||
'uhid-freebsd>=1.2.1;platform_system=="FreeBSD"',
|
||||
],
|
||||
install_requires=["six", "cryptography>=1.5"],
|
||||
extras_require={':python_version < "3.4"': ["enum34"], "pcsc": ["pyscard"]},
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: BSD License",
|
||||
|
|
Loading…
Reference in New Issue