]>
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
, alloc_fail
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_anqp_sharing_oom(dev
, apdev
):
216 """ANQP sharing within ESS and explicit unshare OOM"""
217 check_eap_capa(dev
[0], "MSCHAPV2")
218 dev
[0].flush_scan_cache()
220 bssid
= apdev
[0]['bssid']
221 params
= hs20_ap_params()
222 params
['hessid'] = bssid
223 hostapd
.add_ap(apdev
[0], params
)
225 bssid2
= apdev
[1]['bssid']
226 params
= hs20_ap_params()
227 params
['hessid'] = bssid
228 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
229 hostapd
.add_ap(apdev
[1], params
)
232 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
233 'password': "secret",
234 'domain': "example.com" })
235 dev
[0].scan_for_bss(bssid
, freq
="2412")
236 dev
[0].scan_for_bss(bssid2
, freq
="2412")
237 interworking_select(dev
[0], None, "home", freq
="2412")
238 dev
[0].dump_monitor()
240 with
alloc_fail(dev
[0], 1, "wpa_bss_anqp_clone"):
241 dev
[0].request("ANQP_GET " + bssid
+ " 263")
242 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
244 raise Exception("ANQP operation timed out")
246 def test_ap_nai_home_realm_query(dev
, apdev
):
247 """NAI Home Realm Query"""
248 check_eap_capa(dev
[0], "MSCHAPV2")
249 bssid
= apdev
[0]['bssid']
250 params
= hs20_ap_params()
251 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
252 "0,another.example.org" ]
253 hostapd
.add_ap(apdev
[0], params
)
255 dev
[0].scan(freq
="2412")
256 dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " realm=example.com")
257 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
259 raise Exception("ANQP operation timed out")
260 nai1
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
261 dev
[0].dump_monitor()
263 dev
[0].request("ANQP_GET " + bssid
+ " 263")
264 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
266 raise Exception("ANQP operation timed out")
267 nai2
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
269 if len(nai1
) >= len(nai2
):
270 raise Exception("Unexpected NAI Realm list response lengths")
271 if "example.com".encode('hex') not in nai1
:
272 raise Exception("Home realm not reported")
273 if "example.org".encode('hex') in nai1
:
274 raise Exception("Non-home realm reported")
275 if "example.com".encode('hex') not in nai2
:
276 raise Exception("Home realm not reported in wildcard query")
277 if "example.org".encode('hex') not in nai2
:
278 raise Exception("Non-home realm not reported in wildcard query ")
281 "00:11:22:33:44:55 123",
282 "00:11:22:33:44:55 qq" ]
284 if "FAIL" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd
):
285 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd
)
287 dev
[0].dump_monitor()
288 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
289 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
290 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
292 raise Exception("ANQP operation timed out")
293 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=0.1)
295 raise Exception("Unexpected ANQP response: " + ev
)
297 dev
[0].dump_monitor()
298 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " 01000b6578616d706c652e636f6d"):
299 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
300 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
302 raise Exception("No ANQP response")
303 if "NAI Realm list" not in ev
:
304 raise Exception("Missing NAI Realm list: " + ev
)
306 dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
307 'password': "secret",
308 'domain': "example.com" })
309 dev
[0].dump_monitor()
310 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
311 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
312 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
314 raise Exception("No ANQP response")
315 if "NAI Realm list" not in ev
:
316 raise Exception("Missing NAI Realm list: " + ev
)
318 def test_ap_interworking_scan_filtering(dev
, apdev
):
319 """Interworking scan filtering with HESSID and access network type"""
321 _test_ap_interworking_scan_filtering(dev
, apdev
)
323 dev
[0].request("SET hessid 00:00:00:00:00:00")
324 dev
[0].request("SET access_network_type 15")
326 def _test_ap_interworking_scan_filtering(dev
, apdev
):
327 bssid
= apdev
[0]['bssid']
328 params
= hs20_ap_params()
329 ssid
= "test-hs20-ap1"
330 params
['ssid'] = ssid
331 params
['hessid'] = bssid
332 hapd0
= hostapd
.add_ap(apdev
[0], params
)
334 bssid2
= apdev
[1]['bssid']
335 params
= hs20_ap_params()
336 ssid2
= "test-hs20-ap2"
337 params
['ssid'] = ssid2
338 params
['hessid'] = bssid2
339 params
['access_network_type'] = "1"
340 del params
['venue_group']
341 del params
['venue_type']
342 hostapd
.add_ap(apdev
[1], params
)
346 Wlantest
.setup(hapd0
)
350 logger
.info("Check probe request filtering based on HESSID")
352 dev
[0].request("SET hessid " + bssid2
)
353 dev
[0].scan(freq
="2412")
355 check_probe_resp(wt
, bssid
, bssid2
)
357 logger
.info("Check probe request filtering based on access network type")
359 wt
.clear_bss_counters(bssid
)
360 wt
.clear_bss_counters(bssid2
)
361 dev
[0].request("SET hessid 00:00:00:00:00:00")
362 dev
[0].request("SET access_network_type 14")
363 dev
[0].scan(freq
="2412")
365 check_probe_resp(wt
, bssid2
, bssid
)
367 wt
.clear_bss_counters(bssid
)
368 wt
.clear_bss_counters(bssid2
)
369 dev
[0].request("SET hessid 00:00:00:00:00:00")
370 dev
[0].request("SET access_network_type 1")
371 dev
[0].scan(freq
="2412")
373 check_probe_resp(wt
, bssid
, bssid2
)
375 logger
.info("Check probe request filtering based on HESSID and ANT")
377 wt
.clear_bss_counters(bssid
)
378 wt
.clear_bss_counters(bssid2
)
379 dev
[0].request("SET hessid " + bssid
)
380 dev
[0].request("SET access_network_type 14")
381 dev
[0].scan(freq
="2412")
383 check_probe_resp(wt
, bssid2
, bssid
)
385 wt
.clear_bss_counters(bssid
)
386 wt
.clear_bss_counters(bssid2
)
387 dev
[0].request("SET hessid " + bssid2
)
388 dev
[0].request("SET access_network_type 14")
389 dev
[0].scan(freq
="2412")
391 check_probe_resp(wt
, bssid
, None)
392 check_probe_resp(wt
, bssid2
, None)
394 wt
.clear_bss_counters(bssid
)
395 wt
.clear_bss_counters(bssid2
)
396 dev
[0].request("SET hessid " + bssid
)
397 dev
[0].request("SET access_network_type 1")
398 dev
[0].scan(freq
="2412")
400 check_probe_resp(wt
, bssid
, None)
401 check_probe_resp(wt
, bssid2
, None)
403 def test_ap_hs20_select(dev
, apdev
):
404 """Hotspot 2.0 network selection"""
405 bssid
= apdev
[0]['bssid']
406 params
= hs20_ap_params()
407 params
['hessid'] = bssid
408 hostapd
.add_ap(apdev
[0], params
)
411 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
412 'password': "secret",
413 'domain': "example.com" })
414 interworking_select(dev
[0], bssid
, "home")
416 dev
[0].remove_cred(id)
417 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
418 'password': "secret",
419 'domain': "no.match.example.com" })
420 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
422 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com");
423 interworking_select(dev
[0], bssid
, no_match
=True, freq
="2412")
425 res
= dev
[0].request("SCAN_RESULTS")
426 if "[HS20]" not in res
:
427 raise Exception("HS20 flag missing from scan results: " + res
)
429 bssid2
= apdev
[1]['bssid']
430 params
= hs20_ap_params()
431 params
['nai_realm'] = [ "0,example.org,21" ]
432 params
['hessid'] = bssid2
433 params
['domain_name'] = "example.org"
434 hostapd
.add_ap(apdev
[1], params
)
435 dev
[0].remove_cred(id)
436 id = dev
[0].add_cred_values({ 'realm': "example.org", 'username': "test",
437 'password': "secret",
438 'domain': "example.org" })
439 interworking_select(dev
[0], bssid2
, "home", freq
="2412")
441 def hs20_simulated_sim(dev
, ap
, method
):
443 params
= hs20_ap_params()
444 params
['hessid'] = bssid
445 params
['anqp_3gpp_cell_net'] = "555,444"
446 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
447 hostapd
.add_ap(ap
, params
)
450 dev
.add_cred_values({ 'imsi': "555444-333222111", 'eap': method
,
451 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
452 interworking_select(dev
, "home", freq
="2412")
453 interworking_connect(dev
, bssid
, method
)
454 check_sp_type(dev
, "home")
456 def test_ap_hs20_sim(dev
, apdev
):
457 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
458 hlr_auc_gw_available()
459 hs20_simulated_sim(dev
[0], apdev
[0], "SIM")
460 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
461 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
463 raise Exception("Timeout on already-connected event")
465 def test_ap_hs20_aka(dev
, apdev
):
466 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
467 hlr_auc_gw_available()
468 hs20_simulated_sim(dev
[0], apdev
[0], "AKA")
470 def test_ap_hs20_aka_prime(dev
, apdev
):
471 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
472 hlr_auc_gw_available()
473 hs20_simulated_sim(dev
[0], apdev
[0], "AKA'")
475 def test_ap_hs20_ext_sim(dev
, apdev
):
476 """Hotspot 2.0 with external SIM processing"""
477 hlr_auc_gw_available()
478 bssid
= apdev
[0]['bssid']
479 params
= hs20_ap_params()
480 params
['hessid'] = bssid
481 params
['anqp_3gpp_cell_net'] = "232,01"
482 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
483 hostapd
.add_ap(apdev
[0], params
)
487 dev
[0].request("SET external_sim 1")
488 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
489 interworking_select(dev
[0], "home", freq
="2412")
490 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
491 check_sp_type(dev
[0], "home")
493 dev
[0].request("SET external_sim 0")
495 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
496 """Hotspot 2.0 with external SIM processing in roaming network"""
497 hlr_auc_gw_available()
498 bssid
= apdev
[0]['bssid']
499 params
= hs20_ap_params()
500 params
['hessid'] = bssid
501 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
502 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
503 hostapd
.add_ap(apdev
[0], params
)
507 dev
[0].request("SET external_sim 1")
508 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
509 interworking_select(dev
[0], "roaming", freq
="2412")
510 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
511 check_sp_type(dev
[0], "roaming")
513 dev
[0].request("SET external_sim 0")
515 def test_ap_hs20_username(dev
, apdev
):
516 """Hotspot 2.0 connection in username/password credential"""
517 check_eap_capa(dev
[0], "MSCHAPV2")
518 bssid
= apdev
[0]['bssid']
519 params
= hs20_ap_params()
520 params
['hessid'] = bssid
521 params
['disable_dgaf'] = '1'
522 hostapd
.add_ap(apdev
[0], params
)
525 id = dev
[0].add_cred_values({ 'realm': "example.com",
526 'username': "hs20-test",
527 'password': "password",
528 'ca_cert': "auth_serv/ca.pem",
529 'domain': "example.com",
530 'update_identifier': "1234" })
531 interworking_select(dev
[0], bssid
, "home", freq
="2412")
532 interworking_connect(dev
[0], bssid
, "TTLS")
533 check_sp_type(dev
[0], "home")
534 status
= dev
[0].get_status()
535 if status
['pairwise_cipher'] != "CCMP":
536 raise Exception("Unexpected pairwise cipher")
537 if status
['hs20'] != "2":
538 raise Exception("Unexpected HS 2.0 support indication")
540 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
541 identity
="hs20-test", password
="password",
542 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
545 def test_ap_hs20_connect_api(dev
, apdev
):
546 """Hotspot 2.0 connection with connect API"""
547 check_eap_capa(dev
[0], "MSCHAPV2")
548 bssid
= apdev
[0]['bssid']
549 params
= hs20_ap_params()
550 params
['hessid'] = bssid
551 params
['disable_dgaf'] = '1'
552 hostapd
.add_ap(apdev
[0], params
)
554 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
555 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
557 wpas
.flush_scan_cache()
558 id = wpas
.add_cred_values({ 'realm': "example.com",
559 'username': "hs20-test",
560 'password': "password",
561 'ca_cert': "auth_serv/ca.pem",
562 'domain': "example.com",
563 'update_identifier': "1234" })
564 interworking_select(wpas
, bssid
, "home", freq
="2412")
565 interworking_connect(wpas
, bssid
, "TTLS")
566 check_sp_type(wpas
, "home")
567 status
= wpas
.get_status()
568 if status
['pairwise_cipher'] != "CCMP":
569 raise Exception("Unexpected pairwise cipher")
570 if status
['hs20'] != "2":
571 raise Exception("Unexpected HS 2.0 support indication")
573 def test_ap_hs20_auto_interworking(dev
, apdev
):
574 """Hotspot 2.0 connection with auto_interworking=1"""
575 check_eap_capa(dev
[0], "MSCHAPV2")
576 bssid
= apdev
[0]['bssid']
577 params
= hs20_ap_params()
578 params
['hessid'] = bssid
579 params
['disable_dgaf'] = '1'
580 hostapd
.add_ap(apdev
[0], params
)
582 dev
[0].hs20_enable(auto_interworking
=True)
583 id = dev
[0].add_cred_values({ 'realm': "example.com",
584 'username': "hs20-test",
585 'password': "password",
586 'ca_cert': "auth_serv/ca.pem",
587 'domain': "example.com",
588 'update_identifier': "1234" })
589 dev
[0].request("REASSOCIATE")
590 dev
[0].wait_connected(timeout
=15)
591 check_sp_type(dev
[0], "home")
592 status
= dev
[0].get_status()
593 if status
['pairwise_cipher'] != "CCMP":
594 raise Exception("Unexpected pairwise cipher")
595 if status
['hs20'] != "2":
596 raise Exception("Unexpected HS 2.0 support indication")
598 def test_ap_hs20_auto_interworking_no_match(dev
, apdev
):
599 """Hotspot 2.0 connection with auto_interworking=1 and no matching network"""
600 hapd
= hostapd
.add_ap(apdev
[0], { "ssid": "mismatch" })
602 dev
[0].hs20_enable(auto_interworking
=True)
603 id = dev
[0].connect("mismatch", psk
="12345678", scan_freq
="2412",
604 only_add_network
=True)
605 dev
[0].request("ENABLE_NETWORK " + str(id) + " no-connect")
607 id = dev
[0].add_cred_values({ 'realm': "example.com",
608 'username': "hs20-test",
609 'password': "password",
610 'ca_cert': "auth_serv/ca.pem",
611 'domain': "example.com",
612 'update_identifier': "1234" })
613 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
615 dev
[0].dump_monitor()
617 logger
.info("start ping")
618 if "PONG" not in dev
[0].ctrl
.request("PING", timeout
=2):
619 raise Exception("PING failed")
620 logger
.info("ping done")
624 ev
= dev
[0].wait_event([ "ANQP fetch completed",
625 "CTRL-EVENT-SCAN-RESULTS" ], timeout
=0.05)
628 if "ANQP fetch completed" in ev
:
632 if fetch
> 2 * scan
+ 3:
633 raise Exception("Too many ANQP fetch iterations")
634 dev
[0].dump_monitor()
635 dev
[0].request("DISCONNECT")
637 def test_ap_hs20_auto_interworking_no_cred_match(dev
, apdev
):
638 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
639 bssid
= apdev
[0]['bssid']
640 params
= { "ssid": "test" }
641 hostapd
.add_ap(apdev
[0], params
)
643 dev
[0].hs20_enable(auto_interworking
=True)
644 dev
[0].add_cred_values({ 'realm': "example.com",
645 'username': "hs20-test",
646 'password': "password",
647 'ca_cert': "auth_serv/ca.pem",
648 'domain': "example.com" })
650 id = dev
[0].connect("test", psk
="12345678", only_add_network
=True)
651 dev
[0].request("ENABLE_NETWORK %s" % id)
652 logger
.info("Verify that scanning continues when there is partial network block match")
653 for i
in range(0, 2):
654 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
656 raise Exception("Scan timed out")
657 logger
.info("Scan completed")
659 def eap_test(dev
, ap
, eap_params
, method
, user
):
661 params
= hs20_ap_params()
662 params
['nai_realm'] = [ "0,example.com," + eap_params
]
663 hostapd
.add_ap(ap
, params
)
666 dev
.add_cred_values({ 'realm': "example.com",
667 'ca_cert': "auth_serv/ca.pem",
669 'password': "password" })
670 interworking_select(dev
, bssid
, freq
="2412")
671 interworking_connect(dev
, bssid
, method
)
673 def test_ap_hs20_eap_unknown(dev
, apdev
):
674 """Hotspot 2.0 connection with unknown EAP method"""
675 bssid
= apdev
[0]['bssid']
676 params
= hs20_ap_params()
677 params
['nai_realm'] = "0,example.com,99"
678 hostapd
.add_ap(apdev
[0], params
)
681 dev
[0].add_cred_values(default_cred())
682 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
684 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
685 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
686 check_eap_capa(dev
[0], "MSCHAPV2")
687 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
689 def test_ap_hs20_eap_peap_default(dev
, apdev
):
690 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
691 check_eap_capa(dev
[0], "MSCHAPV2")
692 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
694 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
695 """Hotspot 2.0 connection with PEAP/GTC"""
696 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
698 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
699 """Hotspot 2.0 connection with PEAP/unknown"""
700 bssid
= apdev
[0]['bssid']
701 params
= hs20_ap_params()
702 params
['nai_realm'] = "0,example.com,25[3:99]"
703 hostapd
.add_ap(apdev
[0], params
)
706 dev
[0].add_cred_values(default_cred())
707 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
709 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
710 """Hotspot 2.0 connection with TTLS/CHAP"""
711 skip_with_fips(dev
[0])
712 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
714 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
715 """Hotspot 2.0 connection with TTLS/MSCHAP"""
716 skip_with_fips(dev
[0])
717 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
719 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
720 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
721 check_eap_capa(dev
[0], "MSCHAPV2")
722 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
724 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
725 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
726 bssid
= apdev
[0]['bssid']
727 params
= hs20_ap_params()
728 params
['nai_realm'] = "0,example.com,21[3:99]"
729 hostapd
.add_ap(apdev
[0], params
)
732 dev
[0].add_cred_values(default_cred())
733 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
735 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
736 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
737 bssid
= apdev
[0]['bssid']
738 params
= hs20_ap_params()
739 params
['nai_realm'] = "0,example.com,21[3:5]"
740 hostapd
.add_ap(apdev
[0], params
)
743 dev
[0].add_cred_values(default_cred())
744 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
746 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
747 """Hotspot 2.0 connection with TTLS/unknown"""
748 bssid
= apdev
[0]['bssid']
749 params
= hs20_ap_params()
750 params
['nai_realm'] = "0,example.com,21[2:5]"
751 hostapd
.add_ap(apdev
[0], params
)
754 dev
[0].add_cred_values(default_cred())
755 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
757 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
758 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
759 check_eap_capa(dev
[0], "FAST")
760 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
762 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
763 """Hotspot 2.0 connection with FAST/EAP-GTC"""
764 check_eap_capa(dev
[0], "FAST")
765 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
767 def test_ap_hs20_eap_tls(dev
, apdev
):
768 """Hotspot 2.0 connection with EAP-TLS"""
769 bssid
= apdev
[0]['bssid']
770 params
= hs20_ap_params()
771 params
['nai_realm'] = [ "0,example.com,13[5:6]" ]
772 hostapd
.add_ap(apdev
[0], params
)
775 dev
[0].add_cred_values({ 'realm': "example.com",
776 'username': "certificate-user",
777 'ca_cert': "auth_serv/ca.pem",
778 'client_cert': "auth_serv/user.pem",
779 'private_key': "auth_serv/user.key"})
780 interworking_select(dev
[0], bssid
, freq
="2412")
781 interworking_connect(dev
[0], bssid
, "TLS")
783 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
784 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
785 bssid
= apdev
[0]['bssid']
786 params
= hs20_ap_params()
787 params
['nai_realm'] = [ "0,example.com,99[5:6]" ]
788 hostapd
.add_ap(apdev
[0], params
)
791 dev
[0].add_cred_values({ 'realm': "example.com",
792 'username': "certificate-user",
793 'ca_cert': "auth_serv/ca.pem",
794 'client_cert': "auth_serv/user.pem",
795 'private_key': "auth_serv/user.key"})
796 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
798 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
799 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
800 bssid
= apdev
[0]['bssid']
801 params
= hs20_ap_params()
802 params
['nai_realm'] = [ "0,example.com,21[5:6]" ]
803 hostapd
.add_ap(apdev
[0], params
)
806 dev
[0].add_cred_values({ 'realm': "example.com",
807 'username': "certificate-user",
808 'ca_cert': "auth_serv/ca.pem",
809 'client_cert': "auth_serv/user.pem",
810 'private_key': "auth_serv/user.key"})
811 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
813 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
814 """Hotspot 2.0 connection with invalid cred configuration"""
815 bssid
= apdev
[0]['bssid']
816 params
= hs20_ap_params()
817 hostapd
.add_ap(apdev
[0], params
)
820 dev
[0].add_cred_values({ 'realm': "example.com",
821 'username': "certificate-user",
822 'client_cert': "auth_serv/user.pem" })
823 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
825 def test_ap_hs20_nai_realms(dev
, apdev
):
826 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
827 bssid
= apdev
[0]['bssid']
828 params
= hs20_ap_params()
829 params
['hessid'] = bssid
830 params
['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
831 hostapd
.add_ap(apdev
[0], params
)
834 id = dev
[0].add_cred_values({ 'realm': "example.com",
835 'ca_cert': "auth_serv/ca.pem",
836 'username': "pap user",
837 'password': "password",
838 'domain': "example.com" })
839 interworking_select(dev
[0], bssid
, "home", freq
="2412")
840 interworking_connect(dev
[0], bssid
, "TTLS")
841 check_sp_type(dev
[0], "home")
843 def test_ap_hs20_roaming_consortium(dev
, apdev
):
844 """Hotspot 2.0 connection based on roaming consortium match"""
845 bssid
= apdev
[0]['bssid']
846 params
= hs20_ap_params()
847 params
['hessid'] = bssid
848 hostapd
.add_ap(apdev
[0], params
)
851 for consortium
in [ "112233", "1020304050", "010203040506", "fedcba" ]:
852 id = dev
[0].add_cred_values({ 'username': "user",
853 'password': "password",
854 'domain': "example.com",
855 'ca_cert': "auth_serv/ca.pem",
856 'roaming_consortium': consortium
,
858 interworking_select(dev
[0], bssid
, "home", freq
="2412")
859 interworking_connect(dev
[0], bssid
, "PEAP")
860 check_sp_type(dev
[0], "home")
861 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
862 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
864 raise Exception("Timeout on already-connected event")
865 dev
[0].remove_cred(id)
867 def test_ap_hs20_username_roaming(dev
, apdev
):
868 """Hotspot 2.0 connection in username/password credential (roaming)"""
869 check_eap_capa(dev
[0], "MSCHAPV2")
870 bssid
= apdev
[0]['bssid']
871 params
= hs20_ap_params()
872 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
873 "0,roaming.example.com,21[2:4][5:7]",
874 "0,another.example.com" ]
875 params
['domain_name'] = "another.example.com"
876 params
['hessid'] = bssid
877 hostapd
.add_ap(apdev
[0], params
)
880 id = dev
[0].add_cred_values({ 'realm': "roaming.example.com",
881 'username': "hs20-test",
882 'password': "password",
883 'ca_cert': "auth_serv/ca.pem",
884 'domain': "example.com" })
885 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
886 interworking_connect(dev
[0], bssid
, "TTLS")
887 check_sp_type(dev
[0], "roaming")
889 def test_ap_hs20_username_unknown(dev
, apdev
):
890 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
891 check_eap_capa(dev
[0], "MSCHAPV2")
892 bssid
= apdev
[0]['bssid']
893 params
= hs20_ap_params()
894 params
['hessid'] = bssid
895 hostapd
.add_ap(apdev
[0], params
)
898 id = dev
[0].add_cred_values({ 'realm': "example.com",
899 'ca_cert': "auth_serv/ca.pem",
900 'username': "hs20-test",
901 'password': "password" })
902 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
903 interworking_connect(dev
[0], bssid
, "TTLS")
904 check_sp_type(dev
[0], "unknown")
906 def test_ap_hs20_username_unknown2(dev
, apdev
):
907 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
908 check_eap_capa(dev
[0], "MSCHAPV2")
909 bssid
= apdev
[0]['bssid']
910 params
= hs20_ap_params()
911 params
['hessid'] = bssid
912 del params
['domain_name']
913 hostapd
.add_ap(apdev
[0], params
)
916 id = dev
[0].add_cred_values({ 'realm': "example.com",
917 'ca_cert': "auth_serv/ca.pem",
918 'username': "hs20-test",
919 'password': "password",
920 'domain': "example.com" })
921 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
922 interworking_connect(dev
[0], bssid
, "TTLS")
923 check_sp_type(dev
[0], "unknown")
925 def test_ap_hs20_gas_while_associated(dev
, apdev
):
926 """Hotspot 2.0 connection with GAS query while associated"""
927 check_eap_capa(dev
[0], "MSCHAPV2")
928 bssid
= apdev
[0]['bssid']
929 params
= hs20_ap_params()
930 params
['hessid'] = bssid
931 hostapd
.add_ap(apdev
[0], params
)
934 id = dev
[0].add_cred_values({ 'realm': "example.com",
935 'ca_cert': "auth_serv/ca.pem",
936 'username': "hs20-test",
937 'password': "password",
938 'domain': "example.com" })
939 interworking_select(dev
[0], bssid
, "home", freq
="2412")
940 interworking_connect(dev
[0], bssid
, "TTLS")
942 logger
.info("Verifying GAS query while associated")
943 dev
[0].request("FETCH_ANQP")
944 for i
in range(0, 6):
945 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
947 raise Exception("Operation timed out")
949 def test_ap_hs20_gas_with_another_ap_while_associated(dev
, apdev
):
950 """GAS query with another AP while associated"""
951 check_eap_capa(dev
[0], "MSCHAPV2")
952 bssid
= apdev
[0]['bssid']
953 params
= hs20_ap_params()
954 params
['hessid'] = bssid
955 hostapd
.add_ap(apdev
[0], params
)
957 bssid2
= apdev
[1]['bssid']
958 params
= hs20_ap_params()
959 params
['hessid'] = bssid2
960 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
961 hostapd
.add_ap(apdev
[1], params
)
964 id = dev
[0].add_cred_values({ 'realm': "example.com",
965 'ca_cert': "auth_serv/ca.pem",
966 'username': "hs20-test",
967 'password': "password",
968 'domain': "example.com" })
969 interworking_select(dev
[0], bssid
, "home", freq
="2412")
970 interworking_connect(dev
[0], bssid
, "TTLS")
971 dev
[0].dump_monitor()
973 logger
.info("Verifying GAS query with same AP while associated")
974 dev
[0].request("ANQP_GET " + bssid
+ " 263")
975 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
977 raise Exception("ANQP operation timed out")
978 dev
[0].dump_monitor()
980 logger
.info("Verifying GAS query with another AP while associated")
981 dev
[0].scan_for_bss(bssid2
, 2412)
982 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
983 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
985 raise Exception("ANQP operation timed out")
987 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
988 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
989 check_eap_capa(dev
[0], "MSCHAPV2")
991 _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
)
993 dev
[0].request("SET pmf 0")
995 def _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
996 bssid
= apdev
[0]['bssid']
997 params
= hs20_ap_params()
998 params
['hessid'] = bssid
999 hostapd
.add_ap(apdev
[0], params
)
1001 bssid2
= apdev
[1]['bssid']
1002 params
= hs20_ap_params()
1003 params
['hessid'] = bssid2
1004 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
1005 hostapd
.add_ap(apdev
[1], params
)
1007 dev
[0].hs20_enable()
1008 dev
[0].request("SET pmf 2")
1009 id = dev
[0].add_cred_values({ 'realm': "example.com",
1010 'ca_cert': "auth_serv/ca.pem",
1011 'username': "hs20-test",
1012 'password': "password",
1013 'domain': "example.com" })
1014 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1015 interworking_connect(dev
[0], bssid
, "TTLS")
1017 logger
.info("Verifying GAS query while associated")
1018 dev
[0].request("FETCH_ANQP")
1019 for i
in range(0, 2 * 6):
1020 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1022 raise Exception("Operation timed out")
1024 def test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1025 """GAS query with another AP while associated and using PMF"""
1026 check_eap_capa(dev
[0], "MSCHAPV2")
1028 _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
)
1030 dev
[0].request("SET pmf 0")
1032 def _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1033 bssid
= apdev
[0]['bssid']
1034 params
= hs20_ap_params()
1035 params
['hessid'] = bssid
1036 hostapd
.add_ap(apdev
[0], params
)
1038 bssid2
= apdev
[1]['bssid']
1039 params
= hs20_ap_params()
1040 params
['hessid'] = bssid2
1041 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
1042 hostapd
.add_ap(apdev
[1], params
)
1044 dev
[0].hs20_enable()
1045 dev
[0].request("SET pmf 2")
1046 id = dev
[0].add_cred_values({ 'realm': "example.com",
1047 'ca_cert': "auth_serv/ca.pem",
1048 'username': "hs20-test",
1049 'password': "password",
1050 'domain': "example.com" })
1051 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1052 interworking_connect(dev
[0], bssid
, "TTLS")
1053 dev
[0].dump_monitor()
1055 logger
.info("Verifying GAS query with same AP while associated")
1056 dev
[0].request("ANQP_GET " + bssid
+ " 263")
1057 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1059 raise Exception("ANQP operation timed out")
1060 dev
[0].dump_monitor()
1062 logger
.info("Verifying GAS query with another AP while associated")
1063 dev
[0].scan_for_bss(bssid2
, 2412)
1064 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
1065 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1067 raise Exception("ANQP operation timed out")
1069 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
1070 """Hotspot 2.0 connection with fragmented GAS query while associated"""
1071 check_eap_capa(dev
[0], "MSCHAPV2")
1072 bssid
= apdev
[0]['bssid']
1073 params
= hs20_ap_params()
1074 params
['hessid'] = bssid
1075 hapd
= hostapd
.add_ap(apdev
[0], params
)
1076 hapd
.set("gas_frag_limit", "50")
1078 dev
[0].hs20_enable()
1079 id = dev
[0].add_cred_values({ 'realm': "example.com",
1080 'ca_cert': "auth_serv/ca.pem",
1081 'username': "hs20-test",
1082 'password': "password",
1083 'domain': "example.com" })
1084 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1085 interworking_connect(dev
[0], bssid
, "TTLS")
1087 logger
.info("Verifying GAS query while associated")
1088 dev
[0].request("FETCH_ANQP")
1089 for i
in range(0, 6):
1090 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1092 raise Exception("Operation timed out")
1094 def test_ap_hs20_multiple_connects(dev
, apdev
):
1095 """Hotspot 2.0 connection through multiple network selections"""
1096 check_eap_capa(dev
[0], "MSCHAPV2")
1097 bssid
= apdev
[0]['bssid']
1098 params
= hs20_ap_params()
1099 params
['hessid'] = bssid
1100 hostapd
.add_ap(apdev
[0], params
)
1102 dev
[0].hs20_enable()
1103 values
= { 'realm': "example.com",
1104 'ca_cert': "auth_serv/ca.pem",
1105 'username': "hs20-test",
1106 'password': "password",
1107 'domain': "example.com" }
1108 id = dev
[0].add_cred_values(values
)
1110 dev
[0].scan_for_bss(bssid
, freq
="2412")
1112 for i
in range(0, 3):
1113 logger
.info("Starting Interworking network selection")
1114 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1116 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1117 "INTERWORKING-ALREADY-CONNECTED",
1118 "CTRL-EVENT-CONNECTED"], timeout
=15)
1120 raise Exception("Connection timed out")
1121 if "INTERWORKING-NO-MATCH" in ev
:
1122 raise Exception("Matching AP not found")
1123 if "CTRL-EVENT-CONNECTED" in ev
:
1125 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
1128 dev
[0].request("DISCONNECT")
1129 dev
[0].dump_monitor()
1131 networks
= dev
[0].list_networks()
1132 if len(networks
) > 1:
1133 raise Exception("Duplicated network block detected")
1135 def test_ap_hs20_disallow_aps(dev
, apdev
):
1136 """Hotspot 2.0 connection and disallow_aps"""
1137 bssid
= apdev
[0]['bssid']
1138 params
= hs20_ap_params()
1139 params
['hessid'] = bssid
1140 hostapd
.add_ap(apdev
[0], params
)
1142 dev
[0].hs20_enable()
1143 values
= { 'realm': "example.com",
1144 'ca_cert': "auth_serv/ca.pem",
1145 'username': "hs20-test",
1146 'password': "password",
1147 'domain': "example.com" }
1148 id = dev
[0].add_cred_values(values
)
1150 dev
[0].scan_for_bss(bssid
, freq
="2412")
1152 logger
.info("Verify disallow_aps bssid")
1153 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
1154 dev
[0].request("INTERWORKING_SELECT auto")
1155 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1157 raise Exception("Network selection timed out")
1158 dev
[0].dump_monitor()
1160 logger
.info("Verify disallow_aps ssid")
1161 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
1162 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1163 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1165 raise Exception("Network selection timed out")
1166 dev
[0].dump_monitor()
1168 logger
.info("Verify disallow_aps clear")
1169 dev
[0].request("SET disallow_aps ")
1170 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1172 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
1173 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1174 if "FAIL" not in ret
:
1175 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
1177 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
1178 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1179 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
1180 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1182 def policy_test(dev
, ap
, values
, only_one
=True):
1185 logger
.info("Verify network selection to AP " + ap
['ifname'])
1187 dev
.scan_for_bss(bssid
, freq
="2412")
1189 logger
.info("Verify network selection")
1192 id = dev
.add_cred_values(values
)
1193 dev
.request("INTERWORKING_SELECT auto freq=2412")
1196 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1197 "INTERWORKING-BLACKLISTED",
1198 "INTERWORKING-SELECTED"], timeout
=15)
1200 raise Exception("Network selection timed out")
1202 if "INTERWORKING-NO-MATCH" in ev
:
1203 raise Exception("Matching AP not found")
1204 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1205 raise Exception("Unexpected AP claimed acceptable")
1206 if "INTERWORKING-SELECTED" in ev
:
1207 if bssid
and bssid
not in ev
:
1208 raise Exception("Selected incorrect BSS")
1211 ev
= dev
.wait_connected(timeout
=15)
1212 if bssid
and bssid
not in ev
:
1213 raise Exception("Connected to incorrect BSS")
1215 conn_bssid
= dev
.get_status_field("bssid")
1216 if bssid
and conn_bssid
!= bssid
:
1217 raise Exception("bssid information points to incorrect BSS")
1223 def default_cred(domain
=None, user
="hs20-test"):
1224 cred
= { 'realm': "example.com",
1225 'ca_cert': "auth_serv/ca.pem",
1227 'password': "password" }
1229 cred
['domain'] = domain
1232 def test_ap_hs20_prefer_home(dev
, apdev
):
1233 """Hotspot 2.0 required roaming consortium"""
1234 check_eap_capa(dev
[0], "MSCHAPV2")
1235 params
= hs20_ap_params()
1236 params
['domain_name'] = "example.org"
1237 hostapd
.add_ap(apdev
[0], params
)
1239 params
= hs20_ap_params()
1240 params
['ssid'] = "test-hs20-other"
1241 params
['domain_name'] = "example.com"
1242 hostapd
.add_ap(apdev
[1], params
)
1244 values
= default_cred()
1245 values
['domain'] = "example.com"
1246 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1247 values
['domain'] = "example.org"
1248 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1250 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1251 """Hotspot 2.0 required roaming consortium"""
1252 check_eap_capa(dev
[0], "MSCHAPV2")
1253 params
= hs20_ap_params()
1254 hostapd
.add_ap(apdev
[0], params
)
1256 params
= hs20_ap_params()
1257 params
['ssid'] = "test-hs20-other"
1258 params
['roaming_consortium'] = [ "223344" ]
1259 hostapd
.add_ap(apdev
[1], params
)
1261 values
= default_cred()
1262 values
['required_roaming_consortium'] = "223344"
1263 policy_test(dev
[0], apdev
[1], values
)
1264 values
['required_roaming_consortium'] = "112233"
1265 policy_test(dev
[0], apdev
[0], values
)
1267 id = dev
[0].add_cred()
1268 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1269 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1271 for val
in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1272 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1273 raise Exception("Invalid roaming consortium value accepted: " + val
)
1275 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1276 """Hotspot 2.0 exclusion based on SSID"""
1277 check_eap_capa(dev
[0], "MSCHAPV2")
1278 params
= hs20_ap_params()
1279 params
['roaming_consortium'] = [ "223344" ]
1280 params
['anqp_3gpp_cell_net'] = "555,444"
1281 hostapd
.add_ap(apdev
[0], params
)
1283 params
= hs20_ap_params()
1284 params
['ssid'] = "test-hs20-other"
1285 params
['roaming_consortium'] = [ "223344" ]
1286 params
['anqp_3gpp_cell_net'] = "555,444"
1287 hostapd
.add_ap(apdev
[1], params
)
1289 values
= default_cred()
1290 values
['excluded_ssid'] = "test-hs20"
1291 events
= policy_test(dev
[0], apdev
[1], values
)
1292 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1294 raise Exception("Excluded network not reported")
1295 values
['excluded_ssid'] = "test-hs20-other"
1296 events
= policy_test(dev
[0], apdev
[0], values
)
1297 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1299 raise Exception("Excluded network not reported")
1301 values
= default_cred()
1302 values
['roaming_consortium'] = "223344"
1303 values
['eap'] = "TTLS"
1304 values
['phase2'] = "auth=MSCHAPV2"
1305 values
['excluded_ssid'] = "test-hs20"
1306 events
= policy_test(dev
[0], apdev
[1], values
)
1307 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1309 raise Exception("Excluded network not reported")
1311 values
= { 'imsi': "555444-333222111", 'eap': "SIM",
1312 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1313 'excluded_ssid': "test-hs20" }
1314 events
= policy_test(dev
[0], apdev
[1], values
)
1315 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1317 raise Exception("Excluded network not reported")
1319 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1320 """Hotspot 2.0 and roaming from current to higher priority network"""
1321 check_eap_capa(dev
[0], "MSCHAPV2")
1322 bssid
= apdev
[0]['bssid']
1323 params
= hs20_ap_params(ssid
="test-hs20-visited")
1324 params
['domain_name'] = "visited.example.org"
1325 hostapd
.add_ap(apdev
[0], params
)
1327 dev
[0].hs20_enable()
1328 id = dev
[0].add_cred_values({ 'realm': "example.com",
1329 'ca_cert': "auth_serv/ca.pem",
1330 'username': "hs20-test",
1331 'password': "password",
1332 'domain': "example.com" })
1333 logger
.info("Connect to the only network option")
1334 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1335 dev
[0].dump_monitor()
1336 interworking_connect(dev
[0], bssid
, "TTLS")
1338 logger
.info("Start another AP (home operator) and reconnect")
1339 bssid2
= apdev
[1]['bssid']
1340 params
= hs20_ap_params(ssid
="test-hs20-home")
1341 params
['domain_name'] = "example.com"
1342 hostapd
.add_ap(apdev
[1], params
)
1344 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1345 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1346 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1347 "INTERWORKING-ALREADY-CONNECTED",
1348 "CTRL-EVENT-CONNECTED"], timeout
=15)
1350 raise Exception("Connection timed out")
1351 if "INTERWORKING-NO-MATCH" in ev
:
1352 raise Exception("Matching AP not found")
1353 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1354 raise Exception("Unexpected AP selected")
1355 if bssid2
not in ev
:
1356 raise Exception("Unexpected BSSID after reconnection")
1358 def test_ap_hs20_domain_suffix_match_full(dev
, apdev
):
1359 """Hotspot 2.0 and domain_suffix_match"""
1360 check_domain_match_full(dev
[0])
1361 check_eap_capa(dev
[0], "MSCHAPV2")
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': "server.w1.fi" })
1373 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1374 dev
[0].dump_monitor()
1375 interworking_connect(dev
[0], bssid
, "TTLS")
1376 dev
[0].request("REMOVE_NETWORK all")
1377 dev
[0].dump_monitor()
1379 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1380 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1381 dev
[0].dump_monitor()
1382 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1383 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1385 raise Exception("TLS certificate error not reported")
1386 if "Domain suffix mismatch" not in ev
:
1387 raise Exception("Domain suffix mismatch not reported")
1389 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1390 """Hotspot 2.0 and domain_suffix_match"""
1391 check_eap_capa(dev
[0], "MSCHAPV2")
1392 check_domain_match_full(dev
[0])
1393 bssid
= apdev
[0]['bssid']
1394 params
= hs20_ap_params()
1395 hostapd
.add_ap(apdev
[0], params
)
1397 dev
[0].hs20_enable()
1398 id = dev
[0].add_cred_values({ 'realm': "example.com",
1399 'username': "hs20-test",
1400 'password': "password",
1401 'ca_cert': "auth_serv/ca.pem",
1402 'domain': "example.com",
1403 'domain_suffix_match': "w1.fi" })
1404 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1405 dev
[0].dump_monitor()
1406 interworking_connect(dev
[0], bssid
, "TTLS")
1408 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1409 """Hotspot 2.0 and roaming partner preference"""
1410 check_eap_capa(dev
[0], "MSCHAPV2")
1411 params
= hs20_ap_params()
1412 params
['domain_name'] = "roaming.example.org"
1413 hostapd
.add_ap(apdev
[0], params
)
1415 params
= hs20_ap_params()
1416 params
['ssid'] = "test-hs20-other"
1417 params
['domain_name'] = "roaming.example.net"
1418 hostapd
.add_ap(apdev
[1], params
)
1420 logger
.info("Verify default vs. specified preference")
1421 values
= default_cred()
1422 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1423 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1424 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1425 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1427 logger
.info("Verify partial FQDN match")
1428 values
['roaming_partner'] = "example.net,0,0,*"
1429 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1430 values
['roaming_partner'] = "example.net,0,255,*"
1431 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1433 def test_ap_hs20_max_bss_load(dev
, apdev
):
1434 """Hotspot 2.0 and maximum BSS load"""
1435 check_eap_capa(dev
[0], "MSCHAPV2")
1436 params
= hs20_ap_params()
1437 params
['bss_load_test'] = "12:200:20000"
1438 hostapd
.add_ap(apdev
[0], params
)
1440 params
= hs20_ap_params()
1441 params
['ssid'] = "test-hs20-other"
1442 params
['bss_load_test'] = "5:20:10000"
1443 hostapd
.add_ap(apdev
[1], params
)
1445 logger
.info("Verify maximum BSS load constraint")
1446 values
= default_cred()
1447 values
['domain'] = "example.com"
1448 values
['max_bss_load'] = "100"
1449 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1451 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1452 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1453 raise Exception("Maximum BSS Load case not noticed")
1454 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1455 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1456 raise Exception("Maximum BSS Load case reported incorrectly")
1458 logger
.info("Verify maximum BSS load does not prevent connection")
1459 values
['max_bss_load'] = "1"
1460 events
= policy_test(dev
[0], None, values
)
1462 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1463 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1464 raise Exception("Maximum BSS Load case not noticed")
1465 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1466 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1467 raise Exception("Maximum BSS Load case not noticed")
1469 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1470 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1471 check_eap_capa(dev
[0], "MSCHAPV2")
1472 params
= hs20_ap_params()
1473 params
['bss_load_test'] = "12:200:20000"
1474 hostapd
.add_ap(apdev
[0], params
)
1476 params
= hs20_ap_params()
1477 params
['ssid'] = "test-hs20-other"
1478 hostapd
.add_ap(apdev
[1], params
)
1480 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1481 values
= default_cred()
1482 values
['domain'] = "example.com"
1483 values
['max_bss_load'] = "100"
1484 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1486 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1487 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1488 raise Exception("Maximum BSS Load case not noticed")
1489 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1490 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1491 raise Exception("Maximum BSS Load case reported incorrectly")
1493 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1494 """Hotspot 2.0 multi-cred sp_priority"""
1495 check_eap_capa(dev
[0], "MSCHAPV2")
1497 _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1499 dev
[0].request("SET external_sim 0")
1501 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1502 hlr_auc_gw_available()
1503 bssid
= apdev
[0]['bssid']
1504 params
= hs20_ap_params()
1505 params
['hessid'] = bssid
1506 del params
['domain_name']
1507 params
['anqp_3gpp_cell_net'] = "232,01"
1508 hostapd
.add_ap(apdev
[0], params
)
1510 dev
[0].hs20_enable()
1511 dev
[0].scan_for_bss(bssid
, freq
="2412")
1512 dev
[0].request("SET external_sim 1")
1513 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1514 'provisioning_sp': "example.com",
1515 'sp_priority' :"1" })
1516 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1517 'ca_cert': "auth_serv/ca.pem",
1518 'username': "hs20-test",
1519 'password': "password",
1520 'domain': "example.com",
1521 'provisioning_sp': "example.com",
1522 'sp_priority': "2" })
1523 dev
[0].dump_monitor()
1524 dev
[0].scan_for_bss(bssid
, freq
="2412")
1525 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1526 interworking_ext_sim_auth(dev
[0], "SIM")
1527 check_sp_type(dev
[0], "unknown")
1528 dev
[0].request("REMOVE_NETWORK all")
1530 dev
[0].set_cred(id1
, "sp_priority", "2")
1531 dev
[0].set_cred(id2
, "sp_priority", "1")
1532 dev
[0].dump_monitor()
1533 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1534 interworking_auth(dev
[0], "TTLS")
1535 check_sp_type(dev
[0], "unknown")
1537 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1538 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1539 check_eap_capa(dev
[0], "MSCHAPV2")
1541 _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
1543 dev
[0].request("SET external_sim 0")
1545 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1546 hlr_auc_gw_available()
1547 bssid
= apdev
[0]['bssid']
1548 params
= hs20_ap_params()
1549 params
['hessid'] = bssid
1550 del params
['nai_realm']
1551 del params
['domain_name']
1552 params
['anqp_3gpp_cell_net'] = "232,01"
1553 hostapd
.add_ap(apdev
[0], params
)
1555 bssid2
= apdev
[1]['bssid']
1556 params
= hs20_ap_params()
1557 params
['ssid'] = "test-hs20-other"
1558 params
['hessid'] = bssid2
1559 del params
['domain_name']
1560 del params
['anqp_3gpp_cell_net']
1561 hostapd
.add_ap(apdev
[1], params
)
1563 dev
[0].hs20_enable()
1564 dev
[0].request("SET external_sim 1")
1565 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1566 'provisioning_sp': "example.com",
1567 'sp_priority': "1" })
1568 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1569 'ca_cert': "auth_serv/ca.pem",
1570 'username': "hs20-test",
1571 'password': "password",
1572 'domain': "example.com",
1573 'provisioning_sp': "example.com",
1574 'sp_priority': "2" })
1575 dev
[0].dump_monitor()
1576 dev
[0].scan_for_bss(bssid
, freq
="2412")
1577 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1578 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1579 interworking_ext_sim_auth(dev
[0], "SIM")
1580 check_sp_type(dev
[0], "unknown")
1581 conn_bssid
= dev
[0].get_status_field("bssid")
1582 if conn_bssid
!= bssid
:
1583 raise Exception("Connected to incorrect BSS")
1584 dev
[0].request("REMOVE_NETWORK all")
1586 dev
[0].set_cred(id1
, "sp_priority", "2")
1587 dev
[0].set_cred(id2
, "sp_priority", "1")
1588 dev
[0].dump_monitor()
1589 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1590 interworking_auth(dev
[0], "TTLS")
1591 check_sp_type(dev
[0], "unknown")
1592 conn_bssid
= dev
[0].get_status_field("bssid")
1593 if conn_bssid
!= bssid2
:
1594 raise Exception("Connected to incorrect BSS")
1596 def check_conn_capab_selection(dev
, type, missing
):
1597 dev
.request("INTERWORKING_SELECT freq=2412")
1598 ev
= dev
.wait_event(["INTERWORKING-AP"])
1600 raise Exception("Network selection timed out");
1601 if "type=" + type not in ev
:
1602 raise Exception("Unexpected network type")
1603 if missing
and "conn_capab_missing=1" not in ev
:
1604 raise Exception("conn_capab_missing not reported")
1605 if not missing
and "conn_capab_missing=1" in ev
:
1606 raise Exception("conn_capab_missing reported unexpectedly")
1608 def conn_capab_cred(domain
=None, req_conn_capab
=None):
1609 cred
= default_cred(domain
=domain
)
1611 cred
['req_conn_capab'] = req_conn_capab
1614 def test_ap_hs20_req_conn_capab(dev
, apdev
):
1615 """Hotspot 2.0 network selection with req_conn_capab"""
1616 check_eap_capa(dev
[0], "MSCHAPV2")
1617 bssid
= apdev
[0]['bssid']
1618 params
= hs20_ap_params()
1619 hostapd
.add_ap(apdev
[0], params
)
1621 dev
[0].hs20_enable()
1622 dev
[0].scan_for_bss(bssid
, freq
="2412")
1623 logger
.info("Not used in home network")
1624 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
1625 id = dev
[0].add_cred_values(values
)
1626 check_conn_capab_selection(dev
[0], "home", False)
1628 logger
.info("Used in roaming network")
1629 dev
[0].remove_cred(id)
1630 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
1631 id = dev
[0].add_cred_values(values
)
1632 check_conn_capab_selection(dev
[0], "roaming", True)
1634 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1635 check_auto_select(dev
[0], bssid
)
1637 logger
.info("Additional req_conn_capab checks")
1639 dev
[0].remove_cred(id)
1640 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
1641 id = dev
[0].add_cred_values(values
)
1642 check_conn_capab_selection(dev
[0], "roaming", True)
1644 dev
[0].remove_cred(id)
1645 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
1646 id = dev
[0].add_cred_values(values
)
1647 check_conn_capab_selection(dev
[0], "roaming", True)
1649 bssid2
= apdev
[1]['bssid']
1650 params
= hs20_ap_params(ssid
="test-hs20b")
1651 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1652 hostapd
.add_ap(apdev
[1], params
)
1654 dev
[0].remove_cred(id)
1655 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
1656 id = dev
[0].add_cred_values(values
)
1657 dev
[0].set_cred(id, "req_conn_capab", "6:22")
1658 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1659 dev
[0].request("INTERWORKING_SELECT freq=2412")
1660 for i
in range(0, 2):
1661 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
1663 raise Exception("Network selection timed out");
1664 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
1665 raise Exception("Missing protocol connection capability not reported")
1666 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
1667 raise Exception("Protocol connection capability not reported correctly")
1669 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
1670 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1671 check_eap_capa(dev
[0], "MSCHAPV2")
1672 bssid
= apdev
[0]['bssid']
1673 params
= hs20_ap_params()
1674 params
['domain_name'] = "roaming.example.org"
1675 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1676 hostapd
.add_ap(apdev
[0], params
)
1678 bssid2
= apdev
[1]['bssid']
1679 params
= hs20_ap_params(ssid
="test-hs20-b")
1680 params
['domain_name'] = "roaming.example.net"
1681 hostapd
.add_ap(apdev
[1], params
)
1683 values
= default_cred()
1684 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1685 id = dev
[0].add_cred_values(values
)
1686 check_auto_select(dev
[0], bssid2
)
1688 dev
[0].set_cred(id, "req_conn_capab", "50")
1689 check_auto_select(dev
[0], bssid
)
1691 dev
[0].remove_cred(id)
1692 id = dev
[0].add_cred_values(values
)
1693 dev
[0].set_cred(id, "req_conn_capab", "51")
1694 check_auto_select(dev
[0], bssid2
)
1696 def check_bandwidth_selection(dev
, type, below
):
1697 dev
.request("INTERWORKING_SELECT freq=2412")
1698 ev
= dev
.wait_event(["INTERWORKING-AP"])
1700 raise Exception("Network selection timed out");
1701 logger
.debug("BSS entries:\n" + dev
.request("BSS RANGE=ALL"))
1702 if "type=" + type not in ev
:
1703 raise Exception("Unexpected network type")
1704 if below
and "below_min_backhaul=1" not in ev
:
1705 raise Exception("below_min_backhaul not reported")
1706 if not below
and "below_min_backhaul=1" in ev
:
1707 raise Exception("below_min_backhaul reported unexpectedly")
1709 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
1710 cred
= default_cred(domain
=domain
)
1712 cred
['min_dl_bandwidth_home'] = str(dl_home
)
1714 cred
['min_ul_bandwidth_home'] = str(ul_home
)
1716 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
1718 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
1721 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
1722 """Hotspot 2.0 network selection with min bandwidth (home)"""
1723 check_eap_capa(dev
[0], "MSCHAPV2")
1724 bssid
= apdev
[0]['bssid']
1725 params
= hs20_ap_params()
1726 hostapd
.add_ap(apdev
[0], params
)
1728 dev
[0].hs20_enable()
1729 dev
[0].scan_for_bss(bssid
, freq
="2412")
1730 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1731 id = dev
[0].add_cred_values(values
)
1732 check_bandwidth_selection(dev
[0], "home", False)
1733 dev
[0].remove_cred(id)
1735 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1736 id = dev
[0].add_cred_values(values
)
1737 check_bandwidth_selection(dev
[0], "home", True)
1738 dev
[0].remove_cred(id)
1740 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1741 id = dev
[0].add_cred_values(values
)
1742 check_bandwidth_selection(dev
[0], "home", True)
1743 dev
[0].remove_cred(id)
1745 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1746 id = dev
[0].add_cred_values(values
)
1747 check_bandwidth_selection(dev
[0], "home", True)
1748 check_auto_select(dev
[0], bssid
)
1750 bssid2
= apdev
[1]['bssid']
1751 params
= hs20_ap_params(ssid
="test-hs20-b")
1752 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1753 hostapd
.add_ap(apdev
[1], params
)
1755 check_auto_select(dev
[0], bssid2
)
1757 def test_ap_hs20_min_bandwidth_home_hidden_ssid_in_scan_res(dev
, apdev
):
1758 """Hotspot 2.0 network selection with min bandwidth (home) while hidden SSID is included in scan results"""
1759 check_eap_capa(dev
[0], "MSCHAPV2")
1760 bssid
= apdev
[0]['bssid']
1762 hapd
= hostapd
.add_ap(apdev
[0], { "ssid": 'secret',
1763 "ignore_broadcast_ssid": "1" })
1764 dev
[0].scan_for_bss(bssid
, freq
=2412)
1766 hapd_global
= hostapd
.HostapdGlobal(apdev
[0])
1768 hapd_global
.remove(apdev
[0]['ifname'])
1770 params
= hs20_ap_params()
1771 hostapd
.add_ap(apdev
[0], params
)
1773 dev
[0].hs20_enable()
1774 dev
[0].scan_for_bss(bssid
, freq
="2412")
1775 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1776 id = dev
[0].add_cred_values(values
)
1777 check_bandwidth_selection(dev
[0], "home", False)
1778 dev
[0].remove_cred(id)
1780 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1781 id = dev
[0].add_cred_values(values
)
1782 check_bandwidth_selection(dev
[0], "home", True)
1783 dev
[0].remove_cred(id)
1785 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1786 id = dev
[0].add_cred_values(values
)
1787 check_bandwidth_selection(dev
[0], "home", True)
1788 dev
[0].remove_cred(id)
1790 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1791 id = dev
[0].add_cred_values(values
)
1792 check_bandwidth_selection(dev
[0], "home", True)
1793 check_auto_select(dev
[0], bssid
)
1795 bssid2
= apdev
[1]['bssid']
1796 params
= hs20_ap_params(ssid
="test-hs20-b")
1797 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1798 hostapd
.add_ap(apdev
[1], params
)
1800 check_auto_select(dev
[0], bssid2
)
1802 dev
[0].flush_scan_cache()
1804 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
1805 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1806 check_eap_capa(dev
[0], "MSCHAPV2")
1807 bssid
= apdev
[0]['bssid']
1808 params
= hs20_ap_params()
1809 hostapd
.add_ap(apdev
[0], params
)
1811 dev
[0].hs20_enable()
1812 dev
[0].scan_for_bss(bssid
, freq
="2412")
1813 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
1814 id = dev
[0].add_cred_values(values
)
1815 check_bandwidth_selection(dev
[0], "roaming", False)
1816 dev
[0].remove_cred(id)
1818 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
1819 id = dev
[0].add_cred_values(values
)
1820 check_bandwidth_selection(dev
[0], "roaming", True)
1821 dev
[0].remove_cred(id)
1823 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
1824 id = dev
[0].add_cred_values(values
)
1825 check_bandwidth_selection(dev
[0], "roaming", True)
1826 dev
[0].remove_cred(id)
1828 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
1829 id = dev
[0].add_cred_values(values
)
1830 check_bandwidth_selection(dev
[0], "roaming", True)
1831 check_auto_select(dev
[0], bssid
)
1833 bssid2
= apdev
[1]['bssid']
1834 params
= hs20_ap_params(ssid
="test-hs20-b")
1835 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1836 hostapd
.add_ap(apdev
[1], params
)
1838 check_auto_select(dev
[0], bssid2
)
1840 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
1841 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1842 check_eap_capa(dev
[0], "MSCHAPV2")
1843 bssid
= apdev
[0]['bssid']
1844 params
= hs20_ap_params()
1845 params
['domain_name'] = "roaming.example.org"
1846 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1847 hostapd
.add_ap(apdev
[0], params
)
1849 bssid2
= apdev
[1]['bssid']
1850 params
= hs20_ap_params(ssid
="test-hs20-b")
1851 params
['domain_name'] = "roaming.example.net"
1852 hostapd
.add_ap(apdev
[1], params
)
1854 values
= default_cred()
1855 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1856 id = dev
[0].add_cred_values(values
)
1857 check_auto_select(dev
[0], bssid2
)
1859 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1860 check_auto_select(dev
[0], bssid
)
1862 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1863 check_auto_select(dev
[0], bssid2
)
1865 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
1866 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1867 bssid
= apdev
[0]['bssid']
1868 params
= hs20_ap_params()
1869 del params
['hs20_wan_metrics']
1870 hostapd
.add_ap(apdev
[0], params
)
1872 dev
[0].hs20_enable()
1873 dev
[0].scan_for_bss(bssid
, freq
="2412")
1874 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
1875 dl_roaming
=10000, ul_roaming
=10000)
1876 dev
[0].add_cred_values(values
)
1877 check_bandwidth_selection(dev
[0], "home", False)
1879 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
1880 """Hotspot 2.0 connection and deauthentication request for ESS"""
1881 check_eap_capa(dev
[0], "MSCHAPV2")
1883 _test_ap_hs20_deauth_req_ess(dev
, apdev
)
1885 dev
[0].request("SET pmf 0")
1887 def _test_ap_hs20_deauth_req_ess(dev
, apdev
):
1888 dev
[0].request("SET pmf 2")
1889 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1890 dev
[0].dump_monitor()
1891 addr
= dev
[0].p2p_interface_addr()
1892 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1893 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
1894 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1896 raise Exception("Timeout on deauth imminent notice")
1897 if "1 120 http://example.com/" not in ev
:
1898 raise Exception("Unexpected deauth imminent notice: " + ev
)
1899 hapd
.request("DEAUTHENTICATE " + addr
)
1900 dev
[0].wait_disconnected(timeout
=10)
1901 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1902 raise Exception("Network not marked temporarily disabled")
1903 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1904 "Trying to associate",
1905 "CTRL-EVENT-CONNECTED"], timeout
=5)
1907 raise Exception("Unexpected connection attempt")
1909 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
1910 """Hotspot 2.0 connection and deauthentication request for BSS"""
1911 check_eap_capa(dev
[0], "MSCHAPV2")
1913 _test_ap_hs20_deauth_req_bss(dev
, apdev
)
1915 dev
[0].request("SET pmf 0")
1917 def _test_ap_hs20_deauth_req_bss(dev
, apdev
):
1918 dev
[0].request("SET pmf 2")
1919 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1920 dev
[0].dump_monitor()
1921 addr
= dev
[0].p2p_interface_addr()
1922 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1923 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
1924 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1926 raise Exception("Timeout on deauth imminent notice")
1927 if "0 120 http://example.com/" not in ev
:
1928 raise Exception("Unexpected deauth imminent notice: " + ev
)
1929 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
1930 ev
= dev
[0].wait_disconnected(timeout
=10)
1931 if "reason=4" not in ev
:
1932 raise Exception("Unexpected disconnection reason")
1933 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1934 raise Exception("Network not marked temporarily disabled")
1935 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1936 "Trying to associate",
1937 "CTRL-EVENT-CONNECTED"], timeout
=5)
1939 raise Exception("Unexpected connection attempt")
1941 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1942 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1943 check_eap_capa(dev
[0], "MSCHAPV2")
1945 _test_ap_hs20_deauth_req_from_radius(dev
, apdev
)
1947 dev
[0].request("SET pmf 0")
1949 def _test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1950 bssid
= apdev
[0]['bssid']
1951 params
= hs20_ap_params()
1952 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1953 params
['hs20_deauth_req_timeout'] = "2"
1954 hostapd
.add_ap(apdev
[0], params
)
1956 dev
[0].request("SET pmf 2")
1957 dev
[0].hs20_enable()
1958 dev
[0].add_cred_values({ 'realm': "example.com",
1959 'username': "hs20-deauth-test",
1960 'password': "password" })
1961 interworking_select(dev
[0], bssid
, freq
="2412")
1962 interworking_connect(dev
[0], bssid
, "TTLS")
1963 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
1965 raise Exception("Timeout on deauth imminent notice")
1966 if " 1 100" not in ev
:
1967 raise Exception("Unexpected deauth imminent contents")
1968 dev
[0].wait_disconnected(timeout
=3)
1970 def test_ap_hs20_remediation_required(dev
, apdev
):
1971 """Hotspot 2.0 connection and remediation required from RADIUS"""
1972 check_eap_capa(dev
[0], "MSCHAPV2")
1974 _test_ap_hs20_remediation_required(dev
, apdev
)
1976 dev
[0].request("SET pmf 0")
1978 def _test_ap_hs20_remediation_required(dev
, apdev
):
1979 bssid
= apdev
[0]['bssid']
1980 params
= hs20_ap_params()
1981 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1982 hostapd
.add_ap(apdev
[0], params
)
1984 dev
[0].request("SET pmf 1")
1985 dev
[0].hs20_enable()
1986 dev
[0].add_cred_values({ 'realm': "example.com",
1987 'username': "hs20-subrem-test",
1988 'password': "password" })
1989 interworking_select(dev
[0], bssid
, freq
="2412")
1990 interworking_connect(dev
[0], bssid
, "TTLS")
1991 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1993 raise Exception("Timeout on subscription remediation notice")
1994 if " 1 https://example.com/" not in ev
:
1995 raise Exception("Unexpected subscription remediation event contents")
1997 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1998 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1999 check_eap_capa(dev
[0], "MSCHAPV2")
2001 _test_ap_hs20_remediation_required_ctrl(dev
, apdev
)
2003 dev
[0].request("SET pmf 0")
2005 def _test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
2006 bssid
= apdev
[0]['bssid']
2007 addr
= dev
[0].own_addr()
2008 params
= hs20_ap_params()
2009 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
2010 hapd
= hostapd
.add_ap(apdev
[0], params
)
2012 dev
[0].request("SET pmf 1")
2013 dev
[0].hs20_enable()
2014 dev
[0].add_cred_values(default_cred())
2015 interworking_select(dev
[0], bssid
, freq
="2412")
2016 interworking_connect(dev
[0], bssid
, "TTLS")
2018 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
2019 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2021 raise Exception("Timeout on subscription remediation notice")
2022 if " 1 https://example.com/" not in ev
:
2023 raise Exception("Unexpected subscription remediation event contents")
2025 hapd
.request("HS20_WNM_NOTIF " + addr
)
2026 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2028 raise Exception("Timeout on subscription remediation notice")
2029 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
2030 raise Exception("Unexpected subscription remediation event contents: " + ev
)
2032 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
2033 raise Exception("Unexpected HS20_WNM_NOTIF success")
2034 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
2035 raise Exception("Unexpected HS20_WNM_NOTIF success")
2036 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
2037 raise Exception("Unexpected HS20_WNM_NOTIF success")
2039 def test_ap_hs20_session_info(dev
, apdev
):
2040 """Hotspot 2.0 connection and session information from RADIUS"""
2041 check_eap_capa(dev
[0], "MSCHAPV2")
2043 _test_ap_hs20_session_info(dev
, apdev
)
2045 dev
[0].request("SET pmf 0")
2047 def _test_ap_hs20_session_info(dev
, apdev
):
2048 bssid
= apdev
[0]['bssid']
2049 params
= hs20_ap_params()
2050 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
2051 hostapd
.add_ap(apdev
[0], params
)
2053 dev
[0].request("SET pmf 1")
2054 dev
[0].hs20_enable()
2055 dev
[0].add_cred_values({ 'realm': "example.com",
2056 'username': "hs20-session-info-test",
2057 'password': "password" })
2058 interworking_select(dev
[0], bssid
, freq
="2412")
2059 interworking_connect(dev
[0], bssid
, "TTLS")
2060 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
2062 raise Exception("Timeout on ESS disassociation imminent notice")
2063 if " 1 59904 https://example.com/" not in ev
:
2064 raise Exception("Unexpected ESS disassociation imminent event contents")
2065 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
2067 raise Exception("Scan not started")
2068 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
2070 raise Exception("Scan not completed")
2072 def test_ap_hs20_osen(dev
, apdev
):
2073 """Hotspot 2.0 OSEN connection"""
2074 params
= { 'ssid': "osen",
2076 'auth_server_addr': "127.0.0.1",
2077 'auth_server_port': "1812",
2078 'auth_server_shared_secret': "radius" }
2079 hostapd
.add_ap(apdev
[0], params
)
2081 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
2083 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
2084 scan_freq
="2412", wait_connect
=False)
2085 dev
[0].flush_scan_cache()
2086 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2087 group
="GTK_NOT_USED",
2088 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2089 ca_cert
="auth_serv/ca.pem",
2091 res
= dev
[0].get_bss(apdev
[0]['bssid'])['flags']
2092 if "[OSEN-OSEN-CCMP]" not in res
:
2093 raise Exception("OSEN not reported in BSS")
2095 raise Exception("WEP reported in BSS")
2096 res
= dev
[0].request("SCAN_RESULTS")
2097 if "[OSEN-OSEN-CCMP]" not in res
:
2098 raise Exception("OSEN not reported in SCAN_RESULTS")
2100 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2101 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
2102 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2103 group
="GTK_NOT_USED",
2104 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2105 ca_cert
="auth_serv/ca.pem",
2107 wpas
.request("DISCONNECT")
2109 def test_ap_hs20_network_preference(dev
, apdev
):
2110 """Hotspot 2.0 network selection with preferred home network"""
2111 check_eap_capa(dev
[0], "MSCHAPV2")
2112 bssid
= apdev
[0]['bssid']
2113 params
= hs20_ap_params()
2114 hostapd
.add_ap(apdev
[0], params
)
2116 dev
[0].hs20_enable()
2117 values
= { 'realm': "example.com",
2118 'username': "hs20-test",
2119 'password': "password",
2120 'domain': "example.com" }
2121 dev
[0].add_cred_values(values
)
2123 id = dev
[0].add_network()
2124 dev
[0].set_network_quoted(id, "ssid", "home")
2125 dev
[0].set_network_quoted(id, "psk", "12345678")
2126 dev
[0].set_network(id, "priority", "1")
2127 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2129 dev
[0].scan_for_bss(bssid
, freq
="2412")
2130 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2131 ev
= dev
[0].wait_connected(timeout
=15)
2133 raise Exception("Unexpected network selected")
2135 bssid2
= apdev
[1]['bssid']
2136 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2137 hostapd
.add_ap(apdev
[1], params
)
2139 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2140 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2141 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2142 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2144 raise Exception("Connection timed out")
2145 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2146 raise Exception("No roam to higher priority network")
2147 if bssid2
not in ev
:
2148 raise Exception("Unexpected network selected")
2150 def test_ap_hs20_network_preference2(dev
, apdev
):
2151 """Hotspot 2.0 network selection with preferred credential"""
2152 check_eap_capa(dev
[0], "MSCHAPV2")
2153 bssid2
= apdev
[1]['bssid']
2154 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2155 hostapd
.add_ap(apdev
[1], params
)
2157 dev
[0].hs20_enable()
2158 values
= { 'realm': "example.com",
2159 'username': "hs20-test",
2160 'password': "password",
2161 'domain': "example.com",
2163 dev
[0].add_cred_values(values
)
2165 id = dev
[0].add_network()
2166 dev
[0].set_network_quoted(id, "ssid", "home")
2167 dev
[0].set_network_quoted(id, "psk", "12345678")
2168 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2170 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2171 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2172 ev
= dev
[0].wait_connected(timeout
=15)
2173 if bssid2
not in ev
:
2174 raise Exception("Unexpected network selected")
2176 bssid
= apdev
[0]['bssid']
2177 params
= hs20_ap_params()
2178 hostapd
.add_ap(apdev
[0], params
)
2180 dev
[0].scan_for_bss(bssid
, freq
="2412")
2181 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2182 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2183 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2185 raise Exception("Connection timed out")
2186 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2187 raise Exception("No roam to higher priority network")
2189 raise Exception("Unexpected network selected")
2191 def test_ap_hs20_network_preference3(dev
, apdev
):
2192 """Hotspot 2.0 network selection with two credential (one preferred)"""
2193 check_eap_capa(dev
[0], "MSCHAPV2")
2194 bssid
= apdev
[0]['bssid']
2195 params
= hs20_ap_params()
2196 hostapd
.add_ap(apdev
[0], params
)
2198 bssid2
= apdev
[1]['bssid']
2199 params
= hs20_ap_params(ssid
="test-hs20b")
2200 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
2201 hostapd
.add_ap(apdev
[1], params
)
2203 dev
[0].hs20_enable()
2204 values
= { 'realm': "example.com",
2205 'username': "hs20-test",
2206 'password': "password",
2208 dev
[0].add_cred_values(values
)
2209 values
= { 'realm': "example.org",
2210 'username': "hs20-test",
2211 'password': "password" }
2212 id = dev
[0].add_cred_values(values
)
2214 dev
[0].scan_for_bss(bssid
, freq
="2412")
2215 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2216 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2217 ev
= dev
[0].wait_connected(timeout
=15)
2219 raise Exception("Unexpected network selected")
2221 dev
[0].set_cred(id, "priority", "2")
2222 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2223 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2224 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2226 raise Exception("Connection timed out")
2227 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2228 raise Exception("No roam to higher priority network")
2229 if bssid2
not in ev
:
2230 raise Exception("Unexpected network selected")
2232 def test_ap_hs20_network_preference4(dev
, apdev
):
2233 """Hotspot 2.0 network selection with username vs. SIM credential"""
2234 check_eap_capa(dev
[0], "MSCHAPV2")
2235 bssid
= apdev
[0]['bssid']
2236 params
= hs20_ap_params()
2237 hostapd
.add_ap(apdev
[0], params
)
2239 bssid2
= apdev
[1]['bssid']
2240 params
= hs20_ap_params(ssid
="test-hs20b")
2241 params
['hessid'] = bssid2
2242 params
['anqp_3gpp_cell_net'] = "555,444"
2243 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
2244 hostapd
.add_ap(apdev
[1], params
)
2246 dev
[0].hs20_enable()
2247 values
= { 'realm': "example.com",
2248 'username': "hs20-test",
2249 'password': "password",
2251 dev
[0].add_cred_values(values
)
2252 values
= { 'imsi': "555444-333222111",
2254 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
2255 id = dev
[0].add_cred_values(values
)
2257 dev
[0].scan_for_bss(bssid
, freq
="2412")
2258 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2259 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2260 ev
= dev
[0].wait_connected(timeout
=15)
2262 raise Exception("Unexpected network selected")
2264 dev
[0].set_cred(id, "priority", "2")
2265 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2266 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2267 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2269 raise Exception("Connection timed out")
2270 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2271 raise Exception("No roam to higher priority network")
2272 if bssid2
not in ev
:
2273 raise Exception("Unexpected network selected")
2275 def test_ap_hs20_interworking_select_blocking_scan(dev
, apdev
):
2276 """Ongoing INTERWORKING_SELECT blocking SCAN"""
2277 check_eap_capa(dev
[0], "MSCHAPV2")
2278 bssid
= apdev
[0]['bssid']
2279 params
= hs20_ap_params()
2280 hostapd
.add_ap(apdev
[0], params
)
2282 dev
[0].hs20_enable()
2283 values
= { 'realm': "example.com",
2284 'username': "hs20-test",
2285 'password': "password",
2286 'domain': "example.com" }
2287 dev
[0].add_cred_values(values
)
2289 dev
[0].scan_for_bss(bssid
, freq
="2412")
2290 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2291 if "FAIL-BUSY" not in dev
[0].request("SCAN"):
2292 raise Exception("Unexpected SCAN command result")
2293 dev
[0].wait_connected(timeout
=15)
2295 def test_ap_hs20_fetch_osu(dev
, apdev
):
2296 """Hotspot 2.0 OSU provider and icon fetch"""
2297 bssid
= apdev
[0]['bssid']
2298 params
= hs20_ap_params()
2299 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2300 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2301 params
['osu_method_list'] = "1"
2302 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2303 params
['osu_icon'] = "w1fi_logo"
2304 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2305 params
['osu_server_uri'] = "https://example.com/osu/"
2306 hostapd
.add_ap(apdev
[0], params
)
2308 bssid2
= apdev
[1]['bssid']
2309 params
= hs20_ap_params(ssid
="test-hs20b")
2310 params
['hessid'] = bssid2
2311 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2312 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2313 params
['osu_method_list'] = "0"
2314 params
['osu_nai'] = "osen@example.com"
2315 params
['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
2316 params
['osu_icon'] = "w1fi_logo"
2317 params
['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
2318 params
['osu_server_uri'] = "https://example.org/osu/"
2319 hostapd
.add_ap(apdev
[1], params
)
2321 with
open("w1fi_logo.png", "r") as f
:
2322 orig_logo
= f
.read()
2323 dev
[0].hs20_enable()
2324 dir = "/tmp/osu-fetch"
2325 if os
.path
.isdir(dir):
2326 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2328 os
.remove(dir + "/" + f
)
2335 dev
[1].scan_for_bss(bssid
, freq
="2412")
2336 dev
[2].scan_for_bss(bssid
, freq
="2412")
2337 dev
[0].request("SET osu_dir " + dir)
2338 dev
[0].request("FETCH_OSU")
2339 if "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2340 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2341 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2342 raise Exception("HS20_ICON_REQUEST failed")
2343 if "OK" not in dev
[2].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2344 raise Exception("REQ_HS20_ICON failed")
2347 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2348 "RX-HS20-ANQP-ICON"], timeout
=15)
2350 raise Exception("Timeout on OSU fetch")
2351 if "OSU provider fetch completed" in ev
:
2353 if "RX-HS20-ANQP-ICON" in ev
:
2354 with
open(ev
.split(' ')[1], "r") as f
:
2356 if logo
== orig_logo
:
2359 with
open(dir + "/osu-providers.txt", "r") as f
:
2361 logger
.debug("osu-providers.txt: " + prov
)
2362 if "OSU-PROVIDER " + bssid
not in prov
:
2363 raise Exception("Missing OSU_PROVIDER(1)")
2364 if "OSU-PROVIDER " + bssid2
not in prov
:
2365 raise Exception("Missing OSU_PROVIDER(2)")
2367 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2369 os
.remove(dir + "/" + f
)
2373 raise Exception("Unexpected number of icons fetched")
2375 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2377 raise Exception("Timeout on GAS-QUERY-DONE")
2378 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2380 raise Exception("Timeout on GAS-QUERY-DONE")
2381 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2382 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2383 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2385 raise Exception("Timeout on icon fetch")
2386 if "Icon Binary File" not in ev
:
2387 raise Exception("Unexpected ANQP element")
2389 ev
= dev
[2].wait_event(["RX-HS20-ICON"], timeout
=5)
2391 raise Exception("Timeout on RX-HS20-ICON")
2392 event_icon_len
= ev
.split(' ')[3]
2393 if " w1fi_logo " not in ev
:
2394 raise Exception("RX-HS20-ICON did not have the expected file name")
2396 raise Exception("RX-HS20-ICON did not have the expected BSSID")
2397 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 10"):
2398 raise Exception("GET_HS20_ICON 0..10 failed")
2399 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 5 10"):
2400 raise Exception("GET_HS20_ICON 5..15 failed")
2401 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 100000 10"):
2402 raise Exception("Unexpected success of GET_HS20_ICON with too large offset")
2407 raise Exception("Unexpectedly long icon")
2408 res
= dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo %d 1000" % pos
)
2409 if res
.startswith("FAIL"):
2411 icon
+= base64
.b64decode(res
)
2413 hex = binascii
.hexlify(icon
)
2414 if not hex.startswith("0009696d6167652f706e677d1d"):
2415 raise Exception("Unexpected beacon binary header: " + hex)
2416 with
open('w1fi_logo.png', 'r') as f
:
2418 if icon
[13:] != data
:
2419 raise Exception("Unexpected icon data")
2420 if len(icon
) != int(event_icon_len
):
2421 raise Exception("Unexpected RX-HS20-ICON event length: " + event_icon_len
)
2424 if "OK" not in dev
[i
].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2425 raise Exception("REQ_HS20_ICON failed [2]")
2427 ev
= dev
[i
].wait_event(["RX-HS20-ICON"], timeout
=5)
2429 raise Exception("Timeout on RX-HS20-ICON [2]")
2431 if "FAIL" not in dev
[2].request("DEL_HS20_ICON foo w1fi_logo"):
2432 raise Exception("Invalid DEL_HS20_ICON accepted")
2433 if "OK" not in dev
[2].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
2434 raise Exception("DEL_HS20_ICON failed")
2435 if "OK" not in dev
[1].request("DEL_HS20_ICON " + bssid
):
2436 raise Exception("DEL_HS20_ICON failed")
2437 if "OK" not in dev
[0].request("DEL_HS20_ICON "):
2438 raise Exception("DEL_HS20_ICON failed")
2440 if "FAIL" not in dev
[i
].request("DEL_HS20_ICON "):
2441 raise Exception("DEL_HS20_ICON accepted when no icons left")
2443 def get_icon(dev
, bssid
, iconname
):
2448 raise Exception("Unexpectedly long icon")
2449 res
= dev
.request("GET_HS20_ICON " + bssid
+ " " + iconname
+ " %d 3000" % pos
)
2450 if res
.startswith("FAIL"):
2452 icon
+= base64
.b64decode(res
)
2455 raise Exception("Too short GET_HS20_ICON response")
2456 return icon
[0:13], icon
[13:]
2458 def test_ap_hs20_req_hs20_icon(dev
, apdev
):
2459 """Hotspot 2.0 OSU provider and multi-icon fetch with REQ_HS20_ICON"""
2460 bssid
= apdev
[0]['bssid']
2461 params
= hs20_ap_params()
2462 params
['hs20_icon'] = [ "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
2463 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem" ]
2464 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2465 params
['osu_method_list'] = "1"
2466 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2467 params
['osu_icon'] = [ "w1fi_logo", "w1fi_logo2" ]
2468 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2469 params
['osu_server_uri'] = "https://example.com/osu/"
2470 hostapd
.add_ap(apdev
[0], params
)
2472 dev
[0].scan_for_bss(bssid
, freq
="2412")
2474 # First, fetch two icons from the AP to wpa_supplicant
2476 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2477 raise Exception("REQ_HS20_ICON failed")
2478 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
2480 raise Exception("Timeout on RX-HS20-ICON (1)")
2482 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
2483 raise Exception("REQ_HS20_ICON failed")
2484 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
2486 raise Exception("Timeout on RX-HS20-ICON (2)")
2488 # Then, fetch the icons from wpa_supplicant for validation
2490 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
2491 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
2493 with
open('w1fi_logo.png', 'r') as f
:
2496 raise Exception("Unexpected icon data (1)")
2498 with
open('auth_serv/sha512-server.pem', 'r') as f
:
2501 raise Exception("Unexpected icon data (2)")
2503 # Finally, delete the icons from wpa_supplicant
2505 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
2506 raise Exception("DEL_HS20_ICON failed")
2507 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
2508 raise Exception("DEL_HS20_ICON failed")
2510 def test_ap_hs20_req_hs20_icon_parallel(dev
, apdev
):
2511 """Hotspot 2.0 OSU provider and multi-icon parallel fetch with REQ_HS20_ICON"""
2512 bssid
= apdev
[0]['bssid']
2513 params
= hs20_ap_params()
2514 params
['hs20_icon'] = [ "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
2515 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem" ]
2516 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2517 params
['osu_method_list'] = "1"
2518 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2519 params
['osu_icon'] = [ "w1fi_logo", "w1fi_logo2" ]
2520 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2521 params
['osu_server_uri'] = "https://example.com/osu/"
2522 hostapd
.add_ap(apdev
[0], params
)
2524 dev
[0].scan_for_bss(bssid
, freq
="2412")
2526 # First, fetch two icons from the AP to wpa_supplicant
2528 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2529 raise Exception("REQ_HS20_ICON failed")
2531 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
2532 raise Exception("REQ_HS20_ICON failed")
2533 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
2535 raise Exception("Timeout on RX-HS20-ICON (1)")
2536 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
2538 raise Exception("Timeout on RX-HS20-ICON (2)")
2540 # Then, fetch the icons from wpa_supplicant for validation
2542 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
2543 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
2545 with
open('w1fi_logo.png', 'r') as f
:
2548 raise Exception("Unexpected icon data (1)")
2550 with
open('auth_serv/sha512-server.pem', 'r') as f
:
2553 raise Exception("Unexpected icon data (2)")
2555 # Finally, delete the icons from wpa_supplicant
2557 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
2558 raise Exception("DEL_HS20_ICON failed")
2559 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
2560 raise Exception("DEL_HS20_ICON failed")
2562 def test_ap_hs20_fetch_osu_stop(dev
, apdev
):
2563 """Hotspot 2.0 OSU provider fetch stopped"""
2564 bssid
= apdev
[0]['bssid']
2565 params
= hs20_ap_params()
2566 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2567 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2568 params
['osu_method_list'] = "1"
2569 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2570 params
['osu_icon'] = "w1fi_logo"
2571 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2572 params
['osu_server_uri'] = "https://example.com/osu/"
2573 hapd
= hostapd
.add_ap(apdev
[0], params
)
2575 dev
[0].hs20_enable()
2576 dir = "/tmp/osu-fetch"
2577 if os
.path
.isdir(dir):
2578 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2580 os
.remove(dir + "/" + f
)
2587 dev
[0].request("SET osu_dir " + dir)
2588 dev
[0].request("SCAN freq=2412-2462")
2589 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=10)
2591 raise Exception("Scan did not start")
2592 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2593 raise Exception("FETCH_OSU accepted while scanning")
2594 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
2596 raise Exception("Scan timed out")
2597 hapd
.set("ext_mgmt_frame_handling", "1")
2598 dev
[0].request("FETCH_ANQP")
2599 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2600 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
2601 dev
[0].request("STOP_FETCH_ANQP")
2602 dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2603 dev
[0].dump_monitor()
2605 dev
[0].request("INTERWORKING_SELECT freq=2412")
2607 msg
= hapd
.mgmt_rx()
2608 if msg
['subtype'] == 13:
2610 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2611 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
2612 ev
= dev
[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
2615 raise Exception("Network selection timed out");
2617 dev
[0].dump_monitor()
2618 if "OK" not in dev
[0].request("FETCH_OSU"):
2619 raise Exception("FETCH_OSU failed")
2620 dev
[0].request("CANCEL_FETCH_OSU")
2624 if dev
[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
2627 dev
[0].dump_monitor()
2628 if "OK" not in dev
[0].request("FETCH_OSU"):
2629 raise Exception("FETCH_OSU failed")
2630 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2631 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2632 ev
= dev
[0].wait_event(["GAS-QUERY-START"], 10)
2634 raise Exception("GAS timed out")
2635 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2636 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2637 dev
[0].request("CANCEL_FETCH_OSU")
2638 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], 10)
2640 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
2642 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2644 os
.remove(dir + "/" + f
)
2647 def test_ap_hs20_ft(dev
, apdev
):
2648 """Hotspot 2.0 connection with FT"""
2649 check_eap_capa(dev
[0], "MSCHAPV2")
2650 bssid
= apdev
[0]['bssid']
2651 params
= hs20_ap_params()
2652 params
['wpa_key_mgmt'] = "FT-EAP"
2653 params
['nas_identifier'] = "nas1.w1.fi"
2654 params
['r1_key_holder'] = "000102030405"
2655 params
["mobility_domain"] = "a1b2"
2656 params
["reassociation_deadline"] = "1000"
2657 hostapd
.add_ap(apdev
[0], params
)
2659 dev
[0].hs20_enable()
2660 id = dev
[0].add_cred_values({ 'realm': "example.com",
2661 'username': "hs20-test",
2662 'password': "password",
2663 'ca_cert': "auth_serv/ca.pem",
2664 'domain': "example.com",
2665 'update_identifier': "1234" })
2666 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2667 interworking_connect(dev
[0], bssid
, "TTLS")
2669 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
2670 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2671 check_eap_capa(dev
[0], "MSCHAPV2")
2675 raise HwsimSkip("No sqlite3 module available")
2676 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
2681 con
= sqlite3
.connect(dbfile
)
2684 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2685 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2686 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2687 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2688 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2691 params
= { "ssid": "as", "beacon_int": "2000",
2692 "radius_server_clients": "auth_serv/radius_clients.conf",
2693 "radius_server_auth_port": '18128',
2695 "eap_user_file": "sqlite:" + dbfile
,
2696 "ca_cert": "auth_serv/ca.pem",
2697 "server_cert": "auth_serv/server.pem",
2698 "private_key": "auth_serv/server.key",
2699 "subscr_remediation_url": "https://example.org/",
2700 "subscr_remediation_method": "1" }
2701 hostapd
.add_ap(apdev
[1], params
)
2703 bssid
= apdev
[0]['bssid']
2704 params
= hs20_ap_params()
2705 params
['auth_server_port'] = "18128"
2706 hostapd
.add_ap(apdev
[0], params
)
2708 dev
[0].request("SET pmf 1")
2709 dev
[0].hs20_enable()
2710 id = dev
[0].add_cred_values({ 'realm': "example.com",
2711 'username': "user-mschapv2",
2712 'password': "password",
2713 'ca_cert': "auth_serv/ca.pem" })
2714 interworking_select(dev
[0], bssid
, freq
="2412")
2715 interworking_connect(dev
[0], bssid
, "TTLS")
2716 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2718 raise Exception("Timeout on subscription remediation notice")
2719 if " 1 https://example.org/" not in ev
:
2720 raise Exception("Unexpected subscription remediation event contents")
2724 cur
.execute("SELECT * from authlog")
2725 rows
= cur
.fetchall()
2727 raise Exception("No authlog entries")
2731 dev
[0].request("SET pmf 0")
2733 def test_ap_hs20_external_selection(dev
, apdev
):
2734 """Hotspot 2.0 connection using external network selection and creation"""
2735 check_eap_capa(dev
[0], "MSCHAPV2")
2736 bssid
= apdev
[0]['bssid']
2737 params
= hs20_ap_params()
2738 params
['hessid'] = bssid
2739 params
['disable_dgaf'] = '1'
2740 hostapd
.add_ap(apdev
[0], params
)
2742 dev
[0].hs20_enable()
2743 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
2744 identity
="hs20-test", password
="password",
2745 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2746 scan_freq
="2412", update_identifier
="54321")
2747 if dev
[0].get_status_field("hs20") != "2":
2748 raise Exception("Unexpected hs20 indication")
2750 def test_ap_hs20_random_mac_addr(dev
, apdev
):
2751 """Hotspot 2.0 connection with random MAC address"""
2752 check_eap_capa(dev
[0], "MSCHAPV2")
2753 bssid
= apdev
[0]['bssid']
2754 params
= hs20_ap_params()
2755 params
['hessid'] = bssid
2756 params
['disable_dgaf'] = '1'
2757 hapd
= hostapd
.add_ap(apdev
[0], params
)
2759 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2760 wpas
.interface_add("wlan5")
2761 addr
= wpas
.p2p_interface_addr()
2762 wpas
.request("SET mac_addr 1")
2763 wpas
.request("SET preassoc_mac_addr 1")
2764 wpas
.request("SET rand_addr_lifetime 60")
2766 wpas
.flush_scan_cache()
2767 id = wpas
.add_cred_values({ 'realm': "example.com",
2768 'username': "hs20-test",
2769 'password': "password",
2770 'ca_cert': "auth_serv/ca.pem",
2771 'domain': "example.com",
2772 'update_identifier': "1234" })
2773 interworking_select(wpas
, bssid
, "home", freq
="2412")
2774 interworking_connect(wpas
, bssid
, "TTLS")
2775 addr1
= wpas
.get_driver_status_field("addr")
2777 raise Exception("Did not use random MAC address")
2779 sta
= hapd
.get_sta(addr
)
2780 if sta
['addr'] != "FAIL":
2781 raise Exception("Unexpected STA association with permanent address")
2782 sta
= hapd
.get_sta(addr1
)
2783 if sta
['addr'] != addr1
:
2784 raise Exception("STA association with random address not found")
2786 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
2787 """Multiple networks and cred removal"""
2788 check_eap_capa(dev
[0], "MSCHAPV2")
2789 bssid
= apdev
[0]['bssid']
2790 params
= hs20_ap_params()
2791 params
['nai_realm'] = [ "0,example.com,25[3:26]"]
2792 hapd
= hostapd
.add_ap(apdev
[0], params
)
2794 dev
[0].add_network()
2795 dev
[0].hs20_enable()
2796 id = dev
[0].add_cred_values({ 'realm': "example.com",
2798 'password': "password" })
2799 interworking_select(dev
[0], bssid
, freq
="2412")
2800 interworking_connect(dev
[0], bssid
, "PEAP")
2801 dev
[0].add_network()
2803 dev
[0].request("DISCONNECT")
2804 dev
[0].wait_disconnected(timeout
=10)
2807 hapd
.set("ssid", "another ssid")
2810 interworking_select(dev
[0], bssid
, freq
="2412")
2811 interworking_connect(dev
[0], bssid
, "PEAP")
2812 dev
[0].add_network()
2813 if len(dev
[0].list_networks()) != 5:
2814 raise Exception("Unexpected number of networks prior to remove_crec")
2816 dev
[0].dump_monitor()
2817 dev
[0].remove_cred(id)
2818 if len(dev
[0].list_networks()) != 3:
2819 raise Exception("Unexpected number of networks after to remove_crec")
2820 dev
[0].wait_disconnected(timeout
=10)
2822 def test_ap_hs20_interworking_add_network(dev
, apdev
):
2823 """Hotspot 2.0 connection using INTERWORKING_ADD_NETWORK"""
2824 check_eap_capa(dev
[0], "MSCHAPV2")
2825 bssid
= apdev
[0]['bssid']
2826 params
= hs20_ap_params()
2827 params
['nai_realm'] = [ "0,example.com,21[3:26][6:7][99:99]" ]
2828 hostapd
.add_ap(apdev
[0], params
)
2830 dev
[0].hs20_enable()
2831 dev
[0].add_cred_values(default_cred(user
="user"))
2832 interworking_select(dev
[0], bssid
, freq
=2412)
2833 id = dev
[0].interworking_add_network(bssid
)
2834 dev
[0].select_network(id, freq
=2412)
2835 dev
[0].wait_connected()
2837 def _test_ap_hs20_proxyarp(dev
, apdev
):
2838 bssid
= apdev
[0]['bssid']
2839 params
= hs20_ap_params()
2840 params
['hessid'] = bssid
2841 params
['disable_dgaf'] = '0'
2842 params
['proxy_arp'] = '1'
2843 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
2844 if "OK" in hapd
.request("ENABLE"):
2845 raise Exception("Incomplete hostapd configuration was accepted")
2846 hapd
.set("ap_isolate", "1")
2847 if "OK" in hapd
.request("ENABLE"):
2848 raise Exception("Incomplete hostapd configuration was accepted")
2849 hapd
.set('bridge', 'ap-br0')
2854 # For now, do not report failures due to missing kernel support
2855 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2856 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2858 raise Exception("AP startup timed out")
2859 if "AP-ENABLED" not in ev
:
2860 raise Exception("AP startup failed")
2862 dev
[0].hs20_enable()
2863 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2864 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2866 id = dev
[0].add_cred_values({ 'realm': "example.com",
2867 'username': "hs20-test",
2868 'password': "password",
2869 'ca_cert': "auth_serv/ca.pem",
2870 'domain': "example.com",
2871 'update_identifier': "1234" })
2872 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2873 interworking_connect(dev
[0], bssid
, "TTLS")
2875 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2876 identity
="hs20-test", password
="password",
2877 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2881 addr0
= dev
[0].p2p_interface_addr()
2882 addr1
= dev
[1].p2p_interface_addr()
2884 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2885 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2887 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2888 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2890 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2891 raise Exception("DATA_TEST_FRAME failed")
2893 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2894 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2896 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2897 raise Exception("DATA_TEST_FRAME failed")
2899 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2900 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2902 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2903 raise Exception("DATA_TEST_FRAME failed")
2905 matches
= get_permanent_neighbors("ap-br0")
2906 logger
.info("After connect: " + str(matches
))
2907 if len(matches
) != 3:
2908 raise Exception("Unexpected number of neighbor entries after connect")
2909 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2910 raise Exception("dev0 addr missing")
2911 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2912 raise Exception("dev1 addr(1) missing")
2913 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2914 raise Exception("dev1 addr(2) missing")
2915 dev
[0].request("DISCONNECT")
2916 dev
[1].request("DISCONNECT")
2918 matches
= get_permanent_neighbors("ap-br0")
2919 logger
.info("After disconnect: " + str(matches
))
2920 if len(matches
) > 0:
2921 raise Exception("Unexpected neighbor entries after disconnect")
2923 def test_ap_hs20_hidden_ssid_in_scan_res(dev
, apdev
):
2924 """Hotspot 2.0 connection with hidden SSId in scan results"""
2925 check_eap_capa(dev
[0], "MSCHAPV2")
2926 bssid
= apdev
[0]['bssid']
2928 hapd
= hostapd
.add_ap(apdev
[0], { "ssid": 'secret',
2929 "ignore_broadcast_ssid": "1" })
2930 dev
[0].scan_for_bss(bssid
, freq
=2412)
2932 hapd_global
= hostapd
.HostapdGlobal(apdev
[0])
2934 hapd_global
.remove(apdev
[0]['ifname'])
2936 params
= hs20_ap_params()
2937 params
['hessid'] = bssid
2938 hapd
= hostapd
.add_ap(apdev
[0], params
)
2940 dev
[0].hs20_enable()
2941 id = dev
[0].add_cred_values({ 'realm': "example.com",
2942 'username': "hs20-test",
2943 'password': "password",
2944 'ca_cert': "auth_serv/ca.pem",
2945 'domain': "example.com" })
2946 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2947 interworking_connect(dev
[0], bssid
, "TTLS")
2949 # clear BSS table to avoid issues in following test cases
2950 dev
[0].request("DISCONNECT")
2951 dev
[0].wait_disconnected()
2953 dev
[0].flush_scan_cache()
2954 dev
[0].flush_scan_cache()
2956 def test_ap_hs20_proxyarp(dev
, apdev
):
2957 """Hotspot 2.0 and ProxyARP"""
2958 check_eap_capa(dev
[0], "MSCHAPV2")
2960 _test_ap_hs20_proxyarp(dev
, apdev
)
2962 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2963 stderr
=open('/dev/null', 'w'))
2964 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2965 stderr
=open('/dev/null', 'w'))
2967 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
2968 bssid
= apdev
[0]['bssid']
2969 params
= hs20_ap_params()
2970 params
['hessid'] = bssid
2971 params
['disable_dgaf'] = '1' if disabled
else '0'
2972 params
['proxy_arp'] = '1'
2973 params
['na_mcast_to_ucast'] = '1'
2974 params
['ap_isolate'] = '1'
2975 params
['bridge'] = 'ap-br0'
2976 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
2980 # For now, do not report failures due to missing kernel support
2981 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2982 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
2984 raise Exception("AP startup timed out")
2986 dev
[0].hs20_enable()
2987 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2988 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2990 id = dev
[0].add_cred_values({ 'realm': "example.com",
2991 'username': "hs20-test",
2992 'password': "password",
2993 'ca_cert': "auth_serv/ca.pem",
2994 'domain': "example.com",
2995 'update_identifier': "1234" })
2996 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2997 interworking_connect(dev
[0], bssid
, "TTLS")
2999 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
3000 identity
="hs20-test", password
="password",
3001 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
3005 addr0
= dev
[0].p2p_interface_addr()
3007 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
3009 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
3010 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
3012 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
3013 raise Exception("DATA_TEST_FRAME failed")
3015 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
3017 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3018 raise Exception("DATA_TEST_FRAME failed")
3020 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
3021 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
3022 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3023 raise Exception("DATA_TEST_FRAME failed")
3025 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
3026 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3027 yiaddr
="192.168.1.123", chaddr
=addr0
)
3028 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3029 raise Exception("DATA_TEST_FRAME failed")
3030 # another copy for additional code coverage
3031 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
3032 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3033 yiaddr
="192.168.1.123", chaddr
=addr0
)
3034 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3035 raise Exception("DATA_TEST_FRAME failed")
3037 matches
= get_permanent_neighbors("ap-br0")
3038 logger
.info("After connect: " + str(matches
))
3039 if len(matches
) != 2:
3040 raise Exception("Unexpected number of neighbor entries after connect")
3041 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3042 raise Exception("dev0 addr missing")
3043 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3044 raise Exception("dev0 IPv4 addr missing")
3045 dev
[0].request("DISCONNECT")
3046 dev
[1].request("DISCONNECT")
3048 matches
= get_permanent_neighbors("ap-br0")
3049 logger
.info("After disconnect: " + str(matches
))
3050 if len(matches
) > 0:
3051 raise Exception("Unexpected neighbor entries after disconnect")
3053 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
3054 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
3055 check_eap_capa(dev
[0], "MSCHAPV2")
3057 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
3059 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3060 stderr
=open('/dev/null', 'w'))
3061 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3062 stderr
=open('/dev/null', 'w'))
3064 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
3065 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
3066 check_eap_capa(dev
[0], "MSCHAPV2")
3068 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
3070 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3071 stderr
=open('/dev/null', 'w'))
3072 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3073 stderr
=open('/dev/null', 'w'))
3075 def ip_checksum(buf
):
3079 for i
in range(0, len(buf
), 2):
3080 val
, = struct
.unpack('H', buf
[i
:i
+2])
3083 sum = (sum & 0xffff) + (sum >> 16)
3084 return struct
.pack('H', ~
sum & 0xffff)
3086 def ipv6_solicited_node_mcaddr(target
):
3087 prefix
= socket
.inet_pton(socket
.AF_INET6
, "ff02::1:ff00:0")
3088 mask
= socket
.inet_pton(socket
.AF_INET6
, "::ff:ffff")
3089 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
3090 p
= struct
.unpack('4I', prefix
)
3091 m
= struct
.unpack('4I', mask
)
3092 t
= struct
.unpack('4I', _target
)
3093 res
= (p
[0] |
(t
[0] & m
[0]),
3094 p
[1] |
(t
[1] & m
[1]),
3095 p
[2] |
(t
[2] & m
[2]),
3096 p
[3] |
(t
[3] & m
[3]))
3097 return socket
.inet_ntop(socket
.AF_INET6
, struct
.pack('4I', *res
))
3099 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
3100 start
= struct
.pack("BB", type, code
)
3102 icmp
= start
+ '\x00\x00' + end
3103 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
3104 csum
= ip_checksum(pseudo
+ icmp
)
3105 return start
+ csum
+ end
3107 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
3108 reachable_time
=0, retrans_timer
=0, opt
=None):
3109 link_mc
= binascii
.unhexlify("3333ff000002")
3110 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3112 ehdr
= link_mc
+ _src_ll
+ proto
3113 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
3114 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
3116 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
3117 reachable_time
, retrans_timer
)
3122 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
3124 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
3125 ipv6
+= _ip_src
+ _ip_dst
3127 return ehdr
+ ipv6
+ icmp
3129 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
3130 link_mc
= binascii
.unhexlify("3333ff000002")
3131 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3133 ehdr
= link_mc
+ _src_ll
+ proto
3134 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
3136 ip_dst
= ipv6_solicited_node_mcaddr(target
)
3137 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
3139 reserved
= '\x00\x00\x00\x00'
3140 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
3142 payload
= reserved
+ _target
+ opt
3144 payload
= reserved
+ _target
3145 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
3147 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
3148 ipv6
+= _ip_src
+ _ip_dst
3150 return ehdr
+ ipv6
+ icmp
3152 def send_ns(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
3157 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
3160 src_ll
= dev
.p2p_interface_addr()
3161 cmd
= "DATA_TEST_FRAME "
3164 opt
= "\x01\x01" + binascii
.unhexlify(src_ll
.replace(':',''))
3166 pkt
= build_ns(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
3168 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
3169 raise Exception("DATA_TEST_FRAME failed")
3171 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None, flags
=0):
3172 link_mc
= binascii
.unhexlify("3333ff000002")
3173 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3175 ehdr
= link_mc
+ _src_ll
+ proto
3176 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
3177 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
3179 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
3181 payload
= struct
.pack('>Bxxx', flags
) + _target
+ opt
3183 payload
= struct
.pack('>Bxxx', flags
) + _target
3184 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
3186 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
3187 ipv6
+= _ip_src
+ _ip_dst
3189 return ehdr
+ ipv6
+ icmp
3191 def send_na(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
3196 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
3199 src_ll
= dev
.p2p_interface_addr()
3200 cmd
= "DATA_TEST_FRAME "
3202 pkt
= build_na(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
3204 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
3205 raise Exception("DATA_TEST_FRAME failed")
3207 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
3208 subnet_mask
="255.255.255.0", truncated_opt
=False,
3209 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False):
3210 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
3211 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3213 ehdr
= _dst_ll
+ _src_ll
+ proto
3214 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
3215 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
3216 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
3218 _ciaddr
= '\x00\x00\x00\x00'
3219 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
3220 _siaddr
= '\x00\x00\x00\x00'
3221 _giaddr
= '\x00\x00\x00\x00'
3222 _chaddr
= binascii
.unhexlify(chaddr
.replace(':','') + "00000000000000000000")
3223 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
3224 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
3227 payload
+= '\x63\x82\x53\x00'
3229 payload
+= '\x63\x82\x53\x63'
3231 payload
+= '\x22\xff\x00'
3232 # Option: DHCP Message Type = ACK
3233 payload
+= '\x35\x01\x05'
3236 # Option: Subnet Mask
3237 payload
+= '\x01\x04' + _subnet_mask
3238 # Option: Time Offset
3239 payload
+= struct
.pack('>BBL', 2, 4, 0)
3243 payload
+= '\x00\x00\x00\x00'
3246 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
3247 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
3249 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0) + payload
3252 tot_len
= force_tot_len
3254 tot_len
= 20 + len(udp
)
3255 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
3256 ipv4
= start
+ '\x00\x00' + _ip_src
+ _ip_dst
3257 csum
= ip_checksum(ipv4
)
3258 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
3260 return ehdr
+ ipv4
+ udp
3262 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
3263 target_mac
, target_ip
):
3264 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
3265 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
3267 ehdr
= _dst_ll
+ _src_ll
+ proto
3269 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':',''))
3270 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
3271 _target_mac
= binascii
.unhexlify(target_mac
.replace(':',''))
3272 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
3274 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
3275 arp
+= _sender_mac
+ _sender_ip
3276 arp
+= _target_mac
+ _target_ip
3280 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
3281 sender_mac
=None, sender_ip
="0.0.0.0",
3282 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
3287 if sender_mac
is None:
3288 sender_mac
= hapd_bssid
3289 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
3292 src_ll
= dev
.p2p_interface_addr()
3293 if sender_mac
is None:
3294 sender_mac
= dev
.p2p_interface_addr()
3295 cmd
= "DATA_TEST_FRAME "
3297 pkt
= build_arp(dst_ll
=dst_ll
, src_ll
=src_ll
, opcode
=opcode
,
3298 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
3299 target_mac
=target_mac
, target_ip
=target_ip
)
3300 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
3301 raise Exception("DATA_TEST_FRAME failed")
3303 def get_permanent_neighbors(ifname
):
3304 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
3305 res
= cmd
.stdout
.read()
3307 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
3309 def get_bridge_macs(ifname
):
3310 cmd
= subprocess
.Popen(['brctl', 'showmacs', ifname
],
3311 stdout
=subprocess
.PIPE
)
3312 res
= cmd
.stdout
.read()
3316 def tshark_get_arp(cap
, filter):
3317 res
= run_tshark(cap
, filter,
3318 [ "eth.dst", "eth.src",
3319 "arp.src.hw_mac", "arp.src.proto_ipv4",
3320 "arp.dst.hw_mac", "arp.dst.proto_ipv4" ],
3323 for l
in res
.splitlines():
3324 frames
.append(l
.split('\t'))
3327 def tshark_get_ns(cap
):
3328 res
= run_tshark(cap
, "icmpv6.type == 135",
3329 [ "eth.dst", "eth.src",
3330 "ipv6.src", "ipv6.dst",
3331 "icmpv6.nd.ns.target_address",
3332 "icmpv6.opt.linkaddr" ],
3335 for l
in res
.splitlines():
3336 frames
.append(l
.split('\t'))
3339 def tshark_get_na(cap
):
3340 res
= run_tshark(cap
, "icmpv6.type == 136",
3341 [ "eth.dst", "eth.src",
3342 "ipv6.src", "ipv6.dst",
3343 "icmpv6.nd.na.target_address",
3344 "icmpv6.opt.linkaddr" ],
3347 for l
in res
.splitlines():
3348 frames
.append(l
.split('\t'))
3351 def _test_proxyarp_open(dev
, apdev
, params
, ebtables
=False):
3352 prefix
= "proxyarp_open"
3354 prefix
+= "_ebtables"
3355 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
3356 cap_dev0
= os
.path
.join(params
['logdir'],
3357 prefix
+ ".%s.pcap" % dev
[0].ifname
)
3358 cap_dev1
= os
.path
.join(params
['logdir'],
3359 prefix
+ ".%s.pcap" % dev
[1].ifname
)
3360 cap_dev2
= os
.path
.join(params
['logdir'],
3361 prefix
+ ".%s.pcap" % dev
[2].ifname
)
3363 bssid
= apdev
[0]['bssid']
3364 params
= { 'ssid': 'open' }
3365 params
['proxy_arp'] = '1'
3366 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
3367 hapd
.set("ap_isolate", "1")
3368 hapd
.set('bridge', 'ap-br0')
3373 # For now, do not report failures due to missing kernel support
3374 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
3375 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
3377 raise Exception("AP startup timed out")
3378 if "AP-ENABLED" not in ev
:
3379 raise Exception("AP startup failed")
3381 params2
= { 'ssid': 'another' }
3382 hapd2
= hostapd
.add_ap(apdev
[1], params2
, no_enable
=True)
3383 hapd2
.set('bridge', 'ap-br0')
3386 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
3387 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
3390 for chain
in [ 'FORWARD', 'OUTPUT' ]:
3391 subprocess
.call(['ebtables', '-A', chain
, '-p', 'ARP',
3392 '-d', 'Broadcast', '-o', apdev
[0]['ifname'],
3394 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3395 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3396 '--ip6-icmp-type', 'neighbor-solicitation',
3397 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3398 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3399 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3400 '--ip6-icmp-type', 'neighbor-advertisement',
3401 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3402 subprocess
.call(['ebtables', '-A', chain
,
3403 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3404 '--ip6-icmp-type', 'router-solicitation',
3405 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3406 # Multicast Listener Report Message
3407 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3408 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3409 '--ip6-icmp-type', '143',
3410 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3414 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
3415 '-w', cap_br
, '-s', '2000'],
3416 stderr
=open('/dev/null', 'w'))
3417 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
3418 '-w', cap_dev0
, '-s', '2000'],
3419 stderr
=open('/dev/null', 'w'))
3420 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
3421 '-w', cap_dev1
, '-s', '2000'],
3422 stderr
=open('/dev/null', 'w'))
3423 cmd
[3] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[2].ifname
,
3424 '-w', cap_dev2
, '-s', '2000'],
3425 stderr
=open('/dev/null', 'w'))
3427 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
3428 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
3429 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
3432 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
3433 res
= brcmd
.stdout
.read()
3434 brcmd
.stdout
.close()
3435 logger
.info("Bridge setup: " + res
)
3437 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
3438 stdout
=subprocess
.PIPE
)
3439 res
= brcmd
.stdout
.read()
3440 brcmd
.stdout
.close()
3441 logger
.info("Bridge showstp: " + res
)
3443 addr0
= dev
[0].p2p_interface_addr()
3444 addr1
= dev
[1].p2p_interface_addr()
3445 addr2
= dev
[2].p2p_interface_addr()
3447 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
3448 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
3451 send_ns(dev
[0], ip_src
="::", target
="aaaa:bbbb:cccc::2")
3453 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2")
3454 # test frame without source link-layer address option
3455 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3457 # test frame with bogus option
3458 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3459 opt
="\x70\x01\x01\x02\x03\x04\x05\x05")
3460 # test frame with truncated source link-layer address option
3461 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3462 opt
="\x01\x01\x01\x02\x03\x04")
3463 # test frame with foreign source link-layer address option
3464 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3465 opt
="\x01\x01\x01\x02\x03\x04\x05\x06")
3467 send_ns(dev
[1], ip_src
="aaaa:bbbb:dddd::2", target
="aaaa:bbbb:dddd::2")
3469 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
3470 # another copy for additional code coverage
3471 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
3473 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
3474 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3475 yiaddr
="192.168.1.124", chaddr
=addr0
)
3476 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3477 raise Exception("DATA_TEST_FRAME failed")
3478 # Change address and verify unicast
3479 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
3480 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3481 yiaddr
="192.168.1.123", chaddr
=addr0
)
3482 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3483 raise Exception("DATA_TEST_FRAME failed")
3485 # Not-associated client MAC address
3486 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
3487 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3488 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
3489 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3490 raise Exception("DATA_TEST_FRAME failed")
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
="0.0.0.0", chaddr
=addr1
)
3496 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3497 raise Exception("DATA_TEST_FRAME failed")
3500 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3501 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3502 yiaddr
="192.168.1.126", chaddr
=addr1
,
3503 subnet_mask
="0.0.0.0")
3504 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3505 raise Exception("DATA_TEST_FRAME failed")
3508 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3509 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3510 yiaddr
="192.168.1.127", chaddr
=addr1
,
3512 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3513 raise Exception("DATA_TEST_FRAME failed")
3516 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3517 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3518 yiaddr
="192.168.1.128", chaddr
=addr1
,
3520 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3521 raise Exception("DATA_TEST_FRAME failed")
3523 # Wrong IPv4 total length
3524 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3525 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3526 yiaddr
="192.168.1.129", chaddr
=addr1
,
3528 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3529 raise Exception("DATA_TEST_FRAME failed")
3532 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3533 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3534 yiaddr
="192.168.1.129", chaddr
=addr1
,
3536 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3537 raise Exception("DATA_TEST_FRAME failed")
3539 macs
= get_bridge_macs("ap-br0")
3540 logger
.info("After connect (showmacs): " + str(macs
))
3542 matches
= get_permanent_neighbors("ap-br0")
3543 logger
.info("After connect: " + str(matches
))
3544 if len(matches
) != 4:
3545 raise Exception("Unexpected number of neighbor entries after connect")
3546 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3547 raise Exception("dev0 addr missing")
3548 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
3549 raise Exception("dev1 addr(1) missing")
3550 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
3551 raise Exception("dev1 addr(2) missing")
3552 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3553 raise Exception("dev0 IPv4 addr missing")
3555 targets
= [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
3557 for target
in targets
:
3558 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
3560 for target
in targets
:
3561 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
3564 for target
in targets
:
3565 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
=target
)
3567 # ARP Probe from wireless STA
3568 send_arp(dev
[1], target_ip
="192.168.1.127")
3569 # ARP Announcement from wireless STA
3570 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
3571 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
3574 macs
= get_bridge_macs("ap-br0")
3575 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
3577 matches
= get_permanent_neighbors("ap-br0")
3578 logger
.info("After ARP Probe + Announcement: " + str(matches
))
3580 # ARP Request for the newly introduced IP address from wireless STA
3581 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
3583 # ARP Request for the newly introduced IP address from bridge
3584 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
3585 target_ip
="192.168.1.127")
3586 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
="192.168.1.127")
3588 # ARP Probe from bridge
3589 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.130")
3590 send_arp(dev
[2], target_ip
="192.168.1.131")
3591 # ARP Announcement from bridge (not to be learned by AP for proxyarp)
3592 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
3593 target_ip
="192.168.1.130")
3594 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
3595 target_ip
="192.168.1.130", opcode
=2)
3596 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131")
3597 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131",
3600 macs
= get_bridge_macs("ap-br0")
3601 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
3603 matches
= get_permanent_neighbors("ap-br0")
3604 logger
.info("After ARP Probe + Announcement: " + str(matches
))
3606 # ARP Request for the newly introduced IP address from wireless STA
3607 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.130")
3608 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3609 send_arp(hapd
, hapd_bssid
=bssid
, dst_ll
=addr0
, sender_ip
="192.168.1.130",
3610 target_ip
="192.168.1.123", opcode
=2)
3612 # ARP Request for the newly introduced IP address from wireless STA
3613 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.131")
3614 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3615 send_arp(dev
[2], dst_ll
=addr0
, sender_ip
="192.168.1.131",
3616 target_ip
="192.168.1.123", opcode
=2)
3618 # ARP Request for the newly introduced IP address from bridge
3619 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
3620 target_ip
="192.168.1.130")
3621 send_arp(dev
[2], sender_ip
="192.168.1.104", target_ip
="192.168.1.131")
3623 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
3624 send_arp(dev
[1], target_ip
="192.168.1.123")
3625 # ARP Probe from wireless STA (duplicate address; learned through ARP)
3626 send_arp(dev
[0], target_ip
="192.168.1.127")
3628 # Gratuitous ARP Reply for another STA's IP address
3629 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
3630 target_mac
=addr1
, target_ip
="192.168.1.127")
3631 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
3632 target_mac
=addr0
, target_ip
="192.168.1.123")
3633 # ARP Request to verify previous mapping
3634 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
3635 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
3639 send_ns(dev
[0], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:cccc::2")
3641 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:dddd::2")
3643 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:dddd::2",
3644 ip_src
="aaaa:bbbb:ffff::2")
3646 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:ff00::2")
3648 send_ns(dev
[2], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:ff00::2")
3650 send_ns(dev
[2], target
="aaaa:bbbb:eeee::2", ip_src
="aaaa:bbbb:ff00::2")
3653 # Try to probe for an already assigned address
3654 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="::")
3656 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc::2", ip_src
="::")
3658 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="::")
3662 send_na(dev
[1], target
="aaaa:bbbb:cccc:aeae::3",
3663 ip_src
="aaaa:bbbb:cccc:aeae::3", ip_dst
="ff02::1")
3664 send_na(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc:aeae::4",
3665 ip_src
="aaaa:bbbb:cccc:aeae::4", ip_dst
="ff02::1")
3666 send_na(dev
[2], target
="aaaa:bbbb:cccc:aeae::5",
3667 ip_src
="aaaa:bbbb:cccc:aeae::5", ip_dst
="ff02::1")
3670 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
3671 except Exception, e
:
3672 logger
.info("test_connectibity_iface failed: " + str(e
))
3673 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
3674 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
3675 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
3677 dev
[0].request("DISCONNECT")
3678 dev
[1].request("DISCONNECT")
3680 for i
in range(len(cmd
)):
3682 macs
= get_bridge_macs("ap-br0")
3683 logger
.info("After disconnect (showmacs): " + str(macs
))
3684 matches
= get_permanent_neighbors("ap-br0")
3685 logger
.info("After disconnect: " + str(matches
))
3686 if len(matches
) > 0:
3687 raise Exception("Unexpected neighbor entries after disconnect")
3689 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
3690 stdout
=subprocess
.PIPE
)
3691 res
= cmd
.stdout
.read()
3693 logger
.info("ebtables results:\n" + res
)
3695 # Verify that expected ARP messages were seen and no unexpected
3696 # ARP messages were seen.
3698 arp_req
= tshark_get_arp(cap_dev0
, "arp.opcode == 1")
3699 arp_reply
= tshark_get_arp(cap_dev0
, "arp.opcode == 2")
3700 logger
.info("dev0 seen ARP requests:\n" + str(arp_req
))
3701 logger
.info("dev0 seen ARP replies:\n" + str(arp_reply
))
3703 if [ 'ff:ff:ff:ff:ff:ff', addr1
,
3704 addr1
, '192.168.1.100',
3705 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3706 raise Exception("dev0 saw ARP request from dev1")
3707 if [ 'ff:ff:ff:ff:ff:ff', addr2
,
3708 addr2
, '192.168.1.103',
3709 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3710 raise Exception("dev0 saw ARP request from dev2")
3711 # TODO: Uncomment once fixed in kernel
3712 #if [ 'ff:ff:ff:ff:ff:ff', bssid,
3713 # bssid, '192.168.1.101',
3714 # '00:00:00:00:00:00', '192.168.1.123' ] in arp_req:
3715 # raise Exception("dev0 saw ARP request from br")
3720 raise Exception("Unexpected foreign ARP request on dev0")
3722 arp_req
= tshark_get_arp(cap_dev1
, "arp.opcode == 1")
3723 arp_reply
= tshark_get_arp(cap_dev1
, "arp.opcode == 2")
3724 logger
.info("dev1 seen ARP requests:\n" + str(arp_req
))
3725 logger
.info("dev1 seen ARP replies:\n" + str(arp_reply
))
3727 if [ 'ff:ff:ff:ff:ff:ff', addr2
,
3728 addr2
, '192.168.1.103',
3729 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3730 raise Exception("dev1 saw ARP request from dev2")
3731 if [addr1
, addr0
, addr0
, '192.168.1.123', addr1
, '192.168.1.100'] not in arp_reply
:
3732 raise Exception("dev1 did not get ARP response for 192.168.1.123")
3737 raise Exception("Unexpected foreign ARP request on dev1")
3739 arp_req
= tshark_get_arp(cap_dev2
, "arp.opcode == 1")
3740 arp_reply
= tshark_get_arp(cap_dev2
, "arp.opcode == 2")
3741 logger
.info("dev2 seen ARP requests:\n" + str(arp_req
))
3742 logger
.info("dev2 seen ARP replies:\n" + str(arp_reply
))
3745 addr0
, '192.168.1.123',
3746 addr2
, '192.168.1.103' ] not in arp_reply
:
3747 raise Exception("dev2 did not get ARP response for 192.168.1.123")
3749 arp_req
= tshark_get_arp(cap_br
, "arp.opcode == 1")
3750 arp_reply
= tshark_get_arp(cap_br
, "arp.opcode == 2")
3751 logger
.info("br seen ARP requests:\n" + str(arp_req
))
3752 logger
.info("br seen ARP replies:\n" + str(arp_reply
))
3754 # TODO: Uncomment once fixed in kernel
3756 # addr0, '192.168.1.123',
3757 # bssid, '192.168.1.101' ] not in arp_reply:
3758 # raise Exception("br did not get ARP response for 192.168.1.123")
3760 ns
= tshark_get_ns(cap_dev0
)
3761 logger
.info("dev0 seen NS: " + str(ns
))
3762 na
= tshark_get_na(cap_dev0
)
3763 logger
.info("dev0 seen NA: " + str(na
))
3765 if [ addr0
, addr1
, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2',
3766 'aaaa:bbbb:dddd::2', addr1
] not in na
:
3767 raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
3772 raise Exception("Unexpected foreign NS on dev0: " + str(req
))
3774 ns
= tshark_get_ns(cap_dev1
)
3775 logger
.info("dev1 seen NS: " + str(ns
))
3776 na
= tshark_get_na(cap_dev1
)
3777 logger
.info("dev1 seen NA: " + str(na
))
3779 if [ addr1
, addr0
, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:dddd::2',
3780 'aaaa:bbbb:cccc::2', addr0
] not in na
:
3781 raise Exception("dev1 did not get NA for aaaa:bbbb:cccc::2")
3786 raise Exception("Unexpected foreign NS on dev1: " + str(req
))
3788 ns
= tshark_get_ns(cap_dev2
)
3789 logger
.info("dev2 seen NS: " + str(ns
))
3790 na
= tshark_get_na(cap_dev2
)
3791 logger
.info("dev2 seen NA: " + str(na
))
3793 # FIX: enable once kernel implementation for proxyarp IPv6 is fixed
3794 #if [ addr2, addr0, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:ff00::2',
3795 # 'aaaa:bbbb:cccc::2', addr0 ] not in na:
3796 # raise Exception("dev2 did not get NA for aaaa:bbbb:cccc::2")
3797 #if [ addr2, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:ff00::2',
3798 # 'aaaa:bbbb:dddd::2', addr1 ] not in na:
3799 # raise Exception("dev2 did not get NA for aaaa:bbbb:dddd::2")
3800 #if [ addr2, addr1, 'aaaa:bbbb:eeee::2', 'aaaa:bbbb:ff00::2',
3801 # 'aaaa:bbbb:eeee::2', addr1 ] not in na:
3802 # raise Exception("dev2 did not get NA for aaaa:bbbb:eeee::2")
3804 def test_proxyarp_open(dev
, apdev
, params
):
3805 """ProxyARP with open network"""
3807 _test_proxyarp_open(dev
, apdev
, params
)
3809 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3810 stderr
=open('/dev/null', 'w'))
3811 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3812 stderr
=open('/dev/null', 'w'))
3814 def test_proxyarp_open_ebtables(dev
, apdev
, params
):
3815 """ProxyARP with open network"""
3817 _test_proxyarp_open(dev
, apdev
, params
, ebtables
=True)
3820 subprocess
.call(['ebtables', '-F', 'FORWARD'])
3821 subprocess
.call(['ebtables', '-F', 'OUTPUT'])
3824 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3825 stderr
=open('/dev/null', 'w'))
3826 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3827 stderr
=open('/dev/null', 'w'))
3829 def test_ap_hs20_connect_deinit(dev
, apdev
):
3830 """Hotspot 2.0 connection interrupted with deinit"""
3831 check_eap_capa(dev
[0], "MSCHAPV2")
3832 bssid
= apdev
[0]['bssid']
3833 params
= hs20_ap_params()
3834 params
['hessid'] = bssid
3835 hapd
= hostapd
.add_ap(apdev
[0], params
)
3837 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
3838 wpas
.interface_add("wlan5", drv_params
="")
3840 wpas
.flush_scan_cache()
3841 wpas
.add_cred_values({ 'realm': "example.com",
3842 'username': "hs20-test",
3843 'password': "password",
3844 'ca_cert': "auth_serv/ca.pem",
3845 'domain': "example.com" })
3847 wpas
.scan_for_bss(bssid
, freq
=2412)
3850 wpas
.request("INTERWORKING_SELECT freq=2412")
3852 id = wpas
.request("RADIO_WORK add block-work")
3853 ev
= wpas
.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout
=5)
3855 raise Exception("Timeout while waiting radio work to start")
3856 ev
= wpas
.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout
=5)
3858 raise Exception("Timeout while waiting radio work to start (2)")
3860 # Remove the interface while the gas-query radio work is still pending and
3861 # GAS query has not yet been started.
3862 wpas
.interface_remove("wlan5")
3864 def test_ap_hs20_anqp_format_errors(dev
, apdev
):
3865 """Interworking network selection and ANQP format errors"""
3866 bssid
= apdev
[0]['bssid']
3867 params
= hs20_ap_params()
3868 params
['hessid'] = bssid
3869 hapd
= hostapd
.add_ap(apdev
[0], params
)
3871 dev
[0].hs20_enable()
3872 values
= { 'realm': "example.com",
3873 'ca_cert': "auth_serv/ca.pem",
3874 'username': "hs20-test",
3875 'password': "password",
3876 'domain': "example.com" }
3877 id = dev
[0].add_cred_values(values
)
3879 dev
[0].scan_for_bss(bssid
, freq
="2412")
3881 tests
= [ "00", "ffff", "010011223344", "020008000005112233445500",
3882 "01000400000000", "01000000000000",
3883 "01000300000200", "0100040000ff0000", "01000300000100",
3885 "01000600000056112233",
3886 "01000900000002050001000111",
3887 "01000600000001000000", "01000600000001ff0000",
3888 "01000600000001020001",
3889 "010008000000010400010001", "0100080000000104000100ff",
3890 "010011000000010d00050200020100030005000600",
3893 hapd
.set("anqp_elem", "263:" + t
)
3894 dev
[0].request("INTERWORKING_SELECT freq=2412")
3895 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=5)
3897 raise Exception("Network selection timed out")
3898 dev
[0].dump_monitor()
3900 dev
[0].remove_cred(id)
3901 id = dev
[0].add_cred_values({ 'imsi': "555444-333222111", 'eap': "AKA",
3902 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
3904 tests
= [ "00", "0100", "0001", "00ff", "000200ff", "0003000101",
3907 hapd
.set("anqp_elem", "264:" + t
)
3908 dev
[0].request("INTERWORKING_SELECT freq=2412")
3909 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=5)
3911 raise Exception("Network selection timed out")
3912 dev
[0].dump_monitor()