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