Change tabs to 4 spaces in python files

This commit is contained in:
Ondrej Mikle 2017-10-22 17:27:44 +02:00
parent 5d41737f80
commit 2482462a73
6 changed files with 420 additions and 420 deletions

View file

@ -12,77 +12,77 @@ from optparse import OptionParser
from brmdoor_nfc_daemon import BrmdoorConfig from brmdoor_nfc_daemon import BrmdoorConfig
def addUidAuth(cursor, uid_hex, nick): def addUidAuth(cursor, uid_hex, nick):
""" """
Add user authenticated by UID. UID should be in hex, 4, 7 or 10 bytes long. Add user authenticated by UID. UID should be in hex, 4, 7 or 10 bytes long.
""" """
try: try:
uid_hex.decode("hex") uid_hex.decode("hex")
sql = """INSERT INTO authorized_uids sql = """INSERT INTO authorized_uids
(uid_hex, nick) (uid_hex, nick)
values (?, ?) values (?, ?)
""" """
sql_data = (uid_hex, nick) sql_data = (uid_hex, nick)
cursor.execute(sql, sql_data) cursor.execute(sql, sql_data)
except TypeError: except TypeError:
print >> sys.stderr, "UID must be in proper hex encoding" print >> sys.stderr, "UID must be in proper hex encoding"
sys.exit(1) sys.exit(1)
def addHmacAuth(cursor, uid_hex, nick, key_hex): def addHmacAuth(cursor, uid_hex, nick, key_hex):
""" """
Add user authenticated by Yubikey HMAC-SHA1. UID should be in hex, 4, 7 Add user authenticated by Yubikey HMAC-SHA1. UID should be in hex, 4, 7
or 10 bytes long. HMAC key in key_hex must be exactly 20 bytes in hex. or 10 bytes long. HMAC key in key_hex must be exactly 20 bytes in hex.
""" """
try: try:
uid_hex.decode("hex") uid_hex.decode("hex")
if len(key_hex.decode("hex")) != 20: if len(key_hex.decode("hex")) != 20:
print >> sys.stderr, "Key must be exactly 20 bytes long!" print >> sys.stderr, "Key must be exactly 20 bytes long!"
sys.exit(1) sys.exit(1)
sql = """INSERT INTO authorized_hmac_keys sql = """INSERT INTO authorized_hmac_keys
(uid_hex, nick, key_hex) (uid_hex, nick, key_hex)
VALUES (?, ?, ?) VALUES (?, ?, ?)
""" """
sql_data = (uid_hex, nick, key_hex) sql_data = (uid_hex, nick, key_hex)
cursor.execute(sql, sql_data) cursor.execute(sql, sql_data)
except TypeError: except TypeError:
print >> sys.stderr, "UID and key must be in proper hex encoding" print >> sys.stderr, "UID and key must be in proper hex encoding"
sys.exit(1) sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
parser = OptionParser() parser = OptionParser()
parser.add_option("-c", "--config", action="store", type="string", dest="config", parser.add_option("-c", "--config", action="store", type="string", dest="config",
help="Configuration file") help="Configuration file")
parser.add_option("-a", "--authtype", action="store", type="string", dest="authtype", parser.add_option("-a", "--authtype", action="store", type="string", dest="authtype",
help="Authenthication type - uid or hmac") help="Authenthication type - uid or hmac")
(opts, args) = parser.parse_args() (opts, args) = parser.parse_args()
if opts.config is None: if opts.config is None:
print >> sys.stderr, "You must specify config file via the -c option!" print >> sys.stderr, "You must specify config file via the -c option!"
parser.print_help() parser.print_help()
sys.exit(1) sys.exit(1)
if opts.authtype not in ["uid", "hmac"]: if opts.authtype not in ["uid", "hmac"]:
print >> sys.stderr, "You must specify authentication type via -a option!" print >> sys.stderr, "You must specify authentication type via -a option!"
print >> sys.stderr, "Acceptable choices: uid, hmac" print >> sys.stderr, "Acceptable choices: uid, hmac"
sys.exit(1) sys.exit(1)
config = BrmdoorConfig(opts.config) config = BrmdoorConfig(opts.config)
conn = sqlite3.connect(config.authDbFilename) conn = sqlite3.connect(config.authDbFilename)
cursor = conn.cursor() cursor = conn.cursor()
if opts.authtype == "uid": if opts.authtype == "uid":
if len(args) < 2: if len(args) < 2:
print >> sys.stderr, "You must two additional arguments, hex UID and nick" print >> sys.stderr, "You must two additional arguments, hex UID and nick"
print >> sys.stderr, "Example:" print >> sys.stderr, "Example:"
print >> sys.stderr, "brmdoor_adduser.py -c brmdoor.config -a uid 34795FCC SomeUserName" print >> sys.stderr, "brmdoor_adduser.py -c brmdoor.config -a uid 34795FCC SomeUserName"
sys.exit(1) sys.exit(1)
addUidAuth(cursor, args[0], args[1]) addUidAuth(cursor, args[0], args[1])
elif opts.authtype == "hmac": elif opts.authtype == "hmac":
if len(args) < 3: if len(args) < 3:
print >> sys.stderr, "You must three additional arguments, hex UID and nick and hex key" print >> sys.stderr, "You must three additional arguments, hex UID and nick and hex key"
print >> sys.stderr, "brmdoor_adduser.py -c brmdoor.config -a hmac 40795FCCAB0701 SomeUserName 000102030405060708090a0b0c0d0e0f31323334" print >> sys.stderr, "brmdoor_adduser.py -c brmdoor.config -a hmac 40795FCCAB0701 SomeUserName 000102030405060708090a0b0c0d0e0f31323334"
sys.exit(1) sys.exit(1)
addHmacAuth(cursor, args[0], args[1], args[2]) addHmacAuth(cursor, args[0], args[1], args[2])
conn.commit() conn.commit()
conn.close() conn.close()

