2 # Copyright (c) 2013-2019, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
7 from remotehost
import remote_compatible
13 logger
= logging
.getLogger()
20 from utils
import HwsimSkip
, skip_with_fips
, alloc_fail
, fail_test
, wait_fail_trigger
22 from tshark
import run_tshark
23 from wlantest
import Wlantest
24 from wpasupplicant
import WpaSupplicant
25 from wlantest
import WlantestCapture
26 from test_ap_eap
import check_eap_capa
, check_domain_match_full
27 from test_gas
import gas_rx
, parse_gas
, action_response
, anqp_initial_resp
, send_gas_resp
, ACTION_CATEG_PUBLIC
, GAS_INITIAL_RESPONSE
29 def hs20_ap_params(ssid
="test-hs20"):
30 params
= hostapd
.wpa2_params(ssid
=ssid
)
31 params
['wpa_key_mgmt'] = "WPA-EAP"
32 params
['ieee80211w'] = "1"
33 params
['ieee8021x'] = "1"
34 params
['auth_server_addr'] = "127.0.0.1"
35 params
['auth_server_port'] = "1812"
36 params
['auth_server_shared_secret'] = "radius"
37 params
['interworking'] = "1"
38 params
['access_network_type'] = "14"
39 params
['internet'] = "1"
43 params
['venue_group'] = "7"
44 params
['venue_type'] = "1"
45 params
['venue_name'] = ["eng:Example venue", "fin:Esimerkkipaikka"]
46 params
['roaming_consortium'] = ["112233", "1020304050", "010203040506",
48 params
['domain_name'] = "example.com,another.example.com"
49 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]",
50 "0,another.example.com"]
52 params
['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
53 params
['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0"]
54 params
['hs20_operating_class'] = "5173"
55 params
['anqp_3gpp_cell_net'] = "244,91"
58 def check_auto_select(dev
, bssid
):
59 dev
.scan_for_bss(bssid
, freq
="2412")
60 dev
.request("INTERWORKING_SELECT auto freq=2412")
61 ev
= dev
.wait_connected(timeout
=15)
63 raise Exception("Connected to incorrect network")
64 dev
.request("REMOVE_NETWORK all")
65 dev
.wait_disconnected()
68 def interworking_select(dev
, bssid
, type=None, no_match
=False, freq
=None):
70 if bssid
and freq
and not no_match
:
71 dev
.scan_for_bss(bssid
, freq
=freq
)
72 freq_extra
= " freq=" + str(freq
) if freq
else ""
73 dev
.request("INTERWORKING_SELECT" + freq_extra
)
74 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
77 raise Exception("Network selection timed out")
79 if "INTERWORKING-NO-MATCH" not in ev
:
80 raise Exception("Unexpected network match")
82 if "INTERWORKING-NO-MATCH" in ev
:
83 logger
.info("Matching network not found - try again")
85 dev
.request("INTERWORKING_SELECT" + freq_extra
)
86 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
89 raise Exception("Network selection timed out")
90 if "INTERWORKING-NO-MATCH" in ev
:
91 raise Exception("Matching network not found")
92 if bssid
and bssid
not in ev
:
93 raise Exception("Unexpected BSSID in match")
94 if type and "type=" + type not in ev
:
95 raise Exception("Network type not recognized correctly")
97 def check_sp_type(dev
, sp_type
):
98 type = dev
.get_status_field("sp_type")
100 raise Exception("sp_type not available")
102 raise Exception("sp_type did not indicate %s network" % sp_type
)
104 def hlr_auc_gw_available():
105 if not os
.path
.exists("/tmp/hlr_auc_gw.sock"):
106 raise HwsimSkip("No hlr_auc_gw socket available")
107 if not os
.path
.exists("../../hostapd/hlr_auc_gw"):
108 raise HwsimSkip("No hlr_auc_gw available")
110 def interworking_ext_sim_connect(dev
, bssid
, method
):
111 dev
.request("INTERWORKING_CONNECT " + bssid
)
112 interworking_ext_sim_auth(dev
, method
)
114 def interworking_ext_sim_auth(dev
, method
):
115 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
117 raise Exception("Network connected timed out")
118 if "(" + method
+ ")" not in ev
:
119 raise Exception("Unexpected EAP method selection")
121 ev
= dev
.wait_event(["CTRL-REQ-SIM"], timeout
=15)
123 raise Exception("Wait for external SIM processing request timed out")
125 if p
[1] != "GSM-AUTH":
126 raise Exception("Unexpected CTRL-REQ-SIM type")
127 id = p
[0].split('-')[3]
128 rand
= p
[2].split(' ')[0]
130 res
= subprocess
.check_output(["../../hostapd/hlr_auc_gw",
132 "auth_serv/hlr_auc_gw.milenage_db",
133 "GSM-AUTH-REQ 232010000000000 " + rand
]).decode()
134 if "GSM-AUTH-RESP" not in res
:
135 raise Exception("Unexpected hlr_auc_gw response")
136 resp
= res
.split(' ')[2].rstrip()
138 dev
.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp
)
139 dev
.wait_connected(timeout
=15)
141 def interworking_connect(dev
, bssid
, method
):
142 dev
.request("INTERWORKING_CONNECT " + bssid
)
143 interworking_auth(dev
, method
)
145 def interworking_auth(dev
, method
):
146 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
148 raise Exception("Network connected timed out")
149 if "(" + method
+ ")" not in ev
:
150 raise Exception("Unexpected EAP method selection")
152 dev
.wait_connected(timeout
=15)
154 def check_probe_resp(wt
, bssid_unexpected
, bssid_expected
):
156 count
= wt
.get_bss_counter("probe_response", bssid_unexpected
)
158 raise Exception("Unexpected Probe Response frame from AP")
161 count
= wt
.get_bss_counter("probe_response", bssid_expected
)
163 raise Exception("No Probe Response frame from AP")
165 def test_ap_anqp_sharing(dev
, apdev
):
166 """ANQP sharing within ESS and explicit unshare"""
167 check_eap_capa(dev
[0], "MSCHAPV2")
168 dev
[0].flush_scan_cache()
170 bssid
= apdev
[0]['bssid']
171 params
= hs20_ap_params()
172 params
['hessid'] = bssid
173 hostapd
.add_ap(apdev
[0], params
)
175 bssid2
= apdev
[1]['bssid']
176 params
= hs20_ap_params()
177 params
['hessid'] = bssid
178 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
179 hostapd
.add_ap(apdev
[1], params
)
182 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
183 'password': "secret",
184 'domain': "example.com"})
185 logger
.info("Normal network selection with shared ANQP results")
186 dev
[0].scan_for_bss(bssid
, freq
="2412")
187 dev
[0].scan_for_bss(bssid2
, freq
="2412")
188 interworking_select(dev
[0], None, "home", freq
="2412")
189 dev
[0].dump_monitor()
190 state
= dev
[0].get_status_field('wpa_state')
191 if state
!= "DISCONNECTED":
192 raise Exception("Unexpected wpa_state after INTERWORKING_SELECT: " + state
)
194 logger
.debug("BSS entries:\n" + dev
[0].request("BSS RANGE=ALL"))
195 res1
= dev
[0].get_bss(bssid
)
196 res2
= dev
[0].get_bss(bssid2
)
197 if 'anqp_nai_realm' not in res1
:
198 raise Exception("anqp_nai_realm not found for AP1")
199 if 'anqp_nai_realm' not in res2
:
200 raise Exception("anqp_nai_realm not found for AP2")
201 if res1
['anqp_nai_realm'] != res2
['anqp_nai_realm']:
202 raise Exception("ANQP results were not shared between BSSes")
204 logger
.info("Explicit ANQP request to unshare ANQP results")
205 dev
[0].request("ANQP_GET " + bssid
+ " 263")
206 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
208 raise Exception("ANQP operation timed out")
210 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
211 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
213 raise Exception("ANQP operation timed out")
215 res1
= dev
[0].get_bss(bssid
)
216 res2
= dev
[0].get_bss(bssid2
)
217 if res1
['anqp_nai_realm'] == res2
['anqp_nai_realm']:
218 raise Exception("ANQP results were not unshared")
220 def test_ap_anqp_domain_id(dev
, apdev
):
222 check_eap_capa(dev
[0], "MSCHAPV2")
223 dev
[0].flush_scan_cache()
225 bssid
= apdev
[0]['bssid']
226 params
= hs20_ap_params()
227 params
['hessid'] = bssid
228 params
['anqp_domain_id'] = '1234'
229 hostapd
.add_ap(apdev
[0], params
)
231 bssid2
= apdev
[1]['bssid']
232 params
= hs20_ap_params()
233 params
['hessid'] = bssid
234 params
['anqp_domain_id'] = '1234'
235 hostapd
.add_ap(apdev
[1], params
)
238 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
239 'password': "secret",
240 'domain': "example.com"})
241 dev
[0].scan_for_bss(bssid
, freq
="2412")
242 dev
[0].scan_for_bss(bssid2
, freq
="2412")
243 interworking_select(dev
[0], None, "home", freq
="2412")
245 def test_ap_anqp_no_sharing_diff_ess(dev
, apdev
):
246 """ANQP no sharing between ESSs"""
247 check_eap_capa(dev
[0], "MSCHAPV2")
248 dev
[0].flush_scan_cache()
250 bssid
= apdev
[0]['bssid']
251 params
= hs20_ap_params()
252 params
['hessid'] = bssid
253 hostapd
.add_ap(apdev
[0], params
)
255 bssid2
= apdev
[1]['bssid']
256 params
= hs20_ap_params(ssid
="test-hs20-another")
257 params
['hessid'] = bssid
258 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
259 hostapd
.add_ap(apdev
[1], params
)
262 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
263 'password': "secret",
264 'domain': "example.com"})
265 logger
.info("Normal network selection with shared ANQP results")
266 dev
[0].scan_for_bss(bssid
, freq
="2412")
267 dev
[0].scan_for_bss(bssid2
, freq
="2412")
268 interworking_select(dev
[0], None, "home", freq
="2412")
270 def test_ap_anqp_no_sharing_missing_info(dev
, apdev
):
271 """ANQP no sharing due to missing information"""
272 check_eap_capa(dev
[0], "MSCHAPV2")
273 dev
[0].flush_scan_cache()
275 bssid
= apdev
[0]['bssid']
276 params
= hs20_ap_params()
277 params
['hessid'] = bssid
278 del params
['roaming_consortium']
279 del params
['domain_name']
280 del params
['anqp_3gpp_cell_net']
281 del params
['nai_realm']
282 hostapd
.add_ap(apdev
[0], params
)
284 bssid2
= apdev
[1]['bssid']
285 params
= hs20_ap_params()
286 params
['hessid'] = bssid
287 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
288 hostapd
.add_ap(apdev
[1], params
)
291 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
292 'password': "secret",
293 'domain': "example.com"})
294 logger
.info("Normal network selection with shared ANQP results")
295 dev
[0].scan_for_bss(bssid
, freq
="2412")
296 dev
[0].scan_for_bss(bssid2
, freq
="2412")
297 interworking_select(dev
[0], None, "home", freq
="2412")
299 def test_ap_anqp_sharing_oom(dev
, apdev
):
300 """ANQP sharing within ESS and explicit unshare OOM"""
301 check_eap_capa(dev
[0], "MSCHAPV2")
302 dev
[0].flush_scan_cache()
304 bssid
= apdev
[0]['bssid']
305 params
= hs20_ap_params()
306 params
['hessid'] = bssid
307 hostapd
.add_ap(apdev
[0], params
)
309 bssid2
= apdev
[1]['bssid']
310 params
= hs20_ap_params()
311 params
['hessid'] = bssid
312 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
313 hostapd
.add_ap(apdev
[1], params
)
316 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
317 'password': "secret",
318 'domain': "example.com"})
319 dev
[0].scan_for_bss(bssid
, freq
="2412")
320 dev
[0].scan_for_bss(bssid2
, freq
="2412")
321 interworking_select(dev
[0], None, "home", freq
="2412")
322 dev
[0].dump_monitor()
324 with
alloc_fail(dev
[0], 1, "wpa_bss_anqp_clone"):
325 dev
[0].request("ANQP_GET " + bssid
+ " 263")
326 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
328 raise Exception("ANQP operation timed out")
330 def test_ap_nai_home_realm_query(dev
, apdev
):
331 """NAI Home Realm Query"""
332 check_eap_capa(dev
[0], "MSCHAPV2")
333 bssid
= apdev
[0]['bssid']
334 params
= hs20_ap_params()
335 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]",
336 "0,another.example.org"]
337 hostapd
.add_ap(apdev
[0], params
)
339 dev
[0].scan(freq
="2412")
340 dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " realm=example.com")
341 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
343 raise Exception("ANQP operation timed out")
344 nai1
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
345 dev
[0].dump_monitor()
347 dev
[0].request("ANQP_GET " + bssid
+ " 263")
348 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
350 raise Exception("ANQP operation timed out")
351 nai2
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
353 if len(nai1
) >= len(nai2
):
354 raise Exception("Unexpected NAI Realm list response lengths")
355 if binascii
.hexlify(b
"example.com").decode() not in nai1
:
356 raise Exception("Home realm not reported")
357 if binascii
.hexlify(b
"example.org").decode() in nai1
:
358 raise Exception("Non-home realm reported")
359 if binascii
.hexlify(b
"example.com").decode() not in nai2
:
360 raise Exception("Home realm not reported in wildcard query")
361 if binascii
.hexlify(b
"example.org").decode() not in nai2
:
362 raise Exception("Non-home realm not reported in wildcard query ")
365 "00:11:22:33:44:55 123",
366 "00:11:22:33:44:55 qq"]
368 if "FAIL" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd
):
369 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd
)
371 dev
[0].dump_monitor()
372 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
373 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
374 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
376 raise Exception("ANQP operation timed out")
377 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=0.1)
379 raise Exception("Unexpected ANQP response: " + ev
)
381 dev
[0].dump_monitor()
382 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " 01000b6578616d706c652e636f6d"):
383 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
384 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
386 raise Exception("No ANQP response")
387 if "NAI Realm list" not in ev
:
388 raise Exception("Missing NAI Realm list: " + ev
)
390 dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
391 'password': "secret",
392 'domain': "example.com"})
393 dev
[0].dump_monitor()
394 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
395 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
396 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
398 raise Exception("No ANQP response")
399 if "NAI Realm list" not in ev
:
400 raise Exception("Missing NAI Realm list: " + ev
)
403 def test_ap_interworking_scan_filtering(dev
, apdev
):
404 """Interworking scan filtering with HESSID and access network type"""
406 _test_ap_interworking_scan_filtering(dev
, apdev
)
408 dev
[0].request("SET hessid 00:00:00:00:00:00")
409 dev
[0].request("SET access_network_type 15")
411 def _test_ap_interworking_scan_filtering(dev
, apdev
):
412 bssid
= apdev
[0]['bssid']
413 params
= hs20_ap_params()
414 ssid
= "test-hs20-ap1"
415 params
['ssid'] = ssid
416 params
['hessid'] = bssid
417 hapd0
= hostapd
.add_ap(apdev
[0], params
)
419 bssid2
= apdev
[1]['bssid']
420 params
= hs20_ap_params()
421 ssid2
= "test-hs20-ap2"
422 params
['ssid'] = ssid2
423 params
['hessid'] = bssid2
424 params
['access_network_type'] = "1"
425 del params
['venue_group']
426 del params
['venue_type']
427 hostapd
.add_ap(apdev
[1], params
)
431 Wlantest
.setup(hapd0
)
435 # Make sure wlantest has seen both BSSs to avoid issues in trying to clear
436 # counters for non-existing BSS.
437 dev
[0].scan_for_bss(bssid
, freq
="2412")
438 dev
[0].scan_for_bss(bssid2
, freq
="2412")
439 wt
.clear_bss_counters(bssid
)
440 wt
.clear_bss_counters(bssid2
)
442 logger
.info("Check probe request filtering based on HESSID")
444 dev
[0].request("SET hessid " + bssid2
)
445 dev
[0].scan(freq
="2412")
447 check_probe_resp(wt
, bssid
, bssid2
)
449 logger
.info("Check probe request filtering based on access network type")
451 wt
.clear_bss_counters(bssid
)
452 wt
.clear_bss_counters(bssid2
)
453 dev
[0].request("SET hessid 00:00:00:00:00:00")
454 dev
[0].request("SET access_network_type 14")
455 dev
[0].scan(freq
="2412")
457 check_probe_resp(wt
, bssid2
, bssid
)
459 wt
.clear_bss_counters(bssid
)
460 wt
.clear_bss_counters(bssid2
)
461 dev
[0].request("SET hessid 00:00:00:00:00:00")
462 dev
[0].request("SET access_network_type 1")
463 dev
[0].scan(freq
="2412")
465 check_probe_resp(wt
, bssid
, bssid2
)
467 logger
.info("Check probe request filtering based on HESSID and ANT")
469 wt
.clear_bss_counters(bssid
)
470 wt
.clear_bss_counters(bssid2
)
471 dev
[0].request("SET hessid " + bssid
)
472 dev
[0].request("SET access_network_type 14")
473 dev
[0].scan(freq
="2412")
475 check_probe_resp(wt
, bssid2
, bssid
)
477 wt
.clear_bss_counters(bssid
)
478 wt
.clear_bss_counters(bssid2
)
479 dev
[0].request("SET hessid " + bssid2
)
480 dev
[0].request("SET access_network_type 14")
481 dev
[0].scan(freq
="2412")
483 check_probe_resp(wt
, bssid
, None)
484 check_probe_resp(wt
, bssid2
, None)
486 wt
.clear_bss_counters(bssid
)
487 wt
.clear_bss_counters(bssid2
)
488 dev
[0].request("SET hessid " + bssid
)
489 dev
[0].request("SET access_network_type 1")
490 dev
[0].scan(freq
="2412")
492 check_probe_resp(wt
, bssid
, None)
493 check_probe_resp(wt
, bssid2
, None)
495 def test_ap_hs20_select(dev
, apdev
):
496 """Hotspot 2.0 network selection"""
497 bssid
= apdev
[0]['bssid']
498 params
= hs20_ap_params()
499 params
['hessid'] = bssid
500 hostapd
.add_ap(apdev
[0], params
)
503 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
504 'password': "secret",
505 'domain': "example.com"})
506 interworking_select(dev
[0], bssid
, "home")
508 dev
[0].remove_cred(id)
509 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
510 'password': "secret",
511 'domain': "no.match.example.com"})
512 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
514 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com")
515 interworking_select(dev
[0], bssid
, no_match
=True, freq
="2412")
517 res
= dev
[0].request("SCAN_RESULTS")
518 if "[HS20]" not in res
:
519 raise Exception("HS20 flag missing from scan results: " + res
)
521 bssid2
= apdev
[1]['bssid']
522 params
= hs20_ap_params()
523 params
['nai_realm'] = ["0,example.org,21"]
524 params
['hessid'] = bssid2
525 params
['domain_name'] = "example.org"
526 hostapd
.add_ap(apdev
[1], params
)
527 dev
[0].remove_cred(id)
528 id = dev
[0].add_cred_values({'realm': "example.org", 'username': "test",
529 'password': "secret",
530 'domain': "example.org"})
531 interworking_select(dev
[0], bssid2
, "home", freq
="2412")
533 def hs20_simulated_sim(dev
, ap
, method
):
535 params
= hs20_ap_params()
536 params
['hessid'] = bssid
537 params
['anqp_3gpp_cell_net'] = "555,444"
538 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
539 hostapd
.add_ap(ap
, params
)
542 dev
.add_cred_values({'imsi': "555444-333222111", 'eap': method
,
543 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
544 interworking_select(dev
, bssid
, "home", freq
="2412")
545 interworking_connect(dev
, bssid
, method
)
546 check_sp_type(dev
, "home")
548 def test_ap_hs20_sim(dev
, apdev
):
549 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
550 hlr_auc_gw_available()
551 hs20_simulated_sim(dev
[0], apdev
[0], "SIM")
552 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
553 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
555 raise Exception("Timeout on already-connected event")
557 def test_ap_hs20_sim_invalid(dev
, apdev
):
558 """Hotspot 2.0 with simulated SIM and EAP-SIM - invalid IMSI"""
559 hlr_auc_gw_available()
560 bssid
= apdev
[0]['bssid']
561 params
= hs20_ap_params()
562 params
['hessid'] = bssid
563 params
['anqp_3gpp_cell_net'] = "555,444"
564 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
565 hostapd
.add_ap(apdev
[0], params
)
568 dev
[0].add_cred_values({'imsi': "555444-3332221110", 'eap': "SIM",
569 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
570 # This hits "No valid IMSI available" in build_root_nai()
571 interworking_select(dev
[0], bssid
, freq
="2412")
573 def test_ap_hs20_sim_oom(dev
, apdev
):
574 """Hotspot 2.0 with simulated SIM and EAP-SIM - OOM"""
575 hlr_auc_gw_available()
576 bssid
= apdev
[0]['bssid']
577 params
= hs20_ap_params()
578 params
['hessid'] = bssid
579 params
['anqp_3gpp_cell_net'] = "555,444"
580 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
581 hostapd
.add_ap(apdev
[0], params
)
584 dev
[0].add_cred_values({'imsi': "555444-333222111", 'eap': "SIM",
585 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
586 dev
[0].scan_for_bss(bssid
, freq
=2412)
587 interworking_select(dev
[0], bssid
, freq
="2412")
589 with
alloc_fail(dev
[0], 1, "wpa_config_add_network;interworking_connect_3gpp"):
590 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
591 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
593 with
alloc_fail(dev
[0], 1, "=interworking_connect_3gpp"):
594 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
595 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
597 def test_ap_hs20_aka(dev
, apdev
):
598 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
599 hlr_auc_gw_available()
600 hs20_simulated_sim(dev
[0], apdev
[0], "AKA")
602 def test_ap_hs20_aka_prime(dev
, apdev
):
603 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
604 hlr_auc_gw_available()
605 hs20_simulated_sim(dev
[0], apdev
[0], "AKA'")
607 def test_ap_hs20_ext_sim(dev
, apdev
):
608 """Hotspot 2.0 with external SIM processing"""
609 hlr_auc_gw_available()
610 bssid
= apdev
[0]['bssid']
611 params
= hs20_ap_params()
612 params
['hessid'] = bssid
613 params
['anqp_3gpp_cell_net'] = "232,01"
614 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
615 hostapd
.add_ap(apdev
[0], params
)
619 dev
[0].request("SET external_sim 1")
620 dev
[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM"})
621 interworking_select(dev
[0], bssid
, "home", freq
="2412")
622 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
623 check_sp_type(dev
[0], "home")
625 dev
[0].request("SET external_sim 0")
627 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
628 """Hotspot 2.0 with external SIM processing in roaming network"""
629 hlr_auc_gw_available()
630 bssid
= apdev
[0]['bssid']
631 params
= hs20_ap_params()
632 params
['hessid'] = bssid
633 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
634 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
635 hostapd
.add_ap(apdev
[0], params
)
639 dev
[0].request("SET external_sim 1")
640 dev
[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM"})
641 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
642 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
643 check_sp_type(dev
[0], "roaming")
645 dev
[0].request("SET external_sim 0")
647 def test_ap_hs20_username(dev
, apdev
):
648 """Hotspot 2.0 connection in username/password credential"""
649 check_eap_capa(dev
[0], "MSCHAPV2")
650 bssid
= apdev
[0]['bssid']
651 params
= hs20_ap_params()
652 params
['hessid'] = bssid
653 params
['disable_dgaf'] = '1'
654 hostapd
.add_ap(apdev
[0], params
)
657 id = dev
[0].add_cred_values({'realm': "example.com",
658 'username': "hs20-test",
659 'password': "password",
660 'ca_cert': "auth_serv/ca.pem",
661 'domain': "example.com",
662 'update_identifier': "1234"})
663 interworking_select(dev
[0], bssid
, "home", freq
="2412")
664 interworking_connect(dev
[0], bssid
, "TTLS")
665 check_sp_type(dev
[0], "home")
666 status
= dev
[0].get_status()
667 if status
['pairwise_cipher'] != "CCMP":
668 raise Exception("Unexpected pairwise cipher")
669 if status
['hs20'] != "3":
670 raise Exception("Unexpected HS 2.0 support indication")
672 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
673 identity
="hs20-test", password
="password",
674 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
677 def test_ap_hs20_connect_api(dev
, apdev
):
678 """Hotspot 2.0 connection with connect API"""
679 check_eap_capa(dev
[0], "MSCHAPV2")
680 bssid
= apdev
[0]['bssid']
681 params
= hs20_ap_params()
682 params
['hessid'] = bssid
683 params
['disable_dgaf'] = '1'
684 hostapd
.add_ap(apdev
[0], params
)
686 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
687 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
689 wpas
.flush_scan_cache()
690 id = wpas
.add_cred_values({'realm': "example.com",
691 'username': "hs20-test",
692 'password': "password",
693 'ca_cert': "auth_serv/ca.pem",
694 'domain': "example.com",
695 'update_identifier': "1234"})
696 interworking_select(wpas
, bssid
, "home", freq
="2412")
697 interworking_connect(wpas
, bssid
, "TTLS")
698 check_sp_type(wpas
, "home")
699 status
= wpas
.get_status()
700 if status
['pairwise_cipher'] != "CCMP":
701 raise Exception("Unexpected pairwise cipher")
702 if status
['hs20'] != "3":
703 raise Exception("Unexpected HS 2.0 support indication")
705 def test_ap_hs20_auto_interworking(dev
, apdev
):
706 """Hotspot 2.0 connection with auto_interworking=1"""
707 check_eap_capa(dev
[0], "MSCHAPV2")
708 bssid
= apdev
[0]['bssid']
709 params
= hs20_ap_params()
710 params
['hessid'] = bssid
711 params
['disable_dgaf'] = '1'
712 hostapd
.add_ap(apdev
[0], params
)
714 dev
[0].hs20_enable(auto_interworking
=True)
715 id = dev
[0].add_cred_values({'realm': "example.com",
716 'username': "hs20-test",
717 'password': "password",
718 'ca_cert': "auth_serv/ca.pem",
719 'domain': "example.com",
720 'update_identifier': "1234"})
721 dev
[0].request("REASSOCIATE")
722 dev
[0].wait_connected(timeout
=15)
723 check_sp_type(dev
[0], "home")
724 status
= dev
[0].get_status()
725 if status
['pairwise_cipher'] != "CCMP":
726 raise Exception("Unexpected pairwise cipher")
727 if status
['hs20'] != "3":
728 raise Exception("Unexpected HS 2.0 support indication")
731 def test_ap_hs20_auto_interworking_no_match(dev
, apdev
):
732 """Hotspot 2.0 connection with auto_interworking=1 and no matching network"""
733 hapd
= hostapd
.add_ap(apdev
[0], {"ssid": "mismatch"})
735 dev
[0].hs20_enable(auto_interworking
=True)
736 id = dev
[0].connect("mismatch", psk
="12345678", scan_freq
="2412",
737 only_add_network
=True)
738 dev
[0].request("ENABLE_NETWORK " + str(id) + " no-connect")
740 id = dev
[0].add_cred_values({'realm': "example.com",
741 'username': "hs20-test",
742 'password': "password",
743 'ca_cert': "auth_serv/ca.pem",
744 'domain': "example.com",
745 'update_identifier': "1234"})
746 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
748 dev
[0].dump_monitor()
750 logger
.info("start ping")
751 if "PONG" not in dev
[0].ctrl
.request("PING", timeout
=2):
752 raise Exception("PING failed")
753 logger
.info("ping done")
757 ev
= dev
[0].wait_event(["ANQP fetch completed",
758 "CTRL-EVENT-SCAN-RESULTS"], timeout
=0.05)
761 if "ANQP fetch completed" in ev
:
765 if fetch
> 2 * scan
+ 3:
766 raise Exception("Too many ANQP fetch iterations")
767 dev
[0].dump_monitor()
768 dev
[0].request("DISCONNECT")
771 def test_ap_hs20_auto_interworking_no_cred_match(dev
, apdev
):
772 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
773 bssid
= apdev
[0]['bssid']
774 params
= {"ssid": "test"}
775 hostapd
.add_ap(apdev
[0], params
)
777 dev
[0].hs20_enable(auto_interworking
=True)
778 dev
[0].add_cred_values({'realm': "example.com",
779 'username': "hs20-test",
780 'password': "password",
781 'ca_cert': "auth_serv/ca.pem",
782 'domain': "example.com"})
784 id = dev
[0].connect("test", psk
="12345678", only_add_network
=True)
785 dev
[0].request("ENABLE_NETWORK %s" % id)
786 logger
.info("Verify that scanning continues when there is partial network block match")
787 for i
in range(0, 2):
788 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
790 raise Exception("Scan timed out")
791 logger
.info("Scan completed")
793 def eap_test(dev
, ap
, eap_params
, method
, user
, release
=0):
795 params
= hs20_ap_params()
796 params
['nai_realm'] = ["0,example.com," + eap_params
]
798 params
['hs20_release'] = str(release
)
799 hapd
= hostapd
.add_ap(ap
, params
)
802 dev
.add_cred_values({'realm': "example.com",
803 'ca_cert': "auth_serv/ca.pem",
805 'password': "password"})
806 interworking_select(dev
, bssid
, freq
="2412")
807 interworking_connect(dev
, bssid
, method
)
811 def test_ap_hs20_eap_unknown(dev
, apdev
):
812 """Hotspot 2.0 connection with unknown EAP method"""
813 bssid
= apdev
[0]['bssid']
814 params
= hs20_ap_params()
815 params
['nai_realm'] = "0,example.com,99"
816 hostapd
.add_ap(apdev
[0], params
)
819 dev
[0].add_cred_values(default_cred())
820 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
822 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
823 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
824 check_eap_capa(dev
[0], "MSCHAPV2")
825 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
827 def test_ap_hs20_eap_peap_default(dev
, apdev
):
828 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
829 check_eap_capa(dev
[0], "MSCHAPV2")
830 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
832 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
833 """Hotspot 2.0 connection with PEAP/GTC"""
834 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
837 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
838 """Hotspot 2.0 connection with PEAP/unknown"""
839 bssid
= apdev
[0]['bssid']
840 params
= hs20_ap_params()
841 params
['nai_realm'] = "0,example.com,25[3:99]"
842 hostapd
.add_ap(apdev
[0], params
)
845 dev
[0].add_cred_values(default_cred())
846 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
848 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
849 """Hotspot 2.0 connection with TTLS/CHAP"""
850 skip_with_fips(dev
[0])
851 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
853 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
854 """Hotspot 2.0 connection with TTLS/MSCHAP"""
855 skip_with_fips(dev
[0])
856 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
858 def test_ap_hs20_eap_ttls_default(dev
, apdev
):
859 """Hotspot 2.0 connection with TTLS/default"""
860 skip_with_fips(dev
[0])
861 eap_test(dev
[0], apdev
[0], "21", "TTLS", "hs20-test")
863 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
864 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
865 check_eap_capa(dev
[0], "MSCHAPV2")
866 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
869 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
870 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
871 bssid
= apdev
[0]['bssid']
872 params
= hs20_ap_params()
873 params
['nai_realm'] = "0,example.com,21[3:99]"
874 hostapd
.add_ap(apdev
[0], params
)
877 dev
[0].add_cred_values(default_cred())
878 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
881 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
882 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
883 bssid
= apdev
[0]['bssid']
884 params
= hs20_ap_params()
885 params
['nai_realm'] = "0,example.com,21[3:5]"
886 hostapd
.add_ap(apdev
[0], params
)
889 dev
[0].add_cred_values(default_cred())
890 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
893 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
894 """Hotspot 2.0 connection with TTLS/unknown"""
895 bssid
= apdev
[0]['bssid']
896 params
= hs20_ap_params()
897 params
['nai_realm'] = "0,example.com,21[2:5]"
898 hostapd
.add_ap(apdev
[0], params
)
901 dev
[0].add_cred_values(default_cred())
902 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
904 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
905 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
906 check_eap_capa(dev
[0], "FAST")
907 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
909 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
910 """Hotspot 2.0 connection with FAST/EAP-GTC"""
911 check_eap_capa(dev
[0], "FAST")
912 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
914 def test_ap_hs20_eap_tls(dev
, apdev
):
915 """Hotspot 2.0 connection with EAP-TLS"""
916 bssid
= apdev
[0]['bssid']
917 params
= hs20_ap_params()
918 params
['nai_realm'] = ["0,example.com,13[5:6]"]
919 hostapd
.add_ap(apdev
[0], params
)
921 dev
[0].flush_scan_cache()
923 dev
[0].add_cred_values({'realm': "example.com",
924 'username': "certificate-user",
925 'ca_cert': "auth_serv/ca.pem",
926 'client_cert': "auth_serv/user.pem",
927 'private_key': "auth_serv/user.key"})
928 interworking_select(dev
[0], bssid
, freq
="2412")
929 interworking_connect(dev
[0], bssid
, "TLS")
932 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
933 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
934 bssid
= apdev
[0]['bssid']
935 params
= hs20_ap_params()
936 params
['nai_realm'] = ["0,example.com,99[5:6]"]
937 hostapd
.add_ap(apdev
[0], params
)
940 dev
[0].add_cred_values({'realm': "example.com",
941 'username': "certificate-user",
942 'ca_cert': "auth_serv/ca.pem",
943 'client_cert': "auth_serv/user.pem",
944 'private_key': "auth_serv/user.key"})
945 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
948 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
949 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
950 bssid
= apdev
[0]['bssid']
951 params
= hs20_ap_params()
952 params
['nai_realm'] = ["0,example.com,21[5:6]"]
953 hostapd
.add_ap(apdev
[0], params
)
956 dev
[0].add_cred_values({'realm': "example.com",
957 'username': "certificate-user",
958 'ca_cert': "auth_serv/ca.pem",
959 'client_cert': "auth_serv/user.pem",
960 'private_key': "auth_serv/user.key"})
961 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
964 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
965 """Hotspot 2.0 connection with invalid cred configuration"""
966 bssid
= apdev
[0]['bssid']
967 params
= hs20_ap_params()
968 hostapd
.add_ap(apdev
[0], params
)
971 dev
[0].add_cred_values({'realm': "example.com",
972 'username': "certificate-user",
973 'client_cert': "auth_serv/user.pem"})
974 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
976 def test_ap_hs20_nai_realms(dev
, apdev
):
977 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
978 bssid
= apdev
[0]['bssid']
979 params
= hs20_ap_params()
980 params
['hessid'] = bssid
981 params
['nai_realm'] = ["0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]"]
982 hostapd
.add_ap(apdev
[0], params
)
984 dev
[0].flush_scan_cache()
986 id = dev
[0].add_cred_values({'realm': "example.com",
987 'ca_cert': "auth_serv/ca.pem",
988 'username': "pap user",
989 'password': "password",
990 'domain': "example.com"})
991 interworking_select(dev
[0], bssid
, "home", freq
="2412")
992 interworking_connect(dev
[0], bssid
, "TTLS")
993 check_sp_type(dev
[0], "home")
995 def test_ap_hs20_roaming_consortium(dev
, apdev
):
996 """Hotspot 2.0 connection based on roaming consortium match"""
997 bssid
= apdev
[0]['bssid']
998 params
= hs20_ap_params()
999 params
['hessid'] = bssid
1000 hostapd
.add_ap(apdev
[0], params
)
1002 dev
[0].flush_scan_cache()
1003 dev
[0].hs20_enable()
1004 for consortium
in ["112233", "1020304050", "010203040506", "fedcba"]:
1005 id = dev
[0].add_cred_values({'username': "user",
1006 'password': "password",
1007 'domain': "example.com",
1008 'ca_cert': "auth_serv/ca.pem",
1009 'roaming_consortium': consortium
,
1011 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1012 interworking_connect(dev
[0], bssid
, "PEAP")
1013 check_sp_type(dev
[0], "home")
1014 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1015 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
1017 raise Exception("Timeout on already-connected event")
1018 dev
[0].remove_cred(id)
1020 def test_ap_hs20_roaming_consortiums_match(dev
, apdev
):
1021 """Hotspot 2.0 connection based on roaming_consortiums match"""
1022 bssid
= apdev
[0]['bssid']
1023 params
= hs20_ap_params()
1024 params
['hessid'] = bssid
1025 hostapd
.add_ap(apdev
[0], params
)
1027 dev
[0].flush_scan_cache()
1028 dev
[0].hs20_enable()
1029 tests
= [("112233", "112233"),
1030 ("ffffff,1020304050,eeeeee", "1020304050")]
1031 for consortium
, selected
in tests
:
1032 id = dev
[0].add_cred_values({'username': "user",
1033 'password': "password",
1034 'domain': "my.home.example.com",
1035 'ca_cert': "auth_serv/ca.pem",
1036 'roaming_consortiums': consortium
,
1038 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1039 interworking_connect(dev
[0], bssid
, "PEAP")
1040 check_sp_type(dev
[0], "roaming")
1041 network_id
= dev
[0].get_status_field("id")
1042 sel
= dev
[0].get_network(network_id
, "roaming_consortium_selection")
1044 raise Exception("Unexpected roaming_consortium_selection value: " +
1046 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1047 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
1049 raise Exception("Timeout on already-connected event")
1050 dev
[0].remove_cred(id)
1052 def test_ap_hs20_max_roaming_consortiums(dev
, apdev
):
1053 """Maximum number of cred roaming_consortiums"""
1054 id = dev
[0].add_cred()
1055 consortium
= (36*",ffffff")[1:]
1056 if "OK" not in dev
[0].request('SET_CRED %d roaming_consortiums "%s"' % (id, consortium
)):
1057 raise Exception("Maximum number of consortium OIs rejected")
1058 consortium
= (37*",ffffff")[1:]
1059 if "FAIL" not in dev
[0].request('SET_CRED %d roaming_consortiums "%s"' % (id, consortium
)):
1060 raise Exception("Over maximum number of consortium OIs accepted")
1061 dev
[0].remove_cred(id)
1063 def test_ap_hs20_roaming_consortium_invalid(dev
, apdev
):
1064 """Hotspot 2.0 connection and invalid roaming consortium ANQP-element"""
1065 bssid
= apdev
[0]['bssid']
1066 params
= hs20_ap_params()
1067 params
['hessid'] = bssid
1068 # Override Roaming Consortium ANQP-element with an incorrectly encoded
1070 params
['anqp_elem'] = "261:04fedcba"
1071 hostapd
.add_ap(apdev
[0], params
)
1073 dev
[0].hs20_enable()
1074 id = dev
[0].add_cred_values({'username': "user",
1075 'password': "password",
1076 'domain': "example.com",
1077 'ca_cert': "auth_serv/ca.pem",
1078 'roaming_consortium': "fedcba",
1080 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1082 def test_ap_hs20_roaming_consortium_element(dev
, apdev
):
1083 """Hotspot 2.0 connection and invalid roaming consortium element"""
1084 bssid
= apdev
[0]['bssid']
1085 params
= hs20_ap_params()
1086 params
['hessid'] = bssid
1087 del params
['roaming_consortium']
1088 params
['vendor_elements'] = '6f00'
1089 hapd
= hostapd
.add_ap(apdev
[0], params
)
1091 dev
[0].hs20_enable()
1092 dev
[0].scan_for_bss(bssid
, freq
="2412")
1093 id = dev
[0].add_cred_values({'username': "user",
1094 'password': "password",
1095 'domain': "example.com",
1096 'ca_cert': "auth_serv/ca.pem",
1097 'roaming_consortium': "112233",
1099 interworking_select(dev
[0], bssid
, freq
="2412", no_match
=True)
1101 hapd
.set('vendor_elements', '6f020001')
1102 if "OK" not in hapd
.request("UPDATE_BEACON"):
1103 raise Exception("UPDATE_BEACON failed")
1104 dev
[0].request("BSS_FLUSH 0")
1105 dev
[0].scan_for_bss(bssid
, freq
="2412", force_scan
=True)
1106 interworking_select(dev
[0], bssid
, freq
="2412", no_match
=True)
1108 def test_ap_hs20_roaming_consortium_constraints(dev
, apdev
):
1109 """Hotspot 2.0 connection and roaming consortium constraints"""
1110 bssid
= apdev
[0]['bssid']
1111 params
= hs20_ap_params()
1112 params
['hessid'] = bssid
1113 params
['bss_load_test'] = "12:200:20000"
1114 hostapd
.add_ap(apdev
[0], params
)
1116 dev
[0].hs20_enable()
1118 vals
= {'username': "user",
1119 'password': "password",
1120 'domain': "example.com",
1121 'ca_cert': "auth_serv/ca.pem",
1122 'roaming_consortium': "fedcba",
1125 vals2
['required_roaming_consortium'] = "223344"
1126 id = dev
[0].add_cred_values(vals2
)
1127 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1128 dev
[0].remove_cred(id)
1131 vals2
['min_dl_bandwidth_home'] = "65500"
1132 id = dev
[0].add_cred_values(vals2
)
1133 dev
[0].request("INTERWORKING_SELECT freq=2412")
1134 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1136 raise Exception("No AP found")
1137 if "below_min_backhaul=1" not in ev
:
1138 raise Exception("below_min_backhaul not reported")
1139 dev
[0].remove_cred(id)
1142 vals2
['max_bss_load'] = "100"
1143 id = dev
[0].add_cred_values(vals2
)
1144 dev
[0].request("INTERWORKING_SELECT freq=2412")
1145 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1147 raise Exception("No AP found")
1148 if "over_max_bss_load=1" not in ev
:
1149 raise Exception("over_max_bss_load not reported")
1150 dev
[0].remove_cred(id)
1153 vals2
['req_conn_capab'] = "6:1234"
1154 vals2
['domain'] = 'example.org'
1155 id = dev
[0].add_cred_values(vals2
)
1157 dev
[0].request("INTERWORKING_SELECT freq=2412")
1158 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1160 raise Exception("No AP found")
1161 if "conn_capab_missing=1" not in ev
:
1162 raise Exception("conn_capab_missing not reported")
1163 dev
[0].remove_cred(id)
1165 values
= default_cred()
1166 values
['roaming_consortium'] = "fedcba"
1167 id3
= dev
[0].add_cred_values(values
)
1170 vals2
['roaming_consortium'] = "fedcba"
1171 vals2
['priority'] = "2"
1172 id = dev
[0].add_cred_values(vals2
)
1174 values
= default_cred()
1175 values
['roaming_consortium'] = "fedcba"
1176 id2
= dev
[0].add_cred_values(values
)
1178 dev
[0].request("INTERWORKING_SELECT freq=2412")
1179 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1181 raise Exception("No AP found")
1182 dev
[0].remove_cred(id)
1183 dev
[0].remove_cred(id2
)
1184 dev
[0].remove_cred(id3
)
1186 def test_ap_hs20_3gpp_constraints(dev
, apdev
):
1187 """Hotspot 2.0 connection and 3GPP credential constraints"""
1188 bssid
= apdev
[0]['bssid']
1189 params
= hs20_ap_params()
1190 params
['hessid'] = bssid
1191 params
['anqp_3gpp_cell_net'] = "555,444"
1192 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1193 params
['bss_load_test'] = "12:200:20000"
1194 hapd
= hostapd
.add_ap(apdev
[0], params
)
1196 dev
[0].hs20_enable()
1198 vals
= {'imsi': "555444-333222111",
1200 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"}
1202 vals2
['required_roaming_consortium'] = "223344"
1203 id = dev
[0].add_cred_values(vals2
)
1204 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1205 dev
[0].remove_cred(id)
1208 vals2
['min_dl_bandwidth_home'] = "65500"
1209 id = dev
[0].add_cred_values(vals2
)
1210 dev
[0].request("INTERWORKING_SELECT freq=2412")
1211 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1213 raise Exception("No AP found")
1214 if "below_min_backhaul=1" not in ev
:
1215 raise Exception("below_min_backhaul not reported")
1216 dev
[0].remove_cred(id)
1219 vals2
['max_bss_load'] = "100"
1220 id = dev
[0].add_cred_values(vals2
)
1221 dev
[0].request("INTERWORKING_SELECT freq=2412")
1222 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1224 raise Exception("No AP found")
1225 if "over_max_bss_load=1" not in ev
:
1226 raise Exception("over_max_bss_load not reported")
1227 dev
[0].remove_cred(id)
1229 values
= default_cred()
1230 values
['roaming_consortium'] = "fedcba"
1231 id3
= dev
[0].add_cred_values(values
)
1234 vals2
['roaming_consortium'] = "fedcba"
1235 vals2
['priority'] = "2"
1236 id = dev
[0].add_cred_values(vals2
)
1238 values
= default_cred()
1239 values
['roaming_consortium'] = "fedcba"
1240 id2
= dev
[0].add_cred_values(values
)
1242 dev
[0].request("INTERWORKING_SELECT freq=2412")
1243 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1245 raise Exception("No AP found")
1246 dev
[0].remove_cred(id)
1247 dev
[0].remove_cred(id2
)
1248 dev
[0].remove_cred(id3
)
1251 params
= hs20_ap_params()
1252 params
['hessid'] = bssid
1253 params
['anqp_3gpp_cell_net'] = "555,444"
1254 params
['bss_load_test'] = "12:200:20000"
1255 hapd
= hostapd
.add_ap(apdev
[0], params
)
1257 vals2
['req_conn_capab'] = "6:1234"
1258 id = dev
[0].add_cred_values(vals2
)
1259 dev
[0].request("INTERWORKING_SELECT freq=2412")
1260 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1262 raise Exception("No AP found")
1263 if "conn_capab_missing=1" not in ev
:
1264 raise Exception("conn_capab_missing not reported")
1265 dev
[0].remove_cred(id)
1267 def test_ap_hs20_connect_no_full_match(dev
, apdev
):
1268 """Hotspot 2.0 connection and no full match"""
1269 bssid
= apdev
[0]['bssid']
1270 params
= hs20_ap_params()
1271 params
['hessid'] = bssid
1272 params
['anqp_3gpp_cell_net'] = "555,444"
1273 hostapd
.add_ap(apdev
[0], params
)
1275 dev
[0].hs20_enable()
1277 vals
= {'username': "user",
1278 'password': "password",
1279 'domain': "example.com",
1280 'ca_cert': "auth_serv/ca.pem",
1281 'roaming_consortium': "fedcba",
1283 'min_dl_bandwidth_home': "65500"}
1284 id = dev
[0].add_cred_values(vals
)
1285 dev
[0].request("INTERWORKING_SELECT freq=2412")
1286 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1288 raise Exception("No AP found")
1289 if "below_min_backhaul=1" not in ev
:
1290 raise Exception("below_min_backhaul not reported")
1291 interworking_connect(dev
[0], bssid
, "TTLS")
1292 dev
[0].remove_cred(id)
1293 dev
[0].wait_disconnected()
1295 vals
= {'imsi': "555444-333222111", 'eap': "SIM",
1296 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1297 'min_dl_bandwidth_roaming': "65500"}
1298 id = dev
[0].add_cred_values(vals
)
1299 dev
[0].request("INTERWORKING_SELECT freq=2412")
1300 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1302 raise Exception("No AP found")
1303 if "below_min_backhaul=1" not in ev
:
1304 raise Exception("below_min_backhaul not reported")
1305 interworking_connect(dev
[0], bssid
, "SIM")
1306 dev
[0].remove_cred(id)
1307 dev
[0].wait_disconnected()
1309 def test_ap_hs20_username_roaming(dev
, apdev
):
1310 """Hotspot 2.0 connection in username/password credential (roaming)"""
1311 check_eap_capa(dev
[0], "MSCHAPV2")
1312 bssid
= apdev
[0]['bssid']
1313 params
= hs20_ap_params()
1314 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]",
1315 "0,roaming.example.com,21[2:4][5:7]",
1316 "0,another.example.com"]
1317 params
['domain_name'] = "another.example.com"
1318 params
['hessid'] = bssid
1319 hostapd
.add_ap(apdev
[0], params
)
1321 dev
[0].hs20_enable()
1322 id = dev
[0].add_cred_values({'realm': "roaming.example.com",
1323 'username': "hs20-test",
1324 'password': "password",
1325 'ca_cert': "auth_serv/ca.pem",
1326 'domain': "example.com"})
1327 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1328 interworking_connect(dev
[0], bssid
, "TTLS")
1329 check_sp_type(dev
[0], "roaming")
1331 def test_ap_hs20_username_unknown(dev
, apdev
):
1332 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
1333 check_eap_capa(dev
[0], "MSCHAPV2")
1334 bssid
= apdev
[0]['bssid']
1335 params
= hs20_ap_params()
1336 params
['hessid'] = bssid
1337 hostapd
.add_ap(apdev
[0], params
)
1339 dev
[0].hs20_enable()
1340 id = dev
[0].add_cred_values({'realm': "example.com",
1341 'ca_cert': "auth_serv/ca.pem",
1342 'username': "hs20-test",
1343 'password': "password"})
1344 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
1345 interworking_connect(dev
[0], bssid
, "TTLS")
1346 check_sp_type(dev
[0], "unknown")
1348 def test_ap_hs20_username_unknown2(dev
, apdev
):
1349 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
1350 check_eap_capa(dev
[0], "MSCHAPV2")
1351 bssid
= apdev
[0]['bssid']
1352 params
= hs20_ap_params()
1353 params
['hessid'] = bssid
1354 del params
['domain_name']
1355 hostapd
.add_ap(apdev
[0], params
)
1357 dev
[0].hs20_enable()
1358 id = dev
[0].add_cred_values({'realm': "example.com",
1359 'ca_cert': "auth_serv/ca.pem",
1360 'username': "hs20-test",
1361 'password': "password",
1362 'domain': "example.com"})
1363 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
1364 interworking_connect(dev
[0], bssid
, "TTLS")
1365 check_sp_type(dev
[0], "unknown")
1367 def test_ap_hs20_gas_while_associated(dev
, apdev
):
1368 """Hotspot 2.0 connection with GAS query while associated"""
1369 check_eap_capa(dev
[0], "MSCHAPV2")
1370 bssid
= apdev
[0]['bssid']
1371 params
= hs20_ap_params()
1372 params
['hessid'] = bssid
1373 hostapd
.add_ap(apdev
[0], params
)
1375 dev
[0].hs20_enable()
1376 id = dev
[0].add_cred_values({'realm': "example.com",
1377 'ca_cert': "auth_serv/ca.pem",
1378 'username': "hs20-test",
1379 'password': "password",
1380 'domain': "example.com"})
1381 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1382 interworking_connect(dev
[0], bssid
, "TTLS")
1384 logger
.info("Verifying GAS query while associated")
1385 dev
[0].request("FETCH_ANQP")
1386 for i
in range(0, 6):
1387 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1389 raise Exception("Operation timed out")
1391 def test_ap_hs20_gas_with_another_ap_while_associated(dev
, apdev
):
1392 """GAS query with another AP while associated"""
1393 check_eap_capa(dev
[0], "MSCHAPV2")
1394 bssid
= apdev
[0]['bssid']
1395 params
= hs20_ap_params()
1396 params
['hessid'] = bssid
1397 hostapd
.add_ap(apdev
[0], params
)
1399 bssid2
= apdev
[1]['bssid']
1400 params
= hs20_ap_params()
1401 params
['hessid'] = bssid2
1402 params
['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"]
1403 hostapd
.add_ap(apdev
[1], params
)
1405 dev
[0].hs20_enable()
1406 id = dev
[0].add_cred_values({'realm': "example.com",
1407 'ca_cert': "auth_serv/ca.pem",
1408 'username': "hs20-test",
1409 'password': "password",
1410 'domain': "example.com"})
1411 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1412 interworking_connect(dev
[0], bssid
, "TTLS")
1413 dev
[0].dump_monitor()
1415 logger
.info("Verifying GAS query with same AP while associated")
1416 dev
[0].request("ANQP_GET " + bssid
+ " 263")
1417 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1419 raise Exception("ANQP operation timed out")
1420 dev
[0].dump_monitor()
1422 logger
.info("Verifying GAS query with another AP while associated")
1423 dev
[0].scan_for_bss(bssid2
, 2412)
1424 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
1425 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1427 raise Exception("ANQP operation timed out")
1429 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
1430 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
1431 check_eap_capa(dev
[0], "MSCHAPV2")
1433 _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
)
1435 dev
[0].request("SET pmf 0")
1437 def _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
1438 bssid
= apdev
[0]['bssid']
1439 params
= hs20_ap_params()
1440 params
['hessid'] = bssid
1441 hostapd
.add_ap(apdev
[0], params
)
1443 bssid2
= apdev
[1]['bssid']
1444 params
= hs20_ap_params()
1445 params
['hessid'] = bssid2
1446 params
['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"]
1447 hostapd
.add_ap(apdev
[1], params
)
1449 dev
[0].flush_scan_cache()
1450 dev
[0].hs20_enable()
1451 dev
[0].request("SET pmf 2")
1452 id = dev
[0].add_cred_values({'realm': "example.com",
1453 'ca_cert': "auth_serv/ca.pem",
1454 'username': "hs20-test",
1455 'password': "password",
1456 'domain': "example.com"})
1457 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1458 interworking_connect(dev
[0], bssid
, "TTLS")
1460 logger
.info("Verifying GAS query while associated")
1461 dev
[0].request("FETCH_ANQP")
1462 for i
in range(0, 2 * 6):
1463 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1465 raise Exception("Operation timed out")
1467 def test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1468 """GAS query with another AP while associated and using PMF"""
1469 check_eap_capa(dev
[0], "MSCHAPV2")
1471 _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
)
1473 dev
[0].request("SET pmf 0")
1475 def _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1476 bssid
= apdev
[0]['bssid']
1477 params
= hs20_ap_params()
1478 params
['hessid'] = bssid
1479 hapd
= hostapd
.add_ap(apdev
[0], params
)
1481 bssid2
= apdev
[1]['bssid']
1482 params
= hs20_ap_params()
1483 params
['hessid'] = bssid2
1484 params
['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"]
1485 hostapd
.add_ap(apdev
[1], params
)
1487 dev
[0].hs20_enable()
1488 dev
[0].request("SET pmf 2")
1489 id = dev
[0].add_cred_values({'realm': "example.com",
1490 'ca_cert': "auth_serv/ca.pem",
1491 'username': "hs20-test",
1492 'password': "password",
1493 'domain': "example.com"})
1494 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1495 interworking_connect(dev
[0], bssid
, "TTLS")
1496 dev
[0].dump_monitor()
1499 logger
.info("Verifying GAS query with same AP while associated")
1500 dev
[0].request("ANQP_GET " + bssid
+ " 263")
1501 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1503 raise Exception("ANQP operation timed out")
1504 dev
[0].dump_monitor()
1506 logger
.info("Verifying GAS query with another AP while associated")
1507 dev
[0].scan_for_bss(bssid2
, 2412)
1508 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
1509 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1511 raise Exception("ANQP operation timed out")
1513 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
1514 """Hotspot 2.0 connection with fragmented GAS query while associated"""
1515 check_eap_capa(dev
[0], "MSCHAPV2")
1516 bssid
= apdev
[0]['bssid']
1517 params
= hs20_ap_params()
1518 params
['hessid'] = bssid
1519 hapd
= hostapd
.add_ap(apdev
[0], params
)
1520 hapd
.set("gas_frag_limit", "50")
1522 dev
[0].hs20_enable()
1523 id = dev
[0].add_cred_values({'realm': "example.com",
1524 'ca_cert': "auth_serv/ca.pem",
1525 'username': "hs20-test",
1526 'password': "password",
1527 'domain': "example.com"})
1528 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1529 interworking_connect(dev
[0], bssid
, "TTLS")
1532 logger
.info("Verifying GAS query while associated")
1533 dev
[0].request("FETCH_ANQP")
1534 for i
in range(0, 6):
1535 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1537 raise Exception("Operation timed out")
1539 def test_ap_hs20_multiple_connects(dev
, apdev
):
1540 """Hotspot 2.0 connection through multiple network selections"""
1541 check_eap_capa(dev
[0], "MSCHAPV2")
1542 bssid
= apdev
[0]['bssid']
1543 params
= hs20_ap_params()
1544 params
['hessid'] = bssid
1545 hostapd
.add_ap(apdev
[0], params
)
1547 dev
[0].hs20_enable()
1548 values
= {'realm': "example.com",
1549 'ca_cert': "auth_serv/ca.pem",
1550 'username': "hs20-test",
1551 'password': "password",
1552 'domain': "example.com"}
1553 id = dev
[0].add_cred_values(values
)
1555 dev
[0].scan_for_bss(bssid
, freq
="2412")
1557 for i
in range(0, 3):
1558 logger
.info("Starting Interworking network selection")
1559 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1561 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1562 "INTERWORKING-ALREADY-CONNECTED",
1563 "CTRL-EVENT-CONNECTED"], timeout
=15)
1565 raise Exception("Connection timed out")
1566 if "INTERWORKING-NO-MATCH" in ev
:
1567 raise Exception("Matching AP not found")
1568 if "CTRL-EVENT-CONNECTED" in ev
:
1570 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
1573 dev
[0].request("DISCONNECT")
1574 dev
[0].dump_monitor()
1576 networks
= dev
[0].list_networks()
1577 if len(networks
) > 1:
1578 raise Exception("Duplicated network block detected")
1580 def test_ap_hs20_disallow_aps(dev
, apdev
):
1581 """Hotspot 2.0 connection and disallow_aps"""
1582 bssid
= apdev
[0]['bssid']
1583 params
= hs20_ap_params()
1584 params
['hessid'] = bssid
1585 hostapd
.add_ap(apdev
[0], params
)
1587 dev
[0].hs20_enable()
1588 values
= {'realm': "example.com",
1589 'ca_cert': "auth_serv/ca.pem",
1590 'username': "hs20-test",
1591 'password': "password",
1592 'domain': "example.com"}
1593 id = dev
[0].add_cred_values(values
)
1595 dev
[0].scan_for_bss(bssid
, freq
="2412")
1597 logger
.info("Verify disallow_aps bssid")
1598 dev
[0].request("SET disallow_aps bssid " + bssid
.replace(':', ''))
1599 dev
[0].request("INTERWORKING_SELECT auto")
1600 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1602 raise Exception("Network selection timed out")
1603 dev
[0].dump_monitor()
1605 logger
.info("Verify disallow_aps ssid")
1606 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
1607 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1608 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1610 raise Exception("Network selection timed out")
1611 dev
[0].dump_monitor()
1613 logger
.info("Verify disallow_aps clear")
1614 dev
[0].request("SET disallow_aps ")
1615 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1617 dev
[0].request("SET disallow_aps bssid " + bssid
.replace(':', ''))
1618 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1619 if "FAIL" not in ret
:
1620 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
1622 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
1623 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1624 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
1625 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1627 def policy_test(dev
, ap
, values
, only_one
=True):
1630 logger
.info("Verify network selection to AP " + ap
['ifname'])
1632 dev
.scan_for_bss(bssid
, freq
="2412")
1634 logger
.info("Verify network selection")
1637 id = dev
.add_cred_values(values
)
1638 dev
.request("INTERWORKING_SELECT auto freq=2412")
1641 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1642 "INTERWORKING-BLACKLISTED",
1643 "INTERWORKING-SELECTED"], timeout
=15)
1645 raise Exception("Network selection timed out")
1647 if "INTERWORKING-NO-MATCH" in ev
:
1648 raise Exception("Matching AP not found")
1649 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1650 raise Exception("Unexpected AP claimed acceptable")
1651 if "INTERWORKING-SELECTED" in ev
:
1652 if bssid
and bssid
not in ev
:
1653 raise Exception("Selected incorrect BSS")
1656 ev
= dev
.wait_connected(timeout
=15)
1657 if bssid
and bssid
not in ev
:
1658 raise Exception("Connected to incorrect BSS")
1660 conn_bssid
= dev
.get_status_field("bssid")
1661 if bssid
and conn_bssid
!= bssid
:
1662 raise Exception("bssid information points to incorrect BSS")
1668 def default_cred(domain
=None, user
="hs20-test"):
1669 cred
= {'realm': "example.com",
1670 'ca_cert': "auth_serv/ca.pem",
1672 'password': "password"}
1674 cred
['domain'] = domain
1677 def test_ap_hs20_prefer_home(dev
, apdev
):
1678 """Hotspot 2.0 required roaming consortium"""
1679 check_eap_capa(dev
[0], "MSCHAPV2")
1680 params
= hs20_ap_params()
1681 params
['domain_name'] = "example.org"
1682 hostapd
.add_ap(apdev
[0], params
)
1684 params
= hs20_ap_params()
1685 params
['ssid'] = "test-hs20-other"
1686 params
['domain_name'] = "example.com"
1687 hostapd
.add_ap(apdev
[1], params
)
1689 values
= default_cred()
1690 values
['domain'] = "example.com"
1691 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1692 values
['domain'] = "example.org"
1693 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1695 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1696 """Hotspot 2.0 required roaming consortium"""
1697 check_eap_capa(dev
[0], "MSCHAPV2")
1698 params
= hs20_ap_params()
1699 hostapd
.add_ap(apdev
[0], params
)
1701 params
= hs20_ap_params()
1702 params
['ssid'] = "test-hs20-other"
1703 params
['roaming_consortium'] = ["223344"]
1704 hostapd
.add_ap(apdev
[1], params
)
1706 values
= default_cred()
1707 values
['required_roaming_consortium'] = "223344"
1708 policy_test(dev
[0], apdev
[1], values
)
1709 values
['required_roaming_consortium'] = "112233"
1710 policy_test(dev
[0], apdev
[0], values
)
1712 id = dev
[0].add_cred()
1713 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1714 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1716 for val
in ["", "1", "11", "1122", "1122334",
1717 "112233445566778899aabbccddeeff00"]:
1718 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1719 raise Exception("Invalid roaming consortium value accepted: " + val
)
1721 def test_ap_hs20_req_roaming_consortium_no_match(dev
, apdev
):
1722 """Hotspot 2.0 required roaming consortium and no match"""
1723 check_eap_capa(dev
[0], "MSCHAPV2")
1724 params
= hs20_ap_params()
1725 del params
['roaming_consortium']
1726 hostapd
.add_ap(apdev
[0], params
)
1728 params
= hs20_ap_params()
1729 params
['ssid'] = "test-hs20-other"
1730 params
['roaming_consortium'] = ["223345"]
1731 hostapd
.add_ap(apdev
[1], params
)
1733 values
= default_cred()
1734 values
['required_roaming_consortium'] = "223344"
1735 dev
[0].hs20_enable()
1736 id = dev
[0].add_cred_values(values
)
1737 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1738 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=10)
1740 raise Exception("INTERWORKING-NO-MATCH not reported")
1742 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1743 """Hotspot 2.0 exclusion based on SSID"""
1744 check_eap_capa(dev
[0], "MSCHAPV2")
1745 params
= hs20_ap_params()
1746 params
['roaming_consortium'] = ["223344"]
1747 params
['anqp_3gpp_cell_net'] = "555,444"
1748 hostapd
.add_ap(apdev
[0], params
)
1750 params
= hs20_ap_params()
1751 params
['ssid'] = "test-hs20-other"
1752 params
['roaming_consortium'] = ["223344"]
1753 params
['anqp_3gpp_cell_net'] = "555,444"
1754 hostapd
.add_ap(apdev
[1], params
)
1756 values
= default_cred()
1757 values
['excluded_ssid'] = "test-hs20"
1758 events
= policy_test(dev
[0], apdev
[1], values
)
1759 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1761 raise Exception("Excluded network not reported")
1762 values
['excluded_ssid'] = "test-hs20-other"
1763 events
= policy_test(dev
[0], apdev
[0], values
)
1764 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1766 raise Exception("Excluded network not reported")
1768 values
= default_cred()
1769 values
['roaming_consortium'] = "223344"
1770 values
['eap'] = "TTLS"
1771 values
['phase2'] = "auth=MSCHAPV2"
1772 values
['excluded_ssid'] = "test-hs20"
1773 events
= policy_test(dev
[0], apdev
[1], values
)
1774 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1776 raise Exception("Excluded network not reported")
1778 values
= {'imsi': "555444-333222111", 'eap': "SIM",
1779 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1780 'excluded_ssid': "test-hs20"}
1781 events
= policy_test(dev
[0], apdev
[1], values
)
1782 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1784 raise Exception("Excluded network not reported")
1786 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1787 """Hotspot 2.0 and roaming from current to higher priority network"""
1788 check_eap_capa(dev
[0], "MSCHAPV2")
1789 bssid
= apdev
[0]['bssid']
1790 params
= hs20_ap_params(ssid
="test-hs20-visited")
1791 params
['domain_name'] = "visited.example.org"
1792 hostapd
.add_ap(apdev
[0], params
)
1794 dev
[0].hs20_enable()
1795 id = dev
[0].add_cred_values({'realm': "example.com",
1796 'ca_cert': "auth_serv/ca.pem",
1797 'username': "hs20-test",
1798 'password': "password",
1799 'domain': "example.com"})
1800 logger
.info("Connect to the only network option")
1801 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1802 dev
[0].dump_monitor()
1803 interworking_connect(dev
[0], bssid
, "TTLS")
1805 logger
.info("Start another AP (home operator) and reconnect")
1806 bssid2
= apdev
[1]['bssid']
1807 params
= hs20_ap_params(ssid
="test-hs20-home")
1808 params
['domain_name'] = "example.com"
1809 hostapd
.add_ap(apdev
[1], params
)
1811 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1812 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1813 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1814 "INTERWORKING-ALREADY-CONNECTED",
1815 "CTRL-EVENT-CONNECTED"], timeout
=15)
1817 raise Exception("Connection timed out")
1818 if "INTERWORKING-NO-MATCH" in ev
:
1819 raise Exception("Matching AP not found")
1820 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1821 raise Exception("Unexpected AP selected")
1822 if bssid2
not in ev
:
1823 raise Exception("Unexpected BSSID after reconnection")
1825 def test_ap_hs20_domain_suffix_match_full(dev
, apdev
):
1826 """Hotspot 2.0 and domain_suffix_match"""
1827 check_domain_match_full(dev
[0])
1828 check_eap_capa(dev
[0], "MSCHAPV2")
1829 bssid
= apdev
[0]['bssid']
1830 params
= hs20_ap_params()
1831 hostapd
.add_ap(apdev
[0], params
)
1833 dev
[0].hs20_enable()
1834 id = dev
[0].add_cred_values({'realm': "example.com",
1835 'username': "hs20-test",
1836 'password': "password",
1837 'ca_cert': "auth_serv/ca.pem",
1838 'domain': "example.com",
1839 'domain_suffix_match': "server.w1.fi"})
1840 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1841 dev
[0].dump_monitor()
1842 interworking_connect(dev
[0], bssid
, "TTLS")
1843 dev
[0].request("REMOVE_NETWORK all")
1844 dev
[0].dump_monitor()
1846 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1847 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1848 dev
[0].dump_monitor()
1849 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1850 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1852 raise Exception("TLS certificate error not reported")
1853 if "Domain suffix mismatch" not in ev
:
1854 raise Exception("Domain suffix mismatch not reported")
1856 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1857 """Hotspot 2.0 and domain_suffix_match"""
1858 check_eap_capa(dev
[0], "MSCHAPV2")
1859 check_domain_match_full(dev
[0])
1860 bssid
= apdev
[0]['bssid']
1861 params
= hs20_ap_params()
1862 hostapd
.add_ap(apdev
[0], params
)
1864 dev
[0].hs20_enable()
1865 id = dev
[0].add_cred_values({'realm': "example.com",
1866 'username': "hs20-test",
1867 'password': "password",
1868 'ca_cert': "auth_serv/ca.pem",
1869 'domain': "example.com",
1870 'domain_suffix_match': "w1.fi"})
1871 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1872 dev
[0].dump_monitor()
1873 interworking_connect(dev
[0], bssid
, "TTLS")
1875 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1876 """Hotspot 2.0 and roaming partner preference"""
1877 check_eap_capa(dev
[0], "MSCHAPV2")
1878 params
= hs20_ap_params()
1879 params
['domain_name'] = "roaming.example.org"
1880 hostapd
.add_ap(apdev
[0], params
)
1882 params
= hs20_ap_params()
1883 params
['ssid'] = "test-hs20-other"
1884 params
['domain_name'] = "roaming.example.net"
1885 hostapd
.add_ap(apdev
[1], params
)
1887 logger
.info("Verify default vs. specified preference")
1888 values
= default_cred()
1889 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1890 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1891 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1892 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1894 logger
.info("Verify partial FQDN match")
1895 values
['roaming_partner'] = "example.net,0,0,*"
1896 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1897 values
['roaming_partner'] = "example.net,0,255,*"
1898 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1900 def test_ap_hs20_max_bss_load(dev
, apdev
):
1901 """Hotspot 2.0 and maximum BSS load"""
1902 check_eap_capa(dev
[0], "MSCHAPV2")
1903 params
= hs20_ap_params()
1904 params
['bss_load_test'] = "12:200:20000"
1905 hostapd
.add_ap(apdev
[0], params
)
1907 params
= hs20_ap_params()
1908 params
['ssid'] = "test-hs20-other"
1909 params
['bss_load_test'] = "5:20:10000"
1910 hostapd
.add_ap(apdev
[1], params
)
1912 logger
.info("Verify maximum BSS load constraint")
1913 values
= default_cred()
1914 values
['domain'] = "example.com"
1915 values
['max_bss_load'] = "100"
1916 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1918 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1919 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1920 raise Exception("Maximum BSS Load case not noticed")
1921 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1922 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1923 raise Exception("Maximum BSS Load case reported incorrectly")
1925 logger
.info("Verify maximum BSS load does not prevent connection")
1926 values
['max_bss_load'] = "1"
1927 events
= policy_test(dev
[0], None, values
)
1929 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1930 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1931 raise Exception("Maximum BSS Load case not noticed")
1932 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1933 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1934 raise Exception("Maximum BSS Load case not noticed")
1936 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1937 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1938 check_eap_capa(dev
[0], "MSCHAPV2")
1939 params
= hs20_ap_params()
1940 params
['bss_load_test'] = "12:200:20000"
1941 hostapd
.add_ap(apdev
[0], params
)
1943 params
= hs20_ap_params()
1944 params
['ssid'] = "test-hs20-other"
1945 hostapd
.add_ap(apdev
[1], params
)
1947 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1948 values
= default_cred()
1949 values
['domain'] = "example.com"
1950 values
['max_bss_load'] = "100"
1951 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1953 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1954 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1955 raise Exception("Maximum BSS Load case not noticed")
1956 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1957 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1958 raise Exception("Maximum BSS Load case reported incorrectly")
1960 def test_ap_hs20_max_bss_load_roaming(dev
, apdev
):
1961 """Hotspot 2.0 and maximum BSS load (roaming)"""
1962 check_eap_capa(dev
[0], "MSCHAPV2")
1963 params
= hs20_ap_params()
1964 params
['bss_load_test'] = "12:200:20000"
1965 hostapd
.add_ap(apdev
[0], params
)
1967 values
= default_cred()
1968 values
['domain'] = "roaming.example.com"
1969 values
['max_bss_load'] = "100"
1970 events
= policy_test(dev
[0], apdev
[0], values
, only_one
=True)
1971 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1973 raise Exception("No INTERWORKING-AP event")
1974 if "over_max_bss_load=1" in ev
[0]:
1975 raise Exception("Maximum BSS Load reported for roaming")
1977 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1978 """Hotspot 2.0 multi-cred sp_priority"""
1979 check_eap_capa(dev
[0], "MSCHAPV2")
1981 _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1983 dev
[0].request("SET external_sim 0")
1985 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1986 hlr_auc_gw_available()
1987 bssid
= apdev
[0]['bssid']
1988 params
= hs20_ap_params()
1989 params
['hessid'] = bssid
1990 del params
['domain_name']
1991 params
['anqp_3gpp_cell_net'] = "232,01"
1992 hostapd
.add_ap(apdev
[0], params
)
1994 dev
[0].hs20_enable()
1995 dev
[0].scan_for_bss(bssid
, freq
="2412")
1996 dev
[0].request("SET external_sim 1")
1997 id1
= dev
[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM",
1998 'provisioning_sp': "example.com",
1999 'sp_priority' :"1"})
2000 id2
= dev
[0].add_cred_values({'realm': "example.com",
2001 'ca_cert': "auth_serv/ca.pem",
2002 'username': "hs20-test",
2003 'password': "password",
2004 'domain': "example.com",
2005 'provisioning_sp': "example.com",
2006 'sp_priority': "2"})
2007 dev
[0].dump_monitor()
2008 dev
[0].scan_for_bss(bssid
, freq
="2412")
2009 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2010 interworking_ext_sim_auth(dev
[0], "SIM")
2011 check_sp_type(dev
[0], "unknown")
2012 dev
[0].request("REMOVE_NETWORK all")
2014 dev
[0].set_cred(id1
, "sp_priority", "2")
2015 dev
[0].set_cred(id2
, "sp_priority", "1")
2016 dev
[0].dump_monitor()
2017 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2018 interworking_auth(dev
[0], "TTLS")
2019 check_sp_type(dev
[0], "unknown")
2021 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
2022 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
2023 check_eap_capa(dev
[0], "MSCHAPV2")
2025 _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
2027 dev
[0].request("SET external_sim 0")
2029 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
2030 hlr_auc_gw_available()
2031 bssid
= apdev
[0]['bssid']
2032 params
= hs20_ap_params()
2033 params
['hessid'] = bssid
2034 del params
['nai_realm']
2035 del params
['domain_name']
2036 params
['anqp_3gpp_cell_net'] = "232,01"
2037 hostapd
.add_ap(apdev
[0], params
)
2039 bssid2
= apdev
[1]['bssid']
2040 params
= hs20_ap_params()
2041 params
['ssid'] = "test-hs20-other"
2042 params
['hessid'] = bssid2
2043 del params
['domain_name']
2044 del params
['anqp_3gpp_cell_net']
2045 hostapd
.add_ap(apdev
[1], params
)
2047 dev
[0].hs20_enable()
2048 dev
[0].request("SET external_sim 1")
2049 id1
= dev
[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM",
2050 'provisioning_sp': "example.com",
2051 'sp_priority': "1"})
2052 id2
= dev
[0].add_cred_values({'realm': "example.com",
2053 'ca_cert': "auth_serv/ca.pem",
2054 'username': "hs20-test",
2055 'password': "password",
2056 'domain': "example.com",
2057 'provisioning_sp': "example.com",
2058 'sp_priority': "2"})
2059 dev
[0].dump_monitor()
2060 dev
[0].scan_for_bss(bssid
, freq
="2412")
2061 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2062 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2063 interworking_ext_sim_auth(dev
[0], "SIM")
2064 check_sp_type(dev
[0], "unknown")
2065 conn_bssid
= dev
[0].get_status_field("bssid")
2066 if conn_bssid
!= bssid
:
2067 raise Exception("Connected to incorrect BSS")
2068 dev
[0].request("REMOVE_NETWORK all")
2070 dev
[0].set_cred(id1
, "sp_priority", "2")
2071 dev
[0].set_cred(id2
, "sp_priority", "1")
2072 dev
[0].dump_monitor()
2073 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2074 interworking_auth(dev
[0], "TTLS")
2075 check_sp_type(dev
[0], "unknown")
2076 conn_bssid
= dev
[0].get_status_field("bssid")
2077 if conn_bssid
!= bssid2
:
2078 raise Exception("Connected to incorrect BSS")
2080 def test_ap_hs20_multi_cred_sp_prio_same(dev
, apdev
):
2081 """Hotspot 2.0 multi-cred and same sp_priority"""
2082 check_eap_capa(dev
[0], "MSCHAPV2")
2083 hlr_auc_gw_available()
2084 bssid
= apdev
[0]['bssid']
2085 params
= hs20_ap_params()
2086 params
['hessid'] = bssid
2087 del params
['domain_name']
2088 params
['anqp_3gpp_cell_net'] = "232,01"
2089 hostapd
.add_ap(apdev
[0], params
)
2091 dev
[0].hs20_enable()
2092 dev
[0].scan_for_bss(bssid
, freq
="2412")
2093 id1
= dev
[0].add_cred_values({'realm': "example.com",
2094 'ca_cert': "auth_serv/ca.pem",
2095 'username': "hs20-test",
2096 'password': "password",
2097 'domain': "domain1.example.com",
2098 'provisioning_sp': "example.com",
2099 'sp_priority': "1"})
2100 id2
= dev
[0].add_cred_values({'realm': "example.com",
2101 'ca_cert': "auth_serv/ca.pem",
2102 'username': "hs20-test",
2103 'password': "password",
2104 'domain': "domain2.example.com",
2105 'provisioning_sp': "example.com",
2106 'sp_priority': "1"})
2107 dev
[0].dump_monitor()
2108 dev
[0].scan_for_bss(bssid
, freq
="2412")
2109 check_auto_select(dev
[0], bssid
)
2111 def check_conn_capab_selection(dev
, type, missing
):
2112 dev
.request("INTERWORKING_SELECT freq=2412")
2113 ev
= dev
.wait_event(["INTERWORKING-AP"])
2115 raise Exception("Network selection timed out")
2116 if "type=" + type not in ev
:
2117 raise Exception("Unexpected network type")
2118 if missing
and "conn_capab_missing=1" not in ev
:
2119 raise Exception("conn_capab_missing not reported")
2120 if not missing
and "conn_capab_missing=1" in ev
:
2121 raise Exception("conn_capab_missing reported unexpectedly")
2123 def conn_capab_cred(domain
=None, req_conn_capab
=None):
2124 cred
= default_cred(domain
=domain
)
2126 cred
['req_conn_capab'] = req_conn_capab
2129 def test_ap_hs20_req_conn_capab(dev
, apdev
):
2130 """Hotspot 2.0 network selection with req_conn_capab"""
2131 check_eap_capa(dev
[0], "MSCHAPV2")
2132 bssid
= apdev
[0]['bssid']
2133 params
= hs20_ap_params()
2134 hostapd
.add_ap(apdev
[0], params
)
2136 dev
[0].hs20_enable()
2137 dev
[0].scan_for_bss(bssid
, freq
="2412")
2138 logger
.info("Not used in home network")
2139 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
2140 id = dev
[0].add_cred_values(values
)
2141 check_conn_capab_selection(dev
[0], "home", False)
2143 logger
.info("Used in roaming network")
2144 dev
[0].remove_cred(id)
2145 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
2146 id = dev
[0].add_cred_values(values
)
2147 check_conn_capab_selection(dev
[0], "roaming", True)
2149 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
2150 check_auto_select(dev
[0], bssid
)
2152 logger
.info("Additional req_conn_capab checks")
2154 dev
[0].remove_cred(id)
2155 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
2156 id = dev
[0].add_cred_values(values
)
2157 check_conn_capab_selection(dev
[0], "roaming", True)
2159 dev
[0].remove_cred(id)
2160 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
2161 id = dev
[0].add_cred_values(values
)
2162 check_conn_capab_selection(dev
[0], "roaming", True)
2164 bssid2
= apdev
[1]['bssid']
2165 params
= hs20_ap_params(ssid
="test-hs20b")
2166 params
['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0", "50:0:1"]
2167 hostapd
.add_ap(apdev
[1], params
)
2169 dev
[0].remove_cred(id)
2170 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
2171 id = dev
[0].add_cred_values(values
)
2172 dev
[0].set_cred(id, "req_conn_capab", "6:22")
2173 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2174 dev
[0].request("INTERWORKING_SELECT freq=2412")
2175 for i
in range(0, 2):
2176 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
2178 raise Exception("Network selection timed out")
2179 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
2180 raise Exception("Missing protocol connection capability not reported")
2181 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
2182 raise Exception("Protocol connection capability not reported correctly")
2184 def test_ap_hs20_req_conn_capab2(dev
, apdev
):
2185 """Hotspot 2.0 network selection with req_conn_capab (not present)"""
2186 check_eap_capa(dev
[0], "MSCHAPV2")
2187 bssid
= apdev
[0]['bssid']
2188 params
= hs20_ap_params()
2189 del params
['hs20_conn_capab']
2190 hostapd
.add_ap(apdev
[0], params
)
2192 dev
[0].hs20_enable()
2193 dev
[0].scan_for_bss(bssid
, freq
="2412")
2194 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
2195 id = dev
[0].add_cred_values(values
)
2196 check_conn_capab_selection(dev
[0], "roaming", False)
2198 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
2199 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
2200 check_eap_capa(dev
[0], "MSCHAPV2")
2201 bssid
= apdev
[0]['bssid']
2202 params
= hs20_ap_params()
2203 params
['domain_name'] = "roaming.example.org"
2204 params
['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0", "50:0:1"]
2205 hostapd
.add_ap(apdev
[0], params
)
2207 bssid2
= apdev
[1]['bssid']
2208 params
= hs20_ap_params(ssid
="test-hs20-b")
2209 params
['domain_name'] = "roaming.example.net"
2210 hostapd
.add_ap(apdev
[1], params
)
2212 values
= default_cred()
2213 values
['roaming_partner'] = "roaming.example.net,1,127,*"
2214 id = dev
[0].add_cred_values(values
)
2215 check_auto_select(dev
[0], bssid2
)
2217 dev
[0].set_cred(id, "req_conn_capab", "50")
2218 check_auto_select(dev
[0], bssid
)
2220 dev
[0].remove_cred(id)
2221 id = dev
[0].add_cred_values(values
)
2222 dev
[0].set_cred(id, "req_conn_capab", "51")
2223 check_auto_select(dev
[0], bssid2
)
2225 def check_bandwidth_selection(dev
, type, below
):
2226 dev
.request("INTERWORKING_SELECT freq=2412")
2227 ev
= dev
.wait_event(["INTERWORKING-AP"])
2229 raise Exception("Network selection timed out")
2230 logger
.debug("BSS entries:\n" + dev
.request("BSS RANGE=ALL"))
2231 if "type=" + type not in ev
:
2232 raise Exception("Unexpected network type")
2233 if below
and "below_min_backhaul=1" not in ev
:
2234 raise Exception("below_min_backhaul not reported")
2235 if not below
and "below_min_backhaul=1" in ev
:
2236 raise Exception("below_min_backhaul reported unexpectedly")
2238 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
2239 cred
= default_cred(domain
=domain
)
2241 cred
['min_dl_bandwidth_home'] = str(dl_home
)
2243 cred
['min_ul_bandwidth_home'] = str(ul_home
)
2245 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
2247 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
2250 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
2251 """Hotspot 2.0 network selection with min bandwidth (home)"""
2252 check_eap_capa(dev
[0], "MSCHAPV2")
2253 bssid
= apdev
[0]['bssid']
2254 params
= hs20_ap_params()
2255 hostapd
.add_ap(apdev
[0], params
)
2257 dev
[0].hs20_enable()
2258 dev
[0].scan_for_bss(bssid
, freq
="2412")
2259 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2260 id = dev
[0].add_cred_values(values
)
2261 check_bandwidth_selection(dev
[0], "home", False)
2262 dev
[0].remove_cred(id)
2264 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
2265 id = dev
[0].add_cred_values(values
)
2266 check_bandwidth_selection(dev
[0], "home", True)
2267 dev
[0].remove_cred(id)
2269 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
2270 id = dev
[0].add_cred_values(values
)
2271 check_bandwidth_selection(dev
[0], "home", True)
2272 dev
[0].remove_cred(id)
2274 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
2275 id = dev
[0].add_cred_values(values
)
2276 check_bandwidth_selection(dev
[0], "home", True)
2277 check_auto_select(dev
[0], bssid
)
2279 bssid2
= apdev
[1]['bssid']
2280 params
= hs20_ap_params(ssid
="test-hs20-b")
2281 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2282 hostapd
.add_ap(apdev
[1], params
)
2284 check_auto_select(dev
[0], bssid2
)
2286 def test_ap_hs20_min_bandwidth_home2(dev
, apdev
):
2287 """Hotspot 2.0 network selection with min bandwidth - special cases"""
2288 check_eap_capa(dev
[0], "MSCHAPV2")
2289 bssid
= apdev
[0]['bssid']
2290 params
= hs20_ap_params()
2291 hapd
= hostapd
.add_ap(apdev
[0], params
)
2293 dev
[0].hs20_enable()
2294 dev
[0].scan_for_bss(bssid
, freq
="2412")
2295 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2296 id = dev
[0].add_cred_values(values
)
2297 check_bandwidth_selection(dev
[0], "home", False)
2299 logger
.info("WAN link at capacity")
2300 hapd
.set('hs20_wan_metrics', "09:8000:1000:80:240:3000")
2301 check_bandwidth_selection(dev
[0], "home", True)
2303 logger
.info("Downlink/Uplink Load was not measured")
2304 hapd
.set('hs20_wan_metrics', "01:8000:1000:80:240:0")
2305 check_bandwidth_selection(dev
[0], "home", False)
2307 logger
.info("Uplink and Downlink max values")
2308 hapd
.set('hs20_wan_metrics', "01:4294967295:4294967295:80:240:3000")
2309 check_bandwidth_selection(dev
[0], "home", False)
2311 dev
[0].remove_cred(id)
2313 def test_ap_hs20_min_bandwidth_home_hidden_ssid_in_scan_res(dev
, apdev
):
2314 """Hotspot 2.0 network selection with min bandwidth (home) while hidden SSID is included in scan results"""
2315 check_eap_capa(dev
[0], "MSCHAPV2")
2316 bssid
= apdev
[0]['bssid']
2318 hapd
= hostapd
.add_ap(apdev
[0], {"ssid": 'secret',
2319 "ignore_broadcast_ssid": "1"})
2320 dev
[0].scan_for_bss(bssid
, freq
=2412)
2322 hapd_global
= hostapd
.HostapdGlobal(apdev
[0])
2324 hapd_global
.remove(apdev
[0]['ifname'])
2326 params
= hs20_ap_params()
2327 hostapd
.add_ap(apdev
[0], params
)
2329 dev
[0].hs20_enable()
2330 dev
[0].scan_for_bss(bssid
, freq
="2412")
2331 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2332 id = dev
[0].add_cred_values(values
)
2333 check_bandwidth_selection(dev
[0], "home", False)
2334 dev
[0].remove_cred(id)
2336 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
2337 id = dev
[0].add_cred_values(values
)
2338 check_bandwidth_selection(dev
[0], "home", True)
2339 dev
[0].remove_cred(id)
2341 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
2342 id = dev
[0].add_cred_values(values
)
2343 check_bandwidth_selection(dev
[0], "home", True)
2344 dev
[0].remove_cred(id)
2346 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
2347 id = dev
[0].add_cred_values(values
)
2348 check_bandwidth_selection(dev
[0], "home", True)
2349 check_auto_select(dev
[0], bssid
)
2351 bssid2
= apdev
[1]['bssid']
2352 params
= hs20_ap_params(ssid
="test-hs20-b")
2353 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2354 hostapd
.add_ap(apdev
[1], params
)
2356 check_auto_select(dev
[0], bssid2
)
2358 dev
[0].flush_scan_cache()
2360 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
2361 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
2362 check_eap_capa(dev
[0], "MSCHAPV2")
2363 bssid
= apdev
[0]['bssid']
2364 params
= hs20_ap_params()
2365 hostapd
.add_ap(apdev
[0], params
)
2367 dev
[0].hs20_enable()
2368 dev
[0].scan_for_bss(bssid
, freq
="2412")
2369 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
2370 id = dev
[0].add_cred_values(values
)
2371 check_bandwidth_selection(dev
[0], "roaming", False)
2372 dev
[0].remove_cred(id)
2374 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
2375 id = dev
[0].add_cred_values(values
)
2376 check_bandwidth_selection(dev
[0], "roaming", True)
2377 dev
[0].remove_cred(id)
2379 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
2380 id = dev
[0].add_cred_values(values
)
2381 check_bandwidth_selection(dev
[0], "roaming", True)
2382 dev
[0].remove_cred(id)
2384 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
2385 id = dev
[0].add_cred_values(values
)
2386 check_bandwidth_selection(dev
[0], "roaming", True)
2387 check_auto_select(dev
[0], bssid
)
2389 bssid2
= apdev
[1]['bssid']
2390 params
= hs20_ap_params(ssid
="test-hs20-b")
2391 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2392 hostapd
.add_ap(apdev
[1], params
)
2394 check_auto_select(dev
[0], bssid2
)
2396 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
2397 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
2398 check_eap_capa(dev
[0], "MSCHAPV2")
2399 bssid
= apdev
[0]['bssid']
2400 params
= hs20_ap_params()
2401 params
['domain_name'] = "roaming.example.org"
2402 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2403 hostapd
.add_ap(apdev
[0], params
)
2405 bssid2
= apdev
[1]['bssid']
2406 params
= hs20_ap_params(ssid
="test-hs20-b")
2407 params
['domain_name'] = "roaming.example.net"
2408 hostapd
.add_ap(apdev
[1], params
)
2410 values
= default_cred()
2411 values
['roaming_partner'] = "roaming.example.net,1,127,*"
2412 id = dev
[0].add_cred_values(values
)
2413 check_auto_select(dev
[0], bssid2
)
2415 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
2416 check_auto_select(dev
[0], bssid
)
2418 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
2419 check_auto_select(dev
[0], bssid2
)
2421 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
2422 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
2423 bssid
= apdev
[0]['bssid']
2424 params
= hs20_ap_params()
2425 del params
['hs20_wan_metrics']
2426 hostapd
.add_ap(apdev
[0], params
)
2428 dev
[0].hs20_enable()
2429 dev
[0].scan_for_bss(bssid
, freq
="2412")
2430 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
2431 dl_roaming
=10000, ul_roaming
=10000)
2432 dev
[0].add_cred_values(values
)
2433 check_bandwidth_selection(dev
[0], "home", False)
2435 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
2436 """Hotspot 2.0 connection and deauthentication request for ESS"""
2437 check_eap_capa(dev
[0], "MSCHAPV2")
2439 _test_ap_hs20_deauth_req_ess(dev
, apdev
)
2441 dev
[0].request("SET pmf 0")
2443 def _test_ap_hs20_deauth_req_ess(dev
, apdev
):
2444 dev
[0].request("SET pmf 2")
2445 hapd
= eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
2446 dev
[0].dump_monitor()
2447 addr
= dev
[0].p2p_interface_addr()
2449 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
2450 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
2452 raise Exception("Timeout on deauth imminent notice")
2453 if "1 120 http://example.com/" not in ev
:
2454 raise Exception("Unexpected deauth imminent notice: " + ev
)
2455 hapd
.request("DEAUTHENTICATE " + addr
)
2456 dev
[0].wait_disconnected(timeout
=10)
2457 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
2458 raise Exception("Network not marked temporarily disabled")
2459 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
2460 "Trying to associate",
2461 "CTRL-EVENT-CONNECTED"], timeout
=5)
2463 raise Exception("Unexpected connection attempt")
2465 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
2466 """Hotspot 2.0 connection and deauthentication request for BSS"""
2467 check_eap_capa(dev
[0], "MSCHAPV2")
2469 _test_ap_hs20_deauth_req_bss(dev
, apdev
)
2471 dev
[0].request("SET pmf 0")
2473 def _test_ap_hs20_deauth_req_bss(dev
, apdev
):
2474 dev
[0].request("SET pmf 2")
2475 hapd
= eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
2476 dev
[0].dump_monitor()
2477 addr
= dev
[0].p2p_interface_addr()
2479 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
2480 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
2482 raise Exception("Timeout on deauth imminent notice")
2483 if "0 120 http://example.com/" not in ev
:
2484 raise Exception("Unexpected deauth imminent notice: " + ev
)
2485 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
2486 ev
= dev
[0].wait_disconnected(timeout
=10)
2487 if "reason=4" not in ev
:
2488 raise Exception("Unexpected disconnection reason")
2489 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
2490 raise Exception("Network not marked temporarily disabled")
2491 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
2492 "Trying to associate",
2493 "CTRL-EVENT-CONNECTED"], timeout
=5)
2495 raise Exception("Unexpected connection attempt")
2497 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
2498 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
2499 check_eap_capa(dev
[0], "MSCHAPV2")
2501 _test_ap_hs20_deauth_req_from_radius(dev
, apdev
)
2503 dev
[0].request("SET pmf 0")
2505 def _test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
2506 bssid
= apdev
[0]['bssid']
2507 params
= hs20_ap_params()
2508 params
['nai_realm'] = ["0,example.com,21[2:4]"]
2509 params
['hs20_deauth_req_timeout'] = "2"
2510 hostapd
.add_ap(apdev
[0], params
)
2512 dev
[0].request("SET pmf 2")
2513 dev
[0].hs20_enable()
2514 dev
[0].add_cred_values({'realm': "example.com",
2515 'username': "hs20-deauth-test",
2516 'password': "password"})
2517 interworking_select(dev
[0], bssid
, freq
="2412")
2518 interworking_connect(dev
[0], bssid
, "TTLS")
2519 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
2521 raise Exception("Timeout on deauth imminent notice")
2522 if " 1 100" not in ev
:
2523 raise Exception("Unexpected deauth imminent contents")
2524 dev
[0].wait_disconnected(timeout
=3)
2526 def test_ap_hs20_deauth_req_without_pmf(dev
, apdev
):
2527 """Hotspot 2.0 connection and deauthentication request without PMF"""
2528 check_eap_capa(dev
[0], "MSCHAPV2")
2529 dev
[0].request("SET pmf 0")
2530 hapd
= eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user", release
=1)
2531 dev
[0].dump_monitor()
2532 id = int(dev
[0].get_status_field("id"))
2533 dev
[0].set_network(id, "ieee80211w", "0")
2534 dev
[0].request("DISCONNECT")
2535 dev
[0].wait_disconnected()
2536 dev
[0].select_network(id, freq
=2412)
2537 dev
[0].wait_connected()
2538 addr
= dev
[0].own_addr()
2540 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
2541 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=0.2)
2543 raise Exception("Deauth imminent notice without PMF accepted")
2544 with
alloc_fail(hapd
, 1, "wpabuf_alloc;hostapd_ctrl_iface_hs20_deauth_req"):
2545 if "FAIL" not in hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/"):
2546 raise Exception("HS20_DEAUTH_REQ accepted during OOM")
2548 def test_ap_hs20_remediation_required(dev
, apdev
):
2549 """Hotspot 2.0 connection and remediation required from RADIUS"""
2550 check_eap_capa(dev
[0], "MSCHAPV2")
2552 _test_ap_hs20_remediation_required(dev
, apdev
)
2554 dev
[0].request("SET pmf 0")
2556 def _test_ap_hs20_remediation_required(dev
, apdev
):
2557 bssid
= apdev
[0]['bssid']
2558 params
= hs20_ap_params()
2559 params
['nai_realm'] = ["0,example.com,21[2:4]"]
2560 hostapd
.add_ap(apdev
[0], params
)
2562 dev
[0].request("SET pmf 1")
2563 dev
[0].hs20_enable()
2564 dev
[0].add_cred_values({'realm': "example.com",
2565 'username': "hs20-subrem-test",
2566 'password': "password"})
2567 interworking_select(dev
[0], bssid
, freq
="2412")
2568 interworking_connect(dev
[0], bssid
, "TTLS")
2569 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2571 raise Exception("Timeout on subscription remediation notice")
2572 if " 1 https://example.com/" not in ev
:
2573 raise Exception("Unexpected subscription remediation event contents")
2575 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
2576 """Hotspot 2.0 connection and subrem from ctrl_iface"""
2577 check_eap_capa(dev
[0], "MSCHAPV2")
2579 _test_ap_hs20_remediation_required_ctrl(dev
, apdev
)
2581 dev
[0].request("SET pmf 0")
2583 def _test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
2584 bssid
= apdev
[0]['bssid']
2585 addr
= dev
[0].own_addr()
2586 params
= hs20_ap_params()
2587 params
['nai_realm'] = ["0,example.com,21[2:4]"]
2588 hapd
= hostapd
.add_ap(apdev
[0], params
)
2590 dev
[0].request("SET pmf 1")
2591 dev
[0].hs20_enable()
2592 dev
[0].add_cred_values(default_cred())
2593 interworking_select(dev
[0], bssid
, freq
="2412")
2594 interworking_connect(dev
[0], bssid
, "TTLS")
2596 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
2597 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2599 raise Exception("Timeout on subscription remediation notice")
2600 if " 1 https://example.com/" not in ev
:
2601 raise Exception("Unexpected subscription remediation event contents")
2603 hapd
.request("HS20_WNM_NOTIF " + addr
)
2604 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2606 raise Exception("Timeout on subscription remediation notice")
2607 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
2608 raise Exception("Unexpected subscription remediation event contents: " + ev
)
2610 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
2611 raise Exception("Unexpected HS20_WNM_NOTIF success")
2612 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
2613 raise Exception("Unexpected HS20_WNM_NOTIF success")
2614 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
2615 raise Exception("Unexpected HS20_WNM_NOTIF success")
2616 if "OK" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " "):
2617 raise Exception("HS20_WNM_NOTIF failed with empty URL")
2619 def test_ap_hs20_session_info(dev
, apdev
):
2620 """Hotspot 2.0 connection and session information from RADIUS"""
2621 check_eap_capa(dev
[0], "MSCHAPV2")
2623 _test_ap_hs20_session_info(dev
, apdev
)
2625 dev
[0].request("SET pmf 0")
2627 def _test_ap_hs20_session_info(dev
, apdev
):
2628 bssid
= apdev
[0]['bssid']
2629 params
= hs20_ap_params()
2630 params
['nai_realm'] = ["0,example.com,21[2:4]"]
2631 hostapd
.add_ap(apdev
[0], params
)
2633 dev
[0].request("SET pmf 1")
2634 dev
[0].hs20_enable()
2635 dev
[0].add_cred_values({'realm': "example.com",
2636 'username': "hs20-session-info-test",
2637 'password': "password"})
2638 interworking_select(dev
[0], bssid
, freq
="2412")
2639 interworking_connect(dev
[0], bssid
, "TTLS")
2640 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
2642 raise Exception("Timeout on ESS disassociation imminent notice")
2643 if " 1 59904 https://example.com/" not in ev
:
2644 raise Exception("Unexpected ESS disassociation imminent event contents")
2645 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
2647 raise Exception("Scan not started")
2648 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
2650 raise Exception("Scan not completed")
2652 def test_ap_hs20_osen(dev
, apdev
):
2653 """Hotspot 2.0 OSEN connection"""
2654 params
= {'ssid': "osen",
2656 'auth_server_addr': "127.0.0.1",
2657 'auth_server_port': "1812",
2658 'auth_server_shared_secret': "radius"}
2659 hostapd
.add_ap(apdev
[0], params
)
2661 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
2663 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
2664 scan_freq
="2412", wait_connect
=False)
2665 dev
[0].flush_scan_cache()
2666 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2667 group
="GTK_NOT_USED CCMP",
2668 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2669 ca_cert
="auth_serv/ca.pem",
2671 res
= dev
[0].get_bss(apdev
[0]['bssid'])['flags']
2672 if "[OSEN-OSEN-CCMP]" not in res
:
2673 raise Exception("OSEN not reported in BSS")
2675 raise Exception("WEP reported in BSS")
2676 res
= dev
[0].request("SCAN_RESULTS")
2677 if "[OSEN-OSEN-CCMP]" not in res
:
2678 raise Exception("OSEN not reported in SCAN_RESULTS")
2680 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2681 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
2682 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2683 group
="GTK_NOT_USED CCMP",
2684 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2685 ca_cert
="auth_serv/ca.pem",
2687 wpas
.request("DISCONNECT")
2689 def test_ap_hs20_osen_single_ssid(dev
, apdev
):
2690 """Hotspot 2.0 OSEN-single-SSID connection"""
2691 bssid
= apdev
[0]['bssid']
2692 params
= hs20_ap_params()
2693 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
2694 params
['hessid'] = bssid
2695 hapd
= hostapd
.add_ap(apdev
[0], params
)
2697 # RSN-OSEN (for OSU)
2698 dev
[0].connect("test-hs20", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2699 group
="CCMP GTK_NOT_USED",
2700 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2701 ca_cert
="auth_serv/ca.pem", ieee80211w
='2',
2703 # RSN-EAP (for data connection)
2704 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2705 identity
="hs20-test", password
="password",
2706 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2707 pairwise
="CCMP", group
="CCMP",
2708 ieee80211w
='2', scan_freq
="2412")
2710 res
= dev
[0].get_bss(apdev
[0]['bssid'])['flags']
2711 if "[WPA2-EAP+OSEN-CCMP]" not in res
:
2712 raise Exception("OSEN not reported in BSS")
2714 raise Exception("WEP reported in BSS")
2715 res
= dev
[0].request("SCAN_RESULTS")
2716 if "[WPA2-EAP+OSEN-CCMP]" not in res
:
2717 raise Exception("OSEN not reported in SCAN_RESULTS")
2719 hwsim_utils
.test_connectivity(dev
[1], hapd
)
2720 hwsim_utils
.test_connectivity(dev
[0], hapd
, broadcast
=False)
2721 hwsim_utils
.test_connectivity(dev
[0], hapd
, timeout
=1,
2722 success_expected
=False)
2724 def test_ap_hs20_network_preference(dev
, apdev
):
2725 """Hotspot 2.0 network selection with preferred home network"""
2726 check_eap_capa(dev
[0], "MSCHAPV2")
2727 bssid
= apdev
[0]['bssid']
2728 params
= hs20_ap_params()
2729 hostapd
.add_ap(apdev
[0], params
)
2731 dev
[0].hs20_enable()
2732 values
= {'realm': "example.com",
2733 'username': "hs20-test",
2734 'password': "password",
2735 'domain': "example.com"}
2736 dev
[0].add_cred_values(values
)
2738 id = dev
[0].add_network()
2739 dev
[0].set_network_quoted(id, "ssid", "home")
2740 dev
[0].set_network_quoted(id, "psk", "12345678")
2741 dev
[0].set_network(id, "priority", "1")
2742 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2744 dev
[0].scan_for_bss(bssid
, freq
="2412")
2745 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2746 ev
= dev
[0].wait_connected(timeout
=15)
2748 raise Exception("Unexpected network selected")
2750 bssid2
= apdev
[1]['bssid']
2751 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2752 hostapd
.add_ap(apdev
[1], params
)
2754 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2755 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2756 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2757 "INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
2759 raise Exception("Connection timed out")
2760 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2761 raise Exception("No roam to higher priority network")
2762 if bssid2
not in ev
:
2763 raise Exception("Unexpected network selected")
2765 def test_ap_hs20_network_preference2(dev
, apdev
):
2766 """Hotspot 2.0 network selection with preferred credential"""
2767 check_eap_capa(dev
[0], "MSCHAPV2")
2768 bssid2
= apdev
[1]['bssid']
2769 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2770 hostapd
.add_ap(apdev
[1], params
)
2772 dev
[0].hs20_enable()
2773 values
= {'realm': "example.com",
2774 'username': "hs20-test",
2775 'password': "password",
2776 'domain': "example.com",
2778 dev
[0].add_cred_values(values
)
2780 id = dev
[0].add_network()
2781 dev
[0].set_network_quoted(id, "ssid", "home")
2782 dev
[0].set_network_quoted(id, "psk", "12345678")
2783 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2785 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2786 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2787 ev
= dev
[0].wait_connected(timeout
=15)
2788 if bssid2
not in ev
:
2789 raise Exception("Unexpected network selected")
2791 bssid
= apdev
[0]['bssid']
2792 params
= hs20_ap_params()
2793 hostapd
.add_ap(apdev
[0], params
)
2795 dev
[0].scan_for_bss(bssid
, freq
="2412")
2796 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2797 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2798 "INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
2800 raise Exception("Connection timed out")
2801 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2802 raise Exception("No roam to higher priority network")
2804 raise Exception("Unexpected network selected")
2806 def test_ap_hs20_network_preference3(dev
, apdev
):
2807 """Hotspot 2.0 network selection with two credential (one preferred)"""
2808 check_eap_capa(dev
[0], "MSCHAPV2")
2809 bssid
= apdev
[0]['bssid']
2810 params
= hs20_ap_params()
2811 hostapd
.add_ap(apdev
[0], params
)
2813 bssid2
= apdev
[1]['bssid']
2814 params
= hs20_ap_params(ssid
="test-hs20b")
2815 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
2816 hostapd
.add_ap(apdev
[1], params
)
2818 dev
[0].hs20_enable()
2819 values
= {'realm': "example.com",
2820 'username': "hs20-test",
2821 'password': "password",
2823 dev
[0].add_cred_values(values
)
2824 values
= {'realm': "example.org",
2825 'username': "hs20-test",
2826 'password': "password"}
2827 id = dev
[0].add_cred_values(values
)
2829 dev
[0].scan_for_bss(bssid
, freq
="2412")
2830 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2831 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2832 ev
= dev
[0].wait_connected(timeout
=15)
2834 raise Exception("Unexpected network selected")
2836 dev
[0].set_cred(id, "priority", "2")
2837 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2838 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2839 "INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
2841 raise Exception("Connection timed out")
2842 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2843 raise Exception("No roam to higher priority network")
2844 if bssid2
not in ev
:
2845 raise Exception("Unexpected network selected")
2847 def test_ap_hs20_network_preference4(dev
, apdev
):
2848 """Hotspot 2.0 network selection with username vs. SIM credential"""
2849 check_eap_capa(dev
[0], "MSCHAPV2")
2850 bssid
= apdev
[0]['bssid']
2851 params
= hs20_ap_params()
2852 hostapd
.add_ap(apdev
[0], params
)
2854 bssid2
= apdev
[1]['bssid']
2855 params
= hs20_ap_params(ssid
="test-hs20b")
2856 params
['hessid'] = bssid2
2857 params
['anqp_3gpp_cell_net'] = "555,444"
2858 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
2859 hostapd
.add_ap(apdev
[1], params
)
2861 dev
[0].hs20_enable()
2862 values
= {'realm': "example.com",
2863 'username': "hs20-test",
2864 'password': "password",
2866 dev
[0].add_cred_values(values
)
2867 values
= {'imsi': "555444-333222111",
2869 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"}
2870 id = dev
[0].add_cred_values(values
)
2872 dev
[0].scan_for_bss(bssid
, freq
="2412")
2873 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2874 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2875 ev
= dev
[0].wait_connected(timeout
=15)
2877 raise Exception("Unexpected network selected")
2879 dev
[0].set_cred(id, "priority", "2")
2880 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2881 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2882 "INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
2884 raise Exception("Connection timed out")
2885 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2886 raise Exception("No roam to higher priority network")
2887 if bssid2
not in ev
:
2888 raise Exception("Unexpected network selected")
2890 def test_ap_hs20_interworking_select_blocking_scan(dev
, apdev
):
2891 """Ongoing INTERWORKING_SELECT blocking SCAN"""
2892 check_eap_capa(dev
[0], "MSCHAPV2")
2893 bssid
= apdev
[0]['bssid']
2894 params
= hs20_ap_params()
2895 hostapd
.add_ap(apdev
[0], params
)
2897 dev
[0].hs20_enable()
2898 values
= {'realm': "example.com",
2899 'username': "hs20-test",
2900 'password': "password",
2901 'domain': "example.com"}
2902 dev
[0].add_cred_values(values
)
2904 dev
[0].scan_for_bss(bssid
, freq
="2412")
2905 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2906 if "FAIL-BUSY" not in dev
[0].request("SCAN"):
2907 raise Exception("Unexpected SCAN command result")
2908 dev
[0].wait_connected(timeout
=15)
2910 def test_ap_hs20_fetch_osu(dev
, apdev
):
2911 """Hotspot 2.0 OSU provider and icon fetch"""
2912 bssid
= apdev
[0]['bssid']
2913 params
= hs20_ap_params()
2914 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2915 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2916 params
['osu_method_list'] = "1"
2917 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
2918 params
['osu_icon'] = "w1fi_logo"
2919 params
['osu_service_desc'] = ["eng:Example services", "fin:Esimerkkipalveluja"]
2920 params
['osu_server_uri'] = "https://example.com/osu/"
2921 hostapd
.add_ap(apdev
[0], params
)
2923 bssid2
= apdev
[1]['bssid']
2924 params
= hs20_ap_params(ssid
="test-hs20b")
2925 params
['hessid'] = bssid2
2926 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2927 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2928 params
['osu_method_list'] = "0"
2929 params
['osu_nai'] = "osen@example.com"
2930 params
['osu_friendly_name'] = ["eng:Test2 OSU", "fin:Testi2-OSU"]
2931 params
['osu_icon'] = "w1fi_logo"
2932 params
['osu_service_desc'] = ["eng:Example services2", "fin:Esimerkkipalveluja2"]
2933 params
['osu_server_uri'] = "https://example.org/osu/"
2934 hostapd
.add_ap(apdev
[1], params
)
2936 with
open("w1fi_logo.png", "rb") as f
:
2937 orig_logo
= f
.read()
2938 dev
[0].hs20_enable()
2939 dir = "/tmp/osu-fetch"
2940 if os
.path
.isdir(dir):
2941 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
2943 os
.remove(dir + "/" + f
)
2950 dev
[1].scan_for_bss(bssid
, freq
="2412")
2951 dev
[2].scan_for_bss(bssid
, freq
="2412")
2952 dev
[0].request("SET osu_dir " + dir)
2953 dev
[0].request("FETCH_OSU")
2954 if "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2955 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2956 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2957 raise Exception("HS20_ICON_REQUEST failed")
2958 if "OK" not in dev
[2].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2959 raise Exception("REQ_HS20_ICON failed")
2962 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2963 "RX-HS20-ANQP-ICON"], timeout
=15)
2965 raise Exception("Timeout on OSU fetch")
2966 if "OSU provider fetch completed" in ev
:
2968 if "RX-HS20-ANQP-ICON" in ev
:
2969 with
open(ev
.split(' ')[1], "rb") as f
:
2971 if logo
== orig_logo
:
2974 with
open(dir + "/osu-providers.txt", "r") as f
:
2976 logger
.debug("osu-providers.txt: " + prov
)
2977 if "OSU-PROVIDER " + bssid
not in prov
:
2978 raise Exception("Missing OSU_PROVIDER(1)")
2979 if "OSU-PROVIDER " + bssid2
not in prov
:
2980 raise Exception("Missing OSU_PROVIDER(2)")
2982 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
2984 os
.remove(dir + "/" + f
)
2988 raise Exception("Unexpected number of icons fetched")
2990 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2992 raise Exception("Timeout on GAS-QUERY-DONE")
2993 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2995 raise Exception("Timeout on GAS-QUERY-DONE")
2996 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2997 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2998 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
3000 raise Exception("Timeout on icon fetch")
3001 if "Icon Binary File" not in ev
:
3002 raise Exception("Unexpected ANQP element")
3004 ev
= dev
[2].wait_event(["RX-HS20-ICON"], timeout
=5)
3006 raise Exception("Timeout on RX-HS20-ICON")
3007 event_icon_len
= ev
.split(' ')[3]
3008 if " w1fi_logo " not in ev
:
3009 raise Exception("RX-HS20-ICON did not have the expected file name")
3011 raise Exception("RX-HS20-ICON did not have the expected BSSID")
3012 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 10"):
3013 raise Exception("GET_HS20_ICON 0..10 failed")
3014 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 5 10"):
3015 raise Exception("GET_HS20_ICON 5..15 failed")
3016 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 100000 10"):
3017 raise Exception("Unexpected success of GET_HS20_ICON with too large offset")
3018 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " no_such_logo 0 10"):
3019 raise Exception("GET_HS20_ICON for not existing icon succeeded")
3020 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 3070"):
3021 raise Exception("GET_HS20_ICON with too many output bytes to fit the buffer succeeded")
3022 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 0"):
3023 raise Exception("GET_HS20_ICON 0..0 succeeded")
3028 raise Exception("Unexpectedly long icon")
3029 res
= dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo %d 1000" % pos
)
3030 if res
.startswith("FAIL"):
3032 icon
+= base64
.b64decode(res
)
3034 hex = binascii
.hexlify(icon
).decode()
3035 if not hex.startswith("0009696d6167652f706e677d1d"):
3036 raise Exception("Unexpected beacon binary header: " + hex)
3037 with
open('w1fi_logo.png', 'rb') as f
:
3039 if icon
[13:] != data
:
3040 raise Exception("Unexpected icon data")
3041 if len(icon
) != int(event_icon_len
):
3042 raise Exception("Unexpected RX-HS20-ICON event length: " + event_icon_len
)
3045 if "OK" not in dev
[i
].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3046 raise Exception("REQ_HS20_ICON failed [2]")
3048 ev
= dev
[i
].wait_event(["RX-HS20-ICON"], timeout
=5)
3050 raise Exception("Timeout on RX-HS20-ICON [2]")
3052 if "FAIL" not in dev
[2].request("DEL_HS20_ICON foo w1fi_logo"):
3053 raise Exception("Invalid DEL_HS20_ICON accepted")
3054 if "OK" not in dev
[2].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3055 raise Exception("DEL_HS20_ICON failed")
3056 if "OK" not in dev
[1].request("DEL_HS20_ICON " + bssid
):
3057 raise Exception("DEL_HS20_ICON failed")
3058 if "OK" not in dev
[0].request("DEL_HS20_ICON "):
3059 raise Exception("DEL_HS20_ICON failed")
3061 if "FAIL" not in dev
[i
].request("DEL_HS20_ICON "):
3062 raise Exception("DEL_HS20_ICON accepted when no icons left")
3064 def test_ap_hs20_fetch_osu_no_info(dev
, apdev
):
3065 """Hotspot 2.0 OSU provider and no AP with info"""
3066 bssid
= apdev
[0]['bssid']
3067 params
= hs20_ap_params()
3068 hostapd
.add_ap(apdev
[0], params
)
3070 dev
[0].hs20_enable()
3071 dir = "/tmp/osu-fetch"
3072 if os
.path
.isdir(dir):
3073 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3075 os
.remove(dir + "/" + f
)
3081 dev
[0].scan_for_bss(bssid
, freq
="2412")
3083 dev
[0].request("SET osu_dir " + dir)
3084 dev
[0].request("FETCH_OSU")
3085 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3087 raise Exception("Timeout on OSU fetch")
3089 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3091 os
.remove(dir + "/" + f
)
3094 def test_ap_hs20_fetch_osu_no_icon(dev
, apdev
):
3095 """Hotspot 2.0 OSU provider and no icon found"""
3096 bssid
= apdev
[0]['bssid']
3097 params
= hs20_ap_params()
3098 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3099 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3100 params
['osu_method_list'] = "1"
3101 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3102 params
['osu_icon'] = "w1fi_logo"
3103 params
['osu_service_desc'] = ["eng:Example services",
3104 "fin:Esimerkkipalveluja"]
3105 params
['osu_server_uri'] = "https://example.com/osu/"
3106 hostapd
.add_ap(apdev
[0], params
)
3108 dev
[0].hs20_enable()
3109 dir = "/tmp/osu-fetch"
3110 if os
.path
.isdir(dir):
3111 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3113 os
.remove(dir + "/" + f
)
3119 dev
[0].scan_for_bss(bssid
, freq
="2412")
3121 dev
[0].request("SET osu_dir " + dir)
3122 dev
[0].request("FETCH_OSU")
3123 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3125 raise Exception("Timeout on OSU fetch")
3127 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3129 os
.remove(dir + "/" + f
)
3132 def test_ap_hs20_fetch_osu_single_ssid(dev
, apdev
):
3133 """Hotspot 2.0 OSU provider and single SSID"""
3134 bssid
= apdev
[0]['bssid']
3135 params
= hs20_ap_params()
3136 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3137 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3138 params
['osu_method_list'] = "1"
3139 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3140 params
['osu_nai2'] = "osen@example.com"
3141 params
['osu_icon'] = "w1fi_logo"
3142 params
['osu_service_desc'] = ["eng:Example services",
3143 "fin:Esimerkkipalveluja"]
3144 params
['osu_server_uri'] = "https://example.com/osu/"
3145 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
3146 hostapd
.add_ap(apdev
[0], params
)
3148 dev
[0].hs20_enable()
3149 dir = "/tmp/osu-fetch"
3150 if os
.path
.isdir(dir):
3151 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3153 os
.remove(dir + "/" + f
)
3159 dev
[0].scan_for_bss(bssid
, freq
="2412")
3161 dev
[0].request("SET osu_dir " + dir)
3162 dev
[0].request("FETCH_OSU")
3163 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3165 raise Exception("Timeout on OSU fetch")
3170 with
open(os
.path
.join(dir, "osu-providers.txt"), "r") as f
:
3171 for l
in f
.readlines():
3172 logger
.info(l
.strip())
3173 if l
.strip() == "osu_ssid=HS 2.0 OSU open":
3175 if l
.strip() == "osu_ssid2=test-hs20":
3177 if l
.strip().startswith("osu_nai="):
3179 if l
.strip() == "osu_nai2=osen@example.com":
3182 raise Exception("osu_ssid not reported")
3184 raise Exception("osu_ssid2 not reported")
3186 raise Exception("osu_nai reported unexpectedly")
3188 raise Exception("osu_nai2 not reported")
3190 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3192 os
.remove(dir + "/" + f
)
3195 def test_ap_hs20_fetch_osu_single_ssid2(dev
, apdev
):
3196 """Hotspot 2.0 OSU provider and single SSID (two OSU providers)"""
3197 bssid
= apdev
[0]['bssid']
3198 params
= hs20_ap_params()
3199 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3200 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3201 params
['osu_method_list'] = "1"
3202 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3203 params
['osu_nai2'] = "osen@example.com"
3204 params
['osu_icon'] = "w1fi_logo"
3205 params
['osu_service_desc'] = ["eng:Example services",
3206 "fin:Esimerkkipalveluja"]
3207 params
['osu_server_uri'] = "https://example.com/osu/"
3208 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
3209 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
3211 hapd
.set('osu_server_uri', 'https://another.example.com/osu/')
3212 hapd
.set('osu_method_list', "1")
3213 hapd
.set('osu_nai2', "osen@another.example.com")
3216 dev
[0].hs20_enable()
3217 dir = "/tmp/osu-fetch"
3218 if os
.path
.isdir(dir):
3219 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3221 os
.remove(dir + "/" + f
)
3227 dev
[0].scan_for_bss(bssid
, freq
="2412")
3229 dev
[0].request("SET osu_dir " + dir)
3230 dev
[0].request("FETCH_OSU")
3231 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3233 raise Exception("Timeout on OSU fetch")
3239 with
open(os
.path
.join(dir, "osu-providers.txt"), "r") as f
:
3240 for l
in f
.readlines():
3241 logger
.info(l
.strip())
3242 if l
.strip() == "osu_ssid=HS 2.0 OSU open":
3244 if l
.strip() == "osu_ssid2=test-hs20":
3246 if l
.strip().startswith("osu_nai="):
3248 if l
.strip() == "osu_nai2=osen@example.com":
3250 if l
.strip() == "osu_nai2=osen@another.example.com":
3253 raise Exception("osu_ssid not reported")
3255 raise Exception("osu_ssid2 not reported")
3257 raise Exception("osu_nai reported unexpectedly")
3259 raise Exception("osu_nai2 not reported")
3261 raise Exception("osu_nai2b not reported")
3263 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3265 os
.remove(dir + "/" + f
)
3268 def get_icon(dev
, bssid
, iconname
):
3273 raise Exception("Unexpectedly long icon")
3274 res
= dev
.request("GET_HS20_ICON " + bssid
+ " " + iconname
+ " %d 3000" % pos
)
3275 if res
.startswith("FAIL"):
3277 icon
+= base64
.b64decode(res
)
3280 raise Exception("Too short GET_HS20_ICON response")
3281 return icon
[0:13], icon
[13:]
3283 def test_ap_hs20_req_hs20_icon(dev
, apdev
):
3284 """Hotspot 2.0 OSU provider and multi-icon fetch with REQ_HS20_ICON"""
3285 bssid
= apdev
[0]['bssid']
3286 params
= hs20_ap_params()
3287 params
['hs20_icon'] = ["128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3288 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem"]
3289 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3290 params
['osu_method_list'] = "1"
3291 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3292 params
['osu_icon'] = ["w1fi_logo", "w1fi_logo2"]
3293 params
['osu_service_desc'] = ["eng:Example services",
3294 "fin:Esimerkkipalveluja"]
3295 params
['osu_server_uri'] = "https://example.com/osu/"
3296 hostapd
.add_ap(apdev
[0], params
)
3298 dev
[0].scan_for_bss(bssid
, freq
="2412")
3299 run_req_hs20_icon(dev
, bssid
)
3301 def run_req_hs20_icon(dev
, bssid
):
3302 # First, fetch two icons from the AP to wpa_supplicant
3304 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3305 raise Exception("REQ_HS20_ICON failed")
3306 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3308 raise Exception("Timeout on RX-HS20-ICON (1)")
3310 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
3311 raise Exception("REQ_HS20_ICON failed")
3312 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3314 raise Exception("Timeout on RX-HS20-ICON (2)")
3316 # Then, fetch the icons from wpa_supplicant for validation
3318 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
3319 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
3321 with
open('w1fi_logo.png', 'rb') as f
:
3324 raise Exception("Unexpected icon data (1)")
3326 with
open('auth_serv/sha512-server.pem', 'rb') as f
:
3329 raise Exception("Unexpected icon data (2)")
3331 # Finally, delete the icons from wpa_supplicant
3333 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3334 raise Exception("DEL_HS20_ICON failed")
3335 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
3336 raise Exception("DEL_HS20_ICON failed")
3338 def test_ap_hs20_req_operator_icon(dev
, apdev
):
3339 """Hotspot 2.0 operator icons"""
3340 bssid
= apdev
[0]['bssid']
3341 params
= hs20_ap_params()
3342 params
['hs20_icon'] = ["128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3343 "500:300:fi:image/png:test_logo:auth_serv/sha512-server.pem"]
3344 params
['operator_icon'] = ["w1fi_logo", "unknown_logo", "test_logo"]
3345 hostapd
.add_ap(apdev
[0], params
)
3347 value
= struct
.pack('<HH', 128, 80) + b
"zxx"
3348 value
+= struct
.pack('B', 9) + b
"image/png"
3349 value
+= struct
.pack('B', 9) + b
"w1fi_logo"
3351 value
+= struct
.pack('<HH', 500, 300) + b
"fi\0"
3352 value
+= struct
.pack('B', 9) + b
"image/png"
3353 value
+= struct
.pack('B', 9) + b
"test_logo"
3355 dev
[0].scan_for_bss(bssid
, freq
="2412")
3357 if "OK" not in dev
[0].request("ANQP_GET " + bssid
+ " hs20:12"):
3358 raise Exception("ANQP_GET command failed")
3360 ev
= dev
[0].wait_event(["GAS-QUERY-START"], timeout
=5)
3362 raise Exception("GAS query start timed out")
3364 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
3366 raise Exception("GAS query timed out")
3368 ev
= dev
[0].wait_event(["RX-HS20-ANQP"], timeout
=1)
3369 if ev
is None or "Operator Icon Metadata" not in ev
:
3370 raise Exception("Did not receive Operator Icon Metadata")
3372 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=10)
3374 raise Exception("ANQP-QUERY-DONE event not seen")
3375 if "result=SUCCESS" not in ev
:
3376 raise Exception("Unexpected result: " + ev
)
3378 bss
= dev
[0].get_bss(bssid
)
3379 if "hs20_operator_icon_metadata" not in bss
:
3380 raise Exception("hs20_operator_icon_metadata missing from BSS entry")
3381 if bss
["hs20_operator_icon_metadata"] != binascii
.hexlify(value
).decode():
3382 raise Exception("Unexpected hs20_operator_icon_metadata value: " +
3383 bss
["hs20_operator_icon_metadata"])
3385 run_req_hs20_icon(dev
, bssid
)
3387 def test_ap_hs20_req_hs20_icon_oom(dev
, apdev
):
3388 """Hotspot 2.0 icon fetch OOM with REQ_HS20_ICON"""
3389 bssid
= apdev
[0]['bssid']
3390 params
= hs20_ap_params()
3391 params
['hs20_icon'] = ["128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3392 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem"]
3393 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3394 params
['osu_method_list'] = "1"
3395 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3396 params
['osu_icon'] = ["w1fi_logo", "w1fi_logo2"]
3397 params
['osu_service_desc'] = ["eng:Example services",
3398 "fin:Esimerkkipalveluja"]
3399 params
['osu_server_uri'] = "https://example.com/osu/"
3400 hostapd
.add_ap(apdev
[0], params
)
3402 dev
[0].scan_for_bss(bssid
, freq
="2412")
3404 if "FAIL" not in dev
[0].request("REQ_HS20_ICON 11:22:33:44:55:66 w1fi_logo"):
3405 raise Exception("REQ_HS20_ICON succeeded with unknown BSSID")
3407 with
alloc_fail(dev
[0], 1, "hs20_build_anqp_req;hs20_anqp_send_req"):
3408 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3409 raise Exception("REQ_HS20_ICON succeeded during OOM")
3411 with
alloc_fail(dev
[0], 1, "gas_query_req;hs20_anqp_send_req"):
3412 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3413 raise Exception("REQ_HS20_ICON succeeded during OOM")
3415 with
alloc_fail(dev
[0], 1, "=hs20_anqp_send_req"):
3416 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3417 raise Exception("REQ_HS20_ICON succeeded during OOM")
3418 with
alloc_fail(dev
[0], 2, "=hs20_anqp_send_req"):
3419 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3420 raise Exception("REQ_HS20_ICON succeeded during OOM")
3422 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3423 raise Exception("REQ_HS20_ICON failed")
3424 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3426 raise Exception("Timeout on RX-HS20-ICON (1)")
3428 with
alloc_fail(dev
[0], 1, "hs20_get_icon"):
3429 if "FAIL" not in dev
[0].request("GET_HS20_ICON " + bssid
+ "w1fi_logo 0 100"):
3430 raise Exception("GET_HS20_ICON succeeded during OOM")
3432 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3433 raise Exception("DEL_HS20_ICON failed")
3435 with
alloc_fail(dev
[0], 1, "=hs20_process_icon_binary_file"):
3436 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3437 raise Exception("REQ_HS20_ICON failed")
3438 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
3440 def test_ap_hs20_req_hs20_icon_parallel(dev
, apdev
):
3441 """Hotspot 2.0 OSU provider and multi-icon parallel fetch with REQ_HS20_ICON"""
3442 bssid
= apdev
[0]['bssid']
3443 params
= hs20_ap_params()
3444 params
['hs20_icon'] = ["128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3445 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem"]
3446 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3447 params
['osu_method_list'] = "1"
3448 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3449 params
['osu_icon'] = ["w1fi_logo", "w1fi_logo2"]
3450 params
['osu_service_desc'] = ["eng:Example services",
3451 "fin:Esimerkkipalveluja"]
3452 params
['osu_server_uri'] = "https://example.com/osu/"
3453 hostapd
.add_ap(apdev
[0], params
)
3455 dev
[0].scan_for_bss(bssid
, freq
="2412")
3457 # First, fetch two icons from the AP to wpa_supplicant
3459 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3460 raise Exception("REQ_HS20_ICON failed")
3462 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
3463 raise Exception("REQ_HS20_ICON failed")
3464 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3466 raise Exception("Timeout on RX-HS20-ICON (1)")
3467 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3469 raise Exception("Timeout on RX-HS20-ICON (2)")
3471 # Then, fetch the icons from wpa_supplicant for validation
3473 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
3474 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
3476 with
open('w1fi_logo.png', 'rb') as f
:
3479 raise Exception("Unexpected icon data (1)")
3481 with
open('auth_serv/sha512-server.pem', 'rb') as f
:
3484 raise Exception("Unexpected icon data (2)")
3486 # Finally, delete the icons from wpa_supplicant
3488 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3489 raise Exception("DEL_HS20_ICON failed")
3490 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
3491 raise Exception("DEL_HS20_ICON failed")
3493 def test_ap_hs20_fetch_osu_stop(dev
, apdev
):
3494 """Hotspot 2.0 OSU provider fetch stopped"""
3495 bssid
= apdev
[0]['bssid']
3496 params
= hs20_ap_params()
3497 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3498 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3499 params
['osu_method_list'] = "1"
3500 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3501 params
['osu_icon'] = "w1fi_logo"
3502 params
['osu_service_desc'] = ["eng:Example services",
3503 "fin:Esimerkkipalveluja"]
3504 params
['osu_server_uri'] = "https://example.com/osu/"
3505 hapd
= hostapd
.add_ap(apdev
[0], params
)
3507 dev
[0].hs20_enable()
3508 dir = "/tmp/osu-fetch"
3509 if os
.path
.isdir(dir):
3510 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3512 os
.remove(dir + "/" + f
)
3519 dev
[0].request("SET osu_dir " + dir)
3520 dev
[0].request("SCAN freq=2412-2462")
3521 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=10)
3523 raise Exception("Scan did not start")
3524 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3525 raise Exception("FETCH_OSU accepted while scanning")
3526 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
3528 raise Exception("Scan timed out")
3529 hapd
.set("ext_mgmt_frame_handling", "1")
3530 dev
[0].request("FETCH_ANQP")
3531 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3532 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
3533 dev
[0].request("STOP_FETCH_ANQP")
3534 dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=5)
3535 dev
[0].dump_monitor()
3537 dev
[0].request("INTERWORKING_SELECT freq=2412")
3539 msg
= hapd
.mgmt_rx()
3540 if msg
['subtype'] == 13:
3542 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3543 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
3544 ev
= dev
[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
3547 raise Exception("Network selection timed out")
3549 dev
[0].dump_monitor()
3550 if "OK" not in dev
[0].request("FETCH_OSU"):
3551 raise Exception("FETCH_OSU failed")
3552 dev
[0].request("CANCEL_FETCH_OSU")
3556 if dev
[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
3559 dev
[0].dump_monitor()
3560 if "OK" not in dev
[0].request("FETCH_OSU"):
3561 raise Exception("FETCH_OSU failed")
3562 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3563 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
3564 ev
= dev
[0].wait_event(["GAS-QUERY-START"], 10)
3566 raise Exception("GAS timed out")
3567 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3568 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
3569 dev
[0].request("CANCEL_FETCH_OSU")
3570 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], 10)
3572 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
3574 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3576 os
.remove(dir + "/" + f
)
3579 def test_ap_hs20_fetch_osu_proto(dev
, apdev
):
3580 """Hotspot 2.0 OSU provider and protocol testing"""
3581 bssid
= apdev
[0]['bssid']
3582 params
= hs20_ap_params()
3583 hapd
= hostapd
.add_ap(apdev
[0], params
)
3585 dev
[0].hs20_enable()
3586 dir = "/tmp/osu-fetch"
3587 if os
.path
.isdir(dir):
3588 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3590 os
.remove(dir + "/" + f
)
3597 tests
= [("Empty provider list (no OSU SSID field)", b
''),
3598 ("HS 2.0: Not enough room for OSU SSID",
3599 binascii
.unhexlify('01')),
3600 ("HS 2.0: Invalid OSU SSID Length 33",
3601 binascii
.unhexlify('21') + 33*b
'A'),
3602 ("HS 2.0: Not enough room for Number of OSU Providers",
3603 binascii
.unhexlify('0130')),
3604 ("Truncated OSU Provider",
3605 binascii
.unhexlify('013001020000')),
3606 ("HS 2.0: Ignored 5 bytes of extra data after OSU Providers",
3607 binascii
.unhexlify('0130001122334455')),
3608 ("HS 2.0: Not enough room for OSU Friendly Name Length",
3609 binascii
.unhexlify('013001000000')),
3610 ("HS 2.0: Not enough room for OSU Friendly Name Duples",
3611 build_prov('0100')),
3612 ("Invalid OSU Friendly Name", build_prov('040000000000')),
3613 ("Invalid OSU Friendly Name(2)", build_prov('040004000000')),
3614 ("HS 2.0: Not enough room for OSU Server URI length",
3615 build_prov('0000')),
3616 ("HS 2.0: Not enough room for OSU Server URI",
3617 build_prov('000001')),
3618 ("HS 2.0: Not enough room for OSU Method list length",
3619 build_prov('000000')),
3620 ("HS 2.0: Not enough room for OSU Method list",
3621 build_prov('00000001')),
3622 ("HS 2.0: Not enough room for Icons Available Length",
3623 build_prov('00000000')),
3624 ("HS 2.0: Not enough room for Icons Available Length(2)",
3625 build_prov('00000001ff00')),
3626 ("HS 2.0: Not enough room for Icons Available",
3627 build_prov('000000000100')),
3628 ("HS 2.0: Invalid Icon Metadata",
3629 build_prov('00000000010000')),
3630 ("HS 2.0: Not room for Icon Type",
3631 build_prov('000000000900111122223333330200')),
3632 ("HS 2.0: Not room for Icon Filename length",
3633 build_prov('000000000900111122223333330100')),
3634 ("HS 2.0: Not room for Icon Filename",
3635 build_prov('000000000900111122223333330001')),
3636 ("HS 2.0: Not enough room for OSU_NAI",
3637 build_prov('000000000000')),
3638 ("HS 2.0: Not enough room for OSU_NAI(2)",
3639 build_prov('00000000000001')),
3640 ("HS 2.0: Not enough room for OSU Service Description Length",
3641 build_prov('00000000000000')),
3642 ("HS 2.0: Not enough room for OSU Service Description Length(2)",
3643 build_prov('0000000000000000')),
3644 ("HS 2.0: Not enough room for OSU Service Description Duples",
3645 build_prov('000000000000000100')),
3646 ("Invalid OSU Service Description",
3647 build_prov('00000000000000040000000000')),
3648 ("Invalid OSU Service Description(2)",
3649 build_prov('00000000000000040004000000'))]
3652 dev
[0].request("SET osu_dir " + dir)
3653 run_fetch_osu_icon_failure(hapd
, dev
, bssid
)
3654 for note
, prov
in tests
:
3655 run_fetch_osu(hapd
, dev
, bssid
, note
, prov
)
3657 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3659 os
.remove(dir + "/" + f
)
3662 def test_ap_hs20_fetch_osu_invalid_dir(dev
, apdev
):
3663 """Hotspot 2.0 OSU provider and invalid directory"""
3664 bssid
= apdev
[0]['bssid']
3665 params
= hs20_ap_params()
3666 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3667 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3668 params
['osu_method_list'] = "1"
3669 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3670 params
['osu_icon'] = "w1fi_logo"
3671 params
['osu_service_desc'] = ["eng:Example services",
3672 "fin:Esimerkkipalveluja"]
3673 params
['osu_server_uri'] = "https://example.com/osu/"
3674 hostapd
.add_ap(apdev
[0], params
)
3676 dev
[0].hs20_enable()
3677 dir = "/tmp/osu-fetch-no-such-dir"
3678 dev
[0].scan_for_bss(bssid
, freq
="2412")
3679 dev
[0].request("SET osu_dir " + dir)
3680 dev
[0].request("FETCH_OSU no-scan")
3681 ev
= dev
[0].wait_event(["Could not write OSU provider information"],
3684 raise Exception("Timeout on OSU fetch")
3686 def test_ap_hs20_fetch_osu_oom(dev
, apdev
):
3687 """Hotspot 2.0 OSU provider and OOM"""
3688 bssid
= apdev
[0]['bssid']
3689 params
= hs20_ap_params()
3690 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3691 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3692 params
['osu_method_list'] = "1"
3693 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3694 params
['osu_icon'] = "w1fi_logo"
3695 params
['osu_service_desc'] = ["eng:Example services",
3696 "fin:Esimerkkipalveluja"]
3697 params
['osu_server_uri'] = "https://example.com/osu/"
3698 hostapd
.add_ap(apdev
[0], params
)
3700 dev
[0].hs20_enable()
3701 dir = "/tmp/osu-fetch"
3702 if os
.path
.isdir(dir):
3703 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3705 os
.remove(dir + "/" + f
)
3711 dev
[0].scan_for_bss(bssid
, freq
="2412")
3713 dev
[0].request("SET osu_dir " + dir)
3714 with
alloc_fail(dev
[0], 1, "=hs20_osu_add_prov"):
3715 dev
[0].request("FETCH_OSU no-scan")
3716 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3718 raise Exception("Timeout on OSU fetch")
3719 with
alloc_fail(dev
[0], 1, "hs20_anqp_send_req;hs20_next_osu_icon"):
3720 dev
[0].request("FETCH_OSU no-scan")
3721 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3723 raise Exception("Timeout on OSU fetch")
3725 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3727 os
.remove(dir + "/" + f
)
3730 def build_prov(prov
):
3731 data
= binascii
.unhexlify(prov
)
3732 return binascii
.unhexlify('013001') + struct
.pack('<H', len(data
)) + data
3734 def handle_osu_prov_fetch(hapd
, dev
, prov
):
3735 # GAS/ANQP query for OSU Providers List
3736 query
= gas_rx(hapd
)
3737 gas
= parse_gas(query
['payload'])
3738 dialog_token
= gas
['dialog_token']
3740 resp
= action_response(query
)
3741 osu_prov
= struct
.pack('<HH', 0xdddd, len(prov
) + 6) + binascii
.unhexlify('506f9a110800') + prov
3742 data
= struct
.pack('<H', len(osu_prov
)) + osu_prov
3743 resp
['payload'] = anqp_initial_resp(dialog_token
, 0) + data
3744 send_gas_resp(hapd
, resp
)
3746 ev
= dev
[0].wait_event(["RX-HS20-ANQP"], timeout
=5)
3748 raise Exception("ANQP query response for OSU Providers not received")
3749 if "OSU Providers list" not in ev
:
3750 raise Exception("ANQP query response for OSU Providers not received(2)")
3751 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
3753 raise Exception("ANQP query for OSU Providers list not completed")
3755 def start_osu_fetch(hapd
, dev
, bssid
, note
):
3756 hapd
.set("ext_mgmt_frame_handling", "0")
3757 dev
[0].request("BSS_FLUSH 0")
3758 dev
[0].scan_for_bss(bssid
, freq
="2412")
3759 hapd
.set("ext_mgmt_frame_handling", "1")
3760 dev
[0].dump_monitor()
3761 dev
[0].request("NOTE " + note
)
3762 dev
[0].request("FETCH_OSU no-scan")
3764 def wait_osu_fetch_completed(dev
):
3765 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=5)
3767 raise Exception("Timeout on OSU fetch")
3769 def run_fetch_osu_icon_failure(hapd
, dev
, bssid
):
3770 start_osu_fetch(hapd
, dev
, bssid
, "Icon fetch failure")
3772 prov
= binascii
.unhexlify('01ff' + '01' + '800019000b656e6754657374204f53550c66696e54657374692d4f53551868747470733a2f2f6578616d706c652e636f6d2f6f73752f01011b00800050007a787809696d6167652f706e6709773166695f6c6f676f002a0013656e674578616d706c652073657276696365731566696e4573696d65726b6b6970616c76656c756a61')
3773 handle_osu_prov_fetch(hapd
, dev
, prov
)
3775 # GAS/ANQP query for icon
3776 query
= gas_rx(hapd
)
3777 gas
= parse_gas(query
['payload'])
3778 dialog_token
= gas
['dialog_token']
3780 resp
= action_response(query
)
3781 # Unexpected Advertisement Protocol in response
3782 adv_proto
= struct
.pack('8B', 108, 6, 127, 0xdd, 0x00, 0x11, 0x22, 0x33)
3783 data
= struct
.pack('<H', 0)
3784 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
3785 GAS_INITIAL_RESPONSE
,
3786 gas
['dialog_token'], 0, 0) + adv_proto
+ data
3787 send_gas_resp(hapd
, resp
)
3789 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
3791 raise Exception("ANQP query for icon not completed")
3793 wait_osu_fetch_completed(dev
)
3795 def run_fetch_osu(hapd
, dev
, bssid
, note
, prov
):
3796 start_osu_fetch(hapd
, dev
, bssid
, note
)
3797 handle_osu_prov_fetch(hapd
, dev
, prov
)
3798 wait_osu_fetch_completed(dev
)
3800 def test_ap_hs20_ft(dev
, apdev
):
3801 """Hotspot 2.0 connection with FT"""
3802 check_eap_capa(dev
[0], "MSCHAPV2")
3803 bssid
= apdev
[0]['bssid']
3804 params
= hs20_ap_params()
3805 params
['wpa_key_mgmt'] = "FT-EAP"
3806 params
['nas_identifier'] = "nas1.w1.fi"
3807 params
['r1_key_holder'] = "000102030405"
3808 params
["mobility_domain"] = "a1b2"
3809 params
["reassociation_deadline"] = "1000"
3810 hapd
= hostapd
.add_ap(apdev
[0], params
)
3812 dev
[0].hs20_enable()
3813 id = dev
[0].add_cred_values({'realm': "example.com",
3814 'username': "hs20-test",
3815 'password': "password",
3816 'ca_cert': "auth_serv/ca.pem",
3817 'domain': "example.com",
3818 'update_identifier': "1234"})
3819 interworking_select(dev
[0], bssid
, "home", freq
="2412")
3820 interworking_connect(dev
[0], bssid
, "TTLS")
3821 dev
[0].dump_monitor()
3822 key_mgmt
= dev
[0].get_status_field("key_mgmt")
3823 if key_mgmt
!= "FT-EAP":
3824 raise Exception("Unexpected key_mgmt: " + key_mgmt
)
3825 # speed up testing by avoiding unnecessary scanning of other channels
3826 nid
= dev
[0].get_status_field("id")
3827 dev
[0].set_network(nid
, "scan_freq", "2412")
3829 params
= hs20_ap_params()
3830 hapd2
= hostapd
.add_ap(apdev
[1], params
)
3833 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=10)
3835 raise Exception("Disconnection not reported")
3836 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=5)
3838 raise Exception("Connection to AP2 not reported")
3839 key_mgmt
= dev
[0].get_status_field("key_mgmt")
3840 if key_mgmt
!= "WPA2/IEEE 802.1X/EAP":
3841 raise Exception("Unexpected key_mgmt: " + key_mgmt
)
3843 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
3844 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
3845 check_eap_capa(dev
[0], "MSCHAPV2")
3849 raise HwsimSkip("No sqlite3 module available")
3850 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
3855 con
= sqlite3
.connect(dbfile
)
3858 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
3859 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
3860 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
3861 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
3862 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
3865 params
= {"ssid": "as", "beacon_int": "2000",
3866 "radius_server_clients": "auth_serv/radius_clients.conf",
3867 "radius_server_auth_port": '18128',
3869 "eap_user_file": "sqlite:" + dbfile
,
3870 "ca_cert": "auth_serv/ca.pem",
3871 "server_cert": "auth_serv/server.pem",
3872 "private_key": "auth_serv/server.key",
3873 "subscr_remediation_url": "https://example.org/",
3874 "subscr_remediation_method": "1"}
3875 hostapd
.add_ap(apdev
[1], params
)
3877 bssid
= apdev
[0]['bssid']
3878 params
= hs20_ap_params()
3879 params
['auth_server_port'] = "18128"
3880 hostapd
.add_ap(apdev
[0], params
)
3882 dev
[0].request("SET pmf 1")
3883 dev
[0].hs20_enable()
3884 id = dev
[0].add_cred_values({'realm': "example.com",
3885 'username': "user-mschapv2",
3886 'password': "password",
3887 'ca_cert': "auth_serv/ca.pem"})
3888 interworking_select(dev
[0], bssid
, freq
="2412")
3889 interworking_connect(dev
[0], bssid
, "TTLS")
3890 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
3892 raise Exception("Timeout on subscription remediation notice")
3893 if " 1 https://example.org/" not in ev
:
3894 raise Exception("Unexpected subscription remediation event contents")
3898 cur
.execute("SELECT * from authlog")
3899 rows
= cur
.fetchall()
3901 raise Exception("No authlog entries")
3905 dev
[0].request("SET pmf 0")
3907 def test_ap_hs20_sim_provisioning(dev
, apdev
, params
):
3908 """Hotspot 2.0 AAA server behavior for SIM provisioning"""
3909 check_eap_capa(dev
[0], "SIM")
3913 raise HwsimSkip("No sqlite3 module available")
3914 dbfile
= os
.path
.join(params
['logdir'], "ap_hs20_sim_provisioning-eap-user.db")
3919 con
= sqlite3
.connect(dbfile
)
3922 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER, last_msk TEXT)")
3923 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
3924 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('1','SIM')")
3925 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
3926 cur
.execute("CREATE TABLE current_sessions(mac_addr TEXT PRIMARY KEY, identity TEXT, start_time TEXT, nas TEXT, hs20_t_c_filtering BOOLEAN, waiting_coa_ack BOOLEAN, coa_ack_received BOOLEAN)")
3929 params
= {"ssid": "as", "beacon_int": "2000",
3930 "radius_server_clients": "auth_serv/radius_clients.conf",
3931 "radius_server_auth_port": '18128',
3933 "eap_user_file": "sqlite:" + dbfile
,
3934 "eap_sim_db": "unix:/tmp/hlr_auc_gw.sock",
3935 "ca_cert": "auth_serv/ca.pem",
3936 "server_cert": "auth_serv/server.pem",
3937 "private_key": "auth_serv/server.key",
3938 "hs20_sim_provisioning_url":
3939 "https://example.org/?hotspot2dot0-mobile-identifier-hash=",
3940 "subscr_remediation_method": "1"}
3941 hostapd
.add_ap(apdev
[1], params
)
3943 bssid
= apdev
[0]['bssid']
3944 params
= hs20_ap_params()
3945 params
['auth_server_port'] = "18128"
3946 hostapd
.add_ap(apdev
[0], params
)
3948 dev
[0].request("SET pmf 1")
3949 dev
[0].hs20_enable()
3950 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="SIM",
3952 identity
="1232010000000000",
3953 password
="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
3954 scan_freq
="2412", update_identifier
="54321")
3955 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=0.5)
3957 raise Exception("Unexpected subscription remediation notice")
3958 dev
[0].request("REMOVE_NETWORK all")
3959 dev
[0].wait_disconnected()
3960 dev
[0].dump_monitor()
3962 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="SIM",
3964 identity
="1232010000000000",
3965 password
="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
3966 scan_freq
="2412", update_identifier
="0")
3967 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
3969 raise Exception("Timeout on subscription remediation notice")
3970 if " 1 https://example.org/?hotspot2dot0-mobile-identifier-hash=" not in ev
:
3971 raise Exception("Unexpected subscription remediation event contents: " + ev
)
3972 id_hash
= ev
.split(' ')[2].split('=')[1]
3976 cur
.execute("SELECT * from authlog")
3977 rows
= cur
.fetchall()
3979 raise Exception("No authlog entries")
3983 cur
.execute("SELECT * from sim_provisioning")
3984 rows
= cur
.fetchall()
3986 raise Exeception("Unexpected number of rows in sim_provisioning (%d; expected %d)" % (len(rows
), 1))
3987 logger
.info("sim_provisioning: " + str(rows
))
3988 if len(rows
[0][0]) != 32:
3989 raise Exception("Unexpected mobile_identifier_hash length in DB")
3990 if rows
[0][1] != "232010000000000":
3991 raise Exception("Unexpected IMSI in DB")
3992 if rows
[0][2] != dev
[0].own_addr():
3993 raise Exception("Unexpected MAC address in DB")
3994 if rows
[0][0] != id_hash
:
3995 raise Exception("hotspot2dot0-mobile-identifier-hash mismatch")
3997 dev
[0].request("SET pmf 0")
3999 def test_ap_hs20_external_selection(dev
, apdev
):
4000 """Hotspot 2.0 connection using external network selection and creation"""
4001 check_eap_capa(dev
[0], "MSCHAPV2")
4002 bssid
= apdev
[0]['bssid']
4003 params
= hs20_ap_params()
4004 params
['hessid'] = bssid
4005 params
['disable_dgaf'] = '1'
4006 hostapd
.add_ap(apdev
[0], params
)
4008 dev
[0].hs20_enable()
4009 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
4011 identity
="hs20-test", password
="password",
4012 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
4013 scan_freq
="2412", update_identifier
="54321",
4014 roaming_consortium_selection
="1020304050")
4015 if dev
[0].get_status_field("hs20") != "3":
4016 raise Exception("Unexpected hs20 indication")
4017 network_id
= dev
[0].get_status_field("id")
4018 sel
= dev
[0].get_network(network_id
, "roaming_consortium_selection")
4019 if sel
!= "1020304050":
4020 raise Exception("Unexpected roaming_consortium_selection value: " + sel
)
4022 def test_ap_hs20_random_mac_addr(dev
, apdev
):
4023 """Hotspot 2.0 connection with random MAC address"""
4024 check_eap_capa(dev
[0], "MSCHAPV2")
4025 bssid
= apdev
[0]['bssid']
4026 params
= hs20_ap_params()
4027 params
['hessid'] = bssid
4028 params
['disable_dgaf'] = '1'
4029 hapd
= hostapd
.add_ap(apdev
[0], params
)
4031 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
4032 wpas
.interface_add("wlan5")
4033 addr
= wpas
.p2p_interface_addr()
4034 wpas
.request("SET mac_addr 1")
4035 wpas
.request("SET preassoc_mac_addr 1")
4036 wpas
.request("SET rand_addr_lifetime 60")
4038 wpas
.flush_scan_cache()
4039 id = wpas
.add_cred_values({'realm': "example.com",
4040 'username': "hs20-test",
4041 'password': "password",
4042 'ca_cert': "auth_serv/ca.pem",
4043 'domain': "example.com",
4044 'update_identifier': "1234"})
4045 interworking_select(wpas
, bssid
, "home", freq
="2412")
4046 interworking_connect(wpas
, bssid
, "TTLS")
4047 addr1
= wpas
.get_driver_status_field("addr")
4049 raise Exception("Did not use random MAC address")
4051 sta
= hapd
.get_sta(addr
)
4052 if sta
['addr'] != "FAIL":
4053 raise Exception("Unexpected STA association with permanent address")
4054 sta
= hapd
.get_sta(addr1
)
4055 if sta
['addr'] != addr1
:
4056 raise Exception("STA association with random address not found")
4058 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
4059 """Multiple networks and cred removal"""
4060 check_eap_capa(dev
[0], "MSCHAPV2")
4061 bssid
= apdev
[0]['bssid']
4062 params
= hs20_ap_params()
4063 params
['nai_realm'] = ["0,example.com,25[3:26]"]
4064 hapd
= hostapd
.add_ap(apdev
[0], params
)
4066 dev
[0].add_network()
4067 dev
[0].hs20_enable()
4068 id = dev
[0].add_cred_values({'realm': "example.com",
4070 'password': "password"})
4071 interworking_select(dev
[0], bssid
, freq
="2412")
4072 interworking_connect(dev
[0], bssid
, "PEAP")
4073 dev
[0].add_network()
4075 dev
[0].request("DISCONNECT")
4076 dev
[0].wait_disconnected(timeout
=10)
4079 hapd
.set("ssid", "another ssid")
4082 interworking_select(dev
[0], bssid
, freq
="2412")
4083 interworking_connect(dev
[0], bssid
, "PEAP")
4084 dev
[0].add_network()
4085 if len(dev
[0].list_networks()) != 5:
4086 raise Exception("Unexpected number of networks prior to remove_crec")
4088 dev
[0].dump_monitor()
4089 dev
[0].remove_cred(id)
4090 if len(dev
[0].list_networks()) != 3:
4091 raise Exception("Unexpected number of networks after to remove_crec")
4092 dev
[0].wait_disconnected(timeout
=10)
4094 def test_ap_hs20_interworking_add_network(dev
, apdev
):
4095 """Hotspot 2.0 connection using INTERWORKING_ADD_NETWORK"""
4096 check_eap_capa(dev
[0], "MSCHAPV2")
4097 bssid
= apdev
[0]['bssid']
4098 params
= hs20_ap_params()
4099 params
['nai_realm'] = ["0,example.com,21[3:26][6:7][99:99]"]
4100 hostapd
.add_ap(apdev
[0], params
)
4102 dev
[0].hs20_enable()
4103 dev
[0].add_cred_values(default_cred(user
="user"))
4104 interworking_select(dev
[0], bssid
, freq
=2412)
4105 id = dev
[0].interworking_add_network(bssid
)
4106 dev
[0].select_network(id, freq
=2412)
4107 dev
[0].wait_connected()
4109 def _test_ap_hs20_proxyarp(dev
, apdev
):
4110 bssid
= apdev
[0]['bssid']
4111 params
= hs20_ap_params()
4112 params
['hessid'] = bssid
4113 params
['disable_dgaf'] = '0'
4114 params
['proxy_arp'] = '1'
4115 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4116 if "OK" in hapd
.request("ENABLE"):
4117 raise Exception("Incomplete hostapd configuration was accepted")
4118 hapd
.set("ap_isolate", "1")
4119 if "OK" in hapd
.request("ENABLE"):
4120 raise Exception("Incomplete hostapd configuration was accepted")
4121 hapd
.set('bridge', 'ap-br0')
4126 # For now, do not report failures due to missing kernel support
4127 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4128 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4130 raise Exception("AP startup timed out")
4131 if "AP-ENABLED" not in ev
:
4132 raise Exception("AP startup failed")
4134 dev
[0].hs20_enable()
4135 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4136 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4138 id = dev
[0].add_cred_values({'realm': "example.com",
4139 'username': "hs20-test",
4140 'password': "password",
4141 'ca_cert': "auth_serv/ca.pem",
4142 'domain': "example.com",
4143 'update_identifier': "1234"})
4144 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4145 interworking_connect(dev
[0], bssid
, "TTLS")
4147 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
4148 identity
="hs20-test", password
="password",
4149 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
4153 addr0
= dev
[0].p2p_interface_addr()
4154 addr1
= dev
[1].p2p_interface_addr()
4156 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':', ''))
4157 src_ll_opt1
= b
"\x01\x01" + binascii
.unhexlify(addr1
.replace(':', ''))
4159 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
4160 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
4162 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4163 raise Exception("DATA_TEST_FRAME failed")
4165 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
4166 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
4168 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4169 raise Exception("DATA_TEST_FRAME failed")
4171 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
4172 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
4174 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4175 raise Exception("DATA_TEST_FRAME failed")
4177 matches
= get_permanent_neighbors("ap-br0")
4178 logger
.info("After connect: " + str(matches
))
4179 if len(matches
) != 3:
4180 raise Exception("Unexpected number of neighbor entries after connect")
4181 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4182 raise Exception("dev0 addr missing")
4183 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
4184 raise Exception("dev1 addr(1) missing")
4185 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
4186 raise Exception("dev1 addr(2) missing")
4187 dev
[0].request("DISCONNECT")
4188 dev
[1].request("DISCONNECT")
4190 matches
= get_permanent_neighbors("ap-br0")
4191 logger
.info("After disconnect: " + str(matches
))
4192 if len(matches
) > 0:
4193 raise Exception("Unexpected neighbor entries after disconnect")
4195 def test_ap_hs20_hidden_ssid_in_scan_res(dev
, apdev
):
4196 """Hotspot 2.0 connection with hidden SSId in scan results"""
4197 check_eap_capa(dev
[0], "MSCHAPV2")
4198 bssid
= apdev
[0]['bssid']
4200 hapd
= hostapd
.add_ap(apdev
[0], {"ssid": 'secret',
4201 "ignore_broadcast_ssid": "1"})
4202 dev
[0].scan_for_bss(bssid
, freq
=2412)
4204 hapd_global
= hostapd
.HostapdGlobal(apdev
[0])
4206 hapd_global
.remove(apdev
[0]['ifname'])
4208 params
= hs20_ap_params()
4209 params
['hessid'] = bssid
4210 hapd
= hostapd
.add_ap(apdev
[0], params
)
4212 dev
[0].hs20_enable()
4213 id = dev
[0].add_cred_values({'realm': "example.com",
4214 'username': "hs20-test",
4215 'password': "password",
4216 'ca_cert': "auth_serv/ca.pem",
4217 'domain': "example.com"})
4218 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4219 interworking_connect(dev
[0], bssid
, "TTLS")
4221 # clear BSS table to avoid issues in following test cases
4222 dev
[0].request("DISCONNECT")
4223 dev
[0].wait_disconnected()
4225 dev
[0].flush_scan_cache()
4226 dev
[0].flush_scan_cache()
4228 def test_ap_hs20_proxyarp(dev
, apdev
):
4229 """Hotspot 2.0 and ProxyARP"""
4230 check_eap_capa(dev
[0], "MSCHAPV2")
4232 _test_ap_hs20_proxyarp(dev
, apdev
)
4234 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4235 stderr
=open('/dev/null', 'w'))
4236 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4237 stderr
=open('/dev/null', 'w'))
4239 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
4240 bssid
= apdev
[0]['bssid']
4241 params
= hs20_ap_params()
4242 params
['hessid'] = bssid
4243 params
['disable_dgaf'] = '1' if disabled
else '0'
4244 params
['proxy_arp'] = '1'
4245 params
['na_mcast_to_ucast'] = '1'
4246 params
['ap_isolate'] = '1'
4247 params
['bridge'] = 'ap-br0'
4248 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4252 # For now, do not report failures due to missing kernel support
4253 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4254 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
4256 raise Exception("AP startup timed out")
4258 dev
[0].hs20_enable()
4259 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4260 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4262 id = dev
[0].add_cred_values({'realm': "example.com",
4263 'username': "hs20-test",
4264 'password': "password",
4265 'ca_cert': "auth_serv/ca.pem",
4266 'domain': "example.com",
4267 'update_identifier': "1234"})
4268 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4269 interworking_connect(dev
[0], bssid
, "TTLS")
4271 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
4272 identity
="hs20-test", password
="password",
4273 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
4277 addr0
= dev
[0].p2p_interface_addr()
4279 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':', ''))
4281 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
4282 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
4284 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4285 raise Exception("DATA_TEST_FRAME failed")
4287 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
4289 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4290 raise Exception("DATA_TEST_FRAME failed")
4292 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
4293 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
4294 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4295 raise Exception("DATA_TEST_FRAME failed")
4297 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4298 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4299 yiaddr
="192.168.1.123", chaddr
=addr0
)
4300 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4301 raise Exception("DATA_TEST_FRAME failed")
4302 # another copy for additional code coverage
4303 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
4304 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4305 yiaddr
="192.168.1.123", chaddr
=addr0
)
4306 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4307 raise Exception("DATA_TEST_FRAME failed")
4309 matches
= get_permanent_neighbors("ap-br0")
4310 logger
.info("After connect: " + str(matches
))
4311 if len(matches
) != 2:
4312 raise Exception("Unexpected number of neighbor entries after connect")
4313 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4314 raise Exception("dev0 addr missing")
4315 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4316 raise Exception("dev0 IPv4 addr missing")
4317 dev
[0].request("DISCONNECT")
4318 dev
[1].request("DISCONNECT")
4320 matches
= get_permanent_neighbors("ap-br0")
4321 logger
.info("After disconnect: " + str(matches
))
4322 if len(matches
) > 0:
4323 raise Exception("Unexpected neighbor entries after disconnect")
4325 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
4326 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
4327 check_eap_capa(dev
[0], "MSCHAPV2")
4329 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
4331 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4332 stderr
=open('/dev/null', 'w'))
4333 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4334 stderr
=open('/dev/null', 'w'))
4336 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
4337 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
4338 check_eap_capa(dev
[0], "MSCHAPV2")
4340 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
4342 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4343 stderr
=open('/dev/null', 'w'))
4344 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4345 stderr
=open('/dev/null', 'w'))
4347 def ip_checksum(buf
):
4351 for i
in range(0, len(buf
), 2):
4352 val
, = struct
.unpack('H', buf
[i
:i
+2])
4355 sum = (sum & 0xffff) + (sum >> 16)
4356 return struct
.pack('H', ~
sum & 0xffff)
4358 def ipv6_solicited_node_mcaddr(target
):
4359 prefix
= socket
.inet_pton(socket
.AF_INET6
, "ff02::1:ff00:0")
4360 mask
= socket
.inet_pton(socket
.AF_INET6
, "::ff:ffff")
4361 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4362 p
= struct
.unpack('4I', prefix
)
4363 m
= struct
.unpack('4I', mask
)
4364 t
= struct
.unpack('4I', _target
)
4365 res
= (p
[0] |
(t
[0] & m
[0]),
4366 p
[1] |
(t
[1] & m
[1]),
4367 p
[2] |
(t
[2] & m
[2]),
4368 p
[3] |
(t
[3] & m
[3]))
4369 return socket
.inet_ntop(socket
.AF_INET6
, struct
.pack('4I', *res
))
4371 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
4372 start
= struct
.pack("BB", type, code
)
4374 icmp
= start
+ b
'\x00\x00' + end
4375 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
4376 csum
= ip_checksum(pseudo
+ icmp
)
4377 return start
+ csum
+ end
4379 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
4380 reachable_time
=0, retrans_timer
=0, opt
=None):
4381 link_mc
= binascii
.unhexlify("3333ff000002")
4382 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4384 ehdr
= link_mc
+ _src_ll
+ proto
4385 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4386 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4388 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
4389 reachable_time
, retrans_timer
)
4394 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
4396 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4397 ipv6
+= _ip_src
+ _ip_dst
4399 return ehdr
+ ipv6
+ icmp
4401 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
4402 link_mc
= binascii
.unhexlify("3333ff000002")
4403 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4405 ehdr
= link_mc
+ _src_ll
+ proto
4406 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4408 ip_dst
= ipv6_solicited_node_mcaddr(target
)
4409 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4411 reserved
= b
'\x00\x00\x00\x00'
4412 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4414 payload
= reserved
+ _target
+ opt
4416 payload
= reserved
+ _target
4417 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
4419 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4420 ipv6
+= _ip_src
+ _ip_dst
4422 return ehdr
+ ipv6
+ icmp
4424 def send_ns(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
4429 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4432 src_ll
= dev
.p2p_interface_addr()
4433 cmd
= "DATA_TEST_FRAME "
4436 opt
= b
"\x01\x01" + binascii
.unhexlify(src_ll
.replace(':', ''))
4438 pkt
= build_ns(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
4440 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4441 raise Exception("DATA_TEST_FRAME failed")
4443 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None, flags
=0):
4444 link_mc
= binascii
.unhexlify("3333ff000002")
4445 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4447 ehdr
= link_mc
+ _src_ll
+ proto
4448 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4449 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4451 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4453 payload
= struct
.pack('>Bxxx', flags
) + _target
+ opt
4455 payload
= struct
.pack('>Bxxx', flags
) + _target
4456 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
4458 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4459 ipv6
+= _ip_src
+ _ip_dst
4461 return ehdr
+ ipv6
+ icmp
4463 def send_na(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
4468 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4471 src_ll
= dev
.p2p_interface_addr()
4472 cmd
= "DATA_TEST_FRAME "
4474 pkt
= build_na(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
4476 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4477 raise Exception("DATA_TEST_FRAME failed")
4479 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
4480 subnet_mask
="255.255.255.0", truncated_opt
=False,
4481 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False,
4483 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':', ''))
4484 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4486 ehdr
= _dst_ll
+ _src_ll
+ proto
4487 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
4488 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
4489 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
4491 _ciaddr
= b
'\x00\x00\x00\x00'
4492 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
4493 _siaddr
= b
'\x00\x00\x00\x00'
4494 _giaddr
= b
'\x00\x00\x00\x00'
4495 _chaddr
= binascii
.unhexlify(chaddr
.replace(':', '') + "00000000000000000000")
4496 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
4497 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*b
'\x00'
4500 payload
+= b
'\x63\x82\x53\x00'
4502 payload
+= b
'\x63\x82\x53\x63'
4504 payload
+= b
'\x22\xff\x00'
4505 # Option: DHCP Message Type = ACK
4506 payload
+= b
'\x35\x01\x05'
4509 # Option: Subnet Mask
4510 payload
+= b
'\x01\x04' + _subnet_mask
4511 # Option: Time Offset
4512 payload
+= struct
.pack('>BBL', 2, 4, 0)
4516 payload
+= b
'\x00\x00\x00\x00'
4519 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
4520 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*b
'\x00'
4523 pseudohdr
= _ip_src
+ _ip_dst
+ struct
.pack('>BBH', 0, 17,
4525 udphdr
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0)
4526 checksum
, = struct
.unpack('>H', ip_checksum(pseudohdr
+ udphdr
+ payload
))
4529 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), checksum
) + payload
4532 tot_len
= force_tot_len
4534 tot_len
= 20 + len(udp
)
4535 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
4536 ipv4
= start
+ b
'\x00\x00' + _ip_src
+ _ip_dst
4537 csum
= ip_checksum(ipv4
)
4538 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
4540 return ehdr
+ ipv4
+ udp
4542 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
4543 target_mac
, target_ip
):
4544 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':', ''))
4545 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4547 ehdr
= _dst_ll
+ _src_ll
+ proto
4549 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':', ''))
4550 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
4551 _target_mac
= binascii
.unhexlify(target_mac
.replace(':', ''))
4552 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
4554 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
4555 arp
+= _sender_mac
+ _sender_ip
4556 arp
+= _target_mac
+ _target_ip
4560 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
4561 sender_mac
=None, sender_ip
="0.0.0.0",
4562 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
4567 if sender_mac
is None:
4568 sender_mac
= hapd_bssid
4569 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4572 src_ll
= dev
.p2p_interface_addr()
4573 if sender_mac
is None:
4574 sender_mac
= dev
.p2p_interface_addr()
4575 cmd
= "DATA_TEST_FRAME "
4577 pkt
= build_arp(dst_ll
=dst_ll
, src_ll
=src_ll
, opcode
=opcode
,
4578 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
4579 target_mac
=target_mac
, target_ip
=target_ip
)
4580 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4581 raise Exception("DATA_TEST_FRAME failed")
4583 def get_permanent_neighbors(ifname
):
4584 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
4585 res
= cmd
.stdout
.read().decode()
4587 return [line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
4589 def get_bridge_macs(ifname
):
4590 cmd
= subprocess
.Popen(['brctl', 'showmacs', ifname
],
4591 stdout
=subprocess
.PIPE
)
4592 res
= cmd
.stdout
.read()
4596 def tshark_get_arp(cap
, filter):
4597 res
= run_tshark(cap
, filter,
4598 ["eth.dst", "eth.src",
4599 "arp.src.hw_mac", "arp.src.proto_ipv4",
4600 "arp.dst.hw_mac", "arp.dst.proto_ipv4"],
4603 for l
in res
.splitlines():
4604 frames
.append(l
.split('\t'))
4607 def tshark_get_ns(cap
):
4608 res
= run_tshark(cap
, "icmpv6.type == 135",
4609 ["eth.dst", "eth.src",
4610 "ipv6.src", "ipv6.dst",
4611 "icmpv6.nd.ns.target_address",
4612 "icmpv6.opt.linkaddr"],
4615 for l
in res
.splitlines():
4616 frames
.append(l
.split('\t'))
4619 def tshark_get_na(cap
):
4620 res
= run_tshark(cap
, "icmpv6.type == 136",
4621 ["eth.dst", "eth.src",
4622 "ipv6.src", "ipv6.dst",
4623 "icmpv6.nd.na.target_address",
4624 "icmpv6.opt.linkaddr"],
4627 for l
in res
.splitlines():
4628 frames
.append(l
.split('\t'))
4631 def _test_proxyarp_open(dev
, apdev
, params
, ebtables
=False):
4632 prefix
= "proxyarp_open"
4634 prefix
+= "_ebtables"
4635 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
4636 cap_dev0
= os
.path
.join(params
['logdir'],
4637 prefix
+ ".%s.pcap" % dev
[0].ifname
)
4638 cap_dev1
= os
.path
.join(params
['logdir'],
4639 prefix
+ ".%s.pcap" % dev
[1].ifname
)
4640 cap_dev2
= os
.path
.join(params
['logdir'],
4641 prefix
+ ".%s.pcap" % dev
[2].ifname
)
4643 bssid
= apdev
[0]['bssid']
4644 params
= {'ssid': 'open'}
4645 params
['proxy_arp'] = '1'
4646 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4647 hapd
.set("ap_isolate", "1")
4648 hapd
.set('bridge', 'ap-br0')
4653 # For now, do not report failures due to missing kernel support
4654 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4655 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4657 raise Exception("AP startup timed out")
4658 if "AP-ENABLED" not in ev
:
4659 raise Exception("AP startup failed")
4661 params2
= {'ssid': 'another'}
4662 hapd2
= hostapd
.add_ap(apdev
[1], params2
, no_enable
=True)
4663 hapd2
.set('bridge', 'ap-br0')
4666 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4667 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4670 for chain
in ['FORWARD', 'OUTPUT']:
4672 subprocess
.call(['ebtables', '-A', chain
, '-p', 'ARP',
4673 '-d', 'Broadcast', '-o', apdev
[0]['ifname'],
4676 raise HwsimSkip("No ebtables available")
4680 cmd
[0] = WlantestCapture('ap-br0', cap_br
)
4681 cmd
[1] = WlantestCapture(dev
[0].ifname
, cap_dev0
)
4682 cmd
[2] = WlantestCapture(dev
[1].ifname
, cap_dev1
)
4683 cmd
[3] = WlantestCapture(dev
[2].ifname
, cap_dev2
)
4685 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
4686 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
4687 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
4690 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
4691 res
= brcmd
.stdout
.read().decode()
4692 brcmd
.stdout
.close()
4693 logger
.info("Bridge setup: " + res
)
4695 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
4696 stdout
=subprocess
.PIPE
)
4697 res
= brcmd
.stdout
.read().decode()
4698 brcmd
.stdout
.close()
4699 logger
.info("Bridge showstp: " + res
)
4701 addr0
= dev
[0].p2p_interface_addr()
4702 addr1
= dev
[1].p2p_interface_addr()
4703 addr2
= dev
[2].p2p_interface_addr()
4705 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4706 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4707 yiaddr
="192.168.1.124", chaddr
=addr0
)
4708 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4709 raise Exception("DATA_TEST_FRAME failed")
4710 # Change address and verify unicast
4711 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
4712 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4713 yiaddr
="192.168.1.123", chaddr
=addr0
,
4715 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4716 raise Exception("DATA_TEST_FRAME failed")
4718 # Not-associated client MAC address
4719 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4720 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4721 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
4722 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4723 raise Exception("DATA_TEST_FRAME failed")
4726 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4727 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4728 yiaddr
="0.0.0.0", chaddr
=addr1
)
4729 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4730 raise Exception("DATA_TEST_FRAME failed")
4733 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4734 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4735 yiaddr
="192.168.1.126", chaddr
=addr1
,
4736 subnet_mask
="0.0.0.0")
4737 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4738 raise Exception("DATA_TEST_FRAME failed")
4741 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4742 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4743 yiaddr
="192.168.1.127", chaddr
=addr1
,
4745 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4746 raise Exception("DATA_TEST_FRAME failed")
4749 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4750 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4751 yiaddr
="192.168.1.128", chaddr
=addr1
,
4753 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4754 raise Exception("DATA_TEST_FRAME failed")
4756 # Wrong IPv4 total length
4757 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4758 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4759 yiaddr
="192.168.1.129", chaddr
=addr1
,
4761 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4762 raise Exception("DATA_TEST_FRAME failed")
4765 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4766 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4767 yiaddr
="192.168.1.129", chaddr
=addr1
,
4769 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4770 raise Exception("DATA_TEST_FRAME failed")
4772 macs
= get_bridge_macs("ap-br0")
4773 logger
.info("After connect (showmacs): " + str(macs
))
4775 matches
= get_permanent_neighbors("ap-br0")
4776 logger
.info("After connect: " + str(matches
))
4777 if len(matches
) != 1:
4778 raise Exception("Unexpected number of neighbor entries after connect")
4779 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4780 raise Exception("dev0 IPv4 addr missing")
4782 targets
= ["192.168.1.123", "192.168.1.124", "192.168.1.125",
4784 for target
in targets
:
4785 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
4787 for target
in targets
:
4788 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
4791 for target
in targets
:
4792 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
=target
)
4794 # ARP Probe from wireless STA
4795 send_arp(dev
[1], target_ip
="192.168.1.127")
4796 # ARP Announcement from wireless STA
4797 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
4798 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
4801 macs
= get_bridge_macs("ap-br0")
4802 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
4804 matches
= get_permanent_neighbors("ap-br0")
4805 logger
.info("After ARP Probe + Announcement: " + str(matches
))
4807 # ARP Request for the newly introduced IP address from wireless STA
4808 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
4810 # ARP Request for the newly introduced IP address from bridge
4811 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
4812 target_ip
="192.168.1.127")
4813 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
="192.168.1.127")
4815 # ARP Probe from bridge
4816 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.130")
4817 send_arp(dev
[2], target_ip
="192.168.1.131")
4818 # ARP Announcement from bridge (not to be learned by AP for proxyarp)
4819 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
4820 target_ip
="192.168.1.130")
4821 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
4822 target_ip
="192.168.1.130", opcode
=2)
4823 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131")
4824 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131",
4827 macs
= get_bridge_macs("ap-br0")
4828 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
4830 matches
= get_permanent_neighbors("ap-br0")
4831 logger
.info("After ARP Probe + Announcement: " + str(matches
))
4833 # ARP Request for the newly introduced IP address from wireless STA
4834 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.130")
4835 # ARP Response from bridge (AP does not proxy for non-wireless devices)
4836 send_arp(hapd
, hapd_bssid
=bssid
, dst_ll
=addr0
, sender_ip
="192.168.1.130",
4837 target_ip
="192.168.1.123", opcode
=2)
4839 # ARP Request for the newly introduced IP address from wireless STA
4840 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.131")
4841 # ARP Response from bridge (AP does not proxy for non-wireless devices)
4842 send_arp(dev
[2], dst_ll
=addr0
, sender_ip
="192.168.1.131",
4843 target_ip
="192.168.1.123", opcode
=2)
4845 # ARP Request for the newly introduced IP address from bridge
4846 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
4847 target_ip
="192.168.1.130")
4848 send_arp(dev
[2], sender_ip
="192.168.1.104", target_ip
="192.168.1.131")
4850 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
4851 send_arp(dev
[1], target_ip
="192.168.1.123")
4852 # ARP Probe from wireless STA (duplicate address; learned through ARP)
4853 send_arp(dev
[0], target_ip
="192.168.1.127")
4855 # Gratuitous ARP Reply for another STA's IP address
4856 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
4857 target_mac
=addr1
, target_ip
="192.168.1.127")
4858 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
4859 target_mac
=addr0
, target_ip
="192.168.1.123")
4860 # ARP Request to verify previous mapping
4861 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
4862 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
4865 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
4866 except Exception as e
:
4867 logger
.info("test_connectibity_iface failed: " + str(e
))
4868 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
4869 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
4870 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
4872 dev
[0].request("DISCONNECT")
4873 dev
[1].request("DISCONNECT")
4875 for i
in range(len(cmd
)):
4878 macs
= get_bridge_macs("ap-br0")
4879 logger
.info("After disconnect (showmacs): " + str(macs
))
4880 matches
= get_permanent_neighbors("ap-br0")
4881 logger
.info("After disconnect: " + str(matches
))
4882 if len(matches
) > 0:
4883 raise Exception("Unexpected neighbor entries after disconnect")
4885 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
4886 stdout
=subprocess
.PIPE
)
4887 res
= cmd
.stdout
.read().decode()
4889 logger
.info("ebtables results:\n" + res
)
4891 # Verify that expected ARP messages were seen and no unexpected
4892 # ARP messages were seen.
4894 arp_req
= tshark_get_arp(cap_dev0
, "arp.opcode == 1")
4895 arp_reply
= tshark_get_arp(cap_dev0
, "arp.opcode == 2")
4896 logger
.info("dev0 seen ARP requests:\n" + str(arp_req
))
4897 logger
.info("dev0 seen ARP replies:\n" + str(arp_reply
))
4899 if ['ff:ff:ff:ff:ff:ff', addr1
,
4900 addr1
, '192.168.1.100',
4901 '00:00:00:00:00:00', '192.168.1.123'] in arp_req
:
4902 raise Exception("dev0 saw ARP request from dev1")
4903 if ['ff:ff:ff:ff:ff:ff', addr2
,
4904 addr2
, '192.168.1.103',
4905 '00:00:00:00:00:00', '192.168.1.123'] in arp_req
:
4906 raise Exception("dev0 saw ARP request from dev2")
4907 # TODO: Uncomment once fixed in kernel
4908 #if ['ff:ff:ff:ff:ff:ff', bssid,
4909 # bssid, '192.168.1.101',
4910 # '00:00:00:00:00:00', '192.168.1.123'] in arp_req:
4911 # raise Exception("dev0 saw ARP request from br")
4916 raise Exception("Unexpected foreign ARP request on dev0")
4918 arp_req
= tshark_get_arp(cap_dev1
, "arp.opcode == 1")
4919 arp_reply
= tshark_get_arp(cap_dev1
, "arp.opcode == 2")
4920 logger
.info("dev1 seen ARP requests:\n" + str(arp_req
))
4921 logger
.info("dev1 seen ARP replies:\n" + str(arp_reply
))
4923 if ['ff:ff:ff:ff:ff:ff', addr2
,
4924 addr2
, '192.168.1.103',
4925 '00:00:00:00:00:00', '192.168.1.123'] in arp_req
:
4926 raise Exception("dev1 saw ARP request from dev2")
4927 if [addr1
, addr0
, addr0
, '192.168.1.123', addr1
, '192.168.1.100'] not in arp_reply
:
4928 raise Exception("dev1 did not get ARP response for 192.168.1.123")
4933 raise Exception("Unexpected foreign ARP request on dev1")
4935 arp_req
= tshark_get_arp(cap_dev2
, "arp.opcode == 1")
4936 arp_reply
= tshark_get_arp(cap_dev2
, "arp.opcode == 2")
4937 logger
.info("dev2 seen ARP requests:\n" + str(arp_req
))
4938 logger
.info("dev2 seen ARP replies:\n" + str(arp_reply
))
4941 addr0
, '192.168.1.123',
4942 addr2
, '192.168.1.103'] not in arp_reply
:
4943 raise Exception("dev2 did not get ARP response for 192.168.1.123")
4945 arp_req
= tshark_get_arp(cap_br
, "arp.opcode == 1")
4946 arp_reply
= tshark_get_arp(cap_br
, "arp.opcode == 2")
4947 logger
.info("br seen ARP requests:\n" + str(arp_req
))
4948 logger
.info("br seen ARP replies:\n" + str(arp_reply
))
4950 # TODO: Uncomment once fixed in kernel
4952 # addr0, '192.168.1.123',
4953 # bssid, '192.168.1.101'] not in arp_reply:
4954 # raise Exception("br did not get ARP response for 192.168.1.123")
4956 def _test_proxyarp_open_ipv6(dev
, apdev
, params
, ebtables
=False):
4957 prefix
= "proxyarp_open"
4959 prefix
+= "_ebtables"
4961 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
4962 cap_dev0
= os
.path
.join(params
['logdir'],
4963 prefix
+ ".%s.pcap" % dev
[0].ifname
)
4964 cap_dev1
= os
.path
.join(params
['logdir'],
4965 prefix
+ ".%s.pcap" % dev
[1].ifname
)
4966 cap_dev2
= os
.path
.join(params
['logdir'],
4967 prefix
+ ".%s.pcap" % dev
[2].ifname
)
4969 bssid
= apdev
[0]['bssid']
4970 params
= {'ssid': 'open'}
4971 params
['proxy_arp'] = '1'
4972 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4973 hapd
.set("ap_isolate", "1")
4974 hapd
.set('bridge', 'ap-br0')
4979 # For now, do not report failures due to missing kernel support
4980 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4981 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4983 raise Exception("AP startup timed out")
4984 if "AP-ENABLED" not in ev
:
4985 raise Exception("AP startup failed")
4987 params2
= {'ssid': 'another'}
4988 hapd2
= hostapd
.add_ap(apdev
[1], params2
, no_enable
=True)
4989 hapd2
.set('bridge', 'ap-br0')
4992 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4993 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4996 for chain
in ['FORWARD', 'OUTPUT']:
4998 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
4999 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5000 '--ip6-icmp-type', 'neighbor-solicitation',
5001 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5002 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
5003 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5004 '--ip6-icmp-type', 'neighbor-advertisement',
5005 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5006 subprocess
.call(['ebtables', '-A', chain
,
5007 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5008 '--ip6-icmp-type', 'router-solicitation',
5009 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5010 # Multicast Listener Report Message
5011 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
5012 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5013 '--ip6-icmp-type', '143',
5014 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5016 raise HwsimSkip("No ebtables available")
5020 cmd
[0] = WlantestCapture('ap-br0', cap_br
)
5021 cmd
[1] = WlantestCapture(dev
[0].ifname
, cap_dev0
)
5022 cmd
[2] = WlantestCapture(dev
[1].ifname
, cap_dev1
)
5023 cmd
[3] = WlantestCapture(dev
[2].ifname
, cap_dev2
)
5025 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
5026 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
5027 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
5030 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
5031 res
= brcmd
.stdout
.read().decode()
5032 brcmd
.stdout
.close()
5033 logger
.info("Bridge setup: " + res
)
5035 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
5036 stdout
=subprocess
.PIPE
)
5037 res
= brcmd
.stdout
.read().decode()
5038 brcmd
.stdout
.close()
5039 logger
.info("Bridge showstp: " + res
)
5041 addr0
= dev
[0].p2p_interface_addr()
5042 addr1
= dev
[1].p2p_interface_addr()
5043 addr2
= dev
[2].p2p_interface_addr()
5045 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':', ''))
5046 src_ll_opt1
= b
"\x01\x01" + binascii
.unhexlify(addr1
.replace(':', ''))
5049 send_ns(dev
[0], ip_src
="::", target
="aaaa:bbbb:cccc::2")
5051 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2")
5052 # test frame without source link-layer address option
5053 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5055 # test frame with bogus option
5056 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5057 opt
=b
"\x70\x01\x01\x02\x03\x04\x05\x05")
5058 # test frame with truncated source link-layer address option
5059 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5060 opt
=b
"\x01\x01\x01\x02\x03\x04")
5061 # test frame with foreign source link-layer address option
5062 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5063 opt
=b
"\x01\x01\x01\x02\x03\x04\x05\x06")
5065 send_ns(dev
[1], ip_src
="aaaa:bbbb:dddd::2", target
="aaaa:bbbb:dddd::2")
5067 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
5068 # another copy for additional code coverage
5069 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
5071 macs
= get_bridge_macs("ap-br0")
5072 logger
.info("After connect (showmacs): " + str(macs
))
5074 matches
= get_permanent_neighbors("ap-br0")
5075 logger
.info("After connect: " + str(matches
))
5076 if len(matches
) != 3:
5077 raise Exception("Unexpected number of neighbor entries after connect")
5078 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
5079 raise Exception("dev0 addr missing")
5080 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
5081 raise Exception("dev1 addr(1) missing")
5082 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
5083 raise Exception("dev1 addr(2) missing")
5085 send_ns(dev
[0], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:cccc::2")
5087 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:dddd::2")
5089 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:dddd::2",
5090 ip_src
="aaaa:bbbb:ffff::2")
5092 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:ff00::2")
5094 send_ns(dev
[2], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:ff00::2")
5096 send_ns(dev
[2], target
="aaaa:bbbb:eeee::2", ip_src
="aaaa:bbbb:ff00::2")
5099 # Try to probe for an already assigned address
5100 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="::")
5102 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc::2", ip_src
="::")
5104 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="::")
5108 send_na(dev
[1], target
="aaaa:bbbb:cccc:aeae::3",
5109 ip_src
="aaaa:bbbb:cccc:aeae::3", ip_dst
="ff02::1")
5110 send_na(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc:aeae::4",
5111 ip_src
="aaaa:bbbb:cccc:aeae::4", ip_dst
="ff02::1")
5112 send_na(dev
[2], target
="aaaa:bbbb:cccc:aeae::5",
5113 ip_src
="aaaa:bbbb:cccc:aeae::5", ip_dst
="ff02::1")
5116 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
5117 except Exception as e
:
5118 logger
.info("test_connectibity_iface failed: " + str(e
))
5119 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
5120 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
5121 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
5123 dev
[0].request("DISCONNECT")
5124 dev
[1].request("DISCONNECT")
5126 for i
in range(len(cmd
)):
5128 macs
= get_bridge_macs("ap-br0")
5129 logger
.info("After disconnect (showmacs): " + str(macs
))
5130 matches
= get_permanent_neighbors("ap-br0")
5131 logger
.info("After disconnect: " + str(matches
))
5132 if len(matches
) > 0:
5133 raise Exception("Unexpected neighbor entries after disconnect")
5135 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
5136 stdout
=subprocess
.PIPE
)
5137 res
= cmd
.stdout
.read().decode()
5139 logger
.info("ebtables results:\n" + res
)
5141 ns
= tshark_get_ns(cap_dev0
)
5142 logger
.info("dev0 seen NS: " + str(ns
))
5143 na
= tshark_get_na(cap_dev0
)
5144 logger
.info("dev0 seen NA: " + str(na
))
5146 if [addr0
, addr1
, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2',
5147 'aaaa:bbbb:dddd::2', addr1
] not in na
:
5148 # For now, skip the test instead of reporting the error since the IPv6
5149 # proxyarp support is not yet in the upstream kernel tree.
5150 #raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
5151 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp (IPv6)")
5155 if req
[1] == bssid
and req
[0] == "33:33:ff:" + bssid
[9:] and \
5156 req
[3] == 'ff02::1:ff00:300' and req
[4] == 'fe80::ff:fe00:300':
5157 # At least for now, ignore this special case until the kernel
5158 # can be prevented from sending it out.
5159 logger
.info("dev0: Ignore NS from AP to own local addr: " + str(req
))
5160 elif req
[1] != addr0
:
5161 raise Exception("Unexpected foreign NS on dev0: " + str(req
))
5163 ns
= tshark_get_ns(cap_dev1
)
5164 logger
.info("dev1 seen NS: " + str(ns
))
5165 na
= tshark_get_na(cap_dev1
)
5166 logger
.info("dev1 seen NA: " + str(na
))
5168 if [addr1
, addr0
, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:dddd::2',
5169 'aaaa:bbbb:cccc::2', addr0
] not in na
:
5170 raise Exception("dev1 did not get NA for aaaa:bbbb:cccc::2")
5174 if req
[1] == bssid
and req
[0] == "33:33:ff:" + bssid
[9:] and \
5175 req
[3] == 'ff02::1:ff00:300' and req
[4] == 'fe80::ff:fe00:300':
5176 # At least for now, ignore this special case until the kernel
5177 # can be prevented from sending it out.
5178 logger
.info("dev1: Ignore NS from AP to own local addr: " + str(req
))
5179 elif req
[1] != addr1
:
5180 raise Exception("Unexpected foreign NS on dev1: " + str(req
))
5182 ns
= tshark_get_ns(cap_dev2
)
5183 logger
.info("dev2 seen NS: " + str(ns
))
5184 na
= tshark_get_na(cap_dev2
)
5185 logger
.info("dev2 seen NA: " + str(na
))
5187 # FIX: enable once kernel implementation for proxyarp IPv6 is fixed
5188 #if [addr2, addr0, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:ff00::2',
5189 # 'aaaa:bbbb:cccc::2', addr0] not in na:
5190 # raise Exception("dev2 did not get NA for aaaa:bbbb:cccc::2")
5191 #if [addr2, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:ff00::2',
5192 # 'aaaa:bbbb:dddd::2', addr1] not in na:
5193 # raise Exception("dev2 did not get NA for aaaa:bbbb:dddd::2")
5194 #if [addr2, addr1, 'aaaa:bbbb:eeee::2', 'aaaa:bbbb:ff00::2',
5195 # 'aaaa:bbbb:eeee::2', addr1] not in na:
5196 # raise Exception("dev2 did not get NA for aaaa:bbbb:eeee::2")
5198 def test_proxyarp_open(dev
, apdev
, params
):
5199 """ProxyARP with open network"""
5201 _test_proxyarp_open(dev
, apdev
, params
)
5203 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5204 stderr
=open('/dev/null', 'w'))
5205 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5206 stderr
=open('/dev/null', 'w'))
5208 def test_proxyarp_open_ipv6(dev
, apdev
, params
):
5209 """ProxyARP with open network (IPv6)"""
5211 _test_proxyarp_open_ipv6(dev
, apdev
, params
)
5213 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5214 stderr
=open('/dev/null', 'w'))
5215 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5216 stderr
=open('/dev/null', 'w'))
5218 def test_proxyarp_open_ebtables(dev
, apdev
, params
):
5219 """ProxyARP with open network"""
5221 _test_proxyarp_open(dev
, apdev
, params
, ebtables
=True)
5224 subprocess
.call(['ebtables', '-F', 'FORWARD'])
5225 subprocess
.call(['ebtables', '-F', 'OUTPUT'])
5228 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5229 stderr
=open('/dev/null', 'w'))
5230 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5231 stderr
=open('/dev/null', 'w'))
5233 def test_proxyarp_open_ebtables_ipv6(dev
, apdev
, params
):
5234 """ProxyARP with open network (IPv6)"""
5236 _test_proxyarp_open_ipv6(dev
, apdev
, params
, ebtables
=True)
5239 subprocess
.call(['ebtables', '-F', 'FORWARD'])
5240 subprocess
.call(['ebtables', '-F', 'OUTPUT'])
5243 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5244 stderr
=open('/dev/null', 'w'))
5245 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5246 stderr
=open('/dev/null', 'w'))
5248 def test_proxyarp_errors(dev
, apdev
, params
):
5249 """ProxyARP error cases"""
5251 run_proxyarp_errors(dev
, apdev
, params
)
5253 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5254 stderr
=open('/dev/null', 'w'))
5255 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5256 stderr
=open('/dev/null', 'w'))
5258 def run_proxyarp_errors(dev
, apdev
, params
):
5259 params
= {'ssid': 'open',
5263 'disable_dgaf': '1'}
5264 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
5268 # For now, do not report failures due to missing kernel support
5269 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
5270 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
5272 raise Exception("AP startup timed out")
5273 if "AP-ENABLED" not in ev
:
5274 raise Exception("AP startup failed")
5277 with
alloc_fail(hapd
, 1, "l2_packet_init;x_snoop_get_l2_packet;dhcp_snoop_init"):
5278 if "FAIL" not in hapd
.request("ENABLE"):
5279 raise Exception("ENABLE accepted unexpectedly")
5280 with
alloc_fail(hapd
, 1, "l2_packet_init;x_snoop_get_l2_packet;ndisc_snoop_init"):
5281 if "FAIL" not in hapd
.request("ENABLE"):
5282 raise Exception("ENABLE accepted unexpectedly")
5283 with
fail_test(hapd
, 1, "l2_packet_set_packet_filter;x_snoop_get_l2_packet;ndisc_snoop_init"):
5284 if "FAIL" not in hapd
.request("ENABLE"):
5285 raise Exception("ENABLE accepted unexpectedly")
5286 with
fail_test(hapd
, 1, "l2_packet_set_packet_filter;x_snoop_get_l2_packet;dhcp_snoop_init"):
5287 if "FAIL" not in hapd
.request("ENABLE"):
5288 raise Exception("ENABLE accepted unexpectedly")
5291 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
5292 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
5294 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
5295 addr0
= dev
[0].own_addr()
5297 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
5299 with
fail_test(hapd
, 1, "x_snoop_mcast_to_ucast_convert_send"):
5300 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
5301 raise Exception("DATA_TEST_FRAME failed")
5302 wait_fail_trigger(dev
[0], "GET_FAIL")
5304 with
alloc_fail(hapd
, 1, "sta_ip6addr_add"):
5305 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':', ''))
5306 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
5307 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
5309 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
5310 raise Exception("DATA_TEST_FRAME failed")
5311 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5313 def test_ap_hs20_connect_deinit(dev
, apdev
):
5314 """Hotspot 2.0 connection interrupted with deinit"""
5315 check_eap_capa(dev
[0], "MSCHAPV2")
5316 bssid
= apdev
[0]['bssid']
5317 params
= hs20_ap_params()
5318 params
['hessid'] = bssid
5319 hapd
= hostapd
.add_ap(apdev
[0], params
)
5321 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
5322 wpas
.interface_add("wlan5", drv_params
="")
5324 wpas
.flush_scan_cache()
5325 wpas
.add_cred_values({'realm': "example.com",
5326 'username': "hs20-test",
5327 'password': "password",
5328 'ca_cert': "auth_serv/ca.pem",
5329 'domain': "example.com"})
5331 wpas
.scan_for_bss(bssid
, freq
=2412)
5334 wpas
.request("INTERWORKING_SELECT freq=2412")
5336 id = wpas
.request("RADIO_WORK add block-work")
5337 ev
= wpas
.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout
=5)
5339 raise Exception("Timeout while waiting radio work to start")
5340 ev
= wpas
.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout
=5)
5342 raise Exception("Timeout while waiting radio work to start (2)")
5344 # Remove the interface while the gas-query radio work is still pending and
5345 # GAS query has not yet been started.
5346 wpas
.interface_remove("wlan5")
5348 def test_ap_hs20_anqp_format_errors(dev
, apdev
):
5349 """Interworking network selection and ANQP format errors"""
5350 bssid
= apdev
[0]['bssid']
5351 params
= hs20_ap_params()
5352 params
['hessid'] = bssid
5353 hapd
= hostapd
.add_ap(apdev
[0], params
)
5355 dev
[0].hs20_enable()
5356 values
= {'realm': "example.com",
5357 'ca_cert': "auth_serv/ca.pem",
5358 'username': "hs20-test",
5359 'password': "password",
5360 'domain': "example.com"}
5361 id = dev
[0].add_cred_values(values
)
5363 dev
[0].scan_for_bss(bssid
, freq
="2412")
5365 tests
= ["00", "ffff", "010011223344", "020008000005112233445500",
5366 "01000400000000", "01000000000000",
5367 "01000300000200", "0100040000ff0000", "01000300000100",
5369 "01000600000056112233",
5370 "01000900000002050001000111",
5371 "01000600000001000000", "01000600000001ff0000",
5372 "01000600000001020001",
5373 "010008000000010400010001", "0100080000000104000100ff",
5374 "010011000000010d00050200020100030005000600",
5377 hapd
.set("anqp_elem", "263:" + t
)
5378 dev
[0].request("INTERWORKING_SELECT freq=2412")
5379 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=5)
5381 raise Exception("Network selection timed out")
5382 dev
[0].dump_monitor()
5384 dev
[0].remove_cred(id)
5385 id = dev
[0].add_cred_values({'imsi': "555444-333222111", 'eap': "AKA",
5386 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
5388 tests
= ["00", "0100", "0001", "00ff", "000200ff", "0003000101",
5391 hapd
.set("anqp_elem", "264:" + t
)
5392 dev
[0].request("INTERWORKING_SELECT freq=2412")
5393 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=5)
5395 raise Exception("Network selection timed out")
5396 dev
[0].dump_monitor()
5398 def test_ap_hs20_cred_with_nai_realm(dev
, apdev
):
5399 """Hotspot 2.0 network selection and cred_with_nai_realm cred->realm"""
5400 bssid
= apdev
[0]['bssid']
5401 params
= hs20_ap_params()
5402 params
['hessid'] = bssid
5403 hostapd
.add_ap(apdev
[0], params
)
5405 dev
[0].hs20_enable()
5407 id = dev
[0].add_cred_values({'realm': "example.com",
5409 'password': "secret",
5410 'domain': "example.com",
5412 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5413 dev
[0].remove_cred(id)
5415 id = dev
[0].add_cred_values({'realm': "foo.com",
5417 'password': "secret",
5418 'domain': "example.com",
5419 'roaming_consortium': "112234",
5421 interworking_select(dev
[0], bssid
, "home", freq
=2412, no_match
=True)
5422 dev
[0].remove_cred(id)
5424 def test_ap_hs20_cred_and_no_roaming_consortium(dev
, apdev
):
5425 """Hotspot 2.0 network selection and no roaming consortium"""
5426 bssid
= apdev
[0]['bssid']
5427 params
= hs20_ap_params()
5428 params
['hessid'] = bssid
5429 del params
['roaming_consortium']
5430 hostapd
.add_ap(apdev
[0], params
)
5432 dev
[0].hs20_enable()
5434 id = dev
[0].add_cred_values({'realm': "example.com",
5436 'password': "secret",
5437 'domain': "example.com",
5438 'roaming_consortium': "112234",
5440 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5442 def test_ap_hs20_interworking_oom(dev
, apdev
):
5443 """Hotspot 2.0 network selection and OOM"""
5444 bssid
= apdev
[0]['bssid']
5445 params
= hs20_ap_params()
5446 params
['hessid'] = bssid
5447 params
['nai_realm'] = ["0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]",
5448 "0,example.com,13[5:6],21[2:4][5:7]",
5449 "0,another.example.com"]
5450 hostapd
.add_ap(apdev
[0], params
)
5452 dev
[0].hs20_enable()
5454 id = dev
[0].add_cred_values({'realm': "example.com",
5456 'password': "secret",
5457 'domain': "example.com",
5460 dev
[0].scan_for_bss(bssid
, freq
="2412")
5462 funcs
= ["wpabuf_alloc;interworking_anqp_send_req",
5463 "anqp_build_req;interworking_anqp_send_req",
5464 "gas_query_req;interworking_anqp_send_req",
5465 "dup_binstr;nai_realm_parse_realm",
5466 "=nai_realm_parse_realm",
5470 with
alloc_fail(dev
[0], 1, func
):
5471 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
5472 ev
= dev
[0].wait_event(["Starting ANQP"], timeout
=5)
5474 raise Exception("ANQP did not start")
5475 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5476 dev
[0].dump_monitor()
5478 def test_ap_hs20_no_cred_connect(dev
, apdev
):
5479 """Hotspot 2.0 and connect attempt without credential"""
5480 bssid
= apdev
[0]['bssid']
5481 params
= hs20_ap_params()
5482 params
['hessid'] = bssid
5483 hapd
= hostapd
.add_ap(apdev
[0], params
)
5485 dev
[0].hs20_enable()
5486 dev
[0].scan_for_bss(bssid
, freq
="2412")
5487 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT " + bssid
):
5488 raise Exception("Unexpected INTERWORKING_CONNECT success")
5490 def test_ap_hs20_no_rsn_connect(dev
, apdev
):
5491 """Hotspot 2.0 and connect attempt without RSN"""
5492 bssid
= apdev
[0]['bssid']
5493 params
= hostapd
.wpa_params(ssid
="test-hs20")
5494 params
['wpa_key_mgmt'] = "WPA-EAP"
5495 params
['ieee80211w'] = "1"
5496 params
['ieee8021x'] = "1"
5497 params
['auth_server_addr'] = "127.0.0.1"
5498 params
['auth_server_port'] = "1812"
5499 params
['auth_server_shared_secret'] = "radius"
5500 params
['interworking'] = "1"
5501 params
['roaming_consortium'] = ["112233", "1020304050", "010203040506",
5503 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]",
5504 "0,another.example.com"]
5505 hapd
= hostapd
.add_ap(apdev
[0], params
)
5507 dev
[0].hs20_enable()
5508 dev
[0].scan_for_bss(bssid
, freq
="2412")
5510 id = dev
[0].add_cred_values({'realm': "example.com",
5512 'password': "secret",
5513 'domain': "example.com",
5514 'roaming_consortium': "112233",
5517 interworking_select(dev
[0], bssid
, freq
=2412, no_match
=True)
5518 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT " + bssid
):
5519 raise Exception("Unexpected INTERWORKING_CONNECT success")
5521 def test_ap_hs20_no_match_connect(dev
, apdev
):
5522 """Hotspot 2.0 and connect attempt without matching cred"""
5523 bssid
= apdev
[0]['bssid']
5524 params
= hs20_ap_params()
5525 hapd
= hostapd
.add_ap(apdev
[0], params
)
5527 dev
[0].hs20_enable()
5528 dev
[0].scan_for_bss(bssid
, freq
="2412")
5530 id = dev
[0].add_cred_values({'realm': "example.org",
5532 'password': "secret",
5533 'domain': "example.org",
5534 'roaming_consortium': "112234",
5537 interworking_select(dev
[0], bssid
, freq
=2412, no_match
=True)
5538 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT " + bssid
):
5539 raise Exception("Unexpected INTERWORKING_CONNECT success")
5541 def test_ap_hs20_multiple_home_cred(dev
, apdev
):
5542 """Hotspot 2.0 and select with multiple matching home credentials"""
5543 bssid
= apdev
[0]['bssid']
5544 params
= hs20_ap_params()
5545 params
['hessid'] = bssid
5546 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
5547 params
['domain_name'] = "example.com"
5548 hapd
= hostapd
.add_ap(apdev
[0], params
)
5550 bssid2
= apdev
[1]['bssid']
5551 params
= hs20_ap_params(ssid
="test-hs20-other")
5552 params
['hessid'] = bssid2
5553 params
['nai_realm'] = ["0,example.org,13[5:6],21[2:4][5:7]"]
5554 params
['domain_name'] = "example.org"
5555 hapd2
= hostapd
.add_ap(apdev
[1], params
)
5557 dev
[0].hs20_enable()
5558 dev
[0].scan_for_bss(bssid2
, freq
="2412")
5559 dev
[0].scan_for_bss(bssid
, freq
="2412")
5560 id = dev
[0].add_cred_values({'realm': "example.com",
5562 'username': "hs20-test",
5563 'password': "password",
5564 'domain': "example.com"})
5565 id2
= dev
[0].add_cred_values({'realm': "example.org",
5567 'username': "hs20-test",
5568 'password': "password",
5569 'domain': "example.org"})
5570 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
5571 ev
= dev
[0].wait_connected(timeout
=15)
5572 if bssid2
not in ev
:
5573 raise Exception("Connected to incorrect network")
5575 def test_ap_hs20_anqp_invalid_gas_response(dev
, apdev
):
5576 """Hotspot 2.0 network selection and invalid GAS response"""
5577 bssid
= apdev
[0]['bssid']
5578 params
= hs20_ap_params()
5579 params
['hessid'] = bssid
5580 hapd
= hostapd
.add_ap(apdev
[0], params
)
5582 dev
[0].scan_for_bss(bssid
, freq
="2412")
5583 hapd
.set("ext_mgmt_frame_handling", "1")
5585 dev
[0].hs20_enable()
5587 id = dev
[0].add_cred_values({'realm': "example.com",
5589 'password': "secret",
5590 'domain': "example.com",
5591 'roaming_consortium': "112234",
5593 dev
[0].request("INTERWORKING_SELECT freq=2412")
5595 query
= gas_rx(hapd
)
5596 gas
= parse_gas(query
['payload'])
5598 logger
.info("ANQP: Unexpected Advertisement Protocol in response")
5599 resp
= action_response(query
)
5600 adv_proto
= struct
.pack('8B', 108, 6, 127, 0xdd, 0x00, 0x11, 0x22, 0x33)
5601 data
= struct
.pack('<H', 0)
5602 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5603 GAS_INITIAL_RESPONSE
,
5604 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5605 send_gas_resp(hapd
, resp
)
5607 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5609 raise Exception("No ANQP-QUERY-DONE seen")
5610 if "result=INVALID_FRAME" not in ev
:
5611 raise Exception("Unexpected result: " + ev
)
5613 dev
[0].request("INTERWORKING_SELECT freq=2412")
5615 query
= gas_rx(hapd
)
5616 gas
= parse_gas(query
['payload'])
5618 logger
.info("ANQP: Invalid element length for Info ID 1234")
5619 resp
= action_response(query
)
5620 adv_proto
= struct
.pack('BBBB', 108, 2, 127, 0)
5621 elements
= struct
.pack('<HH', 1234, 1)
5622 data
= struct
.pack('<H', len(elements
)) + elements
5623 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5624 GAS_INITIAL_RESPONSE
,
5625 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5626 send_gas_resp(hapd
, resp
)
5628 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5630 raise Exception("No ANQP-QUERY-DONE seen")
5631 if "result=INVALID_FRAME" not in ev
:
5632 raise Exception("Unexpected result: " + ev
)
5634 with
alloc_fail(dev
[0], 1, "=anqp_add_extra"):
5635 dev
[0].request("INTERWORKING_SELECT freq=2412")
5637 query
= gas_rx(hapd
)
5638 gas
= parse_gas(query
['payload'])
5640 resp
= action_response(query
)
5641 elements
= struct
.pack('<HHHH', 1, 0, 1, 0)
5642 data
= struct
.pack('<H', len(elements
)) + elements
5643 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5644 GAS_INITIAL_RESPONSE
,
5645 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5646 send_gas_resp(hapd
, resp
)
5648 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5650 raise Exception("No ANQP-QUERY-DONE seen")
5651 if "result=SUCCESS" not in ev
:
5652 raise Exception("Unexpected result: " + ev
)
5654 with
alloc_fail(dev
[0], 1, "wpabuf_alloc_copy;anqp_add_extra"):
5655 dev
[0].request("INTERWORKING_SELECT freq=2412")
5657 query
= gas_rx(hapd
)
5658 gas
= parse_gas(query
['payload'])
5660 resp
= action_response(query
)
5661 elements
= struct
.pack('<HHHH', 1, 0, 1, 0)
5662 data
= struct
.pack('<H', len(elements
)) + elements
5663 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5664 GAS_INITIAL_RESPONSE
,
5665 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5666 send_gas_resp(hapd
, resp
)
5668 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5670 raise Exception("No ANQP-QUERY-DONE seen")
5671 if "result=SUCCESS" not in ev
:
5672 raise Exception("Unexpected result: " + ev
)
5674 tests
= [struct
.pack('<HH', 0xdddd, 0),
5675 struct
.pack('<HH3B', 0xdddd, 3, 0x50, 0x6f, 0x9a),
5676 struct
.pack('<HH4B', 0xdddd, 4, 0x50, 0x6f, 0x9a, 0),
5677 struct
.pack('<HH4B', 0xdddd, 4, 0x11, 0x22, 0x33, 0),
5678 struct
.pack('<HHHH', 1, 0, 1, 0)]
5679 for elements
in tests
:
5680 dev
[0].request("INTERWORKING_SELECT freq=2412")
5682 query
= gas_rx(hapd
)
5683 gas
= parse_gas(query
['payload'])
5685 resp
= action_response(query
)
5686 data
= struct
.pack('<H', len(elements
)) + elements
5687 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5688 GAS_INITIAL_RESPONSE
,
5689 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5690 send_gas_resp(hapd
, resp
)
5692 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5694 raise Exception("No ANQP-QUERY-DONE seen")
5695 if "result=SUCCESS" not in ev
:
5696 raise Exception("Unexpected result: " + ev
)
5698 def test_ap_hs20_set_profile_failures(dev
, apdev
):
5699 """Hotspot 2.0 and failures during profile configuration"""
5700 bssid
= apdev
[0]['bssid']
5701 params
= hs20_ap_params()
5702 params
['hessid'] = bssid
5703 params
['anqp_3gpp_cell_net'] = "555,444"
5704 hapd
= hostapd
.add_ap(apdev
[0], params
)
5706 dev
[0].hs20_enable()
5707 dev
[0].scan_for_bss(bssid
, freq
="2412")
5709 id = dev
[0].add_cred_values({'realm': "example.com",
5710 'domain': "example.com",
5712 'password': "secret",
5714 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5715 dev
[0].dump_monitor()
5716 dev
[0].request("NOTE ssid->eap.eap_methods = os_malloc()")
5717 with
alloc_fail(dev
[0], 1, "interworking_set_eap_params"):
5718 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5719 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5720 dev
[0].remove_cred(id)
5722 id = dev
[0].add_cred_values({'realm': "example.com",
5723 'domain': "example.com",
5724 'username': "hs20-test-with-domain@example.com",
5725 'password': "password"})
5726 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5727 dev
[0].dump_monitor()
5728 dev
[0].request("NOTE anon = os_malloc()")
5729 with
alloc_fail(dev
[0], 1, "interworking_set_eap_params"):
5730 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5731 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5732 dev
[0].request("NOTE Successful connection with cred->username including realm")
5733 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5734 dev
[0].wait_connected()
5735 dev
[0].remove_cred(id)
5736 dev
[0].wait_disconnected()
5738 id = dev
[0].add_cred_values({'realm': "example.com",
5739 'domain': "example.com",
5740 'username': "hs20-test",
5741 'password': "password"})
5742 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5743 dev
[0].dump_monitor()
5744 dev
[0].request("NOTE anon = os_malloc() (second)")
5745 with
alloc_fail(dev
[0], 1, "interworking_set_eap_params"):
5746 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5747 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5748 with
alloc_fail(dev
[0], 1, "wpa_config_add_network;interworking_connect"):
5749 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5750 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5751 with
alloc_fail(dev
[0], 1, "=interworking_connect"):
5752 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5753 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5754 dev
[0].request("NOTE wpa_config_set(eap)")
5755 with
alloc_fail(dev
[0], 1, "wpa_config_parse_eap;wpa_config_set;interworking_connect"):
5756 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5757 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5758 dev
[0].request("NOTE wpa_config_set(TTLS-NON_EAP_MSCHAPV2-phase2)")
5759 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5760 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5761 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5762 dev
[0].remove_cred(id)
5764 id = dev
[0].add_cred_values({'roaming_consortium': "112233",
5765 'domain': "example.com",
5766 'username': "hs20-test",
5767 'password': "password",
5769 'phase2': "auth=MSCHAPV2"})
5770 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5771 dev
[0].dump_monitor()
5772 dev
[0].request("NOTE anon = os_strdup()")
5773 with
alloc_fail(dev
[0], 2, "interworking_set_eap_params"):
5774 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5775 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5776 dev
[0].request("NOTE wpa_config_set_quoted(anonymous_identity)")
5777 with
alloc_fail(dev
[0], 1, "=wpa_config_set_quoted;interworking_set_eap_params"):
5778 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5779 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5780 dev
[0].request("NOTE Successful connection with cred->realm not included")
5781 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5782 dev
[0].wait_connected()
5783 dev
[0].remove_cred(id)
5784 dev
[0].wait_disconnected()
5786 id = dev
[0].add_cred_values({'roaming_consortium': "112233",
5787 'domain': "example.com",
5788 'realm': "example.com",
5790 'password': "password",
5792 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5793 dev
[0].dump_monitor()
5794 dev
[0].request("NOTE id = os_strdup()")
5795 with
alloc_fail(dev
[0], 2, "interworking_set_eap_params"):
5796 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5797 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5798 dev
[0].request("NOTE wpa_config_set_quoted(identity)")
5799 with
alloc_fail(dev
[0], 1, "=wpa_config_set_quoted;interworking_set_eap_params"):
5800 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5801 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5802 dev
[0].remove_cred(id)
5804 id = dev
[0].add_cred_values({'roaming_consortium': "112233",
5805 'domain': "example.com",
5806 'realm': "example.com",
5808 'password': "password",
5810 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5811 dev
[0].dump_monitor()
5812 dev
[0].request("NOTE wpa_config_set_quoted(identity) (second)")
5813 with
alloc_fail(dev
[0], 2, "=wpa_config_set_quoted;interworking_set_eap_params"):
5814 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5815 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5816 dev
[0].request("NOTE wpa_config_set_quoted(password)")
5817 with
alloc_fail(dev
[0], 3, "=wpa_config_set_quoted;interworking_set_eap_params"):
5818 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5819 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5820 with
alloc_fail(dev
[0], 1, "wpa_config_add_network;interworking_connect_roaming_consortium"):
5821 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5822 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5823 with
alloc_fail(dev
[0], 1, "=interworking_connect_roaming_consortium"):
5824 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5825 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5826 dev
[0].remove_cred(id)
5828 id = dev
[0].add_cred_values({'roaming_consortium': "112233",
5829 'domain': "example.com",
5830 'realm': "example.com",
5833 dev
[0].set_cred(id, "password", "ext:password")
5834 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5835 dev
[0].dump_monitor()
5836 dev
[0].request("NOTE wpa_config_set(password)")
5837 with
alloc_fail(dev
[0], 3, "wpa_config_set;interworking_set_eap_params"):
5838 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5839 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5840 with
alloc_fail(dev
[0], 1, "interworking_set_hs20_params"):
5841 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5842 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5843 dev
[0].remove_cred(id)
5845 id = dev
[0].add_cred_values({'realm': "example.com",
5846 'domain': "example.com",
5847 'username': "certificate-user",
5848 'phase1': "include_tls_length=0",
5849 'domain_suffix_match': "example.com",
5850 'ca_cert': "auth_serv/ca.pem",
5851 'client_cert': "auth_serv/user.pem",
5852 'private_key': "auth_serv/user.key",
5853 'private_key_passwd': "secret"})
5854 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5855 dev
[0].dump_monitor()
5856 dev
[0].request("NOTE wpa_config_set_quoted(client_cert)")
5857 with
alloc_fail(dev
[0], 2, "=wpa_config_set_quoted;interworking_set_eap_params"):
5858 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5859 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5860 dev
[0].request("NOTE wpa_config_set_quoted(private_key)")
5861 with
alloc_fail(dev
[0], 3, "=wpa_config_set_quoted;interworking_set_eap_params"):
5862 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5863 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5864 dev
[0].request("NOTE wpa_config_set_quoted(private_key_passwd)")
5865 with
alloc_fail(dev
[0], 4, "=wpa_config_set_quoted;interworking_set_eap_params"):
5866 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5867 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5868 dev
[0].request("NOTE wpa_config_set_quoted(ca_cert)")
5869 with
alloc_fail(dev
[0], 5, "=wpa_config_set_quoted;interworking_set_eap_params"):
5870 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5871 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5872 dev
[0].request("NOTE wpa_config_set_quoted(domain_suffix_match)")
5873 with
alloc_fail(dev
[0], 6, "=wpa_config_set_quoted;interworking_set_eap_params"):
5874 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5875 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5876 with
alloc_fail(dev
[0], 1, "interworking_set_hs20_params"):
5877 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5878 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5879 dev
[0].remove_cred(id)
5881 id = dev
[0].add_cred_values({'imsi': "555444-333222111", 'eap': "SIM",
5882 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
5883 interworking_select(dev
[0], bssid
, freq
=2412)
5884 dev
[0].dump_monitor()
5885 with
alloc_fail(dev
[0], 1, "interworking_set_hs20_params"):
5886 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5887 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5888 dev
[0].request("NOTE wpa_config_set_quoted(password;milenage)")
5889 with
alloc_fail(dev
[0], 2, "=wpa_config_set_quoted;interworking_connect_3gpp"):
5890 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5891 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5892 dev
[0].request("NOTE wpa_config_set(eap)")
5893 with
alloc_fail(dev
[0], 1, "wpa_config_parse_eap;wpa_config_set;interworking_connect_3gpp"):
5894 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5895 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5896 dev
[0].request("NOTE set_root_nai:wpa_config_set(identity)")
5897 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;interworking_connect_3gpp"):
5898 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5899 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5900 dev
[0].remove_cred(id)
5902 id = dev
[0].add_cred_values({'roaming_consortium': "112233",
5904 'username': "user@example.com",
5905 'password': "password"})
5906 interworking_select(dev
[0], bssid
, freq
=2412)
5907 dev
[0].dump_monitor()
5908 dev
[0].request("NOTE Interworking: No EAP method set for credential using roaming consortium")
5909 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5910 dev
[0].remove_cred(id)
5913 params
= hs20_ap_params()
5914 params
['nai_realm'] = "0,example.com,25[3:26]"
5915 hapd
= hostapd
.add_ap(apdev
[0], params
)
5916 id = dev
[0].add_cred_values({'realm': "example.com",
5917 'domain': "example.com",
5918 'username': "hs20-test",
5919 'password': "password"})
5920 interworking_select(dev
[0], bssid
, freq
=2412)
5921 dev
[0].dump_monitor()
5922 dev
[0].request("NOTE wpa_config_set(PEAP/FAST-phase1)")
5923 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5924 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5925 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5926 dev
[0].request("NOTE wpa_config_set(PEAP/FAST-pac_interworking)")
5927 with
alloc_fail(dev
[0], 2, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5928 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5929 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5930 dev
[0].request("NOTE wpa_config_set(PEAP/FAST-phase2)")
5931 with
alloc_fail(dev
[0], 3, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5932 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5933 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5936 params
= hs20_ap_params()
5937 params
['nai_realm'] = "0,example.com,21"
5938 hapd
= hostapd
.add_ap(apdev
[0], params
)
5939 interworking_select(dev
[0], bssid
, freq
=2412)
5940 dev
[0].request("NOTE wpa_config_set(TTLS-defaults-phase2)")
5941 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5942 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5943 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5946 params
= hs20_ap_params()
5947 params
['nai_realm'] = "0,example.com,21[2:3]"
5948 hapd
= hostapd
.add_ap(apdev
[0], params
)
5949 interworking_select(dev
[0], bssid
, freq
=2412)
5950 dev
[0].request("NOTE wpa_config_set(TTLS-NON_EAP_MSCHAP-phase2)")
5951 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5952 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5953 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5956 params
= hs20_ap_params()
5957 params
['nai_realm'] = "0,example.com,21[2:2]"
5958 hapd
= hostapd
.add_ap(apdev
[0], params
)
5959 interworking_select(dev
[0], bssid
, freq
=2412)
5960 dev
[0].request("NOTE wpa_config_set(TTLS-NON_EAP_CHAP-phase2)")
5961 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5962 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5963 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5966 params
= hs20_ap_params()
5967 params
['nai_realm'] = "0,example.com,21[2:1]"
5968 hapd
= hostapd
.add_ap(apdev
[0], params
)
5969 interworking_select(dev
[0], bssid
, freq
=2412)
5970 dev
[0].request("NOTE wpa_config_set(TTLS-NON_EAP_PAP-phase2)")
5971 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5972 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5973 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5976 params
= hs20_ap_params()
5977 params
['nai_realm'] = "0,example.com,21[3:26]"
5978 hapd
= hostapd
.add_ap(apdev
[0], params
)
5979 interworking_select(dev
[0], bssid
, freq
=2412)
5980 dev
[0].request("NOTE wpa_config_set(TTLS-EAP-MSCHAPV2-phase2)")
5981 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5982 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5983 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5985 dev
[0].remove_cred(id)
5987 def test_ap_hs20_unexpected(dev
, apdev
):
5988 """Unexpected Hotspot 2.0 AP configuration"""
5989 check_eap_capa(dev
[0], "MSCHAPV2")
5990 bssid
= apdev
[0]['bssid']
5991 params
= hostapd
.wpa_eap_params(ssid
="test-hs20-fake")
5993 params
['wpa_pairwise'] = "TKIP CCMP"
5994 params
['rsn_pairwise'] = "CCMP"
5995 params
['ieee80211w'] = "1"
5996 #params['vendor_elements'] = 'dd07506f9a10140000'
5997 params
['vendor_elements'] = 'dd04506f9a10'
5998 hostapd
.add_ap(apdev
[0], params
)
6000 dev
[0].hs20_enable()
6001 dev
[0].scan_for_bss(bssid
, freq
="2412")
6002 dev
[0].connect("test-hs20-fake", key_mgmt
="WPA-EAP", eap
="TTLS",
6004 identity
="hs20-test", password
="password",
6005 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6008 dev
[1].hs20_enable()
6009 dev
[1].scan_for_bss(bssid
, freq
="2412")
6010 dev
[1].connect("test-hs20-fake", key_mgmt
="WPA-EAP", eap
="TTLS",
6012 identity
="hs20-test", password
="password",
6013 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6016 dev
[2].hs20_enable()
6017 dev
[2].scan_for_bss(bssid
, freq
="2412")
6018 dev
[2].connect("test-hs20-fake", key_mgmt
="WPA-EAP", eap
="TTLS",
6020 proto
="RSN", pairwise
="CCMP",
6021 identity
="hs20-test", password
="password",
6022 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6025 def test_ap_interworking_element_update(dev
, apdev
):
6026 """Dynamic Interworking element update"""
6027 bssid
= apdev
[0]['bssid']
6028 params
= hs20_ap_params()
6029 params
['hessid'] = bssid
6030 hapd
= hostapd
.add_ap(apdev
[0], params
)
6032 dev
[0].hs20_enable()
6033 dev
[0].scan_for_bss(bssid
, freq
="2412")
6034 bss
= dev
[0].get_bss(bssid
)
6035 logger
.info("Before update: " + str(bss
))
6036 if '6b091e0701020000000300' not in bss
['ie']:
6037 raise Exception("Expected Interworking element not seen before update")
6039 # Update configuration parameters related to Interworking element
6040 hapd
.set('access_network_type', '2')
6041 hapd
.set('asra', '1')
6042 hapd
.set('esr', '1')
6043 hapd
.set('uesa', '1')
6044 hapd
.set('venue_group', '2')
6045 hapd
.set('venue_type', '8')
6046 if "OK" not in hapd
.request("UPDATE_BEACON"):
6047 raise Exception("UPDATE_BEACON failed")
6048 dev
[0].request("BSS_FLUSH 0")
6049 dev
[0].scan_for_bss(bssid
, freq
="2412", force_scan
=True)
6050 bss
= dev
[0].get_bss(bssid
)
6051 logger
.info("After update: " + str(bss
))
6052 if '6b09f20208020000000300' not in bss
['ie']:
6053 raise Exception("Expected Interworking element not seen after update")
6055 def test_ap_hs20_terms_and_conditions(dev
, apdev
):
6056 """Hotspot 2.0 Terms and Conditions signaling"""
6057 check_eap_capa(dev
[0], "MSCHAPV2")
6058 bssid
= apdev
[0]['bssid']
6059 params
= hs20_ap_params()
6060 params
['hessid'] = bssid
6061 params
['hs20_t_c_filename'] = 'terms-and-conditions'
6062 params
['hs20_t_c_timestamp'] = '123456789'
6064 hostapd
.add_ap(apdev
[0], params
)
6066 dev
[0].hs20_enable()
6067 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
6068 identity
="hs20-t-c-test", password
="password",
6069 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6070 ieee80211w
='2', scan_freq
="2412")
6071 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=5)
6073 raise Exception("Terms and Conditions Acceptance notification not received")
6074 url
= "https://example.com/t_and_c?addr=%s&ap=123" % dev
[0].own_addr()
6076 raise Exception("Unexpected URL: " + ev
)
6078 def test_ap_hs20_terms_and_conditions_coa(dev
, apdev
):
6079 """Hotspot 2.0 Terms and Conditions signaling - CoA"""
6083 import pyrad
.dictionary
6086 raise HwsimSkip("No pyrad modules available")
6088 check_eap_capa(dev
[0], "MSCHAPV2")
6089 bssid
= apdev
[0]['bssid']
6090 params
= hs20_ap_params()
6091 params
['hessid'] = bssid
6092 params
['hs20_t_c_filename'] = 'terms-and-conditions'
6093 params
['hs20_t_c_timestamp'] = '123456789'
6094 params
['own_ip_addr'] = "127.0.0.1"
6095 params
['radius_das_port'] = "3799"
6096 params
['radius_das_client'] = "127.0.0.1 secret"
6097 params
['radius_das_require_event_timestamp'] = "1"
6098 hapd
= hostapd
.add_ap(apdev
[0], params
)
6100 dev
[0].hs20_enable()
6101 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
6102 identity
="hs20-t-c-test", password
="password",
6103 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6104 ieee80211w
='2', scan_freq
="2412")
6106 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=5)
6108 raise Exception("Terms and Conditions filtering not enabled")
6109 if ev
.split(' ')[1] != dev
[0].own_addr():
6110 raise Exception("Unexpected STA address for filtering: " + ev
)
6112 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=5)
6114 raise Exception("Terms and Conditions Acceptance notification not received")
6115 url
= "https://example.com/t_and_c?addr=%s&ap=123" % dev
[0].own_addr()
6117 raise Exception("Unexpected URL: " + ev
)
6119 dict = pyrad
.dictionary
.Dictionary("dictionary.radius")
6121 srv
= pyrad
.client
.Client(server
="127.0.0.1", acctport
=3799,
6122 secret
=b
"secret", dict=dict)
6126 sta
= hapd
.get_sta(dev
[0].own_addr())
6127 multi_sess_id
= sta
['authMultiSessionId']
6129 logger
.info("CoA-Request with matching Acct-Session-Id")
6130 vsa
= binascii
.unhexlify('00009f68090600000000')
6131 req
= radius_das
.CoAPacket(dict=dict, secret
=b
"secret",
6132 NAS_IP_Address
="127.0.0.1",
6133 Acct_Multi_Session_Id
=multi_sess_id
,
6134 Chargeable_User_Identity
="hs20-cui",
6135 Event_Timestamp
=int(time
.time()),
6136 Vendor_Specific
=vsa
)
6137 reply
= srv
.SendPacket(req
)
6138 logger
.debug("RADIUS response from hostapd")
6139 for i
in list(reply
.keys()):
6140 logger
.debug("%s: %s" % (i
, reply
[i
]))
6141 if reply
.code
!= pyrad
.packet
.CoAACK
:
6142 raise Exception("CoA-Request failed")
6144 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-REMOVE"], timeout
=5)
6146 raise Exception("Terms and Conditions filtering not disabled")
6147 if ev
.split(' ')[1] != dev
[0].own_addr():
6148 raise Exception("Unexpected STA address for filtering: " + ev
)
6150 def test_ap_hs20_terms_and_conditions_sql(dev
, apdev
, params
):
6151 """Hotspot 2.0 Terms and Conditions using SQLite for user DB"""
6152 addr
= dev
[0].own_addr()
6153 run_ap_hs20_terms_and_conditions_sql(dev
, apdev
, params
,
6154 "https://example.com/t_and_c?addr=@1@&ap=123",
6155 "https://example.com/t_and_c?addr=" + addr
+ "&ap=123")
6157 def test_ap_hs20_terms_and_conditions_sql2(dev
, apdev
, params
):
6158 """Hotspot 2.0 Terms and Conditions using SQLite for user DB"""
6159 addr
= dev
[0].own_addr()
6160 run_ap_hs20_terms_and_conditions_sql(dev
, apdev
, params
,
6161 "https://example.com/t_and_c?addr=@1@",
6162 "https://example.com/t_and_c?addr=" + addr
)
6164 def run_ap_hs20_terms_and_conditions_sql(dev
, apdev
, params
, url_template
,
6166 check_eap_capa(dev
[0], "MSCHAPV2")
6170 raise HwsimSkip("No sqlite3 module available")
6171 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
6176 con
= sqlite3
.connect(dbfile
)
6179 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER, t_c_timestamp INTEGER)")
6180 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
6181 cur
.execute("INSERT INTO users(identity,methods,password,phase2) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1)")
6182 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
6183 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
6184 cur
.execute("CREATE TABLE pending_tc(mac_addr TEXT PRIMARY KEY, identity TEXT)")
6185 cur
.execute("CREATE TABLE current_sessions(mac_addr TEXT PRIMARY KEY, identity TEXT, start_time TEXT, nas TEXT, hs20_t_c_filtering BOOLEAN, waiting_coa_ack BOOLEAN, coa_ack_received BOOLEAN)")
6189 params
= {"ssid": "as", "beacon_int": "2000",
6190 "radius_server_clients": "auth_serv/radius_clients.conf",
6191 "radius_server_auth_port": '18128',
6193 "eap_user_file": "sqlite:" + dbfile
,
6194 "ca_cert": "auth_serv/ca.pem",
6195 "server_cert": "auth_serv/server.pem",
6196 "private_key": "auth_serv/server.key"}
6197 params
['hs20_t_c_server_url'] = url_template
6198 authsrv
= hostapd
.add_ap(apdev
[1], params
)
6200 bssid
= apdev
[0]['bssid']
6201 params
= hs20_ap_params()
6202 params
['auth_server_port'] = "18128"
6203 params
['hs20_t_c_filename'] = 'terms-and-conditions'
6204 params
['hs20_t_c_timestamp'] = '123456789'
6205 params
['own_ip_addr'] = "127.0.0.1"
6206 params
['radius_das_port'] = "3799"
6207 params
['radius_das_client'] = "127.0.0.1 radius"
6208 params
['radius_das_require_event_timestamp'] = "1"
6209 params
['disable_pmksa_caching'] = '1'
6210 hapd
= hostapd
.add_ap(apdev
[0], params
)
6212 dev
[0].request("SET pmf 1")
6213 dev
[0].hs20_enable()
6214 id = dev
[0].add_cred_values({'realm': "example.com",
6215 'username': "user-mschapv2",
6216 'password': "password",
6217 'ca_cert': "auth_serv/ca.pem"})
6218 interworking_select(dev
[0], bssid
, freq
="2412")
6219 interworking_connect(dev
[0], bssid
, "TTLS")
6221 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=5)
6223 raise Exception("Terms and Conditions filtering not enabled")
6226 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=5)
6228 raise Exception("Terms and Conditions Acceptance notification not received")
6229 url
= ev
.split(' ')[1]
6230 if url
!= url_expected
:
6231 raise Exception("Unexpected URL delivered to the client: %s (expected %s)" % (url
, url_expected
))
6232 dev
[0].dump_monitor()
6236 cur
.execute("SELECT * from current_sessions")
6237 rows
= cur
.fetchall()
6239 raise Exeception("Unexpected number of rows in current_sessions (%d; expected %d)" % (len(rows
), 1))
6240 logger
.info("current_sessions: " + str(rows
))
6242 if "OK" not in authsrv
.request("DAC_REQUEST coa %s t_c_clear" % dev
[0].own_addr()):
6243 raise Exception("DAC_REQUEST failed")
6245 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-REMOVE"], timeout
=5)
6247 raise Exception("Terms and Conditions filtering not disabled")
6248 if ev
.split(' ')[1] != dev
[0].own_addr():
6249 raise Exception("Unexpected STA address for filtering: " + ev
)
6254 cur
.execute("SELECT * from current_sessions")
6255 rows
= cur
.fetchall()
6257 raise Exeception("Unexpected number of rows in current_sessions (%d; expected %d)" % (len(rows
), 1))
6258 logger
.info("current_sessions: " + str(rows
))
6259 if rows
[0][4] != 0 or rows
[0][5] != 0 or rows
[0][6] != 1:
6260 raise Exception("Unexpected current_sessions information after CoA-ACK")
6262 dev
[0].request("DISCONNECT")
6263 dev
[0].wait_disconnected()
6264 dev
[0].dump_monitor()
6266 # Simulate T&C server operation on user reading the updated version
6269 cur
.execute("SELECT identity FROM pending_tc WHERE mac_addr='" +
6270 dev
[0].own_addr() + "'")
6271 rows
= cur
.fetchall()
6273 raise Exception("No pending_tc entry found")
6274 if rows
[0][0] != 'user-mschapv2':
6275 raise Exception("Unexpected pending_tc identity value")
6277 cur
.execute("UPDATE users SET t_c_timestamp=123456789 WHERE identity='user-mschapv2'")
6279 dev
[0].request("RECONNECT")
6280 dev
[0].wait_connected()
6282 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=0.1)
6284 raise Exception("Terms and Conditions filtering enabled unexpectedly")
6287 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=0.1)
6289 raise Exception("Unexpected Terms and Conditions Acceptance notification")
6290 dev
[0].dump_monitor()
6292 dev
[0].request("DISCONNECT")
6293 dev
[0].wait_disconnected()
6294 dev
[0].dump_monitor()
6297 hapd
.set('hs20_t_c_timestamp', '123456790')
6299 dev
[0].request("RECONNECT")
6300 dev
[0].wait_connected()
6302 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=5)
6304 raise Exception("Terms and Conditions filtering not enabled")
6307 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=5)
6309 raise Exception("Terms and Conditions Acceptance notification not received (2)")
6310 dev
[0].dump_monitor()
6312 dev
[0].request("DISCONNECT")
6313 dev
[0].wait_disconnected()
6314 dev
[0].dump_monitor()
6316 # Simulate T&C server operation on user reading the updated version
6319 cur
.execute("UPDATE users SET t_c_timestamp=123456790 WHERE identity='user-mschapv2'")
6321 dev
[0].request("RECONNECT")
6322 dev
[0].wait_connected()
6324 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=0.1)
6326 raise Exception("Terms and Conditions filtering enabled unexpectedly")
6329 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=0.1)
6331 raise Exception("Unexpected Terms and Conditions Acceptance notification (2)")
6332 dev
[0].dump_monitor()
6335 dev
[0].request("SET pmf 0")
6337 def test_ap_hs20_release_number_1(dev
, apdev
):
6338 """Hotspot 2.0 with AP claiming support for Release 1"""
6339 run_ap_hs20_release_number(dev
, apdev
, 1)
6341 def test_ap_hs20_release_number_2(dev
, apdev
):
6342 """Hotspot 2.0 with AP claiming support for Release 2"""
6343 run_ap_hs20_release_number(dev
, apdev
, 2)
6345 def test_ap_hs20_release_number_3(dev
, apdev
):
6346 """Hotspot 2.0 with AP claiming support for Release 3"""
6347 run_ap_hs20_release_number(dev
, apdev
, 3)
6349 def run_ap_hs20_release_number(dev
, apdev
, release
):
6350 check_eap_capa(dev
[0], "MSCHAPV2")
6351 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user",
6353 rel
= dev
[0].get_status_field('hs20')
6354 if rel
!= str(release
):
6355 raise Exception("Unexpected release number indicated: " + rel
)
6357 def test_ap_hs20_missing_pmf(dev
, apdev
):
6358 """Hotspot 2.0 connection attempt without PMF"""
6359 check_eap_capa(dev
[0], "MSCHAPV2")
6360 bssid
= apdev
[0]['bssid']
6361 params
= hs20_ap_params()
6362 params
['hessid'] = bssid
6363 params
['disable_dgaf'] = '1'
6364 hostapd
.add_ap(apdev
[0], params
)
6366 dev
[0].hs20_enable()
6367 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
6369 identity
="hs20-test", password
="password",
6370 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6371 scan_freq
="2412", update_identifier
="54321",
6372 roaming_consortium_selection
="1020304050",
6374 ev
= dev
[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout
=10)
6375 dev
[0].request("DISCONNECT")
6377 raise Exception("Association rejection not reported")
6378 if "status_code=31" not in ev
:
6379 raise Exception("Unexpected rejection reason: " + ev
)
6381 def test_ap_hs20_open_osu_association(dev
, apdev
):
6382 """Hotspot 2.0 open OSU association"""
6384 run_ap_hs20_open_osu_association(dev
, apdev
)
6386 dev
[0].request("VENDOR_ELEM_REMOVE 13 *")
6388 def run_ap_hs20_open_osu_association(dev
, apdev
):
6389 params
= {"ssid": "HS 2.0 OSU open"}
6390 hostapd
.add_ap(apdev
[0], params
)
6391 dev
[0].connect("HS 2.0 OSU open", key_mgmt
="NONE", scan_freq
="2412")
6392 dev
[0].request("REMOVE_NETWORK all")
6393 dev
[0].wait_disconnected()
6394 dev
[0].dump_monitor()
6395 # Test with unexpected Hotspot 2.0 Indication element in Assoc Req
6396 dev
[0].request("VENDOR_ELEM_ADD 13 dd07506f9a10220000")
6397 dev
[0].connect("HS 2.0 OSU open", key_mgmt
="NONE", scan_freq
="2412")