import wpaspy
wpas_ctrl = '/var/run/hostapd'
+continue_loop = True
def wpas_connect():
ifaces = []
wpas = wpas_connect()
if (wpas == None):
return
- print wpas.request("WPS_NFC_TAG_READ " + message.encode("hex"))
+ if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")):
+ return False
+ return True
def wpas_get_config_token():
class HandoverServer(nfc.handover.HandoverServer):
- def __init__(self):
- super(HandoverServer, self).__init__()
+ def __init__(self, llc):
+ super(HandoverServer, self).__init__(llc)
+ self.ho_server_processing = False
+ self.success = False
def process_request(self, request):
print "HandoverServer - request received"
print "Remote carrier type: " + carrier.type
if carrier.type == "application/vnd.wfa.wsc":
print "WPS carrier type match - add WPS carrier record"
- self.received_carrier = carrier.record
data = wpas_get_handover_sel()
if data is None:
print "Could not get handover select carrier record from hostapd"
continue
print "Handover select carrier record from hostapd:"
print data.encode("hex")
- self.sent_carrier = data
+ wpas_report_handover(carrier.record, data)
message = nfc.ndef.Message(data);
sel.add_carrier(message[0], "active", message[1:])
print str(sel).encode("hex")
print "Sending handover select"
+ self.success = True
return sel
-def wps_handover_resp(peer):
- print "Trying to handle WPS handover"
-
- srv = HandoverServer()
- srv.sent_carrier = None
-
- nfc.llcp.activate(peer);
-
- try:
- print "Trying handover";
- srv.start()
- print "Wait for disconnect"
- while nfc.llcp.connected():
- time.sleep(0.1)
- print "Disconnected after handover"
- except nfc.llcp.ConnectRefused:
- print "Handover connection refused"
- nfc.llcp.shutdown()
- return
-
- if srv.sent_carrier:
- wpas_report_handover(srv.received_carrier, srv.sent_carrier)
-
- print "Remove peer"
- nfc.llcp.shutdown()
- print "Done with handover"
-
-
def wps_tag_read(tag):
+ success = False
if len(tag.ndef.message):
- message = nfc.ndef.Message(tag.ndef.message)
- print "message type " + message.type
-
- for record in message:
+ for record in tag.ndef.message:
print "record type " + record.type
if record.type == "application/vnd.wfa.wsc":
print "WPS tag - send to hostapd"
- wpas_tag_read(tag.ndef.message)
+ success = wpas_tag_read(tag.ndef.message)
break
else:
print "Empty tag"
- print "Remove tag"
- while tag.is_present:
- time.sleep(0.1)
+ return success
+def rdwr_connected_write(tag):
+ print "Tag found - writing"
+ global write_data
+ tag.ndef.message = str(write_data)
+ print "Done - remove tag"
+ global only_one
+ if only_one:
+ global continue_loop
+ continue_loop = False
+ global write_wait_remove
+ while write_wait_remove and tag.is_present:
+ time.sleep(0.1)
+
def wps_write_config_tag(clf):
print "Write WPS config token"
- data = wpas_get_config_token()
- if (data == None):
+ global write_data, write_wait_remove
+ write_wait_remove = True
+ write_data = wpas_get_config_token()
+ if write_data == None:
print "Could not get WPS config token from hostapd"
return
print "Touch an NFC tag"
- while True:
- tag = clf.poll()
- if tag == None:
- time.sleep(0.1)
- continue
- break
-
- print "Tag found - writing"
- tag.ndef.message = data
- print "Done - remove tag"
- while tag.is_present:
- time.sleep(0.1)
+ clf.connect(rdwr={'on-connect': rdwr_connected_write})
def wps_write_password_tag(clf):
print "Write WPS password token"
- data = wpas_get_password_token()
- if (data == None):
+ global write_data, write_wait_remove
+ write_wait_remove = True
+ write_data = wpas_get_password_token()
+ if write_data == None:
print "Could not get WPS password token from hostapd"
return
print "Touch an NFC tag"
- while True:
- tag = clf.poll()
- if tag == None:
+ clf.connect(rdwr={'on-connect': rdwr_connected_write})
+
+
+def rdwr_connected(tag):
+ global only_one
+ print "Tag connected: " + str(tag)
+
+ if tag.ndef:
+ print "NDEF tag: " + tag.type
+ try:
+ print tag.ndef.message.pretty()
+ except Exception, e:
+ print e
+ success = wps_tag_read(tag)
+ if only_one and success:
+ global continue_loop
+ continue_loop = False
+ else:
+ print "Not an NDEF tag - remove tag"
+ while tag.is_present:
time.sleep(0.1)
- continue
- break
- print "Tag found - writing"
- tag.ndef.message = data
- print "Done - remove tag"
- while tag.is_present:
- time.sleep(0.1)
+ return not no_wait
+
+def llcp_startup(clf, llc):
+ print "Start LLCP server"
+ global srv
+ srv = HandoverServer(llc)
+ return llc
-def find_peer(clf):
- while True:
- if nfc.llcp.connected():
- print "LLCP connected"
- general_bytes = nfc.llcp.startup({})
- peer = clf.listen(ord(os.urandom(1)) + 250, general_bytes)
- if isinstance(peer, nfc.DEP):
- print "listen -> DEP";
- if peer.general_bytes.startswith("Ffm"):
- print "Found DEP"
- return peer
- print "mismatch in general_bytes"
- print peer.general_bytes
-
- peer = clf.poll(general_bytes)
- if isinstance(peer, nfc.DEP):
- print "poll -> DEP";
- if peer.general_bytes.startswith("Ffm"):
- print "Found DEP"
- return peer
- print "mismatch in general_bytes"
- print peer.general_bytes
-
- if peer:
- print "Found tag"
- return peer
+def llcp_connected(llc):
+ print "P2P LLCP connected"
+ global wait_connection
+ wait_connection = False
+ global srv
+ srv.start()
+ return True
def main():
clf = nfc.ContactlessFrontend()
try:
+ if not clf.open("usb"):
+ print "Could not open connection with an NFC device"
+ raise SystemExit
+
+ global only_one
+ only_one = False
+
if len(sys.argv) > 1 and sys.argv[1] == "write-config":
wps_write_config_tag(clf)
raise SystemExit
wps_write_password_tag(clf)
raise SystemExit
- while True:
+ global continue_loop
+ while continue_loop:
print "Waiting for a tag or peer to be touched"
-
- tag = find_peer(clf)
- if isinstance(tag, nfc.DEP):
- wps_handover_resp(tag)
- continue
-
- if tag.ndef:
- wps_tag_read(tag)
- continue
-
- print "Not an NDEF tag - remove tag"
- while tag.is_present:
- time.sleep(0.1)
+ wait_connection = True
+ try:
+ if not clf.connect(rdwr={'on-connect': rdwr_connected},
+ llcp={'on-startup': llcp_startup,
+ 'on-connect': llcp_connected}):
+ break
+ except Exception, e:
+ print "clf.connect failed"
+
+ global srv
+ if only_one and srv and srv.success:
+ raise SystemExit
except KeyboardInterrupt:
raise SystemExit
import time
import random
import StringIO
+import threading
import nfc
import nfc.ndef
import wpaspy
wpas_ctrl = '/var/run/wpa_supplicant'
+srv = None
+continue_loop = True
def wpas_connect():
ifaces = []
wpas = wpas_connect()
if (wpas == None):
return False
- if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + message.encode("hex")):
+ if "FAIL" in wpas.request("WPS_NFC_TAG_READ " + str(message).encode("hex")):
return False
return True
class HandoverServer(nfc.handover.HandoverServer):
- def __init__(self):
- super(HandoverServer, self).__init__()
+ def __init__(self, llc):
+ super(HandoverServer, self).__init__(llc)
+ self.sent_carrier = None
+ self.ho_server_processing = False
+ self.success = False
def process_request(self, request):
+ self.ho_server_processing = True
print "HandoverServer - request received"
print "Parsed handover request: " + request.pretty()
print "Remote carrier type: " + carrier.type
if carrier.type == "application/vnd.wfa.wsc":
print "WPS carrier type match - add WPS carrier record"
- self.received_carrier = carrier.record
data = wpas_get_handover_sel(self.uuid)
if data is None:
print "Could not get handover select carrier record from wpa_supplicant"
print "Handover select carrier record from wpa_supplicant:"
print data.encode("hex")
self.sent_carrier = data
+ wpas_report_handover(carrier.record, self.sent_carrier, "RESP")
message = nfc.ndef.Message(data);
sel.add_carrier(message[0], "active", message[1:])
print str(sel).encode("hex")
print "Sending handover select"
+ self.success = True
return sel
-def wps_handover_resp(peer, uuid):
- if uuid is None:
- print "Trying to handle WPS handover"
- else:
- print "Trying to handle WPS handover with AP " + uuid
-
- srv = HandoverServer()
- srv.sent_carrier = None
- srv.uuid = uuid
-
- nfc.llcp.activate(peer);
-
- try:
- print "Trying handover";
- srv.start()
- print "Wait for disconnect"
- while nfc.llcp.connected():
- time.sleep(0.1)
- print "Disconnected after handover"
- except nfc.llcp.ConnectRefused:
- print "Handover connection refused"
- nfc.llcp.shutdown()
- return
-
- if srv.sent_carrier:
- wpas_report_handover(srv.received_carrier, srv.sent_carrier, "RESP")
-
- print "Remove peer"
- nfc.llcp.shutdown()
- print "Done with handover"
- time.sleep(1)
-
-
-def wps_handover_init(peer):
+def wps_handover_init(llc):
print "Trying to initiate WPS handover"
data = wpas_get_handover_req()
print "Handover request:"
print message.pretty()
- nfc.llcp.activate(peer);
-
- client = nfc.handover.HandoverClient()
+ client = nfc.handover.HandoverClient(llc)
try:
print "Trying handover";
client.connect()
print "Connected for handover"
except nfc.llcp.ConnectRefused:
print "Handover connection refused"
- nfc.llcp.shutdown()
client.close()
return
message = client._recv()
if message is None:
print "No response received"
- nfc.llcp.shutdown()
client.close()
return
if message.type != "urn:nfc:wkt:Hs":
print "Response was not Hs - received: " + message.type
- nfc.llcp.shutdown()
client.close()
return
print wifi.pretty()
print "Remove peer"
- nfc.llcp.shutdown()
client.close()
print "Done with handover"
+ global only_one
+ if only_one:
+ global continue_loop
+ continue_loop = False
def wps_tag_read(tag, wait_remove=True):
success = False
if len(tag.ndef.message):
- message = nfc.ndef.Message(tag.ndef.message)
- print "message type " + message.type
-
- for record in message:
+ for record in tag.ndef.message:
print "record type " + record.type
if record.type == "application/vnd.wfa.wsc":
print "WPS tag - send to wpa_supplicant"
return success
+def rdwr_connected_write(tag):
+ print "Tag found - writing"
+ global write_data
+ tag.ndef.message = str(write_data)
+ print "Done - remove tag"
+ global only_one
+ if only_one:
+ global continue_loop
+ continue_loop = False
+ global write_wait_remove
+ while write_wait_remove and tag.is_present:
+ time.sleep(0.1)
+
def wps_write_config_tag(clf, id=None, wait_remove=True):
print "Write WPS config token"
- data = wpas_get_config_token(id)
- if (data == None):
+ global write_data, write_wait_remove
+ write_wait_remove = wait_remove
+ write_data = wpas_get_config_token(id)
+ if write_data == None:
print "Could not get WPS config token from wpa_supplicant"
sys.exit(1)
return
-
print "Touch an NFC tag"
- while True:
- tag = clf.poll()
- if tag == None:
- time.sleep(0.1)
- continue
- break
-
- print "Tag found - writing"
- tag.ndef.message = data
- print "Done - remove tag"
- while wait_remove and tag.is_present:
- time.sleep(0.1)
+ clf.connect(rdwr={'on-connect': rdwr_connected_write})
def wps_write_er_config_tag(clf, uuid):
print "Write WPS ER config token"
- data = wpas_get_er_config_token(uuid)
- if (data == None):
+ global write_data, write_wait_remove
+ write_wait_remove = True
+ write_data = wpas_get_er_config_token(uuid)
+ if write_data == None:
print "Could not get WPS config token from wpa_supplicant"
return
print "Touch an NFC tag"
- while True:
- tag = clf.poll()
- if tag == None:
- time.sleep(0.1)
- continue
- break
-
- print "Tag found - writing"
- tag.ndef.message = data
- print "Done - remove tag"
- while tag.is_present:
- time.sleep(0.1)
+ clf.connect(rdwr={'on-connect': rdwr_connected_write})
def wps_write_password_tag(clf, wait_remove=True):
print "Write WPS password token"
- data = wpas_get_password_token()
- if (data == None):
+ global write_data, write_wait_remove
+ write_wait_remove = wait_remove
+ write_data = wpas_get_password_token()
+ if write_data == None:
print "Could not get WPS password token from wpa_supplicant"
return
print "Touch an NFC tag"
- while True:
- tag = clf.poll()
- if tag == None:
+ clf.connect(rdwr={'on-connect': rdwr_connected_write})
+
+
+def rdwr_connected(tag):
+ global only_one
+ print "Tag connected: " + str(tag)
+
+ if tag.ndef:
+ print "NDEF tag: " + tag.type
+ try:
+ print tag.ndef.message.pretty()
+ except Exception, e:
+ print e
+ success = wps_tag_read(tag, not only_one)
+ if only_one and success:
+ global continue_loop
+ continue_loop = False
+ else:
+ print "Not an NDEF tag - remove tag"
+ while tag.is_present:
time.sleep(0.1)
- continue
- break
+ return True
- print "Tag found - writing"
- tag.ndef.message = data
- print "Done - remove tag"
- while wait_remove and tag.is_present:
- time.sleep(0.1)
+def llcp_worker(llc):
+ global arg_uuid
+ if arg_uuid is None:
+ wps_handover_init(llc)
+ return
-def find_peer(clf):
- while True:
- if nfc.llcp.connected():
- print "LLCP connected"
- general_bytes = nfc.llcp.startup({})
- peer = clf.listen(ord(os.urandom(1)) + 250, general_bytes)
- if isinstance(peer, nfc.DEP):
- print "listen -> DEP";
- if peer.general_bytes.startswith("Ffm"):
- print "Found DEP"
- return peer
- print "mismatch in general_bytes"
- print peer.general_bytes
-
- peer = clf.poll(general_bytes)
- if isinstance(peer, nfc.DEP):
- print "poll -> DEP";
- if peer.general_bytes.startswith("Ffm"):
- print "Found DEP"
- return peer
- print "mismatch in general_bytes"
- print peer.general_bytes
-
- if peer:
- print "Found tag"
- return peer
+ global srv
+ global wait_connection
+ while not wait_connection and srv.sent_carrier is None:
+ if srv.ho_server_processing:
+ time.sleep(0.025)
+
+def llcp_startup(clf, llc):
+ global arg_uuid
+ if arg_uuid:
+ print "Start LLCP server"
+ global srv
+ srv = HandoverServer(llc)
+ if arg_uuid is "ap":
+ print "Trying to handle WPS handover"
+ srv.uuid = None
+ else:
+ print "Trying to handle WPS handover with AP " + arg_uuid
+ srv.uuid = arg_uuid
+ return llc
+
+def llcp_connected(llc):
+ print "P2P LLCP connected"
+ global wait_connection
+ wait_connection = False
+ global arg_uuid
+ if arg_uuid:
+ global srv
+ srv.start()
+ else:
+ threading.Thread(target=llcp_worker, args=(llc,)).start()
+ return True
def main():
clf = nfc.ContactlessFrontend()
try:
+ global arg_uuid
arg_uuid = None
if len(sys.argv) > 1 and sys.argv[1] != '-1':
arg_uuid = sys.argv[1]
+ global only_one
if len(sys.argv) > 1 and sys.argv[1] == '-1':
only_one = True
else:
only_one = False
+ if not clf.open("usb"):
+ print "Could not open connection with an NFC device"
+ raise SystemExit
+
if len(sys.argv) > 1 and sys.argv[1] == "write-config":
wps_write_config_tag(clf)
raise SystemExit
wps_write_password_tag(clf, wait_remove=False)
raise SystemExit
- while True:
+ global continue_loop
+ while continue_loop:
print "Waiting for a tag or peer to be touched"
-
- tag = find_peer(clf)
- if isinstance(tag, nfc.DEP):
- if arg_uuid is None:
- wps_handover_init(tag)
- elif arg_uuid is "ap":
- wps_handover_resp(tag, None)
- else:
- wps_handover_resp(tag, arg_uuid)
- if only_one:
- break
- continue
-
- if tag.ndef:
- success = wps_tag_read(tag, not only_one)
- if only_one:
- if not success:
- sys.exit(1)
+ wait_connection = True
+ try:
+ if not clf.connect(rdwr={'on-connect': rdwr_connected},
+ llcp={'on-startup': llcp_startup,
+ 'on-connect': llcp_connected}):
break
- continue
+ except Exception, e:
+ print "clf.connect failed"
- print "Not an NDEF tag - remove tag"
- if only_one:
- sys.exit(1)
- while tag.is_present:
- time.sleep(0.1)
+ global srv
+ if only_one and srv and srv.success:
+ raise SystemExit
except KeyboardInterrupt:
raise SystemExit