View file

@ -8,150 +8,150 @@ from nfc_smartcard import NFCError
class UidRecord(object): class UidRecord(object):
"""Represents UID<->nick pair""" """Represents UID<->nick pair"""
def __init__(self, uid_hex, nick): def __init__(self, uid_hex, nick):
""" """
Create instance binding UID to nick. UIDs should be either 4, 7 Create instance binding UID to nick. UIDs should be either 4, 7
or 10 bytes long, but that's ISO14443 thing - this object has or 10 bytes long, but that's ISO14443 thing - this object has
no such limitation. no such limitation.
UID will be stored in uppercase hex, converted if necessary. UID will be stored in uppercase hex, converted if necessary.
@param uid_hex: uid in hex @param uid_hex: uid in hex
@param nick: nickname this UID belongs to @param nick: nickname this UID belongs to
""" """
self.uid_hex = uid_hex.upper() self.uid_hex = uid_hex.upper()
self.nick = nick self.nick = nick
def __str__(self): def __str__(self):
return "(uid: %s, nick: %s)" % (self.uid_hex, self.nick) return "(uid: %s, nick: %s)" % (self.uid_hex, self.nick)
def __repr__(self): def __repr__(self):
return "<UidRecord: uid: %s, nick: %s>" % \ return "<UidRecord: uid: %s, nick: %s>" % \
(repr(self.uid_hex), repr(self.nick)) (repr(self.uid_hex), repr(self.nick))
class UidAuthenticator(object): class UidAuthenticator(object):
"""Checks UIDs of ISO14443 RFID cards against database.""" """Checks UIDs of ISO14443 RFID cards against database."""
def __init__(self, filename): def __init__(self, filename):
""" """
Connects to database by given filename and later checks UIDs Connects to database by given filename and later checks UIDs
against that database. against that database.
""" """
#open in autocommit mode - we are not changing anything #open in autocommit mode - we are not changing anything
self.conn = sqlite3.connect(filename, isolation_level=None) self.conn = sqlite3.connect(filename, isolation_level=None)
def fetchUidRecord(self, uid_hex): def fetchUidRecord(self, uid_hex):
""" """
Returns first record that matches given UID or None if nothing Returns first record that matches given UID or None if nothing
is found. is found.
@param uid_hex: uid to match in hex @param uid_hex: uid to match in hex
@returns UidRecord instance if found, None otherwise @returns UidRecord instance if found, None otherwise
""" """
cursor = self.conn.cursor() cursor = self.conn.cursor()
sql = "SELECT nick FROM authorized_uids WHERE UPPER(uid_hex)=?" sql = "SELECT nick FROM authorized_uids WHERE UPPER(uid_hex)=?"
sql_data =(uid_hex.upper(),) sql_data =(uid_hex.upper(),)
cursor.execute(sql, sql_data) cursor.execute(sql, sql_data)
record = cursor.fetchone() record = cursor.fetchone()
if record is None: if record is None:
return None return None
nick = record[0] nick = record[0]
return UidRecord(uid_hex, nick) return UidRecord(uid_hex, nick)
def shutdown(self): def shutdown(self):
"""Closes connection to database""" """Closes connection to database"""
self.conn.close() self.conn.close()
class YubikeyHMACAuthenthicator(object): class YubikeyHMACAuthenthicator(object):
""" """
Uses Yubikey Neo's built-in HMAC functionality on slot 2 (needs to be Uses Yubikey Neo's built-in HMAC functionality on slot 2 (needs to be
configured using Yubikey tools to be on this slot). configured using Yubikey tools to be on this slot).
""" """
def __init__(self, filename, nfcReader): def __init__(self, filename, nfcReader):
""" """
Connects to database by given filename and later checks UIDs Connects to database by given filename and later checks UIDs
against that database. against that database.
""" """
#again autocommit mode #again autocommit mode
self.conn = sqlite3.connect(filename, isolation_level=None) self.conn = sqlite3.connect(filename, isolation_level=None)
self.nfcReader = nfcReader self.nfcReader = nfcReader
def hmacCheck(self, key, challenge, result): def hmacCheck(self, key, challenge, result):
""" """
Returns true iff HMAC-SHA1 with given key and challenge string Returns true iff HMAC-SHA1 with given key and challenge string
transforms into given result. transforms into given result.
""" """
hashed = hmac.new(key, challenge, hashlib.sha1) hashed = hmac.new(key, challenge, hashlib.sha1)
#We should use hmac.compare_digest(), but that's in new Python #We should use hmac.compare_digest(), but that's in new Python
#version only. Here timing side channels are not much of concern. #version only. Here timing side channels are not much of concern.
return hashed.digest() == result return hashed.digest() == result
def checkHMACforUID(self, uid_hex): def checkHMACforUID(self, uid_hex):
""" """
Checks if UID is in database. If so Checks if UID is in database. If so
@param uid_hex: uid to match in hex @param uid_hex: uid to match in hex
@returns UidRecord instance if found, None otherwise @returns UidRecord instance if found, None otherwise
""" """
cursor = self.conn.cursor() cursor = self.conn.cursor()
sql = "SELECT nick, key_hex FROM authorized_hmac_keys WHERE UPPER(uid_hex)=?" sql = "SELECT nick, key_hex FROM authorized_hmac_keys WHERE UPPER(uid_hex)=?"
sql_data =(uid_hex.upper(),) sql_data =(uid_hex.upper(),)
cursor.execute(sql, sql_data) cursor.execute(sql, sql_data)
record = cursor.fetchone() record = cursor.fetchone()
if record is None: if record is None:
return None return None
nick = record[0] nick = record[0]
secretKey = record[1].decode("hex") secretKey = record[1].decode("hex")
challenge = os.urandom(32) challenge = os.urandom(32)
# Select HMAC-SHA1 on slot 2 from Yubikey # Select HMAC-SHA1 on slot 2 from Yubikey
apdusHex = [ apdusHex = [
"00 A4 04 00 07 A0 00 00 05 27 20 01", "00 A4 04 00 07 A0 00 00 05 27 20 01",
"00 01 38 00 %02x %s" % (len(challenge), challenge.encode("hex")) "00 01 38 00 %02x %s" % (len(challenge), challenge.encode("hex"))
] ]
rapdu = None rapdu = None
for apduHex in apdusHex: for apduHex in apdusHex:
try: try:
apdu = apduHex.replace(" ", "").decode("hex") apdu = apduHex.replace(" ", "").decode("hex")
rapdu = self.nfcReader.sendAPDU(apdu) rapdu = self.nfcReader.sendAPDU(apdu)
if not rapdu.valid or rapdu.sw() != 0x9000: if not rapdu.valid or rapdu.sw() != 0x9000:
raise NFCError("HMAC - response SW is not 0x9000") raise NFCError("HMAC - response SW is not 0x9000")
except NFCError, e: except NFCError, e:
logging.debug("Yubikey HMAC command failed: %s" % e.what()) logging.debug("Yubikey HMAC command failed: %s" % e.what())
return None return None
if not self.hmacCheck(secretKey, challenge, rapdu.data()): if not self.hmacCheck(secretKey, challenge, rapdu.data()):
logging.info("HMAC check failed for UID %s", uid_hex) logging.info("HMAC check failed for UID %s", uid_hex)
return None return None
return UidRecord(uid_hex, nick) return UidRecord(uid_hex, nick)
def shutdown(self): def shutdown(self):
"""Closes connection to database""" """Closes connection to database"""
self.conn.close() self.conn.close()
#test routine #test routine
if __name__ == "__main__": if __name__ == "__main__":
authenticator = UidAuthenticator("test_uids_db.sqlite") authenticator = UidAuthenticator("test_uids_db.sqlite")
record = authenticator.fetchUidRecord("043a1482cc2280") record = authenticator.fetchUidRecord("043a1482cc2280")
print "For UID 043a1482cc2280 we found:", repr(record) print "For UID 043a1482cc2280 we found:", repr(record)
record = authenticator.fetchUidRecord("34795fad") record = authenticator.fetchUidRecord("34795fad")
print "For UID 34795fad we found:", repr(record) print "For UID 34795fad we found:", repr(record)
record = authenticator.fetchUidRecord("01020304") record = authenticator.fetchUidRecord("01020304")
print "For UID 01020304 we found:", repr(record) print "For UID 01020304 we found:", repr(record)
authenticator.shutdown() authenticator.shutdown()

