]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - tests/hwsim/test_wpas_ap.py
tests: Transition disable
[thirdparty/hostap.git] / tests / hwsim / test_wpas_ap.py
index 8cd09f04cd8b64699601ba62b6432d3d28405873..8211b6b8d32349a7c1dfebd6a068724594fa480d 100644 (file)
@@ -4,15 +4,17 @@
 # This software may be distributed under the terms of the BSD license.
 # See README for more details.
 
+import hostapd
 from remotehost import remote_compatible
 import time
 import logging
 logger = logging.getLogger()
 
 import hwsim_utils
-from utils import HwsimSkip, alloc_fail
+from utils import HwsimSkip, alloc_fail, clear_regdom_dev
 from wpasupplicant import WpaSupplicant
 from test_p2p_channel import set_country
+from test_wep import check_wep_capa
 
 def wait_ap_ready(dev):
     ev = dev.wait_event(["CTRL-EVENT-CONNECTED"])
@@ -49,7 +51,7 @@ def test_wpas_ap_open(dev):
 
     addr1 = dev[1].p2p_interface_addr()
     addr2 = dev[2].p2p_interface_addr()
-    addrs = [ addr1, addr2 ]
+    addrs = [addr1, addr2]
     sta = dev[0].get_sta(None)
     if sta['addr'] not in addrs:
         raise Exception("Unexpected STA address")
@@ -78,9 +80,32 @@ def test_wpas_ap_open(dev):
     dev[1].request("DISCONNECT")
     dev[2].request("DISCONNECT")
 
+def test_wpas_ap_open_isolate(dev):
+    """wpa_supplicant AP mode - open network with client isolation"""
+    try:
+        dev[0].set("ap_isolate", "1")
+        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", "2412")
+        dev[0].set_network(id, "scan_freq", "2412")
+        dev[0].select_network(id)
+        wait_ap_ready(dev[0])
+
+        dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
+        dev[2].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
+        hwsim_utils.test_connectivity(dev[0], dev[1])
+        hwsim_utils.test_connectivity(dev[0], dev[2])
+        hwsim_utils.test_connectivity(dev[1], dev[2], success_expected=False,
+                                      timeout=1)
+    finally:
+        dev[0].set("ap_isolate", "0")
+
 @remote_compatible
 def test_wpas_ap_wep(dev):
     """wpa_supplicant AP mode - WEP"""
+    check_wep_capa(dev[0])
     id = dev[0].add_network()
     dev[0].set_network(id, "mode", "2")
     dev[0].set_network_quoted(id, "ssid", "wpas-ap-wep")
@@ -360,6 +385,9 @@ def _test_wpas_ap_dfs(dev):
         raise Exception("AP failed to start")
 
     dev[1].connect("wpas-ap-dfs", key_mgmt="NONE")
+    dev[1].wait_regdom(country_ie=True)
+    dev[0].request("DISCONNECT")
+    dev[1].disconnect_and_stop_scan()
 
 @remote_compatible
 def test_wpas_ap_disable(dev):
@@ -470,7 +498,7 @@ def test_wpas_ap_failures(dev):
     dev[0].set_network(id, "frequency", "2412")
     dev[0].set_network(id, "scan_freq", "2412")
     dev[0].select_network(id)
-    ev = dev[0].wait_event([ "CTRL-EVENT-CONNECTED" ], timeout=0.1)
+    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
     if ev is not None:
         raise Exception("Unexpected connection event")
     dev[0].request("REMOVE_NETWORK all")
@@ -485,8 +513,8 @@ def test_wpas_ap_failures(dev):
     dev[0].set_network(id, "scan_freq", "2412")
     dev[0].set_network(id, "pbss", "2")
     dev[0].select_network(id)
-    ev = dev[0].wait_event([ "CTRL-EVENT-CONNECTED",
-                             "CTRL-EVENT-DISCONNECTED" ], timeout=0.1)
+    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+                            "CTRL-EVENT-DISCONNECTED"], timeout=0.1)
     if ev is not None and "CTRL-EVENT-CONNECTED" in ev:
         raise Exception("Unexpected connection event(2)")
     dev[0].request("REMOVE_NETWORK all")
@@ -515,17 +543,18 @@ def test_wpas_ap_oom(dev):
         dev[0].wait_disconnected()
     dev[0].request("REMOVE_NETWORK all")
 
-    id = dev[0].add_network()
-    dev[0].set_network(id, "mode", "2")
-    dev[0].set_network_quoted(id, "ssid", "wpas-ap")
-    dev[0].set_network(id, "key_mgmt", "NONE")
-    dev[0].set_network_quoted(id, "wep_key0", "hello")
-    dev[0].set_network(id, "frequency", "2412")
-    dev[0].set_network(id, "scan_freq", "2412")
-    with alloc_fail(dev[0], 1, "=wpa_supplicant_conf_ap"):
-        dev[0].select_network(id)
-        dev[0].wait_disconnected()
-    dev[0].request("REMOVE_NETWORK all")
+    if "WEP40" in dev[0].get_capability("group"):
+        id = dev[0].add_network()
+        dev[0].set_network(id, "mode", "2")
+        dev[0].set_network_quoted(id, "ssid", "wpas-ap")
+        dev[0].set_network(id, "key_mgmt", "NONE")
+        dev[0].set_network_quoted(id, "wep_key0", "hello")
+        dev[0].set_network(id, "frequency", "2412")
+        dev[0].set_network(id, "scan_freq", "2412")
+        with alloc_fail(dev[0], 1, "=wpa_supplicant_conf_ap"):
+            dev[0].select_network(id)
+            dev[0].wait_disconnected()
+        dev[0].request("REMOVE_NETWORK all")
 
     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
     wpas.interface_add("wlan5")
@@ -546,8 +575,8 @@ def test_wpas_ap_oom(dev):
     for i in range(5):
         with alloc_fail(wpas, i, "=wpa_supplicant_conf_ap"):
             wpas.select_network(id)
-            ev = dev[0].wait_event([ "CTRL-EVENT-CONNECTED",
-                                     "CTRL-EVENT-DISCONNECTED" ], timeout=1)
+            ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
+                                    "CTRL-EVENT-DISCONNECTED"], timeout=1)
         wpas.request("DISCONNECT")
         wpas.wait_disconnected()
 
@@ -590,3 +619,288 @@ def test_wpas_ap_params(dev):
         raise Exception("PMKSA_FLUSH failed")
     wpas.request("DISCONNECT")
     wpas.wait_disconnected()
+
+def test_wpas_ap_global_sta(dev):
+    """wpa_supplicant AP mode - STA commands on global control interface"""
+    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", "2412")
+    dev[0].set_network(id, "scan_freq", "2412")
+    dev[0].select_network(id)
+    wait_ap_ready(dev[0])
+
+    dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
+
+    addr1 = dev[1].own_addr()
+    res = dev[0].global_request("STA " + addr1)
+    if "UNKNOWN COMMAND" in res:
+        raise Exception("STA command not known on global control interface")
+    res = dev[0].global_request("STA-FIRST")
+    if "UNKNOWN COMMAND" in res:
+        raise Exception("STA-FIRST command not known on global control interface")
+    res = dev[0].global_request("STA-NEXT " + addr1)
+    if "UNKNOWN COMMAND" in res:
+        raise Exception("STA-NEXT command not known on global control interface")
+    dev[1].request("DISCONNECT")
+    dev[1].wait_disconnected()
+    dev[0].request("DISCONNECT")
+    dev[0].wait_disconnected()
+
+def test_wpas_ap_5ghz(dev):
+    """wpa_supplicant AP mode - 5 GHz"""
+    try:
+        _test_wpas_ap_5ghz(dev)
+    finally:
+        set_country("00")
+        dev[0].request("SET country 00")
+        dev[1].flush_scan_cache()
+
+def _test_wpas_ap_5ghz(dev):
+    set_country("US")
+    dev[0].request("SET country US")
+    id = dev[0].add_network()
+    dev[0].set_network(id, "mode", "2")
+    dev[0].set_network_quoted(id, "ssid", "wpas-ap-5ghz")
+    dev[0].set_network(id, "key_mgmt", "NONE")
+    dev[0].set_network(id, "frequency", "5180")
+    dev[0].set_network(id, "scan_freq", "5180")
+    dev[0].select_network(id)
+    wait_ap_ready(dev[0])
+
+    dev[1].connect("wpas-ap-5ghz", key_mgmt="NONE", scan_freq="5180")
+    dev[1].request("DISCONNECT")
+    dev[1].wait_disconnected()
+
+def test_wpas_ap_open_vht80(dev):
+    """wpa_supplicant AP mode - VHT 80 MHz"""
+    id = dev[0].add_network()
+    dev[0].set("country", "FI")
+    try:
+        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", "5180")
+        dev[0].set_network(id, "scan_freq", "5180")
+        dev[0].set_network(id, "vht", "1")
+        dev[0].set_network(id, "vht_center_freq1", "5210")
+        dev[0].set_network(id, "max_oper_chwidth", "1")
+        dev[0].set_network(id, "ht40", "1")
+        dev[0].select_network(id)
+        wait_ap_ready(dev[0])
+
+        dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="5180")
+        sig = dev[1].request("SIGNAL_POLL").splitlines()
+        hwsim_utils.test_connectivity(dev[0], dev[1])
+        dev[1].request("DISCONNECT")
+        dev[1].wait_disconnected()
+        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))
+    finally:
+        set_country("00")
+        dev[0].set("country", "00")
+        dev[1].flush_scan_cache()
+
+def test_wpas_ap_no_ht(dev):
+    """wpa_supplicant AP mode - HT disabled"""
+    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", "2412")
+    dev[0].set_network(id, "scan_freq", "2412")
+    dev[0].set_network(id, "ht", "0")
+    dev[0].set_network(id, "wps_disabled", "1")
+    dev[0].select_network(id)
+    wait_ap_ready(dev[0])
+    dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
+    sig = dev[1].request("SIGNAL_POLL").splitlines()
+    dev[1].request("DISCONNECT")
+    dev[1].wait_disconnected()
+    dev[0].request("REMOVE_NETWORK all")
+    dev[0].wait_disconnected()
+
+    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", "2412")
+    dev[0].set_network(id, "scan_freq", "2412")
+    dev[0].set_network(id, "wps_disabled", "1")
+    dev[0].select_network(id)
+    wait_ap_ready(dev[0])
+    dev[1].flush_scan_cache()
+    dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
+    sig2 = dev[1].request("SIGNAL_POLL").splitlines()
+    dev[1].request("DISCONNECT")
+    dev[1].wait_disconnected()
+    dev[0].request("REMOVE_NETWORK all")
+    dev[0].wait_disconnected()
+
+    if "WIDTH=20 MHz (no HT)" not in sig:
+        raise Exception("HT was not disabled: " + str(sig))
+    if "WIDTH=20 MHz" not in sig2:
+        raise Exception("HT was not enabled: " + str(sig2))
+
+def test_wpas_ap_async_fail(dev):
+    """wpa_supplicant AP mode - Async failure"""
+    id = dev[0].add_network()
+    dev[0].set("country", "FI")
+    try:
+        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", "5180")
+        dev[0].set_network(id, "scan_freq", "5180")
+        dev[0].set_network(id, "vht", "1")
+        dev[0].set_network(id, "vht_center_freq1", "5210")
+        dev[0].set_network(id, "max_oper_chwidth", "1")
+        dev[0].set_network(id, "ht40", "1")
+
+        with alloc_fail(dev[0], 1,
+                        "nl80211_get_scan_results;ieee80211n_check_scan"):
+            dev[0].select_network(id)
+            dev[0].wait_disconnected()
+    finally:
+        clear_regdom_dev(dev)
+
+def test_wpas_ap_sae(dev):
+    """wpa_supplicant AP mode - SAE using psk"""
+    run_wpas_ap_sae(dev, False)
+
+def test_wpas_ap_sae_password(dev):
+    """wpa_supplicant AP mode - SAE using sae_password"""
+    run_wpas_ap_sae(dev, True)
+
+def test_wpas_ap_sae_pwe_1(dev):
+    """wpa_supplicant AP mode - SAE using sae_password and sae_pwe=1"""
+    try:
+        dev[0].set("sae_pwe", "1")
+        dev[1].set("sae_pwe", "1")
+        run_wpas_ap_sae(dev, True, sae_password_id=True)
+    finally:
+        dev[0].set("sae_pwe", "0")
+        dev[1].set("sae_pwe", "0")
+
+def run_wpas_ap_sae(dev, sae_password, sae_password_id=False):
+    if "SAE" not in dev[0].get_capability("auth_alg"):
+        raise HwsimSkip("SAE not supported")
+    if "SAE" not in dev[1].get_capability("auth_alg"):
+        raise HwsimSkip("SAE not supported")
+    dev[0].request("SET sae_groups ")
+    id = dev[0].add_network()
+    dev[0].set_network(id, "mode", "2")
+    dev[0].set_network_quoted(id, "ssid", "wpas-ap-sae")
+    dev[0].set_network(id, "proto", "WPA2")
+    dev[0].set_network(id, "key_mgmt", "SAE")
+    dev[0].set_network(id, "pairwise", "CCMP")
+    dev[0].set_network(id, "group", "CCMP")
+    if sae_password:
+        dev[0].set_network_quoted(id, "sae_password", "12345678")
+    else:
+        dev[0].set_network_quoted(id, "psk", "12345678")
+    if sae_password_id:
+        pw_id = "pw id"
+        dev[0].set_network_quoted(id, "sae_password_id", pw_id)
+    else:
+        pw_id = None
+    dev[0].set_network(id, "frequency", "2412")
+    dev[0].set_network(id, "scan_freq", "2412")
+    dev[0].set_network(id, "wps_disabled", "1")
+    dev[0].select_network(id)
+    wait_ap_ready(dev[0])
+
+    dev[1].request("SET sae_groups ")
+    dev[1].connect("wpas-ap-sae", key_mgmt="SAE", sae_password="12345678",
+                   sae_password_id=pw_id, scan_freq="2412")
+
+def test_wpas_ap_scan(dev, apdev):
+    """wpa_supplicant AP mode and scanning"""
+    dev[0].flush_scan_cache()
+
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
+    bssid = hapd.own_addr()
+
+    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", "2412")
+    dev[0].set_network(id, "scan_freq", "2412")
+    dev[0].select_network(id)
+    wait_ap_ready(dev[0])
+    dev[0].dump_monitor()
+
+    if "OK" not in dev[0].request("SCAN freq=2412"):
+        raise Exception("SCAN command not accepted")
+    ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS",
+                            "CTRL-EVENT-SCAN-FAILED"], 15)
+    if ev is None:
+        raise Exception("Scan result timed out")
+    if "CTRL-EVENT-SCAN-FAILED ret=-95" in ev:
+        # Scanning in AP mode not supported
+        return
+    if "CTRL-EVENT-SCAN-FAILED" in ev:
+        raise Exception("Unexpected scan failure reason: " + ev)
+    if "CTRL-EVENT-SCAN-RESULTS" in ev:
+        bss = dev[0].get_bss(bssid)
+        if not bss:
+            raise Exception("AP not found in scan")
+
+def test_wpas_ap_sae(dev):
+    """wpa_supplicant AP mode - SAE using psk"""
+    run_wpas_ap_sae(dev, False)
+
+def test_wpas_ap_sae_and_psk_transition_disable(dev):
+    """wpa_supplicant AP mode - SAE+PSK transition disable indication"""
+    if "SAE" not in dev[0].get_capability("auth_alg"):
+        raise HwsimSkip("SAE not supported")
+    if "SAE" not in dev[1].get_capability("auth_alg"):
+        raise HwsimSkip("SAE not supported")
+    dev[0].set("sae_groups", "")
+    id = dev[0].add_network()
+    dev[0].set_network(id, "mode", "2")
+    dev[0].set_network_quoted(id, "ssid", "wpas-ap-sae")
+    dev[0].set_network(id, "proto", "WPA2")
+    dev[0].set_network(id, "key_mgmt", "SAE")
+    dev[0].set_network(id, "transition_disable", "1")
+    dev[0].set_network(id, "ieee80211w", "1")
+    dev[0].set_network(id, "pairwise", "CCMP")
+    dev[0].set_network(id, "group", "CCMP")
+    dev[0].set_network_quoted(id, "psk", "12345678")
+    dev[0].set_network(id, "frequency", "2412")
+    dev[0].set_network(id, "scan_freq", "2412")
+    dev[0].set_network(id, "wps_disabled", "1")
+    dev[0].select_network(id)
+    wait_ap_ready(dev[0])
+
+    dev[1].set("sae_groups", "")
+    dev[1].connect("wpas-ap-sae", key_mgmt="SAE WPA-PSK",
+                   psk="12345678", ieee80211w="1",
+                   scan_freq="2412")
+    ev = dev[1].wait_event(["TRANSITION-DISABLE"], timeout=1)
+    if ev is None:
+        raise Exception("Transition disable not indicated")
+    if ev.split(' ')[1] != "01":
+        raise Exception("Unexpected transition disable bitmap: " + ev)
+
+    val = dev[1].get_network(id, "ieee80211w")
+    if val != "2":
+        raise Exception("Unexpected ieee80211w value: " + val)
+    val = dev[1].get_network(id, "key_mgmt")
+    if val != "SAE":
+        raise Exception("Unexpected key_mgmt value: " + val)
+    val = dev[1].get_network(id, "group")
+    if val != "CCMP":
+        raise Exception("Unexpected group value: " + val)
+    val = dev[1].get_network(id, "proto")
+    if val != "RSN":
+        raise Exception("Unexpected proto value: " + val)
+
+    dev[1].request("DISCONNECT")
+    dev[1].wait_disconnected()
+    dev[1].request("RECONNECT")
+    dev[1].wait_connected()