]>
git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_hs20.py
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.
13 logger
= logging
.getLogger()
20 from utils
import HwsimSkip
, skip_with_fips
22 from tshark
import run_tshark
23 from wlantest
import Wlantest
24 from wpasupplicant
import WpaSupplicant
25 from test_ap_eap
import check_eap_capa
, check_domain_match_full
27 def hs20_ap_params(ssid
="test-hs20"):
28 params
= hostapd
.wpa2_params(ssid
=ssid
)
29 params
['wpa_key_mgmt'] = "WPA-EAP"
30 params
['ieee80211w'] = "1"
31 params
['ieee8021x'] = "1"
32 params
['auth_server_addr'] = "127.0.0.1"
33 params
['auth_server_port'] = "1812"
34 params
['auth_server_shared_secret'] = "radius"
35 params
['interworking'] = "1"
36 params
['access_network_type'] = "14"
37 params
['internet'] = "1"
41 params
['venue_group'] = "7"
42 params
['venue_type'] = "1"
43 params
['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
44 params
['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
46 params
['domain_name'] = "example.com,another.example.com"
47 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
48 "0,another.example.com" ]
50 params
['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
51 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
52 params
['hs20_operating_class'] = "5173"
53 params
['anqp_3gpp_cell_net'] = "244,91"
56 def check_auto_select(dev
, bssid
):
57 dev
.scan_for_bss(bssid
, freq
="2412")
58 dev
.request("INTERWORKING_SELECT auto freq=2412")
59 ev
= dev
.wait_connected(timeout
=15)
61 raise Exception("Connected to incorrect network")
62 dev
.request("REMOVE_NETWORK all")
63 dev
.wait_disconnected()
66 def interworking_select(dev
, bssid
, type=None, no_match
=False, freq
=None):
68 if bssid
and freq
and not no_match
:
69 dev
.scan_for_bss(bssid
, freq
=freq
)
70 freq_extra
= " freq=" + str(freq
) if freq
else ""
71 dev
.request("INTERWORKING_SELECT" + freq_extra
)
72 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
75 raise Exception("Network selection timed out");
77 if "INTERWORKING-NO-MATCH" not in ev
:
78 raise Exception("Unexpected network match")
80 if "INTERWORKING-NO-MATCH" in ev
:
81 logger
.info("Matching network not found - try again")
83 dev
.request("INTERWORKING_SELECT" + freq_extra
)
84 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
87 raise Exception("Network selection timed out");
88 if "INTERWORKING-NO-MATCH" in ev
:
89 raise Exception("Matching network not found")
90 if bssid
and bssid
not in ev
:
91 raise Exception("Unexpected BSSID in match")
92 if type and "type=" + type not in ev
:
93 raise Exception("Network type not recognized correctly")
95 def check_sp_type(dev
, sp_type
):
96 type = dev
.get_status_field("sp_type")
98 raise Exception("sp_type not available")
100 raise Exception("sp_type did not indicate home network")
102 def hlr_auc_gw_available():
103 if not os
.path
.exists("/tmp/hlr_auc_gw.sock"):
104 raise HwsimSkip("No hlr_auc_gw socket available")
105 if not os
.path
.exists("../../hostapd/hlr_auc_gw"):
106 raise HwsimSkip("No hlr_auc_gw available")
108 def interworking_ext_sim_connect(dev
, bssid
, method
):
109 dev
.request("INTERWORKING_CONNECT " + bssid
)
110 interworking_ext_sim_auth(dev
, method
)
112 def interworking_ext_sim_auth(dev
, method
):
113 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
115 raise Exception("Network connected timed out")
116 if "(" + method
+ ")" not in ev
:
117 raise Exception("Unexpected EAP method selection")
119 ev
= dev
.wait_event(["CTRL-REQ-SIM"], timeout
=15)
121 raise Exception("Wait for external SIM processing request timed out")
123 if p
[1] != "GSM-AUTH":
124 raise Exception("Unexpected CTRL-REQ-SIM type")
125 id = p
[0].split('-')[3]
126 rand
= p
[2].split(' ')[0]
128 res
= subprocess
.check_output(["../../hostapd/hlr_auc_gw",
130 "auth_serv/hlr_auc_gw.milenage_db",
131 "GSM-AUTH-REQ 232010000000000 " + rand
])
132 if "GSM-AUTH-RESP" not in res
:
133 raise Exception("Unexpected hlr_auc_gw response")
134 resp
= res
.split(' ')[2].rstrip()
136 dev
.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp
)
137 dev
.wait_connected(timeout
=15)
139 def interworking_connect(dev
, bssid
, method
):
140 dev
.request("INTERWORKING_CONNECT " + bssid
)
141 interworking_auth(dev
, method
)
143 def interworking_auth(dev
, method
):
144 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
146 raise Exception("Network connected timed out")
147 if "(" + method
+ ")" not in ev
:
148 raise Exception("Unexpected EAP method selection")
150 dev
.wait_connected(timeout
=15)
152 def check_probe_resp(wt
, bssid_unexpected
, bssid_expected
):
154 count
= wt
.get_bss_counter("probe_response", bssid_unexpected
)
156 raise Exception("Unexpected Probe Response frame from AP")
159 count
= wt
.get_bss_counter("probe_response", bssid_expected
)
161 raise Exception("No Probe Response frame from AP")
163 def test_ap_anqp_sharing(dev
, apdev
):
164 """ANQP sharing within ESS and explicit unshare"""
165 check_eap_capa(dev
[0], "MSCHAPV2")
166 dev
[0].flush_scan_cache()
168 bssid
= apdev
[0]['bssid']
169 params
= hs20_ap_params()
170 params
['hessid'] = bssid
171 hostapd
.add_ap(apdev
[0], params
)
173 bssid2
= apdev
[1]['bssid']
174 params
= hs20_ap_params()
175 params
['hessid'] = bssid
176 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
177 hostapd
.add_ap(apdev
[1], params
)
180 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
181 'password': "secret",
182 'domain': "example.com" })
183 logger
.info("Normal network selection with shared ANQP results")
184 dev
[0].scan_for_bss(bssid
, freq
="2412")
185 dev
[0].scan_for_bss(bssid2
, freq
="2412")
186 interworking_select(dev
[0], None, "home", freq
="2412")
187 dev
[0].dump_monitor()
189 logger
.debug("BSS entries:\n" + dev
[0].request("BSS RANGE=ALL"))
190 res1
= dev
[0].get_bss(bssid
)
191 res2
= dev
[0].get_bss(bssid2
)
192 if 'anqp_nai_realm' not in res1
:
193 raise Exception("anqp_nai_realm not found for AP1")
194 if 'anqp_nai_realm' not in res2
:
195 raise Exception("anqp_nai_realm not found for AP2")
196 if res1
['anqp_nai_realm'] != res2
['anqp_nai_realm']:
197 raise Exception("ANQP results were not shared between BSSes")
199 logger
.info("Explicit ANQP request to unshare ANQP results")
200 dev
[0].request("ANQP_GET " + bssid
+ " 263")
201 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
203 raise Exception("ANQP operation timed out")
205 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
206 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
208 raise Exception("ANQP operation timed out")
210 res1
= dev
[0].get_bss(bssid
)
211 res2
= dev
[0].get_bss(bssid2
)
212 if res1
['anqp_nai_realm'] == res2
['anqp_nai_realm']:
213 raise Exception("ANQP results were not unshared")
215 def test_ap_nai_home_realm_query(dev
, apdev
):
216 """NAI Home Realm Query"""
217 check_eap_capa(dev
[0], "MSCHAPV2")
218 bssid
= apdev
[0]['bssid']
219 params
= hs20_ap_params()
220 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
221 "0,another.example.org" ]
222 hostapd
.add_ap(apdev
[0], params
)
224 dev
[0].scan(freq
="2412")
225 dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " realm=example.com")
226 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
228 raise Exception("ANQP operation timed out")
229 nai1
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
230 dev
[0].dump_monitor()
232 dev
[0].request("ANQP_GET " + bssid
+ " 263")
233 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
235 raise Exception("ANQP operation timed out")
236 nai2
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
238 if len(nai1
) >= len(nai2
):
239 raise Exception("Unexpected NAI Realm list response lengths")
240 if "example.com".encode('hex') not in nai1
:
241 raise Exception("Home realm not reported")
242 if "example.org".encode('hex') in nai1
:
243 raise Exception("Non-home realm reported")
244 if "example.com".encode('hex') not in nai2
:
245 raise Exception("Home realm not reported in wildcard query")
246 if "example.org".encode('hex') not in nai2
:
247 raise Exception("Non-home realm not reported in wildcard query ")
250 "00:11:22:33:44:55 123",
251 "00:11:22:33:44:55 qq" ]
253 if "FAIL" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd
):
254 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd
)
256 dev
[0].dump_monitor()
257 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
258 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
259 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
261 raise Exception("ANQP operation timed out")
262 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=0.1)
264 raise Exception("Unexpected ANQP response: " + ev
)
266 dev
[0].dump_monitor()
267 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " 01000b6578616d706c652e636f6d"):
268 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
269 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
271 raise Exception("No ANQP response")
272 if "NAI Realm list" not in ev
:
273 raise Exception("Missing NAI Realm list: " + ev
)
275 dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
276 'password': "secret",
277 'domain': "example.com" })
278 dev
[0].dump_monitor()
279 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
280 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
281 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
283 raise Exception("No ANQP response")
284 if "NAI Realm list" not in ev
:
285 raise Exception("Missing NAI Realm list: " + ev
)
287 def test_ap_interworking_scan_filtering(dev
, apdev
):
288 """Interworking scan filtering with HESSID and access network type"""
290 _test_ap_interworking_scan_filtering(dev
, apdev
)
292 dev
[0].request("SET hessid 00:00:00:00:00:00")
293 dev
[0].request("SET access_network_type 15")
295 def _test_ap_interworking_scan_filtering(dev
, apdev
):
296 bssid
= apdev
[0]['bssid']
297 params
= hs20_ap_params()
298 ssid
= "test-hs20-ap1"
299 params
['ssid'] = ssid
300 params
['hessid'] = bssid
301 hostapd
.add_ap(apdev
[0], params
)
303 bssid2
= apdev
[1]['bssid']
304 params
= hs20_ap_params()
305 ssid2
= "test-hs20-ap2"
306 params
['ssid'] = ssid2
307 params
['hessid'] = bssid2
308 params
['access_network_type'] = "1"
309 del params
['venue_group']
310 del params
['venue_type']
311 hostapd
.add_ap(apdev
[1], params
)
318 logger
.info("Check probe request filtering based on HESSID")
320 dev
[0].request("SET hessid " + bssid2
)
321 dev
[0].scan(freq
="2412")
323 check_probe_resp(wt
, bssid
, bssid2
)
325 logger
.info("Check probe request filtering based on access network type")
327 wt
.clear_bss_counters(bssid
)
328 wt
.clear_bss_counters(bssid2
)
329 dev
[0].request("SET hessid 00:00:00:00:00:00")
330 dev
[0].request("SET access_network_type 14")
331 dev
[0].scan(freq
="2412")
333 check_probe_resp(wt
, bssid2
, bssid
)
335 wt
.clear_bss_counters(bssid
)
336 wt
.clear_bss_counters(bssid2
)
337 dev
[0].request("SET hessid 00:00:00:00:00:00")
338 dev
[0].request("SET access_network_type 1")
339 dev
[0].scan(freq
="2412")
341 check_probe_resp(wt
, bssid
, bssid2
)
343 logger
.info("Check probe request filtering based on HESSID and ANT")
345 wt
.clear_bss_counters(bssid
)
346 wt
.clear_bss_counters(bssid2
)
347 dev
[0].request("SET hessid " + bssid
)
348 dev
[0].request("SET access_network_type 14")
349 dev
[0].scan(freq
="2412")
351 check_probe_resp(wt
, bssid2
, bssid
)
353 wt
.clear_bss_counters(bssid
)
354 wt
.clear_bss_counters(bssid2
)
355 dev
[0].request("SET hessid " + bssid2
)
356 dev
[0].request("SET access_network_type 14")
357 dev
[0].scan(freq
="2412")
359 check_probe_resp(wt
, bssid
, None)
360 check_probe_resp(wt
, bssid2
, None)
362 wt
.clear_bss_counters(bssid
)
363 wt
.clear_bss_counters(bssid2
)
364 dev
[0].request("SET hessid " + bssid
)
365 dev
[0].request("SET access_network_type 1")
366 dev
[0].scan(freq
="2412")
368 check_probe_resp(wt
, bssid
, None)
369 check_probe_resp(wt
, bssid2
, None)
371 def test_ap_hs20_select(dev
, apdev
):
372 """Hotspot 2.0 network selection"""
373 bssid
= apdev
[0]['bssid']
374 params
= hs20_ap_params()
375 params
['hessid'] = bssid
376 hostapd
.add_ap(apdev
[0], params
)
379 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
380 'password': "secret",
381 'domain': "example.com" })
382 interworking_select(dev
[0], bssid
, "home")
384 dev
[0].remove_cred(id)
385 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
386 'password': "secret",
387 'domain': "no.match.example.com" })
388 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
390 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com");
391 interworking_select(dev
[0], bssid
, no_match
=True, freq
="2412")
393 res
= dev
[0].request("SCAN_RESULTS")
394 if "[HS20]" not in res
:
395 raise Exception("HS20 flag missing from scan results: " + res
)
397 bssid2
= apdev
[1]['bssid']
398 params
= hs20_ap_params()
399 params
['nai_realm'] = [ "0,example.org,21" ]
400 params
['hessid'] = bssid2
401 params
['domain_name'] = "example.org"
402 hostapd
.add_ap(apdev
[1], params
)
403 dev
[0].remove_cred(id)
404 id = dev
[0].add_cred_values({ 'realm': "example.org", 'username': "test",
405 'password': "secret",
406 'domain': "example.org" })
407 interworking_select(dev
[0], bssid2
, "home", freq
="2412")
409 def hs20_simulated_sim(dev
, ap
, method
):
411 params
= hs20_ap_params()
412 params
['hessid'] = bssid
413 params
['anqp_3gpp_cell_net'] = "555,444"
414 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
415 hostapd
.add_ap(ap
, params
)
418 dev
.add_cred_values({ 'imsi': "555444-333222111", 'eap': method
,
419 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
420 interworking_select(dev
, "home", freq
="2412")
421 interworking_connect(dev
, bssid
, method
)
422 check_sp_type(dev
, "home")
424 def test_ap_hs20_sim(dev
, apdev
):
425 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
426 hlr_auc_gw_available()
427 hs20_simulated_sim(dev
[0], apdev
[0], "SIM")
428 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
429 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
431 raise Exception("Timeout on already-connected event")
433 def test_ap_hs20_aka(dev
, apdev
):
434 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
435 hlr_auc_gw_available()
436 hs20_simulated_sim(dev
[0], apdev
[0], "AKA")
438 def test_ap_hs20_aka_prime(dev
, apdev
):
439 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
440 hlr_auc_gw_available()
441 hs20_simulated_sim(dev
[0], apdev
[0], "AKA'")
443 def test_ap_hs20_ext_sim(dev
, apdev
):
444 """Hotspot 2.0 with external SIM processing"""
445 hlr_auc_gw_available()
446 bssid
= apdev
[0]['bssid']
447 params
= hs20_ap_params()
448 params
['hessid'] = bssid
449 params
['anqp_3gpp_cell_net'] = "232,01"
450 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
451 hostapd
.add_ap(apdev
[0], params
)
455 dev
[0].request("SET external_sim 1")
456 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
457 interworking_select(dev
[0], "home", freq
="2412")
458 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
459 check_sp_type(dev
[0], "home")
461 dev
[0].request("SET external_sim 0")
463 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
464 """Hotspot 2.0 with external SIM processing in roaming network"""
465 hlr_auc_gw_available()
466 bssid
= apdev
[0]['bssid']
467 params
= hs20_ap_params()
468 params
['hessid'] = bssid
469 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
470 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
471 hostapd
.add_ap(apdev
[0], params
)
475 dev
[0].request("SET external_sim 1")
476 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
477 interworking_select(dev
[0], "roaming", freq
="2412")
478 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
479 check_sp_type(dev
[0], "roaming")
481 dev
[0].request("SET external_sim 0")
483 def test_ap_hs20_username(dev
, apdev
):
484 """Hotspot 2.0 connection in username/password credential"""
485 check_eap_capa(dev
[0], "MSCHAPV2")
486 bssid
= apdev
[0]['bssid']
487 params
= hs20_ap_params()
488 params
['hessid'] = bssid
489 params
['disable_dgaf'] = '1'
490 hostapd
.add_ap(apdev
[0], params
)
493 id = dev
[0].add_cred_values({ 'realm': "example.com",
494 'username': "hs20-test",
495 'password': "password",
496 'ca_cert': "auth_serv/ca.pem",
497 'domain': "example.com",
498 'update_identifier': "1234" })
499 interworking_select(dev
[0], bssid
, "home", freq
="2412")
500 interworking_connect(dev
[0], bssid
, "TTLS")
501 check_sp_type(dev
[0], "home")
502 status
= dev
[0].get_status()
503 if status
['pairwise_cipher'] != "CCMP":
504 raise Exception("Unexpected pairwise cipher")
505 if status
['hs20'] != "2":
506 raise Exception("Unexpected HS 2.0 support indication")
508 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
509 identity
="hs20-test", password
="password",
510 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
513 def test_ap_hs20_connect_api(dev
, apdev
):
514 """Hotspot 2.0 connection with connect API"""
515 check_eap_capa(dev
[0], "MSCHAPV2")
516 bssid
= apdev
[0]['bssid']
517 params
= hs20_ap_params()
518 params
['hessid'] = bssid
519 params
['disable_dgaf'] = '1'
520 hostapd
.add_ap(apdev
[0], params
)
522 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
523 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
525 wpas
.flush_scan_cache()
526 id = wpas
.add_cred_values({ 'realm': "example.com",
527 'username': "hs20-test",
528 'password': "password",
529 'ca_cert': "auth_serv/ca.pem",
530 'domain': "example.com",
531 'update_identifier': "1234" })
532 interworking_select(wpas
, bssid
, "home", freq
="2412")
533 interworking_connect(wpas
, bssid
, "TTLS")
534 check_sp_type(wpas
, "home")
535 status
= wpas
.get_status()
536 if status
['pairwise_cipher'] != "CCMP":
537 raise Exception("Unexpected pairwise cipher")
538 if status
['hs20'] != "2":
539 raise Exception("Unexpected HS 2.0 support indication")
541 def test_ap_hs20_auto_interworking(dev
, apdev
):
542 """Hotspot 2.0 connection with auto_interworking=1"""
543 check_eap_capa(dev
[0], "MSCHAPV2")
544 bssid
= apdev
[0]['bssid']
545 params
= hs20_ap_params()
546 params
['hessid'] = bssid
547 params
['disable_dgaf'] = '1'
548 hostapd
.add_ap(apdev
[0], params
)
550 dev
[0].hs20_enable(auto_interworking
=True)
551 id = dev
[0].add_cred_values({ 'realm': "example.com",
552 'username': "hs20-test",
553 'password': "password",
554 'ca_cert': "auth_serv/ca.pem",
555 'domain': "example.com",
556 'update_identifier': "1234" })
557 dev
[0].request("REASSOCIATE")
558 dev
[0].wait_connected(timeout
=15)
559 check_sp_type(dev
[0], "home")
560 status
= dev
[0].get_status()
561 if status
['pairwise_cipher'] != "CCMP":
562 raise Exception("Unexpected pairwise cipher")
563 if status
['hs20'] != "2":
564 raise Exception("Unexpected HS 2.0 support indication")
566 def test_ap_hs20_auto_interworking_no_match(dev
, apdev
):
567 """Hotspot 2.0 connection with auto_interworking=1 and no matching network"""
568 hapd
= hostapd
.add_ap(apdev
[0], { "ssid": "mismatch" })
570 dev
[0].hs20_enable(auto_interworking
=True)
571 id = dev
[0].connect("mismatch", psk
="12345678", scan_freq
="2412",
572 only_add_network
=True)
573 dev
[0].request("ENABLE_NETWORK " + str(id) + " no-connect")
575 id = dev
[0].add_cred_values({ 'realm': "example.com",
576 'username': "hs20-test",
577 'password': "password",
578 'ca_cert': "auth_serv/ca.pem",
579 'domain': "example.com",
580 'update_identifier': "1234" })
581 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
583 dev
[0].dump_monitor()
585 logger
.info("start ping")
586 if "PONG" not in dev
[0].ctrl
.request("PING", timeout
=2):
587 raise Exception("PING failed")
588 logger
.info("ping done")
592 ev
= dev
[0].wait_event([ "ANQP fetch completed",
593 "CTRL-EVENT-SCAN-RESULTS" ], timeout
=0.05)
596 if "ANQP fetch completed" in ev
:
600 if fetch
> 2 * scan
+ 3:
601 raise Exception("Too many ANQP fetch iterations")
602 dev
[0].dump_monitor()
603 dev
[0].request("DISCONNECT")
605 def test_ap_hs20_auto_interworking_no_cred_match(dev
, apdev
):
606 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
607 bssid
= apdev
[0]['bssid']
608 params
= { "ssid": "test" }
609 hostapd
.add_ap(apdev
[0], params
)
611 dev
[0].hs20_enable(auto_interworking
=True)
612 dev
[0].add_cred_values({ 'realm': "example.com",
613 'username': "hs20-test",
614 'password': "password",
615 'ca_cert': "auth_serv/ca.pem",
616 'domain': "example.com" })
618 id = dev
[0].connect("test", psk
="12345678", only_add_network
=True)
619 dev
[0].request("ENABLE_NETWORK %s" % id)
620 logger
.info("Verify that scanning continues when there is partial network block match")
621 for i
in range(0, 2):
622 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
624 raise Exception("Scan timed out")
625 logger
.info("Scan completed")
627 def eap_test(dev
, ap
, eap_params
, method
, user
):
629 params
= hs20_ap_params()
630 params
['nai_realm'] = [ "0,example.com," + eap_params
]
631 hostapd
.add_ap(ap
, params
)
634 dev
.add_cred_values({ 'realm': "example.com",
635 'ca_cert': "auth_serv/ca.pem",
637 'password': "password" })
638 interworking_select(dev
, bssid
, freq
="2412")
639 interworking_connect(dev
, bssid
, method
)
641 def test_ap_hs20_eap_unknown(dev
, apdev
):
642 """Hotspot 2.0 connection with unknown EAP method"""
643 bssid
= apdev
[0]['bssid']
644 params
= hs20_ap_params()
645 params
['nai_realm'] = "0,example.com,99"
646 hostapd
.add_ap(apdev
[0], params
)
649 dev
[0].add_cred_values(default_cred())
650 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
652 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
653 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
654 check_eap_capa(dev
[0], "MSCHAPV2")
655 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
657 def test_ap_hs20_eap_peap_default(dev
, apdev
):
658 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
659 check_eap_capa(dev
[0], "MSCHAPV2")
660 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
662 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
663 """Hotspot 2.0 connection with PEAP/GTC"""
664 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
666 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
667 """Hotspot 2.0 connection with PEAP/unknown"""
668 bssid
= apdev
[0]['bssid']
669 params
= hs20_ap_params()
670 params
['nai_realm'] = "0,example.com,25[3:99]"
671 hostapd
.add_ap(apdev
[0], params
)
674 dev
[0].add_cred_values(default_cred())
675 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
677 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
678 """Hotspot 2.0 connection with TTLS/CHAP"""
679 skip_with_fips(dev
[0])
680 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
682 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
683 """Hotspot 2.0 connection with TTLS/MSCHAP"""
684 skip_with_fips(dev
[0])
685 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
687 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
688 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
689 check_eap_capa(dev
[0], "MSCHAPV2")
690 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
692 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
693 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
694 bssid
= apdev
[0]['bssid']
695 params
= hs20_ap_params()
696 params
['nai_realm'] = "0,example.com,21[3:99]"
697 hostapd
.add_ap(apdev
[0], params
)
700 dev
[0].add_cred_values(default_cred())
701 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
703 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
704 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
705 bssid
= apdev
[0]['bssid']
706 params
= hs20_ap_params()
707 params
['nai_realm'] = "0,example.com,21[3:5]"
708 hostapd
.add_ap(apdev
[0], params
)
711 dev
[0].add_cred_values(default_cred())
712 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
714 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
715 """Hotspot 2.0 connection with TTLS/unknown"""
716 bssid
= apdev
[0]['bssid']
717 params
= hs20_ap_params()
718 params
['nai_realm'] = "0,example.com,21[2:5]"
719 hostapd
.add_ap(apdev
[0], params
)
722 dev
[0].add_cred_values(default_cred())
723 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
725 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
726 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
727 check_eap_capa(dev
[0], "FAST")
728 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
730 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
731 """Hotspot 2.0 connection with FAST/EAP-GTC"""
732 check_eap_capa(dev
[0], "FAST")
733 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
735 def test_ap_hs20_eap_tls(dev
, apdev
):
736 """Hotspot 2.0 connection with EAP-TLS"""
737 bssid
= apdev
[0]['bssid']
738 params
= hs20_ap_params()
739 params
['nai_realm'] = [ "0,example.com,13[5:6]" ]
740 hostapd
.add_ap(apdev
[0], params
)
743 dev
[0].add_cred_values({ 'realm': "example.com",
744 'username': "certificate-user",
745 'ca_cert': "auth_serv/ca.pem",
746 'client_cert': "auth_serv/user.pem",
747 'private_key': "auth_serv/user.key"})
748 interworking_select(dev
[0], bssid
, freq
="2412")
749 interworking_connect(dev
[0], bssid
, "TLS")
751 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
752 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
753 bssid
= apdev
[0]['bssid']
754 params
= hs20_ap_params()
755 params
['nai_realm'] = [ "0,example.com,99[5:6]" ]
756 hostapd
.add_ap(apdev
[0], params
)
759 dev
[0].add_cred_values({ 'realm': "example.com",
760 'username': "certificate-user",
761 'ca_cert': "auth_serv/ca.pem",
762 'client_cert': "auth_serv/user.pem",
763 'private_key': "auth_serv/user.key"})
764 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
766 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
767 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
768 bssid
= apdev
[0]['bssid']
769 params
= hs20_ap_params()
770 params
['nai_realm'] = [ "0,example.com,21[5:6]" ]
771 hostapd
.add_ap(apdev
[0], params
)
774 dev
[0].add_cred_values({ 'realm': "example.com",
775 'username': "certificate-user",
776 'ca_cert': "auth_serv/ca.pem",
777 'client_cert': "auth_serv/user.pem",
778 'private_key': "auth_serv/user.key"})
779 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
781 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
782 """Hotspot 2.0 connection with invalid cred configuration"""
783 bssid
= apdev
[0]['bssid']
784 params
= hs20_ap_params()
785 hostapd
.add_ap(apdev
[0], params
)
788 dev
[0].add_cred_values({ 'realm': "example.com",
789 'username': "certificate-user",
790 'client_cert': "auth_serv/user.pem" })
791 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
793 def test_ap_hs20_nai_realms(dev
, apdev
):
794 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
795 bssid
= apdev
[0]['bssid']
796 params
= hs20_ap_params()
797 params
['hessid'] = bssid
798 params
['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
799 hostapd
.add_ap(apdev
[0], params
)
802 id = dev
[0].add_cred_values({ 'realm': "example.com",
803 'ca_cert': "auth_serv/ca.pem",
804 'username': "pap user",
805 'password': "password",
806 'domain': "example.com" })
807 interworking_select(dev
[0], bssid
, "home", freq
="2412")
808 interworking_connect(dev
[0], bssid
, "TTLS")
809 check_sp_type(dev
[0], "home")
811 def test_ap_hs20_roaming_consortium(dev
, apdev
):
812 """Hotspot 2.0 connection based on roaming consortium match"""
813 bssid
= apdev
[0]['bssid']
814 params
= hs20_ap_params()
815 params
['hessid'] = bssid
816 hostapd
.add_ap(apdev
[0], params
)
819 for consortium
in [ "112233", "1020304050", "010203040506", "fedcba" ]:
820 id = dev
[0].add_cred_values({ 'username': "user",
821 'password': "password",
822 'domain': "example.com",
823 'ca_cert': "auth_serv/ca.pem",
824 'roaming_consortium': consortium
,
826 interworking_select(dev
[0], bssid
, "home", freq
="2412")
827 interworking_connect(dev
[0], bssid
, "PEAP")
828 check_sp_type(dev
[0], "home")
829 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
830 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
832 raise Exception("Timeout on already-connected event")
833 dev
[0].remove_cred(id)
835 def test_ap_hs20_username_roaming(dev
, apdev
):
836 """Hotspot 2.0 connection in username/password credential (roaming)"""
837 check_eap_capa(dev
[0], "MSCHAPV2")
838 bssid
= apdev
[0]['bssid']
839 params
= hs20_ap_params()
840 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
841 "0,roaming.example.com,21[2:4][5:7]",
842 "0,another.example.com" ]
843 params
['domain_name'] = "another.example.com"
844 params
['hessid'] = bssid
845 hostapd
.add_ap(apdev
[0], params
)
848 id = dev
[0].add_cred_values({ 'realm': "roaming.example.com",
849 'username': "hs20-test",
850 'password': "password",
851 'ca_cert': "auth_serv/ca.pem",
852 'domain': "example.com" })
853 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
854 interworking_connect(dev
[0], bssid
, "TTLS")
855 check_sp_type(dev
[0], "roaming")
857 def test_ap_hs20_username_unknown(dev
, apdev
):
858 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
859 check_eap_capa(dev
[0], "MSCHAPV2")
860 bssid
= apdev
[0]['bssid']
861 params
= hs20_ap_params()
862 params
['hessid'] = bssid
863 hostapd
.add_ap(apdev
[0], params
)
866 id = dev
[0].add_cred_values({ 'realm': "example.com",
867 'ca_cert': "auth_serv/ca.pem",
868 'username': "hs20-test",
869 'password': "password" })
870 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
871 interworking_connect(dev
[0], bssid
, "TTLS")
872 check_sp_type(dev
[0], "unknown")
874 def test_ap_hs20_username_unknown2(dev
, apdev
):
875 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
876 check_eap_capa(dev
[0], "MSCHAPV2")
877 bssid
= apdev
[0]['bssid']
878 params
= hs20_ap_params()
879 params
['hessid'] = bssid
880 del params
['domain_name']
881 hostapd
.add_ap(apdev
[0], params
)
884 id = dev
[0].add_cred_values({ 'realm': "example.com",
885 'ca_cert': "auth_serv/ca.pem",
886 'username': "hs20-test",
887 'password': "password",
888 'domain': "example.com" })
889 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
890 interworking_connect(dev
[0], bssid
, "TTLS")
891 check_sp_type(dev
[0], "unknown")
893 def test_ap_hs20_gas_while_associated(dev
, apdev
):
894 """Hotspot 2.0 connection with GAS query while associated"""
895 check_eap_capa(dev
[0], "MSCHAPV2")
896 bssid
= apdev
[0]['bssid']
897 params
= hs20_ap_params()
898 params
['hessid'] = bssid
899 hostapd
.add_ap(apdev
[0], params
)
902 id = dev
[0].add_cred_values({ 'realm': "example.com",
903 'ca_cert': "auth_serv/ca.pem",
904 'username': "hs20-test",
905 'password': "password",
906 'domain': "example.com" })
907 interworking_select(dev
[0], bssid
, "home", freq
="2412")
908 interworking_connect(dev
[0], bssid
, "TTLS")
910 logger
.info("Verifying GAS query while associated")
911 dev
[0].request("FETCH_ANQP")
912 for i
in range(0, 6):
913 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
915 raise Exception("Operation timed out")
917 def test_ap_hs20_gas_with_another_ap_while_associated(dev
, apdev
):
918 """GAS query with another AP while associated"""
919 check_eap_capa(dev
[0], "MSCHAPV2")
920 bssid
= apdev
[0]['bssid']
921 params
= hs20_ap_params()
922 params
['hessid'] = bssid
923 hostapd
.add_ap(apdev
[0], params
)
925 bssid2
= apdev
[1]['bssid']
926 params
= hs20_ap_params()
927 params
['hessid'] = bssid2
928 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
929 hostapd
.add_ap(apdev
[1], params
)
932 id = dev
[0].add_cred_values({ 'realm': "example.com",
933 'ca_cert': "auth_serv/ca.pem",
934 'username': "hs20-test",
935 'password': "password",
936 'domain': "example.com" })
937 interworking_select(dev
[0], bssid
, "home", freq
="2412")
938 interworking_connect(dev
[0], bssid
, "TTLS")
939 dev
[0].dump_monitor()
941 logger
.info("Verifying GAS query with same AP while associated")
942 dev
[0].request("ANQP_GET " + bssid
+ " 263")
943 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
945 raise Exception("ANQP operation timed out")
946 dev
[0].dump_monitor()
948 logger
.info("Verifying GAS query with another AP while associated")
949 dev
[0].scan_for_bss(bssid2
, 2412)
950 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
951 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
953 raise Exception("ANQP operation timed out")
955 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
956 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
957 check_eap_capa(dev
[0], "MSCHAPV2")
959 _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
)
961 dev
[0].request("SET pmf 0")
963 def _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
964 bssid
= apdev
[0]['bssid']
965 params
= hs20_ap_params()
966 params
['hessid'] = bssid
967 hostapd
.add_ap(apdev
[0], params
)
969 bssid2
= apdev
[1]['bssid']
970 params
= hs20_ap_params()
971 params
['hessid'] = bssid2
972 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
973 hostapd
.add_ap(apdev
[1], params
)
976 dev
[0].request("SET pmf 2")
977 id = dev
[0].add_cred_values({ 'realm': "example.com",
978 'ca_cert': "auth_serv/ca.pem",
979 'username': "hs20-test",
980 'password': "password",
981 'domain': "example.com" })
982 interworking_select(dev
[0], bssid
, "home", freq
="2412")
983 interworking_connect(dev
[0], bssid
, "TTLS")
985 logger
.info("Verifying GAS query while associated")
986 dev
[0].request("FETCH_ANQP")
987 for i
in range(0, 2 * 6):
988 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
990 raise Exception("Operation timed out")
992 def test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
993 """GAS query with another AP while associated and using PMF"""
994 check_eap_capa(dev
[0], "MSCHAPV2")
996 _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
)
998 dev
[0].request("SET pmf 0")
1000 def _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1001 bssid
= apdev
[0]['bssid']
1002 params
= hs20_ap_params()
1003 params
['hessid'] = bssid
1004 hostapd
.add_ap(apdev
[0], params
)
1006 bssid2
= apdev
[1]['bssid']
1007 params
= hs20_ap_params()
1008 params
['hessid'] = bssid2
1009 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
1010 hostapd
.add_ap(apdev
[1], params
)
1012 dev
[0].hs20_enable()
1013 dev
[0].request("SET pmf 2")
1014 id = dev
[0].add_cred_values({ 'realm': "example.com",
1015 'ca_cert': "auth_serv/ca.pem",
1016 'username': "hs20-test",
1017 'password': "password",
1018 'domain': "example.com" })
1019 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1020 interworking_connect(dev
[0], bssid
, "TTLS")
1021 dev
[0].dump_monitor()
1023 logger
.info("Verifying GAS query with same AP while associated")
1024 dev
[0].request("ANQP_GET " + bssid
+ " 263")
1025 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1027 raise Exception("ANQP operation timed out")
1028 dev
[0].dump_monitor()
1030 logger
.info("Verifying GAS query with another AP while associated")
1031 dev
[0].scan_for_bss(bssid2
, 2412)
1032 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
1033 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1035 raise Exception("ANQP operation timed out")
1037 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
1038 """Hotspot 2.0 connection with fragmented GAS query while associated"""
1039 check_eap_capa(dev
[0], "MSCHAPV2")
1040 bssid
= apdev
[0]['bssid']
1041 params
= hs20_ap_params()
1042 params
['hessid'] = bssid
1043 hostapd
.add_ap(apdev
[0], params
)
1044 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1045 hapd
.set("gas_frag_limit", "50")
1047 dev
[0].hs20_enable()
1048 id = dev
[0].add_cred_values({ 'realm': "example.com",
1049 'ca_cert': "auth_serv/ca.pem",
1050 'username': "hs20-test",
1051 'password': "password",
1052 'domain': "example.com" })
1053 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1054 interworking_connect(dev
[0], bssid
, "TTLS")
1056 logger
.info("Verifying GAS query while associated")
1057 dev
[0].request("FETCH_ANQP")
1058 for i
in range(0, 6):
1059 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1061 raise Exception("Operation timed out")
1063 def test_ap_hs20_multiple_connects(dev
, apdev
):
1064 """Hotspot 2.0 connection through multiple network selections"""
1065 check_eap_capa(dev
[0], "MSCHAPV2")
1066 bssid
= apdev
[0]['bssid']
1067 params
= hs20_ap_params()
1068 params
['hessid'] = bssid
1069 hostapd
.add_ap(apdev
[0], params
)
1071 dev
[0].hs20_enable()
1072 values
= { 'realm': "example.com",
1073 'ca_cert': "auth_serv/ca.pem",
1074 'username': "hs20-test",
1075 'password': "password",
1076 'domain': "example.com" }
1077 id = dev
[0].add_cred_values(values
)
1079 dev
[0].scan_for_bss(bssid
, freq
="2412")
1081 for i
in range(0, 3):
1082 logger
.info("Starting Interworking network selection")
1083 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1085 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1086 "INTERWORKING-ALREADY-CONNECTED",
1087 "CTRL-EVENT-CONNECTED"], timeout
=15)
1089 raise Exception("Connection timed out")
1090 if "INTERWORKING-NO-MATCH" in ev
:
1091 raise Exception("Matching AP not found")
1092 if "CTRL-EVENT-CONNECTED" in ev
:
1094 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
1097 dev
[0].request("DISCONNECT")
1098 dev
[0].dump_monitor()
1100 networks
= dev
[0].list_networks()
1101 if len(networks
) > 1:
1102 raise Exception("Duplicated network block detected")
1104 def test_ap_hs20_disallow_aps(dev
, apdev
):
1105 """Hotspot 2.0 connection and disallow_aps"""
1106 bssid
= apdev
[0]['bssid']
1107 params
= hs20_ap_params()
1108 params
['hessid'] = bssid
1109 hostapd
.add_ap(apdev
[0], params
)
1111 dev
[0].hs20_enable()
1112 values
= { 'realm': "example.com",
1113 'ca_cert': "auth_serv/ca.pem",
1114 'username': "hs20-test",
1115 'password': "password",
1116 'domain': "example.com" }
1117 id = dev
[0].add_cred_values(values
)
1119 dev
[0].scan_for_bss(bssid
, freq
="2412")
1121 logger
.info("Verify disallow_aps bssid")
1122 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
1123 dev
[0].request("INTERWORKING_SELECT auto")
1124 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1126 raise Exception("Network selection timed out")
1127 dev
[0].dump_monitor()
1129 logger
.info("Verify disallow_aps ssid")
1130 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
1131 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1132 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1134 raise Exception("Network selection timed out")
1135 dev
[0].dump_monitor()
1137 logger
.info("Verify disallow_aps clear")
1138 dev
[0].request("SET disallow_aps ")
1139 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1141 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
1142 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1143 if "FAIL" not in ret
:
1144 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
1146 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
1147 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1148 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
1149 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1151 def policy_test(dev
, ap
, values
, only_one
=True):
1154 logger
.info("Verify network selection to AP " + ap
['ifname'])
1156 dev
.scan_for_bss(bssid
, freq
="2412")
1158 logger
.info("Verify network selection")
1161 id = dev
.add_cred_values(values
)
1162 dev
.request("INTERWORKING_SELECT auto freq=2412")
1165 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1166 "INTERWORKING-BLACKLISTED",
1167 "INTERWORKING-SELECTED"], timeout
=15)
1169 raise Exception("Network selection timed out")
1171 if "INTERWORKING-NO-MATCH" in ev
:
1172 raise Exception("Matching AP not found")
1173 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1174 raise Exception("Unexpected AP claimed acceptable")
1175 if "INTERWORKING-SELECTED" in ev
:
1176 if bssid
and bssid
not in ev
:
1177 raise Exception("Selected incorrect BSS")
1180 ev
= dev
.wait_connected(timeout
=15)
1181 if bssid
and bssid
not in ev
:
1182 raise Exception("Connected to incorrect BSS")
1184 conn_bssid
= dev
.get_status_field("bssid")
1185 if bssid
and conn_bssid
!= bssid
:
1186 raise Exception("bssid information points to incorrect BSS")
1192 def default_cred(domain
=None, user
="hs20-test"):
1193 cred
= { 'realm': "example.com",
1194 'ca_cert': "auth_serv/ca.pem",
1196 'password': "password" }
1198 cred
['domain'] = domain
1201 def test_ap_hs20_prefer_home(dev
, apdev
):
1202 """Hotspot 2.0 required roaming consortium"""
1203 check_eap_capa(dev
[0], "MSCHAPV2")
1204 params
= hs20_ap_params()
1205 params
['domain_name'] = "example.org"
1206 hostapd
.add_ap(apdev
[0], params
)
1208 params
= hs20_ap_params()
1209 params
['ssid'] = "test-hs20-other"
1210 params
['domain_name'] = "example.com"
1211 hostapd
.add_ap(apdev
[1], params
)
1213 values
= default_cred()
1214 values
['domain'] = "example.com"
1215 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1216 values
['domain'] = "example.org"
1217 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1219 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1220 """Hotspot 2.0 required roaming consortium"""
1221 check_eap_capa(dev
[0], "MSCHAPV2")
1222 params
= hs20_ap_params()
1223 hostapd
.add_ap(apdev
[0], params
)
1225 params
= hs20_ap_params()
1226 params
['ssid'] = "test-hs20-other"
1227 params
['roaming_consortium'] = [ "223344" ]
1228 hostapd
.add_ap(apdev
[1], params
)
1230 values
= default_cred()
1231 values
['required_roaming_consortium'] = "223344"
1232 policy_test(dev
[0], apdev
[1], values
)
1233 values
['required_roaming_consortium'] = "112233"
1234 policy_test(dev
[0], apdev
[0], values
)
1236 id = dev
[0].add_cred()
1237 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1238 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1240 for val
in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1241 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1242 raise Exception("Invalid roaming consortium value accepted: " + val
)
1244 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1245 """Hotspot 2.0 exclusion based on SSID"""
1246 check_eap_capa(dev
[0], "MSCHAPV2")
1247 params
= hs20_ap_params()
1248 params
['roaming_consortium'] = [ "223344" ]
1249 params
['anqp_3gpp_cell_net'] = "555,444"
1250 hostapd
.add_ap(apdev
[0], params
)
1252 params
= hs20_ap_params()
1253 params
['ssid'] = "test-hs20-other"
1254 params
['roaming_consortium'] = [ "223344" ]
1255 params
['anqp_3gpp_cell_net'] = "555,444"
1256 hostapd
.add_ap(apdev
[1], params
)
1258 values
= default_cred()
1259 values
['excluded_ssid'] = "test-hs20"
1260 events
= policy_test(dev
[0], apdev
[1], values
)
1261 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1263 raise Exception("Excluded network not reported")
1264 values
['excluded_ssid'] = "test-hs20-other"
1265 events
= policy_test(dev
[0], apdev
[0], values
)
1266 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1268 raise Exception("Excluded network not reported")
1270 values
= default_cred()
1271 values
['roaming_consortium'] = "223344"
1272 values
['eap'] = "TTLS"
1273 values
['phase2'] = "auth=MSCHAPV2"
1274 values
['excluded_ssid'] = "test-hs20"
1275 events
= policy_test(dev
[0], apdev
[1], values
)
1276 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1278 raise Exception("Excluded network not reported")
1280 values
= { 'imsi': "555444-333222111", 'eap': "SIM",
1281 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1282 'excluded_ssid': "test-hs20" }
1283 events
= policy_test(dev
[0], apdev
[1], values
)
1284 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1286 raise Exception("Excluded network not reported")
1288 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1289 """Hotspot 2.0 and roaming from current to higher priority network"""
1290 check_eap_capa(dev
[0], "MSCHAPV2")
1291 bssid
= apdev
[0]['bssid']
1292 params
= hs20_ap_params(ssid
="test-hs20-visited")
1293 params
['domain_name'] = "visited.example.org"
1294 hostapd
.add_ap(apdev
[0], params
)
1296 dev
[0].hs20_enable()
1297 id = dev
[0].add_cred_values({ 'realm': "example.com",
1298 'ca_cert': "auth_serv/ca.pem",
1299 'username': "hs20-test",
1300 'password': "password",
1301 'domain': "example.com" })
1302 logger
.info("Connect to the only network option")
1303 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1304 dev
[0].dump_monitor()
1305 interworking_connect(dev
[0], bssid
, "TTLS")
1307 logger
.info("Start another AP (home operator) and reconnect")
1308 bssid2
= apdev
[1]['bssid']
1309 params
= hs20_ap_params(ssid
="test-hs20-home")
1310 params
['domain_name'] = "example.com"
1311 hostapd
.add_ap(apdev
[1], params
)
1313 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1314 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1315 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1316 "INTERWORKING-ALREADY-CONNECTED",
1317 "CTRL-EVENT-CONNECTED"], timeout
=15)
1319 raise Exception("Connection timed out")
1320 if "INTERWORKING-NO-MATCH" in ev
:
1321 raise Exception("Matching AP not found")
1322 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1323 raise Exception("Unexpected AP selected")
1324 if bssid2
not in ev
:
1325 raise Exception("Unexpected BSSID after reconnection")
1327 def test_ap_hs20_domain_suffix_match_full(dev
, apdev
):
1328 """Hotspot 2.0 and domain_suffix_match"""
1329 check_domain_match_full(dev
[0])
1330 check_eap_capa(dev
[0], "MSCHAPV2")
1331 bssid
= apdev
[0]['bssid']
1332 params
= hs20_ap_params()
1333 hostapd
.add_ap(apdev
[0], params
)
1335 dev
[0].hs20_enable()
1336 id = dev
[0].add_cred_values({ 'realm': "example.com",
1337 'username': "hs20-test",
1338 'password': "password",
1339 'ca_cert': "auth_serv/ca.pem",
1340 'domain': "example.com",
1341 'domain_suffix_match': "server.w1.fi" })
1342 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1343 dev
[0].dump_monitor()
1344 interworking_connect(dev
[0], bssid
, "TTLS")
1345 dev
[0].request("REMOVE_NETWORK all")
1346 dev
[0].dump_monitor()
1348 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1349 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1350 dev
[0].dump_monitor()
1351 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1352 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1354 raise Exception("TLS certificate error not reported")
1355 if "Domain suffix mismatch" not in ev
:
1356 raise Exception("Domain suffix mismatch not reported")
1358 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1359 """Hotspot 2.0 and domain_suffix_match"""
1360 check_eap_capa(dev
[0], "MSCHAPV2")
1361 check_domain_match_full(dev
[0])
1362 bssid
= apdev
[0]['bssid']
1363 params
= hs20_ap_params()
1364 hostapd
.add_ap(apdev
[0], params
)
1366 dev
[0].hs20_enable()
1367 id = dev
[0].add_cred_values({ 'realm': "example.com",
1368 'username': "hs20-test",
1369 'password': "password",
1370 'ca_cert': "auth_serv/ca.pem",
1371 'domain': "example.com",
1372 'domain_suffix_match': "w1.fi" })
1373 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1374 dev
[0].dump_monitor()
1375 interworking_connect(dev
[0], bssid
, "TTLS")
1377 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1378 """Hotspot 2.0 and roaming partner preference"""
1379 check_eap_capa(dev
[0], "MSCHAPV2")
1380 params
= hs20_ap_params()
1381 params
['domain_name'] = "roaming.example.org"
1382 hostapd
.add_ap(apdev
[0], params
)
1384 params
= hs20_ap_params()
1385 params
['ssid'] = "test-hs20-other"
1386 params
['domain_name'] = "roaming.example.net"
1387 hostapd
.add_ap(apdev
[1], params
)
1389 logger
.info("Verify default vs. specified preference")
1390 values
= default_cred()
1391 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1392 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1393 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1394 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1396 logger
.info("Verify partial FQDN match")
1397 values
['roaming_partner'] = "example.net,0,0,*"
1398 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1399 values
['roaming_partner'] = "example.net,0,255,*"
1400 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1402 def test_ap_hs20_max_bss_load(dev
, apdev
):
1403 """Hotspot 2.0 and maximum BSS load"""
1404 check_eap_capa(dev
[0], "MSCHAPV2")
1405 params
= hs20_ap_params()
1406 params
['bss_load_test'] = "12:200:20000"
1407 hostapd
.add_ap(apdev
[0], params
)
1409 params
= hs20_ap_params()
1410 params
['ssid'] = "test-hs20-other"
1411 params
['bss_load_test'] = "5:20:10000"
1412 hostapd
.add_ap(apdev
[1], params
)
1414 logger
.info("Verify maximum BSS load constraint")
1415 values
= default_cred()
1416 values
['domain'] = "example.com"
1417 values
['max_bss_load'] = "100"
1418 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1420 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1421 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1422 raise Exception("Maximum BSS Load case not noticed")
1423 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1424 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1425 raise Exception("Maximum BSS Load case reported incorrectly")
1427 logger
.info("Verify maximum BSS load does not prevent connection")
1428 values
['max_bss_load'] = "1"
1429 events
= policy_test(dev
[0], None, values
)
1431 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1432 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1433 raise Exception("Maximum BSS Load case not noticed")
1434 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1435 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1436 raise Exception("Maximum BSS Load case not noticed")
1438 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1439 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1440 check_eap_capa(dev
[0], "MSCHAPV2")
1441 params
= hs20_ap_params()
1442 params
['bss_load_test'] = "12:200:20000"
1443 hostapd
.add_ap(apdev
[0], params
)
1445 params
= hs20_ap_params()
1446 params
['ssid'] = "test-hs20-other"
1447 hostapd
.add_ap(apdev
[1], params
)
1449 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1450 values
= default_cred()
1451 values
['domain'] = "example.com"
1452 values
['max_bss_load'] = "100"
1453 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1455 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1456 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1457 raise Exception("Maximum BSS Load case not noticed")
1458 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1459 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1460 raise Exception("Maximum BSS Load case reported incorrectly")
1462 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1463 """Hotspot 2.0 multi-cred sp_priority"""
1464 check_eap_capa(dev
[0], "MSCHAPV2")
1466 _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1468 dev
[0].request("SET external_sim 0")
1470 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1471 hlr_auc_gw_available()
1472 bssid
= apdev
[0]['bssid']
1473 params
= hs20_ap_params()
1474 params
['hessid'] = bssid
1475 del params
['domain_name']
1476 params
['anqp_3gpp_cell_net'] = "232,01"
1477 hostapd
.add_ap(apdev
[0], params
)
1479 dev
[0].hs20_enable()
1480 dev
[0].scan_for_bss(bssid
, freq
="2412")
1481 dev
[0].request("SET external_sim 1")
1482 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1483 'provisioning_sp': "example.com",
1484 'sp_priority' :"1" })
1485 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1486 'ca_cert': "auth_serv/ca.pem",
1487 'username': "hs20-test",
1488 'password': "password",
1489 'domain': "example.com",
1490 'provisioning_sp': "example.com",
1491 'sp_priority': "2" })
1492 dev
[0].dump_monitor()
1493 dev
[0].scan_for_bss(bssid
, freq
="2412")
1494 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1495 interworking_ext_sim_auth(dev
[0], "SIM")
1496 check_sp_type(dev
[0], "unknown")
1497 dev
[0].request("REMOVE_NETWORK all")
1499 dev
[0].set_cred(id1
, "sp_priority", "2")
1500 dev
[0].set_cred(id2
, "sp_priority", "1")
1501 dev
[0].dump_monitor()
1502 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1503 interworking_auth(dev
[0], "TTLS")
1504 check_sp_type(dev
[0], "unknown")
1506 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1507 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1508 check_eap_capa(dev
[0], "MSCHAPV2")
1510 _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
1512 dev
[0].request("SET external_sim 0")
1514 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1515 hlr_auc_gw_available()
1516 bssid
= apdev
[0]['bssid']
1517 params
= hs20_ap_params()
1518 params
['hessid'] = bssid
1519 del params
['nai_realm']
1520 del params
['domain_name']
1521 params
['anqp_3gpp_cell_net'] = "232,01"
1522 hostapd
.add_ap(apdev
[0], params
)
1524 bssid2
= apdev
[1]['bssid']
1525 params
= hs20_ap_params()
1526 params
['ssid'] = "test-hs20-other"
1527 params
['hessid'] = bssid2
1528 del params
['domain_name']
1529 del params
['anqp_3gpp_cell_net']
1530 hostapd
.add_ap(apdev
[1], params
)
1532 dev
[0].hs20_enable()
1533 dev
[0].request("SET external_sim 1")
1534 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1535 'provisioning_sp': "example.com",
1536 'sp_priority': "1" })
1537 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1538 'ca_cert': "auth_serv/ca.pem",
1539 'username': "hs20-test",
1540 'password': "password",
1541 'domain': "example.com",
1542 'provisioning_sp': "example.com",
1543 'sp_priority': "2" })
1544 dev
[0].dump_monitor()
1545 dev
[0].scan_for_bss(bssid
, freq
="2412")
1546 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1547 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1548 interworking_ext_sim_auth(dev
[0], "SIM")
1549 check_sp_type(dev
[0], "unknown")
1550 conn_bssid
= dev
[0].get_status_field("bssid")
1551 if conn_bssid
!= bssid
:
1552 raise Exception("Connected to incorrect BSS")
1553 dev
[0].request("REMOVE_NETWORK all")
1555 dev
[0].set_cred(id1
, "sp_priority", "2")
1556 dev
[0].set_cred(id2
, "sp_priority", "1")
1557 dev
[0].dump_monitor()
1558 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1559 interworking_auth(dev
[0], "TTLS")
1560 check_sp_type(dev
[0], "unknown")
1561 conn_bssid
= dev
[0].get_status_field("bssid")
1562 if conn_bssid
!= bssid2
:
1563 raise Exception("Connected to incorrect BSS")
1565 def check_conn_capab_selection(dev
, type, missing
):
1566 dev
.request("INTERWORKING_SELECT freq=2412")
1567 ev
= dev
.wait_event(["INTERWORKING-AP"])
1569 raise Exception("Network selection timed out");
1570 if "type=" + type not in ev
:
1571 raise Exception("Unexpected network type")
1572 if missing
and "conn_capab_missing=1" not in ev
:
1573 raise Exception("conn_capab_missing not reported")
1574 if not missing
and "conn_capab_missing=1" in ev
:
1575 raise Exception("conn_capab_missing reported unexpectedly")
1577 def conn_capab_cred(domain
=None, req_conn_capab
=None):
1578 cred
= default_cred(domain
=domain
)
1580 cred
['req_conn_capab'] = req_conn_capab
1583 def test_ap_hs20_req_conn_capab(dev
, apdev
):
1584 """Hotspot 2.0 network selection with req_conn_capab"""
1585 check_eap_capa(dev
[0], "MSCHAPV2")
1586 bssid
= apdev
[0]['bssid']
1587 params
= hs20_ap_params()
1588 hostapd
.add_ap(apdev
[0], params
)
1590 dev
[0].hs20_enable()
1591 dev
[0].scan_for_bss(bssid
, freq
="2412")
1592 logger
.info("Not used in home network")
1593 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
1594 id = dev
[0].add_cred_values(values
)
1595 check_conn_capab_selection(dev
[0], "home", False)
1597 logger
.info("Used in roaming network")
1598 dev
[0].remove_cred(id)
1599 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
1600 id = dev
[0].add_cred_values(values
)
1601 check_conn_capab_selection(dev
[0], "roaming", True)
1603 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1604 check_auto_select(dev
[0], bssid
)
1606 logger
.info("Additional req_conn_capab checks")
1608 dev
[0].remove_cred(id)
1609 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
1610 id = dev
[0].add_cred_values(values
)
1611 check_conn_capab_selection(dev
[0], "roaming", True)
1613 dev
[0].remove_cred(id)
1614 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
1615 id = dev
[0].add_cred_values(values
)
1616 check_conn_capab_selection(dev
[0], "roaming", True)
1618 bssid2
= apdev
[1]['bssid']
1619 params
= hs20_ap_params(ssid
="test-hs20b")
1620 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1621 hostapd
.add_ap(apdev
[1], params
)
1623 dev
[0].remove_cred(id)
1624 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
1625 id = dev
[0].add_cred_values(values
)
1626 dev
[0].set_cred(id, "req_conn_capab", "6:22")
1627 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1628 dev
[0].request("INTERWORKING_SELECT freq=2412")
1629 for i
in range(0, 2):
1630 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
1632 raise Exception("Network selection timed out");
1633 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
1634 raise Exception("Missing protocol connection capability not reported")
1635 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
1636 raise Exception("Protocol connection capability not reported correctly")
1638 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
1639 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1640 check_eap_capa(dev
[0], "MSCHAPV2")
1641 bssid
= apdev
[0]['bssid']
1642 params
= hs20_ap_params()
1643 params
['domain_name'] = "roaming.example.org"
1644 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1645 hostapd
.add_ap(apdev
[0], params
)
1647 bssid2
= apdev
[1]['bssid']
1648 params
= hs20_ap_params(ssid
="test-hs20-b")
1649 params
['domain_name'] = "roaming.example.net"
1650 hostapd
.add_ap(apdev
[1], params
)
1652 values
= default_cred()
1653 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1654 id = dev
[0].add_cred_values(values
)
1655 check_auto_select(dev
[0], bssid2
)
1657 dev
[0].set_cred(id, "req_conn_capab", "50")
1658 check_auto_select(dev
[0], bssid
)
1660 dev
[0].remove_cred(id)
1661 id = dev
[0].add_cred_values(values
)
1662 dev
[0].set_cred(id, "req_conn_capab", "51")
1663 check_auto_select(dev
[0], bssid2
)
1665 def check_bandwidth_selection(dev
, type, below
):
1666 dev
.request("INTERWORKING_SELECT freq=2412")
1667 ev
= dev
.wait_event(["INTERWORKING-AP"])
1669 raise Exception("Network selection timed out");
1670 logger
.debug("BSS entries:\n" + dev
.request("BSS RANGE=ALL"))
1671 if "type=" + type not in ev
:
1672 raise Exception("Unexpected network type")
1673 if below
and "below_min_backhaul=1" not in ev
:
1674 raise Exception("below_min_backhaul not reported")
1675 if not below
and "below_min_backhaul=1" in ev
:
1676 raise Exception("below_min_backhaul reported unexpectedly")
1678 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
1679 cred
= default_cred(domain
=domain
)
1681 cred
['min_dl_bandwidth_home'] = str(dl_home
)
1683 cred
['min_ul_bandwidth_home'] = str(ul_home
)
1685 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
1687 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
1690 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
1691 """Hotspot 2.0 network selection with min bandwidth (home)"""
1692 check_eap_capa(dev
[0], "MSCHAPV2")
1693 bssid
= apdev
[0]['bssid']
1694 params
= hs20_ap_params()
1695 hostapd
.add_ap(apdev
[0], params
)
1697 dev
[0].hs20_enable()
1698 dev
[0].scan_for_bss(bssid
, freq
="2412")
1699 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1700 id = dev
[0].add_cred_values(values
)
1701 check_bandwidth_selection(dev
[0], "home", False)
1702 dev
[0].remove_cred(id)
1704 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1705 id = dev
[0].add_cred_values(values
)
1706 check_bandwidth_selection(dev
[0], "home", True)
1707 dev
[0].remove_cred(id)
1709 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1710 id = dev
[0].add_cred_values(values
)
1711 check_bandwidth_selection(dev
[0], "home", True)
1712 dev
[0].remove_cred(id)
1714 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1715 id = dev
[0].add_cred_values(values
)
1716 check_bandwidth_selection(dev
[0], "home", True)
1717 check_auto_select(dev
[0], bssid
)
1719 bssid2
= apdev
[1]['bssid']
1720 params
= hs20_ap_params(ssid
="test-hs20-b")
1721 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1722 hostapd
.add_ap(apdev
[1], params
)
1724 check_auto_select(dev
[0], bssid2
)
1726 def test_ap_hs20_min_bandwidth_home_hidden_ssid_in_scan_res(dev
, apdev
):
1727 """Hotspot 2.0 network selection with min bandwidth (home) while hidden SSID is included in scan results"""
1728 check_eap_capa(dev
[0], "MSCHAPV2")
1729 bssid
= apdev
[0]['bssid']
1731 hapd
= hostapd
.add_ap(apdev
[0], { "ssid": 'secret',
1732 "ignore_broadcast_ssid": "1" })
1733 dev
[0].scan_for_bss(bssid
, freq
=2412)
1735 hapd_global
= hostapd
.HostapdGlobal()
1737 hapd_global
.remove(apdev
[0]['ifname'])
1739 params
= hs20_ap_params()
1740 hostapd
.add_ap(apdev
[0], params
)
1742 dev
[0].hs20_enable()
1743 dev
[0].scan_for_bss(bssid
, freq
="2412")
1744 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1745 id = dev
[0].add_cred_values(values
)
1746 check_bandwidth_selection(dev
[0], "home", False)
1747 dev
[0].remove_cred(id)
1749 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1750 id = dev
[0].add_cred_values(values
)
1751 check_bandwidth_selection(dev
[0], "home", True)
1752 dev
[0].remove_cred(id)
1754 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1755 id = dev
[0].add_cred_values(values
)
1756 check_bandwidth_selection(dev
[0], "home", True)
1757 dev
[0].remove_cred(id)
1759 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1760 id = dev
[0].add_cred_values(values
)
1761 check_bandwidth_selection(dev
[0], "home", True)
1762 check_auto_select(dev
[0], bssid
)
1764 bssid2
= apdev
[1]['bssid']
1765 params
= hs20_ap_params(ssid
="test-hs20-b")
1766 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1767 hostapd
.add_ap(apdev
[1], params
)
1769 check_auto_select(dev
[0], bssid2
)
1771 dev
[0].flush_scan_cache()
1773 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
1774 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1775 check_eap_capa(dev
[0], "MSCHAPV2")
1776 bssid
= apdev
[0]['bssid']
1777 params
= hs20_ap_params()
1778 hostapd
.add_ap(apdev
[0], params
)
1780 dev
[0].hs20_enable()
1781 dev
[0].scan_for_bss(bssid
, freq
="2412")
1782 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
1783 id = dev
[0].add_cred_values(values
)
1784 check_bandwidth_selection(dev
[0], "roaming", False)
1785 dev
[0].remove_cred(id)
1787 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
1788 id = dev
[0].add_cred_values(values
)
1789 check_bandwidth_selection(dev
[0], "roaming", True)
1790 dev
[0].remove_cred(id)
1792 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
1793 id = dev
[0].add_cred_values(values
)
1794 check_bandwidth_selection(dev
[0], "roaming", True)
1795 dev
[0].remove_cred(id)
1797 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
1798 id = dev
[0].add_cred_values(values
)
1799 check_bandwidth_selection(dev
[0], "roaming", True)
1800 check_auto_select(dev
[0], bssid
)
1802 bssid2
= apdev
[1]['bssid']
1803 params
= hs20_ap_params(ssid
="test-hs20-b")
1804 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1805 hostapd
.add_ap(apdev
[1], params
)
1807 check_auto_select(dev
[0], bssid2
)
1809 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
1810 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1811 check_eap_capa(dev
[0], "MSCHAPV2")
1812 bssid
= apdev
[0]['bssid']
1813 params
= hs20_ap_params()
1814 params
['domain_name'] = "roaming.example.org"
1815 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1816 hostapd
.add_ap(apdev
[0], params
)
1818 bssid2
= apdev
[1]['bssid']
1819 params
= hs20_ap_params(ssid
="test-hs20-b")
1820 params
['domain_name'] = "roaming.example.net"
1821 hostapd
.add_ap(apdev
[1], params
)
1823 values
= default_cred()
1824 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1825 id = dev
[0].add_cred_values(values
)
1826 check_auto_select(dev
[0], bssid2
)
1828 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1829 check_auto_select(dev
[0], bssid
)
1831 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1832 check_auto_select(dev
[0], bssid2
)
1834 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
1835 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1836 bssid
= apdev
[0]['bssid']
1837 params
= hs20_ap_params()
1838 del params
['hs20_wan_metrics']
1839 hostapd
.add_ap(apdev
[0], params
)
1841 dev
[0].hs20_enable()
1842 dev
[0].scan_for_bss(bssid
, freq
="2412")
1843 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
1844 dl_roaming
=10000, ul_roaming
=10000)
1845 dev
[0].add_cred_values(values
)
1846 check_bandwidth_selection(dev
[0], "home", False)
1848 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
1849 """Hotspot 2.0 connection and deauthentication request for ESS"""
1850 check_eap_capa(dev
[0], "MSCHAPV2")
1852 _test_ap_hs20_deauth_req_ess(dev
, apdev
)
1854 dev
[0].request("SET pmf 0")
1856 def _test_ap_hs20_deauth_req_ess(dev
, apdev
):
1857 dev
[0].request("SET pmf 2")
1858 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1859 dev
[0].dump_monitor()
1860 addr
= dev
[0].p2p_interface_addr()
1861 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1862 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
1863 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1865 raise Exception("Timeout on deauth imminent notice")
1866 if "1 120 http://example.com/" not in ev
:
1867 raise Exception("Unexpected deauth imminent notice: " + ev
)
1868 hapd
.request("DEAUTHENTICATE " + addr
)
1869 dev
[0].wait_disconnected(timeout
=10)
1870 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1871 raise Exception("Network not marked temporarily disabled")
1872 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1873 "Trying to associate",
1874 "CTRL-EVENT-CONNECTED"], timeout
=5)
1876 raise Exception("Unexpected connection attempt")
1878 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
1879 """Hotspot 2.0 connection and deauthentication request for BSS"""
1880 check_eap_capa(dev
[0], "MSCHAPV2")
1882 _test_ap_hs20_deauth_req_bss(dev
, apdev
)
1884 dev
[0].request("SET pmf 0")
1886 def _test_ap_hs20_deauth_req_bss(dev
, apdev
):
1887 dev
[0].request("SET pmf 2")
1888 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1889 dev
[0].dump_monitor()
1890 addr
= dev
[0].p2p_interface_addr()
1891 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1892 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
1893 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1895 raise Exception("Timeout on deauth imminent notice")
1896 if "0 120 http://example.com/" not in ev
:
1897 raise Exception("Unexpected deauth imminent notice: " + ev
)
1898 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
1899 ev
= dev
[0].wait_disconnected(timeout
=10)
1900 if "reason=4" not in ev
:
1901 raise Exception("Unexpected disconnection reason")
1902 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1903 raise Exception("Network not marked temporarily disabled")
1904 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1905 "Trying to associate",
1906 "CTRL-EVENT-CONNECTED"], timeout
=5)
1908 raise Exception("Unexpected connection attempt")
1910 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1911 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1912 check_eap_capa(dev
[0], "MSCHAPV2")
1914 _test_ap_hs20_deauth_req_from_radius(dev
, apdev
)
1916 dev
[0].request("SET pmf 0")
1918 def _test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1919 bssid
= apdev
[0]['bssid']
1920 params
= hs20_ap_params()
1921 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1922 params
['hs20_deauth_req_timeout'] = "2"
1923 hostapd
.add_ap(apdev
[0], params
)
1925 dev
[0].request("SET pmf 2")
1926 dev
[0].hs20_enable()
1927 dev
[0].add_cred_values({ 'realm': "example.com",
1928 'username': "hs20-deauth-test",
1929 'password': "password" })
1930 interworking_select(dev
[0], bssid
, freq
="2412")
1931 interworking_connect(dev
[0], bssid
, "TTLS")
1932 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
1934 raise Exception("Timeout on deauth imminent notice")
1935 if " 1 100" not in ev
:
1936 raise Exception("Unexpected deauth imminent contents")
1937 dev
[0].wait_disconnected(timeout
=3)
1939 def test_ap_hs20_remediation_required(dev
, apdev
):
1940 """Hotspot 2.0 connection and remediation required from RADIUS"""
1941 check_eap_capa(dev
[0], "MSCHAPV2")
1943 _test_ap_hs20_remediation_required(dev
, apdev
)
1945 dev
[0].request("SET pmf 0")
1947 def _test_ap_hs20_remediation_required(dev
, apdev
):
1948 bssid
= apdev
[0]['bssid']
1949 params
= hs20_ap_params()
1950 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1951 hostapd
.add_ap(apdev
[0], params
)
1953 dev
[0].request("SET pmf 1")
1954 dev
[0].hs20_enable()
1955 dev
[0].add_cred_values({ 'realm': "example.com",
1956 'username': "hs20-subrem-test",
1957 'password': "password" })
1958 interworking_select(dev
[0], bssid
, freq
="2412")
1959 interworking_connect(dev
[0], bssid
, "TTLS")
1960 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1962 raise Exception("Timeout on subscription remediation notice")
1963 if " 1 https://example.com/" not in ev
:
1964 raise Exception("Unexpected subscription remediation event contents")
1966 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1967 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1968 check_eap_capa(dev
[0], "MSCHAPV2")
1970 _test_ap_hs20_remediation_required_ctrl(dev
, apdev
)
1972 dev
[0].request("SET pmf 0")
1974 def _test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1975 bssid
= apdev
[0]['bssid']
1976 addr
= dev
[0].own_addr()
1977 params
= hs20_ap_params()
1978 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1979 hapd
= hostapd
.add_ap(apdev
[0], params
)
1981 dev
[0].request("SET pmf 1")
1982 dev
[0].hs20_enable()
1983 dev
[0].add_cred_values(default_cred())
1984 interworking_select(dev
[0], bssid
, freq
="2412")
1985 interworking_connect(dev
[0], bssid
, "TTLS")
1987 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
1988 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1990 raise Exception("Timeout on subscription remediation notice")
1991 if " 1 https://example.com/" not in ev
:
1992 raise Exception("Unexpected subscription remediation event contents")
1994 hapd
.request("HS20_WNM_NOTIF " + addr
)
1995 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1997 raise Exception("Timeout on subscription remediation notice")
1998 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1999 raise Exception("Unexpected subscription remediation event contents: " + ev
)
2001 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
2002 raise Exception("Unexpected HS20_WNM_NOTIF success")
2003 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
2004 raise Exception("Unexpected HS20_WNM_NOTIF success")
2005 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
2006 raise Exception("Unexpected HS20_WNM_NOTIF success")
2008 def test_ap_hs20_session_info(dev
, apdev
):
2009 """Hotspot 2.0 connection and session information from RADIUS"""
2010 check_eap_capa(dev
[0], "MSCHAPV2")
2012 _test_ap_hs20_session_info(dev
, apdev
)
2014 dev
[0].request("SET pmf 0")
2016 def _test_ap_hs20_session_info(dev
, apdev
):
2017 bssid
= apdev
[0]['bssid']
2018 params
= hs20_ap_params()
2019 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
2020 hostapd
.add_ap(apdev
[0], params
)
2022 dev
[0].request("SET pmf 1")
2023 dev
[0].hs20_enable()
2024 dev
[0].add_cred_values({ 'realm': "example.com",
2025 'username': "hs20-session-info-test",
2026 'password': "password" })
2027 interworking_select(dev
[0], bssid
, freq
="2412")
2028 interworking_connect(dev
[0], bssid
, "TTLS")
2029 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
2031 raise Exception("Timeout on ESS disassociation imminent notice")
2032 if " 1 59904 https://example.com/" not in ev
:
2033 raise Exception("Unexpected ESS disassociation imminent event contents")
2034 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
2036 raise Exception("Scan not started")
2037 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
2039 raise Exception("Scan not completed")
2041 def test_ap_hs20_osen(dev
, apdev
):
2042 """Hotspot 2.0 OSEN connection"""
2043 params
= { 'ssid': "osen",
2045 'auth_server_addr': "127.0.0.1",
2046 'auth_server_port': "1812",
2047 'auth_server_shared_secret': "radius" }
2048 hostapd
.add_ap(apdev
[0], params
)
2050 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
2052 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
2053 scan_freq
="2412", wait_connect
=False)
2054 dev
[0].flush_scan_cache()
2055 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2056 group
="GTK_NOT_USED",
2057 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2058 ca_cert
="auth_serv/ca.pem",
2060 res
= dev
[0].get_bss(apdev
[0]['bssid'])['flags']
2061 if "[OSEN-OSEN-CCMP]" not in res
:
2062 raise Exception("OSEN not reported in BSS")
2064 raise Exception("WEP reported in BSS")
2065 res
= dev
[0].request("SCAN_RESULTS")
2066 if "[OSEN-OSEN-CCMP]" not in res
:
2067 raise Exception("OSEN not reported in SCAN_RESULTS")
2069 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2070 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
2071 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2072 group
="GTK_NOT_USED",
2073 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2074 ca_cert
="auth_serv/ca.pem",
2076 wpas
.request("DISCONNECT")
2078 def test_ap_hs20_network_preference(dev
, apdev
):
2079 """Hotspot 2.0 network selection with preferred home network"""
2080 check_eap_capa(dev
[0], "MSCHAPV2")
2081 bssid
= apdev
[0]['bssid']
2082 params
= hs20_ap_params()
2083 hostapd
.add_ap(apdev
[0], params
)
2085 dev
[0].hs20_enable()
2086 values
= { 'realm': "example.com",
2087 'username': "hs20-test",
2088 'password': "password",
2089 'domain': "example.com" }
2090 dev
[0].add_cred_values(values
)
2092 id = dev
[0].add_network()
2093 dev
[0].set_network_quoted(id, "ssid", "home")
2094 dev
[0].set_network_quoted(id, "psk", "12345678")
2095 dev
[0].set_network(id, "priority", "1")
2096 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2098 dev
[0].scan_for_bss(bssid
, freq
="2412")
2099 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2100 ev
= dev
[0].wait_connected(timeout
=15)
2102 raise Exception("Unexpected network selected")
2104 bssid2
= apdev
[1]['bssid']
2105 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2106 hostapd
.add_ap(apdev
[1], params
)
2108 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2109 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2110 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2111 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2113 raise Exception("Connection timed out")
2114 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2115 raise Exception("No roam to higher priority network")
2116 if bssid2
not in ev
:
2117 raise Exception("Unexpected network selected")
2119 def test_ap_hs20_network_preference2(dev
, apdev
):
2120 """Hotspot 2.0 network selection with preferred credential"""
2121 check_eap_capa(dev
[0], "MSCHAPV2")
2122 bssid2
= apdev
[1]['bssid']
2123 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2124 hostapd
.add_ap(apdev
[1], params
)
2126 dev
[0].hs20_enable()
2127 values
= { 'realm': "example.com",
2128 'username': "hs20-test",
2129 'password': "password",
2130 'domain': "example.com",
2132 dev
[0].add_cred_values(values
)
2134 id = dev
[0].add_network()
2135 dev
[0].set_network_quoted(id, "ssid", "home")
2136 dev
[0].set_network_quoted(id, "psk", "12345678")
2137 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2139 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2140 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2141 ev
= dev
[0].wait_connected(timeout
=15)
2142 if bssid2
not in ev
:
2143 raise Exception("Unexpected network selected")
2145 bssid
= apdev
[0]['bssid']
2146 params
= hs20_ap_params()
2147 hostapd
.add_ap(apdev
[0], params
)
2149 dev
[0].scan_for_bss(bssid
, freq
="2412")
2150 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2151 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2152 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2154 raise Exception("Connection timed out")
2155 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2156 raise Exception("No roam to higher priority network")
2158 raise Exception("Unexpected network selected")
2160 def test_ap_hs20_network_preference3(dev
, apdev
):
2161 """Hotspot 2.0 network selection with two credential (one preferred)"""
2162 check_eap_capa(dev
[0], "MSCHAPV2")
2163 bssid
= apdev
[0]['bssid']
2164 params
= hs20_ap_params()
2165 hostapd
.add_ap(apdev
[0], params
)
2167 bssid2
= apdev
[1]['bssid']
2168 params
= hs20_ap_params(ssid
="test-hs20b")
2169 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
2170 hostapd
.add_ap(apdev
[1], params
)
2172 dev
[0].hs20_enable()
2173 values
= { 'realm': "example.com",
2174 'username': "hs20-test",
2175 'password': "password",
2177 dev
[0].add_cred_values(values
)
2178 values
= { 'realm': "example.org",
2179 'username': "hs20-test",
2180 'password': "password" }
2181 id = dev
[0].add_cred_values(values
)
2183 dev
[0].scan_for_bss(bssid
, freq
="2412")
2184 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2185 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2186 ev
= dev
[0].wait_connected(timeout
=15)
2188 raise Exception("Unexpected network selected")
2190 dev
[0].set_cred(id, "priority", "2")
2191 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2192 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2193 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2195 raise Exception("Connection timed out")
2196 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2197 raise Exception("No roam to higher priority network")
2198 if bssid2
not in ev
:
2199 raise Exception("Unexpected network selected")
2201 def test_ap_hs20_network_preference4(dev
, apdev
):
2202 """Hotspot 2.0 network selection with username vs. SIM credential"""
2203 check_eap_capa(dev
[0], "MSCHAPV2")
2204 bssid
= apdev
[0]['bssid']
2205 params
= hs20_ap_params()
2206 hostapd
.add_ap(apdev
[0], params
)
2208 bssid2
= apdev
[1]['bssid']
2209 params
= hs20_ap_params(ssid
="test-hs20b")
2210 params
['hessid'] = bssid2
2211 params
['anqp_3gpp_cell_net'] = "555,444"
2212 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
2213 hostapd
.add_ap(apdev
[1], params
)
2215 dev
[0].hs20_enable()
2216 values
= { 'realm': "example.com",
2217 'username': "hs20-test",
2218 'password': "password",
2220 dev
[0].add_cred_values(values
)
2221 values
= { 'imsi': "555444-333222111",
2223 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
2224 id = dev
[0].add_cred_values(values
)
2226 dev
[0].scan_for_bss(bssid
, freq
="2412")
2227 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2228 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2229 ev
= dev
[0].wait_connected(timeout
=15)
2231 raise Exception("Unexpected network selected")
2233 dev
[0].set_cred(id, "priority", "2")
2234 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2235 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2236 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2238 raise Exception("Connection timed out")
2239 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2240 raise Exception("No roam to higher priority network")
2241 if bssid2
not in ev
:
2242 raise Exception("Unexpected network selected")
2244 def test_ap_hs20_interworking_select_blocking_scan(dev
, apdev
):
2245 """Ongoing INTERWORKING_SELECT blocking SCAN"""
2246 check_eap_capa(dev
[0], "MSCHAPV2")
2247 bssid
= apdev
[0]['bssid']
2248 params
= hs20_ap_params()
2249 hostapd
.add_ap(apdev
[0], params
)
2251 dev
[0].hs20_enable()
2252 values
= { 'realm': "example.com",
2253 'username': "hs20-test",
2254 'password': "password",
2255 'domain': "example.com" }
2256 dev
[0].add_cred_values(values
)
2258 dev
[0].scan_for_bss(bssid
, freq
="2412")
2259 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2260 if "FAIL-BUSY" not in dev
[0].request("SCAN"):
2261 raise Exception("Unexpected SCAN command result")
2262 dev
[0].wait_connected(timeout
=15)
2264 def test_ap_hs20_fetch_osu(dev
, apdev
):
2265 """Hotspot 2.0 OSU provider and icon fetch"""
2266 bssid
= apdev
[0]['bssid']
2267 params
= hs20_ap_params()
2268 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2269 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2270 params
['osu_method_list'] = "1"
2271 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2272 params
['osu_icon'] = "w1fi_logo"
2273 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2274 params
['osu_server_uri'] = "https://example.com/osu/"
2275 hostapd
.add_ap(apdev
[0], params
)
2277 bssid2
= apdev
[1]['bssid']
2278 params
= hs20_ap_params(ssid
="test-hs20b")
2279 params
['hessid'] = bssid2
2280 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2281 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2282 params
['osu_method_list'] = "0"
2283 params
['osu_nai'] = "osen@example.com"
2284 params
['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
2285 params
['osu_icon'] = "w1fi_logo"
2286 params
['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
2287 params
['osu_server_uri'] = "https://example.org/osu/"
2288 hostapd
.add_ap(apdev
[1], params
)
2290 with
open("w1fi_logo.png", "r") as f
:
2291 orig_logo
= f
.read()
2292 dev
[0].hs20_enable()
2293 dir = "/tmp/osu-fetch"
2294 if os
.path
.isdir(dir):
2295 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2297 os
.remove(dir + "/" + f
)
2304 dev
[1].scan_for_bss(bssid
, freq
="2412")
2305 dev
[2].scan_for_bss(bssid
, freq
="2412")
2306 dev
[0].request("SET osu_dir " + dir)
2307 dev
[0].request("FETCH_OSU")
2308 if "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2309 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2310 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2311 raise Exception("HS20_ICON_REQUEST failed")
2312 if "OK" not in dev
[2].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2313 raise Exception("REQ_HS20_ICON failed")
2316 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2317 "RX-HS20-ANQP-ICON"], timeout
=15)
2319 raise Exception("Timeout on OSU fetch")
2320 if "OSU provider fetch completed" in ev
:
2322 if "RX-HS20-ANQP-ICON" in ev
:
2323 with
open(ev
.split(' ')[1], "r") as f
:
2325 if logo
== orig_logo
:
2328 with
open(dir + "/osu-providers.txt", "r") as f
:
2330 logger
.debug("osu-providers.txt: " + prov
)
2331 if "OSU-PROVIDER " + bssid
not in prov
:
2332 raise Exception("Missing OSU_PROVIDER(1)")
2333 if "OSU-PROVIDER " + bssid2
not in prov
:
2334 raise Exception("Missing OSU_PROVIDER(2)")
2336 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2338 os
.remove(dir + "/" + f
)
2342 raise Exception("Unexpected number of icons fetched")
2344 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2346 raise Exception("Timeout on GAS-QUERY-DONE")
2347 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2349 raise Exception("Timeout on GAS-QUERY-DONE")
2350 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2351 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2352 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2354 raise Exception("Timeout on icon fetch")
2355 if "Icon Binary File" not in ev
:
2356 raise Exception("Unexpected ANQP element")
2358 ev
= dev
[2].wait_event(["RX-HS20-ICON"], timeout
=5)
2360 raise Exception("Timeout on RX-HS20-ICON")
2361 event_icon_len
= ev
.split(' ')[3]
2362 if " w1fi_logo " not in ev
:
2363 raise Exception("RX-HS20-ICON did not have the expected file name")
2365 raise Exception("RX-HS20-ICON did not have the expected BSSID")
2366 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 10"):
2367 raise Exception("GET_HS20_ICON 0..10 failed")
2368 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 5 10"):
2369 raise Exception("GET_HS20_ICON 5..15 failed")
2370 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 100000 10"):
2371 raise Exception("Unexpected success of GET_HS20_ICON with too large offset")
2376 raise Exception("Unexpectedly long icon")
2377 res
= dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo %d 1000" % pos
)
2378 if res
.startswith("FAIL"):
2380 icon
+= base64
.b64decode(res
)
2382 hex = binascii
.hexlify(icon
)
2383 if not hex.startswith("0009696d6167652f706e677d1d"):
2384 raise Exception("Unexpected beacon binary header: " + hex)
2385 with
open('w1fi_logo.png', 'r') as f
:
2387 if icon
[13:] != data
:
2388 raise Exception("Unexpected icon data")
2389 if len(icon
) != int(event_icon_len
):
2390 raise Exception("Unexpected RX-HS20-ICON event length: " + event_icon_len
)
2393 if "OK" not in dev
[i
].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2394 raise Exception("REQ_HS20_ICON failed [2]")
2396 ev
= dev
[i
].wait_event(["RX-HS20-ICON"], timeout
=5)
2398 raise Exception("Timeout on RX-HS20-ICON [2]")
2400 if "FAIL" not in dev
[2].request("DEL_HS20_ICON foo w1fi_logo"):
2401 raise Exception("Invalid DEL_HS20_ICON accepted")
2402 if "OK" not in dev
[2].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
2403 raise Exception("DEL_HS20_ICON failed")
2404 if "OK" not in dev
[1].request("DEL_HS20_ICON " + bssid
):
2405 raise Exception("DEL_HS20_ICON failed")
2406 if "OK" not in dev
[0].request("DEL_HS20_ICON "):
2407 raise Exception("DEL_HS20_ICON failed")
2409 if "FAIL" not in dev
[i
].request("DEL_HS20_ICON "):
2410 raise Exception("DEL_HS20_ICON accepted when no icons left")
2412 def get_icon(dev
, bssid
, iconname
):
2417 raise Exception("Unexpectedly long icon")
2418 res
= dev
.request("GET_HS20_ICON " + bssid
+ " " + iconname
+ " %d 3000" % pos
)
2419 if res
.startswith("FAIL"):
2421 icon
+= base64
.b64decode(res
)
2424 raise Exception("Too short GET_HS20_ICON response")
2425 return icon
[0:13], icon
[13:]
2427 def test_ap_hs20_req_hs20_icon(dev
, apdev
):
2428 """Hotspot 2.0 OSU provider and multi-icon fetch with REQ_HS20_ICON"""
2429 bssid
= apdev
[0]['bssid']
2430 params
= hs20_ap_params()
2431 params
['hs20_icon'] = [ "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
2432 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem" ]
2433 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2434 params
['osu_method_list'] = "1"
2435 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2436 params
['osu_icon'] = [ "w1fi_logo", "w1fi_logo2" ]
2437 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2438 params
['osu_server_uri'] = "https://example.com/osu/"
2439 hostapd
.add_ap(apdev
[0], params
)
2441 dev
[0].scan_for_bss(bssid
, freq
="2412")
2443 # First, fetch two icons from the AP to wpa_supplicant
2445 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2446 raise Exception("REQ_HS20_ICON failed")
2447 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
2449 raise Exception("Timeout on RX-HS20-ICON (1)")
2451 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
2452 raise Exception("REQ_HS20_ICON failed")
2453 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
2455 raise Exception("Timeout on RX-HS20-ICON (2)")
2457 # Then, fetch the icons from wpa_supplicant for validation
2459 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
2460 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
2462 with
open('w1fi_logo.png', 'r') as f
:
2465 raise Exception("Unexpected icon data (1)")
2467 with
open('auth_serv/sha512-server.pem', 'r') as f
:
2470 raise Exception("Unexpected icon data (2)")
2472 # Finally, delete the icons from wpa_supplicant
2474 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
2475 raise Exception("DEL_HS20_ICON failed")
2476 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
2477 raise Exception("DEL_HS20_ICON failed")
2479 def test_ap_hs20_req_hs20_icon_parallel(dev
, apdev
):
2480 """Hotspot 2.0 OSU provider and multi-icon parallel fetch with REQ_HS20_ICON"""
2481 bssid
= apdev
[0]['bssid']
2482 params
= hs20_ap_params()
2483 params
['hs20_icon'] = [ "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
2484 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem" ]
2485 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2486 params
['osu_method_list'] = "1"
2487 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2488 params
['osu_icon'] = [ "w1fi_logo", "w1fi_logo2" ]
2489 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2490 params
['osu_server_uri'] = "https://example.com/osu/"
2491 hostapd
.add_ap(apdev
[0], params
)
2493 dev
[0].scan_for_bss(bssid
, freq
="2412")
2495 # First, fetch two icons from the AP to wpa_supplicant
2497 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2498 raise Exception("REQ_HS20_ICON failed")
2500 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
2501 raise Exception("REQ_HS20_ICON failed")
2502 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
2504 raise Exception("Timeout on RX-HS20-ICON (1)")
2505 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
2507 raise Exception("Timeout on RX-HS20-ICON (2)")
2509 # Then, fetch the icons from wpa_supplicant for validation
2511 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
2512 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
2514 with
open('w1fi_logo.png', 'r') as f
:
2517 raise Exception("Unexpected icon data (1)")
2519 with
open('auth_serv/sha512-server.pem', 'r') as f
:
2522 raise Exception("Unexpected icon data (2)")
2524 # Finally, delete the icons from wpa_supplicant
2526 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
2527 raise Exception("DEL_HS20_ICON failed")
2528 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
2529 raise Exception("DEL_HS20_ICON failed")
2531 def test_ap_hs20_fetch_osu_stop(dev
, apdev
):
2532 """Hotspot 2.0 OSU provider fetch stopped"""
2533 bssid
= apdev
[0]['bssid']
2534 params
= hs20_ap_params()
2535 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2536 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2537 params
['osu_method_list'] = "1"
2538 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2539 params
['osu_icon'] = "w1fi_logo"
2540 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2541 params
['osu_server_uri'] = "https://example.com/osu/"
2542 hapd
= hostapd
.add_ap(apdev
[0], params
)
2544 dev
[0].hs20_enable()
2545 dir = "/tmp/osu-fetch"
2546 if os
.path
.isdir(dir):
2547 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2549 os
.remove(dir + "/" + f
)
2556 dev
[0].request("SET osu_dir " + dir)
2557 dev
[0].request("SCAN freq=2412-2462")
2558 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=10)
2560 raise Exception("Scan did not start")
2561 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2562 raise Exception("FETCH_OSU accepted while scanning")
2563 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
2565 raise Exception("Scan timed out")
2566 hapd
.set("ext_mgmt_frame_handling", "1")
2567 dev
[0].request("FETCH_ANQP")
2568 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2569 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
2570 dev
[0].request("STOP_FETCH_ANQP")
2571 dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2572 dev
[0].dump_monitor()
2574 dev
[0].request("INTERWORKING_SELECT freq=2412")
2576 msg
= hapd
.mgmt_rx()
2577 if msg
['subtype'] == 13:
2579 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2580 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
2581 ev
= dev
[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
2584 raise Exception("Network selection timed out");
2586 dev
[0].dump_monitor()
2587 if "OK" not in dev
[0].request("FETCH_OSU"):
2588 raise Exception("FETCH_OSU failed")
2589 dev
[0].request("CANCEL_FETCH_OSU")
2593 if dev
[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
2596 dev
[0].dump_monitor()
2597 if "OK" not in dev
[0].request("FETCH_OSU"):
2598 raise Exception("FETCH_OSU failed")
2599 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2600 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2601 ev
= dev
[0].wait_event(["GAS-QUERY-START"], 10)
2603 raise Exception("GAS timed out")
2604 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2605 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2606 dev
[0].request("CANCEL_FETCH_OSU")
2607 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], 10)
2609 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
2611 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2613 os
.remove(dir + "/" + f
)
2616 def test_ap_hs20_ft(dev
, apdev
):
2617 """Hotspot 2.0 connection with FT"""
2618 check_eap_capa(dev
[0], "MSCHAPV2")
2619 bssid
= apdev
[0]['bssid']
2620 params
= hs20_ap_params()
2621 params
['wpa_key_mgmt'] = "FT-EAP"
2622 params
['nas_identifier'] = "nas1.w1.fi"
2623 params
['r1_key_holder'] = "000102030405"
2624 params
["mobility_domain"] = "a1b2"
2625 params
["reassociation_deadline"] = "1000"
2626 hostapd
.add_ap(apdev
[0], params
)
2628 dev
[0].hs20_enable()
2629 id = dev
[0].add_cred_values({ 'realm': "example.com",
2630 'username': "hs20-test",
2631 'password': "password",
2632 'ca_cert': "auth_serv/ca.pem",
2633 'domain': "example.com",
2634 'update_identifier': "1234" })
2635 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2636 interworking_connect(dev
[0], bssid
, "TTLS")
2638 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
2639 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2640 check_eap_capa(dev
[0], "MSCHAPV2")
2644 raise HwsimSkip("No sqlite3 module available")
2645 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
2650 con
= sqlite3
.connect(dbfile
)
2653 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2654 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2655 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2656 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2657 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2660 params
= { "ssid": "as", "beacon_int": "2000",
2661 "radius_server_clients": "auth_serv/radius_clients.conf",
2662 "radius_server_auth_port": '18128',
2664 "eap_user_file": "sqlite:" + dbfile
,
2665 "ca_cert": "auth_serv/ca.pem",
2666 "server_cert": "auth_serv/server.pem",
2667 "private_key": "auth_serv/server.key",
2668 "subscr_remediation_url": "https://example.org/",
2669 "subscr_remediation_method": "1" }
2670 hostapd
.add_ap(apdev
[1], params
)
2672 bssid
= apdev
[0]['bssid']
2673 params
= hs20_ap_params()
2674 params
['auth_server_port'] = "18128"
2675 hostapd
.add_ap(apdev
[0], params
)
2677 dev
[0].request("SET pmf 1")
2678 dev
[0].hs20_enable()
2679 id = dev
[0].add_cred_values({ 'realm': "example.com",
2680 'username': "user-mschapv2",
2681 'password': "password",
2682 'ca_cert': "auth_serv/ca.pem" })
2683 interworking_select(dev
[0], bssid
, freq
="2412")
2684 interworking_connect(dev
[0], bssid
, "TTLS")
2685 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2687 raise Exception("Timeout on subscription remediation notice")
2688 if " 1 https://example.org/" not in ev
:
2689 raise Exception("Unexpected subscription remediation event contents")
2693 cur
.execute("SELECT * from authlog")
2694 rows
= cur
.fetchall()
2696 raise Exception("No authlog entries")
2700 dev
[0].request("SET pmf 0")
2702 def test_ap_hs20_external_selection(dev
, apdev
):
2703 """Hotspot 2.0 connection using external network selection and creation"""
2704 check_eap_capa(dev
[0], "MSCHAPV2")
2705 bssid
= apdev
[0]['bssid']
2706 params
= hs20_ap_params()
2707 params
['hessid'] = bssid
2708 params
['disable_dgaf'] = '1'
2709 hostapd
.add_ap(apdev
[0], params
)
2711 dev
[0].hs20_enable()
2712 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
2713 identity
="hs20-test", password
="password",
2714 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2715 scan_freq
="2412", update_identifier
="54321")
2716 if dev
[0].get_status_field("hs20") != "2":
2717 raise Exception("Unexpected hs20 indication")
2719 def test_ap_hs20_random_mac_addr(dev
, apdev
):
2720 """Hotspot 2.0 connection with random MAC address"""
2721 check_eap_capa(dev
[0], "MSCHAPV2")
2722 bssid
= apdev
[0]['bssid']
2723 params
= hs20_ap_params()
2724 params
['hessid'] = bssid
2725 params
['disable_dgaf'] = '1'
2726 hapd
= hostapd
.add_ap(apdev
[0], params
)
2728 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2729 wpas
.interface_add("wlan5")
2730 addr
= wpas
.p2p_interface_addr()
2731 wpas
.request("SET mac_addr 1")
2732 wpas
.request("SET preassoc_mac_addr 1")
2733 wpas
.request("SET rand_addr_lifetime 60")
2735 wpas
.flush_scan_cache()
2736 id = wpas
.add_cred_values({ 'realm': "example.com",
2737 'username': "hs20-test",
2738 'password': "password",
2739 'ca_cert': "auth_serv/ca.pem",
2740 'domain': "example.com",
2741 'update_identifier': "1234" })
2742 interworking_select(wpas
, bssid
, "home", freq
="2412")
2743 interworking_connect(wpas
, bssid
, "TTLS")
2744 addr1
= wpas
.get_driver_status_field("addr")
2746 raise Exception("Did not use random MAC address")
2748 sta
= hapd
.get_sta(addr
)
2749 if sta
['addr'] != "FAIL":
2750 raise Exception("Unexpected STA association with permanent address")
2751 sta
= hapd
.get_sta(addr1
)
2752 if sta
['addr'] != addr1
:
2753 raise Exception("STA association with random address not found")
2755 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
2756 """Multiple networks and cred removal"""
2757 check_eap_capa(dev
[0], "MSCHAPV2")
2758 bssid
= apdev
[0]['bssid']
2759 params
= hs20_ap_params()
2760 params
['nai_realm'] = [ "0,example.com,25[3:26]"]
2761 hapd
= hostapd
.add_ap(apdev
[0], params
)
2763 dev
[0].add_network()
2764 dev
[0].hs20_enable()
2765 id = dev
[0].add_cred_values({ 'realm': "example.com",
2767 'password': "password" })
2768 interworking_select(dev
[0], bssid
, freq
="2412")
2769 interworking_connect(dev
[0], bssid
, "PEAP")
2770 dev
[0].add_network()
2772 dev
[0].request("DISCONNECT")
2773 dev
[0].wait_disconnected(timeout
=10)
2776 hapd
.set("ssid", "another ssid")
2779 interworking_select(dev
[0], bssid
, freq
="2412")
2780 interworking_connect(dev
[0], bssid
, "PEAP")
2781 dev
[0].add_network()
2782 if len(dev
[0].list_networks()) != 5:
2783 raise Exception("Unexpected number of networks prior to remove_crec")
2785 dev
[0].dump_monitor()
2786 dev
[0].remove_cred(id)
2787 if len(dev
[0].list_networks()) != 3:
2788 raise Exception("Unexpected number of networks after to remove_crec")
2789 dev
[0].wait_disconnected(timeout
=10)
2791 def test_ap_hs20_interworking_add_network(dev
, apdev
):
2792 """Hotspot 2.0 connection using INTERWORKING_ADD_NETWORK"""
2793 check_eap_capa(dev
[0], "MSCHAPV2")
2794 bssid
= apdev
[0]['bssid']
2795 params
= hs20_ap_params()
2796 params
['nai_realm'] = [ "0,example.com,21[3:26][6:7][99:99]" ]
2797 hostapd
.add_ap(apdev
[0], params
)
2799 dev
[0].hs20_enable()
2800 dev
[0].add_cred_values(default_cred(user
="user"))
2801 interworking_select(dev
[0], bssid
, freq
=2412)
2802 id = dev
[0].interworking_add_network(bssid
)
2803 dev
[0].select_network(id, freq
=2412)
2804 dev
[0].wait_connected()
2806 def _test_ap_hs20_proxyarp(dev
, apdev
):
2807 bssid
= apdev
[0]['bssid']
2808 params
= hs20_ap_params()
2809 params
['hessid'] = bssid
2810 params
['disable_dgaf'] = '0'
2811 params
['proxy_arp'] = '1'
2812 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
2813 if "OK" in hapd
.request("ENABLE"):
2814 raise Exception("Incomplete hostapd configuration was accepted")
2815 hapd
.set("ap_isolate", "1")
2816 if "OK" in hapd
.request("ENABLE"):
2817 raise Exception("Incomplete hostapd configuration was accepted")
2818 hapd
.set('bridge', 'ap-br0')
2823 # For now, do not report failures due to missing kernel support
2824 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2825 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2827 raise Exception("AP startup timed out")
2828 if "AP-ENABLED" not in ev
:
2829 raise Exception("AP startup failed")
2831 dev
[0].hs20_enable()
2832 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2833 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2835 id = dev
[0].add_cred_values({ 'realm': "example.com",
2836 'username': "hs20-test",
2837 'password': "password",
2838 'ca_cert': "auth_serv/ca.pem",
2839 'domain': "example.com",
2840 'update_identifier': "1234" })
2841 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2842 interworking_connect(dev
[0], bssid
, "TTLS")
2844 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2845 identity
="hs20-test", password
="password",
2846 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2850 addr0
= dev
[0].p2p_interface_addr()
2851 addr1
= dev
[1].p2p_interface_addr()
2853 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2854 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2856 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2857 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2859 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2860 raise Exception("DATA_TEST_FRAME failed")
2862 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2863 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2865 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2866 raise Exception("DATA_TEST_FRAME failed")
2868 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2869 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2871 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2872 raise Exception("DATA_TEST_FRAME failed")
2874 matches
= get_permanent_neighbors("ap-br0")
2875 logger
.info("After connect: " + str(matches
))
2876 if len(matches
) != 3:
2877 raise Exception("Unexpected number of neighbor entries after connect")
2878 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2879 raise Exception("dev0 addr missing")
2880 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2881 raise Exception("dev1 addr(1) missing")
2882 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2883 raise Exception("dev1 addr(2) missing")
2884 dev
[0].request("DISCONNECT")
2885 dev
[1].request("DISCONNECT")
2887 matches
= get_permanent_neighbors("ap-br0")
2888 logger
.info("After disconnect: " + str(matches
))
2889 if len(matches
) > 0:
2890 raise Exception("Unexpected neighbor entries after disconnect")
2892 def test_ap_hs20_hidden_ssid_in_scan_res(dev
, apdev
):
2893 """Hotspot 2.0 connection with hidden SSId in scan results"""
2894 check_eap_capa(dev
[0], "MSCHAPV2")
2895 bssid
= apdev
[0]['bssid']
2897 hapd
= hostapd
.add_ap(apdev
[0], { "ssid": 'secret',
2898 "ignore_broadcast_ssid": "1" })
2899 dev
[0].scan_for_bss(bssid
, freq
=2412)
2901 hapd_global
= hostapd
.HostapdGlobal()
2903 hapd_global
.remove(apdev
[0]['ifname'])
2905 params
= hs20_ap_params()
2906 params
['hessid'] = bssid
2907 hapd
= hostapd
.add_ap(apdev
[0], params
)
2909 dev
[0].hs20_enable()
2910 id = dev
[0].add_cred_values({ 'realm': "example.com",
2911 'username': "hs20-test",
2912 'password': "password",
2913 'ca_cert': "auth_serv/ca.pem",
2914 'domain': "example.com" })
2915 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2916 interworking_connect(dev
[0], bssid
, "TTLS")
2918 # clear BSS table to avoid issues in following test cases
2919 dev
[0].request("DISCONNECT")
2920 dev
[0].wait_disconnected()
2922 dev
[0].flush_scan_cache()
2923 dev
[0].flush_scan_cache()
2925 def test_ap_hs20_proxyarp(dev
, apdev
):
2926 """Hotspot 2.0 and ProxyARP"""
2927 check_eap_capa(dev
[0], "MSCHAPV2")
2929 _test_ap_hs20_proxyarp(dev
, apdev
)
2931 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2932 stderr
=open('/dev/null', 'w'))
2933 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2934 stderr
=open('/dev/null', 'w'))
2936 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
2937 bssid
= apdev
[0]['bssid']
2938 params
= hs20_ap_params()
2939 params
['hessid'] = bssid
2940 params
['disable_dgaf'] = '1' if disabled
else '0'
2941 params
['proxy_arp'] = '1'
2942 params
['na_mcast_to_ucast'] = '1'
2943 params
['ap_isolate'] = '1'
2944 params
['bridge'] = 'ap-br0'
2945 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
2949 # For now, do not report failures due to missing kernel support
2950 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2951 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
2953 raise Exception("AP startup timed out")
2955 dev
[0].hs20_enable()
2956 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2957 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2959 id = dev
[0].add_cred_values({ 'realm': "example.com",
2960 'username': "hs20-test",
2961 'password': "password",
2962 'ca_cert': "auth_serv/ca.pem",
2963 'domain': "example.com",
2964 'update_identifier': "1234" })
2965 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2966 interworking_connect(dev
[0], bssid
, "TTLS")
2968 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2969 identity
="hs20-test", password
="password",
2970 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2974 addr0
= dev
[0].p2p_interface_addr()
2976 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2978 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2979 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2981 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2982 raise Exception("DATA_TEST_FRAME failed")
2984 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
2986 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2987 raise Exception("DATA_TEST_FRAME failed")
2989 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
2990 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
2991 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2992 raise Exception("DATA_TEST_FRAME failed")
2994 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2995 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2996 yiaddr
="192.168.1.123", chaddr
=addr0
)
2997 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2998 raise Exception("DATA_TEST_FRAME failed")
2999 # another copy for additional code coverage
3000 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
3001 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3002 yiaddr
="192.168.1.123", chaddr
=addr0
)
3003 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3004 raise Exception("DATA_TEST_FRAME failed")
3006 matches
= get_permanent_neighbors("ap-br0")
3007 logger
.info("After connect: " + str(matches
))
3008 if len(matches
) != 2:
3009 raise Exception("Unexpected number of neighbor entries after connect")
3010 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3011 raise Exception("dev0 addr missing")
3012 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3013 raise Exception("dev0 IPv4 addr missing")
3014 dev
[0].request("DISCONNECT")
3015 dev
[1].request("DISCONNECT")
3017 matches
= get_permanent_neighbors("ap-br0")
3018 logger
.info("After disconnect: " + str(matches
))
3019 if len(matches
) > 0:
3020 raise Exception("Unexpected neighbor entries after disconnect")
3022 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
3023 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
3024 check_eap_capa(dev
[0], "MSCHAPV2")
3026 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
3028 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3029 stderr
=open('/dev/null', 'w'))
3030 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3031 stderr
=open('/dev/null', 'w'))
3033 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
3034 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
3035 check_eap_capa(dev
[0], "MSCHAPV2")
3037 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
3039 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3040 stderr
=open('/dev/null', 'w'))
3041 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3042 stderr
=open('/dev/null', 'w'))
3044 def ip_checksum(buf
):
3048 for i
in range(0, len(buf
), 2):
3049 val
, = struct
.unpack('H', buf
[i
:i
+2])
3052 sum = (sum & 0xffff) + (sum >> 16)
3053 return struct
.pack('H', ~
sum & 0xffff)
3055 def ipv6_solicited_node_mcaddr(target
):
3056 prefix
= socket
.inet_pton(socket
.AF_INET6
, "ff02::1:ff00:0")
3057 mask
= socket
.inet_pton(socket
.AF_INET6
, "::ff:ffff")
3058 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
3059 p
= struct
.unpack('4I', prefix
)
3060 m
= struct
.unpack('4I', mask
)
3061 t
= struct
.unpack('4I', _target
)
3062 res
= (p
[0] |
(t
[0] & m
[0]),
3063 p
[1] |
(t
[1] & m
[1]),
3064 p
[2] |
(t
[2] & m
[2]),
3065 p
[3] |
(t
[3] & m
[3]))
3066 return socket
.inet_ntop(socket
.AF_INET6
, struct
.pack('4I', *res
))
3068 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
3069 start
= struct
.pack("BB", type, code
)
3071 icmp
= start
+ '\x00\x00' + end
3072 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
3073 csum
= ip_checksum(pseudo
+ icmp
)
3074 return start
+ csum
+ end
3076 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
3077 reachable_time
=0, retrans_timer
=0, opt
=None):
3078 link_mc
= binascii
.unhexlify("3333ff000002")
3079 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3081 ehdr
= link_mc
+ _src_ll
+ proto
3082 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
3083 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
3085 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
3086 reachable_time
, retrans_timer
)
3091 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
3093 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
3094 ipv6
+= _ip_src
+ _ip_dst
3096 return ehdr
+ ipv6
+ icmp
3098 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
3099 link_mc
= binascii
.unhexlify("3333ff000002")
3100 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3102 ehdr
= link_mc
+ _src_ll
+ proto
3103 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
3105 ip_dst
= ipv6_solicited_node_mcaddr(target
)
3106 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
3108 reserved
= '\x00\x00\x00\x00'
3109 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
3111 payload
= reserved
+ _target
+ opt
3113 payload
= reserved
+ _target
3114 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
3116 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
3117 ipv6
+= _ip_src
+ _ip_dst
3119 return ehdr
+ ipv6
+ icmp
3121 def send_ns(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
3126 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
3129 src_ll
= dev
.p2p_interface_addr()
3130 cmd
= "DATA_TEST_FRAME "
3133 opt
= "\x01\x01" + binascii
.unhexlify(src_ll
.replace(':',''))
3135 pkt
= build_ns(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
3137 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
3138 raise Exception("DATA_TEST_FRAME failed")
3140 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None, flags
=0):
3141 link_mc
= binascii
.unhexlify("3333ff000002")
3142 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3144 ehdr
= link_mc
+ _src_ll
+ proto
3145 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
3146 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
3148 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
3150 payload
= struct
.pack('>Bxxx', flags
) + _target
+ opt
3152 payload
= struct
.pack('>Bxxx', flags
) + _target
3153 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
3155 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
3156 ipv6
+= _ip_src
+ _ip_dst
3158 return ehdr
+ ipv6
+ icmp
3160 def send_na(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
3165 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
3168 src_ll
= dev
.p2p_interface_addr()
3169 cmd
= "DATA_TEST_FRAME "
3171 pkt
= build_na(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
3173 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
3174 raise Exception("DATA_TEST_FRAME failed")
3176 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
3177 subnet_mask
="255.255.255.0", truncated_opt
=False,
3178 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False):
3179 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
3180 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3182 ehdr
= _dst_ll
+ _src_ll
+ proto
3183 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
3184 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
3185 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
3187 _ciaddr
= '\x00\x00\x00\x00'
3188 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
3189 _siaddr
= '\x00\x00\x00\x00'
3190 _giaddr
= '\x00\x00\x00\x00'
3191 _chaddr
= binascii
.unhexlify(chaddr
.replace(':','') + "00000000000000000000")
3192 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
3193 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
3196 payload
+= '\x63\x82\x53\x00'
3198 payload
+= '\x63\x82\x53\x63'
3200 payload
+= '\x22\xff\x00'
3201 # Option: DHCP Message Type = ACK
3202 payload
+= '\x35\x01\x05'
3205 # Option: Subnet Mask
3206 payload
+= '\x01\x04' + _subnet_mask
3207 # Option: Time Offset
3208 payload
+= struct
.pack('>BBL', 2, 4, 0)
3212 payload
+= '\x00\x00\x00\x00'
3215 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
3216 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
3218 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0) + payload
3221 tot_len
= force_tot_len
3223 tot_len
= 20 + len(udp
)
3224 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
3225 ipv4
= start
+ '\x00\x00' + _ip_src
+ _ip_dst
3226 csum
= ip_checksum(ipv4
)
3227 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
3229 return ehdr
+ ipv4
+ udp
3231 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
3232 target_mac
, target_ip
):
3233 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
3234 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3236 ehdr
= _dst_ll
+ _src_ll
+ proto
3238 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':',''))
3239 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
3240 _target_mac
= binascii
.unhexlify(target_mac
.replace(':',''))
3241 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
3243 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
3244 arp
+= _sender_mac
+ _sender_ip
3245 arp
+= _target_mac
+ _target_ip
3249 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
3250 sender_mac
=None, sender_ip
="0.0.0.0",
3251 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
3256 if sender_mac
is None:
3257 sender_mac
= hapd_bssid
3258 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
3261 src_ll
= dev
.p2p_interface_addr()
3262 if sender_mac
is None:
3263 sender_mac
= dev
.p2p_interface_addr()
3264 cmd
= "DATA_TEST_FRAME "
3266 pkt
= build_arp(dst_ll
=dst_ll
, src_ll
=src_ll
, opcode
=opcode
,
3267 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
3268 target_mac
=target_mac
, target_ip
=target_ip
)
3269 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
3270 raise Exception("DATA_TEST_FRAME failed")
3272 def get_permanent_neighbors(ifname
):
3273 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
3274 res
= cmd
.stdout
.read()
3276 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
3278 def get_bridge_macs(ifname
):
3279 cmd
= subprocess
.Popen(['brctl', 'showmacs', ifname
],
3280 stdout
=subprocess
.PIPE
)
3281 res
= cmd
.stdout
.read()
3285 def tshark_get_arp(cap
, filter):
3286 res
= run_tshark(cap
, filter,
3287 [ "eth.dst", "eth.src",
3288 "arp.src.hw_mac", "arp.src.proto_ipv4",
3289 "arp.dst.hw_mac", "arp.dst.proto_ipv4" ],
3292 for l
in res
.splitlines():
3293 frames
.append(l
.split('\t'))
3296 def tshark_get_ns(cap
):
3297 res
= run_tshark(cap
, "icmpv6.type == 135",
3298 [ "eth.dst", "eth.src",
3299 "ipv6.src", "ipv6.dst",
3300 "icmpv6.nd.ns.target_address",
3301 "icmpv6.opt.linkaddr" ],
3304 for l
in res
.splitlines():
3305 frames
.append(l
.split('\t'))
3308 def tshark_get_na(cap
):
3309 res
= run_tshark(cap
, "icmpv6.type == 136",
3310 [ "eth.dst", "eth.src",
3311 "ipv6.src", "ipv6.dst",
3312 "icmpv6.nd.na.target_address",
3313 "icmpv6.opt.linkaddr" ],
3316 for l
in res
.splitlines():
3317 frames
.append(l
.split('\t'))
3320 def _test_proxyarp_open(dev
, apdev
, params
, ebtables
=False):
3321 prefix
= "proxyarp_open"
3323 prefix
+= "_ebtables"
3324 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
3325 cap_dev0
= os
.path
.join(params
['logdir'],
3326 prefix
+ ".%s.pcap" % dev
[0].ifname
)
3327 cap_dev1
= os
.path
.join(params
['logdir'],
3328 prefix
+ ".%s.pcap" % dev
[1].ifname
)
3329 cap_dev2
= os
.path
.join(params
['logdir'],
3330 prefix
+ ".%s.pcap" % dev
[2].ifname
)
3332 bssid
= apdev
[0]['bssid']
3333 params
= { 'ssid': 'open' }
3334 params
['proxy_arp'] = '1'
3335 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
3336 hapd
.set("ap_isolate", "1")
3337 hapd
.set('bridge', 'ap-br0')
3342 # For now, do not report failures due to missing kernel support
3343 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
3344 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
3346 raise Exception("AP startup timed out")
3347 if "AP-ENABLED" not in ev
:
3348 raise Exception("AP startup failed")
3350 params2
= { 'ssid': 'another' }
3351 hapd2
= hostapd
.add_ap(apdev
[1], params2
, no_enable
=True)
3352 hapd2
.set('bridge', 'ap-br0')
3355 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
3356 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
3359 for chain
in [ 'FORWARD', 'OUTPUT' ]:
3360 subprocess
.call(['ebtables', '-A', chain
, '-p', 'ARP',
3361 '-d', 'Broadcast', '-o', apdev
[0]['ifname'],
3363 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3364 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3365 '--ip6-icmp-type', 'neighbor-solicitation',
3366 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3367 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3368 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3369 '--ip6-icmp-type', 'neighbor-advertisement',
3370 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3371 subprocess
.call(['ebtables', '-A', chain
,
3372 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3373 '--ip6-icmp-type', 'router-solicitation',
3374 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3375 # Multicast Listener Report Message
3376 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3377 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3378 '--ip6-icmp-type', '143',
3379 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3383 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
3384 '-w', cap_br
, '-s', '2000'],
3385 stderr
=open('/dev/null', 'w'))
3386 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
3387 '-w', cap_dev0
, '-s', '2000'],
3388 stderr
=open('/dev/null', 'w'))
3389 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
3390 '-w', cap_dev1
, '-s', '2000'],
3391 stderr
=open('/dev/null', 'w'))
3392 cmd
[3] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[2].ifname
,
3393 '-w', cap_dev2
, '-s', '2000'],
3394 stderr
=open('/dev/null', 'w'))
3396 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
3397 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
3398 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
3401 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
3402 res
= brcmd
.stdout
.read()
3403 brcmd
.stdout
.close()
3404 logger
.info("Bridge setup: " + res
)
3406 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
3407 stdout
=subprocess
.PIPE
)
3408 res
= brcmd
.stdout
.read()
3409 brcmd
.stdout
.close()
3410 logger
.info("Bridge showstp: " + res
)
3412 addr0
= dev
[0].p2p_interface_addr()
3413 addr1
= dev
[1].p2p_interface_addr()
3414 addr2
= dev
[2].p2p_interface_addr()
3416 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
3417 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
3420 send_ns(dev
[0], ip_src
="::", target
="aaaa:bbbb:cccc::2")
3422 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2")
3423 # test frame without source link-layer address option
3424 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3426 # test frame with bogus option
3427 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3428 opt
="\x70\x01\x01\x02\x03\x04\x05\x05")
3429 # test frame with truncated source link-layer address option
3430 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3431 opt
="\x01\x01\x01\x02\x03\x04")
3432 # test frame with foreign source link-layer address option
3433 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3434 opt
="\x01\x01\x01\x02\x03\x04\x05\x06")
3436 send_ns(dev
[1], ip_src
="aaaa:bbbb:dddd::2", target
="aaaa:bbbb:dddd::2")
3438 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
3439 # another copy for additional code coverage
3440 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
3442 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
3443 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3444 yiaddr
="192.168.1.124", chaddr
=addr0
)
3445 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3446 raise Exception("DATA_TEST_FRAME failed")
3447 # Change address and verify unicast
3448 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
3449 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3450 yiaddr
="192.168.1.123", chaddr
=addr0
)
3451 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3452 raise Exception("DATA_TEST_FRAME failed")
3454 # Not-associated client MAC address
3455 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
3456 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3457 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
3458 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3459 raise Exception("DATA_TEST_FRAME failed")
3462 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3463 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3464 yiaddr
="0.0.0.0", chaddr
=addr1
)
3465 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3466 raise Exception("DATA_TEST_FRAME failed")
3469 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3470 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3471 yiaddr
="192.168.1.126", chaddr
=addr1
,
3472 subnet_mask
="0.0.0.0")
3473 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3474 raise Exception("DATA_TEST_FRAME failed")
3477 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3478 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3479 yiaddr
="192.168.1.127", chaddr
=addr1
,
3481 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3482 raise Exception("DATA_TEST_FRAME failed")
3485 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3486 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3487 yiaddr
="192.168.1.128", chaddr
=addr1
,
3489 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3490 raise Exception("DATA_TEST_FRAME failed")
3492 # Wrong IPv4 total length
3493 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3494 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3495 yiaddr
="192.168.1.129", chaddr
=addr1
,
3497 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3498 raise Exception("DATA_TEST_FRAME failed")
3501 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3502 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3503 yiaddr
="192.168.1.129", chaddr
=addr1
,
3505 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3506 raise Exception("DATA_TEST_FRAME failed")
3508 macs
= get_bridge_macs("ap-br0")
3509 logger
.info("After connect (showmacs): " + str(macs
))
3511 matches
= get_permanent_neighbors("ap-br0")
3512 logger
.info("After connect: " + str(matches
))
3513 if len(matches
) != 4:
3514 raise Exception("Unexpected number of neighbor entries after connect")
3515 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3516 raise Exception("dev0 addr missing")
3517 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
3518 raise Exception("dev1 addr(1) missing")
3519 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
3520 raise Exception("dev1 addr(2) missing")
3521 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3522 raise Exception("dev0 IPv4 addr missing")
3524 targets
= [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
3526 for target
in targets
:
3527 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
3529 for target
in targets
:
3530 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
3533 for target
in targets
:
3534 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
=target
)
3536 # ARP Probe from wireless STA
3537 send_arp(dev
[1], target_ip
="192.168.1.127")
3538 # ARP Announcement from wireless STA
3539 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
3540 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
3543 macs
= get_bridge_macs("ap-br0")
3544 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
3546 matches
= get_permanent_neighbors("ap-br0")
3547 logger
.info("After ARP Probe + Announcement: " + str(matches
))
3549 # ARP Request for the newly introduced IP address from wireless STA
3550 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
3552 # ARP Request for the newly introduced IP address from bridge
3553 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
3554 target_ip
="192.168.1.127")
3555 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
="192.168.1.127")
3557 # ARP Probe from bridge
3558 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.130")
3559 send_arp(dev
[2], target_ip
="192.168.1.131")
3560 # ARP Announcement from bridge (not to be learned by AP for proxyarp)
3561 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
3562 target_ip
="192.168.1.130")
3563 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
3564 target_ip
="192.168.1.130", opcode
=2)
3565 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131")
3566 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131",
3569 macs
= get_bridge_macs("ap-br0")
3570 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
3572 matches
= get_permanent_neighbors("ap-br0")
3573 logger
.info("After ARP Probe + Announcement: " + str(matches
))
3575 # ARP Request for the newly introduced IP address from wireless STA
3576 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.130")
3577 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3578 send_arp(hapd
, hapd_bssid
=bssid
, dst_ll
=addr0
, sender_ip
="192.168.1.130",
3579 target_ip
="192.168.1.123", opcode
=2)
3581 # ARP Request for the newly introduced IP address from wireless STA
3582 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.131")
3583 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3584 send_arp(dev
[2], dst_ll
=addr0
, sender_ip
="192.168.1.131",
3585 target_ip
="192.168.1.123", opcode
=2)
3587 # ARP Request for the newly introduced IP address from bridge
3588 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
3589 target_ip
="192.168.1.130")
3590 send_arp(dev
[2], sender_ip
="192.168.1.104", target_ip
="192.168.1.131")
3592 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
3593 send_arp(dev
[1], target_ip
="192.168.1.123")
3594 # ARP Probe from wireless STA (duplicate address; learned through ARP)
3595 send_arp(dev
[0], target_ip
="192.168.1.127")
3597 # Gratuitous ARP Reply for another STA's IP address
3598 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
3599 target_mac
=addr1
, target_ip
="192.168.1.127")
3600 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
3601 target_mac
=addr0
, target_ip
="192.168.1.123")
3602 # ARP Request to verify previous mapping
3603 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
3604 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
3608 send_ns(dev
[0], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:cccc::2")
3610 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:dddd::2")
3612 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:dddd::2",
3613 ip_src
="aaaa:bbbb:ffff::2")
3615 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:ff00::2")
3617 send_ns(dev
[2], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:ff00::2")
3619 send_ns(dev
[2], target
="aaaa:bbbb:eeee::2", ip_src
="aaaa:bbbb:ff00::2")
3622 # Try to probe for an already assigned address
3623 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="::")
3625 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc::2", ip_src
="::")
3627 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="::")
3631 send_na(dev
[1], target
="aaaa:bbbb:cccc:aeae::3",
3632 ip_src
="aaaa:bbbb:cccc:aeae::3", ip_dst
="ff02::1")
3633 send_na(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc:aeae::4",
3634 ip_src
="aaaa:bbbb:cccc:aeae::4", ip_dst
="ff02::1")
3635 send_na(dev
[2], target
="aaaa:bbbb:cccc:aeae::5",
3636 ip_src
="aaaa:bbbb:cccc:aeae::5", ip_dst
="ff02::1")
3639 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
3640 except Exception, e
:
3641 logger
.info("test_connectibity_iface failed: " + str(e
))
3642 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
3643 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
3644 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
3646 dev
[0].request("DISCONNECT")
3647 dev
[1].request("DISCONNECT")
3649 for i
in range(len(cmd
)):
3651 macs
= get_bridge_macs("ap-br0")
3652 logger
.info("After disconnect (showmacs): " + str(macs
))
3653 matches
= get_permanent_neighbors("ap-br0")
3654 logger
.info("After disconnect: " + str(matches
))
3655 if len(matches
) > 0:
3656 raise Exception("Unexpected neighbor entries after disconnect")
3658 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
3659 stdout
=subprocess
.PIPE
)
3660 res
= cmd
.stdout
.read()
3662 logger
.info("ebtables results:\n" + res
)
3664 # Verify that expected ARP messages were seen and no unexpected
3665 # ARP messages were seen.
3667 arp_req
= tshark_get_arp(cap_dev0
, "arp.opcode == 1")
3668 arp_reply
= tshark_get_arp(cap_dev0
, "arp.opcode == 2")
3669 logger
.info("dev0 seen ARP requests:\n" + str(arp_req
))
3670 logger
.info("dev0 seen ARP replies:\n" + str(arp_reply
))
3672 if [ 'ff:ff:ff:ff:ff:ff', addr1
,
3673 addr1
, '192.168.1.100',
3674 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3675 raise Exception("dev0 saw ARP request from dev1")
3676 if [ 'ff:ff:ff:ff:ff:ff', addr2
,
3677 addr2
, '192.168.1.103',
3678 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3679 raise Exception("dev0 saw ARP request from dev2")
3680 # TODO: Uncomment once fixed in kernel
3681 #if [ 'ff:ff:ff:ff:ff:ff', bssid,
3682 # bssid, '192.168.1.101',
3683 # '00:00:00:00:00:00', '192.168.1.123' ] in arp_req:
3684 # raise Exception("dev0 saw ARP request from br")
3689 raise Exception("Unexpected foreign ARP request on dev0")
3691 arp_req
= tshark_get_arp(cap_dev1
, "arp.opcode == 1")
3692 arp_reply
= tshark_get_arp(cap_dev1
, "arp.opcode == 2")
3693 logger
.info("dev1 seen ARP requests:\n" + str(arp_req
))
3694 logger
.info("dev1 seen ARP replies:\n" + str(arp_reply
))
3696 if [ 'ff:ff:ff:ff:ff:ff', addr2
,
3697 addr2
, '192.168.1.103',
3698 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3699 raise Exception("dev1 saw ARP request from dev2")
3700 if [addr1
, addr0
, addr0
, '192.168.1.123', addr1
, '192.168.1.100'] not in arp_reply
:
3701 raise Exception("dev1 did not get ARP response for 192.168.1.123")
3706 raise Exception("Unexpected foreign ARP request on dev1")
3708 arp_req
= tshark_get_arp(cap_dev2
, "arp.opcode == 1")
3709 arp_reply
= tshark_get_arp(cap_dev2
, "arp.opcode == 2")
3710 logger
.info("dev2 seen ARP requests:\n" + str(arp_req
))
3711 logger
.info("dev2 seen ARP replies:\n" + str(arp_reply
))
3714 addr0
, '192.168.1.123',
3715 addr2
, '192.168.1.103' ] not in arp_reply
:
3716 raise Exception("dev2 did not get ARP response for 192.168.1.123")
3718 arp_req
= tshark_get_arp(cap_br
, "arp.opcode == 1")
3719 arp_reply
= tshark_get_arp(cap_br
, "arp.opcode == 2")
3720 logger
.info("br seen ARP requests:\n" + str(arp_req
))
3721 logger
.info("br seen ARP replies:\n" + str(arp_reply
))
3723 # TODO: Uncomment once fixed in kernel
3725 # addr0, '192.168.1.123',
3726 # bssid, '192.168.1.101' ] not in arp_reply:
3727 # raise Exception("br did not get ARP response for 192.168.1.123")
3729 ns
= tshark_get_ns(cap_dev0
)
3730 logger
.info("dev0 seen NS: " + str(ns
))
3731 na
= tshark_get_na(cap_dev0
)
3732 logger
.info("dev0 seen NA: " + str(na
))
3734 if [ addr0
, addr1
, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2',
3735 'aaaa:bbbb:dddd::2', addr1
] not in na
:
3736 raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
3741 raise Exception("Unexpected foreign NS on dev0: " + str(req
))
3743 ns
= tshark_get_ns(cap_dev1
)
3744 logger
.info("dev1 seen NS: " + str(ns
))
3745 na
= tshark_get_na(cap_dev1
)
3746 logger
.info("dev1 seen NA: " + str(na
))
3748 if [ addr1
, addr0
, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:dddd::2',
3749 'aaaa:bbbb:cccc::2', addr0
] not in na
:
3750 raise Exception("dev1 did not get NA for aaaa:bbbb:cccc::2")
3755 raise Exception("Unexpected foreign NS on dev1: " + str(req
))
3757 ns
= tshark_get_ns(cap_dev2
)
3758 logger
.info("dev2 seen NS: " + str(ns
))
3759 na
= tshark_get_na(cap_dev2
)
3760 logger
.info("dev2 seen NA: " + str(na
))
3762 # FIX: enable once kernel implementation for proxyarp IPv6 is fixed
3763 #if [ addr2, addr0, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:ff00::2',
3764 # 'aaaa:bbbb:cccc::2', addr0 ] not in na:
3765 # raise Exception("dev2 did not get NA for aaaa:bbbb:cccc::2")
3766 #if [ addr2, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:ff00::2',
3767 # 'aaaa:bbbb:dddd::2', addr1 ] not in na:
3768 # raise Exception("dev2 did not get NA for aaaa:bbbb:dddd::2")
3769 #if [ addr2, addr1, 'aaaa:bbbb:eeee::2', 'aaaa:bbbb:ff00::2',
3770 # 'aaaa:bbbb:eeee::2', addr1 ] not in na:
3771 # raise Exception("dev2 did not get NA for aaaa:bbbb:eeee::2")
3773 def test_proxyarp_open(dev
, apdev
, params
):
3774 """ProxyARP with open network"""
3776 _test_proxyarp_open(dev
, apdev
, params
)
3778 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3779 stderr
=open('/dev/null', 'w'))
3780 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3781 stderr
=open('/dev/null', 'w'))
3783 def test_proxyarp_open_ebtables(dev
, apdev
, params
):
3784 """ProxyARP with open network"""
3786 _test_proxyarp_open(dev
, apdev
, params
, ebtables
=True)
3789 subprocess
.call(['ebtables', '-F', 'FORWARD'])
3790 subprocess
.call(['ebtables', '-F', 'OUTPUT'])
3793 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3794 stderr
=open('/dev/null', 'w'))
3795 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3796 stderr
=open('/dev/null', 'w'))
3798 def test_ap_hs20_connect_deinit(dev
, apdev
):
3799 """Hotspot 2.0 connection interrupted with deinit"""
3800 check_eap_capa(dev
[0], "MSCHAPV2")
3801 bssid
= apdev
[0]['bssid']
3802 params
= hs20_ap_params()
3803 params
['hessid'] = bssid
3804 hapd
= hostapd
.add_ap(apdev
[0], params
)
3806 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
3807 wpas
.interface_add("wlan5", drv_params
="")
3809 wpas
.flush_scan_cache()
3810 wpas
.add_cred_values({ 'realm': "example.com",
3811 'username': "hs20-test",
3812 'password': "password",
3813 'ca_cert': "auth_serv/ca.pem",
3814 'domain': "example.com" })
3816 wpas
.scan_for_bss(bssid
, freq
=2412)
3819 wpas
.request("INTERWORKING_SELECT freq=2412")
3821 id = wpas
.request("RADIO_WORK add block-work")
3822 ev
= wpas
.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout
=5)
3824 raise Exception("Timeout while waiting radio work to start")
3825 ev
= wpas
.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout
=5)
3827 raise Exception("Timeout while waiting radio work to start (2)")
3829 # Remove the interface while the gas-query radio work is still pending and
3830 # GAS query has not yet been started.
3831 wpas
.interface_remove("wlan5")
3833 def test_ap_hs20_anqp_format_errors(dev
, apdev
):
3834 """Interworking network selection and ANQP format errors"""
3835 bssid
= apdev
[0]['bssid']
3836 params
= hs20_ap_params()
3837 params
['hessid'] = bssid
3838 hapd
= hostapd
.add_ap(apdev
[0], params
)
3840 dev
[0].hs20_enable()
3841 values
= { 'realm': "example.com",
3842 'ca_cert': "auth_serv/ca.pem",
3843 'username': "hs20-test",
3844 'password': "password",
3845 'domain': "example.com" }
3846 id = dev
[0].add_cred_values(values
)
3848 dev
[0].scan_for_bss(bssid
, freq
="2412")
3850 tests
= [ "00", "ffff", "010011223344", "020008000005112233445500",
3851 "01000400000000", "01000000000000",
3852 "01000300000200", "0100040000ff0000", "01000300000100",
3854 "01000600000056112233",
3855 "01000900000002050001000111",
3856 "01000600000001000000", "01000600000001ff0000",
3857 "01000600000001020001",
3858 "010008000000010400010001", "0100080000000104000100ff",
3859 "010011000000010d00050200020100030005000600",
3862 hapd
.set("anqp_elem", "263:" + t
)
3863 dev
[0].request("INTERWORKING_SELECT freq=2412")
3864 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=5)
3866 raise Exception("Network selection timed out")
3867 dev
[0].dump_monitor()
3869 dev
[0].remove_cred(id)
3870 id = dev
[0].add_cred_values({ 'imsi': "555444-333222111", 'eap': "AKA",
3871 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
3873 tests
= [ "00", "0100", "0001", "00ff", "000200ff", "0003000101",
3876 hapd
.set("anqp_elem", "264:" + t
)
3877 dev
[0].request("INTERWORKING_SELECT freq=2412")
3878 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=5)
3880 raise Exception("Network selection timed out")
3881 dev
[0].dump_monitor()