View file

@ -13,138 +13,138 @@ from brmdoor_authenticator import UidAuthenticator, YubikeyHMACAuthenthicator
import unlocker import unlocker
class BrmdoorConfigError(ConfigParser.Error): class BrmdoorConfigError(ConfigParser.Error):
""" """
Signifies that config has missing or bad values. Signifies that config has missing or bad values.
""" """
pass pass
class BrmdoorConfig(object): class BrmdoorConfig(object):
""" """
Configuration parser. Holds config variables from config file. Configuration parser. Holds config variables from config file.
""" """
_defaults = { _defaults = {
"lock_opened_secs": "5", "lock_opened_secs": "5",
"unknown_uid_timeout_secs": "5", "unknown_uid_timeout_secs": "5",
"log_level": "info" "log_level": "info"
} }
def __init__(self, filename): def __init__(self, filename):
""" """
Parse and read config from given filename. Parse and read config from given filename.
@throws ConfigParser.Error if parsing failed @throws ConfigParser.Error if parsing failed
@throws BrmdoorConfigError if some value was missing or invalid @throws BrmdoorConfigError if some value was missing or invalid
""" """
self.config = ConfigParser.SafeConfigParser(defaults=BrmdoorConfig._defaults) self.config = ConfigParser.SafeConfigParser(defaults=BrmdoorConfig._defaults)
self.config.read(filename) self.config.read(filename)
self.authDbFilename = self.config.get("brmdoor", "auth_db_filename") self.authDbFilename = self.config.get("brmdoor", "auth_db_filename")
self.lockOpenedSecs = self.config.getint("brmdoor", "lock_opened_secs") self.lockOpenedSecs = self.config.getint("brmdoor", "lock_opened_secs")
self.unknownUidTimeoutSecs = self.config.getint("brmdoor", "unknown_uid_timeout_secs") self.unknownUidTimeoutSecs = self.config.getint("brmdoor", "unknown_uid_timeout_secs")
self.logFile = self.config.get("brmdoor", "log_file") self.logFile = self.config.get("brmdoor", "log_file")
self.logLevel = self.convertLoglevel(self.config.get("brmdoor", "log_level")) self.logLevel = self.convertLoglevel(self.config.get("brmdoor", "log_level"))
self.unlocker = self.config.get("brmdoor", "unlocker") self.unlocker = self.config.get("brmdoor", "unlocker")
def convertLoglevel(self, levelString): def convertLoglevel(self, levelString):
"""Converts string 'debug', 'info', etc. into corresponding """Converts string 'debug', 'info', etc. into corresponding
logging.XXX value which is returned. logging.XXX value which is returned.
@raises BrmdoorConfigError if the level is undefined @raises BrmdoorConfigError if the level is undefined
""" """
try: try:
return getattr(logging, levelString.upper()) return getattr(logging, levelString.upper())
except AttributeError: except AttributeError:
raise BrmdoorConfigError("No such loglevel - %s" % levelString) raise BrmdoorConfigError("No such loglevel - %s" % levelString)
class NFCScanner(object): class NFCScanner(object):
"""Thread reading data from NFC reader""" """Thread reading data from NFC reader"""
def __init__(self, config): def __init__(self, config):
"""Create worker reading UIDs from PN53x reader. """Create worker reading UIDs from PN53x reader.
""" """
self.authenticator = UidAuthenticator(config.authDbFilename) self.authenticator = UidAuthenticator(config.authDbFilename)
self.hmacAuthenticator = None self.hmacAuthenticator = None
self.unknownUidTimeoutSecs = config.unknownUidTimeoutSecs self.unknownUidTimeoutSecs = config.unknownUidTimeoutSecs
self.lockOpenedSecs = config.lockOpenedSecs self.lockOpenedSecs = config.lockOpenedSecs
unlockerClassName = config.unlocker unlockerClassName = config.unlocker
unlockerClass = getattr(unlocker, unlockerClassName) unlockerClass = getattr(unlocker, unlockerClassName)
self.unlocker = unlockerClass(config) self.unlocker = unlockerClass(config)
def run(self): def run(self):
""" """
Waits for a card to get into reader field. Reads its UID and Waits for a card to get into reader field. Reads its UID and
compares to database of authorized users. Unlocks lock if compares to database of authorized users. Unlocks lock if
authorized. authorized.
""" """
self.nfc = NFCDevice() self.nfc = NFCDevice()
self.hmacAuthenticator = YubikeyHMACAuthenthicator( self.hmacAuthenticator = YubikeyHMACAuthenthicator(
config.authDbFilename, self.nfc config.authDbFilename, self.nfc
) )
#self.nfc.pollNr = 0xFF #poll indefinitely #self.nfc.pollNr = 0xFF #poll indefinitely
while True: while True:
try: try:
uid_hex = hexlify(self.nfc.scanUID()) uid_hex = hexlify(self.nfc.scanUID())
logging.debug("Got UID %s", uid_hex) logging.debug("Got UID %s", uid_hex)
if len(uid_hex) > 0: if len(uid_hex) > 0:
self.actOnUid(uid_hex) self.actOnUid(uid_hex)
else: else:
#prevent busy loop if reader goes awry #prevent busy loop if reader goes awry
time.sleep(0.3) time.sleep(0.3)
except NFCError, e: except NFCError, e:
#this exception happens also when scanUID times out #this exception happens also when scanUID times out
logging.debug("Failed to wait for RFID card: %s", e) logging.debug("Failed to wait for RFID card: %s", e)
except KeyboardInterrupt: except KeyboardInterrupt:
logging.info("Exiting on keyboard interrupt") logging.info("Exiting on keyboard interrupt")
self.nfc.close() self.nfc.close()
self.nfc.unload() self.nfc.unload()
self.unlocker.lock() self.unlocker.lock()
sys.exit(2) sys.exit(2)
except Exception: except Exception:
logging.exception("Exception in main unlock thread") logging.exception("Exception in main unlock thread")
def actOnUid(self, uid_hex): def actOnUid(self, uid_hex):
""" """
Do something with the UID scanned. Try to authenticate it against Do something with the UID scanned. Try to authenticate it against
database and open lock if authorized. database and open lock if authorized.
""" """
record = self.authenticator.fetchUidRecord(uid_hex) record = self.authenticator.fetchUidRecord(uid_hex)
#direct UID match #direct UID match
if record is not None: if record is not None:
logging.info("Unlocking for UID %s", record) logging.info("Unlocking for UID %s", record)
self.unlocker.unlock() self.unlocker.unlock()
return return
#test for Yubikey HMAC auth #test for Yubikey HMAC auth
record = self.hmacAuthenticator.checkHMACforUID(uid_hex) record = self.hmacAuthenticator.checkHMACforUID(uid_hex)
if record is not None: if record is not None:
logging.info("Unlocking after HMAC for UID %s", record) logging.info("Unlocking after HMAC for UID %s", record)
self.unlocker.unlock() self.unlocker.unlock()
return return
logging.info("Unknown UID %s", uid_hex) logging.info("Unknown UID %s", uid_hex)
time.sleep(self.unknownUidTimeoutSecs) time.sleep(self.unknownUidTimeoutSecs)
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 2: if len(sys.argv) < 2:
print >> sys.stderr, "Syntax: brmdoor_nfc_daemon.py brmdoor_nfc.config" print >> sys.stderr, "Syntax: brmdoor_nfc_daemon.py brmdoor_nfc.config"
sys.exit(1) sys.exit(1)
config = BrmdoorConfig(sys.argv[1]) config = BrmdoorConfig(sys.argv[1])
if config.logFile == "-": if config.logFile == "-":
logging.basicConfig(stream=sys.stderr, level=config.logLevel, logging.basicConfig(stream=sys.stderr, level=config.logLevel,
format="%(asctime)s %(levelname)s %(message)s [%(pathname)s:%(lineno)d]") format="%(asctime)s %(levelname)s %(message)s [%(pathname)s:%(lineno)d]")
else: else:
logging.basicConfig(filename=config.logFile, level=config.logLevel, logging.basicConfig(filename=config.logFile, level=config.logLevel,
format="%(asctime)s %(levelname)s %(message)s [%(pathname)s:%(lineno)d]") format="%(asctime)s %(levelname)s %(message)s [%(pathname)s:%(lineno)d]")
nfcScanner = NFCScanner(config) nfcScanner = NFCScanner(config)
nfcScanner.run() nfcScanner.run()

