tests: Remove unnecessary use of sudo from test cases
[mech_eap.git] / tests / hwsim / test_ap_psk.py
1 # WPA2-Personal tests
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
7 import binascii
8 import hashlib
9 import hmac
10 import logging
11 logger = logging.getLogger()
12 import os
13 import re
14 import struct
15 import subprocess
16 import time
17
18 import hostapd
19 from utils import HwsimSkip
20 import hwsim_utils
21 from wpasupplicant import WpaSupplicant
22
23 def check_mib(dev, vals):
24     mib = dev.get_mib()
25     for v in vals:
26         if mib[v[0]] != v[1]:
27             raise Exception("Unexpected {} = {} (expected {})".format(v[0], mib[v[0]], v[1]))
28
29 def test_ap_wpa2_psk(dev, apdev):
30     """WPA2-PSK AP with PSK instead of passphrase"""
31     ssid = "test-wpa2-psk"
32     passphrase = 'qwertyuiop'
33     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
34     params = hostapd.wpa2_params(ssid=ssid)
35     params['wpa_psk'] = psk
36     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
37     key_mgmt = hapd.get_config()['key_mgmt']
38     if key_mgmt.split(' ')[0] != "WPA-PSK":
39         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
40     dev[0].connect(ssid, raw_psk=psk, scan_freq="2412")
41     dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
42
43     sig = dev[0].request("SIGNAL_POLL").splitlines()
44     pkt = dev[0].request("PKTCNT_POLL").splitlines()
45     if "FREQUENCY=2412" not in sig:
46         raise Exception("Unexpected SIGNAL_POLL value: " + str(sig))
47     if "TXBAD=0" not in pkt:
48         raise Exception("Unexpected TXBAD value: " + str(pkt))
49
50 def test_ap_wpa2_psk_file(dev, apdev):
51     """WPA2-PSK AP with PSK from a file"""
52     ssid = "test-wpa2-psk"
53     passphrase = 'qwertyuiop'
54     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
55     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
56     params['wpa_psk_file'] = 'hostapd.wpa_psk'
57     hostapd.add_ap(apdev[0]['ifname'], params)
58     dev[1].connect(ssid, psk="very secret", scan_freq="2412", wait_connect=False)
59     dev[2].connect(ssid, raw_psk=psk, scan_freq="2412")
60     dev[2].request("REMOVE_NETWORK all")
61     dev[0].connect(ssid, psk="very secret", scan_freq="2412")
62     dev[0].request("REMOVE_NETWORK all")
63     dev[2].connect(ssid, psk="another passphrase for all STAs", scan_freq="2412")
64     dev[0].connect(ssid, psk="another passphrase for all STAs", scan_freq="2412")
65     ev = dev[1].wait_event(["WPA: 4-Way Handshake failed"], timeout=10)
66     if ev is None:
67         raise Exception("Timed out while waiting for failure report")
68     dev[1].request("REMOVE_NETWORK all")
69
70 def test_ap_wpa2_ptk_rekey(dev, apdev):
71     """WPA2-PSK AP and PTK rekey enforced by station"""
72     ssid = "test-wpa2-psk"
73     passphrase = 'qwertyuiop'
74     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
75     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
76     dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412")
77     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
78     if ev is None:
79         raise Exception("PTK rekey timed out")
80     hwsim_utils.test_connectivity(dev[0], hapd)
81
82 def test_ap_wpa2_ptk_rekey_ap(dev, apdev):
83     """WPA2-PSK AP and PTK rekey enforced by AP"""
84     ssid = "test-wpa2-psk"
85     passphrase = 'qwertyuiop'
86     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
87     params['wpa_ptk_rekey'] = '2'
88     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
89     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
90     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
91     if ev is None:
92         raise Exception("PTK rekey timed out")
93     hwsim_utils.test_connectivity(dev[0], hapd)
94
95 def test_ap_wpa2_sha256_ptk_rekey(dev, apdev):
96     """WPA2-PSK/SHA256 AKM AP and PTK rekey enforced by station"""
97     ssid = "test-wpa2-psk"
98     passphrase = 'qwertyuiop'
99     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
100     params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
101     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
102     dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
103                    wpa_ptk_rekey="1", scan_freq="2412")
104     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
105     if ev is None:
106         raise Exception("PTK rekey timed out")
107     hwsim_utils.test_connectivity(dev[0], hapd)
108     check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-6"),
109                         ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-6") ])
110
111 def test_ap_wpa2_sha256_ptk_rekey_ap(dev, apdev):
112     """WPA2-PSK/SHA256 AKM AP and PTK rekey enforced by AP"""
113     ssid = "test-wpa2-psk"
114     passphrase = 'qwertyuiop'
115     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
116     params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
117     params['wpa_ptk_rekey'] = '2'
118     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
119     dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK-SHA256",
120                    scan_freq="2412")
121     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
122     if ev is None:
123         raise Exception("PTK rekey timed out")
124     hwsim_utils.test_connectivity(dev[0], hapd)
125     check_mib(dev[0], [ ("dot11RSNAAuthenticationSuiteRequested", "00-0f-ac-6"),
126                         ("dot11RSNAAuthenticationSuiteSelected", "00-0f-ac-6") ])
127
128 def test_ap_wpa_ptk_rekey(dev, apdev):
129     """WPA-PSK/TKIP AP and PTK rekey enforced by station"""
130     ssid = "test-wpa-psk"
131     passphrase = 'qwertyuiop'
132     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
133     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
134     dev[0].connect(ssid, psk=passphrase, wpa_ptk_rekey="1", scan_freq="2412")
135     if "[WPA-PSK-TKIP]" not in dev[0].request("SCAN_RESULTS"):
136         raise Exception("Scan results missing WPA element info")
137     ev = dev[0].wait_event(["WPA: Key negotiation completed"])
138     if ev is None:
139         raise Exception("PTK rekey timed out")
140     hwsim_utils.test_connectivity(dev[0], hapd)
141
142 def test_ap_wpa_ptk_rekey_ap(dev, apdev):
143     """WPA-PSK/TKIP AP and PTK rekey enforced by AP"""
144     ssid = "test-wpa-psk"
145     passphrase = 'qwertyuiop'
146     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
147     params['wpa_ptk_rekey'] = '2'
148     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
149     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
150     ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=10)
151     if ev is None:
152         raise Exception("PTK rekey timed out")
153     hwsim_utils.test_connectivity(dev[0], hapd)
154
155 def test_ap_wpa_ccmp(dev, apdev):
156     """WPA-PSK/CCMP"""
157     ssid = "test-wpa-psk"
158     passphrase = 'qwertyuiop'
159     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
160     params['wpa_pairwise'] = "CCMP"
161     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
162     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
163     hwsim_utils.test_connectivity(dev[0], hapd)
164     check_mib(dev[0], [ ("dot11RSNAConfigGroupCipherSize", "128"),
165                         ("dot11RSNAGroupCipherRequested", "00-50-f2-4"),
166                         ("dot11RSNAPairwiseCipherRequested", "00-50-f2-4"),
167                         ("dot11RSNAAuthenticationSuiteRequested", "00-50-f2-2"),
168                         ("dot11RSNAGroupCipherSelected", "00-50-f2-4"),
169                         ("dot11RSNAPairwiseCipherSelected", "00-50-f2-4"),
170                         ("dot11RSNAAuthenticationSuiteSelected", "00-50-f2-2"),
171                         ("dot1xSuppSuppControlledPortStatus", "Authorized") ])
172
173 def test_ap_wpa2_psk_file(dev, apdev):
174     """WPA2-PSK AP with various PSK file error and success cases"""
175     addr0 = dev[0].own_addr()
176     addr1 = dev[1].own_addr()
177     addr2 = dev[2].own_addr()
178     ssid = "psk"
179     pskfile = "/tmp/ap_wpa2_psk_file_errors.psk_file"
180     try:
181         os.remove(pskfile)
182     except:
183         pass
184
185     params = { "ssid": ssid, "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
186                "rsn_pairwise": "CCMP", "wpa_psk_file": pskfile }
187
188     try:
189         # missing PSK file
190         hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
191         if "FAIL" not in hapd.request("ENABLE"):
192             raise Exception("Unexpected ENABLE success")
193         hapd.request("DISABLE")
194
195         # invalid MAC address
196         with open(pskfile, "w") as f:
197             f.write("\n")
198             f.write("foo\n")
199         if "FAIL" not in hapd.request("ENABLE"):
200             raise Exception("Unexpected ENABLE success")
201         hapd.request("DISABLE")
202
203         # no PSK on line
204         with open(pskfile, "w") as f:
205             f.write("00:11:22:33:44:55\n")
206         if "FAIL" not in hapd.request("ENABLE"):
207             raise Exception("Unexpected ENABLE success")
208         hapd.request("DISABLE")
209
210         # invalid PSK
211         with open(pskfile, "w") as f:
212             f.write("00:11:22:33:44:55 1234567\n")
213         if "FAIL" not in hapd.request("ENABLE"):
214             raise Exception("Unexpected ENABLE success")
215         hapd.request("DISABLE")
216
217         # valid PSK file
218         with open(pskfile, "w") as f:
219             f.write("00:11:22:33:44:55 12345678\n")
220             f.write(addr0 + " 123456789\n")
221             f.write(addr1 + " 123456789a\n")
222             f.write(addr2 + " 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\n")
223         if "FAIL" in hapd.request("ENABLE"):
224             raise Exception("Unexpected ENABLE failure")
225
226         dev[0].connect(ssid, psk="123456789", scan_freq="2412")
227         dev[1].connect(ssid, psk="123456789a", scan_freq="2412")
228         dev[2].connect(ssid, raw_psk="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", scan_freq="2412")
229
230     finally:
231         try:
232             os.remove(pskfile)
233         except:
234             pass
235
236 def test_ap_wpa2_psk_wildcard_ssid(dev, apdev):
237     """WPA2-PSK AP and wildcard SSID configuration"""
238     ssid = "test-wpa2-psk"
239     passphrase = 'qwertyuiop'
240     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
241     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
242     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
243     dev[0].connect("", bssid=apdev[0]['bssid'], psk=passphrase,
244                    scan_freq="2412")
245     dev[1].connect("", bssid=apdev[0]['bssid'], raw_psk=psk, scan_freq="2412")
246
247 def test_ap_wpa2_gtk_rekey(dev, apdev):
248     """WPA2-PSK AP and GTK rekey enforced by AP"""
249     ssid = "test-wpa2-psk"
250     passphrase = 'qwertyuiop'
251     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
252     params['wpa_group_rekey'] = '1'
253     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
254     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
255     ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
256     if ev is None:
257         raise Exception("GTK rekey timed out")
258     hwsim_utils.test_connectivity(dev[0], hapd)
259
260 def test_ap_wpa_gtk_rekey(dev, apdev):
261     """WPA-PSK/TKIP AP and GTK rekey enforced by AP"""
262     ssid = "test-wpa-psk"
263     passphrase = 'qwertyuiop'
264     params = hostapd.wpa_params(ssid=ssid, passphrase=passphrase)
265     params['wpa_group_rekey'] = '1'
266     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
267     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
268     ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
269     if ev is None:
270         raise Exception("GTK rekey timed out")
271     hwsim_utils.test_connectivity(dev[0], hapd)
272
273 def test_ap_wpa2_gmk_rekey(dev, apdev):
274     """WPA2-PSK AP and GMK and GTK rekey enforced by AP"""
275     ssid = "test-wpa2-psk"
276     passphrase = 'qwertyuiop'
277     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
278     params['wpa_group_rekey'] = '1'
279     params['wpa_gmk_rekey'] = '2'
280     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
281     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
282     for i in range(0, 3):
283         ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
284         if ev is None:
285             raise Exception("GTK rekey timed out")
286     hwsim_utils.test_connectivity(dev[0], hapd)
287
288 def test_ap_wpa2_strict_rekey(dev, apdev):
289     """WPA2-PSK AP and strict GTK rekey enforced by AP"""
290     ssid = "test-wpa2-psk"
291     passphrase = 'qwertyuiop'
292     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
293     params['wpa_strict_rekey'] = '1'
294     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
295     dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
296     dev[1].connect(ssid, psk=passphrase, scan_freq="2412")
297     dev[1].request("DISCONNECT")
298     ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
299     if ev is None:
300         raise Exception("GTK rekey timed out")
301     hwsim_utils.test_connectivity(dev[0], hapd)
302
303 def test_ap_wpa2_bridge_fdb(dev, apdev):
304     """Bridge FDB entry removal"""
305     try:
306         ssid = "test-wpa2-psk"
307         passphrase = "12345678"
308         params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
309         params['bridge'] = 'ap-br0'
310         hostapd.add_ap(apdev[0]['ifname'], params)
311         subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
312         subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
313         dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
314                        bssid=apdev[0]['bssid'])
315         dev[1].connect(ssid, psk=passphrase, scan_freq="2412",
316                        bssid=apdev[0]['bssid'])
317         addr0 = dev[0].p2p_interface_addr()
318         hwsim_utils.test_connectivity_sta(dev[0], dev[1])
319         cmd = subprocess.Popen(['brctl', 'showmacs', 'ap-br0'],
320                                stdout=subprocess.PIPE)
321         macs1 = cmd.stdout.read()
322         dev[0].request("DISCONNECT")
323         dev[1].request("DISCONNECT")
324         time.sleep(1)
325         cmd = subprocess.Popen(['brctl', 'showmacs', 'ap-br0'],
326                                stdout=subprocess.PIPE)
327         macs2 = cmd.stdout.read()
328
329         addr1 = dev[1].p2p_interface_addr()
330         if addr0 not in macs1 or addr1 not in macs1:
331             raise Exception("Bridge FDB entry missing")
332         if addr0 in macs2 or addr1 in macs2:
333             raise Exception("Bridge FDB entry was not removed")
334     finally:
335         subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
336         subprocess.call(['brctl', 'delbr', 'ap-br0'])
337
338 def test_ap_wpa2_already_in_bridge(dev, apdev):
339     """hostapd behavior with interface already in bridge"""
340     ifname = apdev[0]['ifname']
341     br_ifname = 'ext-ap-br0'
342     try:
343         ssid = "test-wpa2-psk"
344         passphrase = "12345678"
345         subprocess.call(['brctl', 'addbr', br_ifname])
346         subprocess.call(['brctl', 'setfd', br_ifname, '0'])
347         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
348         subprocess.call(['iw', ifname, 'set', 'type', '__ap'])
349         subprocess.call(['brctl', 'addif', br_ifname, ifname])
350         params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
351         hapd = hostapd.add_ap(ifname, params)
352         if hapd.get_driver_status_field('brname') != br_ifname:
353             raise Exception("Bridge name not identified correctly")
354         dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
355     finally:
356         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
357         subprocess.call(['brctl', 'delif', br_ifname, ifname])
358         subprocess.call(['iw', ifname, 'set', 'type', 'station'])
359         subprocess.call(['brctl', 'delbr', br_ifname])
360
361 def test_ap_wpa2_in_different_bridge(dev, apdev):
362     """hostapd behavior with interface in different bridge"""
363     ifname = apdev[0]['ifname']
364     br_ifname = 'ext-ap-br0'
365     try:
366         ssid = "test-wpa2-psk"
367         passphrase = "12345678"
368         subprocess.call(['brctl', 'addbr', br_ifname])
369         subprocess.call(['brctl', 'setfd', br_ifname, '0'])
370         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
371         subprocess.call(['iw', ifname, 'set', 'type', '__ap'])
372         subprocess.call(['brctl', 'addif', br_ifname, ifname])
373         time.sleep(0.5)
374         params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
375         params['bridge'] = 'ap-br0'
376         hapd = hostapd.add_ap(ifname, params)
377         subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
378         subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
379         brname = hapd.get_driver_status_field('brname')
380         if brname != 'ap-br0':
381             raise Exception("Incorrect bridge: " + brname)
382         dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
383         hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
384         if hapd.get_driver_status_field("added_bridge") != "1":
385             raise Exception("Unexpected added_bridge value")
386         if hapd.get_driver_status_field("added_if_into_bridge") != "1":
387             raise Exception("Unexpected added_if_into_bridge value")
388         dev[0].request("DISCONNECT")
389         hapd.disable()
390     finally:
391         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
392         subprocess.call(['brctl', 'delif', br_ifname, ifname],
393                         stderr=open('/dev/null', 'w'))
394         subprocess.call(['brctl', 'delbr', br_ifname])
395
396 def test_ap_wpa2_ext_add_to_bridge(dev, apdev):
397     """hostapd behavior with interface added to bridge externally"""
398     ifname = apdev[0]['ifname']
399     br_ifname = 'ext-ap-br0'
400     try:
401         ssid = "test-wpa2-psk"
402         passphrase = "12345678"
403         params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
404         hapd = hostapd.add_ap(ifname, params)
405
406         subprocess.call(['brctl', 'addbr', br_ifname])
407         subprocess.call(['brctl', 'setfd', br_ifname, '0'])
408         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
409         subprocess.call(['brctl', 'addif', br_ifname, ifname])
410         dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
411         if hapd.get_driver_status_field('brname') != br_ifname:
412             raise Exception("Bridge name not identified correctly")
413     finally:
414         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
415         subprocess.call(['brctl', 'delif', br_ifname, ifname])
416         subprocess.call(['brctl', 'delbr', br_ifname])
417
418 def test_ap_wpa2_psk_ext(dev, apdev):
419     """WPA2-PSK AP using external EAPOL I/O"""
420     bssid = apdev[0]['bssid']
421     ssid = "test-wpa2-psk"
422     passphrase = 'qwertyuiop'
423     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
424     params = hostapd.wpa2_params(ssid=ssid)
425     params['wpa_psk'] = psk
426     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
427     hapd.request("SET ext_eapol_frame_io 1")
428     dev[0].request("SET ext_eapol_frame_io 1")
429     dev[0].connect(ssid, psk=passphrase, scan_freq="2412", wait_connect=False)
430     addr = dev[0].p2p_interface_addr()
431     while True:
432         ev = hapd.wait_event(["EAPOL-TX", "AP-STA-CONNECTED"], timeout=15)
433         if ev is None:
434             raise Exception("Timeout on EAPOL-TX from hostapd")
435         if "AP-STA-CONNECTED" in ev:
436             dev[0].wait_connected(timeout=15)
437             break
438         res = dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
439         if "OK" not in res:
440             raise Exception("EAPOL_RX to wpa_supplicant failed")
441         ev = dev[0].wait_event(["EAPOL-TX", "CTRL-EVENT-CONNECTED"], timeout=15)
442         if ev is None:
443             raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
444         if "CTRL-EVENT-CONNECTED" in ev:
445             break
446         res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
447         if "OK" not in res:
448             raise Exception("EAPOL_RX to hostapd failed")
449
450 def parse_eapol(data):
451     (version, type, length) = struct.unpack('>BBH', data[0:4])
452     payload = data[4:]
453     if length > len(payload):
454         raise Exception("Invalid EAPOL length")
455     if length < len(payload):
456         payload = payload[0:length]
457     eapol = {}
458     eapol['version'] = version
459     eapol['type'] = type
460     eapol['length'] = length
461     eapol['payload'] = payload
462     if type == 3:
463         # EAPOL-Key
464         (eapol['descr_type'],) = struct.unpack('B', payload[0:1])
465         payload = payload[1:]
466         if eapol['descr_type'] == 2 or eapol['descr_type'] == 254:
467             # RSN EAPOL-Key
468             (key_info, key_len) = struct.unpack('>HH', payload[0:4])
469             eapol['rsn_key_info'] = key_info
470             eapol['rsn_key_len'] = key_len
471             eapol['rsn_replay_counter'] = payload[4:12]
472             eapol['rsn_key_nonce'] = payload[12:44]
473             eapol['rsn_key_iv'] = payload[44:60]
474             eapol['rsn_key_rsc'] = payload[60:68]
475             eapol['rsn_key_id'] = payload[68:76]
476             eapol['rsn_key_mic'] = payload[76:92]
477             payload = payload[92:]
478             (eapol['rsn_key_data_len'],) = struct.unpack('>H', payload[0:2])
479             payload = payload[2:]
480             eapol['rsn_key_data'] = payload
481     return eapol
482
483 def build_eapol(msg):
484     data = struct.pack(">BBH", msg['version'], msg['type'], msg['length'])
485     if msg['type'] == 3:
486         data += struct.pack('>BHH', msg['descr_type'], msg['rsn_key_info'],
487                             msg['rsn_key_len'])
488         data += msg['rsn_replay_counter']
489         data += msg['rsn_key_nonce']
490         data += msg['rsn_key_iv']
491         data += msg['rsn_key_rsc']
492         data += msg['rsn_key_id']
493         data += msg['rsn_key_mic']
494         data += struct.pack('>H', msg['rsn_key_data_len'])
495         data += msg['rsn_key_data']
496     else:
497         data += msg['payload']
498     return data
499
500 def sha1_prf(key, label, data, outlen):
501     res = ''
502     counter = 0
503     while outlen > 0:
504         m = hmac.new(key, label, hashlib.sha1)
505         m.update(struct.pack('B', 0))
506         m.update(data)
507         m.update(struct.pack('B', counter))
508         counter += 1
509         hash = m.digest()
510         if outlen > len(hash):
511             res += hash
512             outlen -= len(hash)
513         else:
514             res += hash[0:outlen]
515             outlen = 0
516     return res
517
518 def pmk_to_ptk(pmk, addr1, addr2, nonce1, nonce2):
519     if addr1 < addr2:
520         data = binascii.unhexlify(addr1.replace(':','')) + binascii.unhexlify(addr2.replace(':',''))
521     else:
522         data = binascii.unhexlify(addr2.replace(':','')) + binascii.unhexlify(addr1.replace(':',''))
523     if nonce1 < nonce2:
524         data += nonce1 + nonce2
525     else:
526         data += nonce2 + nonce1
527     label = "Pairwise key expansion"
528     ptk = sha1_prf(pmk, label, data, 48)
529     kck = ptk[0:16]
530     kek = ptk[16:32]
531     return (ptk, kck, kek)
532
533 def eapol_key_mic(kck, msg):
534     msg['rsn_key_mic'] = binascii.unhexlify('00000000000000000000000000000000')
535     data = build_eapol(msg)
536     m = hmac.new(kck, data, hashlib.sha1)
537     msg['rsn_key_mic'] = m.digest()[0:16]
538
539 def rsn_eapol_key_set(msg, key_info, key_len, nonce, data):
540     msg['rsn_key_info'] = key_info
541     msg['rsn_key_len'] = key_len
542     if nonce:
543         msg['rsn_key_nonce'] = nonce
544     else:
545         msg['rsn_key_nonce'] = binascii.unhexlify('0000000000000000000000000000000000000000000000000000000000000000')
546     if data:
547         msg['rsn_key_data_len'] = len(data)
548         msg['rsn_key_data'] = data
549         msg['length'] = 95 + len(data)
550     else:
551         msg['rsn_key_data_len'] = 0
552         msg['rsn_key_data'] = ''
553         msg['length'] = 95
554
555 def recv_eapol(hapd):
556     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
557     if ev is None:
558         raise Exception("Timeout on EAPOL-TX from hostapd")
559     eapol = binascii.unhexlify(ev.split(' ')[2])
560     return parse_eapol(eapol)
561
562 def send_eapol(hapd, addr, data):
563     res = hapd.request("EAPOL_RX " + addr + " " + binascii.hexlify(data))
564     if "OK" not in res:
565         raise Exception("EAPOL_RX to hostapd failed")
566
567 def reply_eapol(info, hapd, addr, msg, key_info, nonce, data, kck):
568     logger.info("Send EAPOL-Key msg " + info)
569     rsn_eapol_key_set(msg, key_info, 0, nonce, data)
570     eapol_key_mic(kck, msg)
571     send_eapol(hapd, addr, build_eapol(msg))
572
573 def hapd_connected(hapd):
574     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=15)
575     if ev is None:
576         raise Exception("Timeout on AP-STA-CONNECTED from hostapd")
577
578 def eapol_test(apdev, dev, wpa2=True):
579     bssid = apdev['bssid']
580     if wpa2:
581         ssid = "test-wpa2-psk"
582     else:
583         ssid = "test-wpa-psk"
584     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
585     pmk = binascii.unhexlify(psk)
586     if wpa2:
587         params = hostapd.wpa2_params(ssid=ssid)
588     else:
589         params = hostapd.wpa_params(ssid=ssid)
590     params['wpa_psk'] = psk
591     hapd = hostapd.add_ap(apdev['ifname'], params)
592     hapd.request("SET ext_eapol_frame_io 1")
593     dev.request("SET ext_eapol_frame_io 1")
594     dev.connect(ssid, psk="not used", scan_freq="2412", wait_connect=False)
595     addr = dev.p2p_interface_addr()
596     if wpa2:
597         rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac020000')
598     else:
599         rsne = binascii.unhexlify('dd160050f20101000050f20201000050f20201000050f202')
600     snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111')
601     return (bssid,ssid,hapd,snonce,pmk,addr,rsne)
602
603 def test_ap_wpa2_psk_ext_eapol(dev, apdev):
604     """WPA2-PSK AP using external EAPOL supplicant"""
605     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
606
607     msg = recv_eapol(hapd)
608     anonce = msg['rsn_key_nonce']
609     logger.info("Replay same data back")
610     send_eapol(hapd, addr, build_eapol(msg))
611
612     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
613
614     logger.info("Truncated Key Data in EAPOL-Key msg 2/4")
615     rsn_eapol_key_set(msg, 0x0101, 0, snonce, rsne)
616     msg['length'] = 95 + 22 - 1
617     send_eapol(hapd, addr, build_eapol(msg))
618
619     reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, rsne, kck)
620
621     msg = recv_eapol(hapd)
622     if anonce != msg['rsn_key_nonce']:
623         raise Exception("ANonce changed")
624     logger.info("Replay same data back")
625     send_eapol(hapd, addr, build_eapol(msg))
626
627     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
628     hapd_connected(hapd)
629
630 def test_ap_wpa2_psk_ext_eapol_retry1(dev, apdev):
631     """WPA2 4-way handshake with EAPOL-Key 1/4 retransmitted"""
632     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
633
634     msg1 = recv_eapol(hapd)
635     anonce = msg1['rsn_key_nonce']
636
637     msg2 = recv_eapol(hapd)
638     if anonce != msg2['rsn_key_nonce']:
639         raise Exception("ANonce changed")
640
641     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
642
643     logger.info("Send EAPOL-Key msg 2/4")
644     msg = msg2
645     rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
646     eapol_key_mic(kck, msg)
647     send_eapol(hapd, addr, build_eapol(msg))
648
649     msg = recv_eapol(hapd)
650     if anonce != msg['rsn_key_nonce']:
651         raise Exception("ANonce changed")
652
653     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
654     hapd_connected(hapd)
655
656 def test_ap_wpa2_psk_ext_eapol_retry1b(dev, apdev):
657     """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted"""
658     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
659
660     msg1 = recv_eapol(hapd)
661     anonce = msg1['rsn_key_nonce']
662     msg2 = recv_eapol(hapd)
663     if anonce != msg2['rsn_key_nonce']:
664         raise Exception("ANonce changed")
665
666     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
667     reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
668     reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce, rsne, kck)
669
670     msg = recv_eapol(hapd)
671     if anonce != msg['rsn_key_nonce']:
672         raise Exception("ANonce changed")
673
674     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
675     hapd_connected(hapd)
676
677 def test_ap_wpa2_psk_ext_eapol_retry1c(dev, apdev):
678     """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted and SNonce changing"""
679     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
680
681     msg1 = recv_eapol(hapd)
682     anonce = msg1['rsn_key_nonce']
683
684     msg2 = recv_eapol(hapd)
685     if anonce != msg2['rsn_key_nonce']:
686         raise Exception("ANonce changed")
687     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
688     reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
689
690     snonce2 = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
691     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce2, anonce)
692     reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce2, rsne, kck)
693
694     msg = recv_eapol(hapd)
695     if anonce != msg['rsn_key_nonce']:
696         raise Exception("ANonce changed")
697     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
698     hapd_connected(hapd)
699
700 def test_ap_wpa2_psk_ext_eapol_retry1d(dev, apdev):
701     """WPA2 4-way handshake with EAPOL-Key 1/4 and 2/4 retransmitted and SNonce changing and older used"""
702     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
703
704     msg1 = recv_eapol(hapd)
705     anonce = msg1['rsn_key_nonce']
706     msg2 = recv_eapol(hapd)
707     if anonce != msg2['rsn_key_nonce']:
708         raise Exception("ANonce changed")
709
710     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
711     reply_eapol("2/4 (a)", hapd, addr, msg1, 0x010a, snonce, rsne, kck)
712
713     snonce2 = binascii.unhexlify('2222222222222222222222222222222222222222222222222222222222222222')
714     (ptk2, kck2, kek2) = pmk_to_ptk(pmk, addr, bssid, snonce2, anonce)
715
716     reply_eapol("2/4 (b)", hapd, addr, msg2, 0x010a, snonce2, rsne, kck2)
717     msg = recv_eapol(hapd)
718     if anonce != msg['rsn_key_nonce']:
719         raise Exception("ANonce changed")
720     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
721     hapd_connected(hapd)
722
723 def test_ap_wpa2_psk_ext_eapol_type_diff(dev, apdev):
724     """WPA2 4-way handshake using external EAPOL supplicant"""
725     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
726
727     msg = recv_eapol(hapd)
728     anonce = msg['rsn_key_nonce']
729
730     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
731
732     # Incorrect descriptor type (frame dropped)
733     msg['descr_type'] = 253
734     rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
735     eapol_key_mic(kck, msg)
736     send_eapol(hapd, addr, build_eapol(msg))
737
738     # Incorrect descriptor type, but with a workaround (frame processed)
739     msg['descr_type'] = 254
740     rsn_eapol_key_set(msg, 0x010a, 0, snonce, rsne)
741     eapol_key_mic(kck, msg)
742     send_eapol(hapd, addr, build_eapol(msg))
743
744     msg = recv_eapol(hapd)
745     if anonce != msg['rsn_key_nonce']:
746         raise Exception("ANonce changed")
747     logger.info("Replay same data back")
748     send_eapol(hapd, addr, build_eapol(msg))
749
750     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
751     hapd_connected(hapd)
752
753 def test_ap_wpa_psk_ext_eapol(dev, apdev):
754     """WPA2-PSK AP using external EAPOL supplicant"""
755     (bssid,ssid,hapd,snonce,pmk,addr,wpae) = eapol_test(apdev[0], dev[0],
756                                                         wpa2=False)
757
758     msg = recv_eapol(hapd)
759     anonce = msg['rsn_key_nonce']
760     logger.info("Replay same data back")
761     send_eapol(hapd, addr, build_eapol(msg))
762     logger.info("Too short data")
763     send_eapol(hapd, addr, build_eapol(msg)[0:98])
764
765     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
766     msg['descr_type'] = 2
767     reply_eapol("2/4(invalid type)", hapd, addr, msg, 0x010a, snonce, wpae, kck)
768     msg['descr_type'] = 254
769     reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, wpae, kck)
770
771     msg = recv_eapol(hapd)
772     if anonce != msg['rsn_key_nonce']:
773         raise Exception("ANonce changed")
774     logger.info("Replay same data back")
775     send_eapol(hapd, addr, build_eapol(msg))
776
777     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
778     hapd_connected(hapd)
779
780 def test_ap_wpa2_psk_ext_eapol_key_info(dev, apdev):
781     """WPA2-PSK 4-way handshake with strange key info values"""
782     (bssid,ssid,hapd,snonce,pmk,addr,rsne) = eapol_test(apdev[0], dev[0])
783
784     msg = recv_eapol(hapd)
785     anonce = msg['rsn_key_nonce']
786
787     (ptk, kck, kek) = pmk_to_ptk(pmk, addr, bssid, snonce, anonce)
788     rsn_eapol_key_set(msg, 0x0000, 0, snonce, rsne)
789     send_eapol(hapd, addr, build_eapol(msg))
790     rsn_eapol_key_set(msg, 0xffff, 0, snonce, rsne)
791     send_eapol(hapd, addr, build_eapol(msg))
792     # SMK M1
793     rsn_eapol_key_set(msg, 0x2802, 0, snonce, rsne)
794     send_eapol(hapd, addr, build_eapol(msg))
795     # SMK M3
796     rsn_eapol_key_set(msg, 0x2002, 0, snonce, rsne)
797     send_eapol(hapd, addr, build_eapol(msg))
798     # Request
799     rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
800     send_eapol(hapd, addr, build_eapol(msg))
801     # Request
802     rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
803     tmp_kck = binascii.unhexlify('00000000000000000000000000000000')
804     eapol_key_mic(tmp_kck, msg)
805     send_eapol(hapd, addr, build_eapol(msg))
806
807     reply_eapol("2/4", hapd, addr, msg, 0x010a, snonce, rsne, kck)
808
809     msg = recv_eapol(hapd)
810     if anonce != msg['rsn_key_nonce']:
811         raise Exception("ANonce changed")
812
813     # Request (valic MIC)
814     rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
815     eapol_key_mic(kck, msg)
816     send_eapol(hapd, addr, build_eapol(msg))
817     # Request (valid MIC, replayed counter)
818     rsn_eapol_key_set(msg, 0x0902, 0, snonce, rsne)
819     eapol_key_mic(kck, msg)
820     send_eapol(hapd, addr, build_eapol(msg))
821
822     reply_eapol("4/4", hapd, addr, msg, 0x030a, None, None, kck)
823     hapd_connected(hapd)
824
825 def find_wpas_process(dev):
826     ifname = dev.ifname
827     cmd = subprocess.Popen(['ps', 'ax'], stdout=subprocess.PIPE)
828     (data,err) = cmd.communicate()
829     for l in data.splitlines():
830         if "wpa_supplicant" not in l:
831             continue
832         if "-i" + ifname not in l:
833             continue
834         return int(l.strip().split(' ')[0])
835     raise Exception("Could not find wpa_supplicant process")
836
837 def read_process_memory(pid, key=None):
838     buf = bytes()
839     with open('/proc/%d/maps' % pid, 'r') as maps, \
840          open('/proc/%d/mem' % pid, 'r') as mem:
841         for l in maps.readlines():
842             m = re.match(r'([0-9a-f]+)-([0-9a-f]+) ([-r][-w][-x][-p])', l)
843             if not m:
844                 continue
845             start = int(m.group(1), 16)
846             end = int(m.group(2), 16)
847             perm = m.group(3)
848             if start > 0xffffffffffff:
849                 continue
850             if end < start:
851                 continue
852             if not perm.startswith('rw'):
853                 continue
854             mem.seek(start)
855             data = mem.read(end - start)
856             buf += data
857             if key and key in data:
858                 logger.info("Key found in " + l)
859     return buf
860
861 def verify_not_present(buf, key, fname, keyname):
862     pos = buf.find(key)
863     if pos < 0:
864         return
865
866     prefix = 2048 if pos > 2048 else pos
867     with open(fname + keyname, 'w') as f:
868         f.write(buf[pos - prefix:pos + 2048])
869     raise Exception(keyname + " found after disassociation")
870
871 def get_key_locations(buf, key, keyname):
872     count = 0
873     pos = 0
874     while True:
875         pos = buf.find(key, pos)
876         if pos < 0:
877             break
878         logger.info("Found %s at %d" % (keyname, pos))
879         count += 1
880         pos += len(key)
881     return count
882
883 def test_wpa2_psk_key_lifetime_in_memory(dev, apdev, params):
884     """WPA2-PSK and PSK/PTK lifetime in memory"""
885     ssid = "test-wpa2-psk"
886     passphrase = 'qwertyuiop'
887     psk = '602e323e077bc63bd80307ef4745b754b0ae0a925c2638ecd13a794b9527b9e6'
888     pmk = binascii.unhexlify(psk)
889     p = hostapd.wpa2_params(ssid=ssid)
890     p['wpa_psk'] = psk
891     hapd = hostapd.add_ap(apdev[0]['ifname'], p)
892
893     pid = find_wpas_process(dev[0])
894
895     id = dev[0].connect(ssid, raw_psk=psk, scan_freq="2412",
896                         only_add_network=True)
897
898     logger.info("Checking keys in memory after network profile configuration")
899     buf = read_process_memory(pid, pmk)
900     get_key_locations(buf, pmk, "PMK")
901
902     dev[0].request("REMOVE_NETWORK all")
903     logger.info("Checking keys in memory after network profile removal")
904     buf = read_process_memory(pid, pmk)
905     get_key_locations(buf, pmk, "PMK")
906
907     id = dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
908                         only_add_network=True)
909
910     logger.info("Checking keys in memory before connection")
911     buf = read_process_memory(pid, pmk)
912     get_key_locations(buf, pmk, "PMK")
913
914     dev[0].connect_network(id, timeout=20)
915     time.sleep(1)
916
917     buf = read_process_memory(pid, pmk)
918
919     dev[0].request("DISCONNECT")
920     dev[0].wait_disconnected()
921
922     dev[0].relog()
923     ptk = None
924     gtk = None
925     with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
926         for l in f.readlines():
927             if "WPA: PTK - hexdump" in l:
928                 val = l.strip().split(':')[3].replace(' ', '')
929                 ptk = binascii.unhexlify(val)
930             if "WPA: Group Key - hexdump" in l:
931                 val = l.strip().split(':')[3].replace(' ', '')
932                 gtk = binascii.unhexlify(val)
933     if not pmk or not ptk or not gtk:
934         raise Exception("Could not find keys from debug log")
935     if len(gtk) != 16:
936         raise Exception("Unexpected GTK length")
937
938     kck = ptk[0:16]
939     kek = ptk[16:32]
940     tk = ptk[32:48]
941
942     logger.info("Checking keys in memory while associated")
943     get_key_locations(buf, pmk, "PMK")
944     if pmk not in buf:
945         raise HwsimSkip("PMK not found while associated")
946     if kck not in buf:
947         raise Exception("KCK not found while associated")
948     if kek not in buf:
949         raise Exception("KEK not found while associated")
950     if tk in buf:
951         raise Exception("TK found from memory")
952     if gtk in buf:
953         raise Exception("GTK found from memory")
954
955     logger.info("Checking keys in memory after disassociation")
956     buf = read_process_memory(pid, pmk)
957     get_key_locations(buf, pmk, "PMK")
958
959     # Note: PMK/PSK is still present in network configuration
960
961     fname = os.path.join(params['logdir'],
962                          'wpa2_psk_key_lifetime_in_memory.memctx-')
963     verify_not_present(buf, kck, fname, "KCK")
964     verify_not_present(buf, kek, fname, "KEK")
965     verify_not_present(buf, tk, fname, "TK")
966     verify_not_present(buf, gtk, fname, "GTK")
967
968     dev[0].request("REMOVE_NETWORK all")
969
970     logger.info("Checking keys in memory after network profile removal")
971     buf = read_process_memory(pid, pmk)
972     get_key_locations(buf, pmk, "PMK")
973
974     verify_not_present(buf, pmk, fname, "PMK")
975     verify_not_present(buf, kck, fname, "KCK")
976     verify_not_present(buf, kek, fname, "KEK")
977     verify_not_present(buf, tk, fname, "TK")
978     verify_not_present(buf, gtk, fname, "GTK")
979
980 def test_ap_wpa2_psk_wep(dev, apdev):
981     """WPA2-PSK AP and WEP enabled"""
982     ssid = "test-wpa2-psk"
983     passphrase = 'qwertyuiop'
984     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
985     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
986     try:
987         hapd.set('wep_key0', '"hello"')
988         raise Exception("WEP key accepted to WPA2 network")
989     except Exception:
990         pass
991
992 def test_ap_wpa2_psk_wpas_in_bridge(dev, apdev):
993     """WPA2-PSK AP and wpas interface in a bridge"""
994     br_ifname='sta-br0'
995     ifname='wlan5'
996     try:
997         _test_ap_wpa2_psk_wpas_in_bridge(dev, apdev)
998     finally:
999         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
1000         subprocess.call(['brctl', 'delif', br_ifname, ifname])
1001         subprocess.call(['brctl', 'delbr', br_ifname])
1002         subprocess.call(['iw', ifname, 'set', '4addr', 'on'])
1003
1004 def _test_ap_wpa2_psk_wpas_in_bridge(dev, apdev):
1005     ssid = "test-wpa2-psk"
1006     passphrase = 'qwertyuiop'
1007     params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
1008     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1009
1010     br_ifname='sta-br0'
1011     ifname='wlan5'
1012     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1013     subprocess.call(['brctl', 'addbr', br_ifname])
1014     subprocess.call(['brctl', 'setfd', br_ifname, '0'])
1015     subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
1016     subprocess.call(['iw', ifname, 'set', '4addr', 'on'])
1017     subprocess.check_call(['brctl', 'addif', br_ifname, ifname])
1018     wpas.interface_add(ifname, br_ifname=br_ifname)
1019
1020     wpas.connect(ssid, psk=passphrase, scan_freq="2412")