]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_ap_hs20.py
nl80211: Fix br_ifindex storing when hostapd creates the bridge
[thirdparty/hostap.git] / tests / hwsim / test_ap_hs20.py
CommitLineData
93a06242 1# Hotspot 2.0 tests
2f37a66d 2# Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
93a06242
JM
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7import time
8import subprocess
9import logging
c9aa4308 10logger = logging.getLogger()
97de642a 11import os
efd43d85
JM
12import os.path
13import subprocess
93a06242
JM
14
15import hostapd
715bf904 16from wlantest import Wlantest
9d1e1172 17from wpasupplicant import WpaSupplicant
93a06242 18
d4058934
JM
19def hs20_ap_params(ssid="test-hs20"):
20 params = hostapd.wpa2_params(ssid=ssid)
93a06242
JM
21 params['wpa_key_mgmt'] = "WPA-EAP"
22 params['ieee80211w'] = "1"
23 params['ieee8021x'] = "1"
24 params['auth_server_addr'] = "127.0.0.1"
25 params['auth_server_port'] = "1812"
26 params['auth_server_shared_secret'] = "radius"
27 params['interworking'] = "1"
28 params['access_network_type'] = "14"
29 params['internet'] = "1"
30 params['asra'] = "0"
31 params['esr'] = "0"
32 params['uesa'] = "0"
33 params['venue_group'] = "7"
34 params['venue_type'] = "1"
35 params['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
36 params['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
37 "fedcba" ]
38 params['domain_name'] = "example.com,another.example.com"
39 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
40 "0,another.example.com" ]
41 params['hs20'] = "1"
42 params['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
43 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
44 params['hs20_operating_class'] = "5173"
45 params['anqp_3gpp_cell_net'] = "244,91"
46 return params
47
9714fbcd 48def check_auto_select(dev, bssid):
841bed04 49 dev.scan_for_bss(bssid, freq="2412")
9714fbcd
JM
50 dev.request("INTERWORKING_SELECT auto freq=2412")
51 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
52 if ev is None:
53 raise Exception("Connection timed out")
54 if bssid not in ev:
55 raise Exception("Connected to incorrect network")
56 dev.request("REMOVE_NETWORK all")
57
2f37a66d 58def interworking_select(dev, bssid, type=None, no_match=False, freq=None):
bbe86767 59 dev.dump_monitor()
841bed04
JM
60 if bssid and freq and not no_match:
61 dev.scan_for_bss(bssid, freq=freq)
2f37a66d
JM
62 freq_extra = " freq=" + freq if freq else ""
63 dev.request("INTERWORKING_SELECT" + freq_extra)
bbe86767
JM
64 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
65 timeout=15)
93a06242
JM
66 if ev is None:
67 raise Exception("Network selection timed out");
bbe86767
JM
68 if no_match:
69 if "INTERWORKING-NO-MATCH" not in ev:
70 raise Exception("Unexpected network match")
71 return
93a06242 72 if "INTERWORKING-NO-MATCH" in ev:
0dee3a0a
JM
73 logger.info("Matching network not found - try again")
74 dev.dump_monitor()
75 dev.request("INTERWORKING_SELECT" + freq_extra)
76 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
77 timeout=15)
78 if ev is None:
79 raise Exception("Network selection timed out");
80 if "INTERWORKING-NO-MATCH" in ev:
81 raise Exception("Matching network not found")
2cdd91d8 82 if bssid and bssid not in ev:
93a06242 83 raise Exception("Unexpected BSSID in match")
bbe86767
JM
84 if type and "type=" + type not in ev:
85 raise Exception("Network type not recognized correctly")
93a06242 86
bbe86767
JM
87def check_sp_type(dev, sp_type):
88 type = dev.get_status_field("sp_type")
89 if type is None:
90 raise Exception("sp_type not available")
91 if type != sp_type:
92 raise Exception("sp_type did not indicate home network")
efd43d85 93
bbe86767 94def hlr_auc_gw_available():
efd43d85
JM
95 if not os.path.exists("/tmp/hlr_auc_gw.sock"):
96 logger.info("No hlr_auc_gw available");
bbe86767 97 return False
efd43d85
JM
98 if not os.path.exists("../../hostapd/hlr_auc_gw"):
99 logger.info("No hlr_auc_gw available");
bbe86767
JM
100 return False
101 return True
efd43d85 102
bbe86767
JM
103def interworking_ext_sim_connect(dev, bssid, method):
104 dev.request("INTERWORKING_CONNECT " + bssid)
078683ac 105 interworking_ext_sim_auth(dev, method)
efd43d85 106
078683ac 107def interworking_ext_sim_auth(dev, method):
bbe86767 108 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
efd43d85
JM
109 if ev is None:
110 raise Exception("Network connected timed out")
bbe86767 111 if "(" + method + ")" not in ev:
efd43d85
JM
112 raise Exception("Unexpected EAP method selection")
113
bbe86767 114 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
efd43d85
JM
115 if ev is None:
116 raise Exception("Wait for external SIM processing request timed out")
117 p = ev.split(':', 2)
118 if p[1] != "GSM-AUTH":
119 raise Exception("Unexpected CTRL-REQ-SIM type")
120 id = p[0].split('-')[3]
121 rand = p[2].split(' ')[0]
122
123 res = subprocess.check_output(["../../hostapd/hlr_auc_gw",
124 "-m",
125 "auth_serv/hlr_auc_gw.milenage_db",
126 "GSM-AUTH-REQ 232010000000000 " + rand])
127 if "GSM-AUTH-RESP" not in res:
128 raise Exception("Unexpected hlr_auc_gw response")
129 resp = res.split(' ')[2].rstrip()
130
bbe86767
JM
131 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
132 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
efd43d85
JM
133 if ev is None:
134 raise Exception("Connection timed out")
f4defd91 135
8fba2e5d
JM
136def interworking_connect(dev, bssid, method):
137 dev.request("INTERWORKING_CONNECT " + bssid)
078683ac 138 interworking_auth(dev, method)
8fba2e5d 139
078683ac 140def interworking_auth(dev, method):
8fba2e5d
JM
141 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
142 if ev is None:
143 raise Exception("Network connected timed out")
144 if "(" + method + ")" not in ev:
145 raise Exception("Unexpected EAP method selection")
146
147 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
148 if ev is None:
149 raise Exception("Connection timed out")
150
715bf904
JM
151def check_probe_resp(wt, bssid_unexpected, bssid_expected):
152 if bssid_unexpected:
153 count = wt.get_bss_counter("probe_response", bssid_unexpected)
154 if count > 0:
155 raise Exception("Unexpected Probe Response frame from AP")
156
157 if bssid_expected:
158 count = wt.get_bss_counter("probe_response", bssid_expected)
159 if count == 0:
160 raise Exception("No Probe Response frame from AP")
161
2cdd91d8
JM
162def test_ap_anqp_sharing(dev, apdev):
163 """ANQP sharing within ESS and explicit unshare"""
164 bssid = apdev[0]['bssid']
165 params = hs20_ap_params()
166 params['hessid'] = bssid
167 hostapd.add_ap(apdev[0]['ifname'], params)
168
169 bssid2 = apdev[1]['bssid']
170 params = hs20_ap_params()
171 params['hessid'] = bssid
172 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
173 hostapd.add_ap(apdev[1]['ifname'], params)
174
2cdd91d8
JM
175 dev[0].hs20_enable()
176 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
177 'password': "secret",
178 'domain': "example.com" })
179 logger.info("Normal network selection with shared ANQP results")
841bed04
JM
180 dev[0].scan_for_bss(bssid, freq="2412")
181 dev[0].scan_for_bss(bssid2, freq="2412")
2f37a66d 182 interworking_select(dev[0], None, "home", freq="2412")
2cdd91d8
JM
183 dev[0].dump_monitor()
184
185 res1 = dev[0].get_bss(bssid)
186 res2 = dev[0].get_bss(bssid2)
187 if res1['anqp_nai_realm'] != res2['anqp_nai_realm']:
188 raise Exception("ANQP results were not shared between BSSes")
189
190 logger.info("Explicit ANQP request to unshare ANQP results")
191 dev[0].request("ANQP_GET " + bssid + " 263")
192 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
193 if ev is None:
194 raise Exception("ANQP operation timed out")
195
196 dev[0].request("ANQP_GET " + bssid2 + " 263")
197 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
198 if ev is None:
199 raise Exception("ANQP operation timed out")
200
201 res1 = dev[0].get_bss(bssid)
202 res2 = dev[0].get_bss(bssid2)
203 if res1['anqp_nai_realm'] == res2['anqp_nai_realm']:
204 raise Exception("ANQP results were not unshared")
205
cddc19e5
JM
206def test_ap_nai_home_realm_query(dev, apdev):
207 """NAI Home Realm Query"""
208 bssid = apdev[0]['bssid']
209 params = hs20_ap_params()
210 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
211 "0,another.example.org" ]
212 hostapd.add_ap(apdev[0]['ifname'], params)
213
214 dev[0].scan(freq="2412")
215 dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " realm=example.com")
216 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
217 if ev is None:
218 raise Exception("ANQP operation timed out")
219 nai1 = dev[0].get_bss(bssid)['anqp_nai_realm']
220 dev[0].dump_monitor()
221
222 dev[0].request("ANQP_GET " + bssid + " 263")
223 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
224 if ev is None:
225 raise Exception("ANQP operation timed out")
226 nai2 = dev[0].get_bss(bssid)['anqp_nai_realm']
227
228 if len(nai1) >= len(nai2):
229 raise Exception("Unexpected NAI Realm list response lengths")
230 if "example.com".encode('hex') not in nai1:
231 raise Exception("Home realm not reported")
232 if "example.org".encode('hex') in nai1:
233 raise Exception("Non-home realm reported")
234 if "example.com".encode('hex') not in nai2:
235 raise Exception("Home realm not reported in wildcard query")
236 if "example.org".encode('hex') not in nai2:
237 raise Exception("Non-home realm not reported in wildcard query ")
238
715bf904
JM
239def test_ap_interworking_scan_filtering(dev, apdev):
240 """Interworking scan filtering with HESSID and access network type"""
241 bssid = apdev[0]['bssid']
242 params = hs20_ap_params()
243 ssid = "test-hs20-ap1"
244 params['ssid'] = ssid
245 params['hessid'] = bssid
246 hostapd.add_ap(apdev[0]['ifname'], params)
247
248 bssid2 = apdev[1]['bssid']
249 params = hs20_ap_params()
250 ssid2 = "test-hs20-ap2"
251 params['ssid'] = ssid2
252 params['hessid'] = bssid2
253 params['access_network_type'] = "1"
8175854e
JM
254 del params['venue_group']
255 del params['venue_type']
715bf904
JM
256 hostapd.add_ap(apdev[1]['ifname'], params)
257
715bf904
JM
258 dev[0].hs20_enable()
259
260 wt = Wlantest()
261 wt.flush()
262
263 logger.info("Check probe request filtering based on HESSID")
264
265 dev[0].request("SET hessid " + bssid2)
0589f401 266 dev[0].scan(freq="2412")
94a2dd0b 267 time.sleep(0.03)
715bf904
JM
268 check_probe_resp(wt, bssid, bssid2)
269
270 logger.info("Check probe request filtering based on access network type")
271
272 wt.clear_bss_counters(bssid)
273 wt.clear_bss_counters(bssid2)
274 dev[0].request("SET hessid 00:00:00:00:00:00")
275 dev[0].request("SET access_network_type 14")
0589f401 276 dev[0].scan(freq="2412")
94a2dd0b 277 time.sleep(0.03)
715bf904
JM
278 check_probe_resp(wt, bssid2, bssid)
279
280 wt.clear_bss_counters(bssid)
281 wt.clear_bss_counters(bssid2)
282 dev[0].request("SET hessid 00:00:00:00:00:00")
283 dev[0].request("SET access_network_type 1")
0589f401 284 dev[0].scan(freq="2412")
94a2dd0b 285 time.sleep(0.03)
715bf904
JM
286 check_probe_resp(wt, bssid, bssid2)
287
288 logger.info("Check probe request filtering based on HESSID and ANT")
289
290 wt.clear_bss_counters(bssid)
291 wt.clear_bss_counters(bssid2)
292 dev[0].request("SET hessid " + bssid)
293 dev[0].request("SET access_network_type 14")
0589f401 294 dev[0].scan(freq="2412")
94a2dd0b 295 time.sleep(0.03)
715bf904
JM
296 check_probe_resp(wt, bssid2, bssid)
297
298 wt.clear_bss_counters(bssid)
299 wt.clear_bss_counters(bssid2)
300 dev[0].request("SET hessid " + bssid2)
301 dev[0].request("SET access_network_type 14")
0589f401 302 dev[0].scan(freq="2412")
94a2dd0b 303 time.sleep(0.03)
715bf904
JM
304 check_probe_resp(wt, bssid, None)
305 check_probe_resp(wt, bssid2, None)
306
307 wt.clear_bss_counters(bssid)
308 wt.clear_bss_counters(bssid2)
309 dev[0].request("SET hessid " + bssid)
310 dev[0].request("SET access_network_type 1")
0589f401 311 dev[0].scan(freq="2412")
94a2dd0b 312 time.sleep(0.03)
715bf904
JM
313 check_probe_resp(wt, bssid, None)
314 check_probe_resp(wt, bssid2, None)
315
bbe86767
JM
316def test_ap_hs20_select(dev, apdev):
317 """Hotspot 2.0 network selection"""
318 bssid = apdev[0]['bssid']
319 params = hs20_ap_params()
320 params['hessid'] = bssid
321 hostapd.add_ap(apdev[0]['ifname'], params)
322
323 dev[0].hs20_enable()
2232edf8
JM
324 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
325 'password': "secret",
326 'domain': "example.com" })
bbe86767
JM
327 interworking_select(dev[0], bssid, "home")
328
329 dev[0].remove_cred(id)
2232edf8
JM
330 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
331 'password': "secret",
332 'domain': "no.match.example.com" })
2f37a66d 333 interworking_select(dev[0], bssid, "roaming", freq="2412")
bbe86767
JM
334
335 dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
2f37a66d 336 interworking_select(dev[0], bssid, no_match=True, freq="2412")
bbe86767 337
4b572e3a
JM
338 bssid2 = apdev[1]['bssid']
339 params = hs20_ap_params()
340 params['nai_realm'] = [ "0,example.org,21" ]
341 params['hessid'] = bssid2
342 params['domain_name'] = "example.org"
343 hostapd.add_ap(apdev[1]['ifname'], params)
344 dev[0].remove_cred(id)
345 id = dev[0].add_cred_values({ 'realm': "example.org", 'username': "test",
346 'password': "secret",
347 'domain': "example.org" })
348 interworking_select(dev[0], bssid2, "home", freq="2412")
349
459e96cd
JM
350def hs20_simulated_sim(dev, ap, method):
351 bssid = ap['bssid']
352 params = hs20_ap_params()
353 params['hessid'] = bssid
354 params['anqp_3gpp_cell_net'] = "555,444"
355 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
356 hostapd.add_ap(ap['ifname'], params)
357
459e96cd
JM
358 dev.hs20_enable()
359 dev.add_cred_values({ 'imsi': "555444-333222111", 'eap': method,
360 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
2f37a66d 361 interworking_select(dev, "home", freq="2412")
459e96cd
JM
362 interworking_connect(dev, bssid, method)
363 check_sp_type(dev, "home")
364
365def test_ap_hs20_sim(dev, apdev):
366 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
367 if not hlr_auc_gw_available():
368 return "skip"
369 hs20_simulated_sim(dev[0], apdev[0], "SIM")
16ab63f4
JM
370 dev[0].request("INTERWORKING_SELECT auto freq=2412")
371 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
372 if ev is None:
373 raise Exception("Timeout on already-connected event")
459e96cd
JM
374
375def test_ap_hs20_aka(dev, apdev):
376 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
377 if not hlr_auc_gw_available():
378 return "skip"
379 hs20_simulated_sim(dev[0], apdev[0], "AKA")
380
381def test_ap_hs20_aka_prime(dev, apdev):
382 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
383 if not hlr_auc_gw_available():
384 return "skip"
385 hs20_simulated_sim(dev[0], apdev[0], "AKA'")
386
bbe86767
JM
387def test_ap_hs20_ext_sim(dev, apdev):
388 """Hotspot 2.0 with external SIM processing"""
389 if not hlr_auc_gw_available():
390 return "skip"
391 bssid = apdev[0]['bssid']
392 params = hs20_ap_params()
393 params['hessid'] = bssid
394 params['anqp_3gpp_cell_net'] = "232,01"
395 params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
396 hostapd.add_ap(apdev[0]['ifname'], params)
397
398 dev[0].hs20_enable()
399 dev[0].request("SET external_sim 1")
2232edf8 400 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
2f37a66d 401 interworking_select(dev[0], "home", freq="2412")
bbe86767
JM
402 interworking_ext_sim_connect(dev[0], bssid, "SIM")
403 check_sp_type(dev[0], "home")
59f8a3c6
JM
404
405def test_ap_hs20_ext_sim_roaming(dev, apdev):
406 """Hotspot 2.0 with external SIM processing in roaming network"""
407 if not hlr_auc_gw_available():
408 return "skip"
409 bssid = apdev[0]['bssid']
410 params = hs20_ap_params()
411 params['hessid'] = bssid
412 params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
413 params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
414 hostapd.add_ap(apdev[0]['ifname'], params)
415
416 dev[0].hs20_enable()
417 dev[0].request("SET external_sim 1")
2232edf8 418 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
2f37a66d 419 interworking_select(dev[0], "roaming", freq="2412")
59f8a3c6
JM
420 interworking_ext_sim_connect(dev[0], bssid, "SIM")
421 check_sp_type(dev[0], "roaming")
8fba2e5d
JM
422
423def test_ap_hs20_username(dev, apdev):
424 """Hotspot 2.0 connection in username/password credential"""
8fba2e5d
JM
425 bssid = apdev[0]['bssid']
426 params = hs20_ap_params()
427 params['hessid'] = bssid
d627e131 428 params['disable_dgaf'] = '1'
8fba2e5d
JM
429 hostapd.add_ap(apdev[0]['ifname'], params)
430
431 dev[0].hs20_enable()
2232edf8
JM
432 id = dev[0].add_cred_values({ 'realm': "example.com",
433 'username': "hs20-test",
434 'password': "password",
a1281b9f 435 'ca_cert': "auth_serv/ca.pem",
5f1e31cf
JM
436 'domain': "example.com",
437 'update_identifier': "1234" })
2f37a66d 438 interworking_select(dev[0], bssid, "home", freq="2412")
8fba2e5d
JM
439 interworking_connect(dev[0], bssid, "TTLS")
440 check_sp_type(dev[0], "home")
10b3cc67
JM
441 status = dev[0].get_status()
442 if status['pairwise_cipher'] != "CCMP":
443 raise Exception("Unexpected pairwise cipher")
444 if status['hs20'] != "2":
445 raise Exception("Unexpected HS 2.0 support indication")
8fba2e5d 446
a1281b9f
JM
447 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS",
448 identity="hs20-test", password="password",
449 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
450 scan_freq="2412")
451
1e780974
JM
452def test_ap_hs20_connect_api(dev, apdev):
453 """Hotspot 2.0 connection with connect API"""
454 bssid = apdev[0]['bssid']
455 params = hs20_ap_params()
456 params['hessid'] = bssid
457 params['disable_dgaf'] = '1'
458 hostapd.add_ap(apdev[0]['ifname'], params)
459
460 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
461 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
462 wpas.hs20_enable()
463 id = wpas.add_cred_values({ 'realm': "example.com",
464 'username': "hs20-test",
465 'password': "password",
466 'ca_cert': "auth_serv/ca.pem",
467 'domain': "example.com",
468 'update_identifier': "1234" })
469 interworking_select(wpas, bssid, "home", freq="2412")
470 interworking_connect(wpas, bssid, "TTLS")
471 check_sp_type(wpas, "home")
472 status = wpas.get_status()
473 if status['pairwise_cipher'] != "CCMP":
474 raise Exception("Unexpected pairwise cipher")
475 if status['hs20'] != "2":
476 raise Exception("Unexpected HS 2.0 support indication")
477
543f9f7e
JM
478def test_ap_hs20_auto_interworking(dev, apdev):
479 """Hotspot 2.0 connection with auto_interworking=1"""
480 bssid = apdev[0]['bssid']
481 params = hs20_ap_params()
482 params['hessid'] = bssid
483 params['disable_dgaf'] = '1'
484 hostapd.add_ap(apdev[0]['ifname'], params)
485
486 dev[0].hs20_enable(auto_interworking=True)
487 id = dev[0].add_cred_values({ 'realm': "example.com",
488 'username': "hs20-test",
489 'password': "password",
490 'ca_cert': "auth_serv/ca.pem",
491 'domain': "example.com",
492 'update_identifier': "1234" })
493 dev[0].request("REASSOCIATE")
494 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
495 if ev is None:
496 raise Exception("Connection timed out")
497 check_sp_type(dev[0], "home")
498 status = dev[0].get_status()
499 if status['pairwise_cipher'] != "CCMP":
500 raise Exception("Unexpected pairwise cipher")
501 if status['hs20'] != "2":
502 raise Exception("Unexpected HS 2.0 support indication")
503
bedb6ea5
JM
504def test_ap_hs20_auto_interworking_no_cred_match(dev, apdev):
505 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
506 bssid = apdev[0]['bssid']
507 params = { "ssid": "test" }
508 hostapd.add_ap(apdev[0]['ifname'], params)
509
510 dev[0].hs20_enable(auto_interworking=True)
511 dev[0].add_cred_values({ 'realm': "example.com",
512 'username': "hs20-test",
513 'password': "password",
514 'ca_cert': "auth_serv/ca.pem",
515 'domain': "example.com" })
516
517 id = dev[0].connect("test", psk="12345678", only_add_network=True)
518 dev[0].request("ENABLE_NETWORK %s" % id)
519 logger.info("Verify that scanning continues when there is partial network block match")
520 for i in range(0, 2):
521 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
522 if ev is None:
523 raise Exception("Scan timed out")
524 logger.info("Scan completed")
525
dcd68168
JM
526def eap_test(dev, ap, eap_params, method, user):
527 bssid = ap['bssid']
528 params = hs20_ap_params()
529 params['nai_realm'] = [ "0,example.com," + eap_params ]
530 hostapd.add_ap(ap['ifname'], params)
531
dcd68168
JM
532 dev.hs20_enable()
533 dev.add_cred_values({ 'realm': "example.com",
534 'username': user,
535 'password': "password" })
2f37a66d 536 interworking_select(dev, bssid, freq="2412")
dcd68168
JM
537 interworking_connect(dev, bssid, method)
538
932be82c
JM
539def test_ap_hs20_eap_unknown(dev, apdev):
540 """Hotspot 2.0 connection with unknown EAP method"""
541 bssid = apdev[0]['bssid']
542 params = hs20_ap_params()
543 params['nai_realm'] = "0,example.com,99"
544 hostapd.add_ap(apdev[0]['ifname'], params)
545
546 dev[0].hs20_enable()
547 dev[0].add_cred_values(default_cred())
548 interworking_select(dev[0], None, no_match=True, freq="2412")
549
dcd68168
JM
550def test_ap_hs20_eap_peap_mschapv2(dev, apdev):
551 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
552 eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user")
553
932be82c
JM
554def test_ap_hs20_eap_peap_default(dev, apdev):
555 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
556 eap_test(dev[0], apdev[0], "25", "PEAP", "user")
557
dcd68168
JM
558def test_ap_hs20_eap_peap_gtc(dev, apdev):
559 """Hotspot 2.0 connection with PEAP/GTC"""
560 eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user")
561
932be82c
JM
562def test_ap_hs20_eap_peap_unknown(dev, apdev):
563 """Hotspot 2.0 connection with PEAP/unknown"""
564 bssid = apdev[0]['bssid']
565 params = hs20_ap_params()
566 params['nai_realm'] = "0,example.com,25[3:99]"
567 hostapd.add_ap(apdev[0]['ifname'], params)
568
569 dev[0].hs20_enable()
570 dev[0].add_cred_values(default_cred())
571 interworking_select(dev[0], None, no_match=True, freq="2412")
572
dcd68168
JM
573def test_ap_hs20_eap_ttls_chap(dev, apdev):
574 """Hotspot 2.0 connection with TTLS/CHAP"""
575 eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user")
576
577def test_ap_hs20_eap_ttls_mschap(dev, apdev):
578 """Hotspot 2.0 connection with TTLS/MSCHAP"""
579 eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user")
580
581def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev):
582 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
932be82c
JM
583 eap_test(dev[0], apdev[0], "21[3:26][6:7][99:99]", "TTLS", "user")
584
585def test_ap_hs20_eap_ttls_eap_unknown(dev, apdev):
586 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
587 bssid = apdev[0]['bssid']
588 params = hs20_ap_params()
589 params['nai_realm'] = "0,example.com,21[3:99]"
590 hostapd.add_ap(apdev[0]['ifname'], params)
591
592 dev[0].hs20_enable()
593 dev[0].add_cred_values(default_cred())
594 interworking_select(dev[0], None, no_match=True, freq="2412")
595
596def test_ap_hs20_eap_ttls_eap_unsupported(dev, apdev):
597 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
598 bssid = apdev[0]['bssid']
599 params = hs20_ap_params()
600 params['nai_realm'] = "0,example.com,21[3:5]"
601 hostapd.add_ap(apdev[0]['ifname'], params)
602
603 dev[0].hs20_enable()
604 dev[0].add_cred_values(default_cred())
605 interworking_select(dev[0], None, no_match=True, freq="2412")
606
607def test_ap_hs20_eap_ttls_unknown(dev, apdev):
608 """Hotspot 2.0 connection with TTLS/unknown"""
609 bssid = apdev[0]['bssid']
610 params = hs20_ap_params()
611 params['nai_realm'] = "0,example.com,21[2:5]"
612 hostapd.add_ap(apdev[0]['ifname'], params)
613
614 dev[0].hs20_enable()
615 dev[0].add_cred_values(default_cred())
616 interworking_select(dev[0], None, no_match=True, freq="2412")
dcd68168
JM
617
618def test_ap_hs20_eap_fast_mschapv2(dev, apdev):
619 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
620 eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user")
621
622def test_ap_hs20_eap_fast_gtc(dev, apdev):
623 """Hotspot 2.0 connection with FAST/EAP-GTC"""
624 eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user")
625
626def test_ap_hs20_eap_tls(dev, apdev):
627 """Hotspot 2.0 connection with EAP-TLS"""
628 bssid = apdev[0]['bssid']
629 params = hs20_ap_params()
630 params['nai_realm'] = [ "0,example.com,13[5:6]" ]
631 hostapd.add_ap(apdev[0]['ifname'], params)
632
dcd68168
JM
633 dev[0].hs20_enable()
634 dev[0].add_cred_values({ 'realm': "example.com",
635 'username': "certificate-user",
636 'ca_cert': "auth_serv/ca.pem",
637 'client_cert': "auth_serv/user.pem",
638 'private_key': "auth_serv/user.key"})
2f37a66d 639 interworking_select(dev[0], bssid, freq="2412")
dcd68168
JM
640 interworking_connect(dev[0], bssid, "TLS")
641
932be82c
JM
642def test_ap_hs20_eap_cert_unknown(dev, apdev):
643 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
644 bssid = apdev[0]['bssid']
645 params = hs20_ap_params()
646 params['nai_realm'] = [ "0,example.com,99[5:6]" ]
647 hostapd.add_ap(apdev[0]['ifname'], params)
648
649 dev[0].hs20_enable()
650 dev[0].add_cred_values({ 'realm': "example.com",
651 'username': "certificate-user",
652 'ca_cert': "auth_serv/ca.pem",
653 'client_cert': "auth_serv/user.pem",
654 'private_key': "auth_serv/user.key"})
655 interworking_select(dev[0], None, no_match=True, freq="2412")
656
657def test_ap_hs20_eap_cert_unsupported(dev, apdev):
658 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
659 bssid = apdev[0]['bssid']
660 params = hs20_ap_params()
661 params['nai_realm'] = [ "0,example.com,21[5:6]" ]
662 hostapd.add_ap(apdev[0]['ifname'], params)
663
664 dev[0].hs20_enable()
665 dev[0].add_cred_values({ 'realm': "example.com",
666 'username': "certificate-user",
667 'ca_cert': "auth_serv/ca.pem",
668 'client_cert': "auth_serv/user.pem",
669 'private_key': "auth_serv/user.key"})
670 interworking_select(dev[0], None, no_match=True, freq="2412")
671
672def test_ap_hs20_eap_invalid_cred(dev, apdev):
673 """Hotspot 2.0 connection with invalid cred configuration"""
674 bssid = apdev[0]['bssid']
675 params = hs20_ap_params()
676 hostapd.add_ap(apdev[0]['ifname'], params)
677
678 dev[0].hs20_enable()
679 dev[0].add_cred_values({ 'realm': "example.com",
680 'username': "certificate-user",
681 'client_cert': "auth_serv/user.pem" })
682 interworking_select(dev[0], None, no_match=True, freq="2412")
683
0aca5d13
JM
684def test_ap_hs20_nai_realms(dev, apdev):
685 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
686 bssid = apdev[0]['bssid']
687 params = hs20_ap_params()
688 params['hessid'] = bssid
689 params['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
690 hostapd.add_ap(apdev[0]['ifname'], params)
691
0aca5d13
JM
692 dev[0].hs20_enable()
693 id = dev[0].add_cred_values({ 'realm': "example.com",
694 'username': "pap user",
695 'password': "password",
696 'domain': "example.com" })
2f37a66d 697 interworking_select(dev[0], bssid, "home", freq="2412")
0aca5d13
JM
698 interworking_connect(dev[0], bssid, "TTLS")
699 check_sp_type(dev[0], "home")
700
e209eb98
JM
701def test_ap_hs20_roaming_consortium(dev, apdev):
702 """Hotspot 2.0 connection based on roaming consortium match"""
703 bssid = apdev[0]['bssid']
704 params = hs20_ap_params()
705 params['hessid'] = bssid
706 hostapd.add_ap(apdev[0]['ifname'], params)
707
e209eb98 708 dev[0].hs20_enable()
80584122
JM
709 for consortium in [ "112233", "1020304050", "010203040506", "fedcba" ]:
710 id = dev[0].add_cred_values({ 'username': "user",
711 'password': "password",
712 'domain': "example.com",
713 'roaming_consortium': consortium,
714 'eap': "PEAP" })
715 interworking_select(dev[0], bssid, "home", freq="2412")
716 interworking_connect(dev[0], bssid, "PEAP")
717 check_sp_type(dev[0], "home")
718 dev[0].request("INTERWORKING_SELECT auto freq=2412")
719 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
720 if ev is None:
721 raise Exception("Timeout on already-connected event")
722 dev[0].remove_cred(id)
e209eb98 723
8fba2e5d
JM
724def test_ap_hs20_username_roaming(dev, apdev):
725 """Hotspot 2.0 connection in username/password credential (roaming)"""
8fba2e5d
JM
726 bssid = apdev[0]['bssid']
727 params = hs20_ap_params()
728 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
729 "0,roaming.example.com,21[2:4][5:7]",
730 "0,another.example.com" ]
731 params['domain_name'] = "another.example.com"
732 params['hessid'] = bssid
733 hostapd.add_ap(apdev[0]['ifname'], params)
734
735 dev[0].hs20_enable()
2232edf8
JM
736 id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
737 'username': "hs20-test",
738 'password': "password",
739 'domain': "example.com" })
2f37a66d 740 interworking_select(dev[0], bssid, "roaming", freq="2412")
8fba2e5d
JM
741 interworking_connect(dev[0], bssid, "TTLS")
742 check_sp_type(dev[0], "roaming")
743
744def test_ap_hs20_username_unknown(dev, apdev):
745 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
8fba2e5d
JM
746 bssid = apdev[0]['bssid']
747 params = hs20_ap_params()
748 params['hessid'] = bssid
749 hostapd.add_ap(apdev[0]['ifname'], params)
750
751 dev[0].hs20_enable()
2232edf8
JM
752 id = dev[0].add_cred_values({ 'realm': "example.com",
753 'username': "hs20-test",
754 'password': "password" })
2f37a66d 755 interworking_select(dev[0], bssid, "unknown", freq="2412")
8fba2e5d
JM
756 interworking_connect(dev[0], bssid, "TTLS")
757 check_sp_type(dev[0], "unknown")
758
759def test_ap_hs20_username_unknown2(dev, apdev):
760 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
8fba2e5d
JM
761 bssid = apdev[0]['bssid']
762 params = hs20_ap_params()
763 params['hessid'] = bssid
764 del params['domain_name']
765 hostapd.add_ap(apdev[0]['ifname'], params)
766
767 dev[0].hs20_enable()
2232edf8
JM
768 id = dev[0].add_cred_values({ 'realm': "example.com",
769 'username': "hs20-test",
770 'password': "password",
771 'domain': "example.com" })
2f37a66d 772 interworking_select(dev[0], bssid, "unknown", freq="2412")
8fba2e5d
JM
773 interworking_connect(dev[0], bssid, "TTLS")
774 check_sp_type(dev[0], "unknown")
d1ba402f 775
483691bd
JM
776def test_ap_hs20_gas_while_associated(dev, apdev):
777 """Hotspot 2.0 connection with GAS query while associated"""
778 bssid = apdev[0]['bssid']
779 params = hs20_ap_params()
780 params['hessid'] = bssid
781 hostapd.add_ap(apdev[0]['ifname'], params)
782
483691bd
JM
783 dev[0].hs20_enable()
784 id = dev[0].add_cred_values({ 'realm': "example.com",
785 'username': "hs20-test",
786 'password': "password",
787 'domain': "example.com" })
2f37a66d 788 interworking_select(dev[0], bssid, "home", freq="2412")
483691bd
JM
789 interworking_connect(dev[0], bssid, "TTLS")
790
791 logger.info("Verifying GAS query while associated")
792 dev[0].request("FETCH_ANQP")
793 for i in range(0, 6):
794 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
795 if ev is None:
796 raise Exception("Operation timed out")
797
ee2caef3
JM
798def test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
799 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
800 bssid = apdev[0]['bssid']
801 params = hs20_ap_params()
802 params['hessid'] = bssid
803 hostapd.add_ap(apdev[0]['ifname'], params)
804
805 bssid2 = apdev[1]['bssid']
806 params = hs20_ap_params()
807 params['hessid'] = bssid2
808 params['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
809 hostapd.add_ap(apdev[1]['ifname'], params)
810
811 dev[0].hs20_enable()
812 dev[0].request("SET pmf 2")
813 id = dev[0].add_cred_values({ 'realm': "example.com",
814 'username': "hs20-test",
815 'password': "password",
816 'domain': "example.com" })
817 interworking_select(dev[0], bssid, "home", freq="2412")
818 interworking_connect(dev[0], bssid, "TTLS")
819
820 logger.info("Verifying GAS query while associated")
821 dev[0].request("FETCH_ANQP")
822 for i in range(0, 2 * 6):
823 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
824 if ev is None:
825 raise Exception("Operation timed out")
826
483691bd
JM
827def test_ap_hs20_gas_frag_while_associated(dev, apdev):
828 """Hotspot 2.0 connection with fragmented GAS query while associated"""
829 bssid = apdev[0]['bssid']
830 params = hs20_ap_params()
831 params['hessid'] = bssid
832 hostapd.add_ap(apdev[0]['ifname'], params)
833 hapd = hostapd.Hostapd(apdev[0]['ifname'])
834 hapd.set("gas_frag_limit", "50")
835
483691bd
JM
836 dev[0].hs20_enable()
837 id = dev[0].add_cred_values({ 'realm': "example.com",
838 'username': "hs20-test",
839 'password': "password",
840 'domain': "example.com" })
2f37a66d 841 interworking_select(dev[0], bssid, "home", freq="2412")
483691bd
JM
842 interworking_connect(dev[0], bssid, "TTLS")
843
844 logger.info("Verifying GAS query while associated")
845 dev[0].request("FETCH_ANQP")
846 for i in range(0, 6):
847 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
848 if ev is None:
849 raise Exception("Operation timed out")
850
6a0b4002
JM
851def test_ap_hs20_multiple_connects(dev, apdev):
852 """Hotspot 2.0 connection through multiple network selections"""
853 bssid = apdev[0]['bssid']
854 params = hs20_ap_params()
855 params['hessid'] = bssid
856 hostapd.add_ap(apdev[0]['ifname'], params)
857
858 dev[0].hs20_enable()
859 values = { 'realm': "example.com",
860 'username': "hs20-test",
861 'password': "password",
862 'domain': "example.com" }
863 id = dev[0].add_cred_values(values)
864
841bed04
JM
865 dev[0].scan_for_bss(bssid, freq="2412")
866
6a0b4002
JM
867 for i in range(0, 3):
868 logger.info("Starting Interworking network selection")
2f37a66d 869 dev[0].request("INTERWORKING_SELECT auto freq=2412")
6a0b4002
JM
870 while True:
871 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
872 "INTERWORKING-ALREADY-CONNECTED",
873 "CTRL-EVENT-CONNECTED"], timeout=15)
874 if ev is None:
875 raise Exception("Connection timed out")
876 if "INTERWORKING-NO-MATCH" in ev:
877 raise Exception("Matching AP not found")
878 if "CTRL-EVENT-CONNECTED" in ev:
879 break
880 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
881 break
882 if i == 0:
883 dev[0].request("DISCONNECT")
884 dev[0].dump_monitor()
885
886 networks = dev[0].list_networks()
887 if len(networks) > 1:
888 raise Exception("Duplicated network block detected")
889
b4264f8f
JM
890def test_ap_hs20_disallow_aps(dev, apdev):
891 """Hotspot 2.0 connection and disallow_aps"""
892 bssid = apdev[0]['bssid']
893 params = hs20_ap_params()
894 params['hessid'] = bssid
895 hostapd.add_ap(apdev[0]['ifname'], params)
896
897 dev[0].hs20_enable()
898 values = { 'realm': "example.com",
899 'username': "hs20-test",
900 'password': "password",
901 'domain': "example.com" }
902 id = dev[0].add_cred_values(values)
903
841bed04
JM
904 dev[0].scan_for_bss(bssid, freq="2412")
905
b4264f8f
JM
906 logger.info("Verify disallow_aps bssid")
907 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
908 dev[0].request("INTERWORKING_SELECT auto")
909 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
910 if ev is None:
911 raise Exception("Network selection timed out")
912 dev[0].dump_monitor()
913
914 logger.info("Verify disallow_aps ssid")
915 dev[0].request("SET disallow_aps ssid 746573742d68733230")
2f37a66d 916 dev[0].request("INTERWORKING_SELECT auto freq=2412")
b4264f8f
JM
917 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
918 if ev is None:
919 raise Exception("Network selection timed out")
920 dev[0].dump_monitor()
921
922 logger.info("Verify disallow_aps clear")
923 dev[0].request("SET disallow_aps ")
2f37a66d 924 interworking_select(dev[0], bssid, "home", freq="2412")
b4264f8f
JM
925
926 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
927 ret = dev[0].request("INTERWORKING_CONNECT " + bssid)
928 if "FAIL" not in ret:
929 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
930
d1ba402f
JM
931def policy_test(dev, ap, values, only_one=True):
932 dev.dump_monitor()
19839f8e
JM
933 if ap:
934 logger.info("Verify network selection to AP " + ap['ifname'])
935 bssid = ap['bssid']
841bed04 936 dev.scan_for_bss(bssid, freq="2412")
19839f8e
JM
937 else:
938 logger.info("Verify network selection")
939 bssid = None
d1ba402f
JM
940 dev.hs20_enable()
941 id = dev.add_cred_values(values)
2f37a66d 942 dev.request("INTERWORKING_SELECT auto freq=2412")
19839f8e 943 events = []
d1ba402f
JM
944 while True:
945 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1965cc3a 946 "INTERWORKING-BLACKLISTED",
953a574d 947 "INTERWORKING-SELECTED"], timeout=15)
d1ba402f 948 if ev is None:
953a574d 949 raise Exception("Network selection timed out")
19839f8e 950 events.append(ev)
d1ba402f
JM
951 if "INTERWORKING-NO-MATCH" in ev:
952 raise Exception("Matching AP not found")
19839f8e 953 if bssid and only_one and "INTERWORKING-AP" in ev and bssid not in ev:
d1ba402f 954 raise Exception("Unexpected AP claimed acceptable")
953a574d 955 if "INTERWORKING-SELECTED" in ev:
19839f8e 956 if bssid and bssid not in ev:
953a574d 957 raise Exception("Selected incorrect BSS")
d1ba402f
JM
958 break
959
953a574d
JM
960 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
961 if ev is None:
962 raise Exception("Connection timed out")
19839f8e 963 if bssid and bssid not in ev:
953a574d
JM
964 raise Exception("Connected to incorrect BSS")
965
d1ba402f 966 conn_bssid = dev.get_status_field("bssid")
19839f8e 967 if bssid and conn_bssid != bssid:
d1ba402f
JM
968 raise Exception("bssid information points to incorrect BSS")
969
970 dev.remove_cred(id)
971 dev.dump_monitor()
19839f8e 972 return events
d1ba402f 973
9714fbcd
JM
974def default_cred(domain=None):
975 cred = { 'realm': "example.com",
d355372c
JM
976 'username': "hs20-test",
977 'password': "password" }
9714fbcd
JM
978 if domain:
979 cred['domain'] = domain
980 return cred
d355372c 981
cfa57df6
JM
982def test_ap_hs20_prefer_home(dev, apdev):
983 """Hotspot 2.0 required roaming consortium"""
984 params = hs20_ap_params()
985 params['domain_name'] = "example.org"
986 hostapd.add_ap(apdev[0]['ifname'], params)
987
988 params = hs20_ap_params()
989 params['ssid'] = "test-hs20-other"
990 params['domain_name'] = "example.com"
991 hostapd.add_ap(apdev[1]['ifname'], params)
992
993 values = default_cred()
994 values['domain'] = "example.com"
995 policy_test(dev[0], apdev[1], values, only_one=False)
996 values['domain'] = "example.org"
997 policy_test(dev[0], apdev[0], values, only_one=False)
998
d1ba402f
JM
999def test_ap_hs20_req_roaming_consortium(dev, apdev):
1000 """Hotspot 2.0 required roaming consortium"""
1001 params = hs20_ap_params()
1002 hostapd.add_ap(apdev[0]['ifname'], params)
1003
1004 params = hs20_ap_params()
1005 params['ssid'] = "test-hs20-other"
1006 params['roaming_consortium'] = [ "223344" ]
1007 hostapd.add_ap(apdev[1]['ifname'], params)
1008
d355372c
JM
1009 values = default_cred()
1010 values['required_roaming_consortium'] = "223344"
d1ba402f
JM
1011 policy_test(dev[0], apdev[1], values)
1012 values['required_roaming_consortium'] = "112233"
1013 policy_test(dev[0], apdev[0], values)
d355372c 1014
af70a093
JM
1015 id = dev[0].add_cred()
1016 dev[0].set_cred(id, "required_roaming_consortium", "112233")
1017 dev[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1018
1019 for val in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1020 if "FAIL" not in dev[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val)):
1021 raise Exception("Invalid roaming consortium value accepted: " + val)
1022
d355372c
JM
1023def test_ap_hs20_excluded_ssid(dev, apdev):
1024 """Hotspot 2.0 exclusion based on SSID"""
1025 params = hs20_ap_params()
e2afdef2
JM
1026 params['roaming_consortium'] = [ "223344" ]
1027 params['anqp_3gpp_cell_net'] = "555,444"
d355372c
JM
1028 hostapd.add_ap(apdev[0]['ifname'], params)
1029
1030 params = hs20_ap_params()
1031 params['ssid'] = "test-hs20-other"
1032 params['roaming_consortium'] = [ "223344" ]
e2afdef2 1033 params['anqp_3gpp_cell_net'] = "555,444"
d355372c
JM
1034 hostapd.add_ap(apdev[1]['ifname'], params)
1035
1036 values = default_cred()
1037 values['excluded_ssid'] = "test-hs20"
1965cc3a
JM
1038 events = policy_test(dev[0], apdev[1], values)
1039 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1040 if len(ev) != 1:
1041 raise Exception("Excluded network not reported")
d355372c 1042 values['excluded_ssid'] = "test-hs20-other"
1965cc3a
JM
1043 events = policy_test(dev[0], apdev[0], values)
1044 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[1]['bssid'] in e]
1045 if len(ev) != 1:
1046 raise Exception("Excluded network not reported")
d4058934 1047
e2afdef2
JM
1048 values = default_cred()
1049 values['roaming_consortium'] = "223344"
1050 values['eap'] = "TTLS"
1051 values['phase2'] = "auth=MSCHAPV2"
1052 values['excluded_ssid'] = "test-hs20"
1053 events = policy_test(dev[0], apdev[1], values)
1054 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1055 if len(ev) != 1:
1056 raise Exception("Excluded network not reported")
1057
1058 values = { 'imsi': "555444-333222111", 'eap': "SIM",
1059 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1060 'excluded_ssid': "test-hs20" }
1061 events = policy_test(dev[0], apdev[1], values)
1062 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1063 if len(ev) != 1:
1064 raise Exception("Excluded network not reported")
1065
d4058934
JM
1066def test_ap_hs20_roam_to_higher_prio(dev, apdev):
1067 """Hotspot 2.0 and roaming from current to higher priority network"""
1068 bssid = apdev[0]['bssid']
1069 params = hs20_ap_params(ssid="test-hs20-visited")
1070 params['domain_name'] = "visited.example.org"
1071 hostapd.add_ap(apdev[0]['ifname'], params)
1072
1073 dev[0].hs20_enable()
1074 id = dev[0].add_cred_values({ 'realm': "example.com",
1075 'username': "hs20-test",
1076 'password': "password",
1077 'domain': "example.com" })
1078 logger.info("Connect to the only network option")
1079 interworking_select(dev[0], bssid, "roaming", freq="2412")
1080 dev[0].dump_monitor()
1081 interworking_connect(dev[0], bssid, "TTLS")
1082
1083 logger.info("Start another AP (home operator) and reconnect")
1084 bssid2 = apdev[1]['bssid']
1085 params = hs20_ap_params(ssid="test-hs20-home")
1086 params['domain_name'] = "example.com"
1087 hostapd.add_ap(apdev[1]['ifname'], params)
1088
841bed04 1089 dev[0].scan_for_bss(bssid2, freq="2412", force_scan=True)
d4058934
JM
1090 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1091 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
1092 "INTERWORKING-ALREADY-CONNECTED",
1093 "CTRL-EVENT-CONNECTED"], timeout=15)
1094 if ev is None:
1095 raise Exception("Connection timed out")
1096 if "INTERWORKING-NO-MATCH" in ev:
1097 raise Exception("Matching AP not found")
1098 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1099 raise Exception("Unexpected AP selected")
1100 if bssid2 not in ev:
1101 raise Exception("Unexpected BSSID after reconnection")
12c587a5
JM
1102
1103def test_ap_hs20_domain_suffix_match(dev, apdev):
1104 """Hotspot 2.0 and domain_suffix_match"""
1105 bssid = apdev[0]['bssid']
1106 params = hs20_ap_params()
1107 hostapd.add_ap(apdev[0]['ifname'], params)
1108
1109 dev[0].hs20_enable()
1110 id = dev[0].add_cred_values({ 'realm': "example.com",
1111 'username': "hs20-test",
1112 'password': "password",
1113 'domain': "example.com",
1114 'domain_suffix_match': "w1.fi" })
1115 interworking_select(dev[0], bssid, "home", freq="2412")
1116 dev[0].dump_monitor()
1117 interworking_connect(dev[0], bssid, "TTLS")
1118 dev[0].request("REMOVE_NETWORK all")
1119 dev[0].dump_monitor()
1120
1121 dev[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1122 interworking_select(dev[0], bssid, "home", freq="2412")
1123 dev[0].dump_monitor()
1124 dev[0].request("INTERWORKING_CONNECT " + bssid)
1125 ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1126 if ev is None:
1127 raise Exception("TLS certificate error not reported")
1128 if "Domain suffix mismatch" not in ev:
1129 raise Exception("Domain suffix mismatch not reported")
078683ac 1130
2253ea44
JM
1131def test_ap_hs20_roaming_partner_preference(dev, apdev):
1132 """Hotspot 2.0 and roaming partner preference"""
1133 params = hs20_ap_params()
1134 params['domain_name'] = "roaming.example.org"
1135 hostapd.add_ap(apdev[0]['ifname'], params)
1136
1137 params = hs20_ap_params()
1138 params['ssid'] = "test-hs20-other"
1139 params['domain_name'] = "roaming.example.net"
1140 hostapd.add_ap(apdev[1]['ifname'], params)
1141
1142 logger.info("Verify default vs. specified preference")
1143 values = default_cred()
1144 values['roaming_partner'] = "roaming.example.net,1,127,*"
1145 policy_test(dev[0], apdev[1], values, only_one=False)
1146 values['roaming_partner'] = "roaming.example.net,1,129,*"
1147 policy_test(dev[0], apdev[0], values, only_one=False)
1148
1149 logger.info("Verify partial FQDN match")
1150 values['roaming_partner'] = "example.net,0,0,*"
1151 policy_test(dev[0], apdev[1], values, only_one=False)
1152 values['roaming_partner'] = "example.net,0,255,*"
1153 policy_test(dev[0], apdev[0], values, only_one=False)
1154
19839f8e
JM
1155def test_ap_hs20_max_bss_load(dev, apdev):
1156 """Hotspot 2.0 and maximum BSS load"""
1157 params = hs20_ap_params()
1158 params['bss_load_test'] = "12:200:20000"
1159 hostapd.add_ap(apdev[0]['ifname'], params)
1160
1161 params = hs20_ap_params()
1162 params['ssid'] = "test-hs20-other"
1163 params['bss_load_test'] = "5:20:10000"
1164 hostapd.add_ap(apdev[1]['ifname'], params)
1165
1166 logger.info("Verify maximum BSS load constraint")
1167 values = default_cred()
1168 values['domain'] = "example.com"
1169 values['max_bss_load'] = "100"
1170 events = policy_test(dev[0], apdev[1], values, only_one=False)
1171
1172 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1173 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1174 raise Exception("Maximum BSS Load case not noticed")
1175 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1176 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1177 raise Exception("Maximum BSS Load case reported incorrectly")
1178
1179 logger.info("Verify maximum BSS load does not prevent connection")
1180 values['max_bss_load'] = "1"
1181 events = policy_test(dev[0], None, values)
1182
1183 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1184 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1185 raise Exception("Maximum BSS Load case not noticed")
1186 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1187 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1188 raise Exception("Maximum BSS Load case not noticed")
1189
1190def test_ap_hs20_max_bss_load2(dev, apdev):
1191 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1192 params = hs20_ap_params()
1193 params['bss_load_test'] = "12:200:20000"
1194 hostapd.add_ap(apdev[0]['ifname'], params)
1195
1196 params = hs20_ap_params()
1197 params['ssid'] = "test-hs20-other"
1198 hostapd.add_ap(apdev[1]['ifname'], params)
1199
1200 logger.info("Verify maximum BSS load constraint with AP advertisement")
1201 values = default_cred()
1202 values['domain'] = "example.com"
1203 values['max_bss_load'] = "100"
1204 events = policy_test(dev[0], apdev[1], values, only_one=False)
1205
1206 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1207 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1208 raise Exception("Maximum BSS Load case not noticed")
1209 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1210 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1211 raise Exception("Maximum BSS Load case reported incorrectly")
1212
078683ac
JM
1213def test_ap_hs20_multi_cred_sp_prio(dev, apdev):
1214 """Hotspot 2.0 multi-cred sp_priority"""
1215 if not hlr_auc_gw_available():
1216 return "skip"
1217 bssid = apdev[0]['bssid']
1218 params = hs20_ap_params()
1219 params['hessid'] = bssid
1220 del params['domain_name']
1221 params['anqp_3gpp_cell_net'] = "232,01"
1222 hostapd.add_ap(apdev[0]['ifname'], params)
1223
1224 dev[0].hs20_enable()
852cb016 1225 dev[0].scan_for_bss(bssid, freq="2412")
078683ac
JM
1226 dev[0].request("SET external_sim 1")
1227 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1228 'provisioning_sp': "example.com",
1229 'sp_priority' :"1" })
1230 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1231 'username': "hs20-test",
1232 'password': "password",
1233 'domain': "example.com",
1234 'provisioning_sp': "example.com",
1235 'sp_priority': "2" })
1236 dev[0].dump_monitor()
852cb016 1237 dev[0].scan_for_bss(bssid, freq="2412")
0b651713 1238 dev[0].request("INTERWORKING_SELECT auto freq=2412")
078683ac
JM
1239 interworking_ext_sim_auth(dev[0], "SIM")
1240 check_sp_type(dev[0], "unknown")
1241 dev[0].request("REMOVE_NETWORK all")
1242
1243 dev[0].set_cred(id1, "sp_priority", "2")
1244 dev[0].set_cred(id2, "sp_priority", "1")
1245 dev[0].dump_monitor()
0b651713 1246 dev[0].request("INTERWORKING_SELECT auto freq=2412")
078683ac
JM
1247 interworking_auth(dev[0], "TTLS")
1248 check_sp_type(dev[0], "unknown")
1249
1250def test_ap_hs20_multi_cred_sp_prio2(dev, apdev):
1251 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1252 if not hlr_auc_gw_available():
1253 return "skip"
1254 bssid = apdev[0]['bssid']
1255 params = hs20_ap_params()
1256 params['hessid'] = bssid
1257 del params['nai_realm']
1258 del params['domain_name']
1259 params['anqp_3gpp_cell_net'] = "232,01"
1260 hostapd.add_ap(apdev[0]['ifname'], params)
1261
1262 bssid2 = apdev[1]['bssid']
1263 params = hs20_ap_params()
1264 params['ssid'] = "test-hs20-other"
1265 params['hessid'] = bssid2
1266 del params['domain_name']
1267 del params['anqp_3gpp_cell_net']
1268 hostapd.add_ap(apdev[1]['ifname'], params)
1269
1270 dev[0].hs20_enable()
1271 dev[0].request("SET external_sim 1")
1272 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1273 'provisioning_sp': "example.com",
1274 'sp_priority': "1" })
1275 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1276 'username': "hs20-test",
1277 'password': "password",
1278 'domain': "example.com",
1279 'provisioning_sp': "example.com",
1280 'sp_priority': "2" })
1281 dev[0].dump_monitor()
852cb016
JM
1282 dev[0].scan_for_bss(bssid, freq="2412")
1283 dev[0].scan_for_bss(bssid2, freq="2412")
0b651713 1284 dev[0].request("INTERWORKING_SELECT auto freq=2412")
078683ac
JM
1285 interworking_ext_sim_auth(dev[0], "SIM")
1286 check_sp_type(dev[0], "unknown")
1287 conn_bssid = dev[0].get_status_field("bssid")
1288 if conn_bssid != bssid:
1289 raise Exception("Connected to incorrect BSS")
1290 dev[0].request("REMOVE_NETWORK all")
1291
1292 dev[0].set_cred(id1, "sp_priority", "2")
1293 dev[0].set_cred(id2, "sp_priority", "1")
1294 dev[0].dump_monitor()
0b651713 1295 dev[0].request("INTERWORKING_SELECT auto freq=2412")
078683ac
JM
1296 interworking_auth(dev[0], "TTLS")
1297 check_sp_type(dev[0], "unknown")
1298 conn_bssid = dev[0].get_status_field("bssid")
1299 if conn_bssid != bssid2:
1300 raise Exception("Connected to incorrect BSS")
5e32f825 1301
a3dd0478
JM
1302def check_conn_capab_selection(dev, type, missing):
1303 dev.request("INTERWORKING_SELECT freq=2412")
1304 ev = dev.wait_event(["INTERWORKING-AP"])
1305 if ev is None:
1306 raise Exception("Network selection timed out");
1307 if "type=" + type not in ev:
1308 raise Exception("Unexpected network type")
1309 if missing and "conn_capab_missing=1" not in ev:
1310 raise Exception("conn_capab_missing not reported")
1311 if not missing and "conn_capab_missing=1" in ev:
1312 raise Exception("conn_capab_missing reported unexpectedly")
1313
1314def conn_capab_cred(domain=None, req_conn_capab=None):
1315 cred = default_cred(domain=domain)
1316 if req_conn_capab:
1317 cred['req_conn_capab'] = req_conn_capab
1318 return cred
1319
18153179
JM
1320def test_ap_hs20_req_conn_capab(dev, apdev):
1321 """Hotspot 2.0 network selection with req_conn_capab"""
1322 bssid = apdev[0]['bssid']
1323 params = hs20_ap_params()
1324 hostapd.add_ap(apdev[0]['ifname'], params)
1325
1326 dev[0].hs20_enable()
852cb016 1327 dev[0].scan_for_bss(bssid, freq="2412")
18153179 1328 logger.info("Not used in home network")
a3dd0478
JM
1329 values = conn_capab_cred(domain="example.com", req_conn_capab="6:1234")
1330 id = dev[0].add_cred_values(values)
1331 check_conn_capab_selection(dev[0], "home", False)
18153179
JM
1332
1333 logger.info("Used in roaming network")
1334 dev[0].remove_cred(id)
a3dd0478
JM
1335 values = conn_capab_cred(domain="example.org", req_conn_capab="6:1234")
1336 id = dev[0].add_cred_values(values)
1337 check_conn_capab_selection(dev[0], "roaming", True)
18153179
JM
1338
1339 logger.info("Verify that req_conn_capab does not prevent connection if no other network is available")
a3dd0478
JM
1340 check_auto_select(dev[0], bssid)
1341
1342 logger.info("Additional req_conn_capab checks")
1343
1344 dev[0].remove_cred(id)
1345 values = conn_capab_cred(domain="example.org", req_conn_capab="1:0")
1346 id = dev[0].add_cred_values(values)
1347 check_conn_capab_selection(dev[0], "roaming", True)
1348
1349 dev[0].remove_cred(id)
1350 values = conn_capab_cred(domain="example.org", req_conn_capab="17:5060")
1351 id = dev[0].add_cred_values(values)
1352 check_conn_capab_selection(dev[0], "roaming", True)
1353
1354 bssid2 = apdev[1]['bssid']
1355 params = hs20_ap_params(ssid="test-hs20b")
1356 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1357 hostapd.add_ap(apdev[1]['ifname'], params)
1358
1359 dev[0].remove_cred(id)
1360 values = conn_capab_cred(domain="example.org", req_conn_capab="50")
1361 id = dev[0].add_cred_values(values)
1362 dev[0].set_cred(id, "req_conn_capab", "6:22")
841bed04 1363 dev[0].scan_for_bss(bssid2, freq="2412")
a3dd0478
JM
1364 dev[0].request("INTERWORKING_SELECT freq=2412")
1365 for i in range(0, 2):
1366 ev = dev[0].wait_event(["INTERWORKING-AP"])
1367 if ev is None:
1368 raise Exception("Network selection timed out");
1369 if bssid in ev and "conn_capab_missing=1" not in ev:
1370 raise Exception("Missing protocol connection capability not reported")
1371 if bssid2 in ev and "conn_capab_missing=1" in ev:
1372 raise Exception("Protocol connection capability not reported correctly")
1373
1374def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev, apdev):
1375 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1376 bssid = apdev[0]['bssid']
1377 params = hs20_ap_params()
1378 params['domain_name'] = "roaming.example.org"
1379 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1380 hostapd.add_ap(apdev[0]['ifname'], params)
1381
1382 bssid2 = apdev[1]['bssid']
1383 params = hs20_ap_params(ssid="test-hs20-b")
1384 params['domain_name'] = "roaming.example.net"
1385 hostapd.add_ap(apdev[1]['ifname'], params)
1386
1387 values = default_cred()
1388 values['roaming_partner'] = "roaming.example.net,1,127,*"
1389 id = dev[0].add_cred_values(values)
1390 check_auto_select(dev[0], bssid2)
1391
1392 dev[0].set_cred(id, "req_conn_capab", "50")
1393 check_auto_select(dev[0], bssid)
1394
1395 dev[0].remove_cred(id)
1396 id = dev[0].add_cred_values(values)
1397 dev[0].set_cred(id, "req_conn_capab", "51")
1398 check_auto_select(dev[0], bssid2)
18153179 1399
9714fbcd
JM
1400def check_bandwidth_selection(dev, type, below):
1401 dev.request("INTERWORKING_SELECT freq=2412")
1402 ev = dev.wait_event(["INTERWORKING-AP"])
1403 if ev is None:
1404 raise Exception("Network selection timed out");
1405 if "type=" + type not in ev:
1406 raise Exception("Unexpected network type")
1407 if below and "below_min_backhaul=1" not in ev:
1408 raise Exception("below_min_backhaul not reported")
1409 if not below and "below_min_backhaul=1" in ev:
1410 raise Exception("below_min_backhaul reported unexpectedly")
1411
1412def bw_cred(domain=None, dl_home=None, ul_home=None, dl_roaming=None, ul_roaming=None):
1413 cred = default_cred(domain=domain)
1414 if dl_home:
1415 cred['min_dl_bandwidth_home'] = str(dl_home)
1416 if ul_home:
1417 cred['min_ul_bandwidth_home'] = str(ul_home)
1418 if dl_roaming:
1419 cred['min_dl_bandwidth_roaming'] = str(dl_roaming)
1420 if ul_roaming:
1421 cred['min_ul_bandwidth_roaming'] = str(ul_roaming)
1422 return cred
1423
1424def test_ap_hs20_min_bandwidth_home(dev, apdev):
1425 """Hotspot 2.0 network selection with min bandwidth (home)"""
1426 bssid = apdev[0]['bssid']
1427 params = hs20_ap_params()
1428 hostapd.add_ap(apdev[0]['ifname'], params)
1429
1430 dev[0].hs20_enable()
852cb016 1431 dev[0].scan_for_bss(bssid, freq="2412")
9714fbcd
JM
1432 values = bw_cred(domain="example.com", dl_home=5490, ul_home=58)
1433 id = dev[0].add_cred_values(values)
1434 check_bandwidth_selection(dev[0], "home", False)
1435 dev[0].remove_cred(id)
1436
1437 values = bw_cred(domain="example.com", dl_home=5491, ul_home=58)
1438 id = dev[0].add_cred_values(values)
1439 check_bandwidth_selection(dev[0], "home", True)
1440 dev[0].remove_cred(id)
1441
1442 values = bw_cred(domain="example.com", dl_home=5490, ul_home=59)
1443 id = dev[0].add_cred_values(values)
1444 check_bandwidth_selection(dev[0], "home", True)
1445 dev[0].remove_cred(id)
1446
1447 values = bw_cred(domain="example.com", dl_home=5491, ul_home=59)
1448 id = dev[0].add_cred_values(values)
1449 check_bandwidth_selection(dev[0], "home", True)
1450 check_auto_select(dev[0], bssid)
1451
1452 bssid2 = apdev[1]['bssid']
1453 params = hs20_ap_params(ssid="test-hs20-b")
1454 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1455 hostapd.add_ap(apdev[1]['ifname'], params)
1456
1457 check_auto_select(dev[0], bssid2)
1458
1459def test_ap_hs20_min_bandwidth_roaming(dev, apdev):
1460 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1461 bssid = apdev[0]['bssid']
1462 params = hs20_ap_params()
1463 hostapd.add_ap(apdev[0]['ifname'], params)
1464
1465 dev[0].hs20_enable()
852cb016 1466 dev[0].scan_for_bss(bssid, freq="2412")
9714fbcd
JM
1467 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=58)
1468 id = dev[0].add_cred_values(values)
1469 check_bandwidth_selection(dev[0], "roaming", False)
1470 dev[0].remove_cred(id)
1471
1472 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=58)
1473 id = dev[0].add_cred_values(values)
1474 check_bandwidth_selection(dev[0], "roaming", True)
1475 dev[0].remove_cred(id)
1476
1477 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=59)
1478 id = dev[0].add_cred_values(values)
1479 check_bandwidth_selection(dev[0], "roaming", True)
1480 dev[0].remove_cred(id)
1481
1482 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=59)
1483 id = dev[0].add_cred_values(values)
1484 check_bandwidth_selection(dev[0], "roaming", True)
1485 check_auto_select(dev[0], bssid)
1486
1487 bssid2 = apdev[1]['bssid']
1488 params = hs20_ap_params(ssid="test-hs20-b")
1489 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1490 hostapd.add_ap(apdev[1]['ifname'], params)
1491
1492 check_auto_select(dev[0], bssid2)
1493
1494def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev, apdev):
1495 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1496 bssid = apdev[0]['bssid']
1497 params = hs20_ap_params()
1498 params['domain_name'] = "roaming.example.org"
1499 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1500 hostapd.add_ap(apdev[0]['ifname'], params)
1501
1502 bssid2 = apdev[1]['bssid']
1503 params = hs20_ap_params(ssid="test-hs20-b")
1504 params['domain_name'] = "roaming.example.net"
1505 hostapd.add_ap(apdev[1]['ifname'], params)
1506
1507 values = default_cred()
1508 values['roaming_partner'] = "roaming.example.net,1,127,*"
1509 id = dev[0].add_cred_values(values)
1510 check_auto_select(dev[0], bssid2)
1511
1512 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1513 check_auto_select(dev[0], bssid)
1514
1515 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1516 check_auto_select(dev[0], bssid2)
1517
1518def test_ap_hs20_min_bandwidth_no_wan_metrics(dev, apdev):
1519 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1520 bssid = apdev[0]['bssid']
1521 params = hs20_ap_params()
1522 del params['hs20_wan_metrics']
1523 hostapd.add_ap(apdev[0]['ifname'], params)
1524
1525 dev[0].hs20_enable()
852cb016 1526 dev[0].scan_for_bss(bssid, freq="2412")
9714fbcd
JM
1527 values = bw_cred(domain="example.com", dl_home=10000, ul_home=10000,
1528 dl_roaming=10000, ul_roaming=10000)
1529 dev[0].add_cred_values(values)
1530 check_bandwidth_selection(dev[0], "home", False)
1531
5e32f825
JM
1532def test_ap_hs20_deauth_req_ess(dev, apdev):
1533 """Hotspot 2.0 connection and deauthentication request for ESS"""
1534 dev[0].request("SET pmf 2")
1535 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1536 dev[0].dump_monitor()
1537 addr = dev[0].p2p_interface_addr()
1538 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1539 hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/")
1540 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1541 if ev is None:
1542 raise Exception("Timeout on deauth imminent notice")
1543 if "1 120 http://example.com/" not in ev:
1544 raise Exception("Unexpected deauth imminent notice: " + ev)
1545 hapd.request("DEAUTHENTICATE " + addr)
1546 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1547 if ev is None:
1548 raise Exception("Timeout on disconnection")
c61e5a82
JM
1549 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1550 raise Exception("Network not marked temporarily disabled")
5e32f825
JM
1551 ev = dev[0].wait_event(["SME: Trying to authenticate",
1552 "Trying to associate",
1553 "CTRL-EVENT-CONNECTED"], timeout=5)
1554 if ev is not None:
1555 raise Exception("Unexpected connection attempt")
1556
1557def test_ap_hs20_deauth_req_bss(dev, apdev):
1558 """Hotspot 2.0 connection and deauthentication request for BSS"""
1559 dev[0].request("SET pmf 2")
1560 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1561 dev[0].dump_monitor()
1562 addr = dev[0].p2p_interface_addr()
1563 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1564 hapd.request("HS20_DEAUTH_REQ " + addr + " 0 120 http://example.com/")
1565 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1566 if ev is None:
1567 raise Exception("Timeout on deauth imminent notice")
1568 if "0 120 http://example.com/" not in ev:
1569 raise Exception("Unexpected deauth imminent notice: " + ev)
1570 hapd.request("DEAUTHENTICATE " + addr + " reason=4")
1571 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1572 if ev is None:
1573 raise Exception("Timeout on disconnection")
1574 if "reason=4" not in ev:
1575 raise Exception("Unexpected disconnection reason")
c61e5a82
JM
1576 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1577 raise Exception("Network not marked temporarily disabled")
5e32f825
JM
1578 ev = dev[0].wait_event(["SME: Trying to authenticate",
1579 "Trying to associate",
1580 "CTRL-EVENT-CONNECTED"], timeout=5)
1581 if ev is not None:
1582 raise Exception("Unexpected connection attempt")
9e709315 1583
48ef12e7
JM
1584def test_ap_hs20_deauth_req_from_radius(dev, apdev):
1585 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1586 bssid = apdev[0]['bssid']
1587 params = hs20_ap_params()
1588 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1589 params['hs20_deauth_req_timeout'] = "2"
1590 hostapd.add_ap(apdev[0]['ifname'], params)
1591
1592 dev[0].request("SET pmf 2")
1593 dev[0].hs20_enable()
1594 dev[0].add_cred_values({ 'realm': "example.com",
1595 'username': "hs20-deauth-test",
1596 'password': "password" })
1597 interworking_select(dev[0], bssid, freq="2412")
1598 interworking_connect(dev[0], bssid, "TTLS")
1599 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout=5)
1600 if ev is None:
1601 raise Exception("Timeout on deauth imminent notice")
1602 if " 1 100" not in ev:
1603 raise Exception("Unexpected deauth imminent contents")
1604 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=3)
1605 if ev is None:
1606 raise Exception("Timeout on disconnection")
1607
5cf88011
JM
1608def test_ap_hs20_remediation_required(dev, apdev):
1609 """Hotspot 2.0 connection and remediation required from RADIUS"""
1610 bssid = apdev[0]['bssid']
1611 params = hs20_ap_params()
1612 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1613 hostapd.add_ap(apdev[0]['ifname'], params)
1614
1615 dev[0].request("SET pmf 1")
1616 dev[0].hs20_enable()
1617 dev[0].add_cred_values({ 'realm': "example.com",
1618 'username': "hs20-subrem-test",
1619 'password': "password" })
1620 interworking_select(dev[0], bssid, freq="2412")
1621 interworking_connect(dev[0], bssid, "TTLS")
1622 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1623 if ev is None:
1624 raise Exception("Timeout on subscription remediation notice")
1625 if " 1 https://example.com/" not in ev:
1626 raise Exception("Unexpected subscription remediation event contents")
1627
32b450fc
JM
1628def test_ap_hs20_remediation_required_ctrl(dev, apdev):
1629 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1630 bssid = apdev[0]['bssid']
1631 addr = dev[0].p2p_dev_addr()
1632 params = hs20_ap_params()
1633 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1634 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1635
1636 dev[0].request("SET pmf 1")
1637 dev[0].hs20_enable()
1638 dev[0].add_cred_values(default_cred())
1639 interworking_select(dev[0], bssid, freq="2412")
1640 interworking_connect(dev[0], bssid, "TTLS")
1641
1642 hapd.request("HS20_WNM_NOTIF " + addr + " https://example.com/")
1643 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1644 if ev is None:
1645 raise Exception("Timeout on subscription remediation notice")
1646 if " 1 https://example.com/" not in ev:
1647 raise Exception("Unexpected subscription remediation event contents")
1648
1649 hapd.request("HS20_WNM_NOTIF " + addr)
1650 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1651 if ev is None:
1652 raise Exception("Timeout on subscription remediation notice")
1653 if not ev.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1654 raise Exception("Unexpected subscription remediation event contents: " + ev)
1655
1656 if "FAIL" not in hapd.request("HS20_WNM_NOTIF "):
1657 raise Exception("Unexpected HS20_WNM_NOTIF success")
1658 if "FAIL" not in hapd.request("HS20_WNM_NOTIF foo"):
1659 raise Exception("Unexpected HS20_WNM_NOTIF success")
1660 if "FAIL" not in hapd.request("HS20_WNM_NOTIF " + addr + " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1661 raise Exception("Unexpected HS20_WNM_NOTIF success")
1662
8fc1f204
JM
1663def test_ap_hs20_session_info(dev, apdev):
1664 """Hotspot 2.0 connection and session information from RADIUS"""
1665 bssid = apdev[0]['bssid']
1666 params = hs20_ap_params()
1667 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1668 hostapd.add_ap(apdev[0]['ifname'], params)
1669
1670 dev[0].request("SET pmf 1")
1671 dev[0].hs20_enable()
1672 dev[0].add_cred_values({ 'realm': "example.com",
1673 'username': "hs20-session-info-test",
1674 'password': "password" })
1675 interworking_select(dev[0], bssid, freq="2412")
1676 interworking_connect(dev[0], bssid, "TTLS")
1677 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout=10)
1678 if ev is None:
1679 raise Exception("Timeout on ESS disassociation imminent notice")
1680 if " 1 59904 https://example.com/" not in ev:
1681 raise Exception("Unexpected ESS disassociation imminent event contents")
1682 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1683 if ev is None:
1684 raise Exception("Scan not started")
64502039 1685 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=30)
8fc1f204
JM
1686 if ev is None:
1687 raise Exception("Scan not completed")
1688
9e709315
JM
1689def test_ap_hs20_osen(dev, apdev):
1690 """Hotspot 2.0 OSEN connection"""
1691 params = { 'ssid': "osen",
1692 'osen': "1",
1693 'auth_server_addr': "127.0.0.1",
1694 'auth_server_port': "1812",
1695 'auth_server_shared_secret': "radius" }
1696 hostapd.add_ap(apdev[0]['ifname'], params)
1697
8abb3d4e
JM
1698 dev[1].connect("osen", key_mgmt="NONE", scan_freq="2412",
1699 wait_connect=False)
1700 dev[2].connect("osen", key_mgmt="NONE", wep_key0='"hello"',
1701 scan_freq="2412", wait_connect=False)
9e709315
JM
1702 dev[0].connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1703 group="GTK_NOT_USED",
1704 eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1705 ca_cert="auth_serv/ca.pem",
1706 scan_freq="2412")
a96066a5 1707
9d1e1172
JM
1708 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1709 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1710 wpas.connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1711 group="GTK_NOT_USED",
1712 eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1713 ca_cert="auth_serv/ca.pem",
1714 scan_freq="2412")
1715 wpas.request("DISCONNECT")
1716
a96066a5
JM
1717def test_ap_hs20_network_preference(dev, apdev):
1718 """Hotspot 2.0 network selection with preferred home network"""
1719 bssid = apdev[0]['bssid']
1720 params = hs20_ap_params()
1721 hostapd.add_ap(apdev[0]['ifname'], params)
1722
1723 dev[0].hs20_enable()
1724 values = { 'realm': "example.com",
1725 'username': "hs20-test",
1726 'password': "password",
1727 'domain': "example.com" }
1728 dev[0].add_cred_values(values)
1729
1730 id = dev[0].add_network()
1731 dev[0].set_network_quoted(id, "ssid", "home")
1732 dev[0].set_network_quoted(id, "psk", "12345678")
1733 dev[0].set_network(id, "priority", "1")
1734 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1735
852cb016 1736 dev[0].scan_for_bss(bssid, freq="2412")
a96066a5
JM
1737 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1738 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1739 if ev is None:
1740 raise Exception("Connection timed out")
1741 if bssid not in ev:
1742 raise Exception("Unexpected network selected")
1743
1744 bssid2 = apdev[1]['bssid']
1745 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1746 hostapd.add_ap(apdev[1]['ifname'], params)
1747
852cb016 1748 dev[0].scan_for_bss(bssid2, freq="2412")
a96066a5
JM
1749 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1750 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1751 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1752 if ev is None:
1753 raise Exception("Connection timed out")
1754 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1755 raise Exception("No roam to higher priority network")
1756 if bssid2 not in ev:
1757 raise Exception("Unexpected network selected")
1758
1759def test_ap_hs20_network_preference2(dev, apdev):
1760 """Hotspot 2.0 network selection with preferred credential"""
1761 bssid2 = apdev[1]['bssid']
1762 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1763 hostapd.add_ap(apdev[1]['ifname'], params)
1764
1765 dev[0].hs20_enable()
1766 values = { 'realm': "example.com",
1767 'username': "hs20-test",
1768 'password': "password",
1769 'domain': "example.com",
1770 'priority': "1" }
1771 dev[0].add_cred_values(values)
1772
1773 id = dev[0].add_network()
1774 dev[0].set_network_quoted(id, "ssid", "home")
1775 dev[0].set_network_quoted(id, "psk", "12345678")
1776 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1777
852cb016 1778 dev[0].scan_for_bss(bssid2, freq="2412")
a96066a5
JM
1779 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1780 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1781 if ev is None:
1782 raise Exception("Connection timed out")
1783 if bssid2 not in ev:
1784 raise Exception("Unexpected network selected")
1785
1786 bssid = apdev[0]['bssid']
1787 params = hs20_ap_params()
1788 hostapd.add_ap(apdev[0]['ifname'], params)
1789
852cb016 1790 dev[0].scan_for_bss(bssid, freq="2412")
a96066a5
JM
1791 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1792 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1793 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1794 if ev is None:
1795 raise Exception("Connection timed out")
1796 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1797 raise Exception("No roam to higher priority network")
1798 if bssid not in ev:
1799 raise Exception("Unexpected network selected")
eaff3458
JM
1800
1801def test_ap_hs20_network_preference3(dev, apdev):
1802 """Hotspot 2.0 network selection with two credential (one preferred)"""
1803 bssid = apdev[0]['bssid']
1804 params = hs20_ap_params()
1805 hostapd.add_ap(apdev[0]['ifname'], params)
1806
1807 bssid2 = apdev[1]['bssid']
1808 params = hs20_ap_params(ssid="test-hs20b")
1809 params['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
1810 hostapd.add_ap(apdev[1]['ifname'], params)
1811
1812 dev[0].hs20_enable()
1813 values = { 'realm': "example.com",
1814 'username': "hs20-test",
1815 'password': "password",
1816 'priority': "1" }
1817 dev[0].add_cred_values(values)
1818 values = { 'realm': "example.org",
1819 'username': "hs20-test",
1820 'password': "password" }
1821 id = dev[0].add_cred_values(values)
1822
852cb016
JM
1823 dev[0].scan_for_bss(bssid, freq="2412")
1824 dev[0].scan_for_bss(bssid2, freq="2412")
eaff3458
JM
1825 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1826 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1827 if ev is None:
1828 raise Exception("Connection timed out")
1829 if bssid not in ev:
1830 raise Exception("Unexpected network selected")
1831
1832 dev[0].set_cred(id, "priority", "2")
1833 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1834 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1835 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1836 if ev is None:
1837 raise Exception("Connection timed out")
1838 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1839 raise Exception("No roam to higher priority network")
1840 if bssid2 not in ev:
1841 raise Exception("Unexpected network selected")
1221639d
JM
1842
1843def test_ap_hs20_network_preference4(dev, apdev):
1844 """Hotspot 2.0 network selection with username vs. SIM credential"""
1845 bssid = apdev[0]['bssid']
1846 params = hs20_ap_params()
1847 hostapd.add_ap(apdev[0]['ifname'], params)
1848
1849 bssid2 = apdev[1]['bssid']
1850 params = hs20_ap_params(ssid="test-hs20b")
1851 params['hessid'] = bssid2
1852 params['anqp_3gpp_cell_net'] = "555,444"
1853 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1854 hostapd.add_ap(apdev[1]['ifname'], params)
1855
1856 dev[0].hs20_enable()
1857 values = { 'realm': "example.com",
1858 'username': "hs20-test",
1859 'password': "password",
1860 'priority': "1" }
1861 dev[0].add_cred_values(values)
1862 values = { 'imsi': "555444-333222111",
1863 'eap': "SIM",
1864 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1865 id = dev[0].add_cred_values(values)
1866
852cb016
JM
1867 dev[0].scan_for_bss(bssid, freq="2412")
1868 dev[0].scan_for_bss(bssid2, freq="2412")
1221639d
JM
1869 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1870 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1871 if ev is None:
1872 raise Exception("Connection timed out")
1873 if bssid not in ev:
1874 raise Exception("Unexpected network selected")
1875
1876 dev[0].set_cred(id, "priority", "2")
1877 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1878 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1879 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1880 if ev is None:
1881 raise Exception("Connection timed out")
1882 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1883 raise Exception("No roam to higher priority network")
1884 if bssid2 not in ev:
1885 raise Exception("Unexpected network selected")
97de642a
JM
1886
1887def test_ap_hs20_fetch_osu(dev, apdev):
1888 """Hotspot 2.0 OSU provider and icon fetch"""
1889 bssid = apdev[0]['bssid']
1890 params = hs20_ap_params()
1891 params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1892 params['osu_ssid'] = '"HS 2.0 OSU open"'
1893 params['osu_method_list'] = "1"
1894 params['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
1895 params['osu_icon'] = "w1fi_logo"
1896 params['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
1897 params['osu_server_uri'] = "https://example.com/osu/"
1898 hostapd.add_ap(apdev[0]['ifname'], params)
1899
1900 bssid2 = apdev[1]['bssid']
1901 params = hs20_ap_params(ssid="test-hs20b")
1902 params['hessid'] = bssid2
1903 params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1904 params['osu_ssid'] = '"HS 2.0 OSU OSEN"'
1905 params['osu_method_list'] = "0"
6acecce1 1906 params['osu_nai'] = "osen@example.com"
97de642a
JM
1907 params['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
1908 params['osu_icon'] = "w1fi_logo"
1909 params['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
1910 params['osu_server_uri'] = "https://example.org/osu/"
1911 hostapd.add_ap(apdev[1]['ifname'], params)
1912
1913 with open("w1fi_logo.png", "r") as f:
1914 orig_logo = f.read()
1915 dev[0].hs20_enable()
1916 dir = "/tmp/osu-fetch"
1917 if os.path.isdir(dir):
1918 files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
1919 for f in files:
1920 os.remove(dir + "/" + f)
1921 else:
1922 try:
1923 os.makedirs(dir)
1924 except:
1925 pass
1926 try:
0a578716 1927 dev[1].scan_for_bss(bssid, freq="2412")
97de642a
JM
1928 dev[0].request("SET osu_dir " + dir)
1929 dev[0].request("FETCH_OSU")
d2fb8b86
JM
1930 if "OK" not in dev[1].request("HS20_ICON_REQUEST " + bssid + " w1fi_logo"):
1931 raise Exception("HS20_ICON_REQUEST failed")
97de642a
JM
1932 icons = 0
1933 while True:
1934 ev = dev[0].wait_event(["OSU provider fetch completed",
1935 "RX-HS20-ANQP-ICON"], timeout=15)
1936 if ev is None:
1937 raise Exception("Timeout on OSU fetch")
1938 if "OSU provider fetch completed" in ev:
1939 break
1940 if "RX-HS20-ANQP-ICON" in ev:
1941 with open(ev.split(' ')[1], "r") as f:
1942 logo = f.read()
1943 if logo == orig_logo:
1944 icons += 1
1945
1946 with open(dir + "/osu-providers.txt", "r") as f:
1947 prov = f.read()
1948 if "OSU-PROVIDER " + bssid not in prov:
1949 raise Exception("Missing OSU_PROVIDER")
1950 if "OSU-PROVIDER " + bssid2 not in prov:
1951 raise Exception("Missing OSU_PROVIDER")
1952 finally:
1953 files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
1954 for f in files:
1955 os.remove(dir + "/" + f)
1956 os.rmdir(dir)
1957
1958 if icons != 2:
1959 raise Exception("Unexpected number of icons fetched")
d2fb8b86
JM
1960
1961 ev = dev[1].wait_event(["GAS-QUERY-START"], timeout=5)
1962 if ev is None:
1963 raise Exception("Timeout on GAS-QUERY-DONE")
1964 ev = dev[1].wait_event(["GAS-QUERY-DONE"], timeout=5)
1965 if ev is None:
1966 raise Exception("Timeout on GAS-QUERY-DONE")
1967 if "freq=2412 status_code=0 result=SUCCESS" not in ev:
1968 raise Exception("Unexpected GAS-QUERY-DONE: " + ev)
1969 ev = dev[1].wait_event(["RX-HS20-ANQP"], timeout=15)
1970 if ev is None:
1971 raise Exception("Timeout on icon fetch")
1972 if "Icon Binary File" not in ev:
1973 raise Exception("Unexpected ANQP element")
37ffe7c5
JM
1974
1975def test_ap_hs20_ft(dev, apdev):
1976 """Hotspot 2.0 connection with FT"""
1977 bssid = apdev[0]['bssid']
1978 params = hs20_ap_params()
1979 params['wpa_key_mgmt'] = "FT-EAP"
1980 params['nas_identifier'] = "nas1.w1.fi"
1981 params['r1_key_holder'] = "000102030405"
1982 params["mobility_domain"] = "a1b2"
1983 params["reassociation_deadline"] = "1000"
1984 hostapd.add_ap(apdev[0]['ifname'], params)
1985
1986 dev[0].hs20_enable()
1987 id = dev[0].add_cred_values({ 'realm': "example.com",
1988 'username': "hs20-test",
1989 'password': "password",
1990 'ca_cert': "auth_serv/ca.pem",
1991 'domain': "example.com",
1992 'update_identifier': "1234" })
1993 interworking_select(dev[0], bssid, "home", freq="2412")
1994 interworking_connect(dev[0], bssid, "TTLS")
350a7ba9
JM
1995
1996def test_ap_hs20_remediation_sql(dev, apdev, params):
1997 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
1998 try:
1999 import sqlite3
2000 except ImportError:
2001 return "skip"
2002 dbfile = os.path.join(params['logdir'], "eap-user.db")
2003 try:
2004 os.remove(dbfile)
2005 except:
2006 pass
2007 con = sqlite3.connect(dbfile)
2008 with con:
2009 cur = con.cursor()
2010 cur.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2011 cur.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2012 cur.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2013 cur.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2014 cur.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2015
2016 try:
2017 params = { "ssid": "as", "beacon_int": "2000",
2018 "radius_server_clients": "auth_serv/radius_clients.conf",
2019 "radius_server_auth_port": '18128',
2020 "eap_server": "1",
2021 "eap_user_file": "sqlite:" + dbfile,
2022 "ca_cert": "auth_serv/ca.pem",
2023 "server_cert": "auth_serv/server.pem",
2024 "private_key": "auth_serv/server.key",
2025 "subscr_remediation_url": "https://example.org/",
2026 "subscr_remediation_method": "1" }
2027 hostapd.add_ap(apdev[1]['ifname'], params)
2028
2029 bssid = apdev[0]['bssid']
2030 params = hs20_ap_params()
2031 params['auth_server_port'] = "18128"
2032 hostapd.add_ap(apdev[0]['ifname'], params)
2033
2034 dev[0].request("SET pmf 1")
2035 dev[0].hs20_enable()
2036 id = dev[0].add_cred_values({ 'realm': "example.com",
2037 'username': "user-mschapv2",
2038 'password': "password",
2039 'ca_cert': "auth_serv/ca.pem" })
2040 interworking_select(dev[0], bssid, freq="2412")
2041 interworking_connect(dev[0], bssid, "TTLS")
2042 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
2043 if ev is None:
2044 raise Exception("Timeout on subscription remediation notice")
2045 if " 1 https://example.org/" not in ev:
2046 raise Exception("Unexpected subscription remediation event contents")
2047
2048 with con:
2049 cur = con.cursor()
2050 cur.execute("SELECT * from authlog")
2051 rows = cur.fetchall()
2052 if len(rows) < 1:
2053 raise Exception("No authlog entries")
2054
2055 finally:
2056 os.remove(dbfile)
f1a36a53
JM
2057
2058def test_ap_hs20_external_selection(dev, apdev):
2059 """Hotspot 2.0 connection using external network selection and creation"""
2060 bssid = apdev[0]['bssid']
2061 params = hs20_ap_params()
2062 params['hessid'] = bssid
2063 params['disable_dgaf'] = '1'
2064 hostapd.add_ap(apdev[0]['ifname'], params)
2065
2066 dev[0].hs20_enable()
2067 dev[0].connect("test-hs20", proto="RSN", key_mgmt="WPA-EAP", eap="TTLS",
2068 identity="hs20-test", password="password",
2069 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
2070 scan_freq="2412", update_identifier="54321")
2071 if dev[0].get_status_field("hs20") != "2":
2072 raise Exception("Unexpected hs20 indication")
816e3df9
JM
2073
2074def test_ap_hs20_random_mac_addr(dev, apdev):
2075 """Hotspot 2.0 connection with random MAC address"""
2076 bssid = apdev[0]['bssid']
2077 params = hs20_ap_params()
2078 params['hessid'] = bssid
2079 params['disable_dgaf'] = '1'
2080 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2081
2082 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2083 wpas.interface_add("wlan5")
2084 addr = wpas.p2p_interface_addr()
2085 wpas.request("SET mac_addr 1")
2086 wpas.request("SET preassoc_mac_addr 1")
2087 wpas.request("SET rand_addr_lifetime 60")
2088 wpas.hs20_enable()
4a7d73d1 2089 wpas.scan(freq="2412", only_new=True)
816e3df9
JM
2090 id = wpas.add_cred_values({ 'realm': "example.com",
2091 'username': "hs20-test",
2092 'password': "password",
2093 'ca_cert': "auth_serv/ca.pem",
2094 'domain': "example.com",
2095 'update_identifier': "1234" })
2096 interworking_select(wpas, bssid, "home", freq="2412")
2097 interworking_connect(wpas, bssid, "TTLS")
816e3df9
JM
2098 addr1 = wpas.get_driver_status_field("addr")
2099 if addr == addr1:
2100 raise Exception("Did not use random MAC address")
2101
2102 sta = hapd.get_sta(addr)
2103 if sta['addr'] != "FAIL":
2104 raise Exception("Unexpected STA association with permanent address")
2105 sta = hapd.get_sta(addr1)
2106 if sta['addr'] != addr1:
2107 raise Exception("STA association with random address not found")