2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
10 logger = logging.getLogger()
15 from wlantest import Wlantest
17 def hs20_ap_params(ssid="test-hs20"):
18 params = hostapd.wpa2_params(ssid=ssid)
19 params['wpa_key_mgmt'] = "WPA-EAP"
20 params['ieee80211w'] = "1"
21 params['ieee8021x'] = "1"
22 params['auth_server_addr'] = "127.0.0.1"
23 params['auth_server_port'] = "1812"
24 params['auth_server_shared_secret'] = "radius"
25 params['interworking'] = "1"
26 params['access_network_type'] = "14"
27 params['internet'] = "1"
31 params['venue_group'] = "7"
32 params['venue_type'] = "1"
33 params['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
34 params['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
36 params['domain_name'] = "example.com,another.example.com"
37 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
38 "0,another.example.com" ]
40 params['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
41 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
42 params['hs20_operating_class'] = "5173"
43 params['anqp_3gpp_cell_net'] = "244,91"
46 def check_auto_select(dev, bssid):
47 dev.request("INTERWORKING_SELECT auto freq=2412")
48 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
50 raise Exception("Connection timed out")
52 raise Exception("Connected to incorrect network")
53 dev.request("REMOVE_NETWORK all")
55 def interworking_select(dev, bssid, type=None, no_match=False, freq=None):
57 freq_extra = " freq=" + freq if freq else ""
58 dev.request("INTERWORKING_SELECT" + freq_extra)
59 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
62 raise Exception("Network selection timed out");
64 if "INTERWORKING-NO-MATCH" not in ev:
65 raise Exception("Unexpected network match")
67 if "INTERWORKING-NO-MATCH" in ev:
68 raise Exception("Matching network not found")
69 if bssid and bssid not in ev:
70 raise Exception("Unexpected BSSID in match")
71 if type and "type=" + type not in ev:
72 raise Exception("Network type not recognized correctly")
74 def check_sp_type(dev, sp_type):
75 type = dev.get_status_field("sp_type")
77 raise Exception("sp_type not available")
79 raise Exception("sp_type did not indicate home network")
81 def hlr_auc_gw_available():
82 if not os.path.exists("/tmp/hlr_auc_gw.sock"):
83 logger.info("No hlr_auc_gw available");
85 if not os.path.exists("../../hostapd/hlr_auc_gw"):
86 logger.info("No hlr_auc_gw available");
90 def interworking_ext_sim_connect(dev, bssid, method):
91 dev.request("INTERWORKING_CONNECT " + bssid)
92 interworking_ext_sim_auth(dev, method)
94 def interworking_ext_sim_auth(dev, method):
95 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
97 raise Exception("Network connected timed out")
98 if "(" + method + ")" not in ev:
99 raise Exception("Unexpected EAP method selection")
101 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
103 raise Exception("Wait for external SIM processing request timed out")
105 if p[1] != "GSM-AUTH":
106 raise Exception("Unexpected CTRL-REQ-SIM type")
107 id = p[0].split('-')[3]
108 rand = p[2].split(' ')[0]
110 res = subprocess.check_output(["../../hostapd/hlr_auc_gw",
112 "auth_serv/hlr_auc_gw.milenage_db",
113 "GSM-AUTH-REQ 232010000000000 " + rand])
114 if "GSM-AUTH-RESP" not in res:
115 raise Exception("Unexpected hlr_auc_gw response")
116 resp = res.split(' ')[2].rstrip()
118 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
119 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
121 raise Exception("Connection timed out")
123 def interworking_connect(dev, bssid, method):
124 dev.request("INTERWORKING_CONNECT " + bssid)
125 interworking_auth(dev, method)
127 def interworking_auth(dev, method):
128 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
130 raise Exception("Network connected timed out")
131 if "(" + method + ")" not in ev:
132 raise Exception("Unexpected EAP method selection")
134 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
136 raise Exception("Connection timed out")
138 def check_probe_resp(wt, bssid_unexpected, bssid_expected):
140 count = wt.get_bss_counter("probe_response", bssid_unexpected)
142 raise Exception("Unexpected Probe Response frame from AP")
145 count = wt.get_bss_counter("probe_response", bssid_expected)
147 raise Exception("No Probe Response frame from AP")
149 def test_ap_anqp_sharing(dev, apdev):
150 """ANQP sharing within ESS and explicit unshare"""
151 bssid = apdev[0]['bssid']
152 params = hs20_ap_params()
153 params['hessid'] = bssid
154 hostapd.add_ap(apdev[0]['ifname'], params)
156 bssid2 = apdev[1]['bssid']
157 params = hs20_ap_params()
158 params['hessid'] = bssid
159 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
160 hostapd.add_ap(apdev[1]['ifname'], params)
163 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
164 'password': "secret",
165 'domain': "example.com" })
166 logger.info("Normal network selection with shared ANQP results")
167 interworking_select(dev[0], None, "home", freq="2412")
168 dev[0].dump_monitor()
170 res1 = dev[0].get_bss(bssid)
171 res2 = dev[0].get_bss(bssid2)
172 if res1['anqp_nai_realm'] != res2['anqp_nai_realm']:
173 raise Exception("ANQP results were not shared between BSSes")
175 logger.info("Explicit ANQP request to unshare ANQP results")
176 dev[0].request("ANQP_GET " + bssid + " 263")
177 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
179 raise Exception("ANQP operation timed out")
181 dev[0].request("ANQP_GET " + bssid2 + " 263")
182 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
184 raise Exception("ANQP operation timed out")
186 res1 = dev[0].get_bss(bssid)
187 res2 = dev[0].get_bss(bssid2)
188 if res1['anqp_nai_realm'] == res2['anqp_nai_realm']:
189 raise Exception("ANQP results were not unshared")
191 def test_ap_nai_home_realm_query(dev, apdev):
192 """NAI Home Realm Query"""
193 bssid = apdev[0]['bssid']
194 params = hs20_ap_params()
195 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
196 "0,another.example.org" ]
197 hostapd.add_ap(apdev[0]['ifname'], params)
199 dev[0].scan(freq="2412")
200 dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " realm=example.com")
201 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
203 raise Exception("ANQP operation timed out")
204 nai1 = dev[0].get_bss(bssid)['anqp_nai_realm']
205 dev[0].dump_monitor()
207 dev[0].request("ANQP_GET " + bssid + " 263")
208 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
210 raise Exception("ANQP operation timed out")
211 nai2 = dev[0].get_bss(bssid)['anqp_nai_realm']
213 if len(nai1) >= len(nai2):
214 raise Exception("Unexpected NAI Realm list response lengths")
215 if "example.com".encode('hex') not in nai1:
216 raise Exception("Home realm not reported")
217 if "example.org".encode('hex') in nai1:
218 raise Exception("Non-home realm reported")
219 if "example.com".encode('hex') not in nai2:
220 raise Exception("Home realm not reported in wildcard query")
221 if "example.org".encode('hex') not in nai2:
222 raise Exception("Non-home realm not reported in wildcard query ")
224 def test_ap_interworking_scan_filtering(dev, apdev):
225 """Interworking scan filtering with HESSID and access network type"""
226 bssid = apdev[0]['bssid']
227 params = hs20_ap_params()
228 ssid = "test-hs20-ap1"
229 params['ssid'] = ssid
230 params['hessid'] = bssid
231 hostapd.add_ap(apdev[0]['ifname'], params)
233 bssid2 = apdev[1]['bssid']
234 params = hs20_ap_params()
235 ssid2 = "test-hs20-ap2"
236 params['ssid'] = ssid2
237 params['hessid'] = bssid2
238 params['access_network_type'] = "1"
239 del params['venue_group']
240 del params['venue_type']
241 hostapd.add_ap(apdev[1]['ifname'], params)
248 logger.info("Check probe request filtering based on HESSID")
250 dev[0].request("SET hessid " + bssid2)
251 dev[0].scan(freq="2412")
253 check_probe_resp(wt, bssid, bssid2)
255 logger.info("Check probe request filtering based on access network type")
257 wt.clear_bss_counters(bssid)
258 wt.clear_bss_counters(bssid2)
259 dev[0].request("SET hessid 00:00:00:00:00:00")
260 dev[0].request("SET access_network_type 14")
261 dev[0].scan(freq="2412")
263 check_probe_resp(wt, bssid2, bssid)
265 wt.clear_bss_counters(bssid)
266 wt.clear_bss_counters(bssid2)
267 dev[0].request("SET hessid 00:00:00:00:00:00")
268 dev[0].request("SET access_network_type 1")
269 dev[0].scan(freq="2412")
271 check_probe_resp(wt, bssid, bssid2)
273 logger.info("Check probe request filtering based on HESSID and ANT")
275 wt.clear_bss_counters(bssid)
276 wt.clear_bss_counters(bssid2)
277 dev[0].request("SET hessid " + bssid)
278 dev[0].request("SET access_network_type 14")
279 dev[0].scan(freq="2412")
281 check_probe_resp(wt, bssid2, bssid)
283 wt.clear_bss_counters(bssid)
284 wt.clear_bss_counters(bssid2)
285 dev[0].request("SET hessid " + bssid2)
286 dev[0].request("SET access_network_type 14")
287 dev[0].scan(freq="2412")
289 check_probe_resp(wt, bssid, None)
290 check_probe_resp(wt, bssid2, None)
292 wt.clear_bss_counters(bssid)
293 wt.clear_bss_counters(bssid2)
294 dev[0].request("SET hessid " + bssid)
295 dev[0].request("SET access_network_type 1")
296 dev[0].scan(freq="2412")
298 check_probe_resp(wt, bssid, None)
299 check_probe_resp(wt, bssid2, None)
301 def test_ap_hs20_select(dev, apdev):
302 """Hotspot 2.0 network selection"""
303 bssid = apdev[0]['bssid']
304 params = hs20_ap_params()
305 params['hessid'] = bssid
306 hostapd.add_ap(apdev[0]['ifname'], params)
309 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
310 'password': "secret",
311 'domain': "example.com" })
312 interworking_select(dev[0], bssid, "home")
314 dev[0].remove_cred(id)
315 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
316 'password': "secret",
317 'domain': "no.match.example.com" })
318 interworking_select(dev[0], bssid, "roaming", freq="2412")
320 dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
321 interworking_select(dev[0], bssid, no_match=True, freq="2412")
323 bssid2 = apdev[1]['bssid']
324 params = hs20_ap_params()
325 params['nai_realm'] = [ "0,example.org,21" ]
326 params['hessid'] = bssid2
327 params['domain_name'] = "example.org"
328 hostapd.add_ap(apdev[1]['ifname'], params)
329 dev[0].remove_cred(id)
330 id = dev[0].add_cred_values({ 'realm': "example.org", 'username': "test",
331 'password': "secret",
332 'domain': "example.org" })
333 interworking_select(dev[0], bssid2, "home", freq="2412")
335 def hs20_simulated_sim(dev, ap, method):
337 params = hs20_ap_params()
338 params['hessid'] = bssid
339 params['anqp_3gpp_cell_net'] = "555,444"
340 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
341 hostapd.add_ap(ap['ifname'], params)
344 dev.add_cred_values({ 'imsi': "555444-333222111", 'eap': method,
345 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
346 interworking_select(dev, "home", freq="2412")
347 interworking_connect(dev, bssid, method)
348 check_sp_type(dev, "home")
350 def test_ap_hs20_sim(dev, apdev):
351 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
352 if not hlr_auc_gw_available():
354 hs20_simulated_sim(dev[0], apdev[0], "SIM")
355 dev[0].request("INTERWORKING_SELECT auto freq=2412")
356 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
358 raise Exception("Timeout on already-connected event")
360 def test_ap_hs20_aka(dev, apdev):
361 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
362 if not hlr_auc_gw_available():
364 hs20_simulated_sim(dev[0], apdev[0], "AKA")
366 def test_ap_hs20_aka_prime(dev, apdev):
367 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
368 if not hlr_auc_gw_available():
370 hs20_simulated_sim(dev[0], apdev[0], "AKA'")
372 def test_ap_hs20_ext_sim(dev, apdev):
373 """Hotspot 2.0 with external SIM processing"""
374 if not hlr_auc_gw_available():
376 bssid = apdev[0]['bssid']
377 params = hs20_ap_params()
378 params['hessid'] = bssid
379 params['anqp_3gpp_cell_net'] = "232,01"
380 params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
381 hostapd.add_ap(apdev[0]['ifname'], params)
384 dev[0].request("SET external_sim 1")
385 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
386 interworking_select(dev[0], "home", freq="2412")
387 interworking_ext_sim_connect(dev[0], bssid, "SIM")
388 check_sp_type(dev[0], "home")
390 def test_ap_hs20_ext_sim_roaming(dev, apdev):
391 """Hotspot 2.0 with external SIM processing in roaming network"""
392 if not hlr_auc_gw_available():
394 bssid = apdev[0]['bssid']
395 params = hs20_ap_params()
396 params['hessid'] = bssid
397 params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
398 params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
399 hostapd.add_ap(apdev[0]['ifname'], params)
402 dev[0].request("SET external_sim 1")
403 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
404 interworking_select(dev[0], "roaming", freq="2412")
405 interworking_ext_sim_connect(dev[0], bssid, "SIM")
406 check_sp_type(dev[0], "roaming")
408 def test_ap_hs20_username(dev, apdev):
409 """Hotspot 2.0 connection in username/password credential"""
410 bssid = apdev[0]['bssid']
411 params = hs20_ap_params()
412 params['hessid'] = bssid
413 hostapd.add_ap(apdev[0]['ifname'], params)
416 id = dev[0].add_cred_values({ 'realm': "example.com",
417 'username': "hs20-test",
418 'password': "password",
419 'ca_cert': "auth_serv/ca.pem",
420 'domain': "example.com",
421 'update_identifier': "1234" })
422 interworking_select(dev[0], bssid, "home", freq="2412")
423 interworking_connect(dev[0], bssid, "TTLS")
424 check_sp_type(dev[0], "home")
425 status = dev[0].get_status()
426 if status['pairwise_cipher'] != "CCMP":
427 raise Exception("Unexpected pairwise cipher")
428 if status['hs20'] != "2":
429 raise Exception("Unexpected HS 2.0 support indication")
431 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS",
432 identity="hs20-test", password="password",
433 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
436 def eap_test(dev, ap, eap_params, method, user):
438 params = hs20_ap_params()
439 params['nai_realm'] = [ "0,example.com," + eap_params ]
440 hostapd.add_ap(ap['ifname'], params)
443 dev.add_cred_values({ 'realm': "example.com",
445 'password': "password" })
446 interworking_select(dev, bssid, freq="2412")
447 interworking_connect(dev, bssid, method)
449 def test_ap_hs20_eap_peap_mschapv2(dev, apdev):
450 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
451 eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user")
453 def test_ap_hs20_eap_peap_gtc(dev, apdev):
454 """Hotspot 2.0 connection with PEAP/GTC"""
455 eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user")
457 def test_ap_hs20_eap_ttls_chap(dev, apdev):
458 """Hotspot 2.0 connection with TTLS/CHAP"""
459 eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user")
461 def test_ap_hs20_eap_ttls_mschap(dev, apdev):
462 """Hotspot 2.0 connection with TTLS/MSCHAP"""
463 eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user")
465 def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev):
466 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
467 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
469 def test_ap_hs20_eap_fast_mschapv2(dev, apdev):
470 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
471 eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user")
473 def test_ap_hs20_eap_fast_gtc(dev, apdev):
474 """Hotspot 2.0 connection with FAST/EAP-GTC"""
475 eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user")
477 def test_ap_hs20_eap_tls(dev, apdev):
478 """Hotspot 2.0 connection with EAP-TLS"""
479 bssid = apdev[0]['bssid']
480 params = hs20_ap_params()
481 params['nai_realm'] = [ "0,example.com,13[5:6]" ]
482 hostapd.add_ap(apdev[0]['ifname'], params)
485 dev[0].add_cred_values({ 'realm': "example.com",
486 'username': "certificate-user",
487 'ca_cert': "auth_serv/ca.pem",
488 'client_cert': "auth_serv/user.pem",
489 'private_key': "auth_serv/user.key"})
490 interworking_select(dev[0], bssid, freq="2412")
491 interworking_connect(dev[0], bssid, "TLS")
493 def test_ap_hs20_nai_realms(dev, apdev):
494 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
495 bssid = apdev[0]['bssid']
496 params = hs20_ap_params()
497 params['hessid'] = bssid
498 params['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
499 hostapd.add_ap(apdev[0]['ifname'], params)
502 id = dev[0].add_cred_values({ 'realm': "example.com",
503 'username': "pap user",
504 'password': "password",
505 'domain': "example.com" })
506 interworking_select(dev[0], bssid, "home", freq="2412")
507 interworking_connect(dev[0], bssid, "TTLS")
508 check_sp_type(dev[0], "home")
510 def test_ap_hs20_roaming_consortium(dev, apdev):
511 """Hotspot 2.0 connection based on roaming consortium match"""
512 bssid = apdev[0]['bssid']
513 params = hs20_ap_params()
514 params['hessid'] = bssid
515 hostapd.add_ap(apdev[0]['ifname'], params)
518 id = dev[0].add_cred_values({ 'realm': "example.com",
520 'password': "password",
521 'domain': "example.com",
522 'roaming_consortium': "fedcba",
524 interworking_select(dev[0], bssid, "home", freq="2412")
525 interworking_connect(dev[0], bssid, "PEAP")
526 check_sp_type(dev[0], "home")
527 dev[0].request("INTERWORKING_SELECT auto freq=2412")
528 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
530 raise Exception("Timeout on already-connected event")
532 def test_ap_hs20_username_roaming(dev, apdev):
533 """Hotspot 2.0 connection in username/password credential (roaming)"""
534 bssid = apdev[0]['bssid']
535 params = hs20_ap_params()
536 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
537 "0,roaming.example.com,21[2:4][5:7]",
538 "0,another.example.com" ]
539 params['domain_name'] = "another.example.com"
540 params['hessid'] = bssid
541 hostapd.add_ap(apdev[0]['ifname'], params)
544 id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
545 'username': "hs20-test",
546 'password': "password",
547 'domain': "example.com" })
548 interworking_select(dev[0], bssid, "roaming", freq="2412")
549 interworking_connect(dev[0], bssid, "TTLS")
550 check_sp_type(dev[0], "roaming")
552 def test_ap_hs20_username_unknown(dev, apdev):
553 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
554 bssid = apdev[0]['bssid']
555 params = hs20_ap_params()
556 params['hessid'] = bssid
557 hostapd.add_ap(apdev[0]['ifname'], params)
560 id = dev[0].add_cred_values({ 'realm': "example.com",
561 'username': "hs20-test",
562 'password': "password" })
563 interworking_select(dev[0], bssid, "unknown", freq="2412")
564 interworking_connect(dev[0], bssid, "TTLS")
565 check_sp_type(dev[0], "unknown")
567 def test_ap_hs20_username_unknown2(dev, apdev):
568 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
569 bssid = apdev[0]['bssid']
570 params = hs20_ap_params()
571 params['hessid'] = bssid
572 del params['domain_name']
573 hostapd.add_ap(apdev[0]['ifname'], params)
576 id = dev[0].add_cred_values({ 'realm': "example.com",
577 'username': "hs20-test",
578 'password': "password",
579 'domain': "example.com" })
580 interworking_select(dev[0], bssid, "unknown", freq="2412")
581 interworking_connect(dev[0], bssid, "TTLS")
582 check_sp_type(dev[0], "unknown")
584 def test_ap_hs20_gas_while_associated(dev, apdev):
585 """Hotspot 2.0 connection with GAS query while associated"""
586 bssid = apdev[0]['bssid']
587 params = hs20_ap_params()
588 params['hessid'] = bssid
589 hostapd.add_ap(apdev[0]['ifname'], params)
592 id = dev[0].add_cred_values({ 'realm': "example.com",
593 'username': "hs20-test",
594 'password': "password",
595 'domain': "example.com" })
596 interworking_select(dev[0], bssid, "home", freq="2412")
597 interworking_connect(dev[0], bssid, "TTLS")
599 logger.info("Verifying GAS query while associated")
600 dev[0].request("FETCH_ANQP")
601 for i in range(0, 6):
602 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
604 raise Exception("Operation timed out")
606 def test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
607 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
608 bssid = apdev[0]['bssid']
609 params = hs20_ap_params()
610 params['hessid'] = bssid
611 hostapd.add_ap(apdev[0]['ifname'], params)
613 bssid2 = apdev[1]['bssid']
614 params = hs20_ap_params()
615 params['hessid'] = bssid2
616 params['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
617 hostapd.add_ap(apdev[1]['ifname'], params)
620 dev[0].request("SET pmf 2")
621 id = dev[0].add_cred_values({ 'realm': "example.com",
622 'username': "hs20-test",
623 'password': "password",
624 'domain': "example.com" })
625 interworking_select(dev[0], bssid, "home", freq="2412")
626 interworking_connect(dev[0], bssid, "TTLS")
628 logger.info("Verifying GAS query while associated")
629 dev[0].request("FETCH_ANQP")
630 for i in range(0, 2 * 6):
631 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
633 raise Exception("Operation timed out")
635 def test_ap_hs20_gas_frag_while_associated(dev, apdev):
636 """Hotspot 2.0 connection with fragmented GAS query while associated"""
637 bssid = apdev[0]['bssid']
638 params = hs20_ap_params()
639 params['hessid'] = bssid
640 hostapd.add_ap(apdev[0]['ifname'], params)
641 hapd = hostapd.Hostapd(apdev[0]['ifname'])
642 hapd.set("gas_frag_limit", "50")
645 id = dev[0].add_cred_values({ 'realm': "example.com",
646 'username': "hs20-test",
647 'password': "password",
648 'domain': "example.com" })
649 interworking_select(dev[0], bssid, "home", freq="2412")
650 interworking_connect(dev[0], bssid, "TTLS")
652 logger.info("Verifying GAS query while associated")
653 dev[0].request("FETCH_ANQP")
654 for i in range(0, 6):
655 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
657 raise Exception("Operation timed out")
659 def test_ap_hs20_multiple_connects(dev, apdev):
660 """Hotspot 2.0 connection through multiple network selections"""
661 bssid = apdev[0]['bssid']
662 params = hs20_ap_params()
663 params['hessid'] = bssid
664 hostapd.add_ap(apdev[0]['ifname'], params)
667 values = { 'realm': "example.com",
668 'username': "hs20-test",
669 'password': "password",
670 'domain': "example.com" }
671 id = dev[0].add_cred_values(values)
673 for i in range(0, 3):
674 logger.info("Starting Interworking network selection")
675 dev[0].request("INTERWORKING_SELECT auto freq=2412")
677 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
678 "INTERWORKING-ALREADY-CONNECTED",
679 "CTRL-EVENT-CONNECTED"], timeout=15)
681 raise Exception("Connection timed out")
682 if "INTERWORKING-NO-MATCH" in ev:
683 raise Exception("Matching AP not found")
684 if "CTRL-EVENT-CONNECTED" in ev:
686 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
689 dev[0].request("DISCONNECT")
690 dev[0].dump_monitor()
692 networks = dev[0].list_networks()
693 if len(networks) > 1:
694 raise Exception("Duplicated network block detected")
696 def test_ap_hs20_disallow_aps(dev, apdev):
697 """Hotspot 2.0 connection and disallow_aps"""
698 bssid = apdev[0]['bssid']
699 params = hs20_ap_params()
700 params['hessid'] = bssid
701 hostapd.add_ap(apdev[0]['ifname'], params)
704 values = { 'realm': "example.com",
705 'username': "hs20-test",
706 'password': "password",
707 'domain': "example.com" }
708 id = dev[0].add_cred_values(values)
710 logger.info("Verify disallow_aps bssid")
711 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
712 dev[0].request("INTERWORKING_SELECT auto")
713 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
715 raise Exception("Network selection timed out")
716 dev[0].dump_monitor()
718 logger.info("Verify disallow_aps ssid")
719 dev[0].request("SET disallow_aps ssid 746573742d68733230")
720 dev[0].request("INTERWORKING_SELECT auto freq=2412")
721 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
723 raise Exception("Network selection timed out")
724 dev[0].dump_monitor()
726 logger.info("Verify disallow_aps clear")
727 dev[0].request("SET disallow_aps ")
728 interworking_select(dev[0], bssid, "home", freq="2412")
730 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
731 ret = dev[0].request("INTERWORKING_CONNECT " + bssid)
732 if "FAIL" not in ret:
733 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
735 def policy_test(dev, ap, values, only_one=True):
738 logger.info("Verify network selection to AP " + ap['ifname'])
741 logger.info("Verify network selection")
744 id = dev.add_cred_values(values)
745 dev.request("INTERWORKING_SELECT auto freq=2412")
748 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
749 "INTERWORKING-BLACKLISTED",
750 "INTERWORKING-SELECTED"], timeout=15)
752 raise Exception("Network selection timed out")
754 if "INTERWORKING-NO-MATCH" in ev:
755 raise Exception("Matching AP not found")
756 if bssid and only_one and "INTERWORKING-AP" in ev and bssid not in ev:
757 raise Exception("Unexpected AP claimed acceptable")
758 if "INTERWORKING-SELECTED" in ev:
759 if bssid and bssid not in ev:
760 raise Exception("Selected incorrect BSS")
763 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
765 raise Exception("Connection timed out")
766 if bssid and bssid not in ev:
767 raise Exception("Connected to incorrect BSS")
769 conn_bssid = dev.get_status_field("bssid")
770 if bssid and conn_bssid != bssid:
771 raise Exception("bssid information points to incorrect BSS")
777 def default_cred(domain=None):
778 cred = { 'realm': "example.com",
779 'username': "hs20-test",
780 'password': "password" }
782 cred['domain'] = domain
785 def test_ap_hs20_prefer_home(dev, apdev):
786 """Hotspot 2.0 required roaming consortium"""
787 params = hs20_ap_params()
788 params['domain_name'] = "example.org"
789 hostapd.add_ap(apdev[0]['ifname'], params)
791 params = hs20_ap_params()
792 params['ssid'] = "test-hs20-other"
793 params['domain_name'] = "example.com"
794 hostapd.add_ap(apdev[1]['ifname'], params)
796 values = default_cred()
797 values['domain'] = "example.com"
798 policy_test(dev[0], apdev[1], values, only_one=False)
799 values['domain'] = "example.org"
800 policy_test(dev[0], apdev[0], values, only_one=False)
802 def test_ap_hs20_req_roaming_consortium(dev, apdev):
803 """Hotspot 2.0 required roaming consortium"""
804 params = hs20_ap_params()
805 hostapd.add_ap(apdev[0]['ifname'], params)
807 params = hs20_ap_params()
808 params['ssid'] = "test-hs20-other"
809 params['roaming_consortium'] = [ "223344" ]
810 hostapd.add_ap(apdev[1]['ifname'], params)
812 values = default_cred()
813 values['required_roaming_consortium'] = "223344"
814 policy_test(dev[0], apdev[1], values)
815 values['required_roaming_consortium'] = "112233"
816 policy_test(dev[0], apdev[0], values)
818 id = dev[0].add_cred()
819 dev[0].set_cred(id, "required_roaming_consortium", "112233")
820 dev[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
822 for val in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
823 if "FAIL" not in dev[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val)):
824 raise Exception("Invalid roaming consortium value accepted: " + val)
826 def test_ap_hs20_excluded_ssid(dev, apdev):
827 """Hotspot 2.0 exclusion based on SSID"""
828 params = hs20_ap_params()
829 params['roaming_consortium'] = [ "223344" ]
830 params['anqp_3gpp_cell_net'] = "555,444"
831 hostapd.add_ap(apdev[0]['ifname'], params)
833 params = hs20_ap_params()
834 params['ssid'] = "test-hs20-other"
835 params['roaming_consortium'] = [ "223344" ]
836 params['anqp_3gpp_cell_net'] = "555,444"
837 hostapd.add_ap(apdev[1]['ifname'], params)
839 values = default_cred()
840 values['excluded_ssid'] = "test-hs20"
841 events = policy_test(dev[0], apdev[1], values)
842 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
844 raise Exception("Excluded network not reported")
845 values['excluded_ssid'] = "test-hs20-other"
846 events = policy_test(dev[0], apdev[0], values)
847 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[1]['bssid'] in e]
849 raise Exception("Excluded network not reported")
851 values = default_cred()
852 values['roaming_consortium'] = "223344"
853 values['eap'] = "TTLS"
854 values['phase2'] = "auth=MSCHAPV2"
855 values['excluded_ssid'] = "test-hs20"
856 events = policy_test(dev[0], apdev[1], values)
857 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
859 raise Exception("Excluded network not reported")
861 values = { 'imsi': "555444-333222111", 'eap': "SIM",
862 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
863 'excluded_ssid': "test-hs20" }
864 events = policy_test(dev[0], apdev[1], values)
865 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
867 raise Exception("Excluded network not reported")
869 def test_ap_hs20_roam_to_higher_prio(dev, apdev):
870 """Hotspot 2.0 and roaming from current to higher priority network"""
871 bssid = apdev[0]['bssid']
872 params = hs20_ap_params(ssid="test-hs20-visited")
873 params['domain_name'] = "visited.example.org"
874 hostapd.add_ap(apdev[0]['ifname'], params)
877 id = dev[0].add_cred_values({ 'realm': "example.com",
878 'username': "hs20-test",
879 'password': "password",
880 'domain': "example.com" })
881 logger.info("Connect to the only network option")
882 interworking_select(dev[0], bssid, "roaming", freq="2412")
883 dev[0].dump_monitor()
884 interworking_connect(dev[0], bssid, "TTLS")
886 logger.info("Start another AP (home operator) and reconnect")
887 bssid2 = apdev[1]['bssid']
888 params = hs20_ap_params(ssid="test-hs20-home")
889 params['domain_name'] = "example.com"
890 hostapd.add_ap(apdev[1]['ifname'], params)
892 dev[0].request("INTERWORKING_SELECT auto freq=2412")
893 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
894 "INTERWORKING-ALREADY-CONNECTED",
895 "CTRL-EVENT-CONNECTED"], timeout=15)
897 raise Exception("Connection timed out")
898 if "INTERWORKING-NO-MATCH" in ev:
899 raise Exception("Matching AP not found")
900 if "INTERWORKING-ALREADY-CONNECTED" in ev:
901 raise Exception("Unexpected AP selected")
903 raise Exception("Unexpected BSSID after reconnection")
905 def test_ap_hs20_domain_suffix_match(dev, apdev):
906 """Hotspot 2.0 and domain_suffix_match"""
907 bssid = apdev[0]['bssid']
908 params = hs20_ap_params()
909 hostapd.add_ap(apdev[0]['ifname'], params)
912 id = dev[0].add_cred_values({ 'realm': "example.com",
913 'username': "hs20-test",
914 'password': "password",
915 'domain': "example.com",
916 'domain_suffix_match': "w1.fi" })
917 interworking_select(dev[0], bssid, "home", freq="2412")
918 dev[0].dump_monitor()
919 interworking_connect(dev[0], bssid, "TTLS")
920 dev[0].request("REMOVE_NETWORK all")
921 dev[0].dump_monitor()
923 dev[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
924 interworking_select(dev[0], bssid, "home", freq="2412")
925 dev[0].dump_monitor()
926 dev[0].request("INTERWORKING_CONNECT " + bssid)
927 ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
929 raise Exception("TLS certificate error not reported")
930 if "Domain suffix mismatch" not in ev:
931 raise Exception("Domain suffix mismatch not reported")
933 def test_ap_hs20_roaming_partner_preference(dev, apdev):
934 """Hotspot 2.0 and roaming partner preference"""
935 params = hs20_ap_params()
936 params['domain_name'] = "roaming.example.org"
937 hostapd.add_ap(apdev[0]['ifname'], params)
939 params = hs20_ap_params()
940 params['ssid'] = "test-hs20-other"
941 params['domain_name'] = "roaming.example.net"
942 hostapd.add_ap(apdev[1]['ifname'], params)
944 logger.info("Verify default vs. specified preference")
945 values = default_cred()
946 values['roaming_partner'] = "roaming.example.net,1,127,*"
947 policy_test(dev[0], apdev[1], values, only_one=False)
948 values['roaming_partner'] = "roaming.example.net,1,129,*"
949 policy_test(dev[0], apdev[0], values, only_one=False)
951 logger.info("Verify partial FQDN match")
952 values['roaming_partner'] = "example.net,0,0,*"
953 policy_test(dev[0], apdev[1], values, only_one=False)
954 values['roaming_partner'] = "example.net,0,255,*"
955 policy_test(dev[0], apdev[0], values, only_one=False)
957 def test_ap_hs20_max_bss_load(dev, apdev):
958 """Hotspot 2.0 and maximum BSS load"""
959 params = hs20_ap_params()
960 params['bss_load_test'] = "12:200:20000"
961 hostapd.add_ap(apdev[0]['ifname'], params)
963 params = hs20_ap_params()
964 params['ssid'] = "test-hs20-other"
965 params['bss_load_test'] = "5:20:10000"
966 hostapd.add_ap(apdev[1]['ifname'], params)
968 logger.info("Verify maximum BSS load constraint")
969 values = default_cred()
970 values['domain'] = "example.com"
971 values['max_bss_load'] = "100"
972 events = policy_test(dev[0], apdev[1], values, only_one=False)
974 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
975 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
976 raise Exception("Maximum BSS Load case not noticed")
977 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
978 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
979 raise Exception("Maximum BSS Load case reported incorrectly")
981 logger.info("Verify maximum BSS load does not prevent connection")
982 values['max_bss_load'] = "1"
983 events = policy_test(dev[0], None, values)
985 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
986 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
987 raise Exception("Maximum BSS Load case not noticed")
988 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
989 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
990 raise Exception("Maximum BSS Load case not noticed")
992 def test_ap_hs20_max_bss_load2(dev, apdev):
993 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
994 params = hs20_ap_params()
995 params['bss_load_test'] = "12:200:20000"
996 hostapd.add_ap(apdev[0]['ifname'], params)
998 params = hs20_ap_params()
999 params['ssid'] = "test-hs20-other"
1000 hostapd.add_ap(apdev[1]['ifname'], params)
1002 logger.info("Verify maximum BSS load constraint with AP advertisement")
1003 values = default_cred()
1004 values['domain'] = "example.com"
1005 values['max_bss_load'] = "100"
1006 events = policy_test(dev[0], apdev[1], values, only_one=False)
1008 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1009 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1010 raise Exception("Maximum BSS Load case not noticed")
1011 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1012 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1013 raise Exception("Maximum BSS Load case reported incorrectly")
1015 def test_ap_hs20_multi_cred_sp_prio(dev, apdev):
1016 """Hotspot 2.0 multi-cred sp_priority"""
1017 if not hlr_auc_gw_available():
1019 bssid = apdev[0]['bssid']
1020 params = hs20_ap_params()
1021 params['hessid'] = bssid
1022 del params['domain_name']
1023 params['anqp_3gpp_cell_net'] = "232,01"
1024 hostapd.add_ap(apdev[0]['ifname'], params)
1026 dev[0].hs20_enable()
1027 dev[0].request("SET external_sim 1")
1028 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1029 'provisioning_sp': "example.com",
1030 'sp_priority' :"1" })
1031 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1032 'username': "hs20-test",
1033 'password': "password",
1034 'domain': "example.com",
1035 'provisioning_sp': "example.com",
1036 'sp_priority': "2" })
1037 dev[0].dump_monitor()
1038 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1039 interworking_ext_sim_auth(dev[0], "SIM")
1040 check_sp_type(dev[0], "unknown")
1041 dev[0].request("REMOVE_NETWORK all")
1043 dev[0].set_cred(id1, "sp_priority", "2")
1044 dev[0].set_cred(id2, "sp_priority", "1")
1045 dev[0].dump_monitor()
1046 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1047 interworking_auth(dev[0], "TTLS")
1048 check_sp_type(dev[0], "unknown")
1050 def test_ap_hs20_multi_cred_sp_prio2(dev, apdev):
1051 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1052 if not hlr_auc_gw_available():
1054 bssid = apdev[0]['bssid']
1055 params = hs20_ap_params()
1056 params['hessid'] = bssid
1057 del params['nai_realm']
1058 del params['domain_name']
1059 params['anqp_3gpp_cell_net'] = "232,01"
1060 hostapd.add_ap(apdev[0]['ifname'], params)
1062 bssid2 = apdev[1]['bssid']
1063 params = hs20_ap_params()
1064 params['ssid'] = "test-hs20-other"
1065 params['hessid'] = bssid2
1066 del params['domain_name']
1067 del params['anqp_3gpp_cell_net']
1068 hostapd.add_ap(apdev[1]['ifname'], params)
1070 dev[0].hs20_enable()
1071 dev[0].request("SET external_sim 1")
1072 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1073 'provisioning_sp': "example.com",
1074 'sp_priority': "1" })
1075 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1076 'username': "hs20-test",
1077 'password': "password",
1078 'domain': "example.com",
1079 'provisioning_sp': "example.com",
1080 'sp_priority': "2" })
1081 dev[0].dump_monitor()
1082 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1083 interworking_ext_sim_auth(dev[0], "SIM")
1084 check_sp_type(dev[0], "unknown")
1085 conn_bssid = dev[0].get_status_field("bssid")
1086 if conn_bssid != bssid:
1087 raise Exception("Connected to incorrect BSS")
1088 dev[0].request("REMOVE_NETWORK all")
1090 dev[0].set_cred(id1, "sp_priority", "2")
1091 dev[0].set_cred(id2, "sp_priority", "1")
1092 dev[0].dump_monitor()
1093 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1094 interworking_auth(dev[0], "TTLS")
1095 check_sp_type(dev[0], "unknown")
1096 conn_bssid = dev[0].get_status_field("bssid")
1097 if conn_bssid != bssid2:
1098 raise Exception("Connected to incorrect BSS")
1100 def check_conn_capab_selection(dev, type, missing):
1101 dev.request("INTERWORKING_SELECT freq=2412")
1102 ev = dev.wait_event(["INTERWORKING-AP"])
1104 raise Exception("Network selection timed out");
1105 if "type=" + type not in ev:
1106 raise Exception("Unexpected network type")
1107 if missing and "conn_capab_missing=1" not in ev:
1108 raise Exception("conn_capab_missing not reported")
1109 if not missing and "conn_capab_missing=1" in ev:
1110 raise Exception("conn_capab_missing reported unexpectedly")
1112 def conn_capab_cred(domain=None, req_conn_capab=None):
1113 cred = default_cred(domain=domain)
1115 cred['req_conn_capab'] = req_conn_capab
1118 def test_ap_hs20_req_conn_capab(dev, apdev):
1119 """Hotspot 2.0 network selection with req_conn_capab"""
1120 bssid = apdev[0]['bssid']
1121 params = hs20_ap_params()
1122 hostapd.add_ap(apdev[0]['ifname'], params)
1124 dev[0].hs20_enable()
1125 logger.info("Not used in home network")
1126 values = conn_capab_cred(domain="example.com", req_conn_capab="6:1234")
1127 id = dev[0].add_cred_values(values)
1128 check_conn_capab_selection(dev[0], "home", False)
1130 logger.info("Used in roaming network")
1131 dev[0].remove_cred(id)
1132 values = conn_capab_cred(domain="example.org", req_conn_capab="6:1234")
1133 id = dev[0].add_cred_values(values)
1134 check_conn_capab_selection(dev[0], "roaming", True)
1136 logger.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1137 check_auto_select(dev[0], bssid)
1139 logger.info("Additional req_conn_capab checks")
1141 dev[0].remove_cred(id)
1142 values = conn_capab_cred(domain="example.org", req_conn_capab="1:0")
1143 id = dev[0].add_cred_values(values)
1144 check_conn_capab_selection(dev[0], "roaming", True)
1146 dev[0].remove_cred(id)
1147 values = conn_capab_cred(domain="example.org", req_conn_capab="17:5060")
1148 id = dev[0].add_cred_values(values)
1149 check_conn_capab_selection(dev[0], "roaming", True)
1151 bssid2 = apdev[1]['bssid']
1152 params = hs20_ap_params(ssid="test-hs20b")
1153 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1154 hostapd.add_ap(apdev[1]['ifname'], params)
1156 dev[0].remove_cred(id)
1157 values = conn_capab_cred(domain="example.org", req_conn_capab="50")
1158 id = dev[0].add_cred_values(values)
1159 dev[0].set_cred(id, "req_conn_capab", "6:22")
1160 dev[0].request("INTERWORKING_SELECT freq=2412")
1161 for i in range(0, 2):
1162 ev = dev[0].wait_event(["INTERWORKING-AP"])
1164 raise Exception("Network selection timed out");
1165 if bssid in ev and "conn_capab_missing=1" not in ev:
1166 raise Exception("Missing protocol connection capability not reported")
1167 if bssid2 in ev and "conn_capab_missing=1" in ev:
1168 raise Exception("Protocol connection capability not reported correctly")
1170 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev, apdev):
1171 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1172 bssid = apdev[0]['bssid']
1173 params = hs20_ap_params()
1174 params['domain_name'] = "roaming.example.org"
1175 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1176 hostapd.add_ap(apdev[0]['ifname'], params)
1178 bssid2 = apdev[1]['bssid']
1179 params = hs20_ap_params(ssid="test-hs20-b")
1180 params['domain_name'] = "roaming.example.net"
1181 hostapd.add_ap(apdev[1]['ifname'], params)
1183 values = default_cred()
1184 values['roaming_partner'] = "roaming.example.net,1,127,*"
1185 id = dev[0].add_cred_values(values)
1186 check_auto_select(dev[0], bssid2)
1188 dev[0].set_cred(id, "req_conn_capab", "50")
1189 check_auto_select(dev[0], bssid)
1191 dev[0].remove_cred(id)
1192 id = dev[0].add_cred_values(values)
1193 dev[0].set_cred(id, "req_conn_capab", "51")
1194 check_auto_select(dev[0], bssid2)
1196 def check_bandwidth_selection(dev, type, below):
1197 dev.request("INTERWORKING_SELECT freq=2412")
1198 ev = dev.wait_event(["INTERWORKING-AP"])
1200 raise Exception("Network selection timed out");
1201 if "type=" + type not in ev:
1202 raise Exception("Unexpected network type")
1203 if below and "below_min_backhaul=1" not in ev:
1204 raise Exception("below_min_backhaul not reported")
1205 if not below and "below_min_backhaul=1" in ev:
1206 raise Exception("below_min_backhaul reported unexpectedly")
1208 def bw_cred(domain=None, dl_home=None, ul_home=None, dl_roaming=None, ul_roaming=None):
1209 cred = default_cred(domain=domain)
1211 cred['min_dl_bandwidth_home'] = str(dl_home)
1213 cred['min_ul_bandwidth_home'] = str(ul_home)
1215 cred['min_dl_bandwidth_roaming'] = str(dl_roaming)
1217 cred['min_ul_bandwidth_roaming'] = str(ul_roaming)
1220 def test_ap_hs20_min_bandwidth_home(dev, apdev):
1221 """Hotspot 2.0 network selection with min bandwidth (home)"""
1222 bssid = apdev[0]['bssid']
1223 params = hs20_ap_params()
1224 hostapd.add_ap(apdev[0]['ifname'], params)
1226 dev[0].hs20_enable()
1227 values = bw_cred(domain="example.com", dl_home=5490, ul_home=58)
1228 id = dev[0].add_cred_values(values)
1229 check_bandwidth_selection(dev[0], "home", False)
1230 dev[0].remove_cred(id)
1232 values = bw_cred(domain="example.com", dl_home=5491, ul_home=58)
1233 id = dev[0].add_cred_values(values)
1234 check_bandwidth_selection(dev[0], "home", True)
1235 dev[0].remove_cred(id)
1237 values = bw_cred(domain="example.com", dl_home=5490, ul_home=59)
1238 id = dev[0].add_cred_values(values)
1239 check_bandwidth_selection(dev[0], "home", True)
1240 dev[0].remove_cred(id)
1242 values = bw_cred(domain="example.com", dl_home=5491, ul_home=59)
1243 id = dev[0].add_cred_values(values)
1244 check_bandwidth_selection(dev[0], "home", True)
1245 check_auto_select(dev[0], bssid)
1247 bssid2 = apdev[1]['bssid']
1248 params = hs20_ap_params(ssid="test-hs20-b")
1249 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1250 hostapd.add_ap(apdev[1]['ifname'], params)
1252 check_auto_select(dev[0], bssid2)
1254 def test_ap_hs20_min_bandwidth_roaming(dev, apdev):
1255 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1256 bssid = apdev[0]['bssid']
1257 params = hs20_ap_params()
1258 hostapd.add_ap(apdev[0]['ifname'], params)
1260 dev[0].hs20_enable()
1261 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=58)
1262 id = dev[0].add_cred_values(values)
1263 check_bandwidth_selection(dev[0], "roaming", False)
1264 dev[0].remove_cred(id)
1266 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=58)
1267 id = dev[0].add_cred_values(values)
1268 check_bandwidth_selection(dev[0], "roaming", True)
1269 dev[0].remove_cred(id)
1271 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=59)
1272 id = dev[0].add_cred_values(values)
1273 check_bandwidth_selection(dev[0], "roaming", True)
1274 dev[0].remove_cred(id)
1276 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=59)
1277 id = dev[0].add_cred_values(values)
1278 check_bandwidth_selection(dev[0], "roaming", True)
1279 check_auto_select(dev[0], bssid)
1281 bssid2 = apdev[1]['bssid']
1282 params = hs20_ap_params(ssid="test-hs20-b")
1283 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1284 hostapd.add_ap(apdev[1]['ifname'], params)
1286 check_auto_select(dev[0], bssid2)
1288 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev, apdev):
1289 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1290 bssid = apdev[0]['bssid']
1291 params = hs20_ap_params()
1292 params['domain_name'] = "roaming.example.org"
1293 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1294 hostapd.add_ap(apdev[0]['ifname'], params)
1296 bssid2 = apdev[1]['bssid']
1297 params = hs20_ap_params(ssid="test-hs20-b")
1298 params['domain_name'] = "roaming.example.net"
1299 hostapd.add_ap(apdev[1]['ifname'], params)
1301 values = default_cred()
1302 values['roaming_partner'] = "roaming.example.net,1,127,*"
1303 id = dev[0].add_cred_values(values)
1304 check_auto_select(dev[0], bssid2)
1306 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1307 check_auto_select(dev[0], bssid)
1309 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1310 check_auto_select(dev[0], bssid2)
1312 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev, apdev):
1313 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1314 bssid = apdev[0]['bssid']
1315 params = hs20_ap_params()
1316 del params['hs20_wan_metrics']
1317 hostapd.add_ap(apdev[0]['ifname'], params)
1319 dev[0].hs20_enable()
1320 values = bw_cred(domain="example.com", dl_home=10000, ul_home=10000,
1321 dl_roaming=10000, ul_roaming=10000)
1322 dev[0].add_cred_values(values)
1323 check_bandwidth_selection(dev[0], "home", False)
1325 def test_ap_hs20_deauth_req_ess(dev, apdev):
1326 """Hotspot 2.0 connection and deauthentication request for ESS"""
1327 dev[0].request("SET pmf 2")
1328 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1329 dev[0].dump_monitor()
1330 addr = dev[0].p2p_interface_addr()
1331 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1332 hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/")
1333 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1335 raise Exception("Timeout on deauth imminent notice")
1336 if "1 120 http://example.com/" not in ev:
1337 raise Exception("Unexpected deauth imminent notice: " + ev)
1338 hapd.request("DEAUTHENTICATE " + addr)
1339 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1341 raise Exception("Timeout on disconnection")
1342 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1343 raise Exception("Network not marked temporarily disabled")
1344 ev = dev[0].wait_event(["SME: Trying to authenticate",
1345 "Trying to associate",
1346 "CTRL-EVENT-CONNECTED"], timeout=5)
1348 raise Exception("Unexpected connection attempt")
1350 def test_ap_hs20_deauth_req_bss(dev, apdev):
1351 """Hotspot 2.0 connection and deauthentication request for BSS"""
1352 dev[0].request("SET pmf 2")
1353 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1354 dev[0].dump_monitor()
1355 addr = dev[0].p2p_interface_addr()
1356 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1357 hapd.request("HS20_DEAUTH_REQ " + addr + " 0 120 http://example.com/")
1358 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1360 raise Exception("Timeout on deauth imminent notice")
1361 if "0 120 http://example.com/" not in ev:
1362 raise Exception("Unexpected deauth imminent notice: " + ev)
1363 hapd.request("DEAUTHENTICATE " + addr + " reason=4")
1364 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1366 raise Exception("Timeout on disconnection")
1367 if "reason=4" not in ev:
1368 raise Exception("Unexpected disconnection reason")
1369 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1370 raise Exception("Network not marked temporarily disabled")
1371 ev = dev[0].wait_event(["SME: Trying to authenticate",
1372 "Trying to associate",
1373 "CTRL-EVENT-CONNECTED"], timeout=5)
1375 raise Exception("Unexpected connection attempt")
1377 def test_ap_hs20_osen(dev, apdev):
1378 """Hotspot 2.0 OSEN connection"""
1379 params = { 'ssid': "osen",
1381 'auth_server_addr': "127.0.0.1",
1382 'auth_server_port': "1812",
1383 'auth_server_shared_secret': "radius" }
1384 hostapd.add_ap(apdev[0]['ifname'], params)
1386 dev[0].connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1387 group="GTK_NOT_USED",
1388 eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1389 ca_cert="auth_serv/ca.pem",
1392 def test_ap_hs20_network_preference(dev, apdev):
1393 """Hotspot 2.0 network selection with preferred home network"""
1394 bssid = apdev[0]['bssid']
1395 params = hs20_ap_params()
1396 hostapd.add_ap(apdev[0]['ifname'], params)
1398 dev[0].hs20_enable()
1399 values = { 'realm': "example.com",
1400 'username': "hs20-test",
1401 'password': "password",
1402 'domain': "example.com" }
1403 dev[0].add_cred_values(values)
1405 id = dev[0].add_network()
1406 dev[0].set_network_quoted(id, "ssid", "home")
1407 dev[0].set_network_quoted(id, "psk", "12345678")
1408 dev[0].set_network(id, "priority", "1")
1409 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1411 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1412 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1414 raise Exception("Connection timed out")
1416 raise Exception("Unexpected network selected")
1418 bssid2 = apdev[1]['bssid']
1419 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1420 hostapd.add_ap(apdev[1]['ifname'], params)
1422 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1423 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1424 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1426 raise Exception("Connection timed out")
1427 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1428 raise Exception("No roam to higher priority network")
1429 if bssid2 not in ev:
1430 raise Exception("Unexpected network selected")
1432 def test_ap_hs20_network_preference2(dev, apdev):
1433 """Hotspot 2.0 network selection with preferred credential"""
1434 bssid2 = apdev[1]['bssid']
1435 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1436 hostapd.add_ap(apdev[1]['ifname'], params)
1438 dev[0].hs20_enable()
1439 values = { 'realm': "example.com",
1440 'username': "hs20-test",
1441 'password': "password",
1442 'domain': "example.com",
1444 dev[0].add_cred_values(values)
1446 id = dev[0].add_network()
1447 dev[0].set_network_quoted(id, "ssid", "home")
1448 dev[0].set_network_quoted(id, "psk", "12345678")
1449 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1451 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1452 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1454 raise Exception("Connection timed out")
1455 if bssid2 not in ev:
1456 raise Exception("Unexpected network selected")
1458 bssid = apdev[0]['bssid']
1459 params = hs20_ap_params()
1460 hostapd.add_ap(apdev[0]['ifname'], params)
1462 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1463 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1464 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1466 raise Exception("Connection timed out")
1467 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1468 raise Exception("No roam to higher priority network")
1470 raise Exception("Unexpected network selected")
1472 def test_ap_hs20_network_preference3(dev, apdev):
1473 """Hotspot 2.0 network selection with two credential (one preferred)"""
1474 bssid = apdev[0]['bssid']
1475 params = hs20_ap_params()
1476 hostapd.add_ap(apdev[0]['ifname'], params)
1478 bssid2 = apdev[1]['bssid']
1479 params = hs20_ap_params(ssid="test-hs20b")
1480 params['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
1481 hostapd.add_ap(apdev[1]['ifname'], params)
1483 dev[0].hs20_enable()
1484 values = { 'realm': "example.com",
1485 'username': "hs20-test",
1486 'password': "password",
1488 dev[0].add_cred_values(values)
1489 values = { 'realm': "example.org",
1490 'username': "hs20-test",
1491 'password': "password" }
1492 id = dev[0].add_cred_values(values)
1494 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1495 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1497 raise Exception("Connection timed out")
1499 raise Exception("Unexpected network selected")
1501 dev[0].set_cred(id, "priority", "2")
1502 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1503 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1504 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1506 raise Exception("Connection timed out")
1507 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1508 raise Exception("No roam to higher priority network")
1509 if bssid2 not in ev:
1510 raise Exception("Unexpected network selected")
1512 def test_ap_hs20_network_preference4(dev, apdev):
1513 """Hotspot 2.0 network selection with username vs. SIM credential"""
1514 bssid = apdev[0]['bssid']
1515 params = hs20_ap_params()
1516 hostapd.add_ap(apdev[0]['ifname'], params)
1518 bssid2 = apdev[1]['bssid']
1519 params = hs20_ap_params(ssid="test-hs20b")
1520 params['hessid'] = bssid2
1521 params['anqp_3gpp_cell_net'] = "555,444"
1522 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1523 hostapd.add_ap(apdev[1]['ifname'], params)
1525 dev[0].hs20_enable()
1526 values = { 'realm': "example.com",
1527 'username': "hs20-test",
1528 'password': "password",
1530 dev[0].add_cred_values(values)
1531 values = { 'imsi': "555444-333222111",
1533 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1534 id = dev[0].add_cred_values(values)
1536 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1537 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1539 raise Exception("Connection timed out")
1541 raise Exception("Unexpected network selected")
1543 dev[0].set_cred(id, "priority", "2")
1544 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1545 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1546 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1548 raise Exception("Connection timed out")
1549 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1550 raise Exception("No roam to higher priority network")
1551 if bssid2 not in ev:
1552 raise Exception("Unexpected network selected")