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