View file

@ -10,23 +10,23 @@ import sys
import sqlite3 import sqlite3
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 2: if len(sys.argv) < 2:
print >> sys.stderr, "You must specify filename as arg1 where the DB is to be created" print >> sys.stderr, "You must specify filename as arg1 where the DB is to be created"
filename = sys.argv[1] filename = sys.argv[1]
conn = sqlite3.connect(filename) conn = sqlite3.connect(filename)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("""CREATE TABLE authorized_uids( cursor.execute("""CREATE TABLE authorized_uids(
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
uid_hex TEXT, uid_hex TEXT,
nick TEXT) nick TEXT)
""") """)
cursor.execute("""CREATE TABLE authorized_hmac_keys( cursor.execute("""CREATE TABLE authorized_hmac_keys(
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
uid_hex TEXT, uid_hex TEXT,
key_hex TEXT, key_hex TEXT,
nick TEXT) nick TEXT)
""") """)
conn.commit() conn.commit()
conn.close() conn.close()

View file

@ -5,8 +5,8 @@ from nfc_smartcard import NFCDevice, NFCError
from binascii import hexlify from binascii import hexlify
def formatAPDU(apdu): def formatAPDU(apdu):
return " ".join(["%02X" % ord(b) for b in apdu]) return " ".join(["%02X" % ord(b) for b in apdu])
tests = { tests = {
# Reading of file E104, where usually NDEF message is # Reading of file E104, where usually NDEF message is
"ndef4": [ "ndef4": [
@ -55,26 +55,26 @@ hex_apdus = tests[apdu_test]
apdus = [hex_apdu.replace(" ","").decode("hex") for hex_apdu in hex_apdus] apdus = [hex_apdu.replace(" ","").decode("hex") for hex_apdu in hex_apdus]
try: try:
nfc = NFCDevice() nfc = NFCDevice()
uid = nfc.scanUID() uid = nfc.scanUID()
print "UID", hexlify(uid) print "UID", hexlify(uid)
#nfc.close() #nfc.close()
#nfc.open() #nfc.open()
print "Now trying to send ISO14443-4 APDUs" print "Now trying to send ISO14443-4 APDUs"
try: try:
#nfc.selectPassiveTarget() #nfc.selectPassiveTarget()
for apdu in apdus: for apdu in apdus:
print "Command APDU:", formatAPDU(apdu) print "Command APDU:", formatAPDU(apdu)
rapdu = nfc.sendAPDU(apdu) rapdu = nfc.sendAPDU(apdu)
print "Response APDU valid: %s, SW %04x, data %s" % (rapdu.valid(), rapdu.sw(), hexlify(rapdu.data())) print "Response APDU valid: %s, SW %04x, data %s" % (rapdu.valid(), rapdu.sw(), hexlify(rapdu.data()))
except NFCError, e: except NFCError, e:
print "Failed to transmit APDU:", e.what() print "Failed to transmit APDU:", e.what()
print "Device is opened:", nfc.opened() print "Device is opened:", nfc.opened()
print "Closing device" print "Closing device"
nfc.close() nfc.close()
print "Device is opened:", nfc.opened() print "Device is opened:", nfc.opened()
nfc.unload() nfc.unload()
except NFCError, e: except NFCError, e:
print "Reading UID failed:", e.what() print "Reading UID failed:", e.what()

View file

@ -2,55 +2,55 @@ import time
import wiringpi2 as wiringpi import wiringpi2 as wiringpi
class Unlocker(object): class Unlocker(object):
"""Abstract class/interface for Unlocker object. """Abstract class/interface for Unlocker object.
Unlocker useful for simulation, but does not actually unlock any lock. Unlocker useful for simulation, but does not actually unlock any lock.
""" """
def __init__(self, config): def __init__(self, config):
""" """
Creates unlocked instance from config, where section named after Creates unlocked instance from config, where section named after
the class is supposed to exist. the class is supposed to exist.
@param config: BrmdoorConfig instance @param config: BrmdoorConfig instance
""" """
self.config = config.config self.config = config.config
self.lockOpenedSecs = config.lockOpenedSecs self.lockOpenedSecs = config.lockOpenedSecs
self.unlockerName = type(self).__name__ self.unlockerName = type(self).__name__
def unlock(self): def unlock(self):
"""Unlock lock for given self.lockOpenedSecs. """Unlock lock for given self.lockOpenedSecs.
In this class case, it's only simulated In this class case, it's only simulated
""" """
time.sleep(self.lockOpenedSecs) time.sleep(self.lockOpenedSecs)
def lock(self): def lock(self):
""" """
Lock the lock back. Meant to be used when program is shut down Lock the lock back. Meant to be used when program is shut down
so that lock is not left disengaged. so that lock is not left disengaged.
""" """
pass pass
class UnlockerWiringPi(Unlocker): class UnlockerWiringPi(Unlocker):
"""Uses configured pings via WiringPi to open lock. """Uses configured pings via WiringPi to open lock.
""" """
def __init__(self, config): def __init__(self, config):
Unlocker.__init__(self, config) Unlocker.__init__(self, config)
wiringpi.wiringPiSetupGpio() # pin numbers follow P1 GPIO header wiringpi.wiringPiSetupGpio() # pin numbers follow P1 GPIO header
self.lockPin = self.config.getint("UnlockerWiringPi", "lock_pin") self.lockPin = self.config.getint("UnlockerWiringPi", "lock_pin")
wiringpi.pinMode(self.lockPin, 1) #output wiringpi.pinMode(self.lockPin, 1) #output
def unlock(self): def unlock(self):
"""Unlocks lock at configured pin by pulling it high. """Unlocks lock at configured pin by pulling it high.
""" """
wiringpi.digitalWrite(self.lockPin, 1) wiringpi.digitalWrite(self.lockPin, 1)
time.sleep(self.lockOpenedSecs) time.sleep(self.lockOpenedSecs)
wiringpi.digitalWrite(self.lockPin, 0) wiringpi.digitalWrite(self.lockPin, 0)
def lock(self): def lock(self):
""" """
Lock the lock back. Meant to be used when program is shut down Lock the lock back. Meant to be used when program is shut down
so that lock is not left disengaged. so that lock is not left disengaged.
""" """
wiringpi.digitalWrite(self.lockPin, 0) wiringpi.digitalWrite(self.lockPin, 0)