+
+def test_ap_ft_extra_ie(dev, apdev):
+ """WPA2-PSK-FT AP with WPA2-PSK enabled and unexpected MDE"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params["wpa_key_mgmt"] = "WPA-PSK FT-PSK"
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ dev[1].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
+ scan_freq="2412")
+ dev[2].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
+ scan_freq="2412")
+ try:
+ # Add Mobility Domain element to test AP validation code.
+ dev[0].request("VENDOR_ELEM_ADD 13 3603a1b201")
+ dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK", proto="WPA2",
+ scan_freq="2412", wait_connect=False)
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-ASSOC-REJECT"], timeout=10)
+ if ev is None:
+ raise Exception("No connection result")
+ if "CTRL-EVENT-CONNECTED" in ev:
+ raise Exception("Non-FT association accepted with MDE")
+ if "status_code=43" not in ev:
+ raise Exception("Unexpected status code: " + ev)
+ dev[0].request("DISCONNECT")
+ finally:
+ dev[0].request("VENDOR_ELEM_REMOVE 13 *")
+
+def test_ap_ft_ric(dev, apdev):
+ """WPA2-PSK-FT AP and RIC"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ dev[0].set("ric_ies", "")
+ dev[0].set("ric_ies", '""')
+ if "FAIL" not in dev[0].request("SET ric_ies q"):
+ raise Exception("Invalid ric_ies value accepted")
+
+ tests = ["3900",
+ "3900ff04eeeeeeee",
+ "390400000000",
+ "390400000000" + "390400000000",
+ "390400000000" + "dd050050f20202",
+ "390400000000" + "dd3d0050f2020201" + 55*"00",
+ "390400000000" + "dd3d0050f2020201aa300010270000000000000000000000000000000000000000000000000000ffffff7f00000000000000000000000040420f00ffff0000",
+ "390401010000" + "dd3d0050f2020201aa3000dc050000000000000000000000000000000000000000000000000000dc050000000000000000000000000000808d5b0028230000"]
+ for t in tests:
+ dev[0].set("ric_ies", t)
+ run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
+ test_connectivity=False)
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+ dev[0].dump_monitor()
+
+def ie_hex(ies, id):
+ return binascii.hexlify(struct.pack('BB', id, len(ies[id])) + ies[id]).decode()
+
+def test_ap_ft_reassoc_proto(dev, apdev):
+ """WPA2-PSK-FT AP Reassociation Request frame parsing"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
+ ieee80211w="1", scan_freq="2412")
+ if dev[0].get_status_field('bssid') == hapd0.own_addr():
+ hapd1ap = hapd0
+ hapd2ap = hapd1
+ else:
+ hapd1ap = hapd1
+ hapd2ap = hapd0
+
+ dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
+ hapd2ap.set("ext_mgmt_frame_handling", "1")
+ dev[0].request("ROAM " + hapd2ap.own_addr())
+
+ while True:
+ req = hapd2ap.mgmt_rx()
+ hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
+ if req['subtype'] == 11:
+ break
+
+ while True:
+ req = hapd2ap.mgmt_rx()
+ if req['subtype'] == 2:
+ break
+ hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
+
+ # IEEE 802.11 header + fixed fields before IEs
+ hdr = binascii.hexlify(req['frame'][0:34]).decode()
+ ies = parse_ie(binascii.hexlify(req['frame'][34:]))
+ # First elements: SSID, Supported Rates, Extended Supported Rates
+ ies1 = ie_hex(ies, 0) + ie_hex(ies, 1) + ie_hex(ies, 50)
+
+ rsne = ie_hex(ies, 48)
+ mde = ie_hex(ies, 54)
+ fte = ie_hex(ies, 55)
+ tests = []
+ # RSN: Trying to use FT, but MDIE not included
+ tests += [rsne]
+ # RSN: Attempted to use unknown MDIE
+ tests += [rsne + "3603000000"]
+ # Invalid RSN pairwise cipher
+ tests += ["30260100000fac040100000fac030100000fac040000010029208a42cd25c85aa571567dce10dae3"]
+ # FT: No PMKID in RSNIE
+ tests += ["30160100000fac040100000fac040100000fac0400000000" + ie_hex(ies, 54)]
+ # FT: Invalid FTIE
+ tests += [rsne + mde]
+ # FT: RIC IE(s) in the frame, but not included in protected IE count
+ # FT: Failed to parse FT IEs
+ tests += [rsne + mde + fte + "3900"]
+ # FT: SNonce mismatch in FTIE
+ tests += [rsne + mde + "37520000" + 16*"00" + 32*"00" + 32*"00"]
+ # FT: ANonce mismatch in FTIE
+ tests += [rsne + mde + fte[0:40] + 32*"00" + fte[104:]]
+ # FT: No R0KH-ID subelem in FTIE
+ tests += [rsne + mde + "3752" + fte[4:168]]
+ # FT: R0KH-ID in FTIE did not match with the current R0KH-ID
+ tests += [rsne + mde + "3755" + fte[4:168] + "0301ff"]
+ # FT: No R1KH-ID subelem in FTIE
+ tests += [rsne + mde + "375e" + fte[4:168] + "030a" + binascii.hexlify(b"nas1.w1.fi").decode()]
+ # FT: Unknown R1KH-ID used in ReassocReq
+ tests += [rsne + mde + "3766" + fte[4:168] + "030a" + binascii.hexlify(b"nas1.w1.fi").decode() + "0106000000000000"]
+ # FT: PMKID in Reassoc Req did not match with the PMKR1Name derived from auth request
+ tests += [rsne[:-32] + 16*"00" + mde + fte]
+ # Invalid MIC in FTIE
+ tests += [rsne + mde + fte[0:8] + 16*"00" + fte[40:]]
+ for t in tests:
+ hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + ies1 + t)
+
+def test_ap_ft_reassoc_local_fail(dev, apdev):
+ """WPA2-PSK-FT AP Reassociation Request frame and local failure"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
+ ieee80211w="1", scan_freq="2412")
+ if dev[0].get_status_field('bssid') == hapd0.own_addr():
+ hapd1ap = hapd0
+ hapd2ap = hapd1
+ else:
+ hapd1ap = hapd1
+ hapd2ap = hapd0
+
+ dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
+ # FT: Failed to calculate MIC
+ with fail_test(hapd2ap, 1, "wpa_ft_validate_reassoc"):
+ dev[0].request("ROAM " + hapd2ap.own_addr())
+ ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10)
+ dev[0].request("DISCONNECT")
+ if ev is None:
+ raise Exception("Association reject not seen")
+
+def test_ap_ft_reassoc_replay(dev, apdev, params):
+ """WPA2-PSK-FT AP and replayed Reassociation Request frame"""
+ capfile = os.path.join(params['logdir'], "hwsim0.pcapng")
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
+ scan_freq="2412")
+ if dev[0].get_status_field('bssid') == hapd0.own_addr():
+ hapd1ap = hapd0
+ hapd2ap = hapd1
+ else:
+ hapd1ap = hapd1
+ hapd2ap = hapd0
+
+ dev[0].scan_for_bss(hapd2ap.own_addr(), freq="2412")
+ hapd2ap.set("ext_mgmt_frame_handling", "1")
+ dev[0].dump_monitor()
+ if "OK" not in dev[0].request("ROAM " + hapd2ap.own_addr()):
+ raise Exception("ROAM failed")
+
+ reassocreq = None
+ count = 0
+ while count < 100:
+ req = hapd2ap.mgmt_rx()
+ count += 1
+ hapd2ap.dump_monitor()
+ hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
+ if req['subtype'] == 2:
+ reassocreq = req
+ ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
+ if ev is None:
+ raise Exception("No TX status seen")
+ cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
+ if "OK" not in hapd2ap.request(cmd):
+ raise Exception("MGMT_TX_STATUS_PROCESS failed")
+ break
+ hapd2ap.set("ext_mgmt_frame_handling", "0")
+ if reassocreq is None:
+ raise Exception("No Reassociation Request frame seen")
+ dev[0].wait_connected()
+ dev[0].dump_monitor()
+ hapd2ap.dump_monitor()
+
+ hwsim_utils.test_connectivity(dev[0], hapd2ap)
+
+ logger.info("Replay the last Reassociation Request frame")
+ hapd2ap.dump_monitor()
+ hapd2ap.set("ext_mgmt_frame_handling", "1")
+ hapd2ap.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + binascii.hexlify(req['frame']).decode())
+ ev = hapd2ap.wait_event(["MGMT-TX-STATUS"], timeout=5)
+ if ev is None:
+ raise Exception("No TX status seen")
+ cmd = "MGMT_TX_STATUS_PROCESS %s" % (" ".join(ev.split(' ')[1:4]))
+ if "OK" not in hapd2ap.request(cmd):
+ raise Exception("MGMT_TX_STATUS_PROCESS failed")
+ hapd2ap.set("ext_mgmt_frame_handling", "0")
+
+ try:
+ hwsim_utils.test_connectivity(dev[0], hapd2ap)
+ ok = True
+ except:
+ ok = False
+
+ ap = hapd2ap.own_addr()
+ sta = dev[0].own_addr()
+ filt = "wlan.fc.type == 2 && " + \
+ "wlan.da == " + sta + " && " + \
+ "wlan.sa == " + ap + " && " + \
+ "wlan.fc.protected == 1"
+ fields = ["wlan.ccmp.extiv"]
+ res = run_tshark(capfile, filt, fields)
+ vals = res.splitlines()
+ logger.info("CCMP PN: " + str(vals))
+ if len(vals) < 2:
+ raise Exception("Could not find all CCMP protected frames from capture")
+ if len(set(vals)) < len(vals):
+ raise Exception("Duplicate CCMP PN used")
+
+ if not ok:
+ raise Exception("The second hwsim connectivity test failed")
+
+def test_ap_ft_psk_file(dev, apdev):
+ """WPA2-PSK-FT AP with PSK from a file"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1a(ssid=ssid, passphrase=passphrase)
+ params['wpa_psk_file'] = 'hostapd.wpa_psk'
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[1].connect(ssid, psk="very secret",
+ key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
+ scan_freq="2412", wait_connect=False)
+ dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
+ ieee80211w="1", scan_freq="2412")
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+ dev[0].connect(ssid, psk="very secret", key_mgmt="FT-PSK", proto="WPA2",
+ ieee80211w="1", scan_freq="2412")
+ dev[0].request("REMOVE_NETWORK all")
+ dev[0].wait_disconnected()
+ dev[0].connect(ssid, psk="secret passphrase",
+ key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
+ scan_freq="2412")
+ dev[2].connect(ssid, psk="another passphrase for all STAs",
+ key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1",
+ scan_freq="2412")
+ ev = dev[1].wait_event(["WPA: 4-Way Handshake failed"], timeout=10)
+ if ev is None:
+ raise Exception("Timed out while waiting for failure report")
+ dev[1].request("REMOVE_NETWORK all")
+
+def test_ap_ft_eap_ap_config_change(dev, apdev):
+ """WPA2-EAP-FT AP changing from 802.1X-only to FT-only"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+ bssid = apdev[0]['bssid']
+
+ radius = hostapd.radius_params()
+ params = ft_params1(ssid=ssid, passphrase=passphrase, discovery=True)
+ params['wpa_key_mgmt'] = "WPA-EAP"
+ params["ieee8021x"] = "1"
+ params["pmk_r1_push"] = "0"
+ params["r0kh"] = "ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
+ params["r1kh"] = "00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"
+ params["eap_server"] = "0"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ dev[0].connect(ssid, key_mgmt="FT-EAP WPA-EAP", proto="WPA2",
+ eap="GPSK", identity="gpsk user",
+ password="abcdefghijklmnop0123456789abcdef",
+ scan_freq="2412")
+ dev[0].request("DISCONNECT")
+ dev[0].wait_disconnected()
+ dev[0].dump_monitor()
+
+ hapd.disable()
+ hapd.set('wpa_key_mgmt', "FT-EAP")
+ hapd.enable()
+
+ dev[0].request("BSS_FLUSH 0")
+ dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True)
+
+ dev[0].request("RECONNECT")
+ dev[0].wait_connected()
+
+def test_ap_ft_eap_sha384(dev, apdev):
+ """WPA2-EAP-FT with SHA384"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ radius = hostapd.radius_params()
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params["ieee80211w"] = "2"
+ params['wpa_key_mgmt'] = "FT-EAP-SHA384"
+ params["ieee8021x"] = "1"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ params["ieee80211w"] = "2"
+ params['wpa_key_mgmt'] = "FT-EAP-SHA384"
+ params["ieee8021x"] = "1"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True,
+ sha384=True)
+
+def test_ap_ft_eap_sha384_reassoc(dev, apdev):
+ """WPA2-EAP-FT with SHA384 using REASSOCIATE"""
+ check_suite_b_192_capa(dev)
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ radius = hostapd.radius_params()
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params["ieee80211w"] = "2"
+ params['wpa_key_mgmt'] = "WPA-EAP-SUITE-B-192 FT-EAP-SHA384"
+ params["ieee8021x"] = "1"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ params["ieee80211w"] = "2"
+ params['wpa_key_mgmt'] = "WPA-EAP-SUITE-B-192 FT-EAP-SHA384"
+ params["ieee8021x"] = "1"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, eap=True,
+ sha384=True, also_non_ft=True, roam_with_reassoc=True)
+
+def test_ap_ft_eap_sha384_over_ds(dev, apdev):
+ """WPA2-EAP-FT with SHA384 over DS"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ radius = hostapd.radius_params()
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params["ieee80211w"] = "2"
+ params['wpa_key_mgmt'] = "FT-EAP-SHA384"
+ params["ieee8021x"] = "1"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ params["ieee80211w"] = "2"
+ params['wpa_key_mgmt'] = "FT-EAP-SHA384"
+ params["ieee8021x"] = "1"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
+ eap=True, sha384=True)
+
+def test_ap_ft_roam_rrm(dev, apdev):
+ """WPA2-PSK-FT AP and radio measurement request"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params["rrm_beacon_report"] = "1"
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ bssid0 = hapd0.own_addr()
+
+ addr = dev[0].own_addr()
+ dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2",
+ scan_freq="2412")
+ check_beacon_req(hapd0, addr, 1)
+
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ params["rrm_beacon_report"] = "1"
+ hapd1 = hostapd.add_ap(apdev[1], params)
+ bssid1 = hapd1.own_addr()
+
+ dev[0].scan_for_bss(bssid1, freq=2412)
+ dev[0].roam(bssid1)
+ check_beacon_req(hapd1, addr, 2)
+
+ dev[0].scan_for_bss(bssid0, freq=2412)
+ dev[0].roam(bssid0)
+ check_beacon_req(hapd0, addr, 3)
+
+def test_ap_ft_pmksa_caching(dev, apdev):
+ """FT-EAP and PMKSA caching for initial mobility domain association"""
+ ssid = "test-ft"
+ identity = "gpsk user"
+
+ radius = hostapd.radius_params()
+ params = ft_params1(ssid=ssid)
+ params['wpa_key_mgmt'] = "FT-EAP"
+ params["ieee8021x"] = "1"
+ params["mobility_domain"] = "c3d4"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ params = ft_params2(ssid=ssid)
+ params['wpa_key_mgmt'] = "FT-EAP"
+ params["ieee8021x"] = "1"
+ params["mobility_domain"] = "c3d4"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ run_roams(dev[0], apdev, hapd, hapd1, ssid, None, eap=True,
+ eap_identity=identity, pmksa_caching=True)
+
+def test_ap_ft_pmksa_caching_sha384(dev, apdev):
+ """FT-EAP-SHA384 and PMKSA caching for initial mobility domain association"""
+ ssid = "test-ft"
+ identity = "gpsk user"
+
+ radius = hostapd.radius_params()
+ params = ft_params1(ssid=ssid)
+ params['wpa_key_mgmt'] = "FT-EAP-SHA384"
+ params["ieee8021x"] = "1"
+ params["mobility_domain"] = "c3d4"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd = hostapd.add_ap(apdev[0], params)
+
+ params = ft_params2(ssid=ssid)
+ params['wpa_key_mgmt'] = "FT-EAP-SHA384"
+ params["ieee8021x"] = "1"
+ params["mobility_domain"] = "c3d4"
+ params = dict(list(radius.items()) + list(params.items()))
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ run_roams(dev[0], apdev, hapd, hapd1, ssid, None, eap=True,
+ eap_identity=identity, pmksa_caching=True, sha384=True)
+
+def test_ap_ft_r1_key_expiration(dev, apdev):
+ """WPA2-PSK-FT and PMK-R1 expiration"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params['r1_max_key_lifetime'] = "2"
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ params['r1_max_key_lifetime'] = "2"
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ # This succeeds, but results in having to run another PMK-R1 pull before the
+ # second AP can complete FT protocol.
+ run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, wait_before_roam=4)
+
+def test_ap_ft_r0_key_expiration(dev, apdev):
+ """WPA2-PSK-FT and PMK-R0 expiration"""
+ ssid = "test-ft"
+ passphrase = "12345678"
+
+ params = ft_params1(ssid=ssid, passphrase=passphrase)
+ params['ft_r0_key_lifetime'] = "2"
+ hapd0 = hostapd.add_ap(apdev[0], params)
+ params = ft_params2(ssid=ssid, passphrase=passphrase)
+ params['ft_r0_key_lifetime'] = "2"
+ hapd1 = hostapd.add_ap(apdev[1], params)
+
+ bssid2 = run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase,
+ return_after_initial=True)
+ time.sleep(4)
+ dev[0].scan_for_bss(bssid2, freq="2412")
+ if "OK" not in dev[0].request("ROAM " + bssid2):
+ raise Exception("ROAM failed")
+ ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+ "CTRL-EVENT-AUTH-REJECT",
+ "CTRL-EVENT-ASSOC-REJECT"], timeout=5)
+ dev[0].request("DISCONNECT")
+ if ev is None or "CTRL-EVENT-AUTH-REJECT" not in ev:
+ raise Exception("FT protocol failure not reported")
+ if "status_code=53" not in ev:
+ raise Exception("Unexpected status in FT protocol failure: " + ev)
+
+ # Generate a new PMK-R0
+ dev[0].dump_monitor()
+ dev[0].request("RECONNECT")
+ dev[0].wait_connected()