]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
tests: DPP GAS Query error cases with hostapd
authorJouni Malinen <j@w1.fi>
Sun, 21 Mar 2021 11:18:00 +0000 (13:18 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 21 Mar 2021 14:33:41 +0000 (16:33 +0200)
Signed-off-by: Jouni Malinen <j@w1.fi>
tests/hwsim/test_dpp.py

index f96e378e34985989499855512f1beb1cb50e1fe9..b19e3a32807c8af6398fb2fe340c5fbe2554f685 100644 (file)
@@ -2682,16 +2682,306 @@ def test_dpp_hostapd_enrollee_gas_timeout(dev, apdev):
     dev[0].set("ext_mgmt_frame_handling", "1")
     dev[0].dpp_listen(2437, role="configurator")
     hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0])
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if "result=TIMEOUT" not in ev:
+        raise Exception("GAS timeout not reported")
 
-    for i in range(3):
-        msg = dev[0].mgmt_rx()
+def test_dpp_hostapd_enrollee_gas_timeout_comeback(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS timeout during comeback"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=4)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if "result=TIMEOUT" not in ev:
+        raise Exception("GAS timeout not reported")
+
+def process_dpp_frames(dev, count=3):
+    for i in range(count):
+        msg = dev.mgmt_rx()
         cmd = "MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())
-        if "OK" not in dev[0].request(cmd):
+        if "OK" not in dev.request(cmd):
             raise Exception("MGMT_RX_PROCESS failed")
+
+def test_dpp_hostapd_enrollee_gas_errors(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS query local errors"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+
+    # GAS without comeback
+    tests = [(1, "gas_query_append;gas_query_rx_initial", 3, True),
+             (1, "gas_query_rx_initial", 3, True),
+             (1, "gas_query_tx_initial_req", 2, True),
+             (1, "gas_query_ap_req", 2, False)]
+    for count, func, frame_count, wait_ev in tests:
+        dev[0].request("DPP_STOP_LISTEN")
+        dev[0].dpp_listen(2437, role="configurator")
+        dev[0].dump_monitor()
+        hapd.dump_monitor()
+        with alloc_fail(hapd, count, func):
+            hapd.dpp_auth_init(uri=uri0, role="enrollee")
+            process_dpp_frames(dev[0], count=frame_count)
+            if wait_ev:
+                ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+                if not ev or "result=INTERNAL_ERROR" not in ev:
+                    raise Exception("Unexpect GAS query result: " + str(ev))
+
+    # GAS with comeback
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+
+    tests = [(1, "gas_query_append;gas_query_rx_comeback", 4),
+             (1, "wpabuf_alloc;gas_query_tx_comeback_req", 3),
+             (1, "hostapd_drv_send_action;gas_query_tx_comeback_req", 3)]
+    for count, func, frame_count in tests:
+        dev[0].request("DPP_STOP_LISTEN")
+        dev[0].dpp_listen(2437, role="configurator")
+        dev[0].dump_monitor()
+        hapd.dump_monitor()
+        with alloc_fail(hapd, count, func):
+            hapd.dpp_auth_init(uri=uri0, role="enrollee")
+            process_dpp_frames(dev[0], count=frame_count)
+            ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+            if not ev or "result=INTERNAL_ERROR" not in ev:
+                raise Exception("Unexpect GAS query result: " + str(ev))
+
+def test_dpp_hostapd_enrollee_gas_proto(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS query protocol testing"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    bssid = hapd.own_addr()
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
+    # GAS: Advertisement Protocol changed between initial and comeback response from 02:00:00:00:00:00
+    adv_proto = "6c087fdd05506f9a1a02"
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=PEER_ERROR" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    # Another comeback delay
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 1)
+    adv_proto = "6c087fdd05506f9a1a01"
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    msg = dev[0].mgmt_rx()
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 1)
+    # GAS: Invalid comeback response with non-zero frag_id and comeback_delay from 02:00:00:00:00:00
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=PEER_ERROR" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    # Valid comeback response
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    msg = dev[0].mgmt_rx()
+    # GAS: Drop frame as possible retry of previous fragment
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Unexpected frag_id in response from 02:00:00:00:00:00
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x82, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=PEER_ERROR" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    # GAS: Unexpected initial response from 02:00:00:00:00:00 dialog token 3 when waiting for comeback response
+    hdr = struct.pack('<BBBHBH', 4, 11, dialog_token, 0, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Allow non-zero status for outstanding comeback response
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 95, 0x80, 0)
+    # GAS: Ignore 1 octets of extra data after Query Response from 02:00:00:00:00:00
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001" + "ff"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: No pending query found for 02:00:00:00:00:00 dialog token 4
+    hdr = struct.pack('<BBBHBH', 4, 13, (dialog_token + 1) % 256, 0, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Truncated Query Response in response from 02:00:00:00:00:00
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "0010"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: No room for GAS Response Length
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "03"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Unexpected Advertisement Protocol element ID 0 in response from 02:00:00:00:00:00
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
+    adv_proto_broken = "0000"
+    action = binascii.hexlify(hdr).decode() + adv_proto_broken + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: No room for Advertisement Protocol element in the response from 02:00:00:00:00:00
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x81, 0)
+    adv_proto_broken = "00ff"
+    action = binascii.hexlify(hdr).decode() + adv_proto_broken + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # No room for Comeback Delay
+    hdr = struct.pack('<BBBHBB', 4, 13, dialog_token, 0, 0x81, 0)
+    action = binascii.hexlify(hdr).decode()
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # No room for frag_id
+    hdr = struct.pack('<BBBH', 4, 13, dialog_token, 0)
+    action = binascii.hexlify(hdr).decode()
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Query to 02:00:00:00:00:00 dialog token 3 failed - status code 1
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 1, 0x81, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=FAILURE" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=2)
+    msg = dev[0].mgmt_rx()
+    payload = msg['payload']
+    dialog_token, = struct.unpack('B', payload[2:3])
+    # Unexpected comeback delay
+    hdr = struct.pack('<BBBHBH', 4, 13, dialog_token, 0, 0x80, 0)
+    adv_proto = "6c087fdd05506f9a1a01"
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    # GAS: Query to 02:00:00:00:00:00 dialog token 3 failed - status code 1
+    hdr = struct.pack('<BBBHBH', 4, 11, dialog_token, 1, 0x80, 0)
+    action = binascii.hexlify(hdr).decode() + adv_proto + "0300" + "001001"
+    cmd = "MGMT_TX %s %s freq=2437 wait_time=100 action=%s" % (bssid, bssid, action)
+    dev[0].request(cmd)
+    ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
+    if not ev or "result=FAILURE" not in ev:
+        raise Exception("Unexpect GAS query result: " + str(ev))
+    dev[0].request("DPP_STOP_LISTEN")
+    hapd.dump_monitor()
+    dev[0].dump_monitor()
+
+def test_dpp_hostapd_enrollee_gas_tx_status_errors(dev, apdev):
+    """DPP and hostapd as Enrollee with GAS TX status errors"""
+    check_dpp_capab(dev[0])
+    hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured",
+                                     "channel": "6"})
+    check_dpp_capab(hapd)
+    conf_id = dev[0].dpp_configurator_add()
+    id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True)
+    uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0)
+    conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' '
+    dev[0].set("dpp_config_obj_override", conf)
+    dev[0].set("dpp_configurator_params",
+               "conf=ap-dpp configurator=%d" % conf_id)
+    dev[0].set("ext_mgmt_frame_handling", "1")
+    dev[0].dpp_listen(2437, role="configurator")
+    hapd.dpp_auth_init(uri=uri0, role="enrollee")
+    process_dpp_frames(dev[0], count=3)
+
+    hapd.set("ext_mgmt_frame_handling", "1")
+    # GAS: TX status for unexpected destination
+    frame = "d0003a01" + "222222222222"
+    frame += hapd.own_addr().replace(':', '') + "ffffffffffff"
+    frame += "5000" + "040a"
+    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=1 buf=" + frame)
+
+    # GAS: No ACK to GAS request
+    frame = "d0003a01" + dev[0].own_addr().replace(':', '')
+    frame += hapd.own_addr().replace(':', '') + "ffffffffffff"
+    frame += "5000" + "040a"
+    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=0 buf=" + frame)
+
     ev = hapd.wait_event(["GAS-QUERY-DONE"], timeout=10)
     if "result=TIMEOUT" not in ev:
         raise Exception("GAS timeout not reported")
 
+    # GAS: Unexpected TX status: dst=02:00:00:00:00:00 ok=1 - no query in progress
+    hapd.request("MGMT_TX_STATUS_PROCESS stype=13 ok=1 buf=" + frame)
+    hapd.set("ext_mgmt_frame_handling", "0")
+
 def test_dpp_hostapd_configurator_override_objects(dev, apdev):
     """DPP with hostapd as configurator and override objects"""
     check_dpp_capab(dev[0])