2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
12 logger = logging.getLogger()
19 from utils import HwsimSkip, skip_with_fips
21 from tshark import run_tshark
22 from wlantest import Wlantest
23 from wpasupplicant import WpaSupplicant
24 from test_ap_eap import check_eap_capa, check_domain_match_full
26 def hs20_ap_params(ssid="test-hs20"):
27 params = hostapd.wpa2_params(ssid=ssid)
28 params['wpa_key_mgmt'] = "WPA-EAP"
29 params['ieee80211w'] = "1"
30 params['ieee8021x'] = "1"
31 params['auth_server_addr'] = "127.0.0.1"
32 params['auth_server_port'] = "1812"
33 params['auth_server_shared_secret'] = "radius"
34 params['interworking'] = "1"
35 params['access_network_type'] = "14"
36 params['internet'] = "1"
40 params['venue_group'] = "7"
41 params['venue_type'] = "1"
42 params['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
43 params['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
45 params['domain_name'] = "example.com,another.example.com"
46 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
47 "0,another.example.com" ]
49 params['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
50 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
51 params['hs20_operating_class'] = "5173"
52 params['anqp_3gpp_cell_net'] = "244,91"
55 def check_auto_select(dev, bssid):
56 dev.scan_for_bss(bssid, freq="2412")
57 dev.request("INTERWORKING_SELECT auto freq=2412")
58 ev = dev.wait_connected(timeout=15)
60 raise Exception("Connected to incorrect network")
61 dev.request("REMOVE_NETWORK all")
62 dev.wait_disconnected()
65 def interworking_select(dev, bssid, type=None, no_match=False, freq=None):
67 if bssid and freq and not no_match:
68 dev.scan_for_bss(bssid, freq=freq)
69 freq_extra = " freq=" + str(freq) if freq else ""
70 dev.request("INTERWORKING_SELECT" + freq_extra)
71 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
74 raise Exception("Network selection timed out");
76 if "INTERWORKING-NO-MATCH" not in ev:
77 raise Exception("Unexpected network match")
79 if "INTERWORKING-NO-MATCH" in ev:
80 logger.info("Matching network not found - try again")
82 dev.request("INTERWORKING_SELECT" + freq_extra)
83 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
86 raise Exception("Network selection timed out");
87 if "INTERWORKING-NO-MATCH" in ev:
88 raise Exception("Matching network not found")
89 if bssid and bssid not in ev:
90 raise Exception("Unexpected BSSID in match")
91 if type and "type=" + type not in ev:
92 raise Exception("Network type not recognized correctly")
94 def check_sp_type(dev, sp_type):
95 type = dev.get_status_field("sp_type")
97 raise Exception("sp_type not available")
99 raise Exception("sp_type did not indicate home network")
101 def hlr_auc_gw_available():
102 if not os.path.exists("/tmp/hlr_auc_gw.sock"):
103 raise HwsimSkip("No hlr_auc_gw socket available")
104 if not os.path.exists("../../hostapd/hlr_auc_gw"):
105 raise HwsimSkip("No hlr_auc_gw available")
107 def interworking_ext_sim_connect(dev, bssid, method):
108 dev.request("INTERWORKING_CONNECT " + bssid)
109 interworking_ext_sim_auth(dev, method)
111 def interworking_ext_sim_auth(dev, method):
112 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
114 raise Exception("Network connected timed out")
115 if "(" + method + ")" not in ev:
116 raise Exception("Unexpected EAP method selection")
118 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
120 raise Exception("Wait for external SIM processing request timed out")
122 if p[1] != "GSM-AUTH":
123 raise Exception("Unexpected CTRL-REQ-SIM type")
124 id = p[0].split('-')[3]
125 rand = p[2].split(' ')[0]
127 res = subprocess.check_output(["../../hostapd/hlr_auc_gw",
129 "auth_serv/hlr_auc_gw.milenage_db",
130 "GSM-AUTH-REQ 232010000000000 " + rand])
131 if "GSM-AUTH-RESP" not in res:
132 raise Exception("Unexpected hlr_auc_gw response")
133 resp = res.split(' ')[2].rstrip()
135 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
136 dev.wait_connected(timeout=15)
138 def interworking_connect(dev, bssid, method):
139 dev.request("INTERWORKING_CONNECT " + bssid)
140 interworking_auth(dev, method)
142 def interworking_auth(dev, method):
143 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
145 raise Exception("Network connected timed out")
146 if "(" + method + ")" not in ev:
147 raise Exception("Unexpected EAP method selection")
149 dev.wait_connected(timeout=15)
151 def check_probe_resp(wt, bssid_unexpected, bssid_expected):
153 count = wt.get_bss_counter("probe_response", bssid_unexpected)
155 raise Exception("Unexpected Probe Response frame from AP")
158 count = wt.get_bss_counter("probe_response", bssid_expected)
160 raise Exception("No Probe Response frame from AP")
162 def test_ap_anqp_sharing(dev, apdev):
163 """ANQP sharing within ESS and explicit unshare"""
164 check_eap_capa(dev[0], "MSCHAPV2")
165 dev[0].flush_scan_cache()
167 bssid = apdev[0]['bssid']
168 params = hs20_ap_params()
169 params['hessid'] = bssid
170 hostapd.add_ap(apdev[0]['ifname'], params)
172 bssid2 = apdev[1]['bssid']
173 params = hs20_ap_params()
174 params['hessid'] = bssid
175 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
176 hostapd.add_ap(apdev[1]['ifname'], params)
179 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
180 'password': "secret",
181 'domain': "example.com" })
182 logger.info("Normal network selection with shared ANQP results")
183 dev[0].scan_for_bss(bssid, freq="2412")
184 dev[0].scan_for_bss(bssid2, freq="2412")
185 interworking_select(dev[0], None, "home", freq="2412")
186 dev[0].dump_monitor()
188 logger.debug("BSS entries:\n" + dev[0].request("BSS RANGE=ALL"))
189 res1 = dev[0].get_bss(bssid)
190 res2 = dev[0].get_bss(bssid2)
191 if 'anqp_nai_realm' not in res1:
192 raise Exception("anqp_nai_realm not found for AP1")
193 if 'anqp_nai_realm' not in res2:
194 raise Exception("anqp_nai_realm not found for AP2")
195 if res1['anqp_nai_realm'] != res2['anqp_nai_realm']:
196 raise Exception("ANQP results were not shared between BSSes")
198 logger.info("Explicit ANQP request to unshare ANQP results")
199 dev[0].request("ANQP_GET " + bssid + " 263")
200 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
202 raise Exception("ANQP operation timed out")
204 dev[0].request("ANQP_GET " + bssid2 + " 263")
205 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
207 raise Exception("ANQP operation timed out")
209 res1 = dev[0].get_bss(bssid)
210 res2 = dev[0].get_bss(bssid2)
211 if res1['anqp_nai_realm'] == res2['anqp_nai_realm']:
212 raise Exception("ANQP results were not unshared")
214 def test_ap_nai_home_realm_query(dev, apdev):
215 """NAI Home Realm Query"""
216 check_eap_capa(dev[0], "MSCHAPV2")
217 bssid = apdev[0]['bssid']
218 params = hs20_ap_params()
219 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
220 "0,another.example.org" ]
221 hostapd.add_ap(apdev[0]['ifname'], params)
223 dev[0].scan(freq="2412")
224 dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " realm=example.com")
225 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
227 raise Exception("ANQP operation timed out")
228 nai1 = dev[0].get_bss(bssid)['anqp_nai_realm']
229 dev[0].dump_monitor()
231 dev[0].request("ANQP_GET " + bssid + " 263")
232 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
234 raise Exception("ANQP operation timed out")
235 nai2 = dev[0].get_bss(bssid)['anqp_nai_realm']
237 if len(nai1) >= len(nai2):
238 raise Exception("Unexpected NAI Realm list response lengths")
239 if "example.com".encode('hex') not in nai1:
240 raise Exception("Home realm not reported")
241 if "example.org".encode('hex') in nai1:
242 raise Exception("Non-home realm reported")
243 if "example.com".encode('hex') not in nai2:
244 raise Exception("Home realm not reported in wildcard query")
245 if "example.org".encode('hex') not in nai2:
246 raise Exception("Non-home realm not reported in wildcard query ")
249 "00:11:22:33:44:55 123",
250 "00:11:22:33:44:55 qq" ]
252 if "FAIL" not in dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd):
253 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd)
255 dev[0].dump_monitor()
256 if "OK" not in dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid):
257 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
258 ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10)
260 raise Exception("ANQP operation timed out")
261 ev = dev[0].wait_event(["RX-ANQP"], timeout=0.1)
263 raise Exception("Unexpected ANQP response: " + ev)
265 dev[0].dump_monitor()
266 if "OK" not in dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " 01000b6578616d706c652e636f6d"):
267 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
268 ev = dev[0].wait_event(["RX-ANQP"], timeout=10)
270 raise Exception("No ANQP response")
271 if "NAI Realm list" not in ev:
272 raise Exception("Missing NAI Realm list: " + ev)
274 dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
275 'password': "secret",
276 'domain': "example.com" })
277 dev[0].dump_monitor()
278 if "OK" not in dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid):
279 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
280 ev = dev[0].wait_event(["RX-ANQP"], timeout=10)
282 raise Exception("No ANQP response")
283 if "NAI Realm list" not in ev:
284 raise Exception("Missing NAI Realm list: " + ev)
286 def test_ap_interworking_scan_filtering(dev, apdev):
287 """Interworking scan filtering with HESSID and access network type"""
289 _test_ap_interworking_scan_filtering(dev, apdev)
291 dev[0].request("SET hessid 00:00:00:00:00:00")
292 dev[0].request("SET access_network_type 15")
294 def _test_ap_interworking_scan_filtering(dev, apdev):
295 bssid = apdev[0]['bssid']
296 params = hs20_ap_params()
297 ssid = "test-hs20-ap1"
298 params['ssid'] = ssid
299 params['hessid'] = bssid
300 hostapd.add_ap(apdev[0]['ifname'], params)
302 bssid2 = apdev[1]['bssid']
303 params = hs20_ap_params()
304 ssid2 = "test-hs20-ap2"
305 params['ssid'] = ssid2
306 params['hessid'] = bssid2
307 params['access_network_type'] = "1"
308 del params['venue_group']
309 del params['venue_type']
310 hostapd.add_ap(apdev[1]['ifname'], params)
317 logger.info("Check probe request filtering based on HESSID")
319 dev[0].request("SET hessid " + bssid2)
320 dev[0].scan(freq="2412")
322 check_probe_resp(wt, bssid, bssid2)
324 logger.info("Check probe request filtering based on access network type")
326 wt.clear_bss_counters(bssid)
327 wt.clear_bss_counters(bssid2)
328 dev[0].request("SET hessid 00:00:00:00:00:00")
329 dev[0].request("SET access_network_type 14")
330 dev[0].scan(freq="2412")
332 check_probe_resp(wt, bssid2, bssid)
334 wt.clear_bss_counters(bssid)
335 wt.clear_bss_counters(bssid2)
336 dev[0].request("SET hessid 00:00:00:00:00:00")
337 dev[0].request("SET access_network_type 1")
338 dev[0].scan(freq="2412")
340 check_probe_resp(wt, bssid, bssid2)
342 logger.info("Check probe request filtering based on HESSID and ANT")
344 wt.clear_bss_counters(bssid)
345 wt.clear_bss_counters(bssid2)
346 dev[0].request("SET hessid " + bssid)
347 dev[0].request("SET access_network_type 14")
348 dev[0].scan(freq="2412")
350 check_probe_resp(wt, bssid2, bssid)
352 wt.clear_bss_counters(bssid)
353 wt.clear_bss_counters(bssid2)
354 dev[0].request("SET hessid " + bssid2)
355 dev[0].request("SET access_network_type 14")
356 dev[0].scan(freq="2412")
358 check_probe_resp(wt, bssid, None)
359 check_probe_resp(wt, bssid2, None)
361 wt.clear_bss_counters(bssid)
362 wt.clear_bss_counters(bssid2)
363 dev[0].request("SET hessid " + bssid)
364 dev[0].request("SET access_network_type 1")
365 dev[0].scan(freq="2412")
367 check_probe_resp(wt, bssid, None)
368 check_probe_resp(wt, bssid2, None)
370 def test_ap_hs20_select(dev, apdev):
371 """Hotspot 2.0 network selection"""
372 bssid = apdev[0]['bssid']
373 params = hs20_ap_params()
374 params['hessid'] = bssid
375 hostapd.add_ap(apdev[0]['ifname'], params)
378 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
379 'password': "secret",
380 'domain': "example.com" })
381 interworking_select(dev[0], bssid, "home")
383 dev[0].remove_cred(id)
384 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
385 'password': "secret",
386 'domain': "no.match.example.com" })
387 interworking_select(dev[0], bssid, "roaming", freq="2412")
389 dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
390 interworking_select(dev[0], bssid, no_match=True, freq="2412")
392 res = dev[0].request("SCAN_RESULTS")
393 if "[HS20]" not in res:
394 raise Exception("HS20 flag missing from scan results: " + res)
396 bssid2 = apdev[1]['bssid']
397 params = hs20_ap_params()
398 params['nai_realm'] = [ "0,example.org,21" ]
399 params['hessid'] = bssid2
400 params['domain_name'] = "example.org"
401 hostapd.add_ap(apdev[1]['ifname'], params)
402 dev[0].remove_cred(id)
403 id = dev[0].add_cred_values({ 'realm': "example.org", 'username': "test",
404 'password': "secret",
405 'domain': "example.org" })
406 interworking_select(dev[0], bssid2, "home", freq="2412")
408 def hs20_simulated_sim(dev, ap, method):
410 params = hs20_ap_params()
411 params['hessid'] = bssid
412 params['anqp_3gpp_cell_net'] = "555,444"
413 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
414 hostapd.add_ap(ap['ifname'], params)
417 dev.add_cred_values({ 'imsi': "555444-333222111", 'eap': method,
418 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
419 interworking_select(dev, "home", freq="2412")
420 interworking_connect(dev, bssid, method)
421 check_sp_type(dev, "home")
423 def test_ap_hs20_sim(dev, apdev):
424 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
425 hlr_auc_gw_available()
426 hs20_simulated_sim(dev[0], apdev[0], "SIM")
427 dev[0].request("INTERWORKING_SELECT auto freq=2412")
428 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
430 raise Exception("Timeout on already-connected event")
432 def test_ap_hs20_aka(dev, apdev):
433 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
434 hlr_auc_gw_available()
435 hs20_simulated_sim(dev[0], apdev[0], "AKA")
437 def test_ap_hs20_aka_prime(dev, apdev):
438 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
439 hlr_auc_gw_available()
440 hs20_simulated_sim(dev[0], apdev[0], "AKA'")
442 def test_ap_hs20_ext_sim(dev, apdev):
443 """Hotspot 2.0 with external SIM processing"""
444 hlr_auc_gw_available()
445 bssid = apdev[0]['bssid']
446 params = hs20_ap_params()
447 params['hessid'] = bssid
448 params['anqp_3gpp_cell_net'] = "232,01"
449 params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
450 hostapd.add_ap(apdev[0]['ifname'], params)
454 dev[0].request("SET external_sim 1")
455 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
456 interworking_select(dev[0], "home", freq="2412")
457 interworking_ext_sim_connect(dev[0], bssid, "SIM")
458 check_sp_type(dev[0], "home")
460 dev[0].request("SET external_sim 0")
462 def test_ap_hs20_ext_sim_roaming(dev, apdev):
463 """Hotspot 2.0 with external SIM processing in roaming network"""
464 hlr_auc_gw_available()
465 bssid = apdev[0]['bssid']
466 params = hs20_ap_params()
467 params['hessid'] = bssid
468 params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
469 params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
470 hostapd.add_ap(apdev[0]['ifname'], params)
474 dev[0].request("SET external_sim 1")
475 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
476 interworking_select(dev[0], "roaming", freq="2412")
477 interworking_ext_sim_connect(dev[0], bssid, "SIM")
478 check_sp_type(dev[0], "roaming")
480 dev[0].request("SET external_sim 0")
482 def test_ap_hs20_username(dev, apdev):
483 """Hotspot 2.0 connection in username/password credential"""
484 check_eap_capa(dev[0], "MSCHAPV2")
485 bssid = apdev[0]['bssid']
486 params = hs20_ap_params()
487 params['hessid'] = bssid
488 params['disable_dgaf'] = '1'
489 hostapd.add_ap(apdev[0]['ifname'], params)
492 id = dev[0].add_cred_values({ 'realm': "example.com",
493 'username': "hs20-test",
494 'password': "password",
495 'ca_cert': "auth_serv/ca.pem",
496 'domain': "example.com",
497 'update_identifier': "1234" })
498 interworking_select(dev[0], bssid, "home", freq="2412")
499 interworking_connect(dev[0], bssid, "TTLS")
500 check_sp_type(dev[0], "home")
501 status = dev[0].get_status()
502 if status['pairwise_cipher'] != "CCMP":
503 raise Exception("Unexpected pairwise cipher")
504 if status['hs20'] != "2":
505 raise Exception("Unexpected HS 2.0 support indication")
507 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS",
508 identity="hs20-test", password="password",
509 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
512 def test_ap_hs20_connect_api(dev, apdev):
513 """Hotspot 2.0 connection with connect API"""
514 check_eap_capa(dev[0], "MSCHAPV2")
515 bssid = apdev[0]['bssid']
516 params = hs20_ap_params()
517 params['hessid'] = bssid
518 params['disable_dgaf'] = '1'
519 hostapd.add_ap(apdev[0]['ifname'], params)
521 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
522 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
524 wpas.flush_scan_cache()
525 id = wpas.add_cred_values({ 'realm': "example.com",
526 'username': "hs20-test",
527 'password': "password",
528 'ca_cert': "auth_serv/ca.pem",
529 'domain': "example.com",
530 'update_identifier': "1234" })
531 interworking_select(wpas, bssid, "home", freq="2412")
532 interworking_connect(wpas, bssid, "TTLS")
533 check_sp_type(wpas, "home")
534 status = wpas.get_status()
535 if status['pairwise_cipher'] != "CCMP":
536 raise Exception("Unexpected pairwise cipher")
537 if status['hs20'] != "2":
538 raise Exception("Unexpected HS 2.0 support indication")
540 def test_ap_hs20_auto_interworking(dev, apdev):
541 """Hotspot 2.0 connection with auto_interworking=1"""
542 check_eap_capa(dev[0], "MSCHAPV2")
543 bssid = apdev[0]['bssid']
544 params = hs20_ap_params()
545 params['hessid'] = bssid
546 params['disable_dgaf'] = '1'
547 hostapd.add_ap(apdev[0]['ifname'], params)
549 dev[0].hs20_enable(auto_interworking=True)
550 id = dev[0].add_cred_values({ 'realm': "example.com",
551 'username': "hs20-test",
552 'password': "password",
553 'ca_cert': "auth_serv/ca.pem",
554 'domain': "example.com",
555 'update_identifier': "1234" })
556 dev[0].request("REASSOCIATE")
557 dev[0].wait_connected(timeout=15)
558 check_sp_type(dev[0], "home")
559 status = dev[0].get_status()
560 if status['pairwise_cipher'] != "CCMP":
561 raise Exception("Unexpected pairwise cipher")
562 if status['hs20'] != "2":
563 raise Exception("Unexpected HS 2.0 support indication")
565 def test_ap_hs20_auto_interworking_no_match(dev, apdev):
566 """Hotspot 2.0 connection with auto_interworking=1 and no matching network"""
567 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "mismatch" })
569 dev[0].hs20_enable(auto_interworking=True)
570 id = dev[0].connect("mismatch", psk="12345678", scan_freq="2412",
571 only_add_network=True)
572 dev[0].request("ENABLE_NETWORK " + str(id) + " no-connect")
574 id = dev[0].add_cred_values({ 'realm': "example.com",
575 'username': "hs20-test",
576 'password': "password",
577 'ca_cert': "auth_serv/ca.pem",
578 'domain': "example.com",
579 'update_identifier': "1234" })
580 dev[0].request("INTERWORKING_SELECT auto freq=2412")
582 dev[0].dump_monitor()
584 logger.info("start ping")
585 if "PONG" not in dev[0].ctrl.request("PING", timeout=2):
586 raise Exception("PING failed")
587 logger.info("ping done")
591 ev = dev[0].wait_event([ "ANQP fetch completed",
592 "CTRL-EVENT-SCAN-RESULTS" ], timeout=0.05)
595 if "ANQP fetch completed" in ev:
599 if fetch > 2 * scan + 3:
600 raise Exception("Too many ANQP fetch iterations")
601 dev[0].dump_monitor()
602 dev[0].request("DISCONNECT")
604 def test_ap_hs20_auto_interworking_no_cred_match(dev, apdev):
605 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
606 bssid = apdev[0]['bssid']
607 params = { "ssid": "test" }
608 hostapd.add_ap(apdev[0]['ifname'], params)
610 dev[0].hs20_enable(auto_interworking=True)
611 dev[0].add_cred_values({ 'realm': "example.com",
612 'username': "hs20-test",
613 'password': "password",
614 'ca_cert': "auth_serv/ca.pem",
615 'domain': "example.com" })
617 id = dev[0].connect("test", psk="12345678", only_add_network=True)
618 dev[0].request("ENABLE_NETWORK %s" % id)
619 logger.info("Verify that scanning continues when there is partial network block match")
620 for i in range(0, 2):
621 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
623 raise Exception("Scan timed out")
624 logger.info("Scan completed")
626 def eap_test(dev, ap, eap_params, method, user):
628 params = hs20_ap_params()
629 params['nai_realm'] = [ "0,example.com," + eap_params ]
630 hostapd.add_ap(ap['ifname'], params)
633 dev.add_cred_values({ 'realm': "example.com",
634 'ca_cert': "auth_serv/ca.pem",
636 'password': "password" })
637 interworking_select(dev, bssid, freq="2412")
638 interworking_connect(dev, bssid, method)
640 def test_ap_hs20_eap_unknown(dev, apdev):
641 """Hotspot 2.0 connection with unknown EAP method"""
642 bssid = apdev[0]['bssid']
643 params = hs20_ap_params()
644 params['nai_realm'] = "0,example.com,99"
645 hostapd.add_ap(apdev[0]['ifname'], params)
648 dev[0].add_cred_values(default_cred())
649 interworking_select(dev[0], None, no_match=True, freq="2412")
651 def test_ap_hs20_eap_peap_mschapv2(dev, apdev):
652 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
653 check_eap_capa(dev[0], "MSCHAPV2")
654 eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user")
656 def test_ap_hs20_eap_peap_default(dev, apdev):
657 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
658 check_eap_capa(dev[0], "MSCHAPV2")
659 eap_test(dev[0], apdev[0], "25", "PEAP", "user")
661 def test_ap_hs20_eap_peap_gtc(dev, apdev):
662 """Hotspot 2.0 connection with PEAP/GTC"""
663 eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user")
665 def test_ap_hs20_eap_peap_unknown(dev, apdev):
666 """Hotspot 2.0 connection with PEAP/unknown"""
667 bssid = apdev[0]['bssid']
668 params = hs20_ap_params()
669 params['nai_realm'] = "0,example.com,25[3:99]"
670 hostapd.add_ap(apdev[0]['ifname'], params)
673 dev[0].add_cred_values(default_cred())
674 interworking_select(dev[0], None, no_match=True, freq="2412")
676 def test_ap_hs20_eap_ttls_chap(dev, apdev):
677 """Hotspot 2.0 connection with TTLS/CHAP"""
678 skip_with_fips(dev[0])
679 eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user")
681 def test_ap_hs20_eap_ttls_mschap(dev, apdev):
682 """Hotspot 2.0 connection with TTLS/MSCHAP"""
683 skip_with_fips(dev[0])
684 eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user")
686 def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev):
687 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
688 check_eap_capa(dev[0], "MSCHAPV2")
689 eap_test(dev[0], apdev[0], "21[3:26][6:7][99:99]", "TTLS", "user")
691 def test_ap_hs20_eap_ttls_eap_unknown(dev, apdev):
692 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
693 bssid = apdev[0]['bssid']
694 params = hs20_ap_params()
695 params['nai_realm'] = "0,example.com,21[3:99]"
696 hostapd.add_ap(apdev[0]['ifname'], params)
699 dev[0].add_cred_values(default_cred())
700 interworking_select(dev[0], None, no_match=True, freq="2412")
702 def test_ap_hs20_eap_ttls_eap_unsupported(dev, apdev):
703 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
704 bssid = apdev[0]['bssid']
705 params = hs20_ap_params()
706 params['nai_realm'] = "0,example.com,21[3:5]"
707 hostapd.add_ap(apdev[0]['ifname'], params)
710 dev[0].add_cred_values(default_cred())
711 interworking_select(dev[0], None, no_match=True, freq="2412")
713 def test_ap_hs20_eap_ttls_unknown(dev, apdev):
714 """Hotspot 2.0 connection with TTLS/unknown"""
715 bssid = apdev[0]['bssid']
716 params = hs20_ap_params()
717 params['nai_realm'] = "0,example.com,21[2:5]"
718 hostapd.add_ap(apdev[0]['ifname'], params)
721 dev[0].add_cred_values(default_cred())
722 interworking_select(dev[0], None, no_match=True, freq="2412")
724 def test_ap_hs20_eap_fast_mschapv2(dev, apdev):
725 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
726 check_eap_capa(dev[0], "FAST")
727 eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user")
729 def test_ap_hs20_eap_fast_gtc(dev, apdev):
730 """Hotspot 2.0 connection with FAST/EAP-GTC"""
731 check_eap_capa(dev[0], "FAST")
732 eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user")
734 def test_ap_hs20_eap_tls(dev, apdev):
735 """Hotspot 2.0 connection with EAP-TLS"""
736 bssid = apdev[0]['bssid']
737 params = hs20_ap_params()
738 params['nai_realm'] = [ "0,example.com,13[5:6]" ]
739 hostapd.add_ap(apdev[0]['ifname'], params)
742 dev[0].add_cred_values({ 'realm': "example.com",
743 'username': "certificate-user",
744 'ca_cert': "auth_serv/ca.pem",
745 'client_cert': "auth_serv/user.pem",
746 'private_key': "auth_serv/user.key"})
747 interworking_select(dev[0], bssid, freq="2412")
748 interworking_connect(dev[0], bssid, "TLS")
750 def test_ap_hs20_eap_cert_unknown(dev, apdev):
751 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
752 bssid = apdev[0]['bssid']
753 params = hs20_ap_params()
754 params['nai_realm'] = [ "0,example.com,99[5:6]" ]
755 hostapd.add_ap(apdev[0]['ifname'], params)
758 dev[0].add_cred_values({ 'realm': "example.com",
759 'username': "certificate-user",
760 'ca_cert': "auth_serv/ca.pem",
761 'client_cert': "auth_serv/user.pem",
762 'private_key': "auth_serv/user.key"})
763 interworking_select(dev[0], None, no_match=True, freq="2412")
765 def test_ap_hs20_eap_cert_unsupported(dev, apdev):
766 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
767 bssid = apdev[0]['bssid']
768 params = hs20_ap_params()
769 params['nai_realm'] = [ "0,example.com,21[5:6]" ]
770 hostapd.add_ap(apdev[0]['ifname'], params)
773 dev[0].add_cred_values({ 'realm': "example.com",
774 'username': "certificate-user",
775 'ca_cert': "auth_serv/ca.pem",
776 'client_cert': "auth_serv/user.pem",
777 'private_key': "auth_serv/user.key"})
778 interworking_select(dev[0], None, no_match=True, freq="2412")
780 def test_ap_hs20_eap_invalid_cred(dev, apdev):
781 """Hotspot 2.0 connection with invalid cred configuration"""
782 bssid = apdev[0]['bssid']
783 params = hs20_ap_params()
784 hostapd.add_ap(apdev[0]['ifname'], params)
787 dev[0].add_cred_values({ 'realm': "example.com",
788 'username': "certificate-user",
789 'client_cert': "auth_serv/user.pem" })
790 interworking_select(dev[0], None, no_match=True, freq="2412")
792 def test_ap_hs20_nai_realms(dev, apdev):
793 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
794 bssid = apdev[0]['bssid']
795 params = hs20_ap_params()
796 params['hessid'] = bssid
797 params['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
798 hostapd.add_ap(apdev[0]['ifname'], params)
801 id = dev[0].add_cred_values({ 'realm': "example.com",
802 'ca_cert': "auth_serv/ca.pem",
803 'username': "pap user",
804 'password': "password",
805 'domain': "example.com" })
806 interworking_select(dev[0], bssid, "home", freq="2412")
807 interworking_connect(dev[0], bssid, "TTLS")
808 check_sp_type(dev[0], "home")
810 def test_ap_hs20_roaming_consortium(dev, apdev):
811 """Hotspot 2.0 connection based on roaming consortium match"""
812 bssid = apdev[0]['bssid']
813 params = hs20_ap_params()
814 params['hessid'] = bssid
815 hostapd.add_ap(apdev[0]['ifname'], params)
818 for consortium in [ "112233", "1020304050", "010203040506", "fedcba" ]:
819 id = dev[0].add_cred_values({ 'username': "user",
820 'password': "password",
821 'domain': "example.com",
822 'ca_cert': "auth_serv/ca.pem",
823 'roaming_consortium': consortium,
825 interworking_select(dev[0], bssid, "home", freq="2412")
826 interworking_connect(dev[0], bssid, "PEAP")
827 check_sp_type(dev[0], "home")
828 dev[0].request("INTERWORKING_SELECT auto freq=2412")
829 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
831 raise Exception("Timeout on already-connected event")
832 dev[0].remove_cred(id)
834 def test_ap_hs20_username_roaming(dev, apdev):
835 """Hotspot 2.0 connection in username/password credential (roaming)"""
836 check_eap_capa(dev[0], "MSCHAPV2")
837 bssid = apdev[0]['bssid']
838 params = hs20_ap_params()
839 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
840 "0,roaming.example.com,21[2:4][5:7]",
841 "0,another.example.com" ]
842 params['domain_name'] = "another.example.com"
843 params['hessid'] = bssid
844 hostapd.add_ap(apdev[0]['ifname'], params)
847 id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
848 'username': "hs20-test",
849 'password': "password",
850 'ca_cert': "auth_serv/ca.pem",
851 'domain': "example.com" })
852 interworking_select(dev[0], bssid, "roaming", freq="2412")
853 interworking_connect(dev[0], bssid, "TTLS")
854 check_sp_type(dev[0], "roaming")
856 def test_ap_hs20_username_unknown(dev, apdev):
857 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
858 check_eap_capa(dev[0], "MSCHAPV2")
859 bssid = apdev[0]['bssid']
860 params = hs20_ap_params()
861 params['hessid'] = bssid
862 hostapd.add_ap(apdev[0]['ifname'], params)
865 id = dev[0].add_cred_values({ 'realm': "example.com",
866 'ca_cert': "auth_serv/ca.pem",
867 'username': "hs20-test",
868 'password': "password" })
869 interworking_select(dev[0], bssid, "unknown", freq="2412")
870 interworking_connect(dev[0], bssid, "TTLS")
871 check_sp_type(dev[0], "unknown")
873 def test_ap_hs20_username_unknown2(dev, apdev):
874 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
875 check_eap_capa(dev[0], "MSCHAPV2")
876 bssid = apdev[0]['bssid']
877 params = hs20_ap_params()
878 params['hessid'] = bssid
879 del params['domain_name']
880 hostapd.add_ap(apdev[0]['ifname'], params)
883 id = dev[0].add_cred_values({ 'realm': "example.com",
884 'ca_cert': "auth_serv/ca.pem",
885 'username': "hs20-test",
886 'password': "password",
887 'domain': "example.com" })
888 interworking_select(dev[0], bssid, "unknown", freq="2412")
889 interworking_connect(dev[0], bssid, "TTLS")
890 check_sp_type(dev[0], "unknown")
892 def test_ap_hs20_gas_while_associated(dev, apdev):
893 """Hotspot 2.0 connection with GAS query while associated"""
894 check_eap_capa(dev[0], "MSCHAPV2")
895 bssid = apdev[0]['bssid']
896 params = hs20_ap_params()
897 params['hessid'] = bssid
898 hostapd.add_ap(apdev[0]['ifname'], params)
901 id = dev[0].add_cred_values({ 'realm': "example.com",
902 'ca_cert': "auth_serv/ca.pem",
903 'username': "hs20-test",
904 'password': "password",
905 'domain': "example.com" })
906 interworking_select(dev[0], bssid, "home", freq="2412")
907 interworking_connect(dev[0], bssid, "TTLS")
909 logger.info("Verifying GAS query while associated")
910 dev[0].request("FETCH_ANQP")
911 for i in range(0, 6):
912 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
914 raise Exception("Operation timed out")
916 def test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
917 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
918 check_eap_capa(dev[0], "MSCHAPV2")
920 _test_ap_hs20_gas_while_associated_with_pmf(dev, apdev)
922 dev[0].request("SET pmf 0")
924 def _test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
925 bssid = apdev[0]['bssid']
926 params = hs20_ap_params()
927 params['hessid'] = bssid
928 hostapd.add_ap(apdev[0]['ifname'], params)
930 bssid2 = apdev[1]['bssid']
931 params = hs20_ap_params()
932 params['hessid'] = bssid2
933 params['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
934 hostapd.add_ap(apdev[1]['ifname'], params)
937 dev[0].request("SET pmf 2")
938 id = dev[0].add_cred_values({ 'realm': "example.com",
939 'ca_cert': "auth_serv/ca.pem",
940 'username': "hs20-test",
941 'password': "password",
942 'domain': "example.com" })
943 interworking_select(dev[0], bssid, "home", freq="2412")
944 interworking_connect(dev[0], bssid, "TTLS")
946 logger.info("Verifying GAS query while associated")
947 dev[0].request("FETCH_ANQP")
948 for i in range(0, 2 * 6):
949 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
951 raise Exception("Operation timed out")
953 def test_ap_hs20_gas_frag_while_associated(dev, apdev):
954 """Hotspot 2.0 connection with fragmented GAS query while associated"""
955 check_eap_capa(dev[0], "MSCHAPV2")
956 bssid = apdev[0]['bssid']
957 params = hs20_ap_params()
958 params['hessid'] = bssid
959 hostapd.add_ap(apdev[0]['ifname'], params)
960 hapd = hostapd.Hostapd(apdev[0]['ifname'])
961 hapd.set("gas_frag_limit", "50")
964 id = dev[0].add_cred_values({ 'realm': "example.com",
965 'ca_cert': "auth_serv/ca.pem",
966 'username': "hs20-test",
967 'password': "password",
968 'domain': "example.com" })
969 interworking_select(dev[0], bssid, "home", freq="2412")
970 interworking_connect(dev[0], bssid, "TTLS")
972 logger.info("Verifying GAS query while associated")
973 dev[0].request("FETCH_ANQP")
974 for i in range(0, 6):
975 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
977 raise Exception("Operation timed out")
979 def test_ap_hs20_multiple_connects(dev, apdev):
980 """Hotspot 2.0 connection through multiple network selections"""
981 check_eap_capa(dev[0], "MSCHAPV2")
982 bssid = apdev[0]['bssid']
983 params = hs20_ap_params()
984 params['hessid'] = bssid
985 hostapd.add_ap(apdev[0]['ifname'], params)
988 values = { 'realm': "example.com",
989 'ca_cert': "auth_serv/ca.pem",
990 'username': "hs20-test",
991 'password': "password",
992 'domain': "example.com" }
993 id = dev[0].add_cred_values(values)
995 dev[0].scan_for_bss(bssid, freq="2412")
997 for i in range(0, 3):
998 logger.info("Starting Interworking network selection")
999 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1001 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
1002 "INTERWORKING-ALREADY-CONNECTED",
1003 "CTRL-EVENT-CONNECTED"], timeout=15)
1005 raise Exception("Connection timed out")
1006 if "INTERWORKING-NO-MATCH" in ev:
1007 raise Exception("Matching AP not found")
1008 if "CTRL-EVENT-CONNECTED" in ev:
1010 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
1013 dev[0].request("DISCONNECT")
1014 dev[0].dump_monitor()
1016 networks = dev[0].list_networks()
1017 if len(networks) > 1:
1018 raise Exception("Duplicated network block detected")
1020 def test_ap_hs20_disallow_aps(dev, apdev):
1021 """Hotspot 2.0 connection and disallow_aps"""
1022 bssid = apdev[0]['bssid']
1023 params = hs20_ap_params()
1024 params['hessid'] = bssid
1025 hostapd.add_ap(apdev[0]['ifname'], params)
1027 dev[0].hs20_enable()
1028 values = { 'realm': "example.com",
1029 'ca_cert': "auth_serv/ca.pem",
1030 'username': "hs20-test",
1031 'password': "password",
1032 'domain': "example.com" }
1033 id = dev[0].add_cred_values(values)
1035 dev[0].scan_for_bss(bssid, freq="2412")
1037 logger.info("Verify disallow_aps bssid")
1038 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
1039 dev[0].request("INTERWORKING_SELECT auto")
1040 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
1042 raise Exception("Network selection timed out")
1043 dev[0].dump_monitor()
1045 logger.info("Verify disallow_aps ssid")
1046 dev[0].request("SET disallow_aps ssid 746573742d68733230")
1047 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1048 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
1050 raise Exception("Network selection timed out")
1051 dev[0].dump_monitor()
1053 logger.info("Verify disallow_aps clear")
1054 dev[0].request("SET disallow_aps ")
1055 interworking_select(dev[0], bssid, "home", freq="2412")
1057 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
1058 ret = dev[0].request("INTERWORKING_CONNECT " + bssid)
1059 if "FAIL" not in ret:
1060 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
1062 if "FAIL" not in dev[0].request("INTERWORKING_CONNECT foo"):
1063 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1064 if "FAIL" not in dev[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
1065 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1067 def policy_test(dev, ap, values, only_one=True):
1070 logger.info("Verify network selection to AP " + ap['ifname'])
1072 dev.scan_for_bss(bssid, freq="2412")
1074 logger.info("Verify network selection")
1077 id = dev.add_cred_values(values)
1078 dev.request("INTERWORKING_SELECT auto freq=2412")
1081 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1082 "INTERWORKING-BLACKLISTED",
1083 "INTERWORKING-SELECTED"], timeout=15)
1085 raise Exception("Network selection timed out")
1087 if "INTERWORKING-NO-MATCH" in ev:
1088 raise Exception("Matching AP not found")
1089 if bssid and only_one and "INTERWORKING-AP" in ev and bssid not in ev:
1090 raise Exception("Unexpected AP claimed acceptable")
1091 if "INTERWORKING-SELECTED" in ev:
1092 if bssid and bssid not in ev:
1093 raise Exception("Selected incorrect BSS")
1096 ev = dev.wait_connected(timeout=15)
1097 if bssid and bssid not in ev:
1098 raise Exception("Connected to incorrect BSS")
1100 conn_bssid = dev.get_status_field("bssid")
1101 if bssid and conn_bssid != bssid:
1102 raise Exception("bssid information points to incorrect BSS")
1108 def default_cred(domain=None, user="hs20-test"):
1109 cred = { 'realm': "example.com",
1110 'ca_cert': "auth_serv/ca.pem",
1112 'password': "password" }
1114 cred['domain'] = domain
1117 def test_ap_hs20_prefer_home(dev, apdev):
1118 """Hotspot 2.0 required roaming consortium"""
1119 check_eap_capa(dev[0], "MSCHAPV2")
1120 params = hs20_ap_params()
1121 params['domain_name'] = "example.org"
1122 hostapd.add_ap(apdev[0]['ifname'], params)
1124 params = hs20_ap_params()
1125 params['ssid'] = "test-hs20-other"
1126 params['domain_name'] = "example.com"
1127 hostapd.add_ap(apdev[1]['ifname'], params)
1129 values = default_cred()
1130 values['domain'] = "example.com"
1131 policy_test(dev[0], apdev[1], values, only_one=False)
1132 values['domain'] = "example.org"
1133 policy_test(dev[0], apdev[0], values, only_one=False)
1135 def test_ap_hs20_req_roaming_consortium(dev, apdev):
1136 """Hotspot 2.0 required roaming consortium"""
1137 check_eap_capa(dev[0], "MSCHAPV2")
1138 params = hs20_ap_params()
1139 hostapd.add_ap(apdev[0]['ifname'], params)
1141 params = hs20_ap_params()
1142 params['ssid'] = "test-hs20-other"
1143 params['roaming_consortium'] = [ "223344" ]
1144 hostapd.add_ap(apdev[1]['ifname'], params)
1146 values = default_cred()
1147 values['required_roaming_consortium'] = "223344"
1148 policy_test(dev[0], apdev[1], values)
1149 values['required_roaming_consortium'] = "112233"
1150 policy_test(dev[0], apdev[0], values)
1152 id = dev[0].add_cred()
1153 dev[0].set_cred(id, "required_roaming_consortium", "112233")
1154 dev[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1156 for val in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1157 if "FAIL" not in dev[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val)):
1158 raise Exception("Invalid roaming consortium value accepted: " + val)
1160 def test_ap_hs20_excluded_ssid(dev, apdev):
1161 """Hotspot 2.0 exclusion based on SSID"""
1162 check_eap_capa(dev[0], "MSCHAPV2")
1163 params = hs20_ap_params()
1164 params['roaming_consortium'] = [ "223344" ]
1165 params['anqp_3gpp_cell_net'] = "555,444"
1166 hostapd.add_ap(apdev[0]['ifname'], params)
1168 params = hs20_ap_params()
1169 params['ssid'] = "test-hs20-other"
1170 params['roaming_consortium'] = [ "223344" ]
1171 params['anqp_3gpp_cell_net'] = "555,444"
1172 hostapd.add_ap(apdev[1]['ifname'], params)
1174 values = default_cred()
1175 values['excluded_ssid'] = "test-hs20"
1176 events = policy_test(dev[0], apdev[1], values)
1177 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1179 raise Exception("Excluded network not reported")
1180 values['excluded_ssid'] = "test-hs20-other"
1181 events = policy_test(dev[0], apdev[0], values)
1182 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[1]['bssid'] in e]
1184 raise Exception("Excluded network not reported")
1186 values = default_cred()
1187 values['roaming_consortium'] = "223344"
1188 values['eap'] = "TTLS"
1189 values['phase2'] = "auth=MSCHAPV2"
1190 values['excluded_ssid'] = "test-hs20"
1191 events = policy_test(dev[0], apdev[1], values)
1192 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1194 raise Exception("Excluded network not reported")
1196 values = { 'imsi': "555444-333222111", 'eap': "SIM",
1197 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1198 'excluded_ssid': "test-hs20" }
1199 events = policy_test(dev[0], apdev[1], values)
1200 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1202 raise Exception("Excluded network not reported")
1204 def test_ap_hs20_roam_to_higher_prio(dev, apdev):
1205 """Hotspot 2.0 and roaming from current to higher priority network"""
1206 check_eap_capa(dev[0], "MSCHAPV2")
1207 bssid = apdev[0]['bssid']
1208 params = hs20_ap_params(ssid="test-hs20-visited")
1209 params['domain_name'] = "visited.example.org"
1210 hostapd.add_ap(apdev[0]['ifname'], params)
1212 dev[0].hs20_enable()
1213 id = dev[0].add_cred_values({ 'realm': "example.com",
1214 'ca_cert': "auth_serv/ca.pem",
1215 'username': "hs20-test",
1216 'password': "password",
1217 'domain': "example.com" })
1218 logger.info("Connect to the only network option")
1219 interworking_select(dev[0], bssid, "roaming", freq="2412")
1220 dev[0].dump_monitor()
1221 interworking_connect(dev[0], bssid, "TTLS")
1223 logger.info("Start another AP (home operator) and reconnect")
1224 bssid2 = apdev[1]['bssid']
1225 params = hs20_ap_params(ssid="test-hs20-home")
1226 params['domain_name'] = "example.com"
1227 hostapd.add_ap(apdev[1]['ifname'], params)
1229 dev[0].scan_for_bss(bssid2, freq="2412", force_scan=True)
1230 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1231 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
1232 "INTERWORKING-ALREADY-CONNECTED",
1233 "CTRL-EVENT-CONNECTED"], timeout=15)
1235 raise Exception("Connection timed out")
1236 if "INTERWORKING-NO-MATCH" in ev:
1237 raise Exception("Matching AP not found")
1238 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1239 raise Exception("Unexpected AP selected")
1240 if bssid2 not in ev:
1241 raise Exception("Unexpected BSSID after reconnection")
1243 def test_ap_hs20_domain_suffix_match_full(dev, apdev):
1244 """Hotspot 2.0 and domain_suffix_match"""
1245 check_eap_capa(dev[0], "MSCHAPV2")
1246 bssid = apdev[0]['bssid']
1247 params = hs20_ap_params()
1248 hostapd.add_ap(apdev[0]['ifname'], params)
1250 dev[0].hs20_enable()
1251 id = dev[0].add_cred_values({ 'realm': "example.com",
1252 'username': "hs20-test",
1253 'password': "password",
1254 'ca_cert': "auth_serv/ca.pem",
1255 'domain': "example.com",
1256 'domain_suffix_match': "server.w1.fi" })
1257 interworking_select(dev[0], bssid, "home", freq="2412")
1258 dev[0].dump_monitor()
1259 interworking_connect(dev[0], bssid, "TTLS")
1260 dev[0].request("REMOVE_NETWORK all")
1261 dev[0].dump_monitor()
1263 dev[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1264 interworking_select(dev[0], bssid, "home", freq="2412")
1265 dev[0].dump_monitor()
1266 dev[0].request("INTERWORKING_CONNECT " + bssid)
1267 ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1269 raise Exception("TLS certificate error not reported")
1270 if "Domain suffix mismatch" not in ev:
1271 raise Exception("Domain suffix mismatch not reported")
1273 def test_ap_hs20_domain_suffix_match(dev, apdev):
1274 """Hotspot 2.0 and domain_suffix_match"""
1275 check_eap_capa(dev[0], "MSCHAPV2")
1276 check_domain_match_full(dev[0])
1277 bssid = apdev[0]['bssid']
1278 params = hs20_ap_params()
1279 hostapd.add_ap(apdev[0]['ifname'], params)
1281 dev[0].hs20_enable()
1282 id = dev[0].add_cred_values({ 'realm': "example.com",
1283 'username': "hs20-test",
1284 'password': "password",
1285 'ca_cert': "auth_serv/ca.pem",
1286 'domain': "example.com",
1287 'domain_suffix_match': "w1.fi" })
1288 interworking_select(dev[0], bssid, "home", freq="2412")
1289 dev[0].dump_monitor()
1290 interworking_connect(dev[0], bssid, "TTLS")
1292 def test_ap_hs20_roaming_partner_preference(dev, apdev):
1293 """Hotspot 2.0 and roaming partner preference"""
1294 check_eap_capa(dev[0], "MSCHAPV2")
1295 params = hs20_ap_params()
1296 params['domain_name'] = "roaming.example.org"
1297 hostapd.add_ap(apdev[0]['ifname'], params)
1299 params = hs20_ap_params()
1300 params['ssid'] = "test-hs20-other"
1301 params['domain_name'] = "roaming.example.net"
1302 hostapd.add_ap(apdev[1]['ifname'], params)
1304 logger.info("Verify default vs. specified preference")
1305 values = default_cred()
1306 values['roaming_partner'] = "roaming.example.net,1,127,*"
1307 policy_test(dev[0], apdev[1], values, only_one=False)
1308 values['roaming_partner'] = "roaming.example.net,1,129,*"
1309 policy_test(dev[0], apdev[0], values, only_one=False)
1311 logger.info("Verify partial FQDN match")
1312 values['roaming_partner'] = "example.net,0,0,*"
1313 policy_test(dev[0], apdev[1], values, only_one=False)
1314 values['roaming_partner'] = "example.net,0,255,*"
1315 policy_test(dev[0], apdev[0], values, only_one=False)
1317 def test_ap_hs20_max_bss_load(dev, apdev):
1318 """Hotspot 2.0 and maximum BSS load"""
1319 check_eap_capa(dev[0], "MSCHAPV2")
1320 params = hs20_ap_params()
1321 params['bss_load_test'] = "12:200:20000"
1322 hostapd.add_ap(apdev[0]['ifname'], params)
1324 params = hs20_ap_params()
1325 params['ssid'] = "test-hs20-other"
1326 params['bss_load_test'] = "5:20:10000"
1327 hostapd.add_ap(apdev[1]['ifname'], params)
1329 logger.info("Verify maximum BSS load constraint")
1330 values = default_cred()
1331 values['domain'] = "example.com"
1332 values['max_bss_load'] = "100"
1333 events = policy_test(dev[0], apdev[1], values, only_one=False)
1335 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1336 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1337 raise Exception("Maximum BSS Load case not noticed")
1338 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1339 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1340 raise Exception("Maximum BSS Load case reported incorrectly")
1342 logger.info("Verify maximum BSS load does not prevent connection")
1343 values['max_bss_load'] = "1"
1344 events = policy_test(dev[0], None, values)
1346 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1347 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1348 raise Exception("Maximum BSS Load case not noticed")
1349 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1350 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1351 raise Exception("Maximum BSS Load case not noticed")
1353 def test_ap_hs20_max_bss_load2(dev, apdev):
1354 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1355 check_eap_capa(dev[0], "MSCHAPV2")
1356 params = hs20_ap_params()
1357 params['bss_load_test'] = "12:200:20000"
1358 hostapd.add_ap(apdev[0]['ifname'], params)
1360 params = hs20_ap_params()
1361 params['ssid'] = "test-hs20-other"
1362 hostapd.add_ap(apdev[1]['ifname'], params)
1364 logger.info("Verify maximum BSS load constraint with AP advertisement")
1365 values = default_cred()
1366 values['domain'] = "example.com"
1367 values['max_bss_load'] = "100"
1368 events = policy_test(dev[0], apdev[1], values, only_one=False)
1370 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1371 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1372 raise Exception("Maximum BSS Load case not noticed")
1373 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1374 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1375 raise Exception("Maximum BSS Load case reported incorrectly")
1377 def test_ap_hs20_multi_cred_sp_prio(dev, apdev):
1378 """Hotspot 2.0 multi-cred sp_priority"""
1379 check_eap_capa(dev[0], "MSCHAPV2")
1381 _test_ap_hs20_multi_cred_sp_prio(dev, apdev)
1383 dev[0].request("SET external_sim 0")
1385 def _test_ap_hs20_multi_cred_sp_prio(dev, apdev):
1386 hlr_auc_gw_available()
1387 bssid = apdev[0]['bssid']
1388 params = hs20_ap_params()
1389 params['hessid'] = bssid
1390 del params['domain_name']
1391 params['anqp_3gpp_cell_net'] = "232,01"
1392 hostapd.add_ap(apdev[0]['ifname'], params)
1394 dev[0].hs20_enable()
1395 dev[0].scan_for_bss(bssid, freq="2412")
1396 dev[0].request("SET external_sim 1")
1397 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1398 'provisioning_sp': "example.com",
1399 'sp_priority' :"1" })
1400 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1401 'ca_cert': "auth_serv/ca.pem",
1402 'username': "hs20-test",
1403 'password': "password",
1404 'domain': "example.com",
1405 'provisioning_sp': "example.com",
1406 'sp_priority': "2" })
1407 dev[0].dump_monitor()
1408 dev[0].scan_for_bss(bssid, freq="2412")
1409 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1410 interworking_ext_sim_auth(dev[0], "SIM")
1411 check_sp_type(dev[0], "unknown")
1412 dev[0].request("REMOVE_NETWORK all")
1414 dev[0].set_cred(id1, "sp_priority", "2")
1415 dev[0].set_cred(id2, "sp_priority", "1")
1416 dev[0].dump_monitor()
1417 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1418 interworking_auth(dev[0], "TTLS")
1419 check_sp_type(dev[0], "unknown")
1421 def test_ap_hs20_multi_cred_sp_prio2(dev, apdev):
1422 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1423 check_eap_capa(dev[0], "MSCHAPV2")
1425 _test_ap_hs20_multi_cred_sp_prio2(dev, apdev)
1427 dev[0].request("SET external_sim 0")
1429 def _test_ap_hs20_multi_cred_sp_prio2(dev, apdev):
1430 hlr_auc_gw_available()
1431 bssid = apdev[0]['bssid']
1432 params = hs20_ap_params()
1433 params['hessid'] = bssid
1434 del params['nai_realm']
1435 del params['domain_name']
1436 params['anqp_3gpp_cell_net'] = "232,01"
1437 hostapd.add_ap(apdev[0]['ifname'], params)
1439 bssid2 = apdev[1]['bssid']
1440 params = hs20_ap_params()
1441 params['ssid'] = "test-hs20-other"
1442 params['hessid'] = bssid2
1443 del params['domain_name']
1444 del params['anqp_3gpp_cell_net']
1445 hostapd.add_ap(apdev[1]['ifname'], params)
1447 dev[0].hs20_enable()
1448 dev[0].request("SET external_sim 1")
1449 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1450 'provisioning_sp': "example.com",
1451 'sp_priority': "1" })
1452 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1453 'ca_cert': "auth_serv/ca.pem",
1454 'username': "hs20-test",
1455 'password': "password",
1456 'domain': "example.com",
1457 'provisioning_sp': "example.com",
1458 'sp_priority': "2" })
1459 dev[0].dump_monitor()
1460 dev[0].scan_for_bss(bssid, freq="2412")
1461 dev[0].scan_for_bss(bssid2, freq="2412")
1462 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1463 interworking_ext_sim_auth(dev[0], "SIM")
1464 check_sp_type(dev[0], "unknown")
1465 conn_bssid = dev[0].get_status_field("bssid")
1466 if conn_bssid != bssid:
1467 raise Exception("Connected to incorrect BSS")
1468 dev[0].request("REMOVE_NETWORK all")
1470 dev[0].set_cred(id1, "sp_priority", "2")
1471 dev[0].set_cred(id2, "sp_priority", "1")
1472 dev[0].dump_monitor()
1473 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1474 interworking_auth(dev[0], "TTLS")
1475 check_sp_type(dev[0], "unknown")
1476 conn_bssid = dev[0].get_status_field("bssid")
1477 if conn_bssid != bssid2:
1478 raise Exception("Connected to incorrect BSS")
1480 def check_conn_capab_selection(dev, type, missing):
1481 dev.request("INTERWORKING_SELECT freq=2412")
1482 ev = dev.wait_event(["INTERWORKING-AP"])
1484 raise Exception("Network selection timed out");
1485 if "type=" + type not in ev:
1486 raise Exception("Unexpected network type")
1487 if missing and "conn_capab_missing=1" not in ev:
1488 raise Exception("conn_capab_missing not reported")
1489 if not missing and "conn_capab_missing=1" in ev:
1490 raise Exception("conn_capab_missing reported unexpectedly")
1492 def conn_capab_cred(domain=None, req_conn_capab=None):
1493 cred = default_cred(domain=domain)
1495 cred['req_conn_capab'] = req_conn_capab
1498 def test_ap_hs20_req_conn_capab(dev, apdev):
1499 """Hotspot 2.0 network selection with req_conn_capab"""
1500 check_eap_capa(dev[0], "MSCHAPV2")
1501 bssid = apdev[0]['bssid']
1502 params = hs20_ap_params()
1503 hostapd.add_ap(apdev[0]['ifname'], params)
1505 dev[0].hs20_enable()
1506 dev[0].scan_for_bss(bssid, freq="2412")
1507 logger.info("Not used in home network")
1508 values = conn_capab_cred(domain="example.com", req_conn_capab="6:1234")
1509 id = dev[0].add_cred_values(values)
1510 check_conn_capab_selection(dev[0], "home", False)
1512 logger.info("Used in roaming network")
1513 dev[0].remove_cred(id)
1514 values = conn_capab_cred(domain="example.org", req_conn_capab="6:1234")
1515 id = dev[0].add_cred_values(values)
1516 check_conn_capab_selection(dev[0], "roaming", True)
1518 logger.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1519 check_auto_select(dev[0], bssid)
1521 logger.info("Additional req_conn_capab checks")
1523 dev[0].remove_cred(id)
1524 values = conn_capab_cred(domain="example.org", req_conn_capab="1:0")
1525 id = dev[0].add_cred_values(values)
1526 check_conn_capab_selection(dev[0], "roaming", True)
1528 dev[0].remove_cred(id)
1529 values = conn_capab_cred(domain="example.org", req_conn_capab="17:5060")
1530 id = dev[0].add_cred_values(values)
1531 check_conn_capab_selection(dev[0], "roaming", True)
1533 bssid2 = apdev[1]['bssid']
1534 params = hs20_ap_params(ssid="test-hs20b")
1535 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1536 hostapd.add_ap(apdev[1]['ifname'], params)
1538 dev[0].remove_cred(id)
1539 values = conn_capab_cred(domain="example.org", req_conn_capab="50")
1540 id = dev[0].add_cred_values(values)
1541 dev[0].set_cred(id, "req_conn_capab", "6:22")
1542 dev[0].scan_for_bss(bssid2, freq="2412")
1543 dev[0].request("INTERWORKING_SELECT freq=2412")
1544 for i in range(0, 2):
1545 ev = dev[0].wait_event(["INTERWORKING-AP"])
1547 raise Exception("Network selection timed out");
1548 if bssid in ev and "conn_capab_missing=1" not in ev:
1549 raise Exception("Missing protocol connection capability not reported")
1550 if bssid2 in ev and "conn_capab_missing=1" in ev:
1551 raise Exception("Protocol connection capability not reported correctly")
1553 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev, apdev):
1554 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1555 check_eap_capa(dev[0], "MSCHAPV2")
1556 bssid = apdev[0]['bssid']
1557 params = hs20_ap_params()
1558 params['domain_name'] = "roaming.example.org"
1559 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1560 hostapd.add_ap(apdev[0]['ifname'], params)
1562 bssid2 = apdev[1]['bssid']
1563 params = hs20_ap_params(ssid="test-hs20-b")
1564 params['domain_name'] = "roaming.example.net"
1565 hostapd.add_ap(apdev[1]['ifname'], params)
1567 values = default_cred()
1568 values['roaming_partner'] = "roaming.example.net,1,127,*"
1569 id = dev[0].add_cred_values(values)
1570 check_auto_select(dev[0], bssid2)
1572 dev[0].set_cred(id, "req_conn_capab", "50")
1573 check_auto_select(dev[0], bssid)
1575 dev[0].remove_cred(id)
1576 id = dev[0].add_cred_values(values)
1577 dev[0].set_cred(id, "req_conn_capab", "51")
1578 check_auto_select(dev[0], bssid2)
1580 def check_bandwidth_selection(dev, type, below):
1581 dev.request("INTERWORKING_SELECT freq=2412")
1582 ev = dev.wait_event(["INTERWORKING-AP"])
1584 raise Exception("Network selection timed out");
1585 logger.debug("BSS entries:\n" + dev.request("BSS RANGE=ALL"))
1586 if "type=" + type not in ev:
1587 raise Exception("Unexpected network type")
1588 if below and "below_min_backhaul=1" not in ev:
1589 raise Exception("below_min_backhaul not reported")
1590 if not below and "below_min_backhaul=1" in ev:
1591 raise Exception("below_min_backhaul reported unexpectedly")
1593 def bw_cred(domain=None, dl_home=None, ul_home=None, dl_roaming=None, ul_roaming=None):
1594 cred = default_cred(domain=domain)
1596 cred['min_dl_bandwidth_home'] = str(dl_home)
1598 cred['min_ul_bandwidth_home'] = str(ul_home)
1600 cred['min_dl_bandwidth_roaming'] = str(dl_roaming)
1602 cred['min_ul_bandwidth_roaming'] = str(ul_roaming)
1605 def test_ap_hs20_min_bandwidth_home(dev, apdev):
1606 """Hotspot 2.0 network selection with min bandwidth (home)"""
1607 check_eap_capa(dev[0], "MSCHAPV2")
1608 bssid = apdev[0]['bssid']
1609 params = hs20_ap_params()
1610 hostapd.add_ap(apdev[0]['ifname'], params)
1612 dev[0].hs20_enable()
1613 dev[0].scan_for_bss(bssid, freq="2412")
1614 values = bw_cred(domain="example.com", dl_home=5490, ul_home=58)
1615 id = dev[0].add_cred_values(values)
1616 check_bandwidth_selection(dev[0], "home", False)
1617 dev[0].remove_cred(id)
1619 values = bw_cred(domain="example.com", dl_home=5491, ul_home=58)
1620 id = dev[0].add_cred_values(values)
1621 check_bandwidth_selection(dev[0], "home", True)
1622 dev[0].remove_cred(id)
1624 values = bw_cred(domain="example.com", dl_home=5490, ul_home=59)
1625 id = dev[0].add_cred_values(values)
1626 check_bandwidth_selection(dev[0], "home", True)
1627 dev[0].remove_cred(id)
1629 values = bw_cred(domain="example.com", dl_home=5491, ul_home=59)
1630 id = dev[0].add_cred_values(values)
1631 check_bandwidth_selection(dev[0], "home", True)
1632 check_auto_select(dev[0], bssid)
1634 bssid2 = apdev[1]['bssid']
1635 params = hs20_ap_params(ssid="test-hs20-b")
1636 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1637 hostapd.add_ap(apdev[1]['ifname'], params)
1639 check_auto_select(dev[0], bssid2)
1641 def test_ap_hs20_min_bandwidth_home_hidden_ssid_in_scan_res(dev, apdev):
1642 """Hotspot 2.0 network selection with min bandwidth (home) while hidden SSID is included in scan results"""
1643 check_eap_capa(dev[0], "MSCHAPV2")
1644 bssid = apdev[0]['bssid']
1646 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": 'secret',
1647 "ignore_broadcast_ssid": "1" })
1648 dev[0].scan_for_bss(bssid, freq=2412)
1650 hapd_global = hostapd.HostapdGlobal()
1652 hapd_global.remove(apdev[0]['ifname'])
1654 params = hs20_ap_params()
1655 hostapd.add_ap(apdev[0]['ifname'], params)
1657 dev[0].hs20_enable()
1658 dev[0].scan_for_bss(bssid, freq="2412")
1659 values = bw_cred(domain="example.com", dl_home=5490, ul_home=58)
1660 id = dev[0].add_cred_values(values)
1661 check_bandwidth_selection(dev[0], "home", False)
1662 dev[0].remove_cred(id)
1664 values = bw_cred(domain="example.com", dl_home=5491, ul_home=58)
1665 id = dev[0].add_cred_values(values)
1666 check_bandwidth_selection(dev[0], "home", True)
1667 dev[0].remove_cred(id)
1669 values = bw_cred(domain="example.com", dl_home=5490, ul_home=59)
1670 id = dev[0].add_cred_values(values)
1671 check_bandwidth_selection(dev[0], "home", True)
1672 dev[0].remove_cred(id)
1674 values = bw_cred(domain="example.com", dl_home=5491, ul_home=59)
1675 id = dev[0].add_cred_values(values)
1676 check_bandwidth_selection(dev[0], "home", True)
1677 check_auto_select(dev[0], bssid)
1679 bssid2 = apdev[1]['bssid']
1680 params = hs20_ap_params(ssid="test-hs20-b")
1681 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1682 hostapd.add_ap(apdev[1]['ifname'], params)
1684 check_auto_select(dev[0], bssid2)
1686 dev[0].flush_scan_cache()
1688 def test_ap_hs20_min_bandwidth_roaming(dev, apdev):
1689 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1690 check_eap_capa(dev[0], "MSCHAPV2")
1691 bssid = apdev[0]['bssid']
1692 params = hs20_ap_params()
1693 hostapd.add_ap(apdev[0]['ifname'], params)
1695 dev[0].hs20_enable()
1696 dev[0].scan_for_bss(bssid, freq="2412")
1697 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=58)
1698 id = dev[0].add_cred_values(values)
1699 check_bandwidth_selection(dev[0], "roaming", False)
1700 dev[0].remove_cred(id)
1702 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=58)
1703 id = dev[0].add_cred_values(values)
1704 check_bandwidth_selection(dev[0], "roaming", True)
1705 dev[0].remove_cred(id)
1707 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=59)
1708 id = dev[0].add_cred_values(values)
1709 check_bandwidth_selection(dev[0], "roaming", True)
1710 dev[0].remove_cred(id)
1712 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=59)
1713 id = dev[0].add_cred_values(values)
1714 check_bandwidth_selection(dev[0], "roaming", True)
1715 check_auto_select(dev[0], bssid)
1717 bssid2 = apdev[1]['bssid']
1718 params = hs20_ap_params(ssid="test-hs20-b")
1719 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1720 hostapd.add_ap(apdev[1]['ifname'], params)
1722 check_auto_select(dev[0], bssid2)
1724 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev, apdev):
1725 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1726 check_eap_capa(dev[0], "MSCHAPV2")
1727 bssid = apdev[0]['bssid']
1728 params = hs20_ap_params()
1729 params['domain_name'] = "roaming.example.org"
1730 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1731 hostapd.add_ap(apdev[0]['ifname'], params)
1733 bssid2 = apdev[1]['bssid']
1734 params = hs20_ap_params(ssid="test-hs20-b")
1735 params['domain_name'] = "roaming.example.net"
1736 hostapd.add_ap(apdev[1]['ifname'], params)
1738 values = default_cred()
1739 values['roaming_partner'] = "roaming.example.net,1,127,*"
1740 id = dev[0].add_cred_values(values)
1741 check_auto_select(dev[0], bssid2)
1743 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1744 check_auto_select(dev[0], bssid)
1746 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1747 check_auto_select(dev[0], bssid2)
1749 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev, apdev):
1750 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1751 bssid = apdev[0]['bssid']
1752 params = hs20_ap_params()
1753 del params['hs20_wan_metrics']
1754 hostapd.add_ap(apdev[0]['ifname'], params)
1756 dev[0].hs20_enable()
1757 dev[0].scan_for_bss(bssid, freq="2412")
1758 values = bw_cred(domain="example.com", dl_home=10000, ul_home=10000,
1759 dl_roaming=10000, ul_roaming=10000)
1760 dev[0].add_cred_values(values)
1761 check_bandwidth_selection(dev[0], "home", False)
1763 def test_ap_hs20_deauth_req_ess(dev, apdev):
1764 """Hotspot 2.0 connection and deauthentication request for ESS"""
1765 check_eap_capa(dev[0], "MSCHAPV2")
1767 _test_ap_hs20_deauth_req_ess(dev, apdev)
1769 dev[0].request("SET pmf 0")
1771 def _test_ap_hs20_deauth_req_ess(dev, apdev):
1772 dev[0].request("SET pmf 2")
1773 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1774 dev[0].dump_monitor()
1775 addr = dev[0].p2p_interface_addr()
1776 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1777 hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/")
1778 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1780 raise Exception("Timeout on deauth imminent notice")
1781 if "1 120 http://example.com/" not in ev:
1782 raise Exception("Unexpected deauth imminent notice: " + ev)
1783 hapd.request("DEAUTHENTICATE " + addr)
1784 dev[0].wait_disconnected(timeout=10)
1785 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1786 raise Exception("Network not marked temporarily disabled")
1787 ev = dev[0].wait_event(["SME: Trying to authenticate",
1788 "Trying to associate",
1789 "CTRL-EVENT-CONNECTED"], timeout=5)
1791 raise Exception("Unexpected connection attempt")
1793 def test_ap_hs20_deauth_req_bss(dev, apdev):
1794 """Hotspot 2.0 connection and deauthentication request for BSS"""
1795 check_eap_capa(dev[0], "MSCHAPV2")
1797 _test_ap_hs20_deauth_req_bss(dev, apdev)
1799 dev[0].request("SET pmf 0")
1801 def _test_ap_hs20_deauth_req_bss(dev, apdev):
1802 dev[0].request("SET pmf 2")
1803 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1804 dev[0].dump_monitor()
1805 addr = dev[0].p2p_interface_addr()
1806 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1807 hapd.request("HS20_DEAUTH_REQ " + addr + " 0 120 http://example.com/")
1808 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1810 raise Exception("Timeout on deauth imminent notice")
1811 if "0 120 http://example.com/" not in ev:
1812 raise Exception("Unexpected deauth imminent notice: " + ev)
1813 hapd.request("DEAUTHENTICATE " + addr + " reason=4")
1814 ev = dev[0].wait_disconnected(timeout=10)
1815 if "reason=4" not in ev:
1816 raise Exception("Unexpected disconnection reason")
1817 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1818 raise Exception("Network not marked temporarily disabled")
1819 ev = dev[0].wait_event(["SME: Trying to authenticate",
1820 "Trying to associate",
1821 "CTRL-EVENT-CONNECTED"], timeout=5)
1823 raise Exception("Unexpected connection attempt")
1825 def test_ap_hs20_deauth_req_from_radius(dev, apdev):
1826 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1827 check_eap_capa(dev[0], "MSCHAPV2")
1829 _test_ap_hs20_deauth_req_from_radius(dev, apdev)
1831 dev[0].request("SET pmf 0")
1833 def _test_ap_hs20_deauth_req_from_radius(dev, apdev):
1834 bssid = apdev[0]['bssid']
1835 params = hs20_ap_params()
1836 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1837 params['hs20_deauth_req_timeout'] = "2"
1838 hostapd.add_ap(apdev[0]['ifname'], params)
1840 dev[0].request("SET pmf 2")
1841 dev[0].hs20_enable()
1842 dev[0].add_cred_values({ 'realm': "example.com",
1843 'username': "hs20-deauth-test",
1844 'password': "password" })
1845 interworking_select(dev[0], bssid, freq="2412")
1846 interworking_connect(dev[0], bssid, "TTLS")
1847 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout=5)
1849 raise Exception("Timeout on deauth imminent notice")
1850 if " 1 100" not in ev:
1851 raise Exception("Unexpected deauth imminent contents")
1852 dev[0].wait_disconnected(timeout=3)
1854 def test_ap_hs20_remediation_required(dev, apdev):
1855 """Hotspot 2.0 connection and remediation required from RADIUS"""
1856 check_eap_capa(dev[0], "MSCHAPV2")
1858 _test_ap_hs20_remediation_required(dev, apdev)
1860 dev[0].request("SET pmf 0")
1862 def _test_ap_hs20_remediation_required(dev, apdev):
1863 bssid = apdev[0]['bssid']
1864 params = hs20_ap_params()
1865 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1866 hostapd.add_ap(apdev[0]['ifname'], params)
1868 dev[0].request("SET pmf 1")
1869 dev[0].hs20_enable()
1870 dev[0].add_cred_values({ 'realm': "example.com",
1871 'username': "hs20-subrem-test",
1872 'password': "password" })
1873 interworking_select(dev[0], bssid, freq="2412")
1874 interworking_connect(dev[0], bssid, "TTLS")
1875 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1877 raise Exception("Timeout on subscription remediation notice")
1878 if " 1 https://example.com/" not in ev:
1879 raise Exception("Unexpected subscription remediation event contents")
1881 def test_ap_hs20_remediation_required_ctrl(dev, apdev):
1882 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1883 check_eap_capa(dev[0], "MSCHAPV2")
1885 _test_ap_hs20_remediation_required_ctrl(dev, apdev)
1887 dev[0].request("SET pmf 0")
1889 def _test_ap_hs20_remediation_required_ctrl(dev, apdev):
1890 bssid = apdev[0]['bssid']
1891 addr = dev[0].own_addr()
1892 params = hs20_ap_params()
1893 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1894 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1896 dev[0].request("SET pmf 1")
1897 dev[0].hs20_enable()
1898 dev[0].add_cred_values(default_cred())
1899 interworking_select(dev[0], bssid, freq="2412")
1900 interworking_connect(dev[0], bssid, "TTLS")
1902 hapd.request("HS20_WNM_NOTIF " + addr + " https://example.com/")
1903 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1905 raise Exception("Timeout on subscription remediation notice")
1906 if " 1 https://example.com/" not in ev:
1907 raise Exception("Unexpected subscription remediation event contents")
1909 hapd.request("HS20_WNM_NOTIF " + addr)
1910 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1912 raise Exception("Timeout on subscription remediation notice")
1913 if not ev.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1914 raise Exception("Unexpected subscription remediation event contents: " + ev)
1916 if "FAIL" not in hapd.request("HS20_WNM_NOTIF "):
1917 raise Exception("Unexpected HS20_WNM_NOTIF success")
1918 if "FAIL" not in hapd.request("HS20_WNM_NOTIF foo"):
1919 raise Exception("Unexpected HS20_WNM_NOTIF success")
1920 if "FAIL" not in hapd.request("HS20_WNM_NOTIF " + addr + " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1921 raise Exception("Unexpected HS20_WNM_NOTIF success")
1923 def test_ap_hs20_session_info(dev, apdev):
1924 """Hotspot 2.0 connection and session information from RADIUS"""
1925 check_eap_capa(dev[0], "MSCHAPV2")
1927 _test_ap_hs20_session_info(dev, apdev)
1929 dev[0].request("SET pmf 0")
1931 def _test_ap_hs20_session_info(dev, apdev):
1932 bssid = apdev[0]['bssid']
1933 params = hs20_ap_params()
1934 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1935 hostapd.add_ap(apdev[0]['ifname'], params)
1937 dev[0].request("SET pmf 1")
1938 dev[0].hs20_enable()
1939 dev[0].add_cred_values({ 'realm': "example.com",
1940 'username': "hs20-session-info-test",
1941 'password': "password" })
1942 interworking_select(dev[0], bssid, freq="2412")
1943 interworking_connect(dev[0], bssid, "TTLS")
1944 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout=10)
1946 raise Exception("Timeout on ESS disassociation imminent notice")
1947 if " 1 59904 https://example.com/" not in ev:
1948 raise Exception("Unexpected ESS disassociation imminent event contents")
1949 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1951 raise Exception("Scan not started")
1952 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=30)
1954 raise Exception("Scan not completed")
1956 def test_ap_hs20_osen(dev, apdev):
1957 """Hotspot 2.0 OSEN connection"""
1958 params = { 'ssid': "osen",
1960 'auth_server_addr': "127.0.0.1",
1961 'auth_server_port': "1812",
1962 'auth_server_shared_secret': "radius" }
1963 hostapd.add_ap(apdev[0]['ifname'], params)
1965 dev[1].connect("osen", key_mgmt="NONE", scan_freq="2412",
1967 dev[2].connect("osen", key_mgmt="NONE", wep_key0='"hello"',
1968 scan_freq="2412", wait_connect=False)
1969 dev[0].flush_scan_cache()
1970 dev[0].connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1971 group="GTK_NOT_USED",
1972 eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1973 ca_cert="auth_serv/ca.pem",
1975 res = dev[0].get_bss(apdev[0]['bssid'])['flags']
1976 if "[OSEN-OSEN-CCMP]" not in res:
1977 raise Exception("OSEN not reported in BSS")
1979 raise Exception("WEP reported in BSS")
1980 res = dev[0].request("SCAN_RESULTS")
1981 if "[OSEN-OSEN-CCMP]" not in res:
1982 raise Exception("OSEN not reported in SCAN_RESULTS")
1984 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1985 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1986 wpas.connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1987 group="GTK_NOT_USED",
1988 eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1989 ca_cert="auth_serv/ca.pem",
1991 wpas.request("DISCONNECT")
1993 def test_ap_hs20_network_preference(dev, apdev):
1994 """Hotspot 2.0 network selection with preferred home network"""
1995 check_eap_capa(dev[0], "MSCHAPV2")
1996 bssid = apdev[0]['bssid']
1997 params = hs20_ap_params()
1998 hostapd.add_ap(apdev[0]['ifname'], params)
2000 dev[0].hs20_enable()
2001 values = { 'realm': "example.com",
2002 'username': "hs20-test",
2003 'password': "password",
2004 'domain': "example.com" }
2005 dev[0].add_cred_values(values)
2007 id = dev[0].add_network()
2008 dev[0].set_network_quoted(id, "ssid", "home")
2009 dev[0].set_network_quoted(id, "psk", "12345678")
2010 dev[0].set_network(id, "priority", "1")
2011 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
2013 dev[0].scan_for_bss(bssid, freq="2412")
2014 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2015 ev = dev[0].wait_connected(timeout=15)
2017 raise Exception("Unexpected network selected")
2019 bssid2 = apdev[1]['bssid']
2020 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
2021 hostapd.add_ap(apdev[1]['ifname'], params)
2023 dev[0].scan_for_bss(bssid2, freq="2412")
2024 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2025 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2026 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
2028 raise Exception("Connection timed out")
2029 if "INTERWORKING-ALREADY-CONNECTED" in ev:
2030 raise Exception("No roam to higher priority network")
2031 if bssid2 not in ev:
2032 raise Exception("Unexpected network selected")
2034 def test_ap_hs20_network_preference2(dev, apdev):
2035 """Hotspot 2.0 network selection with preferred credential"""
2036 check_eap_capa(dev[0], "MSCHAPV2")
2037 bssid2 = apdev[1]['bssid']
2038 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
2039 hostapd.add_ap(apdev[1]['ifname'], params)
2041 dev[0].hs20_enable()
2042 values = { 'realm': "example.com",
2043 'username': "hs20-test",
2044 'password': "password",
2045 'domain': "example.com",
2047 dev[0].add_cred_values(values)
2049 id = dev[0].add_network()
2050 dev[0].set_network_quoted(id, "ssid", "home")
2051 dev[0].set_network_quoted(id, "psk", "12345678")
2052 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
2054 dev[0].scan_for_bss(bssid2, freq="2412")
2055 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2056 ev = dev[0].wait_connected(timeout=15)
2057 if bssid2 not in ev:
2058 raise Exception("Unexpected network selected")
2060 bssid = apdev[0]['bssid']
2061 params = hs20_ap_params()
2062 hostapd.add_ap(apdev[0]['ifname'], params)
2064 dev[0].scan_for_bss(bssid, freq="2412")
2065 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2066 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2067 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
2069 raise Exception("Connection timed out")
2070 if "INTERWORKING-ALREADY-CONNECTED" in ev:
2071 raise Exception("No roam to higher priority network")
2073 raise Exception("Unexpected network selected")
2075 def test_ap_hs20_network_preference3(dev, apdev):
2076 """Hotspot 2.0 network selection with two credential (one preferred)"""
2077 check_eap_capa(dev[0], "MSCHAPV2")
2078 bssid = apdev[0]['bssid']
2079 params = hs20_ap_params()
2080 hostapd.add_ap(apdev[0]['ifname'], params)
2082 bssid2 = apdev[1]['bssid']
2083 params = hs20_ap_params(ssid="test-hs20b")
2084 params['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
2085 hostapd.add_ap(apdev[1]['ifname'], params)
2087 dev[0].hs20_enable()
2088 values = { 'realm': "example.com",
2089 'username': "hs20-test",
2090 'password': "password",
2092 dev[0].add_cred_values(values)
2093 values = { 'realm': "example.org",
2094 'username': "hs20-test",
2095 'password': "password" }
2096 id = dev[0].add_cred_values(values)
2098 dev[0].scan_for_bss(bssid, freq="2412")
2099 dev[0].scan_for_bss(bssid2, freq="2412")
2100 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2101 ev = dev[0].wait_connected(timeout=15)
2103 raise Exception("Unexpected network selected")
2105 dev[0].set_cred(id, "priority", "2")
2106 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2107 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2108 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
2110 raise Exception("Connection timed out")
2111 if "INTERWORKING-ALREADY-CONNECTED" in ev:
2112 raise Exception("No roam to higher priority network")
2113 if bssid2 not in ev:
2114 raise Exception("Unexpected network selected")
2116 def test_ap_hs20_network_preference4(dev, apdev):
2117 """Hotspot 2.0 network selection with username vs. SIM credential"""
2118 check_eap_capa(dev[0], "MSCHAPV2")
2119 bssid = apdev[0]['bssid']
2120 params = hs20_ap_params()
2121 hostapd.add_ap(apdev[0]['ifname'], params)
2123 bssid2 = apdev[1]['bssid']
2124 params = hs20_ap_params(ssid="test-hs20b")
2125 params['hessid'] = bssid2
2126 params['anqp_3gpp_cell_net'] = "555,444"
2127 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
2128 hostapd.add_ap(apdev[1]['ifname'], params)
2130 dev[0].hs20_enable()
2131 values = { 'realm': "example.com",
2132 'username': "hs20-test",
2133 'password': "password",
2135 dev[0].add_cred_values(values)
2136 values = { 'imsi': "555444-333222111",
2138 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
2139 id = dev[0].add_cred_values(values)
2141 dev[0].scan_for_bss(bssid, freq="2412")
2142 dev[0].scan_for_bss(bssid2, freq="2412")
2143 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2144 ev = dev[0].wait_connected(timeout=15)
2146 raise Exception("Unexpected network selected")
2148 dev[0].set_cred(id, "priority", "2")
2149 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2150 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
2151 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
2153 raise Exception("Connection timed out")
2154 if "INTERWORKING-ALREADY-CONNECTED" in ev:
2155 raise Exception("No roam to higher priority network")
2156 if bssid2 not in ev:
2157 raise Exception("Unexpected network selected")
2159 def test_ap_hs20_interworking_select_blocking_scan(dev, apdev):
2160 """Ongoing INTERWORKING_SELECT blocking SCAN"""
2161 check_eap_capa(dev[0], "MSCHAPV2")
2162 bssid = apdev[0]['bssid']
2163 params = hs20_ap_params()
2164 hostapd.add_ap(apdev[0]['ifname'], params)
2166 dev[0].hs20_enable()
2167 values = { 'realm': "example.com",
2168 'username': "hs20-test",
2169 'password': "password",
2170 'domain': "example.com" }
2171 dev[0].add_cred_values(values)
2173 dev[0].scan_for_bss(bssid, freq="2412")
2174 dev[0].request("INTERWORKING_SELECT auto freq=2412")
2175 if "FAIL-BUSY" not in dev[0].request("SCAN"):
2176 raise Exception("Unexpected SCAN command result")
2177 dev[0].wait_connected(timeout=15)
2179 def test_ap_hs20_fetch_osu(dev, apdev):
2180 """Hotspot 2.0 OSU provider and icon fetch"""
2181 bssid = apdev[0]['bssid']
2182 params = hs20_ap_params()
2183 params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2184 params['osu_ssid'] = '"HS 2.0 OSU open"'
2185 params['osu_method_list'] = "1"
2186 params['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2187 params['osu_icon'] = "w1fi_logo"
2188 params['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2189 params['osu_server_uri'] = "https://example.com/osu/"
2190 hostapd.add_ap(apdev[0]['ifname'], params)
2192 bssid2 = apdev[1]['bssid']
2193 params = hs20_ap_params(ssid="test-hs20b")
2194 params['hessid'] = bssid2
2195 params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2196 params['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2197 params['osu_method_list'] = "0"
2198 params['osu_nai'] = "osen@example.com"
2199 params['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
2200 params['osu_icon'] = "w1fi_logo"
2201 params['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
2202 params['osu_server_uri'] = "https://example.org/osu/"
2203 hostapd.add_ap(apdev[1]['ifname'], params)
2205 with open("w1fi_logo.png", "r") as f:
2206 orig_logo = f.read()
2207 dev[0].hs20_enable()
2208 dir = "/tmp/osu-fetch"
2209 if os.path.isdir(dir):
2210 files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
2212 os.remove(dir + "/" + f)
2219 dev[1].scan_for_bss(bssid, freq="2412")
2220 dev[0].request("SET osu_dir " + dir)
2221 dev[0].request("FETCH_OSU")
2222 if "FAIL" not in dev[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2223 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2224 if "OK" not in dev[1].request("HS20_ICON_REQUEST " + bssid + " w1fi_logo"):
2225 raise Exception("HS20_ICON_REQUEST failed")
2228 ev = dev[0].wait_event(["OSU provider fetch completed",
2229 "RX-HS20-ANQP-ICON"], timeout=15)
2231 raise Exception("Timeout on OSU fetch")
2232 if "OSU provider fetch completed" in ev:
2234 if "RX-HS20-ANQP-ICON" in ev:
2235 with open(ev.split(' ')[1], "r") as f:
2237 if logo == orig_logo:
2240 with open(dir + "/osu-providers.txt", "r") as f:
2242 logger.debug("osu-providers.txt: " + prov)
2243 if "OSU-PROVIDER " + bssid not in prov:
2244 raise Exception("Missing OSU_PROVIDER(1)")
2245 if "OSU-PROVIDER " + bssid2 not in prov:
2246 raise Exception("Missing OSU_PROVIDER(2)")
2248 files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
2250 os.remove(dir + "/" + f)
2254 raise Exception("Unexpected number of icons fetched")
2256 ev = dev[1].wait_event(["GAS-QUERY-START"], timeout=5)
2258 raise Exception("Timeout on GAS-QUERY-DONE")
2259 ev = dev[1].wait_event(["GAS-QUERY-DONE"], timeout=5)
2261 raise Exception("Timeout on GAS-QUERY-DONE")
2262 if "freq=2412 status_code=0 result=SUCCESS" not in ev:
2263 raise Exception("Unexpected GAS-QUERY-DONE: " + ev)
2264 ev = dev[1].wait_event(["RX-HS20-ANQP"], timeout=15)
2266 raise Exception("Timeout on icon fetch")
2267 if "Icon Binary File" not in ev:
2268 raise Exception("Unexpected ANQP element")
2270 def test_ap_hs20_fetch_osu_stop(dev, apdev):
2271 """Hotspot 2.0 OSU provider fetch stopped"""
2272 bssid = apdev[0]['bssid']
2273 params = hs20_ap_params()
2274 params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2275 params['osu_ssid'] = '"HS 2.0 OSU open"'
2276 params['osu_method_list'] = "1"
2277 params['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2278 params['osu_icon'] = "w1fi_logo"
2279 params['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2280 params['osu_server_uri'] = "https://example.com/osu/"
2281 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2283 dev[0].hs20_enable()
2284 dir = "/tmp/osu-fetch"
2285 if os.path.isdir(dir):
2286 files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
2288 os.remove(dir + "/" + f)
2295 dev[0].request("SET osu_dir " + dir)
2296 dev[0].request("SCAN freq=2412-2462")
2297 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=10)
2299 raise Exception("Scan did not start")
2300 if "FAIL" not in dev[0].request("FETCH_OSU"):
2301 raise Exception("FETCH_OSU accepted while scanning")
2302 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
2304 raise Exception("Scan timed out")
2305 hapd.set("ext_mgmt_frame_handling", "1")
2306 dev[0].request("FETCH_ANQP")
2307 if "FAIL" not in dev[0].request("FETCH_OSU"):
2308 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
2309 dev[0].request("STOP_FETCH_ANQP")
2310 dev[0].wait_event(["GAS-QUERY-DONE"], timeout=5)
2311 dev[0].dump_monitor()
2313 dev[0].request("INTERWORKING_SELECT freq=2412")
2315 msg = hapd.mgmt_rx()
2316 if msg['subtype'] == 13:
2318 if "FAIL" not in dev[0].request("FETCH_OSU"):
2319 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
2320 ev = dev[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
2323 raise Exception("Network selection timed out");
2325 dev[0].dump_monitor()
2326 if "OK" not in dev[0].request("FETCH_OSU"):
2327 raise Exception("FETCH_OSU failed")
2328 dev[0].request("CANCEL_FETCH_OSU")
2332 if dev[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
2335 dev[0].dump_monitor()
2336 if "OK" not in dev[0].request("FETCH_OSU"):
2337 raise Exception("FETCH_OSU failed")
2338 if "FAIL" not in dev[0].request("FETCH_OSU"):
2339 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2340 ev = dev[0].wait_event(["GAS-QUERY-START"], 10)
2342 raise Exception("GAS timed out")
2343 if "FAIL" not in dev[0].request("FETCH_OSU"):
2344 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2345 dev[0].request("CANCEL_FETCH_OSU")
2346 ev = dev[0].wait_event(["GAS-QUERY-DONE"], 10)
2348 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
2350 files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
2352 os.remove(dir + "/" + f)
2355 def test_ap_hs20_ft(dev, apdev):
2356 """Hotspot 2.0 connection with FT"""
2357 check_eap_capa(dev[0], "MSCHAPV2")
2358 bssid = apdev[0]['bssid']
2359 params = hs20_ap_params()
2360 params['wpa_key_mgmt'] = "FT-EAP"
2361 params['nas_identifier'] = "nas1.w1.fi"
2362 params['r1_key_holder'] = "000102030405"
2363 params["mobility_domain"] = "a1b2"
2364 params["reassociation_deadline"] = "1000"
2365 hostapd.add_ap(apdev[0]['ifname'], params)
2367 dev[0].hs20_enable()
2368 id = dev[0].add_cred_values({ 'realm': "example.com",
2369 'username': "hs20-test",
2370 'password': "password",
2371 'ca_cert': "auth_serv/ca.pem",
2372 'domain': "example.com",
2373 'update_identifier': "1234" })
2374 interworking_select(dev[0], bssid, "home", freq="2412")
2375 interworking_connect(dev[0], bssid, "TTLS")
2377 def test_ap_hs20_remediation_sql(dev, apdev, params):
2378 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2379 check_eap_capa(dev[0], "MSCHAPV2")
2383 raise HwsimSkip("No sqlite3 module available")
2384 dbfile = os.path.join(params['logdir'], "eap-user.db")
2389 con = sqlite3.connect(dbfile)
2392 cur.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2393 cur.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2394 cur.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2395 cur.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2396 cur.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2399 params = { "ssid": "as", "beacon_int": "2000",
2400 "radius_server_clients": "auth_serv/radius_clients.conf",
2401 "radius_server_auth_port": '18128',
2403 "eap_user_file": "sqlite:" + dbfile,
2404 "ca_cert": "auth_serv/ca.pem",
2405 "server_cert": "auth_serv/server.pem",
2406 "private_key": "auth_serv/server.key",
2407 "subscr_remediation_url": "https://example.org/",
2408 "subscr_remediation_method": "1" }
2409 hostapd.add_ap(apdev[1]['ifname'], params)
2411 bssid = apdev[0]['bssid']
2412 params = hs20_ap_params()
2413 params['auth_server_port'] = "18128"
2414 hostapd.add_ap(apdev[0]['ifname'], params)
2416 dev[0].request("SET pmf 1")
2417 dev[0].hs20_enable()
2418 id = dev[0].add_cred_values({ 'realm': "example.com",
2419 'username': "user-mschapv2",
2420 'password': "password",
2421 'ca_cert': "auth_serv/ca.pem" })
2422 interworking_select(dev[0], bssid, freq="2412")
2423 interworking_connect(dev[0], bssid, "TTLS")
2424 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
2426 raise Exception("Timeout on subscription remediation notice")
2427 if " 1 https://example.org/" not in ev:
2428 raise Exception("Unexpected subscription remediation event contents")
2432 cur.execute("SELECT * from authlog")
2433 rows = cur.fetchall()
2435 raise Exception("No authlog entries")
2439 dev[0].request("SET pmf 0")
2441 def test_ap_hs20_external_selection(dev, apdev):
2442 """Hotspot 2.0 connection using external network selection and creation"""
2443 check_eap_capa(dev[0], "MSCHAPV2")
2444 bssid = apdev[0]['bssid']
2445 params = hs20_ap_params()
2446 params['hessid'] = bssid
2447 params['disable_dgaf'] = '1'
2448 hostapd.add_ap(apdev[0]['ifname'], params)
2450 dev[0].hs20_enable()
2451 dev[0].connect("test-hs20", proto="RSN", key_mgmt="WPA-EAP", eap="TTLS",
2452 identity="hs20-test", password="password",
2453 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
2454 scan_freq="2412", update_identifier="54321")
2455 if dev[0].get_status_field("hs20") != "2":
2456 raise Exception("Unexpected hs20 indication")
2458 def test_ap_hs20_random_mac_addr(dev, apdev):
2459 """Hotspot 2.0 connection with random MAC address"""
2460 check_eap_capa(dev[0], "MSCHAPV2")
2461 bssid = apdev[0]['bssid']
2462 params = hs20_ap_params()
2463 params['hessid'] = bssid
2464 params['disable_dgaf'] = '1'
2465 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2467 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2468 wpas.interface_add("wlan5")
2469 addr = wpas.p2p_interface_addr()
2470 wpas.request("SET mac_addr 1")
2471 wpas.request("SET preassoc_mac_addr 1")
2472 wpas.request("SET rand_addr_lifetime 60")
2474 wpas.flush_scan_cache()
2475 id = wpas.add_cred_values({ 'realm': "example.com",
2476 'username': "hs20-test",
2477 'password': "password",
2478 'ca_cert': "auth_serv/ca.pem",
2479 'domain': "example.com",
2480 'update_identifier': "1234" })
2481 interworking_select(wpas, bssid, "home", freq="2412")
2482 interworking_connect(wpas, bssid, "TTLS")
2483 addr1 = wpas.get_driver_status_field("addr")
2485 raise Exception("Did not use random MAC address")
2487 sta = hapd.get_sta(addr)
2488 if sta['addr'] != "FAIL":
2489 raise Exception("Unexpected STA association with permanent address")
2490 sta = hapd.get_sta(addr1)
2491 if sta['addr'] != addr1:
2492 raise Exception("STA association with random address not found")
2494 def test_ap_hs20_multi_network_and_cred_removal(dev, apdev):
2495 """Multiple networks and cred removal"""
2496 check_eap_capa(dev[0], "MSCHAPV2")
2497 bssid = apdev[0]['bssid']
2498 params = hs20_ap_params()
2499 params['nai_realm'] = [ "0,example.com,25[3:26]"]
2500 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2502 dev[0].add_network()
2503 dev[0].hs20_enable()
2504 id = dev[0].add_cred_values({ 'realm': "example.com",
2506 'password': "password" })
2507 interworking_select(dev[0], bssid, freq="2412")
2508 interworking_connect(dev[0], bssid, "PEAP")
2509 dev[0].add_network()
2511 dev[0].request("DISCONNECT")
2512 dev[0].wait_disconnected(timeout=10)
2515 hapd.set("ssid", "another ssid")
2518 interworking_select(dev[0], bssid, freq="2412")
2519 interworking_connect(dev[0], bssid, "PEAP")
2520 dev[0].add_network()
2521 if len(dev[0].list_networks()) != 5:
2522 raise Exception("Unexpected number of networks prior to remove_crec")
2524 dev[0].dump_monitor()
2525 dev[0].remove_cred(id)
2526 if len(dev[0].list_networks()) != 3:
2527 raise Exception("Unexpected number of networks after to remove_crec")
2528 dev[0].wait_disconnected(timeout=10)
2530 def test_ap_hs20_interworking_add_network(dev, apdev):
2531 """Hotspot 2.0 connection using INTERWORKING_ADD_NETWORK"""
2532 check_eap_capa(dev[0], "MSCHAPV2")
2533 bssid = apdev[0]['bssid']
2534 params = hs20_ap_params()
2535 params['nai_realm'] = [ "0,example.com,21[3:26][6:7][99:99]" ]
2536 hostapd.add_ap(apdev[0]['ifname'], params)
2538 dev[0].hs20_enable()
2539 dev[0].add_cred_values(default_cred(user="user"))
2540 interworking_select(dev[0], bssid, freq=2412)
2541 id = dev[0].interworking_add_network(bssid)
2542 dev[0].select_network(id, freq=2412)
2543 dev[0].wait_connected()
2545 def _test_ap_hs20_proxyarp(dev, apdev):
2546 bssid = apdev[0]['bssid']
2547 params = hs20_ap_params()
2548 params['hessid'] = bssid
2549 params['disable_dgaf'] = '0'
2550 params['proxy_arp'] = '1'
2551 hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
2552 if "OK" in hapd.request("ENABLE"):
2553 raise Exception("Incomplete hostapd configuration was accepted")
2554 hapd.set("ap_isolate", "1")
2555 if "OK" in hapd.request("ENABLE"):
2556 raise Exception("Incomplete hostapd configuration was accepted")
2557 hapd.set('bridge', 'ap-br0')
2562 # For now, do not report failures due to missing kernel support
2563 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2564 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
2566 raise Exception("AP startup timed out")
2567 if "AP-ENABLED" not in ev:
2568 raise Exception("AP startup failed")
2570 dev[0].hs20_enable()
2571 subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
2572 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2574 id = dev[0].add_cred_values({ 'realm': "example.com",
2575 'username': "hs20-test",
2576 'password': "password",
2577 'ca_cert': "auth_serv/ca.pem",
2578 'domain': "example.com",
2579 'update_identifier': "1234" })
2580 interworking_select(dev[0], bssid, "home", freq="2412")
2581 interworking_connect(dev[0], bssid, "TTLS")
2583 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS",
2584 identity="hs20-test", password="password",
2585 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
2589 addr0 = dev[0].p2p_interface_addr()
2590 addr1 = dev[1].p2p_interface_addr()
2592 src_ll_opt0 = "\x01\x01" + binascii.unhexlify(addr0.replace(':',''))
2593 src_ll_opt1 = "\x01\x01" + binascii.unhexlify(addr1.replace(':',''))
2595 pkt = build_ns(src_ll=addr0, ip_src="aaaa:bbbb:cccc::2",
2596 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:cccc::2",
2598 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
2599 raise Exception("DATA_TEST_FRAME failed")
2601 pkt = build_ns(src_ll=addr1, ip_src="aaaa:bbbb:dddd::2",
2602 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:dddd::2",
2604 if "OK" not in dev[1].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
2605 raise Exception("DATA_TEST_FRAME failed")
2607 pkt = build_ns(src_ll=addr1, ip_src="aaaa:bbbb:eeee::2",
2608 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:eeee::2",
2610 if "OK" not in dev[1].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
2611 raise Exception("DATA_TEST_FRAME failed")
2613 matches = get_permanent_neighbors("ap-br0")
2614 logger.info("After connect: " + str(matches))
2615 if len(matches) != 3:
2616 raise Exception("Unexpected number of neighbor entries after connect")
2617 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches:
2618 raise Exception("dev0 addr missing")
2619 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches:
2620 raise Exception("dev1 addr(1) missing")
2621 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches:
2622 raise Exception("dev1 addr(2) missing")
2623 dev[0].request("DISCONNECT")
2624 dev[1].request("DISCONNECT")
2626 matches = get_permanent_neighbors("ap-br0")
2627 logger.info("After disconnect: " + str(matches))
2628 if len(matches) > 0:
2629 raise Exception("Unexpected neighbor entries after disconnect")
2631 def test_ap_hs20_hidden_ssid_in_scan_res(dev, apdev):
2632 """Hotspot 2.0 connection with hidden SSId in scan results"""
2633 check_eap_capa(dev[0], "MSCHAPV2")
2634 bssid = apdev[0]['bssid']
2636 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": 'secret',
2637 "ignore_broadcast_ssid": "1" })
2638 dev[0].scan_for_bss(bssid, freq=2412)
2640 hapd_global = hostapd.HostapdGlobal()
2642 hapd_global.remove(apdev[0]['ifname'])
2644 params = hs20_ap_params()
2645 params['hessid'] = bssid
2646 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2648 dev[0].hs20_enable()
2649 id = dev[0].add_cred_values({ 'realm': "example.com",
2650 'username': "hs20-test",
2651 'password': "password",
2652 'ca_cert': "auth_serv/ca.pem",
2653 'domain': "example.com" })
2654 interworking_select(dev[0], bssid, "home", freq="2412")
2655 interworking_connect(dev[0], bssid, "TTLS")
2657 # clear BSS table to avoid issues in following test cases
2658 dev[0].request("DISCONNECT")
2659 dev[0].wait_disconnected()
2661 dev[0].flush_scan_cache()
2662 dev[0].flush_scan_cache()
2664 def test_ap_hs20_proxyarp(dev, apdev):
2665 """Hotspot 2.0 and ProxyARP"""
2666 check_eap_capa(dev[0], "MSCHAPV2")
2668 _test_ap_hs20_proxyarp(dev, apdev)
2670 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2671 stderr=open('/dev/null', 'w'))
2672 subprocess.call(['brctl', 'delbr', 'ap-br0'],
2673 stderr=open('/dev/null', 'w'))
2675 def _test_ap_hs20_proxyarp_dgaf(dev, apdev, disabled):
2676 bssid = apdev[0]['bssid']
2677 params = hs20_ap_params()
2678 params['hessid'] = bssid
2679 params['disable_dgaf'] = '1' if disabled else '0'
2680 params['proxy_arp'] = '1'
2681 params['na_mcast_to_ucast'] = '1'
2682 params['ap_isolate'] = '1'
2683 params['bridge'] = 'ap-br0'
2684 hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
2688 # For now, do not report failures due to missing kernel support
2689 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2690 ev = hapd.wait_event(["AP-ENABLED"], timeout=10)
2692 raise Exception("AP startup timed out")
2694 dev[0].hs20_enable()
2695 subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
2696 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2698 id = dev[0].add_cred_values({ 'realm': "example.com",
2699 'username': "hs20-test",
2700 'password': "password",
2701 'ca_cert': "auth_serv/ca.pem",
2702 'domain': "example.com",
2703 'update_identifier': "1234" })
2704 interworking_select(dev[0], bssid, "home", freq="2412")
2705 interworking_connect(dev[0], bssid, "TTLS")
2707 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS",
2708 identity="hs20-test", password="password",
2709 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
2713 addr0 = dev[0].p2p_interface_addr()
2715 src_ll_opt0 = "\x01\x01" + binascii.unhexlify(addr0.replace(':',''))
2717 pkt = build_ns(src_ll=addr0, ip_src="aaaa:bbbb:cccc::2",
2718 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:cccc::2",
2720 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt)):
2721 raise Exception("DATA_TEST_FRAME failed")
2723 pkt = build_ra(src_ll=apdev[0]['bssid'], ip_src="aaaa:bbbb:cccc::33",
2725 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
2726 raise Exception("DATA_TEST_FRAME failed")
2728 pkt = build_na(src_ll=apdev[0]['bssid'], ip_src="aaaa:bbbb:cccc::44",
2729 ip_dst="ff01::1", target="aaaa:bbbb:cccc::55")
2730 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
2731 raise Exception("DATA_TEST_FRAME failed")
2733 pkt = build_dhcp_ack(dst_ll="ff:ff:ff:ff:ff:ff", src_ll=bssid,
2734 ip_src="192.168.1.1", ip_dst="255.255.255.255",
2735 yiaddr="192.168.1.123", chaddr=addr0)
2736 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
2737 raise Exception("DATA_TEST_FRAME failed")
2738 # another copy for additional code coverage
2739 pkt = build_dhcp_ack(dst_ll=addr0, src_ll=bssid,
2740 ip_src="192.168.1.1", ip_dst="255.255.255.255",
2741 yiaddr="192.168.1.123", chaddr=addr0)
2742 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
2743 raise Exception("DATA_TEST_FRAME failed")
2745 matches = get_permanent_neighbors("ap-br0")
2746 logger.info("After connect: " + str(matches))
2747 if len(matches) != 2:
2748 raise Exception("Unexpected number of neighbor entries after connect")
2749 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches:
2750 raise Exception("dev0 addr missing")
2751 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches:
2752 raise Exception("dev0 IPv4 addr missing")
2753 dev[0].request("DISCONNECT")
2754 dev[1].request("DISCONNECT")
2756 matches = get_permanent_neighbors("ap-br0")
2757 logger.info("After disconnect: " + str(matches))
2758 if len(matches) > 0:
2759 raise Exception("Unexpected neighbor entries after disconnect")
2761 def test_ap_hs20_proxyarp_disable_dgaf(dev, apdev):
2762 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
2763 check_eap_capa(dev[0], "MSCHAPV2")
2765 _test_ap_hs20_proxyarp_dgaf(dev, apdev, True)
2767 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2768 stderr=open('/dev/null', 'w'))
2769 subprocess.call(['brctl', 'delbr', 'ap-br0'],
2770 stderr=open('/dev/null', 'w'))
2772 def test_ap_hs20_proxyarp_enable_dgaf(dev, apdev):
2773 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
2774 check_eap_capa(dev[0], "MSCHAPV2")
2776 _test_ap_hs20_proxyarp_dgaf(dev, apdev, False)
2778 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2779 stderr=open('/dev/null', 'w'))
2780 subprocess.call(['brctl', 'delbr', 'ap-br0'],
2781 stderr=open('/dev/null', 'w'))
2783 def ip_checksum(buf):
2787 for i in range(0, len(buf), 2):
2788 val, = struct.unpack('H', buf[i:i+2])
2791 sum = (sum & 0xffff) + (sum >> 16)
2792 return struct.pack('H', ~sum & 0xffff)
2794 def ipv6_solicited_node_mcaddr(target):
2795 prefix = socket.inet_pton(socket.AF_INET6, "ff02::1:ff00:0")
2796 mask = socket.inet_pton(socket.AF_INET6, "::ff:ffff")
2797 _target = socket.inet_pton(socket.AF_INET6, target)
2798 p = struct.unpack('4I', prefix)
2799 m = struct.unpack('4I', mask)
2800 t = struct.unpack('4I', _target)
2801 res = (p[0] | (t[0] & m[0]),
2802 p[1] | (t[1] & m[1]),
2803 p[2] | (t[2] & m[2]),
2804 p[3] | (t[3] & m[3]))
2805 return socket.inet_ntop(socket.AF_INET6, struct.pack('4I', *res))
2807 def build_icmpv6(ipv6_addrs, type, code, payload):
2808 start = struct.pack("BB", type, code)
2810 icmp = start + '\x00\x00' + end
2811 pseudo = ipv6_addrs + struct.pack(">LBBBB", len(icmp), 0, 0, 0, 58)
2812 csum = ip_checksum(pseudo + icmp)
2813 return start + csum + end
2815 def build_ra(src_ll, ip_src, ip_dst, cur_hop_limit=0, router_lifetime=0,
2816 reachable_time=0, retrans_timer=0, opt=None):
2817 link_mc = binascii.unhexlify("3333ff000002")
2818 _src_ll = binascii.unhexlify(src_ll.replace(':',''))
2820 ehdr = link_mc + _src_ll + proto
2821 _ip_src = socket.inet_pton(socket.AF_INET6, ip_src)
2822 _ip_dst = socket.inet_pton(socket.AF_INET6, ip_dst)
2824 adv = struct.pack('>BBHLL', cur_hop_limit, 0, router_lifetime,
2825 reachable_time, retrans_timer)
2830 icmp = build_icmpv6(_ip_src + _ip_dst, 134, 0, payload)
2832 ipv6 = struct.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp), 58, 255)
2833 ipv6 += _ip_src + _ip_dst
2835 return ehdr + ipv6 + icmp
2837 def build_ns(src_ll, ip_src, ip_dst, target, opt=None):
2838 link_mc = binascii.unhexlify("3333ff000002")
2839 _src_ll = binascii.unhexlify(src_ll.replace(':',''))
2841 ehdr = link_mc + _src_ll + proto
2842 _ip_src = socket.inet_pton(socket.AF_INET6, ip_src)
2844 ip_dst = ipv6_solicited_node_mcaddr(target)
2845 _ip_dst = socket.inet_pton(socket.AF_INET6, ip_dst)
2847 reserved = '\x00\x00\x00\x00'
2848 _target = socket.inet_pton(socket.AF_INET6, target)
2850 payload = reserved + _target + opt
2852 payload = reserved + _target
2853 icmp = build_icmpv6(_ip_src + _ip_dst, 135, 0, payload)
2855 ipv6 = struct.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp), 58, 255)
2856 ipv6 += _ip_src + _ip_dst
2858 return ehdr + ipv6 + icmp
2860 def send_ns(dev, src_ll=None, target=None, ip_src=None, ip_dst=None, opt=None,
2865 cmd = "DATA_TEST_FRAME ifname=ap-br0 "
2868 src_ll = dev.p2p_interface_addr()
2869 cmd = "DATA_TEST_FRAME "
2872 opt = "\x01\x01" + binascii.unhexlify(src_ll.replace(':',''))
2874 pkt = build_ns(src_ll=src_ll, ip_src=ip_src, ip_dst=ip_dst, target=target,
2876 if "OK" not in dev.request(cmd + binascii.hexlify(pkt)):
2877 raise Exception("DATA_TEST_FRAME failed")
2879 def build_na(src_ll, ip_src, ip_dst, target, opt=None):
2880 link_mc = binascii.unhexlify("3333ff000002")
2881 _src_ll = binascii.unhexlify(src_ll.replace(':',''))
2883 ehdr = link_mc + _src_ll + proto
2884 _ip_src = socket.inet_pton(socket.AF_INET6, ip_src)
2885 _ip_dst = socket.inet_pton(socket.AF_INET6, ip_dst)
2887 reserved = '\x00\x00\x00\x00'
2888 _target = socket.inet_pton(socket.AF_INET6, target)
2890 payload = reserved + _target + opt
2892 payload = reserved + _target
2893 icmp = build_icmpv6(_ip_src + _ip_dst, 136, 0, payload)
2895 ipv6 = struct.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp), 58, 255)
2896 ipv6 += _ip_src + _ip_dst
2898 return ehdr + ipv6 + icmp
2900 def send_na(dev, src_ll=None, target=None, ip_src=None, ip_dst=None, opt=None,
2905 cmd = "DATA_TEST_FRAME ifname=ap-br0 "
2908 src_ll = dev.p2p_interface_addr()
2909 cmd = "DATA_TEST_FRAME "
2911 pkt = build_na(src_ll=src_ll, ip_src=ip_src, ip_dst=ip_dst, target=target,
2913 if "OK" not in dev.request(cmd + binascii.hexlify(pkt)):
2914 raise Exception("DATA_TEST_FRAME failed")
2916 def build_dhcp_ack(dst_ll, src_ll, ip_src, ip_dst, yiaddr, chaddr,
2917 subnet_mask="255.255.255.0", truncated_opt=False,
2918 wrong_magic=False, force_tot_len=None, no_dhcp=False):
2919 _dst_ll = binascii.unhexlify(dst_ll.replace(':',''))
2920 _src_ll = binascii.unhexlify(src_ll.replace(':',''))
2922 ehdr = _dst_ll + _src_ll + proto
2923 _ip_src = socket.inet_pton(socket.AF_INET, ip_src)
2924 _ip_dst = socket.inet_pton(socket.AF_INET, ip_dst)
2925 _subnet_mask = socket.inet_pton(socket.AF_INET, subnet_mask)
2927 _ciaddr = '\x00\x00\x00\x00'
2928 _yiaddr = socket.inet_pton(socket.AF_INET, yiaddr)
2929 _siaddr = '\x00\x00\x00\x00'
2930 _giaddr = '\x00\x00\x00\x00'
2931 _chaddr = binascii.unhexlify(chaddr.replace(':','') + "00000000000000000000")
2932 payload = struct.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2933 payload += _ciaddr + _yiaddr + _siaddr + _giaddr + _chaddr + 192*'\x00'
2936 payload += '\x63\x82\x53\x00'
2938 payload += '\x63\x82\x53\x63'
2940 payload += '\x22\xff\x00'
2941 # Option: DHCP Message Type = ACK
2942 payload += '\x35\x01\x05'
2945 # Option: Subnet Mask
2946 payload += '\x01\x04' + _subnet_mask
2947 # Option: Time Offset
2948 payload += struct.pack('>BBL', 2, 4, 0)
2952 payload += '\x00\x00\x00\x00'
2955 payload = struct.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2956 payload += _ciaddr + _yiaddr + _siaddr + _giaddr + _chaddr + 192*'\x00'
2958 udp = struct.pack('>HHHH', 67, 68, 8 + len(payload), 0) + payload
2961 tot_len = force_tot_len
2963 tot_len = 20 + len(udp)
2964 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
2965 ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
2966 csum = ip_checksum(ipv4)
2967 ipv4 = start + csum + _ip_src + _ip_dst
2969 return ehdr + ipv4 + udp
2971 def build_arp(dst_ll, src_ll, opcode, sender_mac, sender_ip,
2972 target_mac, target_ip):
2973 _dst_ll = binascii.unhexlify(dst_ll.replace(':',''))
2974 _src_ll = binascii.unhexlify(src_ll.replace(':',''))
2976 ehdr = _dst_ll + _src_ll + proto
2978 _sender_mac = binascii.unhexlify(sender_mac.replace(':',''))
2979 _sender_ip = socket.inet_pton(socket.AF_INET, sender_ip)
2980 _target_mac = binascii.unhexlify(target_mac.replace(':',''))
2981 _target_ip = socket.inet_pton(socket.AF_INET, target_ip)
2983 arp = struct.pack('>HHBBH', 1, 0x0800, 6, 4, opcode)
2984 arp += _sender_mac + _sender_ip
2985 arp += _target_mac + _target_ip
2989 def send_arp(dev, dst_ll="ff:ff:ff:ff:ff:ff", src_ll=None, opcode=1,
2990 sender_mac=None, sender_ip="0.0.0.0",
2991 target_mac="00:00:00:00:00:00", target_ip="0.0.0.0",
2996 if sender_mac is None:
2997 sender_mac = hapd_bssid
2998 cmd = "DATA_TEST_FRAME ifname=ap-br0 "
3001 src_ll = dev.p2p_interface_addr()
3002 if sender_mac is None:
3003 sender_mac = dev.p2p_interface_addr()
3004 cmd = "DATA_TEST_FRAME "
3006 pkt = build_arp(dst_ll=dst_ll, src_ll=src_ll, opcode=opcode,
3007 sender_mac=sender_mac, sender_ip=sender_ip,
3008 target_mac=target_mac, target_ip=target_ip)
3009 if "OK" not in dev.request(cmd + binascii.hexlify(pkt)):
3010 raise Exception("DATA_TEST_FRAME failed")
3012 def get_permanent_neighbors(ifname):
3013 cmd = subprocess.Popen(['ip', 'nei'], stdout=subprocess.PIPE)
3014 res = cmd.stdout.read()
3016 return [ line for line in res.splitlines() if "PERMANENT" in line and ifname in line ]
3018 def get_bridge_macs(ifname):
3019 cmd = subprocess.Popen(['brctl', 'showmacs', ifname],
3020 stdout=subprocess.PIPE)
3021 res = cmd.stdout.read()
3025 def tshark_get_arp(cap, filter):
3026 res = run_tshark(cap, filter,
3027 [ "eth.dst", "eth.src",
3028 "arp.src.hw_mac", "arp.src.proto_ipv4",
3029 "arp.dst.hw_mac", "arp.dst.proto_ipv4" ],
3032 for l in res.splitlines():
3033 frames.append(l.split('\t'))
3036 def tshark_get_ns(cap):
3037 res = run_tshark(cap, "icmpv6.type == 135",
3038 [ "eth.dst", "eth.src",
3039 "ipv6.src", "ipv6.dst",
3040 "icmpv6.nd.ns.target_address",
3041 "icmpv6.opt.linkaddr" ],
3044 for l in res.splitlines():
3045 frames.append(l.split('\t'))
3048 def tshark_get_na(cap):
3049 res = run_tshark(cap, "icmpv6.type == 136",
3050 [ "eth.dst", "eth.src",
3051 "ipv6.src", "ipv6.dst",
3052 "icmpv6.nd.na.target_address",
3053 "icmpv6.opt.linkaddr" ],
3056 for l in res.splitlines():
3057 frames.append(l.split('\t'))
3060 def _test_proxyarp_open(dev, apdev, params, ebtables=False):
3061 prefix = "proxyarp_open"
3063 prefix += "_ebtables"
3064 cap_br = os.path.join(params['logdir'], prefix + ".ap-br0.pcap")
3065 cap_dev0 = os.path.join(params['logdir'],
3066 prefix + ".%s.pcap" % dev[0].ifname)
3067 cap_dev1 = os.path.join(params['logdir'],
3068 prefix + ".%s.pcap" % dev[1].ifname)
3069 cap_dev2 = os.path.join(params['logdir'],
3070 prefix + ".%s.pcap" % dev[2].ifname)
3072 bssid = apdev[0]['bssid']
3073 params = { 'ssid': 'open' }
3074 params['proxy_arp'] = '1'
3075 hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
3076 hapd.set("ap_isolate", "1")
3077 hapd.set('bridge', 'ap-br0')
3082 # For now, do not report failures due to missing kernel support
3083 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
3084 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10)
3086 raise Exception("AP startup timed out")
3087 if "AP-ENABLED" not in ev:
3088 raise Exception("AP startup failed")
3090 params2 = { 'ssid': 'another' }
3091 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params2, no_enable=True)
3092 hapd2.set('bridge', 'ap-br0')
3095 subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
3096 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
3099 for chain in [ 'FORWARD', 'OUTPUT' ]:
3100 subprocess.call(['ebtables', '-A', chain, '-p', 'ARP',
3101 '-d', 'Broadcast', '-o', apdev[0]['ifname'],
3103 subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
3104 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3105 '--ip6-icmp-type', 'neighbor-solicitation',
3106 '-o', apdev[0]['ifname'], '-j', 'DROP'])
3107 subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
3108 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3109 '--ip6-icmp-type', 'neighbor-advertisement',
3110 '-o', apdev[0]['ifname'], '-j', 'DROP'])
3111 subprocess.call(['ebtables', '-A', chain,
3112 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3113 '--ip6-icmp-type', 'router-solicitation',
3114 '-o', apdev[0]['ifname'], '-j', 'DROP'])
3115 # Multicast Listener Report Message
3116 subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast',
3117 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3118 '--ip6-icmp-type', '143',
3119 '-o', apdev[0]['ifname'], '-j', 'DROP'])
3123 cmd[0] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
3124 '-w', cap_br, '-s', '2000'],
3125 stderr=open('/dev/null', 'w'))
3126 cmd[1] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[0].ifname,
3127 '-w', cap_dev0, '-s', '2000'],
3128 stderr=open('/dev/null', 'w'))
3129 cmd[2] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[1].ifname,
3130 '-w', cap_dev1, '-s', '2000'],
3131 stderr=open('/dev/null', 'w'))
3132 cmd[3] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', dev[2].ifname,
3133 '-w', cap_dev2, '-s', '2000'],
3134 stderr=open('/dev/null', 'w'))
3136 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3137 dev[1].connect("open", key_mgmt="NONE", scan_freq="2412")
3138 dev[2].connect("another", key_mgmt="NONE", scan_freq="2412")
3141 brcmd = subprocess.Popen(['brctl', 'show'], stdout=subprocess.PIPE)
3142 res = brcmd.stdout.read()
3143 brcmd.stdout.close()
3144 logger.info("Bridge setup: " + res)
3146 brcmd = subprocess.Popen(['brctl', 'showstp', 'ap-br0'],
3147 stdout=subprocess.PIPE)
3148 res = brcmd.stdout.read()
3149 brcmd.stdout.close()
3150 logger.info("Bridge showstp: " + res)
3152 addr0 = dev[0].p2p_interface_addr()
3153 addr1 = dev[1].p2p_interface_addr()
3154 addr2 = dev[2].p2p_interface_addr()
3156 src_ll_opt0 = "\x01\x01" + binascii.unhexlify(addr0.replace(':',''))
3157 src_ll_opt1 = "\x01\x01" + binascii.unhexlify(addr1.replace(':',''))
3160 send_ns(dev[0], ip_src="::", target="aaaa:bbbb:cccc::2")
3162 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2")
3163 # test frame without source link-layer address option
3164 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
3166 # test frame with bogus option
3167 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
3168 opt="\x70\x01\x01\x02\x03\x04\x05\x05")
3169 # test frame with truncated source link-layer address option
3170 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
3171 opt="\x01\x01\x01\x02\x03\x04")
3172 # test frame with foreign source link-layer address option
3173 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2",
3174 opt="\x01\x01\x01\x02\x03\x04\x05\x06")
3176 send_ns(dev[1], ip_src="aaaa:bbbb:dddd::2", target="aaaa:bbbb:dddd::2")
3178 send_ns(dev[1], ip_src="aaaa:bbbb:eeee::2", target="aaaa:bbbb:eeee::2")
3179 # another copy for additional code coverage
3180 send_ns(dev[1], ip_src="aaaa:bbbb:eeee::2", target="aaaa:bbbb:eeee::2")
3182 pkt = build_dhcp_ack(dst_ll="ff:ff:ff:ff:ff:ff", src_ll=bssid,
3183 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3184 yiaddr="192.168.1.124", chaddr=addr0)
3185 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3186 raise Exception("DATA_TEST_FRAME failed")
3187 # Change address and verify unicast
3188 pkt = build_dhcp_ack(dst_ll=addr0, src_ll=bssid,
3189 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3190 yiaddr="192.168.1.123", chaddr=addr0)
3191 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3192 raise Exception("DATA_TEST_FRAME failed")
3194 # Not-associated client MAC address
3195 pkt = build_dhcp_ack(dst_ll="ff:ff:ff:ff:ff:ff", src_ll=bssid,
3196 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3197 yiaddr="192.168.1.125", chaddr="22:33:44:55:66:77")
3198 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3199 raise Exception("DATA_TEST_FRAME failed")
3202 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid,
3203 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3204 yiaddr="0.0.0.0", chaddr=addr1)
3205 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3206 raise Exception("DATA_TEST_FRAME failed")
3209 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid,
3210 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3211 yiaddr="192.168.1.126", chaddr=addr1,
3212 subnet_mask="0.0.0.0")
3213 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3214 raise Exception("DATA_TEST_FRAME failed")
3217 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid,
3218 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3219 yiaddr="192.168.1.127", chaddr=addr1,
3221 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3222 raise Exception("DATA_TEST_FRAME failed")
3225 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid,
3226 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3227 yiaddr="192.168.1.128", chaddr=addr1,
3229 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3230 raise Exception("DATA_TEST_FRAME failed")
3232 # Wrong IPv4 total length
3233 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid,
3234 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3235 yiaddr="192.168.1.129", chaddr=addr1,
3237 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3238 raise Exception("DATA_TEST_FRAME failed")
3241 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid,
3242 ip_src="192.168.1.1", ip_dst="255.255.255.255",
3243 yiaddr="192.168.1.129", chaddr=addr1,
3245 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
3246 raise Exception("DATA_TEST_FRAME failed")
3248 macs = get_bridge_macs("ap-br0")
3249 logger.info("After connect (showmacs): " + str(macs))
3251 matches = get_permanent_neighbors("ap-br0")
3252 logger.info("After connect: " + str(matches))
3253 if len(matches) != 4:
3254 raise Exception("Unexpected number of neighbor entries after connect")
3255 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches:
3256 raise Exception("dev0 addr missing")
3257 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches:
3258 raise Exception("dev1 addr(1) missing")
3259 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches:
3260 raise Exception("dev1 addr(2) missing")
3261 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches:
3262 raise Exception("dev0 IPv4 addr missing")
3264 targets = [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
3266 for target in targets:
3267 send_arp(dev[1], sender_ip="192.168.1.100", target_ip=target)
3269 for target in targets:
3270 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.101",
3273 for target in targets:
3274 send_arp(dev[2], sender_ip="192.168.1.103", target_ip=target)
3276 # ARP Probe from wireless STA
3277 send_arp(dev[1], target_ip="192.168.1.127")
3278 # ARP Announcement from wireless STA
3279 send_arp(dev[1], sender_ip="192.168.1.127", target_ip="192.168.1.127")
3280 send_arp(dev[1], sender_ip="192.168.1.127", target_ip="192.168.1.127",
3283 macs = get_bridge_macs("ap-br0")
3284 logger.info("After ARP Probe + Announcement (showmacs): " + str(macs))
3286 matches = get_permanent_neighbors("ap-br0")
3287 logger.info("After ARP Probe + Announcement: " + str(matches))
3289 # ARP Request for the newly introduced IP address from wireless STA
3290 send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.127")
3292 # ARP Request for the newly introduced IP address from bridge
3293 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.102",
3294 target_ip="192.168.1.127")
3295 send_arp(dev[2], sender_ip="192.168.1.103", target_ip="192.168.1.127")
3297 # ARP Probe from bridge
3298 send_arp(hapd, hapd_bssid=bssid, target_ip="192.168.1.130")
3299 send_arp(dev[2], target_ip="192.168.1.131")
3300 # ARP Announcement from bridge (not to be learned by AP for proxyarp)
3301 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.130",
3302 target_ip="192.168.1.130")
3303 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.130",
3304 target_ip="192.168.1.130", opcode=2)
3305 send_arp(dev[2], sender_ip="192.168.1.131", target_ip="192.168.1.131")
3306 send_arp(dev[2], sender_ip="192.168.1.131", target_ip="192.168.1.131",
3309 macs = get_bridge_macs("ap-br0")
3310 logger.info("After ARP Probe + Announcement (showmacs): " + str(macs))
3312 matches = get_permanent_neighbors("ap-br0")
3313 logger.info("After ARP Probe + Announcement: " + str(matches))
3315 # ARP Request for the newly introduced IP address from wireless STA
3316 send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.130")
3317 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3318 send_arp(hapd, hapd_bssid=bssid, dst_ll=addr0, sender_ip="192.168.1.130",
3319 target_ip="192.168.1.123", opcode=2)
3321 # ARP Request for the newly introduced IP address from wireless STA
3322 send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.131")
3323 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3324 send_arp(dev[2], dst_ll=addr0, sender_ip="192.168.1.131",
3325 target_ip="192.168.1.123", opcode=2)
3327 # ARP Request for the newly introduced IP address from bridge
3328 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.102",
3329 target_ip="192.168.1.130")
3330 send_arp(dev[2], sender_ip="192.168.1.104", target_ip="192.168.1.131")
3332 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
3333 send_arp(dev[1], target_ip="192.168.1.123")
3334 # ARP Probe from wireless STA (duplicate address; learned through ARP)
3335 send_arp(dev[0], target_ip="192.168.1.127")
3337 # Gratuitous ARP Reply for another STA's IP address
3338 send_arp(dev[0], opcode=2, sender_mac=addr0, sender_ip="192.168.1.127",
3339 target_mac=addr1, target_ip="192.168.1.127")
3340 send_arp(dev[1], opcode=2, sender_mac=addr1, sender_ip="192.168.1.123",
3341 target_mac=addr0, target_ip="192.168.1.123")
3342 # ARP Request to verify previous mapping
3343 send_arp(dev[1], sender_ip="192.168.1.127", target_ip="192.168.1.123")
3344 send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.127")
3348 send_ns(dev[0], target="aaaa:bbbb:dddd::2", ip_src="aaaa:bbbb:cccc::2")
3350 send_ns(dev[1], target="aaaa:bbbb:cccc::2", ip_src="aaaa:bbbb:dddd::2")
3352 send_ns(hapd, hapd_bssid=bssid, target="aaaa:bbbb:dddd::2",
3353 ip_src="aaaa:bbbb:ffff::2")
3355 send_ns(dev[2], target="aaaa:bbbb:cccc::2", ip_src="aaaa:bbbb:ff00::2")
3357 send_ns(dev[2], target="aaaa:bbbb:dddd::2", ip_src="aaaa:bbbb:ff00::2")
3359 send_ns(dev[2], target="aaaa:bbbb:eeee::2", ip_src="aaaa:bbbb:ff00::2")
3362 # Try to probe for an already assigned address
3363 send_ns(dev[1], target="aaaa:bbbb:cccc::2", ip_src="::")
3365 send_ns(hapd, hapd_bssid=bssid, target="aaaa:bbbb:cccc::2", ip_src="::")
3367 send_ns(dev[2], target="aaaa:bbbb:cccc::2", ip_src="::")
3371 send_na(dev[1], target="aaaa:bbbb:cccc:aeae::3",
3372 ip_src="aaaa:bbbb:cccc:aeae::3", ip_dst="ff02::1")
3373 send_na(hapd, hapd_bssid=bssid, target="aaaa:bbbb:cccc:aeae::4",
3374 ip_src="aaaa:bbbb:cccc:aeae::4", ip_dst="ff02::1")
3375 send_na(dev[2], target="aaaa:bbbb:cccc:aeae::5",
3376 ip_src="aaaa:bbbb:cccc:aeae::5", ip_dst="ff02::1")
3379 hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
3380 except Exception, e:
3381 logger.info("test_connectibity_iface failed: " + str(e))
3382 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
3383 hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0")
3384 hwsim_utils.test_connectivity(dev[0], dev[1])
3386 dev[0].request("DISCONNECT")
3387 dev[1].request("DISCONNECT")
3389 for i in range(len(cmd)):
3391 macs = get_bridge_macs("ap-br0")
3392 logger.info("After disconnect (showmacs): " + str(macs))
3393 matches = get_permanent_neighbors("ap-br0")
3394 logger.info("After disconnect: " + str(matches))
3395 if len(matches) > 0:
3396 raise Exception("Unexpected neighbor entries after disconnect")
3398 cmd = subprocess.Popen(['ebtables', '-L', '--Lc'],
3399 stdout=subprocess.PIPE)
3400 res = cmd.stdout.read()
3402 logger.info("ebtables results:\n" + res)
3404 # Verify that expected ARP messages were seen and no unexpected
3405 # ARP messages were seen.
3407 arp_req = tshark_get_arp(cap_dev0, "arp.opcode == 1")
3408 arp_reply = tshark_get_arp(cap_dev0, "arp.opcode == 2")
3409 logger.info("dev0 seen ARP requests:\n" + str(arp_req))
3410 logger.info("dev0 seen ARP replies:\n" + str(arp_reply))
3412 if [ 'ff:ff:ff:ff:ff:ff', addr1,
3413 addr1, '192.168.1.100',
3414 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req:
3415 raise Exception("dev0 saw ARP request from dev1")
3416 if [ 'ff:ff:ff:ff:ff:ff', addr2,
3417 addr2, '192.168.1.103',
3418 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req:
3419 raise Exception("dev0 saw ARP request from dev2")
3420 # TODO: Uncomment once fixed in kernel
3421 #if [ 'ff:ff:ff:ff:ff:ff', bssid,
3422 # bssid, '192.168.1.101',
3423 # '00:00:00:00:00:00', '192.168.1.123' ] in arp_req:
3424 # raise Exception("dev0 saw ARP request from br")
3429 raise Exception("Unexpected foreign ARP request on dev0")
3431 arp_req = tshark_get_arp(cap_dev1, "arp.opcode == 1")
3432 arp_reply = tshark_get_arp(cap_dev1, "arp.opcode == 2")
3433 logger.info("dev1 seen ARP requests:\n" + str(arp_req))
3434 logger.info("dev1 seen ARP replies:\n" + str(arp_reply))
3436 if [ 'ff:ff:ff:ff:ff:ff', addr2,
3437 addr2, '192.168.1.103',
3438 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req:
3439 raise Exception("dev1 saw ARP request from dev2")
3440 if [addr1, addr0, addr0, '192.168.1.123', addr1, '192.168.1.100'] not in arp_reply:
3441 raise Exception("dev1 did not get ARP response for 192.168.1.123")
3446 raise Exception("Unexpected foreign ARP request on dev1")
3448 arp_req = tshark_get_arp(cap_dev2, "arp.opcode == 1")
3449 arp_reply = tshark_get_arp(cap_dev2, "arp.opcode == 2")
3450 logger.info("dev2 seen ARP requests:\n" + str(arp_req))
3451 logger.info("dev2 seen ARP replies:\n" + str(arp_reply))
3454 addr0, '192.168.1.123',
3455 addr2, '192.168.1.103' ] not in arp_reply:
3456 raise Exception("dev2 did not get ARP response for 192.168.1.123")
3458 arp_req = tshark_get_arp(cap_br, "arp.opcode == 1")
3459 arp_reply = tshark_get_arp(cap_br, "arp.opcode == 2")
3460 logger.info("br seen ARP requests:\n" + str(arp_req))
3461 logger.info("br seen ARP replies:\n" + str(arp_reply))
3463 # TODO: Uncomment once fixed in kernel
3465 # addr0, '192.168.1.123',
3466 # bssid, '192.168.1.101' ] not in arp_reply:
3467 # raise Exception("br did not get ARP response for 192.168.1.123")
3469 ns = tshark_get_ns(cap_dev0)
3470 logger.info("dev0 seen NS: " + str(ns))
3471 na = tshark_get_na(cap_dev0)
3472 logger.info("dev0 seen NA: " + str(na))
3474 if [ addr0, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2',
3475 'aaaa:bbbb:dddd::2', addr1 ] not in na:
3476 raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
3481 raise Exception("Unexpected foreign NS on dev0: " + str(req))
3483 ns = tshark_get_ns(cap_dev1)
3484 logger.info("dev1 seen NS: " + str(ns))
3485 na = tshark_get_na(cap_dev1)
3486 logger.info("dev1 seen NA: " + str(na))
3488 if [ addr1, addr0, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:dddd::2',
3489 'aaaa:bbbb:cccc::2', addr0 ] not in na:
3490 raise Exception("dev1 did not get NA for aaaa:bbbb:cccc::2")
3495 raise Exception("Unexpected foreign NS on dev1: " + str(req))
3497 ns = tshark_get_ns(cap_dev2)
3498 logger.info("dev2 seen NS: " + str(ns))
3499 na = tshark_get_na(cap_dev2)
3500 logger.info("dev2 seen NA: " + str(na))
3502 # FIX: enable once kernel implementation for proxyarp IPv6 is fixed
3503 #if [ addr2, addr0, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:ff00::2',
3504 # 'aaaa:bbbb:cccc::2', addr0 ] not in na:
3505 # raise Exception("dev2 did not get NA for aaaa:bbbb:cccc::2")
3506 #if [ addr2, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:ff00::2',
3507 # 'aaaa:bbbb:dddd::2', addr1 ] not in na:
3508 # raise Exception("dev2 did not get NA for aaaa:bbbb:dddd::2")
3509 #if [ addr2, addr1, 'aaaa:bbbb:eeee::2', 'aaaa:bbbb:ff00::2',
3510 # 'aaaa:bbbb:eeee::2', addr1 ] not in na:
3511 # raise Exception("dev2 did not get NA for aaaa:bbbb:eeee::2")
3513 def test_proxyarp_open(dev, apdev, params):
3514 """ProxyARP with open network"""
3516 _test_proxyarp_open(dev, apdev, params)
3518 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3519 stderr=open('/dev/null', 'w'))
3520 subprocess.call(['brctl', 'delbr', 'ap-br0'],
3521 stderr=open('/dev/null', 'w'))
3523 def test_proxyarp_open_ebtables(dev, apdev, params):
3524 """ProxyARP with open network"""
3526 _test_proxyarp_open(dev, apdev, params, ebtables=True)
3529 subprocess.call(['ebtables', '-F', 'FORWARD'])
3530 subprocess.call(['ebtables', '-F', 'OUTPUT'])
3533 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3534 stderr=open('/dev/null', 'w'))
3535 subprocess.call(['brctl', 'delbr', 'ap-br0'],
3536 stderr=open('/dev/null', 'w'))
3538 def test_ap_hs20_connect_deinit(dev, apdev):
3539 """Hotspot 2.0 connection interrupted with deinit"""
3540 check_eap_capa(dev[0], "MSCHAPV2")
3541 bssid = apdev[0]['bssid']
3542 params = hs20_ap_params()
3543 params['hessid'] = bssid
3544 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3546 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3547 wpas.interface_add("wlan5", drv_params="")
3549 wpas.flush_scan_cache()
3550 wpas.add_cred_values({ 'realm': "example.com",
3551 'username': "hs20-test",
3552 'password': "password",
3553 'ca_cert': "auth_serv/ca.pem",
3554 'domain': "example.com" })
3556 wpas.scan_for_bss(bssid, freq=2412)
3559 wpas.request("INTERWORKING_SELECT freq=2412")
3561 id = wpas.request("RADIO_WORK add block-work")
3562 ev = wpas.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout=5)
3564 raise Exception("Timeout while waiting radio work to start")
3565 ev = wpas.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout=5)
3567 raise Exception("Timeout while waiting radio work to start (2)")
3569 # Remove the interface while the gas-query radio work is still pending and
3570 # GAS query has not yet been started.
3571 wpas.interface_remove("wlan5")