Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / tests / hwsim / test_ap_vlan.py
1 #!/usr/bin/python
2 #
3 # Test cases for AP VLAN
4 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
5 #
6 # This software may be distributed under the terms of the BSD license.
7 # See README for more details.
8
9 import time
10 import subprocess
11 import logging
12 logger = logging.getLogger(__name__)
13
14 try:
15     import netifaces
16     netifaces_imported = True
17 except ImportError:
18     netifaces_imported = False
19
20 import hwsim_utils
21 import hostapd
22 from utils import iface_is_in_bridge, HwsimSkip
23
24 def test_ap_vlan_open(dev, apdev):
25     """AP VLAN with open network"""
26     params = { "ssid": "test-vlan-open",
27                "dynamic_vlan": "1",
28                "accept_mac_file": "hostapd.accept" }
29     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
30
31     dev[0].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
32     dev[1].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
33     dev[2].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
34     hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
35     hwsim_utils.test_connectivity_iface(dev[1], hapd, "brvlan2")
36     hwsim_utils.test_connectivity(dev[2], hapd)
37
38 def test_ap_vlan_file_open(dev, apdev):
39     """AP VLAN with open network and vlan_file mapping"""
40     params = { "ssid": "test-vlan-open",
41                "dynamic_vlan": "1",
42                "vlan_file": "hostapd.vlan",
43                "accept_mac_file": "hostapd.accept" }
44     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
45
46     dev[0].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
47     dev[1].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
48     dev[2].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
49     hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
50     hwsim_utils.test_connectivity_iface(dev[1], hapd, "brvlan2")
51     hwsim_utils.test_connectivity(dev[2], hapd)
52
53 def test_ap_vlan_wpa2(dev, apdev):
54     """AP VLAN with WPA2-PSK"""
55     params = hostapd.wpa2_params(ssid="test-vlan",
56                                  passphrase="12345678")
57     params['dynamic_vlan'] = "1";
58     params['accept_mac_file'] = "hostapd.accept";
59     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
60
61     dev[0].connect("test-vlan", psk="12345678", scan_freq="2412")
62     dev[1].connect("test-vlan", psk="12345678", scan_freq="2412")
63     dev[2].connect("test-vlan", psk="12345678", scan_freq="2412")
64     hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
65     hwsim_utils.test_connectivity_iface(dev[1], hapd, "brvlan2")
66     hwsim_utils.test_connectivity(dev[2], hapd)
67
68 def test_ap_vlan_wpa2_radius(dev, apdev):
69     """AP VLAN with WPA2-Enterprise and RADIUS attributes"""
70     params = hostapd.wpa2_eap_params(ssid="test-vlan")
71     params['dynamic_vlan'] = "1";
72     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
73
74     dev[0].connect("test-vlan", key_mgmt="WPA-EAP", eap="PAX",
75                    identity="vlan1",
76                    password_hex="0123456789abcdef0123456789abcdef",
77                    scan_freq="2412")
78     dev[1].connect("test-vlan", key_mgmt="WPA-EAP", eap="PAX",
79                    identity="vlan2",
80                    password_hex="0123456789abcdef0123456789abcdef",
81                    scan_freq="2412")
82     dev[2].connect("test-vlan", key_mgmt="WPA-EAP", eap="PAX",
83                    identity="pax.user@example.com",
84                    password_hex="0123456789abcdef0123456789abcdef",
85                    scan_freq="2412")
86     hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
87     hwsim_utils.test_connectivity_iface(dev[1], hapd, "brvlan2")
88     hwsim_utils.test_connectivity(dev[2], hapd)
89
90 def test_ap_vlan_wpa2_radius_id_change(dev, apdev):
91     """AP VLAN with WPA2-Enterprise and RADIUS attributes changing VLANID"""
92     as_params = { "ssid": "as",
93                   "beacon_int": "2000",
94                   "radius_server_clients": "auth_serv/radius_clients.conf",
95                   "radius_server_auth_port": '18128',
96                   "eap_server": "1",
97                   "eap_user_file": "auth_serv/eap_user.conf",
98                   "ca_cert": "auth_serv/ca.pem",
99                   "server_cert": "auth_serv/server.pem",
100                   "private_key": "auth_serv/server.key" }
101     authserv = hostapd.add_ap(apdev[1]['ifname'], as_params)
102
103     params = hostapd.wpa2_eap_params(ssid="test-vlan")
104     params['dynamic_vlan'] = "1";
105     params['auth_server_port'] = "18128"
106     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
107
108     dev[0].connect("test-vlan", key_mgmt="WPA-EAP", eap="PAX",
109                    identity="vlan1",
110                    password_hex="0123456789abcdef0123456789abcdef",
111                    scan_freq="2412")
112     hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
113
114     logger.info("VLAN-ID -> 2")
115
116     authserv.disable()
117     authserv.set('eap_user_file', "auth_serv/eap_user_vlan.conf")
118     authserv.enable()
119
120     dev[0].dump_monitor()
121     dev[0].request("REAUTHENTICATE")
122     ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
123     if ev is None:
124         raise Exception("EAP reauthentication timed out")
125     ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=5)
126     if ev is None:
127         raise Exception("4-way handshake after reauthentication timed out")
128     state = dev[0].get_status_field('wpa_state')
129     if state != "COMPLETED":
130         raise Exception("Unexpected state after reauth: " + state)
131     sta = hapd.get_sta(dev[0].own_addr())
132     if 'vlan_id' not in sta:
133         raise Exception("No VLAN ID in STA info")
134     if sta['vlan_id'] != '2':
135         raise Exception("Unexpected VLAN ID: " + sta['vlan_id'])
136     hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan2")
137
138     logger.info("VLAN-ID -> 1")
139     time.sleep(1)
140
141     authserv.disable()
142     authserv.set('eap_user_file', "auth_serv/eap_user.conf")
143     authserv.enable()
144
145     dev[0].dump_monitor()
146     dev[0].request("REAUTHENTICATE")
147     ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
148     if ev is None:
149         raise Exception("EAP reauthentication timed out")
150     ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=5)
151     if ev is None:
152         raise Exception("4-way handshake after reauthentication timed out")
153     state = dev[0].get_status_field('wpa_state')
154     if state != "COMPLETED":
155         raise Exception("Unexpected state after reauth: " + state)
156     sta = hapd.get_sta(dev[0].own_addr())
157     if 'vlan_id' not in sta:
158         raise Exception("No VLAN ID in STA info")
159     if sta['vlan_id'] != '1':
160         raise Exception("Unexpected VLAN ID: " + sta['vlan_id'])
161     time.sleep(0.2)
162     try:
163         hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
164     except Exception, e:
165         # It is possible for new bridge setup to not be ready immediately, so
166         # try again to avoid reporting issues related to that.
167         logger.info("First VLAN-ID 1 data test failed - try again")
168         hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
169
170 def test_ap_vlan_wpa2_radius_required(dev, apdev):
171     """AP VLAN with WPA2-Enterprise and RADIUS attributes required"""
172     params = hostapd.wpa2_eap_params(ssid="test-vlan")
173     params['dynamic_vlan'] = "2";
174     hostapd.add_ap(apdev[0]['ifname'], params)
175
176     dev[0].connect("test-vlan", key_mgmt="WPA-EAP", eap="PAX",
177                    identity="vlan1",
178                    password_hex="0123456789abcdef0123456789abcdef",
179                    scan_freq="2412")
180     dev[2].connect("test-vlan", key_mgmt="WPA-EAP", eap="PAX",
181                    identity="pax.user@example.com",
182                    password_hex="0123456789abcdef0123456789abcdef",
183                    scan_freq="2412", wait_connect=False)
184     ev = dev[2].wait_event(["CTRL-EVENT-CONNECTED",
185                             "CTRL-EVENT-DISCONNECTED"], timeout=20)
186     if ev is None:
187         raise Exception("Timeout on connection attempt")
188     if "CTRL-EVENT-CONNECTED" in ev:
189         raise Exception("Unexpected success without tunnel parameters")
190
191 def test_ap_vlan_tagged(dev, apdev):
192     """AP VLAN with tagged interface"""
193     params = { "ssid": "test-vlan-open",
194                "dynamic_vlan": "1",
195                "vlan_tagged_interface": "lo",
196                "accept_mac_file": "hostapd.accept" }
197     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
198
199     dev[0].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
200     dev[1].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
201     dev[2].connect("test-vlan-open", key_mgmt="NONE", scan_freq="2412")
202     hwsim_utils.test_connectivity_iface(dev[0], hapd, "brlo.1")
203     hwsim_utils.test_connectivity_iface(dev[1], hapd, "brlo.2")
204     hwsim_utils.test_connectivity(dev[2], hapd)
205
206 def ap_vlan_iface_cleanup_multibss_cleanup():
207     subprocess.call(['ifconfig', 'dummy0', 'down'],
208                     stderr=open('/dev/null', 'w'))
209     ifnames = [ 'wlan3.1', 'wlan3.2', 'wlan3-2.1', 'wlan3-2.2', 'dummy0.2',
210                 'dummy0.1', 'dummy0', 'brvlan1', 'brvlan2' ]
211     for ifname in ifnames:
212         subprocess.call(['ip', 'link', 'del', ifname],
213                         stderr=open('/dev/null', 'w'))
214
215 def ap_vlan_iface_test_and_prepare_environ():
216     ifaces = netifaces.interfaces()
217     if "dummy0" in ifaces:
218         raise Exception("dummy0 already exists before")
219     ifaces = netifaces.interfaces()
220     if "dummy0.1" in ifaces:
221         raise Exception("dummy0.1 already exists before")
222
223     subprocess.call(['ip', 'link', 'add', 'dummy0', 'type', 'dummy'])
224     subprocess.call(['ifconfig', 'dummy0', 'up'])
225
226     ifaces = netifaces.interfaces()
227     if not("dummy0" in ifaces):
228         raise HwsimSkip("failed to add dummy0 - missing kernel config DUMMY ?")
229
230     subprocess.call(['ip', 'link', 'add', 'link', 'dummy0', 'name', 'dummy0.1',
231                      'type', 'vlan', 'id', '1'])
232
233     ifaces = netifaces.interfaces()
234     if not("dummy0.1" in ifaces):
235         raise HwsimSkip("failed to add dummy0.1 - missing kernel config VLAN_8021Q ?")
236
237     subprocess.call(['ip', 'link', 'del', 'dummy0.1'])
238
239     ifaces = netifaces.interfaces()
240     if "dummy0.1" in ifaces:
241         raise Exception("dummy0.1 was not removed before testing")
242
243 def test_ap_vlan_iface_cleanup_multibss(dev, apdev):
244     """AP VLAN operation in multi-BSS multi-VLAN case"""
245
246     # AP VLAN with WPA2-Enterprise and RADIUS attributes changing VLANID
247     # check that multiple bss do not interfere with each other with respect
248     # to deletion of bridge and tagged interface.
249
250     if not netifaces_imported:
251         raise HwsimSkip("python module netifaces not available")
252
253     try:
254         ap_vlan_iface_cleanup_multibss_cleanup()
255         ap_vlan_iface_test_and_prepare_environ()
256
257         as_params = { "ssid": "as",
258                       "beacon_int": "2000",
259                       "radius_server_clients": "auth_serv/radius_clients.conf",
260                       "radius_server_auth_port": '18128',
261                       "eap_server": "1",
262                       "eap_user_file": "auth_serv/eap_user.conf",
263                       "ca_cert": "auth_serv/ca.pem",
264                       "server_cert": "auth_serv/server.pem",
265                       "private_key": "auth_serv/server.key",
266                       "vlan_naming": "1" }
267         authserv = hostapd.add_ap(apdev[1]['ifname'], as_params)
268
269         ifname = apdev[0]['ifname']
270
271         # start the actual test
272         hostapd.add_iface(ifname, 'multi-bss-iface.conf')
273         hapd = hostapd.Hostapd(ifname)
274         hapd1 = hostapd.Hostapd("wlan3-2", 1)
275         hapd1.enable()
276
277         ifaces = netifaces.interfaces()
278         if "brvlan1" in ifaces:
279             raise Exception("bridge brvlan1 already exists before")
280         if "brvlan2" in ifaces:
281             raise Exception("bridge brvlan2 already exists before")
282
283         dev[0].connect("bss-1", key_mgmt="WPA-EAP", eap="PAX",
284                        identity="vlan1",
285                        password_hex="0123456789abcdef0123456789abcdef",
286                        scan_freq="2412")
287
288         ifaces = netifaces.interfaces()
289         if not("brvlan1" in ifaces):
290             raise Exception("bridge brvlan1 was not created")
291
292         hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
293         if not iface_is_in_bridge("brvlan1", "dummy0.1"):
294             raise Exception("dummy0.1 not in brvlan1")
295
296         dev[1].connect("bss-2", key_mgmt="WPA-EAP", eap="PAX",
297                        identity="vlan1",
298                        password_hex="0123456789abcdef0123456789abcdef",
299                        scan_freq="2412")
300
301         hwsim_utils.test_connectivity_iface(dev[1], hapd1, "brvlan1")
302         if not iface_is_in_bridge("brvlan1", "dummy0.1"):
303             raise Exception("dummy0.1 not in brvlan1")
304
305         authserv.disable()
306         authserv.set('eap_user_file', "auth_serv/eap_user_vlan.conf")
307         authserv.enable()
308
309         logger.info("wlan0 -> VLAN 2")
310
311         dev[0].dump_monitor()
312         dev[0].request("REAUTHENTICATE")
313         ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
314         if ev is None:
315             raise Exception("EAP reauthentication timed out")
316         ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=5)
317         if ev is None:
318             raise Exception("4-way handshake after reauthentication timed out")
319         state = dev[0].get_status_field('wpa_state')
320         if state != "COMPLETED":
321             raise Exception("Unexpected state after reauth: " + state)
322
323         ifaces = netifaces.interfaces()
324         if not ("brvlan1" in ifaces):
325             raise Exception("bridge brvlan1 has been removed too early")
326
327         hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan2",
328                                             max_tries=5)
329
330         if not iface_is_in_bridge("brvlan2", "dummy0.2"):
331             raise Exception("dummy0.2 not in brvlan2")
332
333         logger.info("test wlan1 == VLAN 1")
334         hwsim_utils.test_connectivity_iface(dev[1], hapd1, "brvlan1")
335         if not iface_is_in_bridge("brvlan1", "dummy0.1"):
336             raise Exception("dummy0.1 not in brvlan1")
337
338         logger.info("wlan1 -> VLAN 2")
339
340         dev[1].dump_monitor()
341         dev[1].request("REAUTHENTICATE")
342         ev = dev[1].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=15)
343         if ev is None:
344             raise Exception("EAP reauthentication timed out")
345         ev = dev[1].wait_event(["WPA: Key negotiation completed"], timeout=5)
346         if ev is None:
347             raise Exception("4-way handshake after reauthentication timed out")
348         state = dev[1].get_status_field('wpa_state')
349         if state != "COMPLETED":
350             raise Exception("Unexpected state after reauth: " + state)
351
352         # it can take some time for data connectivity to be updated
353         hwsim_utils.test_connectivity_iface(dev[1], hapd1, "brvlan2",
354                                             max_tries=5)
355         logger.info("test wlan0 == VLAN 2")
356         hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan2")
357
358         if not iface_is_in_bridge("brvlan2", "dummy0.2"):
359             raise Exception("dummy0.2 not in brvlan2")
360
361         ifaces = netifaces.interfaces()
362         if "brvlan1" in ifaces:
363             raise Exception("bridge brvlan1 has not been cleaned up")
364
365         # disconnect dev0 first to test a corner case
366         dev[0].request("DISCONNECT")
367         dev[0].wait_disconnected()
368         dev[1].request("DISCONNECT")
369         dev[1].wait_disconnected()
370
371         # station removal needs some time
372         for i in range(5):
373             time.sleep(1)
374             ifaces = netifaces.interfaces()
375             if "brvlan2" not in ifaces:
376                 break
377
378         ifaces = netifaces.interfaces()
379         if "brvlan2" in ifaces:
380             raise Exception("bridge brvlan2 has not been cleaned up")
381
382         hapd.request("DISABLE")
383     finally:
384         ap_vlan_iface_cleanup_multibss_cleanup()