tests: Pass full apdev to add_ap() function (1)
[mech_eap.git] / tests / hwsim / test_ap_pmf.py
1 # Protected management frames tests
2 # Copyright (c) 2013, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import time
8 import subprocess
9 import logging
10 logger = logging.getLogger()
11
12 import hwsim_utils
13 import hostapd
14 from wlantest import Wlantest
15 from wpasupplicant import WpaSupplicant
16 from test_ap_eap import eap_connect
17
18 def test_ap_pmf_required(dev, apdev):
19     """WPA2-PSK AP with PMF required"""
20     ssid = "test-pmf-required"
21     wt = Wlantest()
22     wt.flush()
23     wt.add_passphrase("12345678")
24     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
25     params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
26     params["ieee80211w"] = "2";
27     hapd = hostapd.add_ap(apdev[0], params)
28     key_mgmt = hapd.get_config()['key_mgmt']
29     if key_mgmt.split(' ')[0] != "WPA-PSK-SHA256":
30         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
31     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
32                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
33                    scan_freq="2412")
34     if "[WPA2-PSK-SHA256-CCMP]" not in dev[0].request("SCAN_RESULTS"):
35         raise Exception("Scan results missing RSN element info")
36     hwsim_utils.test_connectivity(dev[0], hapd)
37     dev[1].connect(ssid, psk="12345678", ieee80211w="2",
38                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
39                    scan_freq="2412")
40     hwsim_utils.test_connectivity(dev[1], hapd)
41     hapd = hostapd.Hostapd(apdev[0]['ifname'])
42     hapd.request("SA_QUERY " + dev[0].p2p_interface_addr())
43     hapd.request("SA_QUERY " + dev[1].p2p_interface_addr())
44     wt.require_ap_pmf_mandatory(apdev[0]['bssid'])
45     wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr())
46     wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr())
47     time.sleep(0.1)
48     if wt.get_sta_counter("valid_saqueryresp_tx", apdev[0]['bssid'],
49                           dev[0].p2p_interface_addr()) < 1:
50         raise Exception("STA did not reply to SA Query")
51     if wt.get_sta_counter("valid_saqueryresp_tx", apdev[0]['bssid'],
52                           dev[1].p2p_interface_addr()) < 1:
53         raise Exception("STA did not reply to SA Query")
54
55 def test_ap_pmf_optional(dev, apdev):
56     """WPA2-PSK AP with PMF optional"""
57     ssid = "test-pmf-optional"
58     wt = Wlantest()
59     wt.flush()
60     wt.add_passphrase("12345678")
61     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
62     params["wpa_key_mgmt"] = "WPA-PSK";
63     params["ieee80211w"] = "1";
64     hapd = hostapd.add_ap(apdev[0], params)
65     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
66                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
67                    scan_freq="2412")
68     hwsim_utils.test_connectivity(dev[0], hapd)
69     dev[1].connect(ssid, psk="12345678", ieee80211w="2",
70                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
71                    scan_freq="2412")
72     hwsim_utils.test_connectivity(dev[1], hapd)
73     wt.require_ap_pmf_optional(apdev[0]['bssid'])
74     wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr())
75     wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr())
76
77 def test_ap_pmf_optional_2akm(dev, apdev):
78     """WPA2-PSK AP with PMF optional (2 AKMs)"""
79     ssid = "test-pmf-optional-2akm"
80     wt = Wlantest()
81     wt.flush()
82     wt.add_passphrase("12345678")
83     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
84     params["wpa_key_mgmt"] = "WPA-PSK WPA-PSK-SHA256";
85     params["ieee80211w"] = "1";
86     hapd = hostapd.add_ap(apdev[0], params)
87     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
88                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
89                    scan_freq="2412")
90     hwsim_utils.test_connectivity(dev[0], hapd)
91     dev[1].connect(ssid, psk="12345678", ieee80211w="2",
92                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
93                    scan_freq="2412")
94     hwsim_utils.test_connectivity(dev[1], hapd)
95     wt.require_ap_pmf_optional(apdev[0]['bssid'])
96     wt.require_sta_pmf(apdev[0]['bssid'], dev[0].p2p_interface_addr())
97     wt.require_sta_key_mgmt(apdev[0]['bssid'], dev[0].p2p_interface_addr(),
98                             "PSK-SHA256")
99     wt.require_sta_pmf_mandatory(apdev[0]['bssid'], dev[1].p2p_interface_addr())
100     wt.require_sta_key_mgmt(apdev[0]['bssid'], dev[1].p2p_interface_addr(),
101                             "PSK-SHA256")
102
103 def test_ap_pmf_negative(dev, apdev):
104     """WPA2-PSK AP without PMF (negative test)"""
105     ssid = "test-pmf-negative"
106     wt = Wlantest()
107     wt.flush()
108     wt.add_passphrase("12345678")
109     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
110     hapd = hostapd.add_ap(apdev[0], params)
111     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
112                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
113                    scan_freq="2412")
114     hwsim_utils.test_connectivity(dev[0], hapd)
115     try:
116         dev[1].connect(ssid, psk="12345678", ieee80211w="2",
117                        key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
118                        scan_freq="2412")
119         hwsim_utils.test_connectivity(dev[1], hapd)
120         raise Exception("PMF required STA connected to no PMF AP")
121     except Exception, e:
122         logger.debug("Ignore expected exception: " + str(e))
123     wt.require_ap_no_pmf(apdev[0]['bssid'])
124
125 def test_ap_pmf_assoc_comeback(dev, apdev):
126     """WPA2-PSK AP with PMF association comeback"""
127     ssid = "assoc-comeback"
128     wt = Wlantest()
129     wt.flush()
130     wt.add_passphrase("12345678")
131     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
132     params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
133     params["ieee80211w"] = "2";
134     hapd = hostapd.add_ap(apdev[0], params)
135     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
136                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
137                    scan_freq="2412")
138     hapd.set("ext_mgmt_frame_handling", "1")
139     dev[0].request("DISCONNECT")
140     dev[0].wait_disconnected(timeout=10)
141     hapd.set("ext_mgmt_frame_handling", "0")
142     dev[0].request("REASSOCIATE")
143     dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
144     if wt.get_sta_counter("assocresp_comeback", apdev[0]['bssid'],
145                           dev[0].p2p_interface_addr()) < 1:
146         raise Exception("AP did not use association comeback request")
147
148 def test_ap_pmf_assoc_comeback2(dev, apdev):
149     """WPA2-PSK AP with PMF association comeback (using DROP_SA)"""
150     ssid = "assoc-comeback"
151     wt = Wlantest()
152     wt.flush()
153     wt.add_passphrase("12345678")
154     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
155     params["wpa_key_mgmt"] = "WPA-PSK";
156     params["ieee80211w"] = "1";
157     hapd = hostapd.add_ap(apdev[0], params)
158     dev[0].connect(ssid, psk="12345678", ieee80211w="2",
159                    key_mgmt="WPA-PSK", proto="WPA2", scan_freq="2412")
160     if "OK" not in dev[0].request("DROP_SA"):
161         raise Exception("DROP_SA failed")
162     dev[0].request("REASSOCIATE")
163     dev[0].wait_connected(timeout=10, error="Timeout on re-connection")
164     if wt.get_sta_counter("reassocresp_comeback", apdev[0]['bssid'],
165                           dev[0].p2p_interface_addr()) < 1:
166         raise Exception("AP did not use reassociation comeback request")
167
168 def test_ap_pmf_sta_sa_query(dev, apdev):
169     """WPA2-PSK AP with station using SA Query"""
170     ssid = "assoc-comeback"
171     addr = dev[0].own_addr()
172     wt = Wlantest()
173     wt.flush()
174     wt.add_passphrase("12345678")
175
176     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
177     wpas.interface_add("wlan5", drv_params="use_monitor=1")
178     id = wpas.add_network()
179     wpas.set_network(id, "mode", "2")
180     wpas.set_network_quoted(id, "ssid", ssid)
181     wpas.set_network(id, "proto", "WPA2")
182     wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
183     wpas.set_network(id, "ieee80211w", "2")
184     wpas.set_network_quoted(id, "psk", "12345678")
185     wpas.set_network(id, "pairwise", "CCMP")
186     wpas.set_network(id, "group", "CCMP")
187     wpas.set_network(id, "frequency", "2412")
188     wpas.connect_network(id)
189     bssid = wpas.own_addr()
190     wpas.dump_monitor()
191
192     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
193                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
194                    scan_freq="2412")
195     wpas.dump_monitor()
196     wpas.request("DEAUTHENTICATE " + addr + " test=0")
197     wpas.dump_monitor()
198     wpas.request("DISASSOCIATE " + addr + " test=0")
199     wpas.dump_monitor()
200     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
201     if ev is not None:
202         raise Exception("Unexpected disconnection")
203
204     wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
205     wpas.dump_monitor()
206     wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
207     wpas.dump_monitor()
208     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
209     if ev is not None:
210         raise Exception("Unexpected disconnection")
211     if wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr) < 1:
212         raise Exception("STA did not send SA Query")
213     if wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr) < 1:
214         raise Exception("AP did not reply to SA Query")
215     wpas.dump_monitor()
216
217 def test_ap_pmf_sta_sa_query_no_response(dev, apdev):
218     """WPA2-PSK AP with station using SA Query and getting no response"""
219     ssid = "assoc-comeback"
220     addr = dev[0].own_addr()
221
222     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
223     wpas.interface_add("wlan5", drv_params="use_monitor=1")
224     id = wpas.add_network()
225     wpas.set_network(id, "mode", "2")
226     wpas.set_network_quoted(id, "ssid", ssid)
227     wpas.set_network(id, "proto", "WPA2")
228     wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
229     wpas.set_network(id, "ieee80211w", "2")
230     wpas.set_network_quoted(id, "psk", "12345678")
231     wpas.set_network(id, "pairwise", "CCMP")
232     wpas.set_network(id, "group", "CCMP")
233     wpas.set_network(id, "frequency", "2412")
234     wpas.connect_network(id)
235     bssid = wpas.own_addr()
236     wpas.dump_monitor()
237
238     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
239                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
240                    scan_freq="2412")
241     wpas.dump_monitor()
242     wpas.request("DEAUTHENTICATE " + addr + " test=0")
243     wpas.dump_monitor()
244     wpas.request("DISASSOCIATE " + addr + " test=0")
245     wpas.dump_monitor()
246     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
247     if ev is not None:
248         raise Exception("Unexpected disconnection")
249
250     wpas.request("SET ext_mgmt_frame_handling 1")
251     wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
252     wpas.dump_monitor()
253     wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
254     wpas.dump_monitor()
255     dev[0].wait_disconnected()
256     wpas.dump_monitor()
257     wpas.request("SET ext_mgmt_frame_handling 0")
258     dev[0].wait_connected()
259     wpas.dump_monitor()
260
261 def test_ap_pmf_sta_unprot_deauth_burst(dev, apdev):
262     """WPA2-PSK AP with station receiving burst of unprotected Deauthentication frames"""
263     ssid = "deauth-attack"
264     addr = dev[0].own_addr()
265     wt = Wlantest()
266     wt.flush()
267     wt.add_passphrase("12345678")
268
269     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
270     wpas.interface_add("wlan5", drv_params="use_monitor=1")
271     id = wpas.add_network()
272     wpas.set_network(id, "mode", "2")
273     wpas.set_network_quoted(id, "ssid", ssid)
274     wpas.set_network(id, "proto", "WPA2")
275     wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
276     wpas.set_network(id, "ieee80211w", "2")
277     wpas.set_network_quoted(id, "psk", "12345678")
278     wpas.set_network(id, "pairwise", "CCMP")
279     wpas.set_network(id, "group", "CCMP")
280     wpas.set_network(id, "frequency", "2412")
281     wpas.connect_network(id)
282     bssid = wpas.own_addr()
283
284     dev[0].connect(ssid, psk="12345678", ieee80211w="1",
285                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
286                    scan_freq="2412")
287
288     for i in range(0, 10):
289         wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
290         wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
291     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
292     if ev is not None:
293         raise Exception("Unexpected disconnection")
294     num_req = wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr)
295     num_resp = wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr)
296     if num_req < 1:
297         raise Exception("STA did not send SA Query")
298     if num_resp < 1:
299         raise Exception("AP did not reply to SA Query")
300     if num_req > 1:
301         raise Exception("STA initiated too many SA Query procedures (%d)" % num_req)
302
303     time.sleep(10)
304     for i in range(0, 5):
305         wpas.request("DEAUTHENTICATE " + addr + " reason=6 test=0")
306         wpas.request("DISASSOCIATE " + addr + " reason=7 test=0")
307     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
308     if ev is not None:
309         raise Exception("Unexpected disconnection")
310     num_req = wt.get_sta_counter("valid_saqueryreq_tx", bssid, addr)
311     num_resp = wt.get_sta_counter("valid_saqueryresp_rx", bssid, addr)
312     if num_req != 2 or num_resp != 2:
313         raise Exception("Unexpected number of SA Query procedures (req=%d resp=%d)" % (num_req, num_resp))
314
315 def test_ap_pmf_required_eap(dev, apdev):
316     """WPA2-EAP AP with PMF required"""
317     ssid = "test-pmf-required-eap"
318     params = hostapd.wpa2_eap_params(ssid=ssid)
319     params["wpa_key_mgmt"] = "WPA-EAP-SHA256";
320     params["ieee80211w"] = "2";
321     hapd = hostapd.add_ap(apdev[0], params)
322     key_mgmt = hapd.get_config()['key_mgmt']
323     if key_mgmt.split(' ')[0] != "WPA-EAP-SHA256":
324         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
325     dev[0].connect("test-pmf-required-eap", key_mgmt="WPA-EAP-SHA256",
326                    ieee80211w="2", eap="PSK", identity="psk.user@example.com",
327                    password_hex="0123456789abcdef0123456789abcdef",
328                    scan_freq="2412")
329     dev[1].connect("test-pmf-required-eap", key_mgmt="WPA-EAP WPA-EAP-SHA256",
330                    ieee80211w="1", eap="PSK", identity="psk.user@example.com",
331                    password_hex="0123456789abcdef0123456789abcdef",
332                    scan_freq="2412")
333
334 def test_ap_pmf_optional_eap(dev, apdev):
335     """WPA2EAP AP with PMF optional"""
336     params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
337     params["ieee80211w"] = "1";
338     hapd = hostapd.add_ap(apdev[0], params)
339     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", eap="TTLS",
340                    identity="pap user", anonymous_identity="ttls",
341                    password="password",
342                    ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
343                    ieee80211w="1", scan_freq="2412")
344     dev[1].connect("test-wpa2-eap", key_mgmt="WPA-EAP WPA-EAP-SHA256",
345                    eap="TTLS", identity="pap user", anonymous_identity="ttls",
346                    password="password",
347                    ca_cert="auth_serv/ca.pem", phase2="auth=PAP",
348                    ieee80211w="2", scan_freq="2412")
349
350 def test_ap_pmf_required_sha1(dev, apdev):
351     """WPA2-PSK AP with PMF required with SHA1 AKM"""
352     ssid = "test-pmf-required-sha1"
353     wt = Wlantest()
354     wt.flush()
355     wt.add_passphrase("12345678")
356     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
357     params["wpa_key_mgmt"] = "WPA-PSK";
358     params["ieee80211w"] = "2";
359     hapd = hostapd.add_ap(apdev[0], params)
360     key_mgmt = hapd.get_config()['key_mgmt']
361     if key_mgmt.split(' ')[0] != "WPA-PSK":
362         raise Exception("Unexpected GET_CONFIG(key_mgmt): " + key_mgmt)
363     dev[0].connect(ssid, psk="12345678", ieee80211w="2",
364                    key_mgmt="WPA-PSK", proto="WPA2", scan_freq="2412")
365     if "[WPA2-PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
366         raise Exception("Scan results missing RSN element info")
367     hwsim_utils.test_connectivity(dev[0], hapd)
368
369 def test_ap_pmf_toggle(dev, apdev):
370     """WPA2-PSK AP with PMF optional and changing PMF on reassociation"""
371     try:
372         _test_ap_pmf_toggle(dev, apdev)
373     finally:
374         dev[0].request("SET reassoc_same_bss_optim 0")
375
376 def _test_ap_pmf_toggle(dev, apdev):
377     ssid = "test-pmf-optional"
378     wt = Wlantest()
379     wt.flush()
380     wt.add_passphrase("12345678")
381     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
382     params["wpa_key_mgmt"] = "WPA-PSK";
383     params["ieee80211w"] = "1";
384     params["assoc_sa_query_max_timeout"] = "1"
385     params["assoc_sa_query_retry_timeout"] = "1"
386     hapd = hostapd.add_ap(apdev[0], params)
387     bssid = apdev[0]['bssid']
388     addr = dev[0].own_addr()
389     dev[0].request("SET reassoc_same_bss_optim 1")
390     id = dev[0].connect(ssid, psk="12345678", ieee80211w="1",
391                         key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
392                         scan_freq="2412")
393     wt.require_ap_pmf_optional(bssid)
394     wt.require_sta_pmf(bssid, addr)
395     sta = hapd.get_sta(addr)
396     if '[MFP]' not in sta['flags']:
397         raise Exception("MFP flag not present for STA")
398
399     dev[0].set_network(id, "ieee80211w", "0")
400     dev[0].request("REASSOCIATE")
401     dev[0].wait_connected()
402     wt.require_sta_no_pmf(bssid, addr)
403     sta = hapd.get_sta(addr)
404     if '[MFP]' in sta['flags']:
405         raise Exception("MFP flag unexpectedly present for STA")
406     cmd = subprocess.Popen(['iw', 'dev', apdev[0]['ifname'], 'station', 'get',
407                             addr], stdout=subprocess.PIPE)
408     (data,err) = cmd.communicate()
409     if "yes" in [l for l in data.splitlines() if "MFP" in l][0]:
410         raise Exception("Kernel STA entry had MFP enabled")
411
412     dev[0].set_network(id, "ieee80211w", "1")
413     dev[0].request("REASSOCIATE")
414     dev[0].wait_connected()
415     wt.require_sta_pmf(bssid, addr)
416     sta = hapd.get_sta(addr)
417     if '[MFP]' not in sta['flags']:
418         raise Exception("MFP flag not present for STA")
419     cmd = subprocess.Popen(['iw', 'dev', apdev[0]['ifname'], 'station', 'get',
420                             addr], stdout=subprocess.PIPE)
421     (data,err) = cmd.communicate()
422     if "yes" not in [l for l in data.splitlines() if "MFP" in l][0]:
423         raise Exception("Kernel STA entry did not have MFP enabled")
424
425 def test_ap_pmf_required_sta_no_pmf(dev, apdev):
426     """WPA2-PSK AP with PMF required and PMF disabled on STA"""
427     ssid = "test-pmf-required"
428     params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
429     params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
430     params["ieee80211w"] = "2";
431     hapd = hostapd.add_ap(apdev[0], params)
432
433     # Disable PMF on the station and try to connect
434     dev[0].connect(ssid, psk="12345678", ieee80211w="0",
435                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
436                    scan_freq="2412", wait_connect=False)
437     ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND",
438                             "CTRL-EVENT-ASSOC-REJECT"], timeout=2)
439     if ev is None:
440         raise Exception("No connection result")
441     if "CTRL-EVENT-ASSOC-REJECT" in ev:
442         raise Exception("Tried to connect to PMF required AP without PMF enabled")
443     dev[0].request("REMOVE_NETWORK all")