1# wpa_supplicant control interface
2# Copyright (c) 2014, Qualcomm Atheros, Inc.
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7from remotehost import remote_compatible
8import logging
9logger = logging.getLogger()
10import os
11import socket
12import subprocess
13import time
14import binascii
15
16import hostapd
17import hwsim_utils
18from hwsim import HWSimRadio
19from wpasupplicant import WpaSupplicant
20from utils import *
21from test_wpas_ap import wait_ap_ready
22
23@remote_compatible
24def test_wpas_ctrl_network(dev):
25    """wpa_supplicant ctrl_iface network set/get"""
26    skip_without_tkip(dev[0])
27    id = dev[0].add_network()
28
29    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id)):
30        raise Exception("Unexpected success for invalid SET_NETWORK")
31    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + " name"):
32        raise Exception("Unexpected success for invalid SET_NETWORK")
33    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id + 1) + " proto OPEN"):
34        raise Exception("Unexpected success for invalid network id")
35    if "FAIL" not in dev[0].request("GET_NETWORK " + str(id)):
36        raise Exception("Unexpected success for invalid GET_NETWORK")
37    if "FAIL" not in dev[0].request("GET_NETWORK " + str(id + 1) + " proto"):
38        raise Exception("Unexpected success for invalid network id")
39
40    if "OK" not in dev[0].request("SET_NETWORK " + str(id) + " proto  \t WPA2 "):
41        raise Exception("Unexpected failure for SET_NETWORK proto")
42    res = dev[0].request("GET_NETWORK " + str(id) + " proto")
43    if res != "RSN":
44        raise Exception("Unexpected SET_NETWORK/GET_NETWORK conversion for proto: " + res)
45
46    if "OK" not in dev[0].request("SET_NETWORK " + str(id) + " key_mgmt  \t WPA-PSK "):
47        raise Exception("Unexpected success for SET_NETWORK key_mgmt")
48    res = dev[0].request("GET_NETWORK " + str(id) + " key_mgmt")
49    if res != "WPA-PSK":
50        raise Exception("Unexpected SET_NETWORK/GET_NETWORK conversion for key_mgmt: " + res)
51
52    if "OK" not in dev[0].request("SET_NETWORK " + str(id) + " auth_alg  \t OPEN "):
53        raise Exception("Unexpected failure for SET_NETWORK auth_alg")
54    res = dev[0].request("GET_NETWORK " + str(id) + " auth_alg")
55    if res != "OPEN":
56        raise Exception("Unexpected SET_NETWORK/GET_NETWORK conversion for auth_alg: " + res)
57
58    if "OK" not in dev[0].request("SET_NETWORK " + str(id) + " eap  \t TLS "):
59        raise Exception("Unexpected failure for SET_NETWORK eap")
60    res = dev[0].request("GET_NETWORK " + str(id) + " eap")
61    if res != "TLS":
62        raise Exception("Unexpected SET_NETWORK/GET_NETWORK conversion for eap: " + res)
63
64    tests = ("bssid foo", "key_mgmt foo", "key_mgmt ", "group NONE")
65    for t in tests:
66        if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + " " + t):
67            raise Exception("Unexpected success for invalid SET_NETWORK: " + t)
68
69    tests = [("key_mgmt", "WPA-PSK WPA-EAP IEEE8021X NONE WPA-NONE FT-PSK FT-EAP WPA-PSK-SHA256 WPA-EAP-SHA256"),
70             ("pairwise", "CCMP-256 GCMP-256 CCMP GCMP TKIP"),
71             ("group", "CCMP-256 GCMP-256 CCMP GCMP TKIP"),
72             ("auth_alg", "OPEN SHARED LEAP"),
73             ("scan_freq", "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"),
74             ("freq_list", "2412 2417"),
75             ("scan_ssid", "1"),
76             ("bssid", "00:11:22:33:44:55"),
77             ("proto", "WPA RSN"),
78             ("eap", "TLS"),
79             ("go_p2p_dev_addr", "22:33:44:55:66:aa"),
80             ("p2p_client_list", "22:33:44:55:66:bb 02:11:22:33:44:55")]
81    if "SAE" not in dev[0].get_capability("auth_alg"):
82        tests.append(("key_mgmt", "WPS"))
83    else:
84        tests.append(("key_mgmt", "WPS SAE FT-SAE"))
85
86    dev[0].set_network_quoted(id, "ssid", "test")
87    for field, value in tests:
88        dev[0].set_network(id, field, value)
89        res = dev[0].get_network(id, field)
90        if res != value:
91            raise Exception("Unexpected response for '" + field + "': '" + res + "'")
92
93    try:
94        value = "WPA-EAP-SUITE-B WPA-EAP-SUITE-B-192"
95        dev[0].set_network(id, "key_mgmt", value)
96        res = dev[0].get_network(id, "key_mgmt")
97        if res != value:
98            raise Exception("Unexpected response for key_mgmt")
99    except Exception as e:
100        if str(e).startswith("Unexpected"):
101            raise
102        else:
103            pass
104
105    q_tests = (("identity", "hello"),
106               ("anonymous_identity", "foo@nowhere.com"))
107    for field, value in q_tests:
108        dev[0].set_network_quoted(id, field, value)
109        res = dev[0].get_network(id, field)
110        if res != '"' + value + '"':
111            raise Exception("Unexpected quoted response for '" + field + "': '" + res + "'")
112
113    get_tests = (("foo", None), ("ssid", '"test"'))
114    for field, value in get_tests:
115        res = dev[0].get_network(id, field)
116        if res != value:
117            raise Exception("Unexpected response for '" + field + "': '" + res + "'")
118
119    if dev[0].get_network(id, "password"):
120        raise Exception("Unexpected response for 'password'")
121    dev[0].set_network_quoted(id, "password", "foo")
122    if dev[0].get_network(id, "password") != '*':
123        raise Exception("Unexpected response for 'password' (expected *)")
124    dev[0].set_network(id, "password", "hash:12345678901234567890123456789012")
125    if dev[0].get_network(id, "password") != '*':
126        raise Exception("Unexpected response for 'password' (expected *)")
127    dev[0].set_network(id, "password", "NULL")
128    if dev[0].get_network(id, "password"):
129        raise Exception("Unexpected response for 'password'")
130    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + " password hash:12"):
131        raise Exception("Unexpected success for invalid password hash")
132    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + " password hash:123456789012345678x0123456789012"):
133        raise Exception("Unexpected success for invalid password hash")
134
135    dev[0].set_network(id, "identity", "414243")
136    if dev[0].get_network(id, "identity") != '"ABC"':
137        raise Exception("Unexpected identity hex->text response")
138
139    dev[0].set_network(id, "identity", 'P"abc\ndef"')
140    if dev[0].get_network(id, "identity") != "6162630a646566":
141        raise Exception("Unexpected identity printf->hex response")
142
143    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' identity P"foo'):
144        raise Exception("Unexpected success for invalid identity string")
145
146    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' identity 12x3'):
147        raise Exception("Unexpected success for invalid identity string")
148
149    if "WEP40" in dev[0].get_capability("group"):
150        for i in range(0, 4):
151            if "FAIL" in dev[0].request("SET_NETWORK " + str(id) + ' wep_key' + str(i) + ' aabbccddee'):
152                raise Exception("Unexpected wep_key set failure")
153            if dev[0].get_network(id, "wep_key" + str(i)) != '*':
154                raise Exception("Unexpected wep_key get failure")
155
156    if "FAIL" in dev[0].request("SET_NETWORK " + str(id) + ' psk_list P2P-00:11:22:33:44:55-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'):
157        raise Exception("Unexpected failure for psk_list string")
158
159    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' psk_list 00:11:x2:33:44:55-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'):
160        raise Exception("Unexpected success for invalid psk_list string")
161
162    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' psk_list P2P-00:11:x2:33:44:55-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'):
163        raise Exception("Unexpected success for invalid psk_list string")
164
165    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' psk_list P2P-00:11:22:33:44:55+0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'):
166        raise Exception("Unexpected success for invalid psk_list string")
167
168    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' psk_list P2P-00:11:22:33:44:55-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde'):
169        raise Exception("Unexpected success for invalid psk_list string")
170
171    if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' psk_list P2P-00:11:22:33:44:55-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdex'):
172        raise Exception("Unexpected success for invalid psk_list string")
173
174    if dev[0].get_network(id, "psk_list"):
175        raise Exception("Unexpected psk_list get response")
176
177    if dev[0].list_networks()[0]['ssid'] != "test":
178        raise Exception("Unexpected ssid in LIST_NETWORKS")
179    dev[0].set_network(id, "ssid", "NULL")
180    if dev[0].list_networks()[0]['ssid'] != "":
181        raise Exception("Unexpected ssid in LIST_NETWORKS after clearing it")
182
183    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' ssid "0123456789abcdef0123456789abcdef0"'):
184        raise Exception("Too long SSID accepted")
185    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' scan_ssid qwerty'):
186        raise Exception("Invalid integer accepted")
187    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' scan_ssid 2'):
188        raise Exception("Too large integer accepted")
189    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' psk 12345678'):
190        raise Exception("Invalid PSK accepted")
191    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' psk "1234567"'):
192        raise Exception("Too short PSK accepted")
193    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' psk "1234567890123456789012345678901234567890123456789012345678901234"'):
194        raise Exception("Too long PSK accepted")
195    dev[0].set_network_quoted(id, "psk", "123456768")
196    dev[0].set_network_quoted(id, "psk", "123456789012345678901234567890123456789012345678901234567890123")
197    if dev[0].get_network(id, "psk") != '*':
198        raise Exception("Unexpected psk read result")
199
200    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' eap UNKNOWN'):
201        raise Exception("Unknown EAP method accepted")
202
203    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' password "foo'):
204        raise Exception("Invalid password accepted")
205
206    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' wep_key0 "foo'):
207        raise Exception("Invalid WEP key accepted")
208    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' wep_key0 "12345678901234567"'):
209        raise Exception("Too long WEP key accepted")
210    if "WEP40" in dev[0].get_capability("group"):
211        # too short WEP key is ignored
212        dev[0].set_network_quoted(id, "wep_key0", "1234")
213        dev[0].set_network_quoted(id, "wep_key1", "12345")
214        dev[0].set_network_quoted(id, "wep_key2", "1234567890123")
215        dev[0].set_network_quoted(id, "wep_key3", "1234567890123456")
216
217    dev[0].set_network(id, "go_p2p_dev_addr", "any")
218    if dev[0].get_network(id, "go_p2p_dev_addr") is not None:
219        raise Exception("Unexpected go_p2p_dev_addr value")
220    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' go_p2p_dev_addr 00:11:22:33:44'):
221        raise Exception("Invalid go_p2p_dev_addr accepted")
222    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' p2p_client_list 00:11:22:33:44'):
223        raise Exception("Invalid p2p_client_list accepted")
224    if "FAIL" in dev[0].request('SET_NETWORK ' + str(id) + ' p2p_client_list 00:11:22:33:44:55 00:1'):
225        raise Exception("p2p_client_list truncation workaround failed")
226    if dev[0].get_network(id, "p2p_client_list") != "00:11:22:33:44:55":
227        raise Exception("p2p_client_list truncation workaround did not work")
228
229    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' auth_alg '):
230        raise Exception("Empty auth_alg accepted")
231    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' auth_alg FOO'):
232        raise Exception("Invalid auth_alg accepted")
233
234    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' proto '):
235        raise Exception("Empty proto accepted")
236    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' proto FOO'):
237        raise Exception("Invalid proto accepted")
238
239    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' pairwise '):
240        raise Exception("Empty pairwise accepted")
241    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' pairwise FOO'):
242        raise Exception("Invalid pairwise accepted")
243    if "FAIL" not in dev[0].request('SET_NETWORK ' + str(id) + ' pairwise WEP40'):
244        raise Exception("Invalid pairwise accepted")
245
246    if "OK" not in dev[0].request('BSSID ' + str(id) + ' 00:11:22:33:44:55'):
247        raise Exception("Unexpected BSSID failure")
248    if dev[0].request("GET_NETWORK 0 bssid") != '00:11:22:33:44:55':
249        raise Exception("BSSID command did not set network bssid")
250    if "OK" not in dev[0].request('BSSID ' + str(id) + ' 00:00:00:00:00:00'):
251        raise Exception("Unexpected BSSID failure")
252    if "FAIL" not in dev[0].request("GET_NETWORK 0 bssid"):
253        raise Exception("bssid claimed configured after clearing")
254    if "FAIL" not in dev[0].request('BSSID 123 00:11:22:33:44:55'):
255        raise Exception("Unexpected BSSID success")
256    if "FAIL" not in dev[0].request('BSSID ' + str(id) + ' 00:11:22:33:44'):
257        raise Exception("Unexpected BSSID success")
258    if "FAIL" not in dev[0].request('BSSID ' + str(id)):
259        raise Exception("Unexpected BSSID success")
260
261    tests = ["02:11:22:33:44:55",
262             "02:11:22:33:44:55 02:ae:be:ce:53:77",
263             "02:11:22:33:44:55/ff:00:ff:00:ff:00",
264             "02:11:22:33:44:55/ff:00:ff:00:ff:00 f2:99:88:77:66:55",
265             "f2:99:88:77:66:55 02:11:22:33:44:55/ff:00:ff:00:ff:00",
266             "f2:99:88:77:66:55 02:11:22:33:44:55/ff:00:ff:00:ff:00 12:34:56:78:90:ab",
267             "02:11:22:33:44:55/ff:ff:ff:00:00:00 02:ae:be:ce:53:77/00:00:00:00:00:ff"]
268    for val in tests:
269        dev[0].set_network(id, "bssid_ignore", val)
270        res = dev[0].get_network(id, "bssid_ignore")
271        if res != val:
272            raise Exception("Unexpected bssid_ignore value: %s != %s" % (res, val))
273        dev[0].set_network(id, "bssid_accept", val)
274        res = dev[0].get_network(id, "bssid_accept")
275        if res != val:
276            raise Exception("Unexpected bssid_accept value: %s != %s" % (res, val))
277
278    tests = ["foo",
279             "00:11:22:33:44:5",
280             "00:11:22:33:44:55q",
281             "00:11:22:33:44:55/",
282             "00:11:22:33:44:55/66:77:88:99:aa:b"]
283    for val in tests:
284        if "FAIL" not in dev[0].request("SET_NETWORK %d bssid_ignore %s" % (id, val)):
285            raise Exception("Invalid bssid_ignore value accepted")
286
287@remote_compatible
288def test_wpas_ctrl_network_oom(dev):
289    """wpa_supplicant ctrl_iface network OOM in string parsing"""
290    id = dev[0].add_network()
291
292    tests = [('"foo"', 1, 'dup_binstr;wpa_config_set'),
293             ('P"foo"', 1, 'dup_binstr;wpa_config_set'),
294             ('P"foo"', 2, 'wpa_config_set'),
295             ('112233', 1, 'wpa_config_set')]
296    for val, count, func in tests:
297        with alloc_fail(dev[0], count, func):
298            if "FAIL" not in dev[0].request("SET_NETWORK " + str(id) + ' ssid ' + val):
299                raise Exception("Unexpected success for SET_NETWORK during OOM")
300
301@remote_compatible
302def test_wpas_ctrl_many_networks(dev, apdev):
303    """wpa_supplicant ctrl_iface LIST_NETWORKS with huge number of networks"""
304    for i in range(999):
305        dev[0].add_network()
306        dev[0].dump_monitor()
307    id = dev[0].add_network()
308    ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-ADDED %d" % id])
309    if ev is None:
310        raise Exception("Network added event not seen for the last network")
311    ev = dev[0].wait_global_event(["CTRL-EVENT-NETWORK-ADDED %d" % id], timeout=10)
312    if ev is None:
313        raise Exception("Network added event (global) not seen for the last network")
314    dev[0].dump_monitor()
315    res = dev[0].request("LIST_NETWORKS")
316    if str(id) in res:
317        raise Exception("Last added network was unexpectedly included")
318    res = dev[0].request("LIST_NETWORKS LAST_ID=%d" % (id - 2))
319    if str(id) not in res:
320        raise Exception("Last added network was not present when using LAST_ID")
321    # This command can take a very long time under valgrind testing on a low
322    # power CPU, so increase the command timeout significantly to avoid issues
323    # with the test case failing and following reset operation timing out.
324    dev[0].request("REMOVE_NETWORK all", timeout=60)
325    seen = seen_global = False
326
327    for i in range(1000):
328        ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-REMOVED"])
329        if ev is None:
330            raise Exception("Network removed event not seen for the last network")
331        if str(id) in ev:
332            seen = True
333        ev = dev[0].wait_global_event(["CTRL-EVENT-NETWORK-REMOVED"],
334                                      timeout=10)
335        if ev is None:
336            raise Exception("Network removed event (global) not seen for the last network")
337        if str(id) in ev:
338            seen_global = True
339    if not seen:
340            raise Exception("Network removed event not seen for the last network")
341    if not seen_global:
342            raise Exception("Network removed event (global) not seen for the last network")
343    dev[0].dump_monitor()
344
345@remote_compatible
346def test_wpas_ctrl_dup_network(dev, apdev):
347    """wpa_supplicant ctrl_iface DUP_NETWORK"""
348    ssid = "target"
349    passphrase = 'qwertyuiop'
350    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
351    hostapd.add_ap(apdev[0], params)
352
353    src = dev[0].connect("another", psk=passphrase, scan_freq="2412",
354                         only_add_network=True)
355    id = dev[0].add_network()
356    dev[0].set_network_quoted(id, "ssid", ssid)
357    for f in ["key_mgmt", "psk", "scan_freq"]:
358        res = dev[0].request("DUP_NETWORK {} {} {}".format(src, id, f))
359        if "OK" not in res:
360            raise Exception("DUP_NETWORK failed")
361    dev[0].connect_network(id)
362
363    if "FAIL" not in dev[0].request("DUP_NETWORK "):
364        raise Exception("Unexpected DUP_NETWORK success")
365    if "FAIL" not in dev[0].request("DUP_NETWORK %d " % id):
366        raise Exception("Unexpected DUP_NETWORK success")
367    if "FAIL" not in dev[0].request("DUP_NETWORK %d %d" % (id, id)):
368        raise Exception("Unexpected DUP_NETWORK success")
369    if "FAIL" not in dev[0].request("DUP_NETWORK 123456 1234567 "):
370        raise Exception("Unexpected DUP_NETWORK success")
371    if "FAIL" not in dev[0].request("DUP_NETWORK %d 123456 " % id):
372        raise Exception("Unexpected DUP_NETWORK success")
373    if "FAIL" not in dev[0].request("DUP_NETWORK %d %d foo" % (id, id)):
374        raise Exception("Unexpected DUP_NETWORK success")
375    dev[0].request("DISCONNECT")
376    if "OK" not in dev[0].request("DUP_NETWORK %d %d ssid" % (id, id)):
377        raise Exception("Unexpected DUP_NETWORK failure")
378
379@remote_compatible
380def test_wpas_ctrl_dup_network_global(dev, apdev):
381    """wpa_supplicant ctrl_iface DUP_NETWORK (global)"""
382    ssid = "target"
383    passphrase = 'qwertyuiop'
384    params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
385    hostapd.add_ap(apdev[0], params)
386
387    src = dev[0].connect("another", psk=passphrase, scan_freq="2412",
388                         only_add_network=True)
389    id = dev[0].add_network()
390    dev[0].set_network_quoted(id, "ssid", ssid)
391    for f in ["key_mgmt", "psk", "scan_freq"]:
392        res = dev[0].global_request("DUP_NETWORK {} {} {} {} {}".format(dev[0].ifname, dev[0].ifname, src, id, f))
393        if "OK" not in res:
394            raise Exception("DUP_NETWORK failed")
395    dev[0].connect_network(id)
396
397    if "FAIL" not in dev[0].global_request("DUP_NETWORK "):
398        raise Exception("Unexpected DUP_NETWORK success")
399    if "FAIL" not in dev[0].global_request("DUP_NETWORK %s" % dev[0].ifname):
400        raise Exception("Unexpected DUP_NETWORK success")
401    if "FAIL" not in dev[0].global_request("DUP_NETWORK %s %s" % (dev[0].ifname, dev[0].ifname)):
402        raise Exception("Unexpected DUP_NETWORK success")
403    if "FAIL" not in dev[0].global_request("DUP_NETWORK %s %s %d" % (dev[0].ifname, dev[0].ifname, id)):
404        raise Exception("Unexpected DUP_NETWORK success")
405    if "FAIL" not in dev[0].global_request("DUP_NETWORK %s %s %d %d" % (dev[0].ifname, dev[0].ifname, id, id)):
406        raise Exception("Unexpected DUP_NETWORK success")
407    dev[0].request("DISCONNECT")
408    if "OK" not in dev[0].global_request("DUP_NETWORK %s %s %d %d ssid" % (dev[0].ifname, dev[0].ifname, id, id)):
409        raise Exception("Unexpected DUP_NETWORK failure")
410
411def add_cred(dev):
412    id = dev.add_cred()
413    ev = dev.wait_event(["CRED-ADDED"])
414    if ev is None:
415        raise Exception("Missing CRED-ADDED event")
416    if " " + str(id) not in ev:
417        raise Exception("CRED-ADDED event without matching id")
418    return id
419
420def set_cred(dev, id, field, value):
421    dev.set_cred(id, field, value)
422    ev = dev.wait_event(["CRED-MODIFIED"])
423    if ev is None:
424        raise Exception("Missing CRED-MODIFIED event")
425    if " " + str(id) + " " not in ev:
426        raise Exception("CRED-MODIFIED event without matching id")
427    if field not in ev:
428        raise Exception("CRED-MODIFIED event without matching field")
429
430def set_cred_quoted(dev, id, field, value):
431    dev.set_cred_quoted(id, field, value)
432    ev = dev.wait_event(["CRED-MODIFIED"])
433    if ev is None:
434        raise Exception("Missing CRED-MODIFIED event")
435    if " " + str(id) + " " not in ev:
436        raise Exception("CRED-MODIFIED event without matching id")
437    if field not in ev:
438        raise Exception("CRED-MODIFIED event without matching field")
439
440def remove_cred(dev, id):
441    dev.remove_cred(id)
442    ev = dev.wait_event(["CRED-REMOVED"])
443    if ev is None:
444        raise Exception("Missing CRED-REMOVED event")
445    if " " + str(id) not in ev:
446        raise Exception("CRED-REMOVED event without matching id")
447
448@remote_compatible
449def test_wpas_ctrl_cred(dev):
450    """wpa_supplicant ctrl_iface cred set"""
451    id1 = add_cred(dev[0])
452    if "FAIL" not in dev[0].request("SET_CRED " + str(id1 + 1) + " temporary 1"):
453        raise Exception("SET_CRED succeeded unexpectedly on unknown cred id")
454    if "FAIL" not in dev[0].request("SET_CRED " + str(id1)):
455        raise Exception("Invalid SET_CRED succeeded unexpectedly")
456    if "FAIL" not in dev[0].request("SET_CRED " + str(id1) + " temporary"):
457        raise Exception("Invalid SET_CRED succeeded unexpectedly")
458    if "FAIL" not in dev[0].request("GET_CRED " + str(id1 + 1) + " temporary"):
459        raise Exception("GET_CRED succeeded unexpectedly on unknown cred id")
460    if "FAIL" not in dev[0].request("GET_CRED " + str(id1)):
461        raise Exception("Invalid GET_CRED succeeded unexpectedly")
462    if "FAIL" not in dev[0].request("GET_CRED " + str(id1) + " foo"):
463        raise Exception("Invalid GET_CRED succeeded unexpectedly")
464    id = add_cred(dev[0])
465    id2 = add_cred(dev[0])
466    set_cred(dev[0], id, "temporary", "1")
467    set_cred(dev[0], id, "priority", "1")
468    set_cred(dev[0], id, "pcsc", "1")
469    set_cred(dev[0], id, "sim_num", "0")
470    set_cred_quoted(dev[0], id, "private_key_passwd", "test")
471    set_cred_quoted(dev[0], id, "domain_suffix_match", "test")
472    set_cred_quoted(dev[0], id, "phase1", "test")
473    set_cred_quoted(dev[0], id, "phase2", "test")
474
475    if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " eap FOO"):
476        raise Exception("Unexpected success on unknown EAP method")
477
478    if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " username 12xa"):
479        raise Exception("Unexpected success on invalid string")
480
481    for i in ("11", "1122", "112233445566778899aabbccddeeff00"):
482        if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " roaming_consortium " + i):
483            raise Exception("Unexpected success on invalid roaming_consortium")
484        if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " home_ois " + '"' + i + '"'):
485            raise Exception("Unexpected success on invalid home_ois")
486        if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " required_home_ois " + '"' + i + '"'):
487            raise Exception("Unexpected success on invalid required_home_ois")
488    if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " home_ois " + '"112233' + 36*",112233" + '"'):
489            raise Exception("Unexpected success on invalid home_ois")
490    if "FAIL" in dev[0].request("SET_CRED " + str(id) + " home_ois " + '"112233' + 35*",112233" + '"'):
491            raise Exception("Unexpected failure on maximum number of home_ois")
492
493    dev[0].set_cred(id, "excluded_ssid", "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff")
494    if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " excluded_ssid 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00"):
495        raise Exception("Unexpected success on invalid excluded_ssid")
496
497    if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " foo 4142"):
498        raise Exception("Unexpected success on unknown field")
499
500    tests = ["sp_priority 256",
501             'roaming_partner "example.org"',
502             'roaming_partner "' + 200*'a' + '.example.org,"',
503             'roaming_partner "example.org,1"',
504             'roaming_partner "example.org,1,2"',
505             'roaming_partner "example.org,1,2,ABC"']
506    for t in tests:
507        if "FAIL" not in dev[0].request("SET_CRED " + str(id) + " " + t):
508            raise Exception("Unexpected success on invalid SET_CRED value: " + t)
509
510    id3 = add_cred(dev[0])
511    id4 = add_cred(dev[0])
512    if len(dev[0].request("LIST_CREDS").splitlines()) != 6:
513        raise Exception("Unexpected LIST_CREDS result(1)")
514
515    remove_cred(dev[0], id1)
516    remove_cred(dev[0], id3)
517    remove_cred(dev[0], id4)
518    remove_cred(dev[0], id2)
519    remove_cred(dev[0], id)
520    if "FAIL" not in dev[0].request("REMOVE_CRED 1"):
521        raise Exception("Unexpected success on invalid remove cred")
522    if len(dev[0].request("LIST_CREDS").splitlines()) != 1:
523        raise Exception("Unexpected LIST_CREDS result(2)")
524
525    id = add_cred(dev[0])
526    values = [("temporary", "1", False),
527              ("temporary", "0", False),
528              ("pcsc", "1", False),
529              ("realm", "example.com", True),
530              ("username", "user@example.com", True),
531              ("password", "foo", True, "*"),
532              ("ca_cert", "ca.pem", True),
533              ("client_cert", "user.pem", True),
534              ("private_key", "key.pem", True),
535              ("private_key_passwd", "foo", True, "*"),
536              ("imsi", "310026-000000000", True),
537              ("milenage", "foo", True, "*"),
538              ("domain_suffix_match", "example.com", True),
539              ("domain", "example.com", True),
540              ("domain", "example.org", True, "example.com\nexample.org"),
541              ("roaming_consortium", "0123456789", False),
542              ("required_roaming_consortium", "456789", False),
543              ("eap", "TTLS", False),
544              ("phase1", "foo=bar1", True),
545              ("phase2", "foo=bar2", True),
546              ("excluded_ssid", "test", True),
547              ("excluded_ssid", "foo", True, "test\nfoo"),
548              ("roaming_partner", "example.com,0,4,*", True),
549              ("roaming_partner", "example.org,1,2,US", True,
550               "example.com,0,4,*\nexample.org,1,2,US"),
551              ("update_identifier", "4", False),
552              ("provisioning_sp", "sp.example.com", True),
553              ("sp_priority", "7", False),
554              ("min_dl_bandwidth_home", "100", False),
555              ("min_ul_bandwidth_home", "101", False),
556              ("min_dl_bandwidth_roaming", "102", False),
557              ("min_ul_bandwidth_roaming", "103", False),
558              ("max_bss_load", "57", False),
559              ("req_conn_capab", "6:22,80,443", False),
560              ("req_conn_capab", "17:500", False, "6:22,80,443\n17:500"),
561              ("req_conn_capab", "50", False, "6:22,80,443\n17:500\n50"),
562              ("ocsp", "1", False)]
563    for v in values:
564        if v[2]:
565            set_cred_quoted(dev[0], id, v[0], v[1])
566        else:
567            set_cred(dev[0], id, v[0], v[1])
568        val = dev[0].get_cred(id, v[0])
569        if len(v) == 4:
570            expect = v[3]
571        else:
572            expect = v[1]
573        if val != expect:
574            raise Exception("Unexpected GET_CRED value for {}: {} != {}".format(v[0], val, expect))
575    creds = dev[0].request("LIST_CREDS").splitlines()
576    if len(creds) != 2:
577        raise Exception("Unexpected LIST_CREDS result(3)")
578    if creds[1] != "0\texample.com\tuser@example.com\texample.com\t310026-000000000":
579        raise Exception("Unexpected LIST_CREDS value")
580    remove_cred(dev[0], id)
581    if len(dev[0].request("LIST_CREDS").splitlines()) != 1:
582        raise Exception("Unexpected LIST_CREDS result(4)")
583
584    id = add_cred(dev[0])
585    set_cred_quoted(dev[0], id, "domain", "foo.example.com")
586    id = add_cred(dev[0])
587    set_cred_quoted(dev[0], id, "domain", "bar.example.com")
588    id = add_cred(dev[0])
589    set_cred_quoted(dev[0], id, "domain", "foo.example.com")
590    if "OK" not in dev[0].request("REMOVE_CRED sp_fqdn=foo.example.com"):
591        raise Exception("REMOVE_CRED failed")
592    creds = dev[0].request("LIST_CREDS")
593    if "foo.example.com" in creds:
594        raise Exception("REMOVE_CRED sp_fqdn did not remove cred")
595    if "bar.example.com" not in creds:
596        raise Exception("REMOVE_CRED sp_fqdn removed incorrect cred")
597    dev[0].request("REMOVE_CRED all")
598
599    id = add_cred(dev[0])
600    set_cred_quoted(dev[0], id, "domain", "foo.example.com")
601    set_cred_quoted(dev[0], id, "provisioning_sp", "sp.foo.example.com")
602    id = add_cred(dev[0])
603    set_cred_quoted(dev[0], id, "domain", "bar.example.com")
604    set_cred_quoted(dev[0], id, "provisioning_sp", "sp.bar.example.com")
605    id = add_cred(dev[0])
606    set_cred_quoted(dev[0], id, "domain", "foo.example.com")
607    set_cred_quoted(dev[0], id, "provisioning_sp", "sp.foo.example.com")
608    if "OK" not in dev[0].request("REMOVE_CRED provisioning_sp=sp.foo.example.com"):
609        raise Exception("REMOVE_CRED failed")
610    creds = dev[0].request("LIST_CREDS")
611    if "foo.example.com" in creds:
612        raise Exception("REMOVE_CRED provisioning_sp did not remove cred")
613    if "bar.example.com" not in creds:
614        raise Exception("REMOVE_CRED provisioning_sp removed incorrect cred")
615    dev[0].request("REMOVE_CRED all")
616
617    # Test large number of creds and LIST_CREDS truncation
618    dev[0].dump_monitor()
619    for i in range(0, 100):
620        id = add_cred(dev[0])
621        set_cred_quoted(dev[0], id, "realm", "relatively.long.realm.test%d.example.com" % i)
622        dev[0].dump_monitor()
623    creds = dev[0].request("LIST_CREDS")
624    for i in range(0, 100):
625        dev[0].remove_cred(i)
626        dev[0].dump_monitor()
627    if len(creds) < 3900 or len(creds) > 4100:
628        raise Exception("Unexpected LIST_CREDS length: %d" % len(creds))
629    if "test10.example.com" not in creds:
630        raise Exception("Missing credential")
631    if len(creds.splitlines()) > 95:
632        raise Exception("Too many LIST_CREDS entries in the buffer")
633
634def test_wpas_ctrl_pno(dev):
635    """wpa_supplicant ctrl_iface pno"""
636    if "FAIL" not in dev[0].request("SET pno 1"):
637        raise Exception("Unexpected success in enabling PNO without enabled network blocks")
638    id = dev[0].add_network()
639    dev[0].set_network_quoted(id, "ssid", "test")
640    dev[0].set_network(id, "key_mgmt", "NONE")
641    dev[0].request("ENABLE_NETWORK " + str(id) + " no-connect")
642    #mac80211_hwsim does not yet support PNO, so this fails
643    if "FAIL" not in dev[0].request("SET pno 1"):
644        raise Exception("Unexpected success in enabling PNO")
645    if "FAIL" not in dev[0].request("SET pno 1 freq=2000-3000,5180"):
646        raise Exception("Unexpected success in enabling PNO")
647    if "FAIL" not in dev[0].request("SET pno 1 freq=0-6000"):
648        raise Exception("Unexpected success in enabling PNO")
649    if "FAIL" in dev[0].request("SET pno 0"):
650        raise Exception("Unexpected failure in disabling PNO")
651
652@remote_compatible
653def test_wpas_ctrl_get(dev):
654    """wpa_supplicant ctrl_iface get"""
655    if "FAIL" in dev[0].request("GET version"):
656        raise Exception("Unexpected get failure for version")
657    if "FAIL" in dev[0].request("GET wifi_display"):
658        raise Exception("Unexpected get failure for wifi_display")
659    if "FAIL" not in dev[0].request("GET foo"):
660        raise Exception("Unexpected success on get command")
661
662    dev[0].set("wifi_display", "0")
663    if dev[0].request("GET wifi_display") != '0':
664        raise Exception("Unexpected wifi_display value")
665    dev[0].set("wifi_display", "1")
666    if dev[0].request("GET wifi_display") != '1':
667        raise Exception("Unexpected wifi_display value")
668    dev[0].request("P2P_SET disabled 1")
669    if dev[0].request("GET wifi_display") != '0':
670        raise Exception("Unexpected wifi_display value (P2P disabled)")
671    dev[0].request("P2P_SET disabled 0")
672    if dev[0].request("GET wifi_display") != '1':
673        raise Exception("Unexpected wifi_display value (P2P re-enabled)")
674    dev[0].set("wifi_display", "0")
675    if dev[0].request("GET wifi_display") != '0':
676        raise Exception("Unexpected wifi_display value")
677
678@remote_compatible
679def test_wpas_ctrl_preauth(dev):
680    """wpa_supplicant ctrl_iface preauth"""
681    if "FAIL" not in dev[0].request("PREAUTH "):
682        raise Exception("Unexpected success on invalid PREAUTH")
683    if "FAIL" in dev[0].request("PREAUTH 00:11:22:33:44:55"):
684        raise Exception("Unexpected failure on PREAUTH")
685
686@remote_compatible
687def test_wpas_ctrl_tdls_discover(dev):
688    """wpa_supplicant ctrl_iface tdls_discover"""
689    if "FAIL" not in dev[0].request("TDLS_DISCOVER "):
690        raise Exception("Unexpected success on invalid TDLS_DISCOVER")
691    if "FAIL" not in dev[0].request("TDLS_DISCOVER 00:11:22:33:44:55"):
692        raise Exception("Unexpected success on TDLS_DISCOVER")
693
694@remote_compatible
695def test_wpas_ctrl_tdls_chan_switch(dev):
696    """wpa_supplicant ctrl_iface tdls_chan_switch error cases"""
697    for args in ['', '00:11:22:33:44:55']:
698        if "FAIL" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + args):
699            raise Exception("Unexpected success on invalid TDLS_CANCEL_CHAN_SWITCH: " + args)
700
701    for args in ['', 'foo ', '00:11:22:33:44:55 ', '00:11:22:33:44:55 q',
702                 '00:11:22:33:44:55 81', '00:11:22:33:44:55 81 1234',
703                 '00:11:22:33:44:55 81 1234 center_freq1=234 center_freq2=345 bandwidth=456 sec_channel_offset=567 ht vht']:
704        if "FAIL" not in dev[0].request("TDLS_CHAN_SWITCH " + args):
705            raise Exception("Unexpected success on invalid TDLS_CHAN_SWITCH: " + args)
706
707@remote_compatible
708def test_wpas_ctrl_addr(dev):
709    """wpa_supplicant ctrl_iface invalid address"""
710    if "FAIL" not in dev[0].request("TDLS_SETUP "):
711        raise Exception("Unexpected success on invalid TDLS_SETUP")
712    if "FAIL" not in dev[0].request("TDLS_TEARDOWN "):
713        raise Exception("Unexpected success on invalid TDLS_TEARDOWN")
714    if "FAIL" not in dev[0].request("FT_DS "):
715        raise Exception("Unexpected success on invalid FT_DS")
716    if "FAIL" not in dev[0].request("WPS_PBC 00:11:22:33:44"):
717        raise Exception("Unexpected success on invalid WPS_PBC")
718    if "FAIL" not in dev[0].request("WPS_PIN 00:11:22:33:44"):
719        raise Exception("Unexpected success on invalid WPS_PIN")
720    if "FAIL" not in dev[0].request("WPS_NFC 00:11:22:33:44"):
721        raise Exception("Unexpected success on invalid WPS_NFC")
722    if "FAIL" not in dev[0].request("WPS_REG 00:11:22:33:44 12345670"):
723        raise Exception("Unexpected success on invalid WPS_REG")
724    if "FAIL" not in dev[0].request("IBSS_RSN 00:11:22:33:44"):
725        raise Exception("Unexpected success on invalid IBSS_RSN")
726    if "FAIL" not in dev[0].request("BSSID_IGNORE 00:11:22:33:44"):
727        raise Exception("Unexpected success on invalid BSSID_IGNORE")
728
729@remote_compatible
730def test_wpas_ctrl_wps_errors(dev):
731    """wpa_supplicant ctrl_iface WPS error cases"""
732    if "FAIL" not in dev[0].request("WPS_REG 00:11:22:33:44:55"):
733        raise Exception("Unexpected success on invalid WPS_REG")
734    if "FAIL" not in dev[0].request("WPS_REG 00:11:22:33:44:55 12345670 2233"):
735        raise Exception("Unexpected success on invalid WPS_REG")
736    if "FAIL" not in dev[0].request("WPS_REG 00:11:22:33:44:55 12345670 2233 OPEN"):
737        raise Exception("Unexpected success on invalid WPS_REG")
738    if "FAIL" not in dev[0].request("WPS_REG 00:11:22:33:44:55 12345670 2233 OPEN NONE"):
739        raise Exception("Unexpected success on invalid WPS_REG")
740
741    if "FAIL" not in dev[0].request("WPS_AP_PIN random"):
742        raise Exception("Unexpected success on WPS_AP_PIN in non-AP mode")
743
744    if "FAIL" not in dev[0].request("WPS_ER_PIN any"):
745        raise Exception("Unexpected success on invalid WPS_ER_PIN")
746
747    if "FAIL" not in dev[0].request("WPS_ER_LEARN 00:11:22:33:44:55"):
748        raise Exception("Unexpected success on invalid WPS_ER_LEARN")
749
750    if "FAIL" not in dev[0].request("WPS_ER_SET_CONFIG 00:11:22:33:44:55"):
751        raise Exception("Unexpected success on invalid WPS_ER_SET_CONFIG")
752
753    if "FAIL" not in dev[0].request("WPS_ER_CONFIG 00:11:22:33:44:55"):
754        raise Exception("Unexpected success on invalid WPS_ER_CONFIG")
755    if "FAIL" not in dev[0].request("WPS_ER_CONFIG 00:11:22:33:44:55 12345670"):
756        raise Exception("Unexpected success on invalid WPS_ER_CONFIG")
757    if "FAIL" not in dev[0].request("WPS_ER_CONFIG 00:11:22:33:44:55 12345670 2233"):
758        raise Exception("Unexpected success on invalid WPS_ER_CONFIG")
759    if "FAIL" not in dev[0].request("WPS_ER_CONFIG 00:11:22:33:44:55 12345670 2233 OPEN"):
760        raise Exception("Unexpected success on invalid WPS_ER_CONFIG")
761    if "FAIL" not in dev[0].request("WPS_ER_CONFIG 00:11:22:33:44:55 12345670 2233 OPEN NONE"):
762        raise Exception("Unexpected success on invalid WPS_ER_CONFIG")
763
764    if "FAIL" not in dev[0].request("WPS_ER_NFC_CONFIG_TOKEN WPS"):
765        raise Exception("Unexpected success on invalid WPS_ER_NFC_CONFIG_TOKEN")
766    if "FAIL" not in dev[0].request("WPS_ER_NFC_CONFIG_TOKEN FOO 00:11:22:33:44:55"):
767        raise Exception("Unexpected success on invalid WPS_ER_NFC_CONFIG_TOKEN")
768    if "FAIL" not in dev[0].request("WPS_ER_NFC_CONFIG_TOKEN NDEF 00:11:22:33:44:55"):
769        raise Exception("Unexpected success on invalid WPS_ER_NFC_CONFIG_TOKEN")
770
771    if "FAIL" not in dev[0].request("WPS_NFC_CONFIG_TOKEN FOO"):
772        raise Exception("Unexpected success on invalid WPS_NFC_CONFIG_TOKEN")
773    if "FAIL" not in dev[0].request("WPS_NFC_CONFIG_TOKEN WPS FOO"):
774        raise Exception("Unexpected success on invalid WPS_NFC_CONFIG_TOKEN")
775    if "FAIL" not in dev[0].request("WPS_NFC_TOKEN FOO"):
776        raise Exception("Unexpected success on invalid WPS_NFC_TOKEN")
777
778@remote_compatible
779def test_wpas_ctrl_config_parser(dev):
780    """wpa_supplicant ctrl_iface SET config parser"""
781    if "FAIL" not in dev[0].request("SET pbc_in_m1 qwerty"):
782        raise Exception("Non-number accepted as integer")
783    if "FAIL" not in dev[0].request("SET eapol_version 0"):
784        raise Exception("Out-of-range value accepted")
785    if "FAIL" not in dev[0].request("SET eapol_version 10"):
786        raise Exception("Out-of-range value accepted")
787
788    if "FAIL" not in dev[0].request("SET serial_number 0123456789abcdef0123456789abcdef0"):
789        raise Exception("Too long string accepted")
790
791@remote_compatible
792def test_wpas_ctrl_mib(dev):
793    """wpa_supplicant ctrl_iface MIB"""
794    mib = dev[0].get_mib()
795    if "dot11RSNAOptionImplemented" not in mib:
796        raise Exception("Missing MIB entry")
797    if mib["dot11RSNAOptionImplemented"] != "TRUE":
798        raise Exception("Unexpected dot11RSNAOptionImplemented value")
799
800def test_wpas_ctrl_set_wps_params(dev):
801    """wpa_supplicant ctrl_iface SET config_methods"""
802    try:
803        _test_wpas_ctrl_set_wps_params(dev)
804    finally:
805        dev[2].request("SET config_methods ")
806
807def _test_wpas_ctrl_set_wps_params(dev):
808    ts = ["config_methods label virtual_display virtual_push_button keypad",
809          "device_type 1-0050F204-1",
810          "os_version 01020300",
811          "uuid 12345678-9abc-def0-1234-56789abcdef0"]
812    for t in ts:
813        if "OK" not in dev[2].request("SET " + t):
814            raise Exception("SET failed for: " + t)
815
816    ts = ["uuid 12345678+9abc-def0-1234-56789abcdef0",
817          "uuid 12345678-qabc-def0-1234-56789abcdef0",
818          "uuid 12345678-9abc+def0-1234-56789abcdef0",
819          "uuid 12345678-9abc-qef0-1234-56789abcdef0",
820          "uuid 12345678-9abc-def0+1234-56789abcdef0",
821          "uuid 12345678-9abc-def0-q234-56789abcdef0",
822          "uuid 12345678-9abc-def0-1234+56789abcdef0",
823          "uuid 12345678-9abc-def0-1234-q6789abcdef0",
824          "uuid qwerty"]
825    for t in ts:
826        if "FAIL" not in dev[2].request("SET " + t):
827            raise Exception("SET succeeded for: " + t)
828
829def test_wpas_ctrl_level(dev):
830    """wpa_supplicant ctrl_iface LEVEL"""
831    try:
832        if "FAIL" not in dev[2].request("LEVEL 3"):
833            raise Exception("Unexpected LEVEL success")
834        if "OK" not in dev[2].mon.request("LEVEL 2"):
835            raise Exception("Unexpected LEVEL failure")
836        dev[2].request("SCAN freq=2412")
837        ev = dev[2].wait_event(["State:"], timeout=5)
838        if ev is None:
839            raise Exception("No debug message received")
840        dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=5)
841    finally:
842        dev[2].mon.request("LEVEL 3")
843
844@remote_compatible
845def test_wpas_ctrl_bssid_filter(dev, apdev):
846    """wpa_supplicant bssid_filter"""
847    try:
848        if "OK" not in dev[2].request("SET bssid_filter " + apdev[0]['bssid']):
849            raise Exception("Failed to set bssid_filter")
850        params = {"ssid": "test"}
851        hostapd.add_ap(apdev[0], params)
852        hostapd.add_ap(apdev[1], params)
853        dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
854        dev[2].scan(freq="2412")
855        bss = dev[2].get_bss(apdev[0]['bssid'])
856        if bss is None or len(bss) == 0:
857            raise Exception("Missing BSS data")
858        bss = dev[2].get_bss(apdev[1]['bssid'])
859        if bss and len(bss) != 0:
860            raise Exception("Unexpected BSS data")
861        dev[2].request("SET bssid_filter " + apdev[0]['bssid'] + " " + \
862                       apdev[1]['bssid'])
863        dev[2].scan(freq="2412")
864        bss = dev[2].get_bss(apdev[0]['bssid'])
865        if bss is None or len(bss) == 0:
866            raise Exception("Missing BSS data")
867        bss = dev[2].get_bss(apdev[1]['bssid'])
868        if bss is None or len(bss) == 0:
869            raise Exception("Missing BSS data(2)")
870        res = dev[2].request("SCAN_RESULTS").splitlines()
871        if "test" not in res[1] or "test" not in res[2]:
872            raise Exception("SSID missing from SCAN_RESULTS")
873        if apdev[0]['bssid'] not in res[1] and apdev[1]['bssid'] not in res[1]:
874            raise Exception("BSS1 missing from SCAN_RESULTS")
875        if apdev[0]['bssid'] not in res[2] and apdev[1]['bssid'] not in res[2]:
876            raise Exception("BSS1 missing from SCAN_RESULTS")
877
878        if "FAIL" not in dev[2].request("SET bssid_filter 00:11:22:33:44:55 00:11:22:33:44"):
879            raise Exception("Unexpected success for invalid SET bssid_filter")
880    finally:
881        dev[2].request("SET bssid_filter ")
882
883@remote_compatible
884def test_wpas_ctrl_disallow_aps(dev, apdev):
885    """wpa_supplicant ctrl_iface disallow_aps"""
886    params = {"ssid": "test"}
887    hostapd.add_ap(apdev[0], params)
888
889    if "FAIL" not in dev[0].request("SET disallow_aps bssid "):
890        raise Exception("Unexpected success on invalid disallow_aps")
891    if "FAIL" not in dev[0].request("SET disallow_aps bssid 00:11:22:33:44"):
892        raise Exception("Unexpected success on invalid disallow_aps")
893    if "FAIL" not in dev[0].request("SET disallow_aps ssid 0"):
894        raise Exception("Unexpected success on invalid disallow_aps")
895    if "FAIL" not in dev[0].request("SET disallow_aps ssid 4q"):
896        raise Exception("Unexpected success on invalid disallow_aps")
897    if "FAIL" not in dev[0].request("SET disallow_aps bssid 00:11:22:33:44:55 ssid 112233 ssid 123"):
898        raise Exception("Unexpected success on invalid disallow_aps")
899    if "FAIL" not in dev[0].request("SET disallow_aps ssid 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f00"):
900        raise Exception("Unexpected success on invalid disallow_aps")
901    if "FAIL" not in dev[0].request("SET disallow_aps foo 112233445566"):
902        raise Exception("Unexpected success on invalid disallow_aps")
903
904    dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
905    hostapd.add_ap(apdev[1], params)
906    dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
907    dev[0].dump_monitor()
908    if "OK" not in dev[0].request("SET disallow_aps bssid 00:11:22:33:44:55 bssid 00:22:33:44:55:66"):
909        raise Exception("Failed to set disallow_aps")
910    if "OK" not in dev[0].request("SET disallow_aps bssid " + apdev[0]['bssid']):
911        raise Exception("Failed to set disallow_aps")
912    ev = dev[0].wait_connected(timeout=30, error="Reassociation timed out")
913    if apdev[1]['bssid'] not in ev:
914        raise Exception("Unexpected BSSID")
915
916    dev[0].dump_monitor()
917    if "OK" not in dev[0].request("SET disallow_aps ssid " + binascii.hexlify(b"test").decode()):
918        raise Exception("Failed to set disallow_aps")
919    dev[0].wait_disconnected(timeout=5, error="Disconnection not seen")
920    ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
921    if ev is not None:
922        raise Exception("Unexpected reassociation")
923
924    dev[0].request("DISCONNECT")
925    dev[0].p2p_start_go(freq=2412)
926    if "OK" not in dev[0].request("SET disallow_aps "):
927        raise Exception("Failed to set disallow_aps")
928
929@remote_compatible
930def test_wpas_ctrl_blob(dev):
931    """wpa_supplicant ctrl_iface SET blob"""
932    if "FAIL" not in dev[0].request("SET blob foo"):
933        raise Exception("Unexpected SET success")
934    if "FAIL" not in dev[0].request("SET blob foo 0"):
935        raise Exception("Unexpected SET success")
936    if "FAIL" not in dev[0].request("SET blob foo 0q"):
937        raise Exception("Unexpected SET success")
938    if "OK" not in dev[0].request("SET blob foo 00"):
939        raise Exception("Unexpected SET failure")
940    if "OK" not in dev[0].request("SET blob foo 0011"):
941        raise Exception("Unexpected SET failure")
942
943@remote_compatible
944def test_wpas_ctrl_set_uapsd(dev):
945    """wpa_supplicant ctrl_iface SET uapsd"""
946    if "FAIL" not in dev[0].request("SET uapsd foo"):
947        raise Exception("Unexpected SET success")
948    if "FAIL" not in dev[0].request("SET uapsd 0,0,0"):
949        raise Exception("Unexpected SET success")
950    if "FAIL" not in dev[0].request("SET uapsd 0,0"):
951        raise Exception("Unexpected SET success")
952    if "FAIL" not in dev[0].request("SET uapsd 0"):
953        raise Exception("Unexpected SET success")
954    if "OK" not in dev[0].request("SET uapsd 1,1,1,1;1"):
955        raise Exception("Unexpected SET failure")
956    if "OK" not in dev[0].request("SET uapsd 0,0,0,0;0"):
957        raise Exception("Unexpected SET failure")
958    if "OK" not in dev[0].request("SET uapsd disable"):
959        raise Exception("Unexpected SET failure")
960
961def test_wpas_ctrl_set(dev):
962    """wpa_supplicant ctrl_iface SET"""
963    vals = ["foo",
964            "ampdu 0",
965            "radio_disable 0",
966            "ps 10",
967            "dot11RSNAConfigPMKLifetime 0",
968            "dot11RSNAConfigPMKReauthThreshold 101",
969            "dot11RSNAConfigSATimeout 0",
970            "wps_version_number -1",
971            "wps_version_number 256",
972            "fst_group_id ",
973            "fst_llt 0"]
974    for val in vals:
975        if "FAIL" not in dev[0].request("SET " + val):
976            raise Exception("Unexpected SET success for " + val)
977
978    vals = ["ps 1"]
979    for val in vals:
980        dev[0].request("SET " + val)
981
982    vals = ["EAPOL::heldPeriod 60",
983            "EAPOL::authPeriod 30",
984            "EAPOL::startPeriod 30",
985            "EAPOL::maxStart 3",
986            "dot11RSNAConfigSATimeout 60",
987            "ps -1",
988            "ps 0",
989            "no_keep_alive 0",
990            "tdls_disabled 1",
991            "tdls_disabled 0"]
992    for val in vals:
993        if "OK" not in dev[0].request("SET " + val):
994            raise Exception("Unexpected SET failure for " + val)
995
996    # This fails if wpa_supplicant is built with loadable EAP peer method
997    # support due to missing file and succeeds if no support for loadable
998    # methods is included, so don't check the return value for now.
999    dev[0].request("SET load_dynamic_eap /tmp/hwsim-eap-not-found.so")
1000
1001@remote_compatible
1002def test_wpas_ctrl_get_capability(dev):
1003    """wpa_supplicant ctrl_iface GET_CAPABILITY"""
1004    if "FAIL" not in dev[0].request("GET_CAPABILITY 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"):
1005        raise Exception("Unexpected success on invalid GET_CAPABILITY")
1006    if "FAIL" not in dev[0].request("GET_CAPABILITY eap foo"):
1007        raise Exception("Unexpected success on invalid GET_CAPABILITY")
1008    if "AP" not in dev[0].request("GET_CAPABILITY modes strict"):
1009        raise Exception("Unexpected GET_CAPABILITY response")
1010    res = dev[0].get_capability("eap")
1011    if "TTLS" not in res:
1012        raise Exception("Unexpected GET_CAPABILITY eap response: " + str(res))
1013
1014    res = dev[0].get_capability("pairwise")
1015    if "CCMP" not in res:
1016        raise Exception("Unexpected GET_CAPABILITY pairwise response: " + str(res))
1017
1018    res = dev[0].get_capability("group")
1019    if "CCMP" not in res:
1020        raise Exception("Unexpected GET_CAPABILITY group response: " + str(res))
1021
1022    res = dev[0].get_capability("key_mgmt")
1023    if "WPA-PSK" not in res or "WPA-EAP" not in res:
1024        raise Exception("Unexpected GET_CAPABILITY key_mgmt response: " + str(res))
1025
1026    res = dev[0].get_capability("key_mgmt iftype=STATION")
1027    if "WPA-PSK" not in res or "WPA-EAP" not in res:
1028        raise Exception("Unexpected GET_CAPABILITY key_mgmt iftype=STATION response: " + str(res))
1029
1030    iftypes = [ "STATION", "AP_VLAN", "AP", "P2P_GO", "P2P_CLIENT",
1031                "P2P_DEVICE", "MESH", "IBSS", "NAN", "UNKNOWN" ]
1032    for i in iftypes:
1033        res = dev[0].get_capability("key_mgmt iftype=" + i)
1034        logger.info("GET_CAPABILITY key_mgmt iftype=%s: %s" % (i, res))
1035
1036    res = dev[0].get_capability("proto")
1037    if "WPA" not in res or "RSN" not in res:
1038        raise Exception("Unexpected GET_CAPABILITY proto response: " + str(res))
1039
1040    res = dev[0].get_capability("auth_alg")
1041    if "OPEN" not in res or "SHARED" not in res:
1042        raise Exception("Unexpected GET_CAPABILITY auth_alg response: " + str(res))
1043
1044    res = dev[0].get_capability("modes")
1045    if "IBSS" not in res or "AP" not in res:
1046        raise Exception("Unexpected GET_CAPABILITY modes response: " + str(res))
1047
1048    res = dev[0].get_capability("channels")
1049    if "8" not in res or "36" not in res:
1050        raise Exception("Unexpected GET_CAPABILITY channels response: " + str(res))
1051
1052    res = dev[0].get_capability("freq")
1053    if "2457" not in res or "5180" not in res:
1054        raise Exception("Unexpected GET_CAPABILITY freq response: " + str(res))
1055
1056    res = dev[0].get_capability("tdls")
1057    if "EXTERNAL" not in res[0]:
1058        raise Exception("Unexpected GET_CAPABILITY tdls response: " + str(res))
1059
1060    res = dev[0].get_capability("erp")
1061    if res is None or "ERP" not in res[0]:
1062        raise Exception("Unexpected GET_CAPABILITY erp response: " + str(res))
1063
1064    if dev[0].get_capability("foo") is not None:
1065        raise Exception("Unexpected GET_CAPABILITY foo response: " + str(res))
1066
1067@remote_compatible
1068def test_wpas_ctrl_nfc_report_handover(dev):
1069    """wpa_supplicant ctrl_iface NFC_REPORT_HANDOVER"""
1070    vals = ["FOO",
1071            "ROLE freq=12345",
1072            "ROLE TYPE",
1073            "ROLE TYPE REQ",
1074            "ROLE TYPE REQ SEL",
1075            "ROLE TYPE 0Q SEL",
1076            "ROLE TYPE 00 SEL",
1077            "ROLE TYPE 00 0Q",
1078            "ROLE TYPE 00 00"]
1079    for v in vals:
1080        if "FAIL" not in dev[0].request("NFC_REPORT_HANDOVER " + v):
1081            raise Exception("Unexpected NFC_REPORT_HANDOVER success for " + v)
1082
1083@remote_compatible
1084def test_wpas_ctrl_nfc_tag_read(dev):
1085    """wpa_supplicant ctrl_iface WPS_NFC_TAG_READ"""
1086    vals = ["FOO", "0Q", "00", "000000", "10000001", "10000000", "00000000",
1087            "100e0000", "100e0001ff", "100e000411110000", "100e0004100e0001"]
1088    for v in vals:
1089        if "FAIL" not in dev[0].request("WPS_NFC_TAG_READ " + v):
1090            raise Exception("Unexpected WPS_NFC_TAG_READ success for " + v)
1091
1092@remote_compatible
1093def test_wpas_ctrl_nfc_get_handover(dev):
1094    """wpa_supplicant ctrl_iface NFC_GET_HANDOVER"""
1095    vals = ["FOO", "FOO BAR", "WPS WPS", "WPS WPS-CR", "WPS FOO", "NDEF P2P"]
1096    for v in vals:
1097        if "FAIL" not in dev[0].request("NFC_GET_HANDOVER_REQ " + v):
1098            raise Exception("Unexpected NFC_GET_HANDOVER_REQ success for " + v)
1099
1100    vals = ["NDEF WPS", "NDEF P2P-CR", "WPS P2P-CR"]
1101    for v in vals:
1102        if "FAIL" in dev[0].request("NFC_GET_HANDOVER_REQ " + v):
1103            raise Exception("Unexpected NFC_GET_HANDOVER_REQ failure for " + v)
1104
1105    vals = ["FOO", "FOO BAR", "WPS WPS", "WPS WPS-CR", "WPS FOO", "NDEF P2P",
1106            "NDEF WPS", "NDEF WPS uuid"]
1107    for v in vals:
1108        if "FAIL" not in dev[0].request("NFC_GET_HANDOVER_SEL " + v):
1109            raise Exception("Unexpected NFC_GET_HANDOVER_SEL success for " + v)
1110
1111    vals = ["NDEF P2P-CR", "WPS P2P-CR", "NDEF P2P-CR-TAG",
1112            "WPS P2P-CR-TAG"]
1113    for v in vals:
1114        if "FAIL" in dev[0].request("NFC_GET_HANDOVER_SEL " + v):
1115            raise Exception("Unexpected NFC_GET_HANDOVER_SEL failure for " + v)
1116
1117def get_bssid_ignore_list(dev):
1118    return dev.request("BSSID_IGNORE").splitlines()
1119
1120@remote_compatible
1121def test_wpas_ctrl_bssid_ignore(dev):
1122    """wpa_supplicant ctrl_iface BSSID_IGNORE"""
1123    if "OK" not in dev[0].request("BSSID_IGNORE clear"):
1124        raise Exception("BSSID_IGNORE clear failed")
1125    b = get_bssid_ignore_list(dev[0])
1126    if len(b) != 0:
1127        raise Exception("Unexpected BSSID ignore list contents: " + str(b))
1128    if "OK" not in dev[0].request("BSSID_IGNORE 00:11:22:33:44:55"):
1129        raise Exception("BSSID_IGNORE add failed")
1130    b = get_bssid_ignore_list(dev[0])
1131    if "00:11:22:33:44:55" not in b:
1132        raise Exception("Unexpected BSSID ignore list contents: " + str(b))
1133    if "OK" not in dev[0].request("BSSID_IGNORE 00:11:22:33:44:56"):
1134        raise Exception("BSSID_IGNORE add failed")
1135    b = get_bssid_ignore_list(dev[0])
1136    if "00:11:22:33:44:55" not in b or "00:11:22:33:44:56" not in b:
1137        raise Exception("Unexpected BSSID ignore list contents: " + str(b))
1138    if "OK" not in dev[0].request("BSSID_IGNORE 00:11:22:33:44:56"):
1139        raise Exception("BSSID_IGNORE add failed")
1140    b = get_bssid_ignore_list(dev[0])
1141    if "00:11:22:33:44:55" not in b or "00:11:22:33:44:56" not in b or len(b) != 2:
1142        raise Exception("Unexpected BSSID ignore list contents: " + str(b))
1143
1144    if "OK" not in dev[0].request("BSSID_IGNORE clear"):
1145        raise Exception("BSSID_IGNORE clear failed")
1146    if dev[0].request("BSSID_IGNORE") != "":
1147        raise Exception("Unexpected BSSID ignore list contents")
1148
1149@remote_compatible
1150def test_wpas_ctrl_bssid_ignore_oom(dev):
1151    """wpa_supplicant ctrl_iface BSSID_IGNORE and out-of-memory"""
1152    with alloc_fail(dev[0], 1, "wpa_bssid_ignore_add"):
1153        if "FAIL" not in dev[0].request("BSSID_IGNORE aa:bb:cc:dd:ee:ff"):
1154            raise Exception("Unexpected success with allocation failure")
1155
1156def test_wpas_ctrl_log_level(dev):
1157    """wpa_supplicant ctrl_iface LOG_LEVEL"""
1158    level = dev[2].request("LOG_LEVEL")
1159    if "Current level: MSGDUMP" not in level:
1160        raise Exception("Unexpected debug level(1): " + level)
1161    if "Timestamp: 1" not in level:
1162        raise Exception("Unexpected timestamp(1): " + level)
1163
1164    if "OK" not in dev[2].request("LOG_LEVEL  MSGDUMP  0"):
1165        raise Exception("LOG_LEVEL failed")
1166    level = dev[2].request("LOG_LEVEL")
1167    if "Current level: MSGDUMP" not in level:
1168        raise Exception("Unexpected debug level(2): " + level)
1169    if "Timestamp: 0" not in level:
1170        raise Exception("Unexpected timestamp(2): " + level)
1171
1172    if "OK" not in dev[2].request("LOG_LEVEL  MSGDUMP  1"):
1173        raise Exception("LOG_LEVEL failed")
1174    level = dev[2].request("LOG_LEVEL")
1175    if "Current level: MSGDUMP" not in level:
1176        raise Exception("Unexpected debug level(3): " + level)
1177    if "Timestamp: 1" not in level:
1178        raise Exception("Unexpected timestamp(3): " + level)
1179
1180    if "FAIL" not in dev[2].request("LOG_LEVEL FOO"):
1181        raise Exception("Invalid LOG_LEVEL accepted")
1182
1183    for lev in ["EXCESSIVE", "MSGDUMP", "DEBUG", "INFO", "WARNING", "ERROR"]:
1184        if "OK" not in dev[2].request("LOG_LEVEL " + lev):
1185            raise Exception("LOG_LEVEL failed for " + lev)
1186        level = dev[2].request("LOG_LEVEL")
1187        if "Current level: " + lev not in level:
1188            raise Exception("Unexpected debug level: " + level)
1189
1190    if "OK" not in dev[2].request("LOG_LEVEL  MSGDUMP  1"):
1191        raise Exception("LOG_LEVEL failed")
1192    level = dev[2].request("LOG_LEVEL")
1193    if "Current level: MSGDUMP" not in level:
1194        raise Exception("Unexpected debug level(3): " + level)
1195    if "Timestamp: 1" not in level:
1196        raise Exception("Unexpected timestamp(3): " + level)
1197
1198@remote_compatible
1199def test_wpas_ctrl_enable_disable_network(dev, apdev):
1200    """wpa_supplicant ctrl_iface ENABLE/DISABLE_NETWORK"""
1201    params = {"ssid": "test"}
1202    hostapd.add_ap(apdev[0], params)
1203
1204    id = dev[0].connect("test", key_mgmt="NONE", scan_freq="2412",
1205                        only_add_network=True)
1206    if "OK" not in dev[0].request("DISABLE_NETWORK " + str(id)):
1207        raise Exception("Failed to disable network")
1208    if "OK" not in dev[0].request("ENABLE_NETWORK " + str(id) + " no-connect"):
1209        raise Exception("Failed to enable network")
1210    if "OK" not in dev[0].request("DISABLE_NETWORK all"):
1211        raise Exception("Failed to disable networks")
1212    if "OK" not in dev[0].request("ENABLE_NETWORK " + str(id)):
1213        raise Exception("Failed to enable network")
1214    dev[0].wait_connected(timeout=10)
1215    if "OK" not in dev[0].request("DISABLE_NETWORK " + str(id)):
1216        raise Exception("Failed to disable network")
1217    dev[0].wait_disconnected(timeout=10)
1218    time.sleep(0.1)
1219
1220    if "OK" not in dev[0].request("ENABLE_NETWORK all"):
1221        raise Exception("Failed to enable network")
1222    dev[0].wait_connected(timeout=10)
1223    if "OK" not in dev[0].request("DISABLE_NETWORK all"):
1224        raise Exception("Failed to disable network")
1225    dev[0].wait_disconnected(timeout=10)
1226
1227def test_wpas_ctrl_country(dev, apdev):
1228    """wpa_supplicant SET/GET country code"""
1229    try:
1230        # work around issues with possible pending regdom event from the end of
1231        # the previous test case
1232        time.sleep(0.2)
1233        dev[0].dump_monitor()
1234
1235        if "OK" not in dev[0].request("SET country FI"):
1236            raise Exception("Failed to set country code")
1237        if dev[0].request("GET country") != "FI":
1238            raise Exception("Country code set failed")
1239        ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], 10)
1240        if ev is None:
1241            raise Exception("regdom change event not seen")
1242        if "init=USER type=COUNTRY alpha2=FI" not in ev:
1243            raise Exception("Unexpected event contents: " + ev)
1244        dev[0].request("SET country 00")
1245        if dev[0].request("GET country") != "00":
1246            raise Exception("Country code set failed")
1247        ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], 10)
1248        if ev is None:
1249            raise Exception("regdom change event not seen")
1250        # init=CORE was previously used due to invalid db.txt data for 00. For
1251        # now, allow both it and the new init=USER after fixed db.txt.
1252        if "init=CORE type=WORLD" not in ev and "init=USER type=WORLD" not in ev:
1253            raise Exception("Unexpected event contents: " + ev)
1254    finally:
1255        subprocess.call(['iw', 'reg', 'set', '00'])
1256
1257def test_wpas_ctrl_suspend_resume(dev):
1258    """wpa_supplicant SUSPEND/RESUME"""
1259    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1260    wpas.interface_add("wlan5")
1261    if "OK" not in wpas.global_request("SUSPEND"):
1262        raise Exception("SUSPEND failed")
1263    time.sleep(1)
1264    if "OK" not in wpas.global_request("RESUME"):
1265        raise Exception("RESUME failed")
1266    if "OK" not in wpas.request("SUSPEND"):
1267        raise Exception("Per-interface SUSPEND failed")
1268    if "OK" not in wpas.request("RESUME"):
1269        raise Exception("Per-interface RESUME failed")
1270    ev = wpas.wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1271    if ev is None:
1272        raise Exception("Scan not completed")
1273
1274def test_wpas_ctrl_global(dev):
1275    """wpa_supplicant global control interface"""
1276    wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1277    wpas.interface_add("wlan5")
1278
1279    if "PONG" not in wpas.global_request("PING"):
1280        raise Exception("PING failed")
1281    if "wlan5" not in wpas.global_request("INTERFACES"):
1282        raise Exception("Interface not found")
1283    if "UNKNOWN COMMAND" not in wpas.global_request("FOO"):
1284        raise Exception("Unexpected response to unknown command")
1285    if "PONG" not in wpas.global_request("IFNAME=wlan5 PING"):
1286        raise Exception("Per-interface PING failed")
1287    if "FAIL-NO-IFNAME-MATCH" not in wpas.global_request("IFNAME=notfound PING"):
1288        raise Exception("Unknown interface not reported correctly")
1289    if "FAIL" not in wpas.global_request("SAVE_CONFIG"):
1290        raise Exception("SAVE_CONFIG succeeded unexpectedly")
1291    if "OK" not in wpas.global_request("SET wifi_display 0"):
1292        raise Exception("SET failed")
1293    if "wifi_display=0" not in wpas.global_request("STATUS"):
1294        raise Exception("wifi_display not disabled")
1295    if "OK" not in wpas.global_request("SET wifi_display 1"):
1296        raise Exception("SET failed")
1297    if "wifi_display=1" not in wpas.global_request("STATUS"):
1298        raise Exception("wifi_display not enabled")
1299    if "FAIL" not in wpas.global_request("SET foo 1"):
1300        raise Exception("SET succeeded unexpectedly")
1301
1302    if "p2p_state=IDLE" not in wpas.global_request("STATUS"):
1303        raise Exception("P2P was disabled")
1304    wpas.global_request("P2P_SET disabled 1")
1305    if "p2p_state=DISABLED" not in wpas.global_request("STATUS"):
1306        raise Exception("P2P was not disabled")
1307    wpas.global_request("P2P_SET disabled 0")
1308    if "p2p_state=IDLE" not in wpas.global_request("STATUS"):
1309        raise Exception("P2P was not enabled")
1310
1311    # driver_nl80211.c does not support interface list, so do not fail because
1312    # of that
1313    logger.debug(wpas.global_request("INTERFACE_LIST"))
1314
1315    if "FAIL" not in wpas.global_request("INTERFACE_ADD "):
1316        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1317    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO"):
1318        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1319    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO	conf"):
1320        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1321    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO	conf	driver"):
1322        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1323    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO	conf	driver	ctrliface"):
1324        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1325    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO	conf	driver	ctrliface	driverparam"):
1326        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1327    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO	conf	driver	ctrliface	driverparam	bridge"):
1328        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1329    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO	conf	driver	ctrliface	driverparam	bridge	foo"):
1330        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1331    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO					"):
1332        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1333    if "FAIL" not in wpas.global_request("INTERFACE_ADD FOO	conf	driver	ctrliface	driverparam	bridge	create	abcd"):
1334        raise Exception("INTERFACE_ADD succeeded unexpectedly")
1335
1336@remote_compatible
1337def test_wpas_ctrl_roam(dev, apdev):
1338    """wpa_supplicant ctrl_iface ROAM error cases"""
1339    if "FAIL" not in dev[0].request("ROAM 00:11:22:33:44"):
1340        raise Exception("Unexpected success")
1341    if "FAIL" not in dev[0].request("ROAM 00:11:22:33:44:55"):
1342        raise Exception("Unexpected success")
1343    params = {"ssid": "test"}
1344    hostapd.add_ap(apdev[0], params)
1345    id = dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
1346    if "FAIL" not in dev[0].request("ROAM 00:11:22:33:44:55"):
1347        raise Exception("Unexpected success")
1348
1349@remote_compatible
1350def test_wpas_ctrl_ipaddr(dev, apdev):
1351    """wpa_supplicant IP address in STATUS"""
1352    try:
1353        dev[0].cmd_execute(['ip', 'addr', 'add', '10.174.65.207/32', 'dev',
1354                            dev[0].ifname])
1355        ipaddr = dev[0].get_status_field('ip_address')
1356        if ipaddr != '10.174.65.207':
1357            raise Exception("IP address not in STATUS output")
1358    finally:
1359        dev[0].cmd_execute(['ip', 'addr', 'del', '10.174.65.207/32', 'dev',
1360                            dev[0].ifname])
1361
1362@remote_compatible
1363def test_wpas_ctrl_rsp(dev, apdev):
1364    """wpa_supplicant ctrl_iface CTRL-RSP-"""
1365    if "FAIL" not in dev[0].request("CTRL-RSP-"):
1366        raise Exception("Request succeeded unexpectedly")
1367    if "FAIL" not in dev[0].request("CTRL-RSP-foo-"):
1368        raise Exception("Request succeeded unexpectedly")
1369    if "FAIL" not in dev[0].request("CTRL-RSP-foo-1234567"):
1370        raise Exception("Request succeeded unexpectedly")
1371    if "FAIL" not in dev[0].request("CTRL-RSP-foo-1234567:"):
1372        raise Exception("Request succeeded unexpectedly")
1373    id = dev[0].add_network()
1374    if "FAIL" not in dev[0].request("CTRL-RSP-foo-%d:" % id):
1375        raise Exception("Request succeeded unexpectedly")
1376    for req in ["IDENTITY", "PASSWORD", "NEW_PASSWORD", "PIN", "OTP",
1377                "PASSPHRASE", "SIM"]:
1378        if "OK" not in dev[0].request("CTRL-RSP-%s-%d:" % (req, id)):
1379            raise Exception("Request failed unexpectedly")
1380        if "OK" not in dev[0].request("CTRL-RSP-%s-%d:" % (req, id)):
1381            raise Exception("Request failed unexpectedly")
1382
1383def test_wpas_ctrl_vendor_test(dev, apdev):
1384    """wpas_supplicant and VENDOR test command"""
1385    OUI_QCA = 0x001374
1386    QCA_NL80211_VENDOR_SUBCMD_TEST = 1
1387    QCA_WLAN_VENDOR_ATTR_TEST = 8
1388    attr = struct.pack("@HHI", 4 + 4, QCA_WLAN_VENDOR_ATTR_TEST, 123)
1389    cmd = "VENDOR %x %d %s" % (OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_TEST, binascii.hexlify(attr).decode())
1390
1391    res = dev[0].request(cmd)
1392    if "FAIL" in res:
1393        raise Exception("VENDOR command failed")
1394    val, = struct.unpack("@I", binascii.unhexlify(res))
1395    if val != 125:
1396        raise Exception("Incorrect response value")
1397
1398    res = dev[0].request(cmd + " nested=1")
1399    if "FAIL" in res:
1400        raise Exception("VENDOR command failed")
1401    val, = struct.unpack("@I", binascii.unhexlify(res))
1402    if val != 125:
1403        raise Exception("Incorrect response value")
1404
1405    res = dev[0].request(cmd + " nested=0")
1406    if "FAIL" not in res:
1407        raise Exception("VENDOR command with invalid (not nested) data accepted")
1408
1409@remote_compatible
1410def test_wpas_ctrl_vendor(dev, apdev):
1411    """wpa_supplicant ctrl_iface VENDOR"""
1412    cmds = ["foo",
1413            "1",
1414            "1 foo",
1415            "1 2foo",
1416            "1 2 qq"]
1417    for cmd in cmds:
1418        if "FAIL" not in dev[0].request("VENDOR " + cmd):
1419            raise Exception("Invalid VENDOR command accepted: " + cmd)
1420
1421@remote_compatible
1422def test_wpas_ctrl_mgmt_tx(dev, apdev):
1423    """wpa_supplicant ctrl_iface MGMT_TX"""
1424    cmds = ["foo",
1425            "00:11:22:33:44:55 foo",
1426            "00:11:22:33:44:55 11:22:33:44:55:66",
1427            "00:11:22:33:44:55 11:22:33:44:55:66 freq=0 no_cck=0 wait_time=0 action=123",
1428            "00:11:22:33:44:55 11:22:33:44:55:66 action=12qq"]
1429    for cmd in cmds:
1430        if "FAIL" not in dev[0].request("MGMT_TX " + cmd):
1431            raise Exception("Invalid MGMT_TX command accepted: " + cmd)
1432
1433    if "OK" not in dev[0].request("MGMT_TX_DONE"):
1434        raise Exception("MGMT_TX_DONE failed")
1435
1436@remote_compatible
1437def test_wpas_ctrl_driver_event(dev, apdev):
1438    """wpa_supplicant ctrl_iface DRIVER_EVENT"""
1439    if "FAIL" not in dev[0].request("DRIVER_EVENT foo"):
1440        raise Exception("Invalid DRIVER_EVENT accepted")
1441    if "OK" not in dev[0].request("DRIVER_EVENT ASSOC reassoc=1 req_ies=0000 resp_ies=0000 resp_frame=0000 beacon_ies=0000 freq=2412 wmm::info_bitmap=0 wmm::uapsd_queues=0 addr=02:02:02:02:02:02 authorized=0 key_replay_ctr=00 ptk_kck=00 ptk_kek=00 subnet_status=0 fils_erp_next_seq_num=0 fils_pmk=00 fils_pmkid=" + 16*"00"):
1442        raise Exception("DRIVER_EVENT ASSOC did not succeed")
1443
1444@remote_compatible
1445def test_wpas_ctrl_eapol_rx(dev, apdev):
1446    """wpa_supplicant ctrl_iface EAPOL_RX"""
1447    cmds = ["foo",
1448            "00:11:22:33:44:55 123",
1449            "00:11:22:33:44:55 12qq"]
1450    for cmd in cmds:
1451        if "FAIL" not in dev[0].request("EAPOL_RX " + cmd):
1452            raise Exception("Invalid EAPOL_RX command accepted: " + cmd)
1453
1454@remote_compatible
1455def test_wpas_ctrl_data_test(dev, apdev):
1456    """wpa_supplicant ctrl_iface DATA_TEST"""
1457    dev[0].request("DATA_TEST_CONFIG 0")
1458    if "FAIL" not in dev[0].request("DATA_TEST_TX 00:11:22:33:44:55 00:11:22:33:44:55 0"):
1459        raise Exception("DATA_TEST_TX accepted when not in test mode")
1460
1461    try:
1462        if "OK" not in dev[0].request("DATA_TEST_CONFIG 1"):
1463            raise Exception("DATA_TEST_CONFIG failed")
1464        if "OK" not in dev[0].request("DATA_TEST_CONFIG 1"):
1465            raise Exception("DATA_TEST_CONFIG failed")
1466        cmds = ["foo",
1467                "00:11:22:33:44:55 foo",
1468                "00:11:22:33:44:55 00:11:22:33:44:55 -1",
1469                "00:11:22:33:44:55 00:11:22:33:44:55 256"]
1470        for cmd in cmds:
1471            if "FAIL" not in dev[0].request("DATA_TEST_TX " + cmd):
1472                raise Exception("Invalid DATA_TEST_TX command accepted: " + cmd)
1473        if "OK" not in dev[0].request("DATA_TEST_TX 00:11:22:33:44:55 00:11:22:33:44:55 0"):
1474            raise Exception("DATA_TEST_TX failed")
1475    finally:
1476        dev[0].request("DATA_TEST_CONFIG 0")
1477
1478    cmds = ["",
1479            "00",
1480            "00112233445566778899aabbccdde",
1481            "00112233445566778899aabbccdq"]
1482    for cmd in cmds:
1483        if "FAIL" not in dev[0].request("DATA_TEST_FRAME " + cmd):
1484            raise Exception("Invalid DATA_TEST_FRAME command accepted: " + cmd)
1485
1486    if "OK" not in dev[0].request("DATA_TEST_FRAME 00112233445566778899aabbccddee"):
1487        raise Exception("DATA_TEST_FRAME failed")
1488
1489@remote_compatible
1490def test_wpas_ctrl_vendor_elem(dev, apdev):
1491    """wpa_supplicant ctrl_iface VENDOR_ELEM"""
1492    if "OK" not in dev[0].request("VENDOR_ELEM_ADD 1 "):
1493        raise Exception("VENDOR_ELEM_ADD failed")
1494    cmds = ["-1 ",
1495            "255 ",
1496            "1",
1497            "1 123",
1498            "1 12qq34"]
1499    for cmd in cmds:
1500        if "FAIL" not in dev[0].request("VENDOR_ELEM_ADD " + cmd):
1501            raise Exception("Invalid VENDOR_ELEM_ADD command accepted: " + cmd)
1502
1503    cmds = ["-1 ",
1504            "255 "]
1505    for cmd in cmds:
1506        if "FAIL" not in dev[0].request("VENDOR_ELEM_GET " + cmd):
1507            raise Exception("Invalid VENDOR_ELEM_GET command accepted: " + cmd)
1508
1509    dev[0].request("VENDOR_ELEM_REMOVE 1 *")
1510    cmds = ["-1 ",
1511            "255 ",
1512            "1",
1513            "1",
1514            "1 123",
1515            "1 12qq34",
1516            "1 12",
1517            "1 0000"]
1518    for cmd in cmds:
1519        if "FAIL" not in dev[0].request("VENDOR_ELEM_REMOVE " + cmd):
1520            raise Exception("Invalid VENDOR_ELEM_REMOVE command accepted: " + cmd)
1521
1522    dev[0].request("VENDOR_ELEM_ADD 1 000100")
1523    if "OK" not in dev[0].request("VENDOR_ELEM_REMOVE 1 "):
1524        raise Exception("VENDOR_ELEM_REMOVE failed")
1525    cmds = ["-1 ",
1526            "255 ",
1527            "1",
1528            "1 123",
1529            "1 12qq34",
1530            "1 12",
1531            "1 0000"]
1532    for cmd in cmds:
1533        if "FAIL" not in dev[0].request("VENDOR_ELEM_REMOVE " + cmd):
1534            raise Exception("Invalid VENDOR_ELEM_REMOVE command accepted: " + cmd)
1535    if "OK" not in dev[0].request("VENDOR_ELEM_REMOVE 1 000100"):
1536        raise Exception("VENDOR_ELEM_REMOVE failed")
1537
1538def test_wpas_ctrl_misc(dev, apdev):
1539    """wpa_supplicant ctrl_iface and miscellaneous commands"""
1540    if "OK" not in dev[0].request("RELOG"):
1541        raise Exception("RELOG failed")
1542    if dev[0].request("IFNAME") != dev[0].ifname:
1543        raise Exception("IFNAME returned unexpected response")
1544    if "FAIL" not in dev[0].request("REATTACH"):
1545        raise Exception("REATTACH accepted while disabled")
1546    if "OK" not in dev[2].request("RECONFIGURE"):
1547        raise Exception("RECONFIGURE failed")
1548    if "FAIL" in dev[0].request("INTERFACE_LIST"):
1549        raise Exception("INTERFACE_LIST failed")
1550    if "UNKNOWN COMMAND" not in dev[0].request("FOO"):
1551        raise Exception("Unknown command accepted")
1552
1553    if "FAIL" not in dev[0].global_request("INTERFACE_REMOVE foo"):
1554        raise Exception("Invalid INTERFACE_REMOVE accepted")
1555    if "FAIL" not in dev[0].global_request("SET foo"):
1556        raise Exception("Invalid global SET accepted")
1557
1558@remote_compatible
1559def test_wpas_ctrl_dump(dev, apdev):
1560    """wpa_supplicant ctrl_iface and DUMP/GET global parameters"""
1561    vals = dev[0].get_config()
1562    logger.info("Config values from DUMP: " + str(vals))
1563    for field in vals:
1564        res = dev[0].request("GET " + field)
1565        if res == 'FAIL\n':
1566            res = "null"
1567        if res != vals[field]:
1568            print("'{}' != '{}'".format(res, vals[field]))
1569            raise Exception("Mismatch in config field " + field)
1570    if "beacon_int" not in vals:
1571        raise Exception("Missing config field")
1572
1573def test_wpas_ctrl_interface_add(dev, apdev):
1574    """wpa_supplicant INTERFACE_ADD/REMOVE with vif creation/removal"""
1575    hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
1576    dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
1577    hwsim_utils.test_connectivity(dev[0], hapd)
1578
1579    ifname = "test-" + dev[0].ifname
1580    dev[0].interface_add(ifname, create=True)
1581    wpas = WpaSupplicant(ifname=ifname)
1582    wpas.connect("open", key_mgmt="NONE", scan_freq="2412")
1583    hwsim_utils.test_connectivity(wpas, hapd)
1584    hwsim_utils.test_connectivity(dev[0], hapd)
1585    dev[0].global_request("INTERFACE_REMOVE " + ifname)
1586    hwsim_utils.test_connectivity(dev[0], hapd)
1587
1588def test_wpas_ctrl_interface_add_sta(dev, apdev):
1589    """wpa_supplicant INTERFACE_ADD/REMOVE with STA vif creation/removal"""
1590    hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
1591    ifname = "test-" + dev[0].ifname
1592    dev[0].interface_add(ifname, create=True, if_type='sta')
1593    wpas = WpaSupplicant(ifname=ifname)
1594    wpas.connect("open", key_mgmt="NONE", scan_freq="2412")
1595    wpas.request("DISCONNECT")
1596    wpas.wait_disconnected()
1597    dev[0].global_request("INTERFACE_REMOVE " + ifname)
1598
1599def test_wpas_ctrl_interface_add_ap(dev, apdev):
1600    """wpa_supplicant INTERFACE_ADD/REMOVE AP interface"""
1601    with HWSimRadio() as (radio, iface):
1602        wpas0 = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1603        wpas0.interface_add(iface)
1604
1605        ifname = "test-wpas-ap"
1606        wpas0.interface_add(ifname, create=True, if_type='ap')
1607        wpas = WpaSupplicant(ifname=ifname)
1608
1609        id = wpas.add_network()
1610        wpas.set_network(id, "mode", "2")
1611        wpas.set_network_quoted(id, "ssid", "wpas-ap-open")
1612        wpas.set_network(id, "key_mgmt", "NONE")
1613        wpas.set_network(id, "frequency", "2412")
1614        wpas.set_network(id, "scan_freq", "2412")
1615        wpas.select_network(id)
1616        wait_ap_ready(wpas)
1617
1618        dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
1619        dev[2].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
1620
1621        hwsim_utils.test_connectivity(wpas, dev[1])
1622        hwsim_utils.test_connectivity(dev[1], dev[2])
1623
1624        dev[1].request("DISCONNECT")
1625        dev[2].request("DISCONNECT")
1626        dev[1].wait_disconnected()
1627        dev[2].wait_disconnected()
1628        wpas0.global_request("INTERFACE_REMOVE " + ifname)
1629
1630def test_wpas_ctrl_interface_add_many(dev, apdev):
1631    """wpa_supplicant INTERFACE_ADD/REMOVE with vif creation/removal (many)"""
1632    try:
1633        _test_wpas_ctrl_interface_add_many(dev, apdev)
1634    finally:
1635        for i in range(10):
1636            ifname = "test%d-" % i + dev[0].ifname
1637            dev[0].global_request("INTERFACE_REMOVE " + ifname)
1638
1639def _test_wpas_ctrl_interface_add_many(dev, apdev):
1640    hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
1641    dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
1642    hwsim_utils.test_connectivity(dev[0], hapd)
1643    dev[0].dump_monitor()
1644
1645    l = []
1646    for i in range(10):
1647        ifname = "test%d-" % i + dev[0].ifname
1648        dev[0].interface_add(ifname, create=True)
1649        wpas = WpaSupplicant(ifname=ifname)
1650        wpas.connect("open", key_mgmt="NONE", scan_freq="2412")
1651        wpas.dump_monitor()
1652        l.append(wpas)
1653        dev[0].dump_monitor()
1654    for wpas in l:
1655        wpas.dump_monitor()
1656        hwsim_utils.test_connectivity(wpas, hapd)
1657        wpas.dump_monitor()
1658    dev[0].dump_monitor()
1659
1660def test_wpas_ctrl_interface_add2(dev, apdev):
1661    """wpa_supplicant INTERFACE_ADD/REMOVE with vif without creation/removal"""
1662    ifname = "test-ext-" + dev[0].ifname
1663    try:
1664        _test_wpas_ctrl_interface_add2(dev, apdev, ifname)
1665    finally:
1666        subprocess.call(['iw', 'dev', ifname, 'del'])
1667
1668def _test_wpas_ctrl_interface_add2(dev, apdev, ifname):
1669    hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
1670    dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
1671    hwsim_utils.test_connectivity(dev[0], hapd)
1672
1673    subprocess.call(['iw', 'dev', dev[0].ifname, 'interface', 'add', ifname,
1674                     'type', 'station'])
1675    subprocess.call(['ip', 'link', 'set', 'dev', ifname, 'address',
1676                     '02:01:00:00:02:01'])
1677    dev[0].interface_add(ifname, set_ifname=False, all_params=True)
1678    wpas = WpaSupplicant(ifname=ifname)
1679    wpas.connect("open", key_mgmt="NONE", scan_freq="2412")
1680    hwsim_utils.test_connectivity(wpas, hapd)
1681    hwsim_utils.test_connectivity(dev[0], hapd)
1682    del wpas
1683    dev[0].global_request("INTERFACE_REMOVE " + ifname)
1684    hwsim_utils.test_connectivity(dev[0], hapd)
1685
1686def test_wpas_ctrl_wait(dev, apdev, test_params):
1687    """wpa_supplicant control interface wait for client"""
1688    logfile = os.path.join(test_params['logdir'], 'wpas_ctrl_wait.log-wpas')
1689    pidfile = os.path.join(test_params['logdir'], 'wpas_ctrl_wait.pid-wpas')
1690    conffile = os.path.join(test_params['logdir'], 'wpas_ctrl_wait.conf')
1691    with open(conffile, 'w') as f:
1692        f.write("ctrl_interface=DIR=/var/run/wpa_supplicant\n")
1693
1694    prg = os.path.join(test_params['logdir'],
1695                       'alt-wpa_supplicant/wpa_supplicant/wpa_supplicant')
1696    if not os.path.exists(prg):
1697        prg = '../../wpa_supplicant/wpa_supplicant'
1698    arg = [prg]
1699    cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
1700    out = cmd.communicate()[0].decode()
1701    cmd.wait()
1702    tracing = "Linux tracing" in out
1703
1704    with HWSimRadio() as (radio, iface):
1705        arg = [prg, '-BdddW', '-P', pidfile, '-f', logfile,
1706               '-Dnl80211', '-c', conffile, '-i', iface]
1707        if tracing:
1708            arg += ['-T']
1709        logger.info("Start wpa_supplicant: " + str(arg))
1710        subprocess.call(arg)
1711        wpas = WpaSupplicant(ifname=iface)
1712        if "PONG" not in wpas.request("PING"):
1713            raise Exception("Could not PING wpa_supplicant")
1714        if not os.path.exists(pidfile):
1715            raise Exception("PID file not created")
1716        if "OK" not in wpas.request("TERMINATE"):
1717            raise Exception("Could not TERMINATE")
1718        ev = wpas.wait_event(["CTRL-EVENT-TERMINATING"], timeout=2)
1719        if ev is None:
1720            raise Exception("No termination event received")
1721        for i in range(20):
1722            if not os.path.exists(pidfile):
1723                break
1724            time.sleep(0.1)
1725        if os.path.exists(pidfile):
1726            raise Exception("PID file not removed")
1727
1728@remote_compatible
1729def test_wpas_ctrl_oom(dev):
1730    """Various wpa_supplicant ctrl_iface OOM cases"""
1731    try:
1732        _test_wpas_ctrl_oom(dev)
1733    finally:
1734        dev[0].request("VENDOR_ELEM_REMOVE 1 *")
1735        dev[0].request("VENDOR_ELEM_REMOVE 2 *")
1736        dev[0].request("SET bssid_filter ")
1737
1738def _test_wpas_ctrl_oom(dev):
1739    dev[0].request('VENDOR_ELEM_ADD 2 000100')
1740    tests = [('DRIVER_EVENT AVOID_FREQUENCIES 2412', 'FAIL',
1741              1, 'freq_range_list_parse'),
1742             ('P2P_SET disallow_freq 2412', 'FAIL',
1743              1, 'freq_range_list_parse'),
1744             ('SCAN freq=2412', 'FAIL',
1745              1, 'freq_range_list_parse'),
1746             ('INTERWORKING_SELECT freq=2412', 'FAIL',
1747              1, 'freq_range_list_parse'),
1748             ('SCAN ssid 112233', 'FAIL',
1749              1, 'wpas_ctrl_scan'),
1750             ('MGMT_TX 00:00:00:00:00:00 00:00:00:00:00:00 action=00', 'FAIL',
1751              1, 'wpas_ctrl_iface_mgmt_tx'),
1752             ('EAPOL_RX 00:00:00:00:00:00 00', 'FAIL',
1753              1, 'wpas_ctrl_iface_eapol_rx'),
1754             ('DATA_TEST_FRAME 00112233445566778899aabbccddee', 'FAIL',
1755              1, 'wpas_ctrl_iface_data_test_frame'),
1756             ('DATA_TEST_FRAME 00112233445566778899aabbccddee', 'FAIL',
1757              1, 'l2_packet_init;wpas_ctrl_iface_data_test_frame'),
1758             ('VENDOR_ELEM_ADD 1 000100', 'FAIL',
1759              1, 'wpas_ctrl_vendor_elem_add'),
1760             ('VENDOR_ELEM_ADD 2 000100', 'FAIL',
1761              2, 'wpas_ctrl_vendor_elem_add'),
1762             ('VENDOR_ELEM_REMOVE 2 000100', 'FAIL',
1763              1, 'wpas_ctrl_vendor_elem_remove'),
1764             ('SET bssid_filter 00:11:22:33:44:55', 'FAIL',
1765              1, 'set_bssid_filter'),
1766             ('SET disallow_aps bssid 00:11:22:33:44:55', 'FAIL',
1767              1, 'set_disallow_aps'),
1768             ('SET disallow_aps ssid 11', 'FAIL',
1769              1, 'set_disallow_aps'),
1770             ('SET blob foo 0011', 'FAIL',
1771              1, 'wpas_ctrl_set_blob'),
1772             ('SET blob foo 0011', 'FAIL',
1773              2, 'wpas_ctrl_set_blob'),
1774             ('SET blob foo 0011', 'FAIL',
1775              3, 'wpas_ctrl_set_blob'),
1776             ('WPS_NFC_TAG_READ 00', 'FAIL',
1777              1, 'wpa_supplicant_ctrl_iface_wps_nfc_tag_read'),
1778             ('WPS_NFC_TOKEN NDEF', 'FAIL',
1779              1, 'wpa_supplicant_ctrl_iface_wps_nfc_token'),
1780             ('WPS_NFC_TOKEN NDEF', 'FAIL',
1781              2, 'wpa_supplicant_ctrl_iface_wps_nfc_token'),
1782             ('WPS_NFC_TOKEN NDEF', 'FAIL',
1783              3, 'wpa_supplicant_ctrl_iface_wps_nfc_token'),
1784             ('WPS_NFC_TOKEN NDEF', 'FAIL',
1785              4, 'wpa_supplicant_ctrl_iface_wps_nfc_token'),
1786             ('NFC_REPORT_HANDOVER ROLE TYPE 00 00', 'FAIL',
1787              1, 'wpas_ctrl_nfc_report_handover'),
1788             ('NFC_REPORT_HANDOVER ROLE TYPE 00 00', 'FAIL',
1789              2, 'wpas_ctrl_nfc_report_handover'),
1790             ('NFC_GET_HANDOVER_REQ NDEF WPS-CR', 'FAIL',
1791              1, 'wps_build_nfc_handover_req'),
1792             ('NFC_GET_HANDOVER_REQ NDEF WPS-CR', 'FAIL',
1793              1, 'ndef_build_record'),
1794             ('NFC_GET_HANDOVER_REQ NDEF P2P-CR', None,
1795              1, 'wpas_p2p_nfc_handover'),
1796             ('NFC_GET_HANDOVER_REQ NDEF P2P-CR', None,
1797              1, 'wps_build_nfc_handover_req_p2p'),
1798             ('NFC_GET_HANDOVER_REQ NDEF P2P-CR', 'FAIL',
1799              1, 'ndef_build_record'),
1800             ('NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG', None,
1801              1, 'wpas_ctrl_nfc_get_handover_sel_p2p'),
1802             ('NFC_GET_HANDOVER_SEL NDEF P2P-CR', None,
1803              1, 'wpas_ctrl_nfc_get_handover_sel_p2p'),
1804             ('P2P_ASP_PROVISION_RESP 00:11:22:33:44:55 id=1', 'FAIL',
1805              1, 'p2p_parse_asp_provision_cmd'),
1806             ('P2P_SERV_DISC_REQ 00:11:22:33:44:55 02000001', 'FAIL',
1807              1, 'p2p_ctrl_serv_disc_req'),
1808             ('P2P_SERV_DISC_RESP 2412 00:11:22:33:44:55 1 00', 'FAIL',
1809              1, 'p2p_ctrl_serv_disc_resp'),
1810             ('P2P_SERVICE_ADD bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027',
1811              'FAIL',
1812              1, 'p2p_ctrl_service_add_bonjour'),
1813             ('P2P_SERVICE_ADD bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027',
1814              'FAIL',
1815              2, 'p2p_ctrl_service_add_bonjour'),
1816             ('P2P_SERVICE_ADD bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027',
1817              'FAIL',
1818              3, 'p2p_ctrl_service_add_bonjour'),
1819             ('P2P_SERVICE_DEL bonjour 0b5f6166706f766572746370c00c000c01',
1820              'FAIL',
1821              1, 'p2p_ctrl_service_del_bonjour'),
1822             ('GAS_REQUEST 00:11:22:33:44:55 00', 'FAIL',
1823              1, 'gas_request'),
1824             ('GAS_REQUEST 00:11:22:33:44:55 00 11', 'FAIL',
1825              2, 'gas_request'),
1826             ('HS20_GET_NAI_HOME_REALM_LIST 00:11:22:33:44:55 realm=example.com',
1827             'FAIL',
1828             1, 'hs20_nai_home_realm_list'),
1829             ('HS20_GET_NAI_HOME_REALM_LIST 00:11:22:33:44:55 00',
1830             'FAIL',
1831             1, 'hs20_get_nai_home_realm_list'),
1832             ('WNM_SLEEP enter tfs_req=11', 'FAIL',
1833              1, 'wpas_ctrl_iface_wnm_sleep'),
1834             ('WNM_SLEEP enter tfs_req=11', 'FAIL',
1835              2, 'wpas_ctrl_iface_wnm_sleep'),
1836             ('WNM_SLEEP enter tfs_req=11', 'FAIL',
1837              3, 'wpas_ctrl_iface_wnm_sleep'),
1838             ('WNM_SLEEP enter tfs_req=11', 'FAIL',
1839              4, 'wpas_ctrl_iface_wnm_sleep'),
1840             ('WNM_SLEEP enter tfs_req=11', 'FAIL',
1841              5, 'wpas_ctrl_iface_wnm_sleep'),
1842             ('WNM_SLEEP enter', 'FAIL',
1843              3, 'wpas_ctrl_iface_wnm_sleep'),
1844             ('VENDOR 1 1 00', 'FAIL',
1845              1, 'wpa_supplicant_vendor_cmd'),
1846             ('VENDOR 1 1 00', 'FAIL',
1847              2, 'wpa_supplicant_vendor_cmd'),
1848             ('RADIO_WORK add test', 'FAIL',
1849              1, 'wpas_ctrl_radio_work_add'),
1850             ('RADIO_WORK add test', 'FAIL',
1851              2, 'wpas_ctrl_radio_work_add'),
1852             ('AUTOSCAN periodic:1', 'FAIL',
1853              1, 'wpa_supplicant_ctrl_iface_autoscan'),
1854             ('PING', None,
1855              1, 'wpa_supplicant_ctrl_iface_process')]
1856    tls = dev[0].request("GET tls_library")
1857    if not tls.startswith("internal"):
1858        tests.append(('NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG', 'FAIL',
1859                      4, 'wpas_ctrl_nfc_get_handover_sel_p2p'))
1860    for cmd, exp, count, func in tests:
1861        with alloc_fail(dev[0], count, func):
1862            res = dev[0].request(cmd)
1863            if exp and exp not in res:
1864                raise Exception("Unexpected success for '%s' during OOM (%d:%s)" % (cmd, count, func))
1865
1866    tests = [('FOO', None,
1867              1, 'wpa_supplicant_global_ctrl_iface_process'),
1868             ('IFNAME=notfound PING', 'FAIL\n',
1869              1, 'wpas_global_ctrl_iface_ifname')]
1870    for cmd, exp, count, func in tests:
1871        with alloc_fail(dev[0], count, func):
1872            res = dev[0].global_request(cmd)
1873            if exp and exp not in res:
1874                raise Exception("Unexpected success for '%s' during OOM" % cmd)
1875
1876@remote_compatible
1877def test_wpas_ctrl_error(dev):
1878    """Various wpa_supplicant ctrl_iface error cases"""
1879    tests = [('WPS_NFC_TOKEN NDEF', 'FAIL',
1880              1, 'wpa_supplicant_ctrl_iface_wps_nfc_token'),
1881             ('WPS_NFC_TOKEN NDEF', 'FAIL',
1882              2, 'wpa_supplicant_ctrl_iface_wps_nfc_token'),
1883             ('NFC_GET_HANDOVER_REQ NDEF P2P-CR', None,
1884              1, 'wps_build_nfc_handover_req_p2p')]
1885    for cmd, exp, count, func in tests:
1886        with fail_test(dev[0], count, func):
1887            res = dev[0].request(cmd)
1888            if exp and exp not in res:
1889                raise Exception("Unexpected success for '%s' during failure testing (%d:%s)" % (cmd, count, func))
1890
1891def test_wpas_ctrl_socket_full(dev, apdev, test_params):
1892    """wpa_supplicant control socket and full send buffer"""
1893    if not dev[0].ping():
1894        raise Exception("Could not ping wpa_supplicant at the beginning of the test")
1895    dev[0].get_status()
1896
1897    counter = 0
1898
1899    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
1900    local = "/tmp/wpa_ctrl_test_%d-%d" % (os.getpid(), counter)
1901    counter += 1
1902    s.bind(local)
1903    s.connect("/var/run/wpa_supplicant/wlan0")
1904    for i in range(20):
1905        logger.debug("Command %d" % i)
1906        try:
1907            s.send(b"MIB")
1908        except Exception as e:
1909            logger.info("Could not send command %d: %s" % (i, str(e)))
1910            break
1911        # Close without receiving response
1912        time.sleep(0.01)
1913
1914    if not dev[0].ping():
1915        raise Exception("Could not ping wpa_supplicant in the middle of the test")
1916    dev[0].get_status()
1917
1918    s2 = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
1919    local2 = "/tmp/wpa_ctrl_test_%d-%d" % (os.getpid(), counter)
1920    counter += 1
1921    s2.bind(local2)
1922    s2.connect("/var/run/wpa_supplicant/wlan0")
1923    for i in range(10):
1924        logger.debug("Command %d [2]" % i)
1925        try:
1926            s2.send(b"MIB")
1927        except Exception as e:
1928            logger.info("Could not send command %d [2]: %s" % (i, str(e)))
1929            break
1930        # Close without receiving response
1931        time.sleep(0.01)
1932
1933    s.close()
1934    os.unlink(local)
1935
1936    for i in range(10):
1937        logger.debug("Command %d [3]" % i)
1938        try:
1939            s2.send(b"MIB")
1940        except Exception as e:
1941            logger.info("Could not send command %d [3]: %s" % (i, str(e)))
1942            break
1943        # Close without receiving response
1944        time.sleep(0.01)
1945
1946    s2.close()
1947    os.unlink(local2)
1948
1949    if not dev[0].ping():
1950        raise Exception("Could not ping wpa_supplicant in the middle of the test [2]")
1951    dev[0].get_status()
1952
1953    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
1954    local = "/tmp/wpa_ctrl_test_%d-%d" % (os.getpid(), counter)
1955    counter += 1
1956    s.bind(local)
1957    s.connect("/var/run/wpa_supplicant/wlan0")
1958    s.send(b"ATTACH")
1959    res = s.recv(100).decode()
1960    if "OK" not in res:
1961        raise Exception("Could not attach a test socket")
1962
1963    for i in range(5):
1964        dev[0].scan(freq=2412)
1965
1966    s.close()
1967    os.unlink(local)
1968
1969    for i in range(5):
1970        dev[0].scan(freq=2412)
1971
1972    if not dev[0].ping():
1973        raise Exception("Could not ping wpa_supplicant at the end of the test")
1974    dev[0].get_status()
1975
1976def test_wpas_ctrl_event_burst(dev, apdev):
1977    """wpa_supplicant control socket and event burst"""
1978    if "OK" not in dev[0].request("EVENT_TEST 1000"):
1979        raise Exception("Could not request event messages")
1980
1981    total_i = 0
1982    total_g = 0
1983    for i in range(100):
1984        (i, g) = dev[0].dump_monitor()
1985        total_i += i
1986        total_g += g
1987        logger.info("Received i=%d g=%d" % (i, g))
1988        if total_i >= 1000 and total_g >= 1000:
1989            break
1990        time.sleep(0.05)
1991
1992    if total_i < 1000:
1993        raise Exception("Some per-interface events not seen: %d" % total_i)
1994    if total_g < 1000:
1995        raise Exception("Some global events not seen: %d" % total_g)
1996
1997    if not dev[0].ping():
1998        raise Exception("Could not ping wpa_supplicant at the end of the test")
1999
2000@remote_compatible
2001def test_wpas_ctrl_sched_scan_plans(dev, apdev):
2002    """wpa_supplicant sched_scan_plans parsing"""
2003    dev[0].request("SET sched_scan_plans foo")
2004    dev[0].request("SET sched_scan_plans 10:100 20:200 30")
2005    dev[0].request("SET sched_scan_plans 4294967295:0")
2006    dev[0].request("SET sched_scan_plans 1 1")
2007    dev[0].request("SET sched_scan_plans  ")
2008    try:
2009        with alloc_fail(dev[0], 1, "wpas_sched_scan_plans_set"):
2010            dev[0].request("SET sched_scan_plans 10:100")
2011    finally:
2012        dev[0].request("SET sched_scan_plans ")
2013
2014def test_wpas_ctrl_signal_monitor(dev, apdev):
2015    """wpa_supplicant SIGNAL_MONITOR command"""
2016    hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
2017    dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2018    dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
2019                   bgscan="simple:1:-45:2")
2020    dev[2].connect("open", key_mgmt="NONE", scan_freq="2412")
2021
2022    tests = [" THRESHOLD=-45", " THRESHOLD=-44 HYSTERESIS=5", ""]
2023    try:
2024        if "FAIL" in dev[2].request("SIGNAL_MONITOR THRESHOLD=-1 HYSTERESIS=5"):
2025            raise Exception("SIGNAL_MONITOR command failed")
2026        for t in tests:
2027            if "OK" not in dev[0].request("SIGNAL_MONITOR" + t):
2028                raise Exception("SIGNAL_MONITOR command failed: " + t)
2029        if "FAIL" not in dev[1].request("SIGNAL_MONITOR THRESHOLD=-44 HYSTERESIS=5"):
2030            raise Exception("SIGNAL_MONITOR command accepted while using bgscan")
2031        ev = dev[2].wait_event(["CTRL-EVENT-SIGNAL-CHANGE"], timeout=10)
2032        if ev is None:
2033            raise Exception("No signal change event seen")
2034        if "above=0" not in ev:
2035            raise Exception("Unexpected signal change event contents: " + ev)
2036    finally:
2037        dev[0].request("SIGNAL_MONITOR")
2038        dev[1].request("SIGNAL_MONITOR")
2039        dev[2].request("SIGNAL_MONITOR")
2040
2041    dev[0].request("REMOVE_NETWORK all")
2042    dev[1].request("REMOVE_NETWORK all")
2043    dev[1].wait_disconnected()
2044
2045def test_wpas_ctrl_p2p_listen_offload(dev, apdev):
2046    """wpa_supplicant P2P_LO_START and P2P_LO_STOP commands"""
2047    dev[0].request("P2P_LO_STOP")
2048    dev[0].request("P2P_LO_START ")
2049    dev[0].request("P2P_LO_START 2412")
2050    dev[0].request("P2P_LO_START 2412 100 200 3")
2051    dev[0].request("P2P_LO_STOP")
2052
2053def test_wpas_ctrl_driver_flags(dev, apdev):
2054    """DRIVER_FLAGS command"""
2055    params = hostapd.wpa2_params(ssid="test", passphrase="12345678")
2056    hapd = hostapd.add_ap(apdev[0], params)
2057    hapd_flags = hapd.request("DRIVER_FLAGS")
2058    wpas_flags = dev[0].request("DRIVER_FLAGS")
2059    if "FAIL" in hapd_flags:
2060        raise Exception("DRIVER_FLAGS failed")
2061    if hapd_flags != wpas_flags:
2062        raise Exception("Unexpected difference in hostapd vs. wpa_supplicant DRIVER_FLAGS output")
2063    logger.info("DRIVER_FLAGS: " + hapd_flags)
2064    flags = hapd_flags.split('\n')
2065    if 'AP' not in flags:
2066        raise Exception("AP flag missing from DRIVER_FLAGS")
2067
2068def test_wpas_ctrl_bss_current(dev, apdev):
2069    """wpa_supplicant BSS CURRENT command"""
2070    hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
2071    bssid = hapd.own_addr()
2072    res = dev[0].request("BSS CURRENT")
2073    if res != '':
2074        raise Exception("Unexpected BSS CURRENT response in disconnected state")
2075    dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2076    res = dev[0].request("BSS CURRENT")
2077    if bssid not in res:
2078        raise Exception("Unexpected BSS CURRENT response in connected state")
2079
2080def test_wpas_ctrl_set_lci_errors(dev):
2081    """wpa_supplicant SET lci error cases"""
2082    if "FAIL" not in dev[0].request("SET lci q"):
2083        raise Exception("Invalid LCI value accepted")
2084
2085    with fail_test(dev[0], 1, "os_get_reltime;wpas_ctrl_iface_set_lci"):
2086        if "FAIL" not in dev[0].request("SET lci 00"):
2087            raise Exception("SET lci accepted with failing os_get_reltime")
2088
2089def test_wpas_ctrl_set_radio_disabled(dev):
2090    """wpa_supplicant SET radio_disabled"""
2091    # This is not currently supported with nl80211, but execute the commands
2092    # without checking the result for some additional code coverage.
2093    dev[0].request("SET radio_disabled 1")
2094    dev[0].request("SET radio_disabled 0")
2095
2096def test_wpas_ctrl_set_tdls_trigger_control(dev):
2097    """wpa_supplicant SET tdls_trigger_control"""
2098    # This is not supported with upstream nl80211, but execute the commands
2099    # without checking the result for some additional code coverage.
2100    dev[0].request("SET tdls_trigger_control 1")
2101    dev[0].request("SET tdls_trigger_control 0")
2102
2103def test_wpas_ctrl_set_sched_scan_relative_rssi(dev):
2104    """wpa_supplicant SET relative RSSI"""
2105    tests = ["relative_rssi -1",
2106             "relative_rssi 101",
2107             "relative_band_adjust 2G",
2108             "relative_band_adjust 2G:-101",
2109             "relative_band_adjust 2G:101",
2110             "relative_band_adjust 3G:1"]
2111    for t in tests:
2112        if "FAIL" not in dev[0].request("SET " + t):
2113            raise Exception("No failure reported for SET " + t)
2114
2115    tests = ["relative_rssi 0",
2116             "relative_rssi 10",
2117             "relative_rssi disable",
2118             "relative_band_adjust 2G:-1",
2119             "relative_band_adjust 2G:0",
2120             "relative_band_adjust 2G:1",
2121             "relative_band_adjust 5G:-1",
2122             "relative_band_adjust 5G:1",
2123             "relative_band_adjust 5G:0"]
2124    for t in tests:
2125        if "OK" not in dev[0].request("SET " + t):
2126            raise Exception("Failed to SET " + t)
2127
2128def test_wpas_ctrl_get_pref_freq_list_override(dev):
2129    """wpa_supplicant get_pref_freq_list_override"""
2130    if dev[0].request("GET_PREF_FREQ_LIST ").strip() != "FAIL":
2131        raise Exception("Invalid GET_PREF_FREQ_LIST accepted")
2132
2133    dev[0].set("get_pref_freq_list_override", "foo")
2134    res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
2135    if res != "FAIL":
2136        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2137
2138    dev[0].set("get_pref_freq_list_override", "1234:1,2,3 0")
2139    res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
2140    if res != "FAIL":
2141        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2142
2143    dev[0].set("get_pref_freq_list_override", "1234:1,2,3 0:")
2144    res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
2145    if res != "0":
2146        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2147
2148    dev[0].set("get_pref_freq_list_override", "0:1,2")
2149    res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
2150    if res != "1,2":
2151        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2152
2153    dev[0].set("get_pref_freq_list_override", "1:3,4 0:1,2 2:5,6")
2154    res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
2155    if res != "1,2":
2156        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2157
2158    dev[0].set("get_pref_freq_list_override", "1:3,4 0:1 2:5,6")
2159    res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
2160    if res != "1":
2161        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2162
2163    dev[0].set("get_pref_freq_list_override", "0:1000,1001 2:1002,1003 3:1004,1005 4:1006,1007 8:1010,1011 9:1008,1009")
2164    res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
2165    if res != "1000,1001":
2166        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2167    res = dev[0].request("GET_PREF_FREQ_LIST AP").strip()
2168    if res != "1002,1003":
2169        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2170    res = dev[0].request("GET_PREF_FREQ_LIST P2P_GO").strip()
2171    if res != "1004,1005":
2172        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2173    res = dev[0].request("GET_PREF_FREQ_LIST P2P_CLIENT").strip()
2174    if res != "1006,1007":
2175        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2176    res = dev[0].request("GET_PREF_FREQ_LIST IBSS").strip()
2177    if res != "1008,1009":
2178        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2179    res = dev[0].request("GET_PREF_FREQ_LIST TDLS").strip()
2180    if res != "1010,1011":
2181        raise Exception("Unexpected GET_PREF_FREQ_LIST response: " + res)
2182
2183    dev[0].set("get_pref_freq_list_override", "")
2184    res = dev[0].request("GET_PREF_FREQ_LIST STATION").strip()
2185    logger.info("STATION (without override): " + res)
2186
2187def test_wpas_ctrl_interface_add_driver_init_failure(dev, apdev):
2188    """wpa_supplicant INTERFACE_ADD and driver init failing"""
2189    for i in range(1000):
2190        res = dev[0].global_request("INTERFACE_ADD FOO")
2191        if "FAIL" not in res:
2192            raise Exception("Unexpected result: " + res)
2193    dev[0].dump_monitor()
2194