def test_tnc_peap_soh_errors(dev, apdev): """TNC PEAP-SoH local error cases""" params = int_eap_server_params() params["tnc"] = "1" hostapd.add_ap(apdev[0], params) tests = [ (1, "tncc_build_soh"), (1, "eap_msg_alloc;=eap_peap_phase2_request") ] for count, func in tests: with alloc_fail(dev[0], count, func): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", identity="user", password="******", ca_cert="auth_serv/ca.pem", phase1="peapver=0 tnc=soh cryptobinding=0", phase2="auth=MSCHAPV2", scan_freq="2412", wait_connect=False) wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() with fail_test(dev[0], 1, "os_get_random;tncc_build_soh"): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="PEAP", identity="user", password="******", ca_cert="auth_serv/ca.pem", phase1="peapver=0 tnc=soh cryptobinding=0", phase2="auth=MSCHAPV2", scan_freq="2412", wait_connect=False) wait_fail_trigger(dev[0], "GET_FAIL") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected()
def test_suite_b_192_radius(dev, apdev): """WPA2/GCMP-256 (RADIUS) connection at Suite B 192-bit level""" check_suite_b_192_capa(dev) dev[0].flush_scan_cache() params = suite_b_as_params() params['ca_cert'] = 'auth_serv/ec2-ca.pem' params['server_cert'] = 'auth_serv/ec2-server.pem' params['private_key'] = 'auth_serv/ec2-server.key' params['openssl_ciphers'] = 'SUITEB192' hostapd.add_ap(apdev[1], params) params = { "ssid": "test-suite-b", "wpa": "2", "wpa_key_mgmt": "WPA-EAP-SUITE-B-192", "rsn_pairwise": "GCMP-256", "group_mgmt_cipher": "BIP-GMAC-256", "ieee80211w": "2", "ieee8021x": "1", 'auth_server_addr': "127.0.0.1", 'auth_server_port': "18129", 'auth_server_shared_secret': "radius", 'nas_identifier': "nas.w1.fi" } hapd = hostapd.add_ap(apdev[0], params) dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", ieee80211w="2", openssl_ciphers="SUITEB192", eap="TLS", identity="tls user", ca_cert="auth_serv/ec2-ca.pem", client_cert="auth_serv/ec2-user.pem", private_key="auth_serv/ec2-user.key", pairwise="GCMP-256", group="GCMP-256", scan_freq="2412")
def test_nfc_wps_handover_pk_hash_mismatch_ap(dev, apdev): """WPS NFC connection handover with invalid pkhash from AP (negative)""" ssid = "wps-nfc-handover-pkhash-ap" params = ap_wps_params(ssid) hostapd.add_ap(apdev[0]['ifname'], params) hapd = hostapd.Hostapd(apdev[0]['ifname']) if "FAIL" in hapd.request("SET wps_corrupt_pkhash 1"): raise Exception("Could not enable wps_corrupt_pkhash") logger.info("NFC connection handover") req = dev[0].request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip() if "FAIL" in req: raise Exception("Failed to generate NFC connection handover request") sel = hapd.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip() if "FAIL" in sel: raise Exception("Failed to generate NFC connection handover select") res = hapd.request("NFC_REPORT_HANDOVER RESP WPS " + req + " " + sel) if "FAIL" in res: raise Exception("Failed to report NFC connection handover to to hostapd") dev[0].dump_monitor() res = dev[0].request("NFC_REPORT_HANDOVER INIT WPS " + req + " " + sel) if "FAIL" in res: raise Exception("Failed to report NFC connection handover to to wpa_supplicant") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "WPS-FAIL"], timeout=15) if ev is None: raise Exception("Timed out") if "WPS-FAIL" not in ev: raise Exception("Public key hash mismatch not detected")
def test_ap_wps_pbc_overlap_2sta(dev, apdev): """WPS PBC session overlap with two active STAs""" ssid = "test-wps-pbc-overlap" hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid, "eap_server": "1", "wps_state": "2", "wpa_passphrase": "12345678", "wpa": "2", "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}) hapd = hostapd.Hostapd(apdev[0]['ifname']) logger.info("WPS provisioning step") hapd.request("WPS_PBC") dev[0].request("SET ignore_old_scan_res 1") dev[1].request("SET ignore_old_scan_res 1") dev[0].dump_monitor() dev[1].dump_monitor() dev[0].request("WPS_PBC") dev[1].request("WPS_PBC") ev = dev[0].wait_event(["WPS-M2D"], timeout=15) if ev is None: raise Exception("PBC session overlap not detected (dev0)") if "config_error=12" not in ev: raise Exception("PBC session overlap not correctly reported (dev0)") ev = dev[1].wait_event(["WPS-M2D"], timeout=15) if ev is None: raise Exception("PBC session overlap not detected (dev1)") if "config_error=12" not in ev: raise Exception("PBC session overlap not correctly reported (dev1)")
def start_ap_er(er, ap, ssid): ap_pin = "12345670" ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e" hostapd.add_ap(ap['ifname'], { "ssid": ssid, "eap_server": "1", "wps_state": "2", "wpa_passphrase": "12345678", "wpa": "2", "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP", "device_name": "Wireless AP", "manufacturer": "Company", "model_name": "WAP", "model_number": "123", "serial_number": "12345", "device_type": "6-0050F204-1", "os_version": "01020300", "config_methods": "label push_button", "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"}) logger.info("Learn AP configuration") er.dump_monitor() er.request("SET ignore_old_scan_res 1") er.wps_reg(ap['bssid'], ap_pin) logger.info("Start ER") er.request("WPS_ER_STOP") time.sleep(1) er.request("WPS_ER_START ifname=lo") ev = er.wait_event(["WPS-ER-AP-ADD"], timeout=15) if ev is None: raise Exception("AP discovery timed out") if ap_uuid not in ev: raise Exception("Expected AP UUID not found") logger.info("Use learned network configuration on ER") er.request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
def test_nfc_wps_handover_errors(dev, apdev): """WPS AP NFC handover report error cases""" ssid = "test-wps-nfc-handover" hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid, "eap_server": "1", "wps_state": "1" }) hapd = hostapd.Hostapd(apdev[0]['ifname']) sel = hapd.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip() if "FAIL" in sel: raise Exception("Failed to generate NFC connection handover select") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER "): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP"): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP WPS"): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP WPS 001122"): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP WPS 001122 00"): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP WPS 0 00"): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP WPS 001122 0"): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP WPS 00q122 001122"): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP WPS 001122 001q22"): raise Exception("Unexpected handover report success") if "FAIL" not in hapd.request("NFC_REPORT_HANDOVER RESP FOO 001122 00"): raise Exception("Unexpected handover report success")
def test_nfc_wps_handover_with_pw_token_set(dev, apdev): """Connect to WPS AP with NFC connection handover (wps_nfc_* set)""" ssid = "test-wps-nfc-handover2" params = ap_wps_params(ssid) hostapd.add_ap(apdev[0]['ifname'], params) hapd = hostapd.Hostapd(apdev[0]['ifname']) # enable a password token (which won't be used in this test case) pw = hapd.request("WPS_NFC_TOKEN NDEF").rstrip() if "FAIL" in pw: raise Exception("Failed to generate password token") res = hapd.request("WPS_NFC_TOKEN enable") if "FAIL" in pw: raise Exception("Failed to enable AP password token") logger.info("NFC connection handover") req = dev[0].request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip() if "FAIL" in req: raise Exception("Failed to generate NFC connection handover request") sel = hapd.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip() if "FAIL" in sel: raise Exception("Failed to generate NFC connection handover select") res = hapd.request("NFC_REPORT_HANDOVER RESP WPS " + req + " " + sel) if "FAIL" in res: raise Exception("Failed to report NFC connection handover to to hostapd") dev[0].dump_monitor() res = dev[0].request("NFC_REPORT_HANDOVER INIT WPS " + req + " " + sel) if "FAIL" in res: raise Exception("Failed to report NFC connection handover to to wpa_supplicant") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15) if ev is None: raise Exception("Association with the AP timed out") check_wpa2_connection(dev[0], apdev[0], ssid)
def test_nfc_wps_password_token_ap(dev, apdev): """WPS registrar configuring an AP using AP password token""" ssid = "test-wps-nfc-pw-token-init" hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid, "eap_server": "1", "wps_state": "1" }) hapd = hostapd.Hostapd(apdev[0]['ifname']) logger.info("WPS configuration step") pw = hapd.request("WPS_NFC_TOKEN NDEF").rstrip() if "FAIL" in pw: raise Exception("Failed to generate password token") res = hapd.request("WPS_NFC_TOKEN enable") if "FAIL" in pw: raise Exception("Failed to enable AP password token") res = dev[0].request("WPS_NFC_TAG_READ " + pw) if "FAIL" in res: raise Exception("Failed to provide NFC tag contents to wpa_supplicant") dev[0].dump_monitor() new_ssid = "test-wps-nfc-pw-token-new-ssid" new_passphrase = "1234567890" res = dev[0].request("WPS_REG " + apdev[0]['bssid'] + " nfc-pw " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")) if "FAIL" in res: raise Exception("Failed to start Registrar using NFC password token") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30) if ev is None: raise Exception("Association with the AP timed out") check_wpa2_connection(dev[0], apdev[0], new_ssid, mixed=True) if "FAIL" in hapd.request("WPS_NFC_TOKEN disable"): raise Exception("Failed to disable AP password token") if "FAIL" in hapd.request("WPS_NFC_TOKEN WPS"): raise Exception("Unexpected WPS_NFC_TOKEN WPS failure")
def test_nfc_wps_handover_init(dev, apdev): """Connect to WPS AP with NFC connection handover and move to configured state""" dev[0].request("SET ignore_old_scan_res 1") ssid = "test-wps-nfc-handover-init" hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid, "eap_server": "1", "wps_state": "1" }) hapd = hostapd.Hostapd(apdev[0]['ifname']) logger.info("NFC connection handover") req = dev[0].request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip() if "FAIL" in req: raise Exception("Failed to generate NFC connection handover request") sel = hapd.request("NFC_GET_HANDOVER_SEL NDEF WPS-CR").rstrip() if "FAIL" in sel: raise Exception("Failed to generate NFC connection handover select") res = hapd.request("NFC_REPORT_HANDOVER RESP WPS " + req + " " + sel) if "FAIL" in res: raise Exception("Failed to report NFC connection handover to to hostapd") dev[0].dump_monitor() res = dev[0].request("NFC_REPORT_HANDOVER INIT WPS " + req + " " + sel) if "FAIL" in res: raise Exception("Failed to report NFC connection handover to to wpa_supplicant") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15) if ev is None: raise Exception("Association with the AP timed out") check_wpa2_connection(dev[0], apdev[0], ssid, mixed=True)
def test_ap_open_select_network(dev, apdev): """Open mode connection and SELECT_NETWORK to change network""" hapd1 = hostapd.add_ap(apdev[0], { "ssid": "open" }) bssid1 = apdev[0]['bssid'] hapd2 = hostapd.add_ap(apdev[1], { "ssid": "open2" }) bssid2 = apdev[1]['bssid'] id1 = dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", only_add_network=True) id2 = dev[0].connect("open2", key_mgmt="NONE", scan_freq="2412") hwsim_utils.test_connectivity(dev[0], hapd2) dev[0].select_network(id1) dev[0].wait_connected() res = dev[0].request("BLACKLIST") if bssid1 in res or bssid2 in res: raise Exception("Unexpected blacklist entry") hwsim_utils.test_connectivity(dev[0], hapd1) dev[0].select_network(id2) dev[0].wait_connected() hwsim_utils.test_connectivity(dev[0], hapd2) res = dev[0].request("BLACKLIST") if bssid1 in res or bssid2 in res: raise Exception("Unexpected blacklist entry(2)")
def test_authsrv_testing_options(dev, apdev): """Authentication server and testing options""" params = authsrv_params() authsrv = hostapd.add_ap(apdev[1], params) params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") params['auth_server_port'] = "18128" hapd = hostapd.add_ap(apdev[0], params) dev[0].scan_for_bss(hapd.own_addr(), 2412) # The first two would be fine to run with any server build; the rest are # actually supposed to fail, but they don't fail when using a server build # that does not support the TLS protocol tests. tests = [ "foo@test-unknown", "foo@test-tls-unknown", "foo@test-tls-1", "foo@test-tls-2", "foo@test-tls-3", "foo@test-tls-4", "foo@test-tls-5", "foo@test-tls-6", "foo@test-tls-7", "foo@test-tls-8" ] for t in tests: dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity=t, password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", scan_freq="2412") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected()
def test_prefer_ht40(dev, apdev): """Preference on HT40 over HT20""" params = { "ssid": "test", "channel": "1", "ieee80211n": "1" } hapd = hostapd.add_ap(apdev[0]['ifname'], params) bssid = apdev[0]['bssid'] params = { "ssid": "test", "channel": "1", "ieee80211n": "1", "ht_capab": "[HT40+]" } hapd2 = hostapd.add_ap(apdev[1]['ifname'], params) bssid2 = apdev[1]['bssid'] dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid2, freq=2412) dev[0].connect("test", key_mgmt="NONE", scan_freq="2412") if dev[0].get_status_field('bssid') != bssid2: raise Exception("Unexpected BSS selected") est = dev[0].get_bss(bssid)['est_throughput'] if est != "65000": raise Exception("Unexpected BSS0 est_throughput: " + est) est = dev[0].get_bss(bssid2)['est_throughput'] if est != "135000": raise Exception("Unexpected BSS1 est_throughput: " + est)
def test_pmksa_cache_ap_expiration(dev, apdev): """PMKSA cache entry expiring on AP""" params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache") hostapd.add_ap(apdev[0]['ifname'], params) bssid = apdev[0]['bssid'] dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP", eap="GPSK", identity="gpsk-user-session-timeout", password="******", scan_freq="2412") dev[0].request("DISCONNECT") time.sleep(5) dev[0].dump_monitor() dev[0].request("RECONNECT") ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", "CTRL-EVENT-CONNECTED"], timeout=20) if ev is None: raise Exception("Roaming with the AP timed out") if "CTRL-EVENT-CONNECTED" in ev: raise Exception("EAP exchange missing") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=20) if ev is None: raise Exception("Reassociation with the AP timed out") dev[0].dump_monitor() ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=20) if ev is None: raise Exception("Disconnection event timed out") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=20) if ev is None: raise Exception("Reassociation with the AP timed out")
def test_scan_bss_expiration_on_ssid_change(dev, apdev): """BSS entry expiration when AP changes SSID""" dev[0].flush_scan_cache() hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan" }) bssid = apdev[0]['bssid'] dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") hapd.request("DISABLE") hapd = hostapd.add_ap(apdev[0], { "ssid": "open" }) if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 3"): raise Exception("BSS_EXPIRE_COUNT failed") dev[0].scan(freq="2412") dev[0].scan(freq="2412") if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 2"): raise Exception("BSS_EXPIRE_COUNT failed") res = dev[0].request("SCAN_RESULTS") if "test-scan" not in res: raise Exception("The first SSID not in scan results") if "open" not in res: raise Exception("The second SSID not in scan results") dev[0].connect("open", key_mgmt="NONE") dev[0].request("BSS_FLUSH 0") res = dev[0].request("SCAN_RESULTS") if "test-scan" in res: raise Exception("The BSS entry with the old SSID was not removed") dev[0].request("DISCONNECT") dev[0].wait_disconnected()
def test_olbc(dev, apdev): """OLBC detection""" params = { "ssid": "test-olbc", "channel": "6", "ht_capab": "[HT40-]", "ap_table_expiration_time": "2" } hapd = hostapd.add_ap(apdev[0]['ifname'], params) status = hapd.get_status() if status['olbc'] != '0' or status['olbc_ht'] != '0': raise Exception("Unexpected OLBC information") params = { "ssid": "olbc-ap", "hw_mode": "b", "channel": "6", "wmm_enabled": "0" } hostapd.add_ap(apdev[1]['ifname'], params) time.sleep(0.5) status = hapd.get_status() if status['olbc'] != '1' or status['olbc_ht'] != '1': raise Exception("Missing OLBC information") hapd_global = hostapd.HostapdGlobal() hapd_global.remove(apdev[1]['ifname']) logger.info("Waiting for OLBC state to time out") cleared = False for i in range(0, 15): time.sleep(1) status = hapd.get_status() if status['olbc'] == '0' and status['olbc_ht'] == '0': cleared = True break if not cleared: raise Exception("OLBC state did nto time out")
def test_ap_ft_gtk_rekey(dev, apdev): """WPA2-PSK-FT AP and GTK rekey""" ssid = "test-ft" passphrase="12345678" params = ft_params1(ssid=ssid, passphrase=passphrase) params['wpa_group_rekey'] = '1' hostapd.add_ap(apdev[0]['ifname'], params) dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1") ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2) if ev is None: raise Exception("GTK rekey timed out after initial association") hwsim_utils.test_connectivity(dev[0].ifname, apdev[0]['ifname']) params = ft_params2(ssid=ssid, passphrase=passphrase) params['wpa_group_rekey'] = '1' hostapd.add_ap(apdev[1]['ifname'], params) dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412") dev[0].roam(apdev[1]['bssid']) if dev[0].get_status_field('bssid') != apdev[1]['bssid']: raise Exception("Did not connect to correct AP") hwsim_utils.test_connectivity(dev[0].ifname, apdev[1]['ifname']) ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2) if ev is None: raise Exception("GTK rekey timed out after FT protocol") hwsim_utils.test_connectivity(dev[0].ifname, apdev[1]['ifname'])
def test_sta_ap_scan_0(dev, apdev): """Dynamically added wpa_supplicant interface with AP_SCAN 0 connection""" hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test" }) bssid = apdev[0]['bssid'] logger.info("Create a dynamic wpa_supplicant interface and connect") wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') wpas.interface_add("wlan5") if "OK" not in wpas.request("AP_SCAN 0"): raise Exception("Failed to set AP_SCAN 2") id = wpas.connect("", key_mgmt="NONE", bssid=bssid, only_add_network=True) wpas.request("ENABLE_NETWORK " + str(id) + " no-connect") wpas.request("SCAN") time.sleep(0.5) subprocess.call(['sudo', 'iw', wpas.ifname, 'connect', 'test', '2412']) ev = wpas.wait_event(["CTRL-EVENT-CONNECTED"], timeout=10) if ev is None: raise Exception("Connection not reported") wpas.request("SCAN") ev = wpas.wait_event(["CTRL-EVENT-CONNECTED"], timeout=5) if ev is None: raise Exception("Connection not reported")
def test_radius_macacl(dev, apdev): """RADIUS MAC ACL""" params = hostapd.radius_params() params["ssid"] = "radius" params["macaddr_acl"] = "2" hostapd.add_ap(apdev[0]["ifname"], params) dev[0].connect("radius", key_mgmt="NONE", scan_freq="2412")
def test_ap_ft_eap(dev, apdev): """WPA2-EAP-FT AP""" ssid = "test-ft" passphrase="12345678" radius = hostapd.radius_params() params = ft_params1(ssid=ssid, passphrase=passphrase) params['wpa_key_mgmt'] = "FT-EAP" params["ieee8021x"] = "1" params = dict(radius.items() + params.items()) hapd = hostapd.add_ap(apdev[0]['ifname'], params) key_mgmt = hapd.get_config()['key_mgmt'] if key_mgmt.split(' ')[0] != "FT-EAP": raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt) params = ft_params2(ssid=ssid, passphrase=passphrase) params['wpa_key_mgmt'] = "FT-EAP" params["ieee8021x"] = "1" params = dict(radius.items() + params.items()) hostapd.add_ap(apdev[1]['ifname'], params) run_roams(dev[0], apdev, ssid, passphrase, eap=True) if "[WPA2-FT/EAP-CCMP]" not in dev[0].request("SCAN_RESULTS"): raise Exception("Scan results missing RSN element info") check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-3"), ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-3") ])
def test_ap_pmf_optional_2akm(dev, apdev): """WPA2-PSK AP with PMF optional (2 AKMs)""" ssid = "test-pmf-optional-2akm" wt = Wlantest() wt.flush() wt.add_passphrase("12345678") params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678") params["wpa_key_mgmt"] = "WPA-PSK WPA-PSK-SHA256"; params["ieee80211w"] = "1"; hostapd.add_ap(apdev[0]['ifname'], params) dev[0].connect(ssid, psk="12345678", ieee80211w="1", key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") hwsim_utils.test_connectivity(dev[0].ifname, apdev[0]['ifname']) dev[1].connect(ssid, psk="12345678", ieee80211w="2", key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") hwsim_utils.test_connectivity(dev[1].ifname, apdev[0]['ifname']) wt.require_ap_pmf_optional(apdev[0]['bssid']) wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr()) wt.require_sta_key_mgmt(apdev[0]['bssid'], dev[0].p2p_interface_addr(), "PSK-SHA256") wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr()) wt.require_sta_key_mgmt(apdev[0]['bssid'], dev[1].p2p_interface_addr(), "PSK-SHA256")
def test_radius_ipv6(dev, apdev): """RADIUS connection over IPv6""" params = {} params["ssid"] = "as" params["beacon_int"] = "2000" params["radius_server_clients"] = "auth_serv/radius_clients_ipv6.conf" params["radius_server_ipv6"] = "1" params["radius_server_auth_port"] = "18129" params["radius_server_acct_port"] = "18139" params["eap_server"] = "1" params["eap_user_file"] = "auth_serv/eap_user.conf" params["ca_cert"] = "auth_serv/ca.pem" params["server_cert"] = "auth_serv/server.pem" params["private_key"] = "auth_serv/server.key" hostapd.add_ap(apdev[1]["ifname"], params) params = hostapd.wpa2_eap_params(ssid="radius-ipv6") params["auth_server_addr"] = "::0" params["auth_server_port"] = "18129" params["acct_server_addr"] = "::0" params["acct_server_port"] = "18139" params["acct_server_shared_secret"] = "radius" params["own_ip_addr"] = "::0" hostapd.add_ap(apdev[0]["ifname"], params) connect(dev[0], "radius-ipv6")
def test_gas_concurrent_connect(dev, apdev): """Generic GAS queries with concurrent connection operation""" skip_with_fips(dev[0]) bssid = apdev[0]['bssid'] params = hs20_ap_params() params['hessid'] = bssid hostapd.add_ap(apdev[0], params) dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) logger.debug("Start concurrent connect and GAS request") dev[0].connect("test-gas", key_mgmt="WPA-EAP", eap="TTLS", identity="DOMAIN\mschapv2 user", anonymous_identity="ttls", password="******", phase2="auth=MSCHAPV2", ca_cert="auth_serv/ca.pem", wait_connect=False, scan_freq="2412") req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000101") if "FAIL" in req: raise Exception("GAS query request rejected") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "GAS-RESPONSE-INFO"], timeout=20) if ev is None: raise Exception("Operation timed out") if "CTRL-EVENT-CONNECTED" not in ev: raise Exception("Unexpected operation order") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", "GAS-RESPONSE-INFO"], timeout=20) if ev is None: raise Exception("Operation timed out") if "GAS-RESPONSE-INFO" not in ev: raise Exception("Unexpected operation order") get_gas_response(dev[0], bssid, ev) dev[0].request("DISCONNECT") dev[0].wait_disconnected(timeout=5) logger.debug("Wait six seconds for expiration of connect-without-scan") time.sleep(6) dev[0].dump_monitor() logger.debug("Start concurrent GAS request and connect") req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000101") if "FAIL" in req: raise Exception("GAS query request rejected") dev[0].request("RECONNECT") ev = dev[0].wait_event(["GAS-RESPONSE-INFO"], timeout=10) if ev is None: raise Exception("Operation timed out") get_gas_response(dev[0], bssid, ev) ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=20) if ev is None: raise Exception("No new scan results reported") ev = dev[0].wait_connected(timeout=20, error="Operation tiemd out") if "CTRL-EVENT-CONNECTED" not in ev: raise Exception("Unexpected operation order")
def test_ap_wpa2_tdls_bssid_mismatch(dev, apdev): """TDLS failure due to BSSID mismatch""" try: ssid = "test-wpa2-psk" passphrase = "12345678" params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) params['bridge'] = 'ap-br0' hapd = hostapd.add_ap(apdev[0], params) hostapd.add_ap(apdev[1], params) wlantest_setup(hapd) subprocess.call(['brctl', 'setfd', 'ap-br0', '0']) subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up']) dev[0].connect(ssid, psk=passphrase, scan_freq="2412", bssid=apdev[0]['bssid']) dev[1].connect(ssid, psk=passphrase, scan_freq="2412", bssid=apdev[1]['bssid']) hwsim_utils.test_connectivity_sta(dev[0], dev[1]) hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0") hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0") addr0 = dev[0].p2p_interface_addr() dev[1].tdls_setup(addr0) time.sleep(1) hwsim_utils.test_connectivity_sta(dev[0], dev[1]) finally: subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down']) subprocess.call(['brctl', 'delbr', 'ap-br0'])
def test_ap_qosmap(dev, apdev): """QoS mapping""" drv_flags = dev[0].get_driver_status_field("capa.flags") if int(drv_flags, 0) & 0x40000000 == 0: return "skip" ssid = "test-qosmap" params = {"ssid": ssid} params["qos_map_set"] = "53,2,22,6,8,15,0,7,255,255,16,31,32,39,255,255,40,47,48,55" hostapd.add_ap(apdev[0]["ifname"], params) dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") time.sleep(0.1) check_qos_map(apdev[0], dev[0], 53, 2) check_qos_map(apdev[0], dev[0], 22, 6) check_qos_map(apdev[0], dev[0], 8, 0) check_qos_map(apdev[0], dev[0], 15, 0) check_qos_map(apdev[0], dev[0], 0, 1) check_qos_map(apdev[0], dev[0], 7, 1) check_qos_map(apdev[0], dev[0], 16, 3) check_qos_map(apdev[0], dev[0], 31, 3) check_qos_map(apdev[0], dev[0], 32, 4) check_qos_map(apdev[0], dev[0], 39, 4) check_qos_map(apdev[0], dev[0], 40, 6) check_qos_map(apdev[0], dev[0], 47, 6) check_qos_map(apdev[0], dev[0], 48, 7) check_qos_map(apdev[0], dev[0], 55, 7) hapd = hostapd.Hostapd(apdev[0]["ifname"]) hapd.request("SET_QOS_MAP_SET 22,6,8,15,0,7,255,255,16,31,32,39,255,255,40,47,48,55") hapd.request("SEND_QOS_MAP_CONF " + dev[0].get_status_field("address")) check_qos_map(apdev[0], dev[0], 53, 7) check_qos_map(apdev[0], dev[0], 22, 6) check_qos_map(apdev[0], dev[0], 48, 7) check_qos_map(apdev[0], dev[0], 55, 7) check_qos_map(apdev[0], dev[0], 56, 56 >> 3) check_qos_map(apdev[0], dev[0], 63, 63 >> 3)
def test_ap_qosmap_default_acm(dev, apdev): """QoS mapping with default values and ACM=1 for VO/VI""" ssid = "test-qosmap-default" params = { "ssid": ssid, "wmm_ac_bk_aifs": "7", "wmm_ac_bk_cwmin": "4", "wmm_ac_bk_cwmax": "10", "wmm_ac_bk_txop_limit": "0", "wmm_ac_bk_acm": "0", "wmm_ac_be_aifs": "3", "wmm_ac_be_cwmin": "4", "wmm_ac_be_cwmax": "10", "wmm_ac_be_txop_limit": "0", "wmm_ac_be_acm": "0", "wmm_ac_vi_aifs": "2", "wmm_ac_vi_cwmin": "3", "wmm_ac_vi_cwmax": "4", "wmm_ac_vi_txop_limit": "94", "wmm_ac_vi_acm": "1", "wmm_ac_vo_aifs": "2", "wmm_ac_vo_cwmin": "2", "wmm_ac_vo_cwmax": "2", "wmm_ac_vo_txop_limit": "47", "wmm_ac_vo_acm": "1", } hostapd.add_ap(apdev[0]["ifname"], params) dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") for dscp in [0, 7, 8, 15, 16, 23, 24, 31, 32, 39, 40, 47, 48, 55, 56, 63]: ap_tid = dscp >> 3 tid = ap_tid # downgrade VI/VO to BE if tid in [4, 5, 6, 7]: tid = 3 check_qos_map(apdev[0], dev[0], dscp, tid, ap_tid)
def force_prev_ap_on_24g(ap): # For now, make sure the last operating channel was on 2.4 GHz band to get # sufficient survey data from mac80211_hwsim. hostapd.add_ap(ap, { "ssid": "open" }) time.sleep(0.1) hapd_global = hostapd.HostapdGlobal() hapd_global.remove(ap['ifname'])
def test_wext_scan_hidden(dev, apdev): """WEXT with hidden SSID""" wpas = get_wext_interface() hapd = hostapd.add_ap(apdev[0], { "ssid": "test-scan", "ignore_broadcast_ssid": "1" }) hapd2 = hostapd.add_ap(apdev[1], { "ssid": "test-scan2", "ignore_broadcast_ssid": "1" }) id1 = wpas.connect("test-scan", key_mgmt="NONE", scan_ssid="1", only_add_network=True) wpas.request("SCAN scan_id=%d" % id1) ev = wpas.wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=15) if ev is None: raise Exception("Scan did not complete") if "test-scan" not in wpas.request("SCAN_RESULTS"): raise Exception("Did not find hidden SSID in scan") id = wpas.connect("test-scan2", key_mgmt="NONE", scan_ssid="1", only_add_network=True) wpas.connect_network(id, timeout=30) wpas.request("DISCONNECT") hapd2.disable() hapd.disable() wpas.interface_remove("wlan5") wpas.interface_add("wlan5") wpas.flush_scan_cache(freq=2412) wpas.flush_scan_cache()
def test_gas_generic(dev, apdev): """Generic GAS query""" bssid = apdev[0]['bssid'] params = hs20_ap_params() params['hessid'] = bssid hostapd.add_ap(apdev[0], params) cmds = [ "foo", "00:11:22:33:44:55", "00:11:22:33:44:55 ", "00:11:22:33:44:55 ", "00:11:22:33:44:55 1", "00:11:22:33:44:55 1 1234", "00:11:22:33:44:55 qq", "00:11:22:33:44:55 qq 1234", "00:11:22:33:44:55 00 1", "00:11:22:33:44:55 00 123", "00:11:22:33:44:55 00 ", "00:11:22:33:44:55 00 qq" ] for cmd in cmds: if "FAIL" not in dev[0].request("GAS_REQUEST " + cmd): raise Exception("Invalid GAS_REQUEST accepted: " + cmd) dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) req = dev[0].request("GAS_REQUEST " + bssid + " 00 000102000101") if "FAIL" in req: raise Exception("GAS query request rejected") ev = dev[0].wait_event(["GAS-RESPONSE-INFO"], timeout=10) if ev is None: raise Exception("GAS query timed out") get_gas_response(dev[0], bssid, ev, extra_test=True) if "FAIL" not in dev[0].request("GAS_RESPONSE_GET ff"): raise Exception("Invalid GAS_RESPONSE_GET accepted")
def test_ap_wps_conf_pin(dev, apdev): """WPS PIN provisioning with configured AP""" ssid = "test-wps-conf-pin" hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid, "eap_server": "1", "wps_state": "2", "wpa_passphrase": "12345678", "wpa": "2", "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}) hapd = hostapd.Hostapd(apdev[0]['ifname']) logger.info("WPS provisioning step") pin = dev[0].wps_read_pin() hapd.request("WPS_PIN any " + pin) dev[0].request("SET ignore_old_scan_res 1") dev[0].dump_monitor() dev[0].request("WPS_PIN any " + pin) ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30) if ev is None: raise Exception("Association with the AP timed out") status = dev[0].get_status() if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']: raise Exception("Not fully connected") if status['ssid'] != ssid: raise Exception("Unexpected SSID") if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP': raise Exception("Unexpected encryption configuration") if status['key_mgmt'] != 'WPA2-PSK': raise Exception("Unexpected key_mgmt")
def test_gas_missing_payload(dev, apdev): """No action code in the query frame""" bssid = apdev[0]['bssid'] params = hs20_ap_params() params['hessid'] = bssid hostapd.add_ap(apdev[0], params) dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) cmd = "MGMT_TX {} {} freq=2412 action=040A".format(bssid, bssid) if "FAIL" in dev[0].request(cmd): raise Exception("Could not send test Action frame") ev = dev[0].wait_event(["MGMT-TX-STATUS"], timeout=10) if ev is None: raise Exception("Timeout on MGMT-TX-STATUS") if "result=SUCCESS" not in ev: raise Exception("AP did not ack Action frame") cmd = "MGMT_TX {} {} freq=2412 action=04".format(bssid, bssid) if "FAIL" in dev[0].request(cmd): raise Exception("Could not send test Action frame") ev = dev[0].wait_event(["MGMT-TX-STATUS"], timeout=10) if ev is None: raise Exception("Timeout on MGMT-TX-STATUS") if "result=SUCCESS" not in ev: raise Exception("AP did not ack Action frame")
def test_ap_vlan_wpa2_radius_id_change(dev, apdev): """AP VLAN with WPA2-Enterprise and RADIUS attributes changing VLANID""" as_params = { "ssid": "as", "beacon_int": "2000", "radius_server_clients": "auth_serv/radius_clients.conf", "radius_server_auth_port": '18128', "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf", "ca_cert": "auth_serv/ca.pem", "server_cert": "auth_serv/server.pem", "private_key": "auth_serv/server.key" } authserv = hostapd.add_ap(apdev[1]['ifname'], as_params) params = hostapd.wpa2_eap_params(ssid="test-vlan") params['dynamic_vlan'] = "1" params['auth_server_port'] = "18128" hapd = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].connect("test-vlan", key_mgmt="WPA-EAP", eap="PAX", identity="vlan1", password_hex="0123456789abcdef0123456789abcdef", scan_freq="2412") hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1") logger.info("VLAN-ID -> 2") authserv.disable() authserv.set('eap_user_file', "auth_serv/eap_user_vlan.conf") authserv.enable() dev[0].dump_monitor() dev[0].request("REAUTHENTICATE") ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) if ev is None: raise Exception("EAP reauthentication timed out") ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=5) if ev is None: raise Exception("4-way handshake after reauthentication timed out") state = dev[0].get_status_field('wpa_state') if state != "COMPLETED": raise Exception("Unexpected state after reauth: " + state) sta = hapd.get_sta(dev[0].own_addr()) if 'vlan_id' not in sta: raise Exception("No VLAN ID in STA info") if sta['vlan_id'] != '2': raise Exception("Unexpected VLAN ID: " + sta['vlan_id']) hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan2") logger.info("VLAN-ID -> 1") time.sleep(1) authserv.disable() authserv.set('eap_user_file', "auth_serv/eap_user.conf") authserv.enable() dev[0].dump_monitor() dev[0].request("REAUTHENTICATE") ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15) if ev is None: raise Exception("EAP reauthentication timed out") ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=5) if ev is None: raise Exception("4-way handshake after reauthentication timed out") state = dev[0].get_status_field('wpa_state') if state != "COMPLETED": raise Exception("Unexpected state after reauth: " + state) sta = hapd.get_sta(dev[0].own_addr()) if 'vlan_id' not in sta: raise Exception("No VLAN ID in STA info") if sta['vlan_id'] != '1': raise Exception("Unexpected VLAN ID: " + sta['vlan_id']) time.sleep(0.2) try: hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1") except Exception, e: # It is possible for new bridge setup to not be ready immediately, so # try again to avoid reporting issues related to that. logger.info("First VLAN-ID 1 data test failed - try again") hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
def test_sae_key_lifetime_in_memory(dev, apdev, params): """SAE and key lifetime in memory""" if "SAE" not in dev[0].get_capability("auth_alg"): raise HwsimSkip("SAE not supported") password = "******" p = hostapd.wpa2_params(ssid="test-sae", passphrase=password) p['wpa_key_mgmt'] = 'SAE' hapd = hostapd.add_ap(apdev[0], p) pid = find_wpas_process(dev[0]) dev[0].request("SET sae_groups ") id = dev[0].connect("test-sae", psk=password, key_mgmt="SAE", scan_freq="2412") # The decrypted copy of GTK is freed only after the CTRL-EVENT-CONNECTED # event has been delivered, so verify that wpa_supplicant has returned to # eloop before reading process memory. time.sleep(1) dev[0].ping() buf = read_process_memory(pid, password) dev[0].request("DISCONNECT") dev[0].wait_disconnected() dev[0].relog() sae_k = None sae_keyseed = None sae_kck = None pmk = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "SAE: k - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') sae_k = binascii.unhexlify(val) if "SAE: keyseed - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') sae_keyseed = binascii.unhexlify(val) if "SAE: KCK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') sae_kck = binascii.unhexlify(val) if "SAE: PMK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmk = binascii.unhexlify(val) if "WPA: PTK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') ptk = binascii.unhexlify(val) if "WPA: Group Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not sae_k or not sae_keyseed or not sae_kck or not pmk or not ptk or not gtk: raise Exception("Could not find keys from debug log") if len(gtk) != 16: raise Exception("Unexpected GTK length") kck = ptk[0:16] kek = ptk[16:32] tk = ptk[32:48] fname = os.path.join(params['logdir'], 'sae_key_lifetime_in_memory.memctx-') logger.info("Checking keys in memory while associated") get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") if password not in buf: raise HwsimSkip("Password not found while associated") if pmk not in buf: raise HwsimSkip("PMK not found while associated") if kck not in buf: raise Exception("KCK not found while associated") if kek not in buf: raise Exception("KEK not found while associated") if tk in buf: raise Exception("TK found from memory") if gtk in buf: get_key_locations(buf, gtk, "GTK") raise Exception("GTK found from memory") verify_not_present(buf, sae_k, fname, "SAE(k)") verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") verify_not_present(buf, sae_kck, fname, "SAE(KCK)") logger.info("Checking keys in memory after disassociation") buf = read_process_memory(pid, password) # Note: Password is still present in network configuration # Note: PMK is in PMKSA cache get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") verify_not_present(buf, sae_k, fname, "SAE(k)") verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") verify_not_present(buf, sae_kck, fname, "SAE(KCK)") dev[0].request("PMKSA_FLUSH") logger.info("Checking keys in memory after PMKSA cache flush") buf = read_process_memory(pid, password) get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") verify_not_present(buf, pmk, fname, "PMK") dev[0].request("REMOVE_NETWORK all") logger.info("Checking keys in memory after network profile removal") buf = read_process_memory(pid, password) get_key_locations(buf, password, "Password") get_key_locations(buf, pmk, "PMK") verify_not_present(buf, password, fname, "password") verify_not_present(buf, pmk, fname, "PMK") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") verify_not_present(buf, sae_k, fname, "SAE(k)") verify_not_present(buf, sae_keyseed, fname, "SAE(keyseed)") verify_not_present(buf, sae_kck, fname, "SAE(KCK)")
def test_ap_ht40_5ghz_switch2(dev, apdev): """HT40 co-ex scan on 5 GHz switching pri/sec channel (2)""" clear_scan_cache(apdev[0]) try: hapd = None hapd2 = None params = { "ssid": "test-ht40", "hw_mode": "a", "channel": "36", "country_code": "US", "ht_capab": "[HT40+]"} hapd2 = hostapd.add_ap(apdev[1], params) id = dev[0].add_network() dev[0].set_network(id, "mode", "2") dev[0].set_network_quoted(id, "ssid", "wpas-ap-open") dev[0].set_network(id, "key_mgmt", "NONE") dev[0].set_network(id, "frequency", "5200") dev[0].set_network(id, "scan_freq", "5200") dev[0].select_network(id) time.sleep(1) params = { "ssid": "test-ht40", "hw_mode": "a", "channel": "40", "ht_capab": "[HT40-]"} hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) state = hapd.get_status_field("state") if state != "HT_SCAN": time.sleep(0.1) state = hapd.get_status_field("state") if state != "HT_SCAN": raise Exception("Unexpected interface state - expected HT_SCAN") ev = hapd.wait_event(["AP-ENABLED"], timeout=10) if not ev: raise Exception("AP setup timed out") state = hapd.get_status_field("state") if state != "ENABLED": raise Exception("Unexpected interface state - expected ENABLED") freq = hapd.get_status_field("freq") if freq != "5180": raise Exception("Unexpected frequency: " + freq) pri = hapd.get_status_field("channel") if pri != "36": raise Exception("Unexpected primary channel: " + pri) sec = hapd.get_status_field("secondary_channel") if sec != "1": raise Exception("Unexpected secondary channel: " + sec) dev[0].connect("test-ht40", key_mgmt="NONE", scan_freq=freq) finally: dev[0].request("DISCONNECT") if hapd: hapd.request("DISABLE") if hapd2: hapd2.request("DISABLE") set_world_reg(apdev[0], apdev[1], dev[0]) dev[0].flush_scan_cache()
def test_p2p_listen_chan_optimize(dev, apdev): """P2P listen channel optimization""" wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') wpas.interface_add("wlan5") addr5 = wpas.p2p_dev_addr() try: if "OK" not in wpas.request("SET p2p_optimize_listen_chan 1"): raise Exception("Failed to set p2p_optimize_listen_chan") wpas.p2p_listen() if not dev[0].discover_peer(addr5): raise Exception("Could not discover peer") peer = dev[0].get_peer(addr5) lfreq = peer['listen_freq'] wpas.p2p_stop_find() dev[0].p2p_stop_find() channel = "1" if lfreq != '2412' else "6" freq = "2412" if lfreq != '2412' else "2437" params = { "ssid": "test-open", "channel": channel } hapd = hostapd.add_ap(apdev[0]['ifname'], params) id = wpas.connect("test-open", key_mgmt="NONE", scan_freq=freq) wpas.p2p_listen() if "OK" not in dev[0].request("P2P_FLUSH"): raise Exception("P2P_FLUSH failed") if not dev[0].discover_peer(addr5): raise Exception("Could not discover peer") peer = dev[0].get_peer(addr5) lfreq2 = peer['listen_freq'] if lfreq == lfreq2: raise Exception("Listen channel did not change") if lfreq2 != freq: raise Exception("Listen channel not on AP's operating channel") wpas.p2p_stop_find() dev[0].p2p_stop_find() wpas.request("DISCONNECT") wpas.wait_disconnected() # for larger coverage, cover case of current channel matching wpas.select_network(id) wpas.wait_connected() wpas.request("DISCONNECT") wpas.wait_disconnected() lchannel = "1" if channel != "1" else "6" lfreq3 = "2412" if channel != "1" else "2437" if "OK" not in wpas.request("P2P_SET listen_channel " + lchannel): raise Exception("Failed to set listen channel") wpas.select_network(id) wpas.wait_connected() wpas.p2p_listen() if "OK" not in dev[0].request("P2P_FLUSH"): raise Exception("P2P_FLUSH failed") if not dev[0].discover_peer(addr5): raise Exception("Could not discover peer") peer = dev[0].get_peer(addr5) lfreq4 = peer['listen_freq'] if lfreq4 != lfreq3: raise Exception("Unexpected Listen channel after configuration") wpas.p2p_stop_find() dev[0].p2p_stop_find() finally: wpas.request("SET p2p_optimize_listen_chan 0")
def test_scan_and_bss_entry_removed(dev, apdev): """Last scan result and connect work processing on BSS entry update""" hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open", "eap_server": "1", "wps_state": "2" }) bssid = apdev[0]['bssid'] wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") # Add a BSS entry dev[0].scan_for_bss(bssid, freq="2412") wpas.scan_for_bss(bssid, freq="2412") # Start a connect radio work with a blocking entry preventing this from # proceeding; this stores a pointer to the selected BSS entry. id = dev[0].request("RADIO_WORK add block-work") w_id = wpas.request("RADIO_WORK add block-work") dev[0].wait_event(["EXT-RADIO-WORK-START"], timeout=1) wpas.wait_event(["EXT-RADIO-WORK-START"], timeout=1) nid = dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", wait_connect=False) w_nid = wpas.connect("open", key_mgmt="NONE", scan_freq="2412", wait_connect=False) time.sleep(0.1) # Remove the BSS entry dev[0].request("BSS_FLUSH 0") wpas.request("BSS_FLUSH 0") # Allow the connect radio work to continue. The bss entry stored in the # pending connect work is now stale. This will result in the connection # attempt failing since the BSS entry does not exist. dev[0].request("RADIO_WORK done " + id) wpas.request("RADIO_WORK done " + w_id) ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) if ev is not None: raise Exception("Unexpected connection") dev[0].remove_network(nid) ev = wpas.wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) if ev is not None: raise Exception("Unexpected connection") wpas.remove_network(w_nid) time.sleep(0.5) dev[0].request("BSS_FLUSH 0") wpas.request("BSS_FLUSH 0") # Add a BSS entry dev[0].scan_for_bss(bssid, freq="2412") wpas.scan_for_bss(bssid, freq="2412") # Start a connect radio work with a blocking entry preventing this from # proceeding; this stores a pointer to the selected BSS entry. id = dev[0].request("RADIO_WORK add block-work") w_id = wpas.request("RADIO_WORK add block-work") dev[0].wait_event(["EXT-RADIO-WORK-START"], timeout=1) wpas.wait_event(["EXT-RADIO-WORK-START"], timeout=1) # Schedule a connection based on the current BSS entry. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", wait_connect=False) wpas.connect("open", key_mgmt="NONE", scan_freq="2412", wait_connect=False) # Update scan results with results that have longer set of IEs so that new # memory needs to be allocated for the BSS entry. hapd.request("WPS_PBC") time.sleep(0.1) subprocess.call(['iw', dev[0].ifname, 'scan', 'trigger', 'freq', '2412']) subprocess.call(['iw', wpas.ifname, 'scan', 'trigger', 'freq', '2412']) time.sleep(0.1) # Allow the connect radio work to continue. The bss entry stored in the # pending connect work becomes stale during the scan and it must have been # updated for the connection to work. dev[0].request("RADIO_WORK done " + id) wpas.request("RADIO_WORK done " + w_id) dev[0].wait_connected(timeout=15, error="No connection (sme-connect)") wpas.wait_connected(timeout=15, error="No connection (connect)") dev[0].request("DISCONNECT") wpas.request("DISCONNECT") dev[0].flush_scan_cache() wpas.flush_scan_cache()
def test_scan_bss_operations(dev, apdev): """Control interface behavior on BSS parameters""" hostapd.add_ap(apdev[0]['ifname'], {"ssid": "test-scan"}) bssid = apdev[0]['bssid'] hostapd.add_ap(apdev[1]['ifname'], {"ssid": "test2-scan"}) bssid2 = apdev[1]['bssid'] dev[0].scan(freq="2412") dev[0].scan(freq="2412") dev[0].scan(freq="2412") id1 = dev[0].request("BSS FIRST MASK=0x1").splitlines()[0].split('=')[1] id2 = dev[0].request("BSS LAST MASK=0x1").splitlines()[0].split('=')[1] res = dev[0].request("BSS RANGE=ALL MASK=0x20001") if "id=" + id1 not in res: raise Exception("Missing BSS " + id1) if "id=" + id2 not in res: raise Exception("Missing BSS " + id2) if "====" not in res: raise Exception("Missing delim") if "####" not in res: raise Exception("Missing end") res = dev[0].request("BSS RANGE=ALL MASK=0") if "id=" + id1 not in res: raise Exception("Missing BSS " + id1) if "id=" + id2 not in res: raise Exception("Missing BSS " + id2) if "====" in res: raise Exception("Unexpected delim") if "####" in res: raise Exception("Unexpected end delim") res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines() if len(res) != 2: raise Exception("Unexpected result: " + str(res)) res = dev[0].request("BSS FIRST MASK=0x1") if "id=" + id1 not in res: raise Exception("Unexpected result: " + res) res = dev[0].request("BSS LAST MASK=0x1") if "id=" + id2 not in res: raise Exception("Unexpected result: " + res) res = dev[0].request("BSS ID-" + id1 + " MASK=0x1") if "id=" + id1 not in res: raise Exception("Unexpected result: " + res) res = dev[0].request("BSS NEXT-" + id1 + " MASK=0x1") if "id=" + id2 not in res: raise Exception("Unexpected result: " + res) res = dev[0].request("BSS NEXT-" + id2 + " MASK=0x1") if "id=" in res: raise Exception("Unexpected result: " + res) if len(dev[0].request("BSS RANGE=" + id2 + " MASK=0x1").splitlines()) != 0: raise Exception("Unexpected RANGE=1 result") if len(dev[0].request("BSS RANGE=" + id1 + "- MASK=0x1").splitlines()) != 2: raise Exception("Unexpected RANGE=0- result") if len(dev[0].request("BSS RANGE=-" + id2 + " MASK=0x1").splitlines()) != 2: raise Exception("Unexpected RANGE=-1 result") if len(dev[0].request("BSS RANGE=" + id1 + "-" + id2 + " MASK=0x1").splitlines()) != 2: raise Exception("Unexpected RANGE=0-1 result") if len(dev[0].request("BSS RANGE=" + id2 + "-" + id2 + " MASK=0x1").splitlines()) != 1: raise Exception("Unexpected RANGE=1-1 result") if len(dev[0].request("BSS RANGE=" + str(int(id2) + 1) + "-" + str(int(id2) + 10) + " MASK=0x1").splitlines()) != 0: raise Exception("Unexpected RANGE=2-10 result") if len(dev[0].request("BSS RANGE=0-" + str(int(id2) + 10) + " MASK=0x1").splitlines()) != 2: raise Exception("Unexpected RANGE=0-10 result") if len(dev[0].request("BSS RANGE=" + id1 + "-" + id1 + " MASK=0x1").splitlines()) != 1: raise Exception("Unexpected RANGE=0-0 result") res = dev[0].request("BSS p2p_dev_addr=FOO") if "FAIL" in res or "id=" in res: raise Exception("Unexpected result: " + res) res = dev[0].request("BSS p2p_dev_addr=00:11:22:33:44:55") if "FAIL" in res or "id=" in res: raise Exception("Unexpected result: " + res) dev[0].request("BSS_FLUSH 1000") res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines() if len(res) != 2: raise Exception("Unexpected result after BSS_FLUSH 1000") dev[0].request("BSS_FLUSH 0") res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines() if len(res) != 0: raise Exception("Unexpected result after BSS_FLUSH 0")
def test_scan_external_trigger(dev, apdev): """Avoid operations during externally triggered scan""" hostapd.add_ap(apdev[0]['ifname'], {"ssid": "test-scan"}) bssid = apdev[0]['bssid'] subprocess.call(['iw', dev[0].ifname, 'scan', 'trigger']) check_scan(dev[0], "use_id=1", other_started=True)
def test_ap_vht160(dev, apdev): """VHT with 160 MHz channel width""" try: hapd = None hapd2 = None params = { "ssid": "vht", "country_code": "FI", "hw_mode": "a", "channel": "36", "ht_capab": "[HT40+]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "2", "vht_oper_centr_freq_seg0_idx": "50", 'ieee80211d': '1', 'ieee80211h': '1' } hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) ev = wait_dfs_event(hapd, "DFS-CAC-START", 5) if "DFS-CAC-START" not in ev: raise Exception("Unexpected DFS event") state = hapd.get_status_field("state") if state != "DFS": if state == "DISABLED" and not os.path.exists("dfs"): # Not all systems have recent enough CRDA version and # wireless-regdb changes to support 160 MHz and DFS. For now, # do not report failures for this test case. raise HwsimSkip("CRDA or wireless-regdb did not support 160 MHz") raise Exception("Unexpected interface state: " + state) params = { "ssid": "vht2", "country_code": "FI", "hw_mode": "a", "channel": "104", "ht_capab": "[HT40-]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "2", "vht_oper_centr_freq_seg0_idx": "114", 'ieee80211d': '1', 'ieee80211h': '1' } hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False) ev = wait_dfs_event(hapd2, "DFS-CAC-START", 5) if "DFS-CAC-START" not in ev: raise Exception("Unexpected DFS event(2)") state = hapd2.get_status_field("state") if state != "DFS": raise Exception("Unexpected interface state(2): " + state) logger.info("Waiting for CAC to complete") ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70) if "success=1" not in ev: raise Exception("CAC failed") if "freq=5180" not in ev: raise Exception("Unexpected DFS freq result") ev = hapd.wait_event(["AP-ENABLED"], timeout=5) if not ev: raise Exception("AP setup timed out") state = hapd.get_status_field("state") if state != "ENABLED": raise Exception("Unexpected interface state") ev = wait_dfs_event(hapd2, "DFS-CAC-COMPLETED", 70) if "success=1" not in ev: raise Exception("CAC failed(2)") if "freq=5520" not in ev: raise Exception("Unexpected DFS freq result(2)") ev = hapd2.wait_event(["AP-ENABLED"], timeout=5) if not ev: raise Exception("AP setup timed out(2)") state = hapd2.get_status_field("state") if state != "ENABLED": raise Exception("Unexpected interface state(2)") freq = hapd2.get_status_field("freq") if freq != "5520": raise Exception("Unexpected frequency(2)") dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180") hwsim_utils.test_connectivity(dev[0], hapd) sig = dev[0].request("SIGNAL_POLL").splitlines() if "FREQUENCY=5180" not in sig: raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) if "WIDTH=160 MHz" not in sig: raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) dev[1].connect("vht2", key_mgmt="NONE", scan_freq="5520") hwsim_utils.test_connectivity(dev[1], hapd2) sig = dev[1].request("SIGNAL_POLL").splitlines() if "FREQUENCY=5520" not in sig: raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) if "WIDTH=160 MHz" not in sig: raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) except Exception, e: if isinstance(e, Exception) and str(e) == "AP startup failed": if not vht_supported(): raise HwsimSkip("80/160 MHz channel not supported in regulatory information") raise
def run_owe_transition_mode(dev, apdev): if "OWE" not in dev[0].get_capability("key_mgmt"): raise HwsimSkip("OWE not supported") dev[0].flush_scan_cache() params = { "ssid": "owe-random", "wpa": "2", "wpa_key_mgmt": "OWE", "rsn_pairwise": "CCMP", "owe_transition_bssid": apdev[1]['bssid'], "owe_transition_ssid": '"owe-test"', "ignore_broadcast_ssid": "1" } hapd = hostapd.add_ap(apdev[0], params) bssid = hapd.own_addr() params = { "ssid": "owe-test", "owe_transition_bssid": apdev[0]['bssid'], "owe_transition_ssid": '"owe-random"' } hapd2 = hostapd.add_ap(apdev[1], params) bssid2 = hapd2.own_addr() dev[0].scan_for_bss(bssid, freq="2412") dev[0].scan_for_bss(bssid2, freq="2412") bss = dev[0].get_bss(bssid) if "[WPA2-OWE-CCMP]" not in bss['flags']: raise Exception("OWE AKM not recognized: " + bss['flags']) if "[OWE-TRANS]" not in bss['flags']: raise Exception("OWE transition not recognized: " + bss['flags']) bss = dev[0].get_bss(bssid2) if "[OWE-TRANS-OPEN]" not in bss['flags']: raise Exception("OWE transition (open) not recognized: " + bss['flags']) id = dev[0].connect("owe-test", key_mgmt="OWE") hwsim_utils.test_connectivity(dev[0], hapd) val = dev[0].get_status_field("key_mgmt") if val != "OWE": raise Exception("Unexpected key_mgmt: " + val) logger.info("Move to OWE only mode (disable transition mode)") dev[0].request("DISCONNECT") dev[0].wait_disconnected() dev[0].dump_monitor() hapd2.disable() hapd.disable() dev[0].flush_scan_cache() hapd.set("owe_transition_bssid", "00:00:00:00:00:00") hapd.set("ignore_broadcast_ssid", '0') hapd.set("ssid", 'owe-test') hapd.enable() dev[0].scan_for_bss(bssid, freq="2412") dev[0].select_network(id, 2412) dev[0].wait_connected() hwsim_utils.test_connectivity(dev[0], hapd)
def test_ap_vht80plus80(dev, apdev): """VHT with 80+80 MHz channel width""" try: hapd = None hapd2 = None params = { "ssid": "vht", "country_code": "US", "hw_mode": "a", "channel": "52", "ht_capab": "[HT40+]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "3", "vht_oper_centr_freq_seg0_idx": "58", "vht_oper_centr_freq_seg1_idx": "155", 'ieee80211d': '1', 'ieee80211h': '1' } hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) # This will actually fail since DFS on 80+80 is not yet supported ev = hapd.wait_event(["AP-DISABLED"], timeout=5) # ignore result to avoid breaking the test once 80+80 DFS gets enabled params = { "ssid": "vht2", "country_code": "US", "hw_mode": "a", "channel": "36", "ht_capab": "[HT40+]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "3", "vht_oper_centr_freq_seg0_idx": "42", "vht_oper_centr_freq_seg1_idx": "155" } hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False) ev = hapd2.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5) if not ev: raise Exception("AP setup timed out(2)") if "AP-DISABLED" in ev: # Assume this failed due to missing regulatory update for now raise HwsimSkip("80+80 MHz channel not supported in regulatory information") state = hapd2.get_status_field("state") if state != "ENABLED": raise Exception("Unexpected interface state(2)") dev[1].connect("vht2", key_mgmt="NONE", scan_freq="5180") hwsim_utils.test_connectivity(dev[1], hapd2) sig = dev[1].request("SIGNAL_POLL").splitlines() if "FREQUENCY=5180" not in sig: raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) if "WIDTH=80+80 MHz" not in sig: raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) if "CENTER_FRQ1=5210" not in sig: raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig)) if "CENTER_FRQ2=5775" not in sig: raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig)) except Exception, e: if isinstance(e, Exception) and str(e) == "AP startup failed": if not vht_supported(): raise HwsimSkip("80/160 MHz channel not supported in regulatory information") raise
def test_ap_vht80plus80(dev, apdev): """VHT with 80+80 MHz channel width""" try: hapd = None hapd2 = None params = { "ssid": "vht", "country_code": "US", "hw_mode": "a", "channel": "52", "ht_capab": "[HT40+]", "vht_capab": "[VHT160-80PLUS80]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "3", "vht_oper_centr_freq_seg0_idx": "58", "vht_oper_centr_freq_seg1_idx": "155", 'ieee80211d': '1', 'ieee80211h': '1' } hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) # This will actually fail since DFS on 80+80 is not yet supported ev = hapd.wait_event(["AP-DISABLED"], timeout=5) # ignore result to avoid breaking the test once 80+80 DFS gets enabled params = { "ssid": "vht2", "country_code": "US", "hw_mode": "a", "channel": "36", "ht_capab": "[HT40+]", "vht_capab": "[VHT160-80PLUS80]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "3", "vht_oper_centr_freq_seg0_idx": "42", "vht_oper_centr_freq_seg1_idx": "155" } hapd2 = hostapd.add_ap(apdev[1], params, wait_enabled=False) ev = hapd2.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=5) if not ev: raise Exception("AP setup timed out(2)") if "AP-DISABLED" in ev: # Assume this failed due to missing regulatory update for now raise HwsimSkip( "80+80 MHz channel not supported in regulatory information") state = hapd2.get_status_field("state") if state != "ENABLED": raise Exception("Unexpected interface state(2)") dev[1].connect("vht2", key_mgmt="NONE", scan_freq="5180") hwsim_utils.test_connectivity(dev[1], hapd2) sig = dev[1].request("SIGNAL_POLL").splitlines() if "FREQUENCY=5180" not in sig: raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) if "WIDTH=80+80 MHz" not in sig: raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) if "CENTER_FRQ1=5210" not in sig: raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig)) if "CENTER_FRQ2=5775" not in sig: raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig)) sta = hapd2.get_sta(dev[1].own_addr()) if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2: raise Exception( "No Supported Operating Classes information for STA") opclass = int(sta['supp_op_classes'][0:2], 16) if opclass != 130: raise Exception("Unexpected Current Operating Class from STA: %d" % opclass) except Exception as e: if isinstance(e, Exception) and str(e) == "AP startup failed": if not vht_supported(): raise HwsimSkip( "80/160 MHz channel not supported in regulatory information" ) raise finally: dev[0].request("DISCONNECT") dev[1].request("DISCONNECT") if hapd: hapd.request("DISABLE") if hapd2: hapd2.request("DISABLE") subprocess.call(['iw', 'reg', 'set', '00']) dev[0].flush_scan_cache() dev[1].flush_scan_cache()
def test_ap_acl_mgmt(dev, apdev): """MAC ACL accept/deny management""" ssid = "acl" params = {} filename = hostapd.acl_file(dev, apdev, 'hostapd.macaddr') hostapd.send_file(apdev[0], filename, filename) params['ssid'] = ssid params['deny_mac_file'] = filename hapd = hostapd.add_ap(apdev[0], params) accept = hapd.request("ACCEPT_ACL SHOW").splitlines() logger.info("accept: " + str(accept)) deny = hapd.request("DENY_ACL SHOW").splitlines() logger.info("deny: " + str(deny)) if len(accept) != 0: raise Exception("Unexpected number of accept entries") if len(deny) != 3: raise Exception("Unexpected number of deny entries") if "01:01:01:01:01:01 VLAN_ID=0" not in deny: raise Exception("Missing deny entry") hapd.request("ACCEPT_ACL ADD_MAC 22:33:44:55:66:77") hapd.request("DENY_ACL ADD_MAC 22:33:44:55:66:88 VLAN_ID=2") accept = hapd.request("ACCEPT_ACL SHOW").splitlines() logger.info("accept: " + str(accept)) deny = hapd.request("DENY_ACL SHOW").splitlines() logger.info("deny: " + str(deny)) if len(accept) != 1: raise Exception("Unexpected number of accept entries (2)") if len(deny) != 4: raise Exception("Unexpected number of deny entries (2)") if "01:01:01:01:01:01 VLAN_ID=0" not in deny: raise Exception("Missing deny entry (2)") if "22:33:44:55:66:88 VLAN_ID=2" not in deny: raise Exception("Missing deny entry (2)") if "22:33:44:55:66:77 VLAN_ID=0" not in accept: raise Exception("Missing accept entry (2)") hapd.request("ACCEPT_ACL DEL_MAC 22:33:44:55:66:77") hapd.request("DENY_ACL DEL_MAC 22:33:44:55:66:88") accept = hapd.request("ACCEPT_ACL SHOW").splitlines() logger.info("accept: " + str(accept)) deny = hapd.request("DENY_ACL SHOW").splitlines() logger.info("deny: " + str(deny)) if len(accept) != 0: raise Exception("Unexpected number of accept entries (3)") if len(deny) != 3: raise Exception("Unexpected number of deny entries (3)") if "01:01:01:01:01:01 VLAN_ID=0" not in deny: raise Exception("Missing deny entry (3)") hapd.request("ACCEPT_ACL CLEAR") hapd.request("DENY_ACL CLEAR") accept = hapd.request("ACCEPT_ACL SHOW").splitlines() logger.info("accept: " + str(accept)) deny = hapd.request("DENY_ACL SHOW").splitlines() logger.info("deny: " + str(deny)) if len(accept) != 0: raise Exception("Unexpected number of accept entries (4)") if len(deny) != 0: raise Exception("Unexpected number of deny entries (4)") dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") dev[0].dump_monitor() hapd.request("DENY_ACL ADD_MAC " + dev[0].own_addr()) dev[0].wait_disconnected() dev[0].request("DISCONNECT") if filename.startswith('/tmp/'): os.unlink(filename)
def test_ap_vht80(dev, apdev): """VHT with 80 MHz channel width""" try: hapd = None params = { "ssid": "vht", "country_code": "FI", "hw_mode": "a", "channel": "36", "ht_capab": "[HT40+]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "1", "vht_oper_centr_freq_seg0_idx": "42" } hapd = hostapd.add_ap(apdev[0], params) bssid = apdev[0]['bssid'] dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180") hwsim_utils.test_connectivity(dev[0], hapd) sig = dev[0].request("SIGNAL_POLL").splitlines() if "FREQUENCY=5180" not in sig: raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) if "WIDTH=80 MHz" not in sig: raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) est = dev[0].get_bss(bssid)['est_throughput'] if est != "390001": raise Exception("Unexpected BSS est_throughput: " + est) status = dev[0].get_status() if status["ieee80211ac"] != "1": raise Exception("Unexpected STATUS ieee80211ac value (STA)") status = hapd.get_status() logger.info("hostapd STATUS: " + str(status)) if status["ieee80211n"] != "1": raise Exception("Unexpected STATUS ieee80211n value") if status["ieee80211ac"] != "1": raise Exception("Unexpected STATUS ieee80211ac value") if status["secondary_channel"] != "1": raise Exception("Unexpected STATUS secondary_channel value") if status["vht_oper_chwidth"] != "1": raise Exception("Unexpected STATUS vht_oper_chwidth value") if status["vht_oper_centr_freq_seg0_idx"] != "42": raise Exception( "Unexpected STATUS vht_oper_centr_freq_seg0_idx value") if "vht_caps_info" not in status: raise Exception("Missing vht_caps_info") sta = hapd.get_sta(dev[0].own_addr()) logger.info("hostapd STA: " + str(sta)) if "[HT]" not in sta['flags']: raise Exception("Missing STA flag: HT") if "[VHT]" not in sta['flags']: raise Exception("Missing STA flag: VHT") if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2: raise Exception( "No Supported Operating Classes information for STA") opclass = int(sta['supp_op_classes'][0:2], 16) if opclass != 128: raise Exception("Unexpected Current Operating Class from STA: %d" % opclass) except Exception as e: if isinstance(e, Exception) and str(e) == "AP startup failed": if not vht_supported(): raise HwsimSkip( "80 MHz channel not supported in regulatory information") raise finally: dev[0].request("DISCONNECT") clear_regdom(hapd, dev)
def test_ap_vht80_csa(dev, apdev): """VHT with 80 MHz channel width and CSA""" csa_supported(dev[0]) try: hapd = None params = { "ssid": "vht", "country_code": "US", "hw_mode": "a", "channel": "149", "ht_capab": "[HT40+]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "1", "vht_oper_centr_freq_seg0_idx": "155" } hapd = hostapd.add_ap(apdev[0], params) dev[0].connect("vht", key_mgmt="NONE", scan_freq="5745") hwsim_utils.test_connectivity(dev[0], hapd) hapd.request( "CHAN_SWITCH 5 5180 ht vht blocktx center_freq1=5210 sec_channel_offset=1 bandwidth=80" ) ev = hapd.wait_event(["CTRL-EVENT-STARTED-CHANNEL-SWITCH"], timeout=10) if ev is None: raise Exception("Channel switch start event not seen") if "freq=5180" not in ev: raise Exception("Unexpected channel in CS started") ev = hapd.wait_event(["CTRL-EVENT-CHANNEL-SWITCH"], timeout=10) if ev is None: raise Exception("Channel switch completion event not seen") if "freq=5180" not in ev: raise Exception("Unexpected channel in CS completed") ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10) if ev is None: raise Exception("CSA finished event timed out") if "freq=5180" not in ev: raise Exception("Unexpected channel in CSA finished event") time.sleep(0.5) hwsim_utils.test_connectivity(dev[0], hapd) hapd.request("CHAN_SWITCH 5 5745") ev = hapd.wait_event(["AP-CSA-FINISHED"], timeout=10) if ev is None: raise Exception("CSA finished event timed out") if "freq=5745" not in ev: raise Exception("Unexpected channel in CSA finished event") time.sleep(0.5) hwsim_utils.test_connectivity(dev[0], hapd) # This CSA to same channel will fail in kernel, so use this only for # extra code coverage. hapd.request("CHAN_SWITCH 5 5745") hapd.wait_event(["AP-CSA-FINISHED"], timeout=1) except Exception as e: if isinstance(e, Exception) and str(e) == "AP startup failed": if not vht_supported(): raise HwsimSkip( "80 MHz channel not supported in regulatory information") raise finally: dev[0].request("DISCONNECT") clear_regdom(hapd, dev)
def test_ap_ft_rrb(dev, apdev): """WPA2-PSK-FT RRB protocol testing""" ssid = "test-ft" passphrase="12345678" params = ft_params1(ssid=ssid, passphrase=passphrase) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2", scan_freq="2412") _dst_ll = binascii.unhexlify(apdev[0]['bssid'].replace(':','')) _src_ll = binascii.unhexlify(dev[0].own_addr().replace(':','')) proto = '\x89\x0d' ehdr = _dst_ll + _src_ll + proto # Too short RRB frame pkt = ehdr + '\x01' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # RRB discarded frame wikth unrecognized type pkt = ehdr + '\x02' + '\x02' + '\x01\x00' + _src_ll if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # RRB frame too short for action frame pkt = ehdr + '\x01' + '\x02' + '\x01\x00' + _src_ll if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # Too short RRB frame (not enough room for Action Frame body) pkt = ehdr + '\x01' + '\x02' + '\x00\x00' + _src_ll if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # Unexpected Action frame category pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # Unexpected Action in RRB Request pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # Target AP address in RRB Request does not match with own address pkt = ehdr + '\x01' + '\x00' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # Not enough room for status code in RRB Response pkt = ehdr + '\x01' + '\x01' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # RRB discarded frame with unknown packet_type pkt = ehdr + '\x01' + '\x02' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # RRB Response with non-zero status code; no STA match pkt = ehdr + '\x01' + '\x01' + '\x10\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + '\xff\xff' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # RRB Response with zero status code and extra data; STA match pkt = ehdr + '\x01' + '\x01' + '\x11\x00' + _src_ll + '\x06\x01' + _src_ll + '\x00\x00\x00\x00\x00\x00' + '\x00\x00' + '\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # Too short PMK-R1 pull pkt = ehdr + '\x01' + '\xc8' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # Too short PMK-R1 resp pkt = ehdr + '\x01' + '\xc9' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # Too short PMK-R1 push pkt = ehdr + '\x01' + '\xca' + '\x0e\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed") # No matching R0KH address found for PMK-R0 pull response pkt = ehdr + '\x01' + '\xc9' + '\x5a\x00' + _src_ll + '\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + 76*'\00' if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)): raise Exception("DATA_TEST_FRAME failed")
def test_ap_vht160(dev, apdev): """VHT with 160 MHz channel width (1)""" try: hapd = None params = { "ssid": "vht", "country_code": "FI", "hw_mode": "a", "channel": "36", "ht_capab": "[HT40+]", "vht_capab": "[VHT160]", "ieee80211n": "1", "ieee80211ac": "1", "vht_oper_chwidth": "2", "vht_oper_centr_freq_seg0_idx": "50", 'ieee80211d': '1', 'ieee80211h': '1' } hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False) ev = wait_dfs_event(hapd, "DFS-CAC-START", 5) if "DFS-CAC-START" not in ev: raise Exception("Unexpected DFS event") state = hapd.get_status_field("state") if state != "DFS": if state == "DISABLED" and not os.path.exists("dfs"): # Not all systems have recent enough CRDA version and # wireless-regdb changes to support 160 MHz and DFS. For now, # do not report failures for this test case. raise HwsimSkip( "CRDA or wireless-regdb did not support 160 MHz") raise Exception("Unexpected interface state: " + state) logger.info("Waiting for CAC to complete") ev = wait_dfs_event(hapd, "DFS-CAC-COMPLETED", 70) if "success=1" not in ev: raise Exception("CAC failed") if "freq=5180" not in ev: raise Exception("Unexpected DFS freq result") ev = hapd.wait_event(["AP-ENABLED"], timeout=5) if not ev: raise Exception("AP setup timed out") state = hapd.get_status_field("state") if state != "ENABLED": raise Exception("Unexpected interface state") dev[0].connect("vht", key_mgmt="NONE", scan_freq="5180") dev[0].wait_regdom(country_ie=True) hwsim_utils.test_connectivity(dev[0], hapd) sig = dev[0].request("SIGNAL_POLL").splitlines() if "FREQUENCY=5180" not in sig: raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig)) if "WIDTH=160 MHz" not in sig: raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) sta = hapd.get_sta(dev[0].own_addr()) if 'supp_op_classes' not in sta or len(sta['supp_op_classes']) < 2: raise Exception( "No Supported Operating Classes information for STA") opclass = int(sta['supp_op_classes'][0:2], 16) if opclass != 129: raise Exception("Unexpected Current Operating Class from STA: %d" % opclass) except Exception as e: if isinstance(e, Exception) and str(e) == "AP startup failed": if not vht_supported(): raise HwsimSkip( "80/160 MHz channel not supported in regulatory information" ) raise finally: if hapd: hapd.request("DISABLE") dev[0].disconnect_and_stop_scan() subprocess.call(['iw', 'reg', 'set', '00']) dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) dev[0].flush_scan_cache()
def test_ap_ft_over_ds_unexpected(dev, apdev): """WPA2-PSK-FT AP over DS and unexpected response""" ssid = "test-ft" passphrase="12345678" params = ft_params1(ssid=ssid, passphrase=passphrase) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params) params = ft_params2(ssid=ssid, passphrase=passphrase) hapd1 = hostapd.add_ap(apdev[1]['ifname'], params) dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2", scan_freq="2412") if dev[0].get_status_field('bssid') == apdev[0]['bssid']: ap1 = apdev[0] ap2 = apdev[1] hapd1ap = hapd0 hapd2ap = hapd1 else: ap1 = apdev[1] ap2 = apdev[0] hapd1ap = hapd1 hapd2ap = hapd0 addr = dev[0].own_addr() hapd1ap.set("ext_mgmt_frame_handling", "1") logger.info("Foreign STA address") msg = {} msg['fc'] = 13 << 4 msg['da'] = addr msg['sa'] = ap1['bssid'] msg['bssid'] = ap1['bssid'] msg['payload'] = binascii.unhexlify("06021122334455660102030405060000") hapd1ap.mgmt_tx(msg) logger.info("No over-the-DS in progress") msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000") hapd1ap.mgmt_tx(msg) logger.info("Non-zero status code") msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060100") hapd1ap.mgmt_tx(msg) hapd1ap.dump_monitor() dev[0].scan_for_bss(ap2['bssid'], freq="2412") if "OK" not in dev[0].request("FT_DS " + ap2['bssid']): raise Exception("FT_DS failed") req = hapd1ap.mgmt_rx() logger.info("Foreign Target AP") msg['payload'] = binascii.unhexlify("0602" + addr.replace(':', '') + "0102030405060000") hapd1ap.mgmt_tx(msg) addrs = addr.replace(':', '') + ap2['bssid'].replace(':', '') logger.info("No IEs") msg['payload'] = binascii.unhexlify("0602" + addrs + "0000") hapd1ap.mgmt_tx(msg) logger.info("Invalid IEs (trigger parsing failure)") msg['payload'] = binascii.unhexlify("0602" + addrs + "00003700") hapd1ap.mgmt_tx(msg) logger.info("Too short MDIE") msg['payload'] = binascii.unhexlify("0602" + addrs + "000036021122") hapd1ap.mgmt_tx(msg) logger.info("Mobility domain mismatch") msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603112201") hapd1ap.mgmt_tx(msg) logger.info("No FTIE") msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201") hapd1ap.mgmt_tx(msg) logger.info("FTIE SNonce mismatch") msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "1000000000000000000000000000000000000000000000000000000000000001" + "030a6e6173322e77312e6669") hapd1ap.mgmt_tx(msg) logger.info("No R0KH-ID subelem in FTIE") snonce = binascii.hexlify(req['payload'][111:111+32]) msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137520000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce) hapd1ap.mgmt_tx(msg) logger.info("No R0KH-ID subelem mismatch in FTIE") snonce = binascii.hexlify(req['payload'][111:111+32]) msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a11223344556677889900") hapd1ap.mgmt_tx(msg) logger.info("No R1KH-ID subelem in FTIE") r0khid = binascii.hexlify(req['payload'][145:145+10]) msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b201375e0000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid) hapd1ap.mgmt_tx(msg) logger.info("No RSNE") r0khid = binascii.hexlify(req['payload'][145:145+10]) msg['payload'] = binascii.unhexlify("0602" + addrs + "00003603a1b20137660000" + "00000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + snonce + "030a" + r0khid + "0106000102030405") hapd1ap.mgmt_tx(msg)
def test_rsn_ie_proto_ft_psk_sta(dev, apdev): """RSN element protocol testing for FT-PSK + PMF cases on STA side""" bssid = apdev[0]['bssid'] ssid = "test-ft" passphrase="12345678" params = ft_params1(ssid=ssid, passphrase=passphrase) params["ieee80211w"] = "1"; # This is the RSN element used normally by hostapd params['own_ie_override'] = '30140100000fac040100000fac040100000fac048c00' + '3603a1b201' hapd = hostapd.add_ap(apdev[0]['ifname'], params) id = dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2", ieee80211w="1", scan_freq="2412", pairwise="CCMP", group="CCMP") tests = [ ('PMKIDCount field included', '30160100000fac040100000fac040100000fac048c000000' + '3603a1b201'), ('Extra IE before RSNE', 'dd0400000000' + '30140100000fac040100000fac040100000fac048c00' + '3603a1b201'), ('PMKIDCount and Group Management Cipher suite fields included', '301a0100000fac040100000fac040100000fac048c000000000fac06' + '3603a1b201'), ('Extra octet after defined fields (future extensibility)', '301b0100000fac040100000fac040100000fac048c000000000fac0600' + '3603a1b201'), ('No RSN Capabilities field (PMF disabled in practice)', '30120100000fac040100000fac040100000fac04' + '3603a1b201') ] for txt,ie in tests: dev[0].request("DISCONNECT") dev[0].wait_disconnected() logger.info(txt) hapd.disable() hapd.set('own_ie_override', ie) hapd.enable() dev[0].request("BSS_FLUSH 0") dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True) dev[0].select_network(id, freq=2412) dev[0].wait_connected() dev[0].request("DISCONNECT") dev[0].wait_disconnected() logger.info('Invalid RSNE causing internal hostapd error') hapd.disable() hapd.set('own_ie_override', '30130100000fac040100000fac040100000fac048c' + '3603a1b201') hapd.enable() dev[0].request("BSS_FLUSH 0") dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True) dev[0].select_network(id, freq=2412) # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot # complete. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) if ev is not None: raise Exception("Unexpected connection") dev[0].request("DISCONNECT") logger.info('Unexpected PMKID causing internal hostapd error') hapd.disable() hapd.set('own_ie_override', '30260100000fac040100000fac040100000fac048c000100ffffffffffffffffffffffffffffffff' + '3603a1b201') hapd.enable() dev[0].request("BSS_FLUSH 0") dev[0].scan_for_bss(bssid, 2412, force_scan=True, only_new=True) dev[0].select_network(id, freq=2412) # hostapd fails to generate EAPOL-Key msg 3/4, so this connection cannot # complete. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) if ev is not None: raise Exception("Unexpected connection") dev[0].request("DISCONNECT")
def test_mbo_supp_oper_classes(dev, apdev): """MBO and supported operating classes""" params = { 'ssid': "test-wnm-mbo", 'mbo': '1', "country_code": "US", 'ieee80211d': '1', "ieee80211n": "1", "hw_mode": "a", "channel": "36" } hapd = hostapd.add_ap(apdev[0], params, no_enable=True) params = { 'ssid': "test-wnm-mbo-2", 'mbo': '1', "country_code": "US", 'ieee80211d': '1', "ieee80211n": "1", "hw_mode": "g", "channel": "1" } hapd2 = hostapd.add_ap(apdev[1], params, no_enable=True) try: za2, za5 = run_mbo_supp_oper_classes(dev, apdev, hapd, hapd2, "ZA") fi2, fi5 = run_mbo_supp_oper_classes(dev, apdev, hapd, hapd2, "FI") us2, us5 = run_mbo_supp_oper_classes(dev, apdev, hapd, hapd2, "US") jp2, jp5 = run_mbo_supp_oper_classes(dev, apdev, hapd, hapd2, "JP") bd2, bd5 = run_mbo_supp_oper_classes(dev, apdev, None, hapd2, "BD") kz2, kz5 = run_mbo_supp_oper_classes(dev, apdev, None, hapd2, "KZ") finally: dev[0].dump_monitor() set_reg("00", apdev[0], apdev[1], dev[0]) ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) za = "515354737475767778797a7b808182" fi = "515354737475767778797a7b808182" us = "515354737475767778797a7b7c7d7e7f808182" jp = "51525354737475767778797a7b808182" bd = "5153547c7d7e7f80" kz = "515354" tests = [("ZA", za, za2, za5, True), ("FI", fi, fi2, fi5, True), ("US", us, us2, us5, True), ("JP", jp, jp2, jp5, True), ("BD", bd, bd2, bd5, False), ("KZ", kz, kz2, kz5, False)] for country, expected, res2, res5, inc5 in tests: # For now, allow operating class 129 to be missing since not all # installed regdb files include the 160 MHz channels. expected2 = expected.replace('808182', '8082') # For now, allow operating classes 121-123 to be missing since not all # installed regdb files include the related US DFS channels. expected2 = expected2.replace('78797a7b7c', '787c') if res2 != expected and res2 != expected2: raise Exception( "Unexpected supp_op_class string (country=%s, 2.4 GHz): %s (expected: %s)" % (country, res2, expected)) if inc5 and res5 != expected and res5 != expected2: raise Exception( "Unexpected supp_op_class string (country=%s, 5 GHz): %s (expected: %s)" % (country, res5, expected))
def test_ft_psk_key_lifetime_in_memory(dev, apdev, params): """WPA2-PSK-FT and key lifetime in memory""" ssid = "test-ft" passphrase="04c2726b4b8d5f1b4db9c07aa4d9e9d8f765cb5d25ec817e6cc4fcdd5255db0" psk = '93c90846ff67af9037ed83fb72b63dbeddaa81d47f926c20909b5886f1d9358d' pmk = binascii.unhexlify(psk) p = ft_params1(ssid=ssid, passphrase=passphrase) hapd0 = hostapd.add_ap(apdev[0]['ifname'], p) p = ft_params2(ssid=ssid, passphrase=passphrase) hapd1 = hostapd.add_ap(apdev[1]['ifname'], p) pid = find_wpas_process(dev[0]) dev[0].connect(ssid, psk=passphrase, key_mgmt="FT-PSK", proto="WPA2", scan_freq="2412") time.sleep(1) buf = read_process_memory(pid, pmk) dev[0].request("DISCONNECT") dev[0].wait_disconnected() dev[0].relog() pmkr0 = None pmkr1 = None ptk = None gtk = None with open(os.path.join(params['logdir'], 'log0'), 'r') as f: for l in f.readlines(): if "FT: PMK-R0 - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmkr0 = binascii.unhexlify(val) if "FT: PMK-R1 - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') pmkr1 = binascii.unhexlify(val) if "FT: KCK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') kck = binascii.unhexlify(val) if "FT: KEK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') kek = binascii.unhexlify(val) if "FT: TK - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') tk = binascii.unhexlify(val) if "WPA: Group Key - hexdump" in l: val = l.strip().split(':')[3].replace(' ', '') gtk = binascii.unhexlify(val) if not pmkr0 or not pmkr1 or not kck or not kek or not tk or not gtk: raise Exception("Could not find keys from debug log") if len(gtk) != 16: raise Exception("Unexpected GTK length") logger.info("Checking keys in memory while associated") get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") if pmk not in buf: raise HwsimSkip("PMK not found while associated") if pmkr0 not in buf: raise HwsimSkip("PMK-R0 not found while associated") if pmkr1 not in buf: raise HwsimSkip("PMK-R1 not found while associated") if kck not in buf: raise Exception("KCK not found while associated") if kek not in buf: raise Exception("KEK not found while associated") if tk in buf: raise Exception("TK found from memory") if gtk in buf: raise Exception("GTK found from memory") logger.info("Checking keys in memory after disassociation") buf = read_process_memory(pid, pmk) get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") # Note: PMK/PSK is still present in network configuration fname = os.path.join(params['logdir'], 'ft_psk_key_lifetime_in_memory.memctx-') verify_not_present(buf, pmkr0, fname, "PMK-R0") verify_not_present(buf, pmkr1, fname, "PMK-R1") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK") dev[0].request("REMOVE_NETWORK all") logger.info("Checking keys in memory after network profile removal") buf = read_process_memory(pid, pmk) get_key_locations(buf, pmk, "PMK") get_key_locations(buf, pmkr0, "PMK-R0") get_key_locations(buf, pmkr1, "PMK-R1") verify_not_present(buf, pmk, fname, "PMK") verify_not_present(buf, pmkr0, fname, "PMK-R0") verify_not_present(buf, pmkr1, fname, "PMK-R1") verify_not_present(buf, kck, fname, "KCK") verify_not_present(buf, kek, fname, "KEK") verify_not_present(buf, tk, fname, "TK") verify_not_present(buf, gtk, fname, "GTK")
def test_suite_b_192_pmksa_caching_roam(dev, apdev): """WPA2/GCMP-256 connection at Suite B 192-bit level using PMKSA caching and roaming""" check_suite_b_192_capa(dev) dev[0].flush_scan_cache() params = suite_b_192_ap_params() hapd = hostapd.add_ap(apdev[0], params) bssid = hapd.own_addr() dev[0].connect("test-suite-b", key_mgmt="WPA-EAP-SUITE-B-192", ieee80211w="2", openssl_ciphers="SUITEB192", eap="TLS", identity="tls user", ca_cert="auth_serv/ec2-ca.pem", client_cert="auth_serv/ec2-user.pem", private_key="auth_serv/ec2-user.key", pairwise="GCMP-256", group="GCMP-256", scan_freq="2412") ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5) if ev is None: raise Exception("PMKSA cache entry not added for AP1") hapd.wait_sta() dev[0].dump_monitor() hapd2 = hostapd.add_ap(apdev[1], params) bssid2 = hapd2.own_addr() dev[0].scan_for_bss(bssid2, freq=2412) dev[0].request("ROAM " + bssid2) ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", "CTRL-EVENT-CONNECTED"], timeout=20) if ev is None: raise Exception("Roaming with the AP timed out") if "CTRL-EVENT-EAP-STARTED" not in ev: raise Exception("EAP exchange not seen") ev = dev[0].wait_connected() if bssid2 not in ev: raise Exception("Roam to AP2 connected back to AP1") ev = dev[0].wait_event(["PMKSA-CACHE-ADDED"], timeout=5) if ev is None: raise Exception("PMKSA cache entry not added for AP2") hapd2.wait_sta() dev[0].dump_monitor() dev[0].request("ROAM " + bssid) ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", "CTRL-EVENT-CONNECTED"], timeout=20) if ev is None: raise Exception("Roaming with the AP timed out") if "CTRL-EVENT-EAP-STARTED" in ev: raise Exception("Unexpected EAP exchange") if bssid not in ev: raise Exception("Roam to AP1 connected back to AP2") hapd.wait_sta() dev[0].dump_monitor() dev[0].request("ROAM " + bssid2) ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", "CTRL-EVENT-CONNECTED"], timeout=20) if ev is None: raise Exception("Roaming with the AP timed out") if "CTRL-EVENT-EAP-STARTED" in ev: raise Exception("Unexpected EAP exchange") if bssid2 not in ev: raise Exception("Second roam to AP2 connected back to AP1") hapd2.wait_sta() dev[0].dump_monitor()
def test_dbus_old_connect_eap(dev, apdev): """The old D-Bus interface - add an EAP network and connect""" (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) ssid = "test-wpa2-eap" params = hostapd.wpa2_eap_params(ssid=ssid) hapd = hostapd.add_ap(apdev[0]['ifname'], params) class TestDbusConnect(TestDbus): def __init__(self, bus): TestDbus.__init__(self, bus) self.connected = False self.certification_received = False def __enter__(self): gobject.timeout_add(1, self.run_connect) gobject.timeout_add(15000, self.timeout) self.add_signal(self.stateChange, WPAS_DBUS_OLD_IFACE, "StateChange") self.add_signal(self.certification, WPAS_DBUS_OLD_IFACE, "Certification") self.loop.run() return self def stateChange(self, new, old): logger.debug("stateChange: %s --> %s" % (old, new)) if new == "COMPLETED": self.connected = True self.loop.quit() def certification(self, depth, subject, hash, cert_hex): logger.debug( "certification: depth={} subject={} hash={} cert_hex={}". format(depth, subject, hash, cert_hex)) self.certification_received = True def run_connect(self, *args): logger.debug("run_connect") path = if_obj.addNetwork(dbus_interface=WPAS_DBUS_OLD_IFACE) netw_obj = bus.get_object(WPAS_DBUS_OLD_SERVICE, path) params = dbus.Dictionary( { 'ssid': ssid, 'key_mgmt': 'WPA-EAP', 'eap': 'TTLS', 'anonymous_identity': 'ttls', 'identity': 'pap user', 'ca_cert': 'auth_serv/ca.pem', 'phase2': 'auth=PAP', 'password': '******', 'scan_freq': 2412 }, signature='sv') netw_obj.set(params, dbus_interface=WPAS_DBUS_OLD_NETWORK) netw_obj.enable(dbus_interface=WPAS_DBUS_OLD_NETWORK) self.path = path self.netw_obj = netw_obj return False def success(self): return self.connected and self.certification_received with TestDbusConnect(bus) as t: if not t.success(): raise Exception("Expected signals not seen")
def test_wnm_bss_tm(dev, apdev): """WNM BSS Transition Management""" try: hapd = None hapd2 = None params = { "ssid": "test-wnm", "country_code": "FI", "ieee80211d": "1", "hw_mode": "g", "channel": "1", "bss_transition": "1" } hapd = hostapd.add_ap(apdev[0]['ifname'], params) id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") dev[0].set_network(id, "scan_freq", "") params = { "ssid": "test-wnm", "country_code": "FI", "ieee80211d": "1", "hw_mode": "a", "channel": "36", "bss_transition": "1" } hapd2 = hostapd.add_ap(apdev[1]['ifname'], params) addr = dev[0].p2p_interface_addr() dev[0].dump_monitor() logger.info("No neighbor list entries") if "OK" not in hapd.request("BSS_TM_REQ " + addr): raise Exception("BSS_TM_REQ command failed") ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) if ev is None: raise Exception("No BSS Transition Management Response") if addr not in ev: raise Exception( "Unexpected BSS Transition Management Response address") if "status_code=0" in ev: raise Exception("BSS transition accepted unexpectedly") dev[0].dump_monitor() logger.info( "Neighbor list entry, but not claimed as Preferred Candidate List") if "OK" not in hapd.request( "BSS_TM_REQ " + addr + " neighbor=11:22:33:44:55:66,0x0000,81,3,7"): raise Exception("BSS_TM_REQ command failed") ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) if ev is None: raise Exception("No BSS Transition Management Response") if "status_code=0" in ev: raise Exception("BSS transition accepted unexpectedly") dev[0].dump_monitor() logger.info( "Preferred Candidate List (no matching neighbor) without Disassociation Imminent" ) if "OK" not in hapd.request( "BSS_TM_REQ " + addr + " pref=1 neighbor=11:22:33:44:55:66,0x0000,81,3,7,0301ff neighbor=22:33:44:55:66:77,0x0000,1,36,7 neighbor=00:11:22:33:44:55,0x0000,81,4,7,03010a" ): raise Exception("BSS_TM_REQ command failed") ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) if ev is None: raise Exception("No BSS Transition Management Response") if "status_code=0" in ev: raise Exception("BSS transition accepted unexpectedly") ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5) if ev is None: raise Exception("No scan started") dev[0].dump_monitor() logger.info( "Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent" ) if "OK" not in hapd.request( "BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): raise Exception("BSS_TM_REQ command failed") ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) if ev is None: raise Exception("No BSS Transition Management Response") if "status_code=0" not in ev: raise Exception("BSS transition request was not accepted: " + ev) if "target_bssid=" + apdev[1]['bssid'] not in ev: raise Exception("Unexpected target BSS: " + ev) dev[0].wait_connected(timeout=15, error="No reassociation seen") if apdev[1]['bssid'] not in ev: raise Exception("Unexpected reassociation target: " + ev) ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) if ev is not None: raise Exception("Unexpected scan started") dev[0].dump_monitor() logger.info( "Preferred Candidate List with two matches, no roam needed") if "OK" not in hapd2.request( "BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,030101 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): raise Exception("BSS_TM_REQ command failed") ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10) if ev is None: raise Exception("No BSS Transition Management Response") if "status_code=0" not in ev: raise Exception("BSS transition request was not accepted: " + ev) if "target_bssid=" + apdev[1]['bssid'] not in ev: raise Exception("Unexpected target BSS: " + ev) ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) if ev is not None: raise Exception("Unexpected scan started") ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5) if ev is not None: raise Exception("Unexpected reassociation") finally: dev[0].request("DISCONNECT") if hapd: hapd.request("DISABLE") if hapd2: hapd2.request("DISABLE") subprocess.call(['iw', 'reg', 'set', '00']) dev[0].flush_scan_cache()
def test_mbo_non_pref_chan(dev, apdev): """MBO non-preferred channel list""" ssid = "test-wnm-mbo" params = {'ssid': ssid, 'mbo': '1'} hapd = hostapd.add_ap(apdev[0], params) bssid = apdev[0]['bssid'] if "FAIL" not in dev[0].request("SET non_pref_chan 81:7:200:99"): raise Exception("Invalid non_pref_chan value accepted") if "FAIL" not in dev[0].request("SET non_pref_chan 81:15:200:3"): raise Exception("Invalid non_pref_chan value accepted") if "FAIL" not in dev[0].request("SET non_pref_chan 81:7:200:3 81:7:201:3"): raise Exception("Invalid non_pref_chan value accepted") if "OK" not in dev[0].request("SET non_pref_chan 81:7:200:3"): raise Exception("Failed to set non-preferred channel list") if "OK" not in dev[0].request("SET non_pref_chan 81:7:200:1 81:9:100:2"): raise Exception("Failed to set non-preferred channel list") dev[0].connect(ssid, key_mgmt="NONE", scan_freq="2412") addr = dev[0].own_addr() sta = hapd.get_sta(addr) logger.debug("STA: " + str(sta)) if 'non_pref_chan[0]' not in sta: raise Exception("Missing non_pref_chan[0] value (assoc)") if sta['non_pref_chan[0]'] != '81:200:1:7': raise Exception("Unexpected non_pref_chan[0] value (assoc)") if 'non_pref_chan[1]' not in sta: raise Exception("Missing non_pref_chan[1] value (assoc)") if sta['non_pref_chan[1]'] != '81:100:2:9': raise Exception("Unexpected non_pref_chan[1] value (assoc)") if 'non_pref_chan[2]' in sta: raise Exception("Unexpected non_pref_chan[2] value (assoc)") if "OK" not in dev[0].request("SET non_pref_chan 81:9:100:2"): raise Exception("Failed to update non-preferred channel list") time.sleep(0.1) sta = hapd.get_sta(addr) logger.debug("STA: " + str(sta)) if 'non_pref_chan[0]' not in sta: raise Exception("Missing non_pref_chan[0] value (update 1)") if sta['non_pref_chan[0]'] != '81:100:2:9': raise Exception("Unexpected non_pref_chan[0] value (update 1)") if 'non_pref_chan[1]' in sta: raise Exception("Unexpected non_pref_chan[1] value (update 1)") if "OK" not in dev[0].request( "SET non_pref_chan 81:9:100:2 81:10:100:2 81:8:100:2 81:7:100:1 81:5:100:1" ): raise Exception("Failed to update non-preferred channel list") time.sleep(0.1) sta = hapd.get_sta(addr) logger.debug("STA: " + str(sta)) if 'non_pref_chan[0]' not in sta: raise Exception("Missing non_pref_chan[0] value (update 2)") if sta['non_pref_chan[0]'] != '81:100:1:7,5': raise Exception("Unexpected non_pref_chan[0] value (update 2)") if 'non_pref_chan[1]' not in sta: raise Exception("Missing non_pref_chan[1] value (update 2)") if sta['non_pref_chan[1]'] != '81:100:2:9,10,8': raise Exception("Unexpected non_pref_chan[1] value (update 2)") if 'non_pref_chan[2]' in sta: raise Exception("Unexpected non_pref_chan[2] value (update 2)") if "OK" not in dev[0].request("SET non_pref_chan 81:5:90:2 82:14:91:2"): raise Exception("Failed to update non-preferred channel list") time.sleep(0.1) sta = hapd.get_sta(addr) logger.debug("STA: " + str(sta)) if 'non_pref_chan[0]' not in sta: raise Exception("Missing non_pref_chan[0] value (update 3)") if sta['non_pref_chan[0]'] != '81:90:2:5': raise Exception("Unexpected non_pref_chan[0] value (update 3)") if 'non_pref_chan[1]' not in sta: raise Exception("Missing non_pref_chan[1] value (update 3)") if sta['non_pref_chan[1]'] != '82:91:2:14': raise Exception("Unexpected non_pref_chan[1] value (update 3)") if 'non_pref_chan[2]' in sta: raise Exception("Unexpected non_pref_chan[2] value (update 3)") if "OK" not in dev[0].request("SET non_pref_chan "): raise Exception("Failed to update non-preferred channel list") time.sleep(0.1) sta = hapd.get_sta(addr) logger.debug("STA: " + str(sta)) if 'non_pref_chan[0]' in sta: raise Exception("Unexpected non_pref_chan[0] value (update 4)")
def test_authsrv_oom(dev, apdev): """Authentication server OOM""" params = authsrv_params() authsrv = hostapd.add_ap(apdev[1], params) params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap") params['auth_server_port'] = "18128" hapd = hostapd.add_ap(apdev[0], params) dev[0].scan_for_bss(hapd.own_addr(), 2412) with alloc_fail(authsrv, 1, "hostapd_radius_get_eap_user"): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", wait_connect=False, scan_freq="2412") ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) if ev is None: raise Exception("EAP failure not reported") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() dev[0].dump_monitor() with alloc_fail(authsrv, 1, "srv_log"): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", scan_freq="2412") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() dev[0].dump_monitor() with alloc_fail(authsrv, 1, "radius_server_new_session"): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", wait_connect=False, scan_freq="2412") dev[0].wait_disconnected() dev[0].request("REMOVE_NETWORK all") dev[0].dump_monitor() for count in range(1, 3): with alloc_fail(authsrv, count, "=radius_server_get_new_session"): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", wait_connect=False, scan_freq="2412") dev[0].wait_disconnected() dev[0].request("REMOVE_NETWORK all") dev[0].dump_monitor() with alloc_fail(authsrv, 1, "eap_server_sm_init"): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", wait_connect=False, scan_freq="2412") dev[0].wait_disconnected() dev[0].request("REMOVE_NETWORK all") dev[0].dump_monitor() tests = [ "radius_server_encapsulate_eap", "radius_server_receive_auth" ] for t in tests: with alloc_fail(authsrv, 1, t): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", wait_connect=False, scan_freq="2412") wait_fail_trigger(authsrv, "GET_ALLOC_FAIL") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() dev[0].dump_monitor() tests = [ "radius_msg_add_attr;radius_server_encapsulate_eap", "radius_msg_add_eap;radius_server_encapsulate_eap", "radius_msg_finish_srv;radius_server_encapsulate_eap" ] for t in tests: with fail_test(authsrv, 1, t): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", wait_connect=False, scan_freq="2412") wait_fail_trigger(authsrv, "GET_FAIL") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() dev[0].dump_monitor() with alloc_fail(authsrv, 1, "radius_server_get_new_session"): with fail_test(authsrv, 1, "radius_msg_add_eap;radius_server_reject"): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", wait_connect=False, scan_freq="2412") wait_fail_trigger(authsrv, "GET_FAIL") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() dev[0].dump_monitor() with alloc_fail(authsrv, 1, "radius_server_get_new_session"): with fail_test(authsrv, 1, "radius_msg_finish_srv;radius_server_reject"): dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS", identity="user", anonymous_identity="ttls", password="******", ca_cert="auth_serv/ca.pem", phase2="autheap=GTC", wait_connect=False, scan_freq="2412") wait_fail_trigger(authsrv, "GET_FAIL") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() dev[0].dump_monitor() authsrv.disable() with alloc_fail(authsrv, 1, "radius_server_init;hostapd_setup_radius_srv"): if "FAIL" not in authsrv.request("ENABLE"): raise Exception("ENABLE succeeded during OOM") with alloc_fail(authsrv, 2, "radius_server_init;hostapd_setup_radius_srv"): authsrv.request("ENABLE") # This is actually allowed to continue even though memory allocation # fails. authsrv.disable() for count in range(1, 4): with alloc_fail(authsrv, count, "radius_server_read_clients;radius_server_init;hostapd_setup_radius_srv"): if "FAIL" not in authsrv.request("ENABLE"): raise Exception("ENABLE succeeded during OOM") with alloc_fail(authsrv, 1, "eloop_sock_table_add_sock;radius_server_init;hostapd_setup_radius_srv"): if "FAIL" not in authsrv.request("ENABLE"): raise Exception("ENABLE succeeded during OOM") with alloc_fail(authsrv, 1, "tls_init;authsrv_init"): if "FAIL" not in authsrv.request("ENABLE"): raise Exception("ENABLE succeeded during OOM") for count in range(1, 3): with alloc_fail(authsrv, count, "eap_sim_db_init;authsrv_init"): if "FAIL" not in authsrv.request("ENABLE"): raise Exception("ENABLE succeeded during OOM")
def test_openssl_ecdh_curves(dev, apdev): """OpenSSL ECDH curve configuration""" check_suite_b_192_capa(dev) dev[0].flush_scan_cache() params = suite_b_192_ap_params() params['wpa_key_mgmt'] = "WPA-EAP" del params['openssl_ciphers'] hapd = hostapd.add_ap(apdev[0], params) dev[0].connect("test-suite-b", key_mgmt="WPA-EAP", ieee80211w="2", openssl_ciphers="SUITEB192", eap="TLS", identity="tls user", ca_cert="auth_serv/ec2-ca.pem", client_cert="auth_serv/ec2-user.pem", private_key="auth_serv/ec2-user.key", pairwise="GCMP-256", group="GCMP-256", scan_freq="2412") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() hapd.disable() hapd.set('openssl_ecdh_curves', 'foo') if "FAIL" not in hapd.request("ENABLE"): raise Exception("Invalid openssl_ecdh_curves value accepted") hapd.set('openssl_ecdh_curves', 'P-384') hapd.enable() dev[0].connect("test-suite-b", key_mgmt="WPA-EAP", ieee80211w="2", openssl_ciphers="SUITEB192", eap="TLS", identity="tls user", ca_cert="auth_serv/ec2-ca.pem", client_cert="auth_serv/ec2-user.pem", private_key="auth_serv/ec2-user.key", pairwise="GCMP-256", group="GCMP-256", scan_freq="2412") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected() # Check with server enforcing P-256 and client allowing only P-384 hapd.disable() hapd.set('openssl_ecdh_curves', 'P-256') hapd.enable() dev[0].connect("test-suite-b", key_mgmt="WPA-EAP", ieee80211w="2", openssl_ciphers="SUITEB192", eap="TLS", identity="tls user", ca_cert="auth_serv/ec2-ca.pem", client_cert="auth_serv/ec2-user.pem", private_key="auth_serv/ec2-user.key", pairwise="GCMP-256", group="GCMP-256", scan_freq="2412", wait_connect=False) ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10) if ev is None: raise Exception("EAP failure not reported") dev[0].request("REMOVE_NETWORK all") dev[0].wait_disconnected()
def test_radius_protocol(dev, apdev): """RADIUS Authentication protocol tests with a fake server""" try: import pyrad.server import pyrad.packet import pyrad.dictionary except ImportError: raise HwsimSkip("No pyrad modules available") class TestServer(pyrad.server.Server): def _HandleAuthPacket(self, pkt): pyrad.server.Server._HandleAuthPacket(self, pkt) logger.info("Received authentication request") reply = self.CreateReplyPacket(pkt) reply.code = pyrad.packet.AccessAccept if self.t_events['msg_auth'].is_set(): logger.info("Add Message-Authenticator") if self.t_events['wrong_secret'].is_set(): logger.info("Use incorrect RADIUS shared secret") pw = "incorrect" else: pw = reply.secret hmac_obj = hmac.new(pw) hmac_obj.update(struct.pack("B", reply.code)) hmac_obj.update(struct.pack("B", reply.id)) # reply attributes reply.AddAttribute( "Message-Authenticator", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" ) attrs = reply._PktEncodeAttributes() # Length flen = 4 + 16 + len(attrs) hmac_obj.update(struct.pack(">H", flen)) hmac_obj.update(pkt.authenticator) hmac_obj.update(attrs) if self.t_events['double_msg_auth'].is_set(): logger.info("Include two Message-Authenticator attributes") else: del reply[80] reply.AddAttribute("Message-Authenticator", hmac_obj.digest()) self.SendReplyPacket(pkt.fd, reply) def RunWithStop(self, t_events): self._poll = select.poll() self._fdmap = {} self._PrepareSockets() self.t_events = t_events while not t_events['stop'].is_set(): for (fd, event) in self._poll.poll(1000): if event == select.POLLIN: try: fdo = self._fdmap[fd] self._ProcessInput(fdo) except ServerPacketError as err: logger.info("pyrad server dropping packet: " + str(err)) except pyrad.packet.PacketError as err: logger.info( "pyrad server received invalid packet: " + str(err)) else: logger.error( "Unexpected event in pyrad server main loop") srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"), authport=18138, acctport=18139) srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1", "radius", "localhost") srv.BindToAddress("") t_events = {} t_events['stop'] = threading.Event() t_events['msg_auth'] = threading.Event() t_events['wrong_secret'] = threading.Event() t_events['double_msg_auth'] = threading.Event() t = threading.Thread(target=run_pyrad_server, args=(srv, t_events)) t.start() try: params = hostapd.wpa2_eap_params(ssid="radius-test") params['auth_server_port'] = "18138" hapd = hostapd.add_ap(apdev[0]['ifname'], params) connect(dev[0], "radius-test", wait_connect=False) ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15) if ev is None: raise Exception("Timeout on EAP start") time.sleep(1) dev[0].request("REMOVE_NETWORK all") time.sleep(0.1) dev[0].dump_monitor() t_events['msg_auth'].set() t_events['wrong_secret'].set() connect(dev[0], "radius-test", wait_connect=False) time.sleep(1) dev[0].request("REMOVE_NETWORK all") time.sleep(0.1) dev[0].dump_monitor() t_events['wrong_secret'].clear() connect(dev[0], "radius-test", wait_connect=False) time.sleep(1) dev[0].request("REMOVE_NETWORK all") time.sleep(0.1) dev[0].dump_monitor() t_events['double_msg_auth'].set() connect(dev[0], "radius-test", wait_connect=False) time.sleep(1) finally: t_events['stop'].set() t.join()
def test_wnm_bss_tm_req(dev, apdev): """BSS Transition Management Request""" params = {"ssid": "test-wnm", "bss_transition": "1"} hapd = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") hapd2 = hostapd.add_ap(apdev[1]['ifname'], params) hapd.set("ext_mgmt_frame_handling", "1") # truncated BSS TM Request req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x08) req['payload'] = struct.pack("<BBBBH", ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ, 1, 0, 0) hapd.mgmt_tx(req) expect_ack(hapd) # no disassociation and no candidate list req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], dialog_token=2) hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=2, expect_status=1) # truncated BSS Termination Duration req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x08) hapd.mgmt_tx(req) expect_ack(hapd) # BSS Termination Duration with TSF=0 and Duration=10 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x08, dialog_token=3) req['payload'] += struct.pack("<BBQH", 4, 10, 0, 10) hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=3, expect_status=1) # truncated Session Information URL req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x10) hapd.mgmt_tx(req) expect_ack(hapd) req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x10) req['payload'] += struct.pack("<BBB", 3, 65, 66) hapd.mgmt_tx(req) expect_ack(hapd) # Session Information URL req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x10, dialog_token=4) req['payload'] += struct.pack("<BBB", 2, 65, 66) hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=4, expect_status=0) # Preferred Candidate List without any entries req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x01, dialog_token=5) hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=5, expect_status=7) # Preferred Candidate List with a truncated entry req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x01) req['payload'] += struct.pack("<BB", 52, 1) hapd.mgmt_tx(req) expect_ack(hapd) # Preferred Candidate List with a too short entry req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x01, dialog_token=6) req['payload'] += struct.pack("<BB", 52, 0) hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7) # Preferred Candidate List with a non-matching entry req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x01, dialog_token=6) req['payload'] += struct.pack("<BB6BLBBB", 52, 13, 1, 2, 3, 4, 5, 6, 0, 81, 1, 7) hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7) # Preferred Candidate List with a truncated subelement req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x01, dialog_token=7) req['payload'] += struct.pack("<BB6BLBBBBB", 52, 13 + 2, 1, 2, 3, 4, 5, 6, 0, 81, 1, 7, 1, 1) hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=7, expect_status=7) # Preferred Candidate List with lots of invalid optional subelements req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x01, dialog_token=8) subelems = struct.pack("<BBHB", 1, 3, 0, 100) subelems += struct.pack("<BBB", 2, 1, 65) subelems += struct.pack("<BB", 3, 0) subelems += struct.pack("<BBQB", 4, 9, 0, 10) subelems += struct.pack("<BBHLB", 5, 7, 0, 0, 0) subelems += struct.pack("<BB", 66, 0) subelems += struct.pack("<BBBBBB", 70, 4, 0, 0, 0, 0) subelems += struct.pack("<BB", 71, 0) req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems), 1, 2, 3, 4, 5, 6, 0, 81, 1, 7) + subelems hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7) # Preferred Candidate List with lots of valid optional subelements (twice) req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'], req_mode=0x01, dialog_token=8) # TSF Information subelems = struct.pack("<BBHH", 1, 4, 0, 100) # Condensed Country String subelems += struct.pack("<BBBB", 2, 2, 65, 66) # BSS Transition Candidate Preference subelems += struct.pack("<BBB", 3, 1, 100) # BSS Termination Duration subelems += struct.pack("<BBQH", 4, 10, 0, 10) # Bearing subelems += struct.pack("<BBHLH", 5, 8, 0, 0, 0) # Measurement Pilot Transmission subelems += struct.pack("<BBBBB", 66, 3, 0, 0, 0) # RM Enabled Capabilities subelems += struct.pack("<BBBBBBB", 70, 5, 0, 0, 0, 0, 0) # Multiple BSSID subelems += struct.pack("<BBBB", 71, 2, 0, 0) req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems) * 2, 1, 2, 3, 4, 5, 6, 0, 81, 1, 7) + subelems + subelems hapd.mgmt_tx(req) resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
def test_radius_das_disconnect(dev, apdev): """RADIUS Dynamic Authorization Extensions - Disconnect""" try: import pyrad.client import pyrad.packet import pyrad.dictionary import radius_das except ImportError: raise HwsimSkip("No pyrad modules available") params = hostapd.wpa2_eap_params(ssid="radius-das") params['radius_das_port'] = "3799" params['radius_das_client'] = "127.0.0.1 secret" params['radius_das_require_event_timestamp'] = "1" params['own_ip_addr'] = "127.0.0.1" params['nas_identifier'] = "nas.example.com" hapd = hostapd.add_ap(apdev[0]['ifname'], params) connect(dev[0], "radius-das") addr = dev[0].p2p_interface_addr() sta = hapd.get_sta(addr) id = sta['dot1xAuthSessionId'] dict = pyrad.dictionary.Dictionary("dictionary.radius") srv = pyrad.client.Client(server="127.0.0.1", acctport=3799, secret="secret", dict=dict) srv.retries = 1 srv.timeout = 1 logger.info("Disconnect-Request with incorrect secret") req = radius_das.DisconnectPacket(dict=dict, secret="incorrect", User_Name="foo", NAS_Identifier="localhost", Event_Timestamp=int(time.time())) logger.debug(req) try: reply = srv.SendPacket(req) raise Exception("Unexpected response to Disconnect-Request") except pyrad.client.Timeout: logger.info( "Disconnect-Request with incorrect secret properly ignored") logger.info("Disconnect-Request without Event-Timestamp") req = radius_das.DisconnectPacket(dict=dict, secret="secret", User_Name="*****@*****.**") logger.debug(req) try: reply = srv.SendPacket(req) raise Exception("Unexpected response to Disconnect-Request") except pyrad.client.Timeout: logger.info( "Disconnect-Request without Event-Timestamp properly ignored") logger.info("Disconnect-Request with non-matching Event-Timestamp") req = radius_das.DisconnectPacket(dict=dict, secret="secret", User_Name="*****@*****.**", Event_Timestamp=123456789) logger.debug(req) try: reply = srv.SendPacket(req) raise Exception("Unexpected response to Disconnect-Request") except pyrad.client.Timeout: logger.info( "Disconnect-Request with non-matching Event-Timestamp properly ignored" ) logger.info("Disconnect-Request with unsupported attribute") req = radius_das.DisconnectPacket(dict=dict, secret="secret", User_Name="foo", User_Password="******", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 401) logger.info("Disconnect-Request with invalid Calling-Station-Id") req = radius_das.DisconnectPacket(dict=dict, secret="secret", User_Name="foo", Calling_Station_Id="foo", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 407) logger.info("Disconnect-Request with mismatching User-Name") req = radius_das.DisconnectPacket(dict=dict, secret="secret", User_Name="foo", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503) logger.info("Disconnect-Request with mismatching Calling-Station-Id") req = radius_das.DisconnectPacket(dict=dict, secret="secret", Calling_Station_Id="12:34:56:78:90:aa", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503) logger.info("Disconnect-Request with mismatching Acct-Session-Id") req = radius_das.DisconnectPacket(dict=dict, secret="secret", Acct_Session_Id="12345678-87654321", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503) logger.info("Disconnect-Request with mismatching Acct-Session-Id (len)") req = radius_das.DisconnectPacket(dict=dict, secret="secret", Acct_Session_Id="12345678", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503) logger.info("Disconnect-Request with mismatching Acct-Multi-Session-Id") req = radius_das.DisconnectPacket( dict=dict, secret="secret", Acct_Multi_Session_Id="12345678+87654321", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503) logger.info( "Disconnect-Request with mismatching Acct-Multi-Session-Id (len)") req = radius_das.DisconnectPacket(dict=dict, secret="secret", Acct_Multi_Session_Id="12345678", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503) logger.info("Disconnect-Request with no session identification attributes") req = radius_das.DisconnectPacket(dict=dict, secret="secret", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503) ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) if ev is not None: raise Exception("Unexpected disconnection") logger.info("Disconnect-Request with mismatching NAS-IP-Address") req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_IP_Address="192.168.3.4", Acct_Session_Id=id, Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 403) logger.info("Disconnect-Request with mismatching NAS-Identifier") req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_Identifier="unknown.example.com", Acct_Session_Id=id, Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 403) ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) if ev is not None: raise Exception("Unexpected disconnection") logger.info("Disconnect-Request with matching Acct-Session-Id") req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_IP_Address="127.0.0.1", NAS_Identifier="nas.example.com", Acct_Session_Id=id, Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) dev[0].wait_disconnected(timeout=10) dev[0].wait_connected(timeout=10, error="Re-connection timed out") logger.info("Disconnect-Request with matching Acct-Multi-Session-Id") sta = hapd.get_sta(addr) multi_sess_id = sta['authMultiSessionId'] req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_IP_Address="127.0.0.1", NAS_Identifier="nas.example.com", Acct_Multi_Session_Id=multi_sess_id, Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) dev[0].wait_disconnected(timeout=10) dev[0].wait_connected(timeout=10, error="Re-connection timed out") logger.info("Disconnect-Request with matching User-Name") req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_Identifier="nas.example.com", User_Name="*****@*****.**", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) dev[0].wait_disconnected(timeout=10) dev[0].wait_connected(timeout=10, error="Re-connection timed out") logger.info("Disconnect-Request with matching Calling-Station-Id") req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_IP_Address="127.0.0.1", Calling_Station_Id=addr, Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) dev[0].wait_disconnected(timeout=10) ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", "CTRL-EVENT-CONNECTED"]) if ev is None: raise Exception("Timeout while waiting for re-connection") if "CTRL-EVENT-EAP-STARTED" not in ev: raise Exception( "Unexpected skipping of EAP authentication in reconnection") dev[0].wait_connected(timeout=10, error="Re-connection timed out") logger.info( "Disconnect-Request with matching Calling-Station-Id and non-matching CUI" ) req = radius_das.DisconnectPacket( dict=dict, secret="secret", Calling_Station_Id=addr, Chargeable_User_Identity="*****@*****.**", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, error_cause=503) logger.info("Disconnect-Request with matching CUI") dev[1].connect("radius-das", key_mgmt="WPA-EAP", eap="GPSK", identity="gpsk-cui", password="******", scan_freq="2412") req = radius_das.DisconnectPacket( dict=dict, secret="secret", Chargeable_User_Identity="gpsk-chargeable-user-identity", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) dev[1].wait_disconnected(timeout=10) dev[1].wait_connected(timeout=10, error="Re-connection timed out") ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) if ev is not None: raise Exception("Unexpected disconnection") connect(dev[2], "radius-das") logger.info( "Disconnect-Request with matching User-Name - multiple sessions matching" ) req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_Identifier="nas.example.com", User_Name="*****@*****.**", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, error_cause=508) logger.info( "Disconnect-Request with User-Name matching multiple sessions, Calling-Station-Id only one" ) req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_Identifier="nas.example.com", Calling_Station_Id=addr, User_Name="*****@*****.**", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) dev[0].wait_disconnected(timeout=10) dev[0].wait_connected(timeout=10, error="Re-connection timed out") ev = dev[2].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1) if ev is not None: raise Exception("Unexpected disconnection") logger.info( "Disconnect-Request with matching Acct-Multi-Session-Id after disassociation" ) sta = hapd.get_sta(addr) multi_sess_id = sta['authMultiSessionId'] dev[0].request("DISCONNECT") dev[0].wait_disconnected(timeout=10) req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_IP_Address="127.0.0.1", NAS_Identifier="nas.example.com", Acct_Multi_Session_Id=multi_sess_id, Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) dev[0].request("RECONNECT") ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15) if ev is None: raise Exception("Timeout on EAP start") dev[0].wait_connected(timeout=15) logger.info( "Disconnect-Request with matching User-Name after disassociation") dev[0].request("DISCONNECT") dev[0].wait_disconnected(timeout=10) dev[2].request("DISCONNECT") dev[2].wait_disconnected(timeout=10) req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_IP_Address="127.0.0.1", NAS_Identifier="nas.example.com", User_Name="*****@*****.**", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) logger.info("Disconnect-Request with matching CUI after disassociation") dev[1].request("DISCONNECT") dev[1].wait_disconnected(timeout=10) req = radius_das.DisconnectPacket( dict=dict, secret="secret", NAS_IP_Address="127.0.0.1", NAS_Identifier="nas.example.com", Chargeable_User_Identity="gpsk-chargeable-user-identity", Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) logger.info( "Disconnect-Request with matching Calling-Station-Id after disassociation" ) dev[0].request("RECONNECT") ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15) if ev is None: raise Exception("Timeout on EAP start") dev[0].wait_connected(timeout=15) dev[0].request("DISCONNECT") dev[0].wait_disconnected(timeout=10) req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_IP_Address="127.0.0.1", NAS_Identifier="nas.example.com", Calling_Station_Id=addr, Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectACK) logger.info( "Disconnect-Request with mismatching Calling-Station-Id after disassociation" ) req = radius_das.DisconnectPacket(dict=dict, secret="secret", NAS_IP_Address="127.0.0.1", NAS_Identifier="nas.example.com", Calling_Station_Id=addr, Event_Timestamp=int(time.time())) send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, error_cause=503)
def test_radius_psk(dev, apdev): """WPA2 with PSK from RADIUS""" try: import pyrad.server import pyrad.packet import pyrad.dictionary except ImportError: raise HwsimSkip("No pyrad modules available") class TestServer(pyrad.server.Server): def _HandleAuthPacket(self, pkt): pyrad.server.Server._HandleAuthPacket(self, pkt) logger.info("Received authentication request") reply = self.CreateReplyPacket(pkt) reply.code = pyrad.packet.AccessAccept a = "\xab\xcd" secret = reply.secret if self.t_events['long'].is_set(): p = b'\x10' + "0123456789abcdef" + 15 * b'\x00' b = hashlib.md5(secret + pkt.authenticator + a).digest() pp = bytearray(p[0:16]) bb = bytearray(b) cc = bytearray(pp[i] ^ bb[i] for i in range(len(bb))) b = hashlib.md5(reply.secret + bytes(cc)).digest() pp = bytearray(p[16:32]) bb = bytearray(b) cc += bytearray(pp[i] ^ bb[i] for i in range(len(bb))) data = '\x00' + a + bytes(cc) else: p = b'\x08' + "12345678" + 7 * b'\x00' b = hashlib.md5(secret + pkt.authenticator + a).digest() pp = bytearray(p) bb = bytearray(b) cc = bytearray(pp[i] ^ bb[i] for i in range(len(bb))) data = '\x00' + a + bytes(cc) reply.AddAttribute("Tunnel-Password", data) self.SendReplyPacket(pkt.fd, reply) def RunWithStop(self, t_events): self._poll = select.poll() self._fdmap = {} self._PrepareSockets() self.t_events = t_events while not t_events['stop'].is_set(): for (fd, event) in self._poll.poll(1000): if event == select.POLLIN: try: fdo = self._fdmap[fd] self._ProcessInput(fdo) except ServerPacketError as err: logger.info("pyrad server dropping packet: " + str(err)) except pyrad.packet.PacketError as err: logger.info( "pyrad server received invalid packet: " + str(err)) else: logger.error( "Unexpected event in pyrad server main loop") srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"), authport=18138, acctport=18139) srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1", "radius", "localhost") srv.BindToAddress("") t_events = {} t_events['stop'] = threading.Event() t_events['long'] = threading.Event() t = threading.Thread(target=run_pyrad_server, args=(srv, t_events)) t.start() try: ssid = "test-wpa2-psk" params = hostapd.radius_params() params['ssid'] = ssid params["wpa"] = "2" params["wpa_key_mgmt"] = "WPA-PSK" params["rsn_pairwise"] = "CCMP" params['macaddr_acl'] = '2' params['wpa_psk_radius'] = '2' params['auth_server_port'] = "18138" hapd = hostapd.add_ap(apdev[0]['ifname'], params) dev[0].connect(ssid, psk="12345678", scan_freq="2412") t_events['long'].set() dev[1].connect(ssid, psk="0123456789abcdef", scan_freq="2412") finally: t_events['stop'].set() t.join()