1# hostapd configuration tests
2# Copyright (c) 2014-2016, Jouni Malinen <j@w1.fi>
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7import os
8import signal
9import time
10import logging
11logger = logging.getLogger(__name__)
12import subprocess
13
14from remotehost import remote_compatible
15import hostapd
16from utils import alloc_fail, fail_test
17
18@remote_compatible
19def test_ap_config_errors(dev, apdev):
20    """Various hostapd configuration errors"""
21
22    # IEEE 802.11d without country code
23    params = {"ssid": "foo", "ieee80211d": "1"}
24    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
25    if "FAIL" not in hapd.request("ENABLE"):
26        raise Exception("Unexpected ENABLE success (ieee80211d without country_code)")
27    hostapd.remove_bss(apdev[0])
28
29    # IEEE 802.11h without IEEE 802.11d
30    params = {"ssid": "foo", "ieee80211h": "1"}
31    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
32    if "FAIL" not in hapd.request("ENABLE"):
33        raise Exception("Unexpected ENABLE success (ieee80211h without ieee80211d")
34    hostapd.remove_bss(apdev[0])
35
36    # Power Constraint without IEEE 802.11d
37    params = {"ssid": "foo", "local_pwr_constraint": "1"}
38    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
39    if "FAIL" not in hapd.request("ENABLE"):
40        raise Exception("Unexpected ENABLE success (local_pwr_constraint without ieee80211d)")
41    hostapd.remove_bss(apdev[0])
42
43    # Spectrum management without Power Constraint
44    params = {"ssid": "foo", "spectrum_mgmt_required": "1"}
45    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
46    if "FAIL" not in hapd.request("ENABLE"):
47        raise Exception("Unexpected ENABLE success (spectrum_mgmt_required without local_pwr_constraint)")
48    hostapd.remove_bss(apdev[0])
49
50    # IEEE 802.1X without authentication server
51    params = {"ssid": "foo", "ieee8021x": "1"}
52    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
53    if "FAIL" not in hapd.request("ENABLE"):
54        raise Exception("Unexpected ENABLE success (ieee8021x)")
55    hostapd.remove_bss(apdev[0])
56
57    # RADIUS-PSK without macaddr_acl=2
58    params = hostapd.wpa2_params(ssid="foo", passphrase="12345678")
59    params["wpa_psk_radius"] = "1"
60    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
61    if "FAIL" not in hapd.request("ENABLE"):
62        raise Exception("Unexpected ENABLE success (wpa_psk_radius)")
63    hostapd.remove_bss(apdev[0])
64
65    # FT without NAS-Identifier
66    params = {"wpa": "2",
67              "wpa_key_mgmt": "FT-PSK",
68              "rsn_pairwise": "CCMP",
69              "wpa_passphrase": "12345678"}
70    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
71    if "FAIL" not in hapd.request("ENABLE"):
72        raise Exception("Unexpected ENABLE success (FT without nas_identifier)")
73    hostapd.remove_bss(apdev[0])
74
75    # Hotspot 2.0 without WPA2/CCMP
76    params = hostapd.wpa2_params(ssid="foo")
77    params['wpa_key_mgmt'] = "WPA-EAP"
78    params['ieee8021x'] = "1"
79    params['auth_server_addr'] = "127.0.0.1"
80    params['auth_server_port'] = "1812"
81    params['auth_server_shared_secret'] = "radius"
82    params['interworking'] = "1"
83    params['hs20'] = "1"
84    params['wpa'] = "1"
85    hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
86    if "FAIL" not in hapd.request("ENABLE"):
87        raise Exception("Unexpected ENABLE success (HS 2.0 without WPA2/CCMP)")
88    hostapd.remove_bss(apdev[0])
89
90def test_ap_config_reload(dev, apdev, params):
91    """hostapd configuration reload"""
92    hapd = hostapd.add_ap(apdev[0], {"ssid": "foo"})
93    hapd.set("ssid", "foobar")
94    with open(os.path.join(params['logdir'], 'hostapd-test.pid'), "r") as f:
95        pid = int(f.read())
96    os.kill(pid, signal.SIGHUP)
97    time.sleep(0.1)
98    dev[0].connect("foobar", key_mgmt="NONE", scan_freq="2412")
99    hapd.set("ssid", "foo")
100    os.kill(pid, signal.SIGHUP)
101    dev[0].wait_disconnected()
102    dev[0].request("DISCONNECT")
103
104def test_ap_config_reload_file(dev, apdev, params):
105    """hostapd configuration reload from file"""
106    hapd = hostapd.add_iface(apdev[0], "bss-1.conf")
107    hapd.enable()
108    hapd.set("ssid", "foobar")
109    with open(os.path.join(params['logdir'], 'hostapd-test.pid'), "r") as f:
110        pid = int(f.read())
111    os.kill(pid, signal.SIGHUP)
112    time.sleep(0.1)
113    dev[0].connect("foobar", key_mgmt="NONE", scan_freq="2412")
114    hapd.set("ssid", "foo")
115    os.kill(pid, signal.SIGHUP)
116    dev[0].wait_disconnected()
117    dev[0].request("DISCONNECT")
118
119def test_ap_config_reload_file_while_disabled(dev, apdev, params):
120    """hostapd configuration reload from file when disabled"""
121    hapd = hostapd.add_iface(apdev[0], "bss-1.conf")
122    hapd.enable()
123    ev = hapd.wait_event(["AP-ENABLED"], timeout=3)
124    if ev is None:
125        raise Exception("AP-ENABLED event not reported")
126    hapd.set("ssid", "foobar")
127    with open(os.path.join(params['logdir'], 'hostapd-test.pid'), "r") as f:
128        pid = int(f.read())
129    hapd.disable()
130    ev = hapd.wait_event(["AP-DISABLED"], timeout=3)
131    if ev is None:
132        raise Exception("AP-DISABLED event not reported")
133    hapd.dump_monitor()
134    os.kill(pid, signal.SIGHUP)
135    time.sleep(0.1)
136    hapd.enable()
137    dev[0].connect("foobar", key_mgmt="NONE", scan_freq="2412")
138
139def write_hostapd_config(conffile, ifname, ssid, ht=True, bss2=False,
140                         iface_params=None, bss_params=None):
141    with open(conffile, "w") as f:
142        f.write("driver=nl80211\n")
143        f.write("hw_mode=g\n")
144        f.write("channel=1\n")
145        if ht:
146            f.write("ieee80211n=1\n")
147        f.write("interface=" + ifname + "\n")
148        f.write("ssid=" + ssid + "\n")
149        if iface_params:
150            for l in iface_params:
151                f.write(l + "\n")
152        if bss2:
153            f.write("bss=" + ifname + "_2\n")
154            f.write("ssid=" + ssid + "-2\n")
155        if bss_params:
156            for l in bss_params:
157                f.write(l + "\n")
158
159def test_ap_config_reload_on_sighup(dev, apdev, params):
160    """hostapd configuration reload modification from file on SIGHUP"""
161    run_ap_config_reload_on_sighup(dev, apdev, params)
162
163def term_hostapd_pid(pid, pidfile):
164    os.kill(pid, signal.SIGTERM)
165    removed = False
166    for i in range(20):
167        time.sleep(0.1)
168        if not os.path.exists(pidfile):
169            removed = True
170            break
171    if not removed:
172        raise Exception("hostapd PID file not removed on SIGTERM")
173
174def test_ap_config_reload_on_sighup_no_ht(dev, apdev, params):
175    """hostapd configuration reload modification from file on SIGHUP (no HT)"""
176    run_ap_config_reload_on_sighup(dev, apdev, params, ht=False)
177
178def run_ap_config_reload_on_sighup(dev, apdev, params, ht=True):
179    name = "ap_config_reload_on_sighup"
180    if not ht:
181        name += "_no_ht"
182    pidfile = params['prefix'] + ".hostapd.pid"
183    logfile = params['prefix'] + ".hostapd.log"
184    conffile = params['prefix'] + ".hostapd.conf"
185    prg = os.path.join(params['logdir'], 'alt-hostapd/hostapd/hostapd')
186    if not os.path.exists(prg):
187        prg = '../../hostapd/hostapd'
188    write_hostapd_config(conffile, apdev[0]['ifname'], "test-1", ht=ht)
189    cmd = [prg, '-B', '-dddt', '-P', pidfile, '-f', logfile, conffile]
190    res = subprocess.check_call(cmd)
191    if res != 0:
192        raise Exception("Could not start hostapd: %s" % str(res))
193
194    dev[0].connect("test-1", key_mgmt="NONE", scan_freq="2412")
195    dev[0].request("REMOVE_NETWORK all")
196    dev[0].wait_disconnected()
197
198    write_hostapd_config(conffile, apdev[0]['ifname'], "test-2", ht=ht)
199    with open(pidfile, "r") as f:
200        pid = int(f.read())
201    os.kill(pid, signal.SIGHUP)
202
203    time.sleep(0.1)
204    dev[0].flush_scan_cache()
205
206    dev[0].connect("test-2", key_mgmt="NONE", scan_freq="2412")
207    bss = dev[0].get_bss(apdev[0]['bssid'])
208    dev[0].request("REMOVE_NETWORK all")
209    dev[0].wait_disconnected()
210
211    term_hostapd_pid(pid, pidfile)
212
213    if ht and "dd180050f202" not in bss['ie']:
214            raise Exception("Missing WMM IE after reload")
215    if not ht and "dd180050f202" in bss['ie']:
216            raise Exception("Unexpected WMM IE after reload")
217
218def test_ap_config_reload_on_sighup_bss_changes(dev, apdev, params):
219    """hostapd configuration reload modification from file on SIGHUP with bss remove/add"""
220    pidfile = params['prefix'] + ".hostapd.pid"
221    logfile = params['prefix'] + ".hostapd-log"
222    conffile = params['prefix'] + ".hostapd.conf"
223    prg = os.path.join(params['logdir'], 'alt-hostapd/hostapd/hostapd')
224    if not os.path.exists(prg):
225        prg = '../../hostapd/hostapd'
226    write_hostapd_config(conffile, apdev[0]['ifname'], "test", bss2=True)
227    cmd = [prg, '-B', '-dddt', '-P', pidfile, '-f', logfile, conffile]
228    res = subprocess.check_call(cmd)
229    if res != 0:
230        raise Exception("Could not start hostapd: %s" % str(res))
231
232    dev[0].connect("test", key_mgmt="NONE", scan_freq="2412",
233                   wait_connect=False)
234    dev[1].connect("test-2", key_mgmt="NONE", scan_freq="2412")
235    dev[0].wait_connected()
236    dev[0].request("REMOVE_NETWORK all")
237    dev[1].request("REMOVE_NETWORK all")
238    dev[0].wait_disconnected()
239    dev[1].wait_disconnected()
240    dev[0].dump_monitor()
241    dev[1].dump_monitor()
242
243    write_hostapd_config(conffile, apdev[0]['ifname'], "test-a", bss2=False)
244    with open(pidfile, "r") as f:
245        pid = int(f.read())
246    os.kill(pid, signal.SIGHUP)
247
248    time.sleep(0.5)
249    dev[0].flush_scan_cache()
250
251    dev[0].connect("test-a", key_mgmt="NONE", scan_freq="2412")
252    dev[0].request("REMOVE_NETWORK all")
253    dev[0].wait_disconnected()
254    dev[0].dump_monitor()
255
256    write_hostapd_config(conffile, apdev[0]['ifname'], "test-b", bss2=True)
257    os.kill(pid, signal.SIGHUP)
258
259    time.sleep(0.5)
260    dev[0].flush_scan_cache()
261    dev[1].flush_scan_cache()
262
263    dev[0].connect("test-b", key_mgmt="NONE", scan_freq="2412",
264                   wait_connect=False)
265    dev[1].connect("test-b-2", key_mgmt="NONE", scan_freq="2412")
266    dev[0].wait_connected()
267    dev[0].request("REMOVE_NETWORK all")
268    dev[1].request("REMOVE_NETWORK all")
269    dev[0].wait_disconnected()
270    dev[1].wait_disconnected()
271    dev[0].dump_monitor()
272    dev[1].dump_monitor()
273
274    term_hostapd_pid(pid, pidfile)
275
276def test_ap_config_reload_on_sighup_config_id(dev, apdev, params):
277    """hostapd configuration reload when a config_id is provided"""
278    pidfile = params['prefix'] + ".hostapd.pid"
279    logfile = params['prefix'] + ".hostapd.log"
280    conffile = os.path.abspath(params['prefix'] + ".hostapd.conf")
281    prg = os.path.join(params['logdir'], 'alt-hostapd/hostapd/hostapd')
282    if not os.path.exists(prg):
283        prg = '../../hostapd/hostapd'
284    write_hostapd_config(conffile, apdev[0]['ifname'], "test", bss2=False,
285                         iface_params=["config_id=if1"],
286                         bss_params=[f"bss={apdev[0]['ifname']}_2",
287                                     "ssid=test-2", "config_id=bss2"])
288    cmd = [prg, '-B', '-dddt', '-P', pidfile, '-f', logfile, conffile]
289    res = subprocess.check_call(cmd)
290    if res != 0:
291        raise Exception("Could not start hostapd: %s" % str(res))
292    dev[0].connect("test-2", key_mgmt="NONE", scan_freq="2412")
293
294    write_hostapd_config(conffile, apdev[0]['ifname'], "test-a", bss2=False,
295                         iface_params=["config_id=if1-new"],
296                         bss_params=[f"bss={apdev[0]['ifname']}_2",
297                                     "ssid=test-2", "config_id=bss2"])
298
299    with open(pidfile, "r") as f:
300        pid = int(f.read())
301    os.kill(pid, signal.SIGHUP)
302    ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
303    if ev is not None:
304        raise Exception("Unexpected disconnection when config_id was not changed")
305
306    dev[0].request("REMOVE_NETWORK all")
307    dev[0].wait_disconnected()
308    dev[0].dump_monitor()
309    dev[0].connect("test-a", key_mgmt="NONE", scan_freq="2412")
310
311    term_hostapd_pid(pid, pidfile)
312
313def test_ap_config_reload_before_enable(dev, apdev, params):
314    """hostapd configuration reload before enable"""
315    hapd = hostapd.add_iface(apdev[0], "bss-1.conf")
316    with open(os.path.join(params['logdir'], 'hostapd-test.pid'), "r") as f:
317        pid = int(f.read())
318    os.kill(pid, signal.SIGHUP)
319    hapd.ping()
320
321def test_ap_config_sigusr1(dev, apdev, params):
322    """hostapd SIGUSR1"""
323    hapd = hostapd.add_ap(apdev[0], {"ssid": "foobar"})
324    with open(os.path.join(params['logdir'], 'hostapd-test.pid'), "r") as f:
325        pid = int(f.read())
326    os.kill(pid, signal.SIGUSR1)
327    dev[0].connect("foobar", key_mgmt="NONE", scan_freq="2412")
328    os.kill(pid, signal.SIGUSR1)
329
330def test_ap_config_invalid_value(dev, apdev, params):
331    """Ignoring invalid hostapd configuration parameter updates"""
332    hapd = hostapd.add_ap(apdev[0], {"ssid": "test"}, no_enable=True)
333    not_exist = "/tmp/hostapd-test/does-not-exist"
334    tests = [("driver", "foobar"),
335             ("ssid2", "Q"),
336             ("macaddr_acl", "255"),
337             ("accept_mac_file", not_exist),
338             ("deny_mac_file", not_exist),
339             ("eapol_version", "255"),
340             ("eap_user_file", not_exist),
341             ("wep_key_len_broadcast", "-1"),
342             ("wep_key_len_unicast", "-1"),
343             ("wep_rekey_period", "-1"),
344             ("eap_rekey_period", "-1"),
345             ("radius_client_addr", "foo"),
346             ("acs_chan_bias", "-1:0.8"),
347             ("acs_chan_bias", "1"),
348             ("acs_chan_bias", "1:p"),
349             ("acs_chan_bias", "1:-0.8"),
350             ("acs_chan_bias", "1:0.8p"),
351             ("dtim_period", "0"),
352             ("bss_load_update_period", "-1"),
353             ("send_probe_response", "255"),
354             ("beacon_rate", "ht:-1"),
355             ("beacon_rate", "ht:32"),
356             ("beacon_rate", "vht:-1"),
357             ("beacon_rate", "vht:10"),
358             ("beacon_rate", "9"),
359             ("beacon_rate", "10001"),
360             ("vlan_file", not_exist),
361             ("bss", ""),
362             ("bssid", "foo"),
363             ("extra_cred", not_exist),
364             ("anqp_elem", "265"),
365             ("anqp_elem", "265"),
366             ("anqp_elem", "265:1"),
367             ("anqp_elem", "265:1q"),
368             ("fst_priority", ""),
369             ("fils_cache_id", "q"),
370             ("venue_url", "foo"),
371             ("venue_url", "1:" + 255*"a"),
372             ("sae_password", "secret|mac=qq"),
373             ("dpp_controller", "ipaddr=1"),
374             ("dpp_controller", "ipaddr=127.0.0.1 pkhash=q"),
375             ("dpp_controller", "ipaddr=127.0.0.1 pkhash=" + 32*"qq"),
376             ("dpp_controller", "pkhash=" + 32*"aa"),
377             ("check_cert_subject", ""),
378             ("eap_teap_auth", "-1"),
379             ("eap_teap_auth", "100"),
380             ("group_cipher", "foo"),
381             ("group_cipher", "NONE"),
382             ("chan_util_avg_period", "-1"),
383             ("multi_ap_backhaul_ssid", ""),
384             ("multi_ap_backhaul_ssid", '""'),
385             ("multi_ap_backhaul_ssid", "1"),
386             ("multi_ap_backhaul_ssid", '"' + 33*"A" + '"'),
387             ("multi_ap_backhaul_wpa_passphrase", ""),
388             ("multi_ap_backhaul_wpa_passphrase", 64*"q"),
389             ("multi_ap_backhaul_wpa_psk", "q"),
390             ("multi_ap_backhaul_wpa_psk", 63*"aa"),
391             ("hs20_release", "0"),
392             ("hs20_release", "255"),
393             ("dhcp_server", "::::::"),
394             ("dpp_netaccesskey", "q"),
395             ("dpp_csign", "q"),
396             ("owe_transition_bssid", "q"),
397             ("owe_transition_ssid", ""),
398             ("owe_transition_ssid", '""'),
399             ("owe_transition_ssid", '"' + 33*"a" + '"'),
400             ("multi_ap", "-1"),
401             ("multi_ap", "255"),
402             ("unknown-item", "foo")]
403    for field, val in tests:
404        if "FAIL" not in hapd.request("SET %s %s" % (field, val)):
405            raise Exception("Invalid %s accepted" % field)
406    hapd.enable()
407    dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
408
409def test_ap_config_eap_user_file_parsing(dev, apdev, params):
410    """hostapd eap_user_file parsing"""
411    tmp = params['prefix'] + '.tmp'
412    hapd = hostapd.add_ap(apdev[0], {"ssid": "foobar"})
413
414    for i in range(2):
415        if "OK" not in hapd.request("SET eap_user_file auth_serv/eap_user.conf"):
416            raise Exception("eap_user_file rejected")
417
418    tests = ["#\n\n*\tTLS\nradius_accept_attr=:",
419             "foo\n",
420             "\"foo\n",
421             "\"foo\"\n",
422             "\"foo\" FOOBAR\n",
423             "\"foo\" " + 10*"TLS," + "TLS \"\n",
424             "\"foo\" TLS \nfoo\n",
425             "\"foo\" PEAP hash:foo\n",
426             "\"foo\" PEAP hash:8846f7eaee8fb117ad06bdd830b7586q\n",
427             "\"foo\" PEAP 01020\n",
428             "\"foo\" PEAP 010q\n"
429             '"pwd" PWD ssha1:\n',
430             '"pwd" PWD ssha1:' + 20*'00' + '\n',
431             '"pwd" PWD ssha256:\n',
432             '"pwd" PWD ssha512:\n',
433             '"pwd" PWD ssha1:' + 20*'00' + 'qq\n',
434             '"pwd" PWD ssha1:' + 19*'00' + 'qq00\n',
435             "\"foo\" TLS\nradius_accept_attr=123:x:012\n",
436             "\"foo\" TLS\nradius_accept_attr=123:x:012q\n",
437             "\"foo\" TLS\nradius_accept_attr=123:Q:01\n",
438             "\"foo\" TLS\nradius_accept_attr=123\nfoo\n"]
439    for t in tests:
440        with open(tmp, "w") as f:
441            f.write(t)
442        if "FAIL" not in hapd.request("SET eap_user_file " + tmp):
443            raise Exception("Invalid eap_user_file accepted")
444
445    tests = [("\"foo\" TLS\n", 2, "hostapd_config_read_eap_user"),
446             ("\"foo\" PEAP \"foo\"\n", 3, "hostapd_config_read_eap_user"),
447             ("\"foo\" PEAP hash:8846f7eaee8fb117ad06bdd830b75861\n", 3,
448              "hostapd_config_read_eap_user"),
449             ("\"foo\" PEAP 0102\n", 3, "hostapd_config_read_eap_user"),
450             ("\"foo\" TLS\nradius_accept_attr=123\n", 1,
451              "=hostapd_parse_radius_attr"),
452             ("\"foo\" TLS\nradius_accept_attr=123\n", 1,
453              "wpabuf_alloc;hostapd_parse_radius_attr"),
454             ("\"foo\" TLS\nradius_accept_attr=123:s:foo\n", 2,
455              "hostapd_parse_radius_attr"),
456             ("\"foo\" TLS\nradius_accept_attr=123:x:0102\n", 2,
457              "hostapd_parse_radius_attr"),
458             ("\"foo\" TLS\nradius_accept_attr=123:d:1\n", 2,
459              "hostapd_parse_radius_attr"),
460             ('"pwd" PWD ssha1:046239e0660a59015231082a071c803e9f5848ae42eaccb4c08c97ae397bc879c4b071b9088ee715\n', 1, "hostapd_config_eap_user_salted"),
461             ('"pwd" PWD ssha1:046239e0660a59015231082a071c803e9f5848ae42eaccb4c08c97ae397bc879c4b071b9088ee715\n', 2, "hostapd_config_eap_user_salted"),
462             ("* TLS\n", 1, "hostapd_config_read_eap_user")]
463    for t, count, func in tests:
464        with alloc_fail(hapd, count, func):
465            with open(tmp, "w") as f:
466                f.write(t)
467            if "FAIL" not in hapd.request("SET eap_user_file " + tmp):
468                raise Exception("eap_user_file accepted during OOM")
469
470def test_ap_config_set_oom(dev, apdev):
471    """hostapd configuration parsing OOM"""
472    hapd = hostapd.add_ap(apdev[0], {"ssid": "foobar"})
473
474    tests = [(1, "hostapd_parse_das_client",
475              "SET radius_das_client 192.168.1.123 pw"),
476             (1, "hostapd_parse_chanlist", "SET chanlist 1 6 11-13"),
477             (1, "hostapd_config_bss", "SET bss foo"),
478             (2, "hostapd_config_bss", "SET bss foo"),
479             (3, "hostapd_config_bss", "SET bss foo"),
480             (1, "add_r0kh",
481              "SET r0kh 02:01:02:03:04:05 r0kh-1.example.com 000102030405060708090a0b0c0d0e0f"),
482             (1, "add_r1kh",
483              "SET r1kh 02:01:02:03:04:05 02:11:22:33:44:55 000102030405060708090a0b0c0d0e0f"),
484             (1, "parse_roaming_consortium", "SET roaming_consortium 021122"),
485             (1, "parse_lang_string", "SET venue_name eng:Example venue"),
486             (1, "parse_3gpp_cell_net",
487              "SET anqp_3gpp_cell_net 244,91;310,026;234,56"),
488             (1, "parse_nai_realm", "SET nai_realm 0,example.com;example.net"),
489             (2, "parse_nai_realm", "SET nai_realm 0,example.com;example.net"),
490             (1, "parse_anqp_elem", "SET anqp_elem 265:0000"),
491             (2, "parse_anqp_elem", "SET anqp_elem 266:000000"),
492             (1, "parse_venue_url", "SET venue_url 1:http://example.com/"),
493             (1, "hs20_parse_conn_capab", "SET hs20_conn_capab 1:0:2"),
494             (1, "hs20_parse_wan_metrics",
495              "SET hs20_wan_metrics 01:8000:1000:80:240:3000"),
496             (1, "hostapd_config_parse_acs_chan_bias",
497              "SET acs_chan_bias 1:0.8 6:0.8 11:0.8"),
498             (2, "hostapd_config_parse_acs_chan_bias",
499              "SET acs_chan_bias 1:0.8 6:0.8 11:0.8"),
500             (1, "parse_wpabuf_hex", "SET vendor_elements 01020304"),
501             (1, "parse_fils_realm", "SET fils_realm example.com"),
502             (1, "parse_sae_password", "SET sae_password secret"),
503             (2, "parse_sae_password", "SET sae_password secret"),
504             (2, "parse_sae_password", "SET sae_password secret|id=pw"),
505             (3, "parse_sae_password", "SET sae_password secret|id=pw"),
506             (1, "hostapd_dpp_controller_parse", "SET dpp_controller ipaddr=127.0.0.1 pkhash=" + 32*"11"),
507             (1, "hostapd_config_fill", "SET check_cert_subject foo"),
508             (1, "hostapd_config_fill", "SET multi_ap_backhaul_wpa_psk " + 64*"00"),
509             (1, "hostapd_parse_intlist;hostapd_config_fill",
510              "SET owe_groups 19"),
511             (1, "hostapd_config_fill",
512              "SET pac_opaque_encr_key 000102030405060708090a0b0c0d0e0f"),
513             (1, "hostapd_config_fill", "SET eap_message hello"),
514             (1, "hostapd_config_fill",
515              "SET wpa_psk 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"),
516             (1, "hostapd_config_fill", "SET time_zone EST5"),
517             (1, "hostapd_config_fill",
518              "SET network_auth_type 02http://www.example.com/redirect/"),
519             (1, "hostapd_config_fill", "SET domain_name example.com"),
520             (1, "hostapd_config_fill", "SET hs20_operating_class 5173"),
521             (1, "hostapd_config_fill", "SET own_ie_override 11223344"),
522             (1, "hostapd_parse_intlist", "SET sae_groups 19 25"),
523             (1, "hostapd_parse_intlist", "SET basic_rates 10 20 55 110"),
524             (1, "hostapd_parse_intlist", "SET supported_rates 10 20 55 110")]
525    if "WEP40" in dev[0].get_capability("group"):
526        tests += [(1, "hostapd_config_read_wep", "SET wep_key0 \"hello\""),
527                  (1, "hostapd_config_read_wep", "SET wep_key0 0102030405")]
528    for count, func, cmd in tests:
529        with alloc_fail(hapd, count, func):
530            if "FAIL" not in hapd.request(cmd):
531                raise Exception("Command accepted during OOM: " + cmd)
532
533    hapd.set("hs20_conn_capab", "1:0:2")
534    hapd.set("nai_realm", "0,example.com;example.net")
535    hapd.set("venue_name", "eng:Example venue")
536    hapd.set("roaming_consortium", "021122")
537    hapd.set("vendor_elements", "01020304")
538    hapd.set("vendor_elements", "01020304")
539    hapd.set("vendor_elements", "")
540    hapd.set("lci", "11223344")
541    hapd.set("civic", "11223344")
542    hapd.set("lci", "")
543    hapd.set("civic", "")
544
545    tests = [(1, "parse_roaming_consortium", "SET roaming_consortium 021122"),
546             (2, "parse_nai_realm", "SET nai_realm 0,example.com;example.net"),
547             (1, "parse_lang_string", "SET venue_name eng:Example venue"),
548             (1, "hs20_parse_conn_capab", "SET hs20_conn_capab 1:0:2")]
549    for count, func, cmd in tests:
550        with alloc_fail(hapd, count, func):
551            if "FAIL" not in hapd.request(cmd):
552                raise Exception("Command accepted during OOM (2): " + cmd)
553
554    tests = [(1, "parse_fils_realm", "SET fils_realm example.com")]
555    for count, func, cmd in tests:
556        with fail_test(hapd, count, func):
557            if "FAIL" not in hapd.request(cmd):
558                raise Exception("Command accepted during FAIL_TEST: " + cmd)
559
560def test_ap_config_set_errors(dev, apdev):
561    """hostapd configuration parsing errors"""
562    hapd = hostapd.add_ap(apdev[0], {"ssid": "foobar"})
563    if "WEP40" in dev[0].get_capability("group"):
564        hapd.set("wep_key0", '"hello"')
565        hapd.set("wep_key1", '"hello"')
566        hapd.set("wep_key0", '')
567        hapd.set("wep_key0", '"hello"')
568        if "FAIL" not in hapd.request("SET wep_key1 \"hello\""):
569            raise Exception("SET wep_key1 allowed to override existing key")
570        hapd.set("wep_key1", '')
571        hapd.set("wep_key1", '"hello"')
572
573    hapd.set("auth_server_addr", "127.0.0.1")
574    hapd.set("acct_server_addr", "127.0.0.1")
575
576    hapd.set("fst_group_id", "hello")
577    if "FAIL" not in hapd.request("SET fst_group_id hello2"):
578        raise Exception("Duplicate fst_group_id accepted")
579
580    tests = ["SET eap_reauth_period -1",
581             "SET fst_llt ",
582             "SET auth_server_addr_replace foo",
583             "SET acct_server_addr_replace foo"]
584    for t in tests:
585        if "FAIL" not in hapd.request(t):
586            raise Exception("Invalid command accepted: " + t)
587
588    # Deprecated entries
589    hapd.set("tx_queue_after_beacon_aifs", '2')
590    hapd.set("tx_queue_beacon_aifs", '2')
591    hapd.set("tx_queue_data9_aifs", '2')
592    hapd.set("debug", '1')
593    hapd.set("dump_file", '/tmp/hostapd-test-dump')
594    hapd.set("eap_authenticator", '0')
595    hapd.set("radio_measurements", '0')
596    hapd.set("radio_measurements", '1')
597    hapd.set("peerkey", "0")
598
599    # Various extra coverage (not really errors)
600    hapd.set("logger_syslog_level", '1')
601    hapd.set("logger_syslog", '0')
602    hapd.set("ctrl_interface_group", '4')
603    hapd.set("tls_flags", "[ALLOW-SIGN-RSA-MD5][DISABLE-TIME-CHECKS][DISABLE-TLSv1.0]")
604
605    for i in range(50000):
606        if "OK" not in hapd.request("SET hs20_conn_capab 17:5060:0"):
607            logger.info("hs20_conn_capab limit at %d" % i)
608            break
609    if i < 1000 or i >= 49999:
610        raise Exception("hs20_conn_capab limit not seen")
611