WPS NFC: Update wps-nfc.py and wps-ap-nfc.py to use new nfcpy API

This moves many of the peer discovery operations into the core nfcpy.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2013-11-29 12:16:38 +02:00 committed by Jouni Malinen
parent c8373f1015
commit 6f8fa6e552
2 changed files with 209 additions and 245 deletions

View file

@ -21,6 +21,7 @@ logging.basicConfig()
import wpaspy
wpas_ctrl = '/var/run/hostapd'
continue_loop = True
def wpas_connect():
ifaces = []
@ -48,7 +49,9 @@ def wpas_tag_read(message):
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():
@ -82,8 +85,10 @@ def wpas_report_handover(req, sel):
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"
@ -95,14 +100,13 @@ class HandoverServer(nfc.handover.HandoverServer):
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:])
@ -112,132 +116,112 @@ class HandoverServer(nfc.handover.HandoverServer):
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 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
def llcp_startup(clf, llc):
print "Start LLCP server"
global srv
srv = HandoverServer(llc)
return llc
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
@ -246,21 +230,21 @@ def main():
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"
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"
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)
global srv
if only_one and srv and srv.success:
raise SystemExit
except KeyboardInterrupt:
raise SystemExit

View file

@ -11,6 +11,7 @@ import sys
import time
import random
import StringIO
import threading
import nfc
import nfc.ndef
@ -23,6 +24,8 @@ logging.basicConfig()
import wpaspy
wpas_ctrl = '/var/run/wpa_supplicant'
srv = None
continue_loop = True
def wpas_connect():
ifaces = []
@ -50,7 +53,7 @@ def wpas_tag_read(message):
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
@ -107,10 +110,14 @@ def wpas_report_handover(req, sel, type):
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()
@ -120,7 +127,6 @@ class HandoverServer(nfc.handover.HandoverServer):
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"
@ -128,6 +134,7 @@ class HandoverServer(nfc.handover.HandoverServer):
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:])
@ -137,43 +144,11 @@ class HandoverServer(nfc.handover.HandoverServer):
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()
@ -195,16 +170,13 @@ def wps_handover_init(peer):
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
@ -217,12 +189,10 @@ def wps_handover_init(peer):
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
@ -241,18 +211,18 @@ def wps_handover_init(peer):
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"
@ -269,114 +239,137 @@ def wps_tag_read(tag, wait_remove=True):
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
print "Tag found - writing"
tag.ndef.message = data
print "Done - remove tag"
while wait_remove and tag.is_present:
time.sleep(0.1)
return True
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
def llcp_worker(llc):
global arg_uuid
if arg_uuid is None:
wps_handover_init(llc)
return
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
global srv
global wait_connection
while not wait_connection and srv.sent_carrier is None:
if srv.ho_server_processing:
time.sleep(0.025)
if peer:
print "Found tag"
return peer
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
@ -401,34 +394,21 @@ def main():
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:
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"
if tag.ndef:
success = wps_tag_read(tag, not only_one)
if only_one:
if not success:
sys.exit(1)
break
continue
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