tests: Avoid race condition in DPP GAS protocol testing
Responder receives Authentication Request and Config Request in a sequence and it is possible for the Config Request to be received before MGMT_RX_PROCESS has been processed for Authentication Request in the cases where the test script is in the middle of RX processing. This can result in DPP-AUTH-SUCCESS being delivered only after the MGMT-RX event for Config Reques which means that wait_auth_success() would lose that MGMT-RX event. Avoid this issue by caching the "extra" MGMT-RX event within wait_auth_success() and having the caller verify if the Config Request (GAS Initial Request) has already been received before waiting to receive it. This makes dpp_gas, dpp_gas_comeback_after_failure, and dpp_gas_timeout_handling more robust. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
5c5f86900b
commit
8dd272fded
2 changed files with 30 additions and 10 deletions
|
@ -4858,8 +4858,9 @@ def test_dpp_keygen_configurator_error(dev, apdev):
|
||||||
if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD curve=unknown"):
|
if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD curve=unknown"):
|
||||||
raise Exception("Unexpected success of invalid DPP_CONFIGURATOR_ADD")
|
raise Exception("Unexpected success of invalid DPP_CONFIGURATOR_ADD")
|
||||||
|
|
||||||
def rx_process_frame(dev):
|
def rx_process_frame(dev, msg=None):
|
||||||
msg = dev.mgmt_rx()
|
if msg is None:
|
||||||
|
msg = dev.mgmt_rx()
|
||||||
if msg is None:
|
if msg is None:
|
||||||
raise Exception("No management frame RX reported")
|
raise Exception("No management frame RX reported")
|
||||||
if "OK" not in dev.request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(
|
if "OK" not in dev.request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(
|
||||||
|
@ -4873,7 +4874,12 @@ def wait_auth_success(responder, initiator, configurator=None, enrollee=None,
|
||||||
require_configurator_failure=False,
|
require_configurator_failure=False,
|
||||||
timeout=5, stop_responder=False, stop_initiator=False):
|
timeout=5, stop_responder=False, stop_initiator=False):
|
||||||
res = {}
|
res = {}
|
||||||
ev = responder.wait_event(["DPP-AUTH-SUCCESS", "DPP-FAIL"], timeout=timeout)
|
ev = responder.wait_event(["DPP-AUTH-SUCCESS", "DPP-FAIL",
|
||||||
|
"MGMT-RX"], timeout=timeout)
|
||||||
|
if ev and "MGMT-RX" in ev:
|
||||||
|
res['responder-mgmt-rx'] = ev
|
||||||
|
ev = responder.wait_event(["DPP-AUTH-SUCCESS", "DPP-FAIL"],
|
||||||
|
timeout=timeout)
|
||||||
if ev is None or "DPP-AUTH-SUCCESS" not in ev:
|
if ev is None or "DPP-AUTH-SUCCESS" not in ev:
|
||||||
raise Exception("DPP authentication did not succeed (Responder)")
|
raise Exception("DPP authentication did not succeed (Responder)")
|
||||||
for i in ev.split(' '):
|
for i in ev.split(' '):
|
||||||
|
@ -4945,10 +4951,14 @@ def test_dpp_gas_timeout_handling(dev, apdev):
|
||||||
# DPP Authentication Confirmation
|
# DPP Authentication Confirmation
|
||||||
rx_process_frame(dev[0])
|
rx_process_frame(dev[0])
|
||||||
|
|
||||||
wait_auth_success(dev[0], dev[1])
|
res = wait_auth_success(dev[0], dev[1])
|
||||||
|
if 'responder-mgmt-rx' in res:
|
||||||
|
msg = dev[0].mgmt_rx_parse(res['responder-mgmt-rx'])
|
||||||
|
else:
|
||||||
|
msg = None
|
||||||
|
|
||||||
# DPP Configuration Request (GAS Initial Request frame)
|
# DPP Configuration Request (GAS Initial Request frame)
|
||||||
rx_process_frame(dev[0])
|
rx_process_frame(dev[0], msg)
|
||||||
|
|
||||||
# DPP Configuration Request (GAS Comeback Request frame)
|
# DPP Configuration Request (GAS Comeback Request frame)
|
||||||
rx_process_frame(dev[0])
|
rx_process_frame(dev[0])
|
||||||
|
@ -4970,10 +4980,14 @@ def test_dpp_gas_comeback_after_failure(dev, apdev):
|
||||||
# DPP Authentication Confirmation
|
# DPP Authentication Confirmation
|
||||||
rx_process_frame(dev[0])
|
rx_process_frame(dev[0])
|
||||||
|
|
||||||
wait_auth_success(dev[0], dev[1])
|
res = wait_auth_success(dev[0], dev[1])
|
||||||
|
if 'responder-mgmt-rx' in res:
|
||||||
|
msg = dev[0].mgmt_rx_parse(res['responder-mgmt-rx'])
|
||||||
|
else:
|
||||||
|
msg = None
|
||||||
|
|
||||||
# DPP Configuration Request (GAS Initial Request frame)
|
# DPP Configuration Request (GAS Initial Request frame)
|
||||||
rx_process_frame(dev[0])
|
rx_process_frame(dev[0], msg)
|
||||||
|
|
||||||
# DPP Configuration Request (GAS Comeback Request frame)
|
# DPP Configuration Request (GAS Comeback Request frame)
|
||||||
msg = dev[0].mgmt_rx()
|
msg = dev[0].mgmt_rx()
|
||||||
|
@ -5002,14 +5016,17 @@ def test_dpp_gas(dev, apdev):
|
||||||
# DPP Authentication Confirmation
|
# DPP Authentication Confirmation
|
||||||
rx_process_frame(dev[0])
|
rx_process_frame(dev[0])
|
||||||
|
|
||||||
wait_auth_success(dev[0], dev[1])
|
res = wait_auth_success(dev[0], dev[1])
|
||||||
|
|
||||||
# DPP Configuration Request (GAS Initial Request frame)
|
# DPP Configuration Request (GAS Initial Request frame)
|
||||||
msg = dev[0].mgmt_rx()
|
if 'responder-mgmt-rx' in res:
|
||||||
|
msg = dev[0].mgmt_rx_parse(res['responder-mgmt-rx'])
|
||||||
|
else:
|
||||||
|
msg = dev[0].mgmt_rx()
|
||||||
|
|
||||||
# Protected Dual of GAS Initial Request frame (dropped by GAS server)
|
# Protected Dual of GAS Initial Request frame (dropped by GAS server)
|
||||||
if msg == None:
|
if msg == None:
|
||||||
raise Exception("MGMT_RX_PROCESS failed. <Please retry>")
|
raise Exception("GAS Initial Request frame not received")
|
||||||
frame = binascii.hexlify(msg['frame'])
|
frame = binascii.hexlify(msg['frame'])
|
||||||
frame = frame[0:48] + b"09" + frame[50:]
|
frame = frame[0:48] + b"09" + frame[50:]
|
||||||
frame = frame.decode()
|
frame = frame.decode()
|
||||||
|
|
|
@ -1382,6 +1382,9 @@ class WpaSupplicant:
|
||||||
ev = self.wait_event(["MGMT-RX"], timeout=timeout)
|
ev = self.wait_event(["MGMT-RX"], timeout=timeout)
|
||||||
if ev is None:
|
if ev is None:
|
||||||
return None
|
return None
|
||||||
|
return self.mgmt_rx_parse(ev)
|
||||||
|
|
||||||
|
def mgmt_rx_parse(self, ev):
|
||||||
msg = {}
|
msg = {}
|
||||||
items = ev.split(' ')
|
items = ev.split(' ')
|
||||||
field, val = items[1].split('=')
|
field, val = items[1].split('=')
|
||||||
|
|
Loading…
Reference in a new issue