Updated to hostap_2_6
[mech_eap.git] / libeap / tests / hwsim / test_wpas_config.py
1 # wpa_supplicant config file
2 # Copyright (c) 2014, 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 logging
8 logger = logging.getLogger()
9 import os
10
11 from wpasupplicant import WpaSupplicant
12 import hostapd
13
14 def check_config(config):
15     with open(config, "r") as f:
16         data = f.read()
17     if "update_config=1\n" not in data:
18         raise Exception("Missing update_config")
19     if "device_name=name\n" not in data:
20         raise Exception("Missing device_name")
21     if "eapol_version=2\n" not in data:
22         raise Exception("Missing eapol_version")
23     if "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=" not in data:
24         raise Exception("Missing ctrl_interface")
25     if "blob-base64-foo={" not in data:
26         raise Exception("Missing blob")
27     if "cred={" not in data:
28         raise Exception("Missing cred")
29     if "network={" not in data:
30         raise Exception("Missing network")
31     if "wps_priority=5\n" not in data:
32         raise Exception("Missing wps_priority")
33     if "ip_addr_go=192.168.1.1\n" not in data:
34         raise Exception("Missing ip_addr_go")
35     if "ip_addr_mask=255.255.255.0\n" not in data:
36         raise Exception("Missing ip_addr_mask")
37     if "ip_addr_start=192.168.1.10\n" not in data:
38         raise Exception("Missing ip_addr_start")
39     if "ip_addr_end=192.168.1.20\n" not in data:
40         raise Exception("Missing ip_addr_end")
41     return data
42
43 def test_wpas_config_file(dev):
44     """wpa_supplicant config file parsing/writing"""
45     config = "/tmp/test_wpas_config_file.conf"
46     if os.path.exists(config):
47         os.remove(config)
48
49     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
50     try:
51         wpas.interface_add("wlan5", config=config)
52         initialized = True
53     except:
54         initialized = False
55     if initialized:
56         raise Exception("Missing config file did not result in an error")
57
58     try:
59         with open(config, "w") as f:
60             f.write("update_config=1 \t\r\n")
61             f.write("# foo\n")
62             f.write("\n")
63             f.write(" \t\reapol_version=2")
64             for i in range(0, 100):
65                 f.write("                    ")
66             f.write("foo\n")
67             f.write("device_name=name#foo\n")
68
69         wpas.interface_add("wlan5", config=config)
70
71         wpas.request("SET wps_priority 5")
72
73         id = wpas.add_network()
74         wpas.set_network_quoted(id, "ssid", "foo")
75         wpas.set_network_quoted(id, "psk", "12345678")
76         wpas.set_network(id, "bssid", "00:11:22:33:44:55")
77         wpas.set_network(id, "proto", "RSN")
78         wpas.set_network(id, "key_mgmt", "WPA-PSK-SHA256")
79         wpas.set_network(id, "pairwise", "CCMP")
80         wpas.set_network(id, "group", "CCMP")
81         wpas.set_network(id, "auth_alg", "OPEN")
82
83         id = wpas.add_cred()
84         wpas.set_cred(id, "priority", "3")
85         wpas.set_cred(id, "sp_priority", "6")
86         wpas.set_cred(id, "update_identifier", "4")
87         wpas.set_cred(id, "ocsp", "1")
88         wpas.set_cred(id, "eap", "TTLS")
89         wpas.set_cred(id, "req_conn_capab", "6:1234")
90         wpas.set_cred_quoted(id, "realm", "example.com")
91         wpas.set_cred_quoted(id, "provisioning_sp", "example.com")
92         wpas.set_cred_quoted(id, "domain", "example.com")
93         wpas.set_cred_quoted(id, "domain_suffix_match", "example.com")
94         wpas.set_cred(id, "roaming_consortium", "112233")
95         wpas.set_cred(id, "required_roaming_consortium", "112233")
96         wpas.set_cred_quoted(id, "roaming_partner",
97                              "roaming.example.net,1,127,*")
98         wpas.set_cred_quoted(id, "ca_cert", "/tmp/ca.pem")
99         wpas.set_cred_quoted(id, "username", "user")
100         wpas.set_cred_quoted(id, "password", "secret")
101         ev = wpas.wait_event(["CRED-MODIFIED 0 password"])
102
103         wpas.request("SET blob foo 12345678")
104         wpas.request("SET ip_addr_go 192.168.1.1")
105         wpas.request("SET ip_addr_mask 255.255.255.0")
106         wpas.request("SET ip_addr_start 192.168.1.10")
107         wpas.request("SET ip_addr_end 192.168.1.20")
108
109         if "OK" not in wpas.request("SAVE_CONFIG"):
110             raise Exception("Failed to save configuration file")
111         if "OK" not in wpas.global_request("SAVE_CONFIG"):
112             raise Exception("Failed to save configuration file")
113
114         wpas.interface_remove("wlan5")
115         data1 = check_config(config)
116
117         wpas.interface_add("wlan5", config=config)
118         if len(wpas.list_networks()) != 1:
119             raise Exception("Unexpected number of networks")
120         if len(wpas.request("LIST_CREDS").splitlines()) != 2:
121             raise Exception("Unexpected number of credentials")
122
123         if "OK" not in wpas.request("SAVE_CONFIG"):
124             raise Exception("Failed to save configuration file")
125         data2 = check_config(config)
126
127         if data1 != data2:
128             logger.debug(data1)
129             logger.debug(data2)
130             raise Exception("Unexpected configuration change")
131
132         wpas.request("SET update_config 0")
133         wpas.global_request("SET update_config 0")
134         if "OK" in wpas.request("SAVE_CONFIG"):
135             raise Exception("SAVE_CONFIG succeeded unexpectedly")
136         if "OK" in wpas.global_request("SAVE_CONFIG"):
137             raise Exception("SAVE_CONFIG (global) succeeded unexpectedly")
138
139         # replace the config file with a directory to break writing/renaming
140         os.remove(config)
141         os.mkdir(config)
142         wpas.request("SET update_config 1")
143         wpas.global_request("SET update_config 1")
144         if "OK" in wpas.request("SAVE_CONFIG"):
145             raise Exception("SAVE_CONFIG succeeded unexpectedly")
146         if "OK" in wpas.global_request("SAVE_CONFIG"):
147             raise Exception("SAVE_CONFIG (global) succeeded unexpectedly")
148
149     finally:
150         try:
151             os.remove(config)
152         except:
153             pass
154         try:
155             os.remove(config + ".tmp")
156         except:
157             pass
158         try:
159             os.rmdir(config)
160         except:
161             pass
162
163 def test_wpas_config_file_wps(dev, apdev):
164     """wpa_supplicant config file parsing/writing with WPS"""
165     config = "/tmp/test_wpas_config_file.conf"
166     if os.path.exists(config):
167         os.remove(config)
168
169     params = { "ssid": "test-wps", "eap_server": "1", "wps_state": "2",
170                "skip_cred_build": "1", "extra_cred": "wps-ctrl-cred" }
171     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
172
173     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
174
175     try:
176         with open(config, "w") as f:
177             f.write("update_config=1\n")
178
179         wpas.interface_add("wlan5", config=config)
180
181         hapd.request("WPS_PIN any 12345670")
182         wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
183         wpas.request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
184         ev = wpas.wait_event(["WPS-FAIL"], timeout=10)
185         if ev is None:
186             raise Exception("WPS-FAIL event timed out")
187
188         with open(config, "r") as f:
189             data = f.read()
190             logger.info("Configuration file contents: " + data)
191             if "network=" in data:
192                 raise Exception("Unexpected network block in configuration data")
193
194     finally:
195         try:
196             os.remove(config)
197         except:
198             pass
199         try:
200             os.remove(config + ".tmp")
201         except:
202             pass
203         try:
204             os.rmdir(config)
205         except:
206             pass
207
208 def test_wpas_config_file_wps2(dev, apdev):
209     """wpa_supplicant config file parsing/writing with WPS (2)"""
210     config = "/tmp/test_wpas_config_file.conf"
211     if os.path.exists(config):
212         os.remove(config)
213
214     params = { "ssid": "test-wps", "eap_server": "1", "wps_state": "2",
215                "skip_cred_build": "1", "extra_cred": "wps-ctrl-cred2" }
216     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
217
218     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
219
220     try:
221         with open(config, "w") as f:
222             f.write("update_config=1\n")
223
224         wpas.interface_add("wlan5", config=config)
225
226         hapd.request("WPS_PIN any 12345670")
227         wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
228         wpas.request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
229         ev = wpas.wait_event(["WPS-SUCCESS"], timeout=10)
230         if ev is None:
231             raise Exception("WPS-SUCCESS event timed out")
232
233         with open(config, "r") as f:
234             data = f.read()
235             logger.info("Configuration file contents: " + data)
236
237             with open(config, "r") as f:
238                 data = f.read()
239                 if "network=" not in data:
240                     raise Exception("Missing network block in configuration data")
241                 if "ssid=410a420d430044" not in data:
242                     raise Exception("Unexpected ssid parameter value")
243
244     finally:
245         try:
246             os.remove(config)
247         except:
248             pass
249         try:
250             os.remove(config + ".tmp")
251         except:
252             pass
253         try:
254             os.rmdir(config)
255         except:
256             pass
257
258 def test_wpas_config_file_set_psk(dev):
259     """wpa_supplicant config file parsing/writing with arbitrary PSK value"""
260     config = "/tmp/test_wpas_config_file.conf"
261     if os.path.exists(config):
262         os.remove(config)
263
264     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
265
266     try:
267         with open(config, "w") as f:
268             f.write("update_config=1\n")
269
270         wpas.interface_add("wlan5", config=config)
271
272         id = wpas.add_network()
273         wpas.set_network_quoted(id, "ssid", "foo")
274         if "OK" in wpas.request('SET_NETWORK %d psk "12345678"\n}\nmodel_name=foobar\nnetwork={\n#\"' % id):
275             raise Exception("Invalid psk value accepted")
276
277         if "OK" not in wpas.request("SAVE_CONFIG"):
278             raise Exception("Failed to save configuration file")
279
280         with open(config, "r") as f:
281             data = f.read()
282             logger.info("Configuration file contents: " + data)
283             if "model_name" in data:
284                 raise Exception("Unexpected parameter added to configuration")
285
286         wpas.interface_remove("wlan5")
287         wpas.interface_add("wlan5", config=config)
288
289     finally:
290         try:
291             os.remove(config)
292         except:
293             pass
294         try:
295             os.remove(config + ".tmp")
296         except:
297             pass
298         try:
299             os.rmdir(config)
300         except:
301             pass
302
303 def test_wpas_config_file_set_cred(dev):
304     """wpa_supplicant config file parsing/writing with arbitrary cred values"""
305     config = "/tmp/test_wpas_config_file.conf"
306     if os.path.exists(config):
307         os.remove(config)
308
309     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
310
311     try:
312         with open(config, "w") as f:
313             f.write("update_config=1\n")
314
315         wpas.interface_add("wlan5", config=config)
316
317         id = wpas.add_cred()
318         wpas.set_cred_quoted(id, "username", "hello")
319         fields = [ "username", "milenage", "imsi", "password", "realm",
320                    "phase1", "phase2", "provisioning_sp" ]
321         for field in fields:
322             if "FAIL" not in wpas.request('SET_CRED %d %s "hello"\n}\nmodel_name=foobar\ncred={\n#\"' % (id, field)):
323                 raise Exception("Invalid %s value accepted" % field)
324
325         if "OK" not in wpas.request("SAVE_CONFIG"):
326             raise Exception("Failed to save configuration file")
327
328         with open(config, "r") as f:
329             data = f.read()
330             logger.info("Configuration file contents: " + data)
331             if "model_name" in data:
332                 raise Exception("Unexpected parameter added to configuration")
333
334         wpas.interface_remove("wlan5")
335         wpas.interface_add("wlan5", config=config)
336
337     finally:
338         try:
339             os.remove(config)
340         except:
341             pass
342         try:
343             os.remove(config + ".tmp")
344         except:
345             pass
346         try:
347             os.rmdir(config)
348         except:
349             pass
350
351 def test_wpas_config_file_set_global(dev):
352     """wpa_supplicant config file parsing/writing with arbitrary global values"""
353     config = "/tmp/test_wpas_config_file.conf"
354     if os.path.exists(config):
355         os.remove(config)
356
357     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
358
359     try:
360         with open(config, "w") as f:
361             f.write("update_config=1\n")
362
363         wpas.interface_add("wlan5", config=config)
364
365         fields = [ "model_name", "device_name", "ctrl_interface_group",
366                    "opensc_engine_path", "pkcs11_engine_path",
367                    "pkcs11_module_path", "openssl_ciphers", "pcsc_reader",
368                    "pcsc_pin", "driver_param", "manufacturer", "model_name",
369                    "model_number", "serial_number", "config_methods",
370                    "p2p_ssid_postfix", "autoscan", "ext_password_backend",
371                    "osu_dir", "wowlan_triggers", "fst_group_id",
372                    "sched_scan_plans", "non_pref_chan" ]
373         for field in fields:
374             if "FAIL" not in wpas.request('SET %s hello\nmodel_name=foobar' % field):
375                 raise Exception("Invalid %s value accepted" % field)
376
377         if "OK" not in wpas.request("SAVE_CONFIG"):
378             raise Exception("Failed to save configuration file")
379
380         with open(config, "r") as f:
381             data = f.read()
382             logger.info("Configuration file contents: " + data)
383             if "model_name" in data:
384                 raise Exception("Unexpected parameter added to configuration")
385
386         wpas.interface_remove("wlan5")
387         wpas.interface_add("wlan5", config=config)
388
389     finally:
390         try:
391             os.remove(config)
392         except:
393             pass
394         try:
395             os.remove(config + ".tmp")
396         except:
397             pass
398         try:
399             os.rmdir(config)
400         except:
401             pass