Merge branch 'master' into feature/winbio-data

This commit is contained in:
Mary Strodl 2020-08-06 00:31:09 -04:00
commit 26d9fa8eb3
No known key found for this signature in database
GPG key ID: 23B7FC1590D8E30E
20 changed files with 152 additions and 96 deletions

17
.gitignore vendored
View file

@ -1,16 +1,17 @@
debian/tmp/
debian/debhelper-build-stamp
debian/python3-validity/
debian/python3-validity.substvars
debian/files
debian/*.debhelper debian/*.debhelper
debian/.debhelper/ debian/.debhelper/
debian/debhelper-build-stamp
debian/files
debian/python3-validity.substvars
debian/python3-validity/
debian/tmp/
__pycache__ *.bin
*.log
.idea/*
.pybuild/ .pybuild/
__pycache__
build build
dist dist
python_validity.egg-info/ python_validity.egg-info/
tls.dict tls.dict
*.bin
*.log

View file

@ -57,6 +57,24 @@ auth [success=2 default=ignore] pam_fprintd.so max_tries=1 timeout=10 # debug
auth [success=1 default=ignore] pam_unix.so nullok_secure try_first_pass auth [success=1 default=ignore] pam_unix.so nullok_secure try_first_pass
``` ```
## Windows interoperability
Note: This section is likely only relevant if you will be dual booting.
To be able to use the same set of fingerprints for Windows and Linux, you first
need to extract the Windows user IDs (known as SIDs). To do this, start Windows,
start `cmd.exe` and run `wmic useraccount get name,sid`. This will provide a
list of all users and the corresponding SIDs.
You can then create a mapping from the Linux user names (as written in the
first `:`-separated field of `/etc/passwd`). This mapping is defined in
`/etc/python-validity/dbus-service.yaml`. For example:
```yaml
user_to_sid:
"myusername": "S-1-5-21-1234567890-1234567890-1234567890-1001"
"someotheruser": "S-1-5-21-1234567890-1234567890-1234567890-1003"
```
## Playground ## Playground
This package contains a set of scripts you can use to do a low-level debugging of the sensor protocol. This package contains a set of scripts you can use to do a low-level debugging of the sensor protocol.

View file

@ -1,18 +1,23 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import signal
import argparse import argparse
import re
import os import os
import pwd import pwd
import re
import signal
import sys import sys
import time import time
import typing
from binascii import hexlify, unhexlify
from pathlib import Path
from threading import Thread
import dbus import dbus
import dbus.mainloop.glib import dbus.mainloop.glib
import dbus.service import dbus.service
import yaml
from usb import core as usb_core from usb import core as usb_core
from binascii import hexlify, unhexlify
from threading import Thread
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
from gi.repository import GLib from gi.repository import GLib
import logging import logging
@ -22,44 +27,55 @@ from validitysensor import init
from validitysensor.tls import tls from validitysensor.tls import tls
from validitysensor.usb import usb from validitysensor.usb import usb
from validitysensor.sid import sid_from_string from validitysensor.sid import sid_from_string
from validitysensor.db import subtype_to_string, db from validitysensor.db import subtype_to_string, db, SidIdentity, User
from validitysensor.sensor import sensor, reboot, RebootException from validitysensor.sensor import sensor, RebootException
from validitysensor.winbio_constants import finger_ids from validitysensor.winbio_constants import finger_ids
GLib.threads_init() GLib.threads_init()
INTERFACE_NAME='io.github.uunicorn.Fprint.Device' INTERFACE_NAME = 'io.github.uunicorn.Fprint.Device'
loop = GLib.MainLoop() loop = GLib.MainLoop()
class NoEnrolledPrints(dbus.DBusException): class NoEnrolledPrints(dbus.DBusException):
_dbus_error_name = 'net.reactivated.Fprint.Error.NoEnrolledPrints' _dbus_error_name = 'net.reactivated.Fprint.Error.NoEnrolledPrints'
def __init__(self): def __init__(self):
super().__init__('No enrolled prints found') super().__init__('No enrolled prints found')
def uid2identity(uid):
sidstr='S-1-5-21-111111111-1111111111-1111111111-%d' % uid
return sid_from_string(sidstr)
class Device(dbus.service.Object): class Device(dbus.service.Object):
def __init__(self, bus_name): def __init__(self, bus_name: dbus.Bus, config: typing.Dict[str, typing.Any]):
dbus.service.Object.__init__(self, bus_name, '/io/github/uunicorn/Fprint/Device') dbus.service.Object.__init__(self, bus_name, '/io/github/uunicorn/Fprint/Device')
self.config = config
def user2identity(self, user: str) -> SidIdentity:
"""Compute UID to SID mapping"""
pw = pwd.getpwnam(user)
uid = pw.pw_uid
if user in self.config['user_to_sid']:
sidstr = self.config['user_to_sid'][user]
else:
sidstr = 'S-1-5-21-111111111-1111111111-1111111111-%d' % uid
return sid_from_string(sidstr)
def user2record(self, user: str) -> User:
"""Resolve user name to database object"""
return db.lookup_user(self.user2identity(user))
@dbus.service.method(dbus_interface=INTERFACE_NAME, @dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature="s", in_signature="s",
out_signature="as") out_signature="as")
def ListEnrolledFingers(self, usr): def ListEnrolledFingers(self, user):
try: try:
logging.debug('In ListEnrolledFingers %s' % usr) logging.debug('In ListEnrolledFingers %s' % user)
pw=pwd.getpwnam(usr) usr = self.user2record(user)
uid=pw.pw_uid
usr=db.lookup_user(uid2identity(uid))
if usr == None: if usr is None:
return [] return []
rc = [subtype_to_string(f['subtype']) for f in usr.fingers] rc = [subtype_to_string(f['subtype']) for f in usr.fingers]
logging.debug(repr(rc)) logging.debug(repr(rc))
return rc return rc
@ -67,14 +83,13 @@ class Device(dbus.service.Object):
raise e raise e
@dbus.service.method(dbus_interface=INTERFACE_NAME, @dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature='s', in_signature='s',
out_signature='') out_signature='')
def DeleteEnrolledFingers(self, user): def DeleteEnrolledFingers(self, user):
logging.debug('In DeleteEnrolledFingers %s' % user) logging.debug('In DeleteEnrolledFingers %s' % user)
pw=pwd.getpwnam(user) usr = self.user2record(user)
usr=db.lookup_user(uid2identity(pw.pw_uid))
if usr == None: if usr is None:
return return
db.del_record(usr.dbid) db.del_record(usr.dbid)
@ -85,10 +100,9 @@ class Device(dbus.service.Object):
def VerifyStart(self, user, finger): def VerifyStart(self, user, finger):
logging.debug('In VerifyStart for %s, %s' % (user, finger)) logging.debug('In VerifyStart for %s, %s' % (user, finger))
pw = pwd.getpwnam(user) usr = self.user2record(user)
usr = db.lookup_user(uid2identity(pw.pw_uid))
if usr == None: if usr is None:
raise NoEnrolledPrints() raise NoEnrolledPrints()
self.VerifyFingerSelected('any') self.VerifyFingerSelected('any')
@ -115,7 +129,6 @@ class Device(dbus.service.Object):
thread = Thread(target=run) thread = Thread(target=run)
thread.daemon = True thread.daemon = True
thread.start() thread.start()
@dbus.service.method(dbus_interface=INTERFACE_NAME, @dbus.service.method(dbus_interface=INTERFACE_NAME,
in_signature='', in_signature='',
@ -128,8 +141,6 @@ class Device(dbus.service.Object):
out_signature='') out_signature='')
def EnrollStart(self, user, finger_name): def EnrollStart(self, user, finger_name):
logging.debug('In EnrollStart %s for %s' % (finger_name, user)) logging.debug('In EnrollStart %s for %s' % (finger_name, user))
pw=pwd.getpwnam(user)
uid=pw.pw_uid
# left-ring-finger => LH # left-ring-finger => LH
hand = 'LH' if finger_name[0] == 'l' else 'RH' hand = 'LH' if finger_name[0] == 'l' else 'RH'
@ -137,6 +148,9 @@ class Device(dbus.service.Object):
generic_finger = '_'.join(finger_name.split('-')[1:]).upper() generic_finger = '_'.join(finger_name.split('-')[1:]).upper()
winbio_name = 'WINBIO_ANSI_381_POS_' + hand + '_' + generic_finger winbio_name = 'WINBIO_ANSI_381_POS_' + hand + '_' + generic_finger
usr = self.user2identity(user)
index = finger_ids.get(winbio_name, None)
def update_cb(rsp, e): def update_cb(rsp, e):
if e is not None: if e is not None:
self.EnrollStatus('enroll-retry-scan', False) self.EnrollStatus('enroll-retry-scan', False)
@ -145,7 +159,7 @@ class Device(dbus.service.Object):
def run(): def run():
try: try:
sensor.enroll(uid2identity(uid), index, update_cb) sensor.enroll(usr, index, update_cb)
self.EnrollStatus('enroll-completed', True) self.EnrollStatus('enroll-completed', True)
except usb_core.USBError as e: except usb_core.USBError as e:
logging.exception(e) logging.exception(e)
@ -155,9 +169,8 @@ class Device(dbus.service.Object):
logging.exception(e) logging.exception(e)
self.EnrollStatus('enroll-failed', True) self.EnrollStatus('enroll-failed', True)
index = finger_ids.get(winbio_name, None)
if index == None: if index == None:
logging.error( logging.exception(
'Unknown finger name passed to enroll? ' + 'Unknown finger name passed to enroll? ' +
finger_name + ' (' + winbio_name + ')' finger_name + ' (' + winbio_name + ')'
) )
@ -166,7 +179,6 @@ class Device(dbus.service.Object):
thread = Thread(target=run) thread = Thread(target=run)
thread.daemon = True thread.daemon = True
thread.start() thread.start()
@dbus.service.signal(dbus_interface=INTERFACE_NAME, signature='sb') @dbus.service.signal(dbus_interface=INTERFACE_NAME, signature='sb')
def VerifyStatus(self, result, done): def VerifyStatus(self, result, done):
@ -187,7 +199,9 @@ class Device(dbus.service.Object):
logging.debug('RunCmd') logging.debug('RunCmd')
return hexlify(tls.app(unhexlify(cmd))).decode() return hexlify(tls.app(unhexlify(cmd))).decode()
backoff_file='/usr/share/python-validity/backoff'
backoff_file = '/usr/share/python-validity/backoff'
# I don't know how to tell systemd to backoff in case of multiple instance of the same template service, help! # I don't know how to tell systemd to backoff in case of multiple instance of the same template service, help!
def backoff(): def backoff():
@ -195,10 +209,10 @@ def backoff():
with open(backoff_file, 'r') as f: with open(backoff_file, 'r') as f:
lines = list(map(float, f.readlines())) lines = list(map(float, f.readlines()))
else: else:
lines=[] lines = []
while len(lines) > 0 and lines[0] + 60 < time.time(): while len(lines) > 0 and lines[0] + 60 < time.time():
lines=lines[1:] lines = lines[1:]
lines += [time.time()] lines += [time.time()]
@ -209,10 +223,12 @@ def backoff():
if len(lines) > 10: if len(lines) > 10:
raise Exception('Refusing to start more than 10 times per minute') raise Exception('Refusing to start more than 10 times per minute')
if __name__ == '__main__':
def main():
parser = argparse.ArgumentParser('Open fprintd DBus service') parser = argparse.ArgumentParser('Open fprintd DBus service')
parser.add_argument('--debug', help='Enable tracing', action='store_true') parser.add_argument('--debug', help='Enable tracing', action='store_true')
parser.add_argument('--devpath', help='USB device path: usb-<busnum>-<address>') parser.add_argument('--devpath', help='USB device path: usb-<busnum>-<address>')
parser.add_argument('--configpath', default='/etc/python-validity', type=Path, help='Path to config files')
args = parser.parse_args() args = parser.parse_args()
if args.debug: if args.debug:
@ -222,16 +238,34 @@ if __name__ == '__main__':
else: else:
level = logging.INFO level = logging.INFO
handler = logging.handlers.SysLogHandler(address = '/dev/log') handler = logging.handlers.SysLogHandler(address='/dev/log')
logging.basicConfig(level=level, handlers=[handler]) logging.basicConfig(level=level, handlers=[handler])
# Load and perform basic validation of config file.
try:
with (args.configpath / 'dbus-service.yaml').open(mode='rt') as configfd:
config = yaml.load(configfd)
except FileNotFoundError:
# No configuration file. Create default
config = {'user_to_sid': {}}
if 'user_to_sid' not in config:
raise Exception("No user to SID mapping in config file!")
# Be kind to user, and allow empty mapping that got turned into a null by mistake.
if config['user_to_sid'] is None:
config['user_to_sid'] = {}
if not all(isinstance(e, str) for e in config['user_to_sid'].keys()):
raise Exception("Keys in user to SID map must be strings")
if not all(isinstance(e, str) for e in config['user_to_sid'].values()):
raise Exception("Values in user to SID map must be strings")
backoff() backoff()
try: try:
if args.devpath is None: if args.devpath is None:
init.open() init.open()
else: else:
z = re.match('^usb-(\d+)-(\d+)$', args.devpath) z = re.match(r'^usb-(\d+)-(\d+)$', args.devpath)
if not z: if not z:
parser.error('Option --devpath should look like this: usb-<busnum>-<address>') parser.error('Option --devpath should look like this: usb-<busnum>-<address>')
@ -242,9 +276,8 @@ if __name__ == '__main__':
bus = dbus.SystemBus() bus = dbus.SystemBus()
svc = Device(bus) svc = Device(bus, config)
watcher = None
def watch_cb(name): def watch_cb(name):
if name == '': if name == '':
logging.debug('Manager is offline') logging.debug('Manager is offline')
@ -253,13 +286,14 @@ if __name__ == '__main__':
mgr = bus.get_object(name, '/net/reactivated/Fprint/Manager') mgr = bus.get_object(name, '/net/reactivated/Fprint/Manager')
mgr = dbus.Interface(mgr, 'net.reactivated.Fprint.Manager') mgr = dbus.Interface(mgr, 'net.reactivated.Fprint.Manager')
mgr.RegisterDevice(svc) mgr.RegisterDevice(svc)
watcher = bus.watch_name_owner('net.reactivated.Fprint', watch_cb) watcher = bus.watch_name_owner('net.reactivated.Fprint', watch_cb)
# Kick off the open-fprintd if it was not started yet # Kick off the open-fprintd if it was not started yet
bus.get_object('net.reactivated.Fprint', '/net/reactivated/Fprint/Manager') bus.get_object('net.reactivated.Fprint', '/net/reactivated/Fprint/Manager')
def die(x): def die(x):
logging.info('Cought signal %d. Stopping...' % x) logging.info('Caught signal %d. Stopping...' % x)
loop.quit() loop.quit()
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, die, signal.SIGINT) GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, die, signal.SIGINT)
@ -270,3 +304,6 @@ if __name__ == '__main__':
logging.exception(e) logging.exception(e)
raise e raise e
if __name__ == '__main__':
main()

1
debian/control vendored
View file

@ -15,6 +15,7 @@ Depends: ${python3:Depends},
${misc:Depends}, ${misc:Depends},
python3-dbus, python3-dbus,
python3-usb, python3-usb,
python3-yaml,
dbus, dbus,
open-fprintd (>= 0.2~), open-fprintd (>= 0.2~),
innoextract (>= 1.6~) innoextract (>= 1.6~)

1
debian/install vendored
View file

@ -4,3 +4,4 @@ usr/lib/python*/*-packages/validitysensor/*.py
usr/lib/python-validity usr/lib/python-validity
usr/share/dbus-1 usr/share/dbus-1
usr/share/python-validity usr/share/python-validity
etc/python-validity

View file

@ -1,11 +1,11 @@
[Unit] [Unit]
Description=Restart python-validity after resume Description=Restart python-validity after resume
After=suspend.target hibernate.target After=suspend.target hibernate.target hybrid-sleep.target
[Service] [Service]
Type=simple Type=simple
ExecStart=/bin/systemctl --no-block restart python3-validity.service ExecStart=/bin/systemctl --no-block restart python3-validity.service
[Install] [Install]
WantedBy=suspend.target hibernate.target WantedBy=suspend.target hibernate.target hybrid-sleep.target

1
debian/rules vendored
View file

@ -12,4 +12,3 @@ override_dh_installsystemd:
override_dh_auto_install: override_dh_auto_install:
python3 ./setup.py install --root=$(CURDIR)/debian/tmp --prefix=/usr --install-layout=deb python3 ./setup.py install --root=$(CURDIR)/debian/tmp --prefix=/usr --install-layout=deb

View file

@ -0,0 +1,8 @@
# Mapping for users
# Add mappings from a user to a SID to use the same fingerprints as enrolled by
# Windows. By default, mappings will be generated from the numerical UID if not
# found here. This is fine if you are not dual booting and want to share
# mappings with Windows.
user_to_sid:
# Example:
#"username": "S-1-5-21-1234567890-1234567890-1234567890-1234"

View file

@ -12,7 +12,8 @@ setup(name='python-validity',
], ],
install_requires=[ install_requires=[
'cryptography >= 2.1.4', 'cryptography >= 2.1.4',
'pyusb >= 1.0.2' 'pyusb >= 1.0.0',
'pyyaml >= 3.12'
], ],
data_files=[ data_files=[
('share/dbus-1/system.d/', ['dbus_service/io.github.uunicorn.Fprint.conf']), ('share/dbus-1/system.d/', ['dbus_service/io.github.uunicorn.Fprint.conf']),

View file

@ -1,10 +1,8 @@
import typing
import logging
from .util import unhex
from .tls import tls from .tls import tls
from .util import assert_status from .util import assert_status
from struct import pack, unpack from binascii import hexlify
from binascii import hexlify, unhexlify
from .blobs import db_write_enable from .blobs import db_write_enable
from .flash import call_cleanups from .flash import call_cleanups
from .sid import * from .sid import *
@ -28,7 +26,7 @@ class User():
def __repr__(self): def __repr__(self):
return '<User: dbid=%04x identity=%s fingers=%s>' % (self.dbid, repr(self.identity), repr(self.fingers)) return '<User: dbid=%04x identity=%s fingers=%s>' % (self.dbid, repr(self.identity), repr(self.fingers))
def subtype_to_string(s): def subtype_to_string(s: int):
finger_name = finger_names.get(s, None) finger_name = finger_names.get(s, None)
return finger_name or 'Unknown' return finger_name or 'Unknown'
@ -69,7 +67,7 @@ def parse_identity(b):
raise Exception('Don''t know how to handle identity type %d' % t) raise Exception('Don''t know how to handle identity type %d' % t)
def parse_user(rsp): def parse_user(rsp: bytes):
assert_status(rsp[:2]) assert_status(rsp[:2])
rsp=rsp[2:] rsp=rsp[2:]
@ -91,7 +89,7 @@ def parse_user(rsp):
return user return user
def identity_to_bytes(identity): def identity_to_bytes(identity: str):
if isinstance(identity, SidIdentity): if isinstance(identity, SidIdentity):
b=identity.to_bytes() b=identity.to_bytes()
b = pack('<LL', 3, len(b)) + b b = pack('<LL', 3, len(b)) + b
@ -155,7 +153,7 @@ class Db():
def get_user(self, dbid): def get_user(self, dbid):
return parse_user(tls.cmd(pack('<BHHH', 0x4a, dbid, 0, 0))) return parse_user(tls.cmd(pack('<BHHH', 0x4a, dbid, 0, 0)))
def lookup_user(self, identity): def lookup_user(self, identity: str) -> typing.Optional[User]:
stg = self.get_user_storage(name='StgWindsor') stg = self.get_user_storage(name='StgWindsor')
data = identity_to_bytes(identity) data = identity_to_bytes(identity)

View file

@ -1,7 +1,5 @@
from .tls import tls from .tls import tls
from struct import pack, unpack from struct import pack, unpack
from binascii import hexlify, unhexlify
from .util import assert_status, unhex from .util import assert_status, unhex
from .blobs import db_write_enable from .blobs import db_write_enable
from .hw_tables import flash_ic_table_lookup from .hw_tables import flash_ic_table_lookup

View file

@ -1,6 +1,5 @@
import atexit import atexit
import signal
import logging import logging
from validitysensor.usb import usb from validitysensor.usb import usb

View file

@ -3,9 +3,6 @@ from struct import pack, unpack
import logging import logging
from .db import db from .db import db
from .usb import usb
from .tls import tls
from .flash import read_flash
def machine_id_rec_value(b): def machine_id_rec_value(b):
b = b.encode('utf-16le') b = b.encode('utf-16le')

View file

@ -1,7 +1,7 @@
import os import os
from struct import pack, unpack from struct import pack, unpack
from binascii import hexlify, unhexlify from binascii import unhexlify
import logging import logging
from hashlib import sha256 from hashlib import sha256

View file

@ -1,4 +1,4 @@
import typing
from enum import Enum from enum import Enum
from hashlib import sha256 from hashlib import sha256
import os.path import os.path
@ -6,7 +6,7 @@ import logging
from usb import core as usb_core from usb import core as usb_core
from .tls import tls from .tls import tls
from .usb import usb, CancelledException from .usb import usb, CancelledException
from .db import db, subtype_to_string from .db import db, SidIdentity
from .flash import write_enable, call_cleanups, read_flash, erase_flash, write_flash_all, read_flash_all from .flash import write_enable, call_cleanups, read_flash, erase_flash, write_flash_all, read_flash_all
from time import sleep from time import sleep
from struct import pack, unpack from struct import pack, unpack
@ -70,11 +70,12 @@ def factory_reset():
reboot() reboot()
class RomInfo(): class RomInfo():
def get(): @classmethod
def get(cls):
rsp=tls.cmd(b'\x01') rsp=tls.cmd(b'\x01')
assert_status(rsp) assert_status(rsp)
rsp=rsp[2:] rsp=rsp[2:]
return RomInfo(*unpack('<LLBBxBxxxB', rsp[0:0x10])) return cls(*unpack('<LLBBxBxxxB', rsp[0:0x10]))
def __init__(self, timestamp, build, major, minor, product, u1): def __init__(self, timestamp, build, major, minor, product, u1):
self.timestamp, self.build, self.major, self.minor, self.product, self.u1 = timestamp, build, major, minor, product, u1 self.timestamp, self.build, self.major, self.minor, self.product, self.u1 = timestamp, build, major, minor, product, u1
@ -739,7 +740,9 @@ class Sensor():
return tinfo return tinfo
def enroll(self, identity, subtype, update_cb): # TODO: Better typing information needed.
def enroll(self, identity: SidIdentity, subtype: int,
update_cb: typing.Callable[[typing.Any, typing.Optional[Exception]], None]):
def do_create_finger(final_template, tid): def do_create_finger(final_template, tid):
tinfo = self.make_finger_data(subtype, final_template, tid) tinfo = self.make_finger_data(subtype, final_template, tid)
@ -794,7 +797,7 @@ class Sensor():
return rc return rc
def match_finger(self): def match_finger(self) -> typing.Tuple[int, int, bytes]:
try: try:
stg_id=0 # match against any storage stg_id=0 # match against any storage
usr_id=0 # match against any user usr_id=0 # match against any user

View file

@ -1,8 +1,9 @@
from struct import unpack, pack from struct import unpack, pack
import typing
class SidIdentity(): class SidIdentity():
def __init__(self, revision, auth, subauth): def __init__(self, revision: int, auth: int, subauth: typing.Sequence[int]):
self.revision = revision self.revision = revision
self.auth = auth self.auth = auth
self.subauth = subauth self.subauth = subauth
@ -17,7 +18,7 @@ class SidIdentity():
def __repr__(self): def __repr__(self):
return 'S-%d-%d-%s' % (self.revision, self.auth, '-'.join(map(str, self.subauth))) return 'S-%d-%d-%s' % (self.revision, self.auth, '-'.join(map(str, self.subauth)))
def sid_from_bytes(b): def sid_from_bytes(b: bytes):
revision = b[0] revision = b[0]
subcnt = b[1] subcnt = b[1]
auth = 0 auth = 0
@ -30,7 +31,7 @@ def sid_from_bytes(b):
return SidIdentity(revision, auth, subauth) return SidIdentity(revision, auth, subauth)
def sid_from_string(s): def sid_from_string(s: str):
parts = s.split('-') parts = s.split('-')
if parts[0] != 'S': if parts[0] != 'S':

View file

@ -4,9 +4,10 @@ from binascii import hexlify, unhexlify
class SensorTypeInfo: class SensorTypeInfo:
table=[] table=[]
def get_by_type(sensor_type): @classmethod
def get_by_type(cls, sensor_type):
from . import generated_tables from . import generated_tables
for i in SensorTypeInfo.table: for i in cls.table:
if i.sensor_type == sensor_type: if i.sensor_type == sensor_type:
return i return i
@ -46,7 +47,8 @@ def metric(i, rominfo):
class SensorCaptureProg: class SensorCaptureProg:
table=[] table=[]
def get(rominfo, sensor_type, a0, a1): @classmethod
def get(cls, rominfo, sensor_type, a0, a1):
from . import generated_tables from . import generated_tables
maximum = 0 maximum = 0

View file

@ -1,6 +1,4 @@
import re
import hmac import hmac
import sys
import os import os
import pickle import pickle
import logging import logging
@ -14,8 +12,8 @@ from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes
from hashlib import sha256 from hashlib import sha256
from .usb import unhex, usb from .util import unhex
from .util import assert_status from .usb import usb
password_hardcoded=unhexlify('717cd72d0962bc4a2846138dbb2c24192512a76407065f383846139d4bec2033') password_hardcoded=unhexlify('717cd72d0962bc4a2846138dbb2c24192512a76407065f383846139d4bec2033')
@ -289,7 +287,7 @@ class Tls():
def handle_server_hello_done(self, p): def handle_server_hello_done(self, p):
if p != b'': if p != b'':
raise Exeception('Not expecting any body for "server hello done" pkt: %s' % hexlify(p).decode()) raise Exception('Not expecting any body for "server hello done" pkt: %s' % hexlify(p).decode())
def handle_finish(self, b): def handle_finish(self, b):
hs_hash = self.handshake_hash.copy().digest() hs_hash = self.handshake_hash.copy().digest()

View file

@ -1,14 +1,10 @@
from binascii import hexlify, unhexlify
from time import ctime from time import ctime
import logging import logging
from os.path import basename from os.path import basename
from .tls import tls
from .usb import usb from .usb import usb
from .sensor import reboot, write_hw_reg32, read_hw_reg32, identify_sensor from .sensor import reboot, write_hw_reg32, read_hw_reg32, identify_sensor
from .flash import read_flash, erase_flash, write_flash_all, write_fw_signature, get_fw_info from .flash import write_flash_all, write_fw_signature, get_fw_info
from .util import assert_status
firmware_home='/usr/share/python-validity' firmware_home='/usr/share/python-validity'

View file

@ -3,10 +3,8 @@ import logging
import errno import errno
import usb.core as ucore import usb.core as ucore
from binascii import * from binascii import *
from .util import assert_status, unhex from .util import assert_status
from struct import unpack from struct import unpack
from usb.util import claim_interface, release_interface
from threading import Thread
from usb.core import USBError from usb.core import USBError
from .blobs import init_hardcoded, init_hardcoded_clean_slate from .blobs import init_hardcoded, init_hardcoded_clean_slate