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 test_ap_eap
import check_eap_capa
, check_domain_match_full
26 from test_gas
import gas_rx
, parse_gas
, action_response
, anqp_initial_resp
, send_gas_resp
, ACTION_CATEG_PUBLIC
, GAS_INITIAL_RESPONSE
28 def hs20_ap_params(ssid
="test-hs20"):
29 params
= hostapd
.wpa2_params(ssid
=ssid
)
30 params
['wpa_key_mgmt'] = "WPA-EAP"
31 params
['ieee80211w'] = "1"
32 params
['ieee8021x'] = "1"
33 params
['auth_server_addr'] = "127.0.0.1"
34 params
['auth_server_port'] = "1812"
35 params
['auth_server_shared_secret'] = "radius"
36 params
['interworking'] = "1"
37 params
['access_network_type'] = "14"
38 params
['internet'] = "1"
42 params
['venue_group'] = "7"
43 params
['venue_type'] = "1"
44 params
['venue_name'] = ["eng:Example venue", "fin:Esimerkkipaikka"]
45 params
['roaming_consortium'] = ["112233", "1020304050", "010203040506",
47 params
['domain_name'] = "example.com,another.example.com"
48 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]",
49 "0,another.example.com"]
51 params
['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
52 params
['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0"]
53 params
['hs20_operating_class'] = "5173"
54 params
['anqp_3gpp_cell_net'] = "244,91"
57 def check_auto_select(dev
, bssid
):
58 dev
.scan_for_bss(bssid
, freq
="2412")
59 dev
.request("INTERWORKING_SELECT auto freq=2412")
60 ev
= dev
.wait_connected(timeout
=15)
62 raise Exception("Connected to incorrect network")
63 dev
.request("REMOVE_NETWORK all")
64 dev
.wait_disconnected()
67 def interworking_select(dev
, bssid
, type=None, no_match
=False, freq
=None):
69 if bssid
and freq
and not no_match
:
70 dev
.scan_for_bss(bssid
, freq
=freq
)
71 freq_extra
= " freq=" + str(freq
) if freq
else ""
72 dev
.request("INTERWORKING_SELECT" + freq_extra
)
73 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
76 raise Exception("Network selection timed out")
78 if "INTERWORKING-NO-MATCH" not in ev
:
79 raise Exception("Unexpected network match")
81 if "INTERWORKING-NO-MATCH" in ev
:
82 logger
.info("Matching network not found - try again")
84 dev
.request("INTERWORKING_SELECT" + freq_extra
)
85 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
88 raise Exception("Network selection timed out")
89 if "INTERWORKING-NO-MATCH" in ev
:
90 raise Exception("Matching network not found")
91 if bssid
and bssid
not in ev
:
92 raise Exception("Unexpected BSSID in match")
93 if type and "type=" + type not in ev
:
94 raise Exception("Network type not recognized correctly")
96 def check_sp_type(dev
, sp_type
):
97 type = dev
.get_status_field("sp_type")
99 raise Exception("sp_type not available")
101 raise Exception("sp_type did not indicate %s network" % sp_type
)
103 def hlr_auc_gw_available():
104 if not os
.path
.exists("/tmp/hlr_auc_gw.sock"):
105 raise HwsimSkip("No hlr_auc_gw socket available")
106 if not os
.path
.exists("../../hostapd/hlr_auc_gw"):
107 raise HwsimSkip("No hlr_auc_gw available")
109 def interworking_ext_sim_connect(dev
, bssid
, method
):
110 dev
.request("INTERWORKING_CONNECT " + bssid
)
111 interworking_ext_sim_auth(dev
, method
)
113 def interworking_ext_sim_auth(dev
, method
):
114 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
116 raise Exception("Network connected timed out")
117 if "(" + method
+ ")" not in ev
:
118 raise Exception("Unexpected EAP method selection")
120 ev
= dev
.wait_event(["CTRL-REQ-SIM"], timeout
=15)
122 raise Exception("Wait for external SIM processing request timed out")
124 if p
[1] != "GSM-AUTH":
125 raise Exception("Unexpected CTRL-REQ-SIM type")
126 id = p
[0].split('-')[3]
127 rand
= p
[2].split(' ')[0]
129 res
= subprocess
.check_output(["../../hostapd/hlr_auc_gw",
131 "auth_serv/hlr_auc_gw.milenage_db",
132 "GSM-AUTH-REQ 232010000000000 " + rand
]).decode()
133 if "GSM-AUTH-RESP" not in res
:
134 raise Exception("Unexpected hlr_auc_gw response")
135 resp
= res
.split(' ')[2].rstrip()
137 dev
.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp
)
138 dev
.wait_connected(timeout
=15)
140 def interworking_connect(dev
, bssid
, method
):
141 dev
.request("INTERWORKING_CONNECT " + bssid
)
142 interworking_auth(dev
, method
)
144 def interworking_auth(dev
, method
):
145 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
147 raise Exception("Network connected timed out")
148 if "(" + method
+ ")" not in ev
:
149 raise Exception("Unexpected EAP method selection")
151 dev
.wait_connected(timeout
=15)
153 def check_probe_resp(wt
, bssid_unexpected
, bssid_expected
):
155 count
= wt
.get_bss_counter("probe_response", bssid_unexpected
)
157 raise Exception("Unexpected Probe Response frame from AP")
160 count
= wt
.get_bss_counter("probe_response", bssid_expected
)
162 raise Exception("No Probe Response frame from AP")
164 def test_ap_anqp_sharing(dev
, apdev
):
165 """ANQP sharing within ESS and explicit unshare"""
166 check_eap_capa(dev
[0], "MSCHAPV2")
167 dev
[0].flush_scan_cache()
169 bssid
= apdev
[0]['bssid']
170 params
= hs20_ap_params()
171 params
['hessid'] = bssid
172 hostapd
.add_ap(apdev
[0], params
)
174 bssid2
= apdev
[1]['bssid']
175 params
= hs20_ap_params()
176 params
['hessid'] = bssid
177 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
178 hostapd
.add_ap(apdev
[1], params
)
181 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
182 'password': "secret",
183 'domain': "example.com"})
184 logger
.info("Normal network selection with shared ANQP results")
185 dev
[0].scan_for_bss(bssid
, freq
="2412")
186 dev
[0].scan_for_bss(bssid2
, freq
="2412")
187 interworking_select(dev
[0], None, "home", freq
="2412")
188 dev
[0].dump_monitor()
189 state
= dev
[0].get_status_field('wpa_state')
190 if state
!= "DISCONNECTED":
191 raise Exception("Unexpected wpa_state after INTERWORKING_SELECT: " + state
)
193 logger
.debug("BSS entries:\n" + dev
[0].request("BSS RANGE=ALL"))
194 res1
= dev
[0].get_bss(bssid
)
195 res2
= dev
[0].get_bss(bssid2
)
196 if 'anqp_nai_realm' not in res1
:
197 raise Exception("anqp_nai_realm not found for AP1")
198 if 'anqp_nai_realm' not in res2
:
199 raise Exception("anqp_nai_realm not found for AP2")
200 if res1
['anqp_nai_realm'] != res2
['anqp_nai_realm']:
201 raise Exception("ANQP results were not shared between BSSes")
203 logger
.info("Explicit ANQP request to unshare ANQP results")
204 dev
[0].request("ANQP_GET " + bssid
+ " 263")
205 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
207 raise Exception("ANQP operation timed out")
209 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
210 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
212 raise Exception("ANQP operation timed out")
214 res1
= dev
[0].get_bss(bssid
)
215 res2
= dev
[0].get_bss(bssid2
)
216 if res1
['anqp_nai_realm'] == res2
['anqp_nai_realm']:
217 raise Exception("ANQP results were not unshared")
219 def test_ap_anqp_domain_id(dev
, apdev
):
221 check_eap_capa(dev
[0], "MSCHAPV2")
222 dev
[0].flush_scan_cache()
224 bssid
= apdev
[0]['bssid']
225 params
= hs20_ap_params()
226 params
['hessid'] = bssid
227 params
['anqp_domain_id'] = '1234'
228 hostapd
.add_ap(apdev
[0], params
)
230 bssid2
= apdev
[1]['bssid']
231 params
= hs20_ap_params()
232 params
['hessid'] = bssid
233 params
['anqp_domain_id'] = '1234'
234 hostapd
.add_ap(apdev
[1], params
)
237 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
238 'password': "secret",
239 'domain': "example.com"})
240 dev
[0].scan_for_bss(bssid
, freq
="2412")
241 dev
[0].scan_for_bss(bssid2
, freq
="2412")
242 interworking_select(dev
[0], None, "home", freq
="2412")
244 def test_ap_anqp_no_sharing_diff_ess(dev
, apdev
):
245 """ANQP no sharing between ESSs"""
246 check_eap_capa(dev
[0], "MSCHAPV2")
247 dev
[0].flush_scan_cache()
249 bssid
= apdev
[0]['bssid']
250 params
= hs20_ap_params()
251 params
['hessid'] = bssid
252 hostapd
.add_ap(apdev
[0], params
)
254 bssid2
= apdev
[1]['bssid']
255 params
= hs20_ap_params(ssid
="test-hs20-another")
256 params
['hessid'] = bssid
257 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
258 hostapd
.add_ap(apdev
[1], params
)
261 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
262 'password': "secret",
263 'domain': "example.com"})
264 logger
.info("Normal network selection with shared ANQP results")
265 dev
[0].scan_for_bss(bssid
, freq
="2412")
266 dev
[0].scan_for_bss(bssid2
, freq
="2412")
267 interworking_select(dev
[0], None, "home", freq
="2412")
269 def test_ap_anqp_no_sharing_missing_info(dev
, apdev
):
270 """ANQP no sharing due to missing information"""
271 check_eap_capa(dev
[0], "MSCHAPV2")
272 dev
[0].flush_scan_cache()
274 bssid
= apdev
[0]['bssid']
275 params
= hs20_ap_params()
276 params
['hessid'] = bssid
277 del params
['roaming_consortium']
278 del params
['domain_name']
279 del params
['anqp_3gpp_cell_net']
280 del params
['nai_realm']
281 hostapd
.add_ap(apdev
[0], params
)
283 bssid2
= apdev
[1]['bssid']
284 params
= hs20_ap_params()
285 params
['hessid'] = bssid
286 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
287 hostapd
.add_ap(apdev
[1], params
)
290 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
291 'password': "secret",
292 'domain': "example.com"})
293 logger
.info("Normal network selection with shared ANQP results")
294 dev
[0].scan_for_bss(bssid
, freq
="2412")
295 dev
[0].scan_for_bss(bssid2
, freq
="2412")
296 interworking_select(dev
[0], None, "home", freq
="2412")
298 def test_ap_anqp_sharing_oom(dev
, apdev
):
299 """ANQP sharing within ESS and explicit unshare OOM"""
300 check_eap_capa(dev
[0], "MSCHAPV2")
301 dev
[0].flush_scan_cache()
303 bssid
= apdev
[0]['bssid']
304 params
= hs20_ap_params()
305 params
['hessid'] = bssid
306 hostapd
.add_ap(apdev
[0], params
)
308 bssid2
= apdev
[1]['bssid']
309 params
= hs20_ap_params()
310 params
['hessid'] = bssid
311 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"]
312 hostapd
.add_ap(apdev
[1], params
)
315 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
316 'password': "secret",
317 'domain': "example.com"})
318 dev
[0].scan_for_bss(bssid
, freq
="2412")
319 dev
[0].scan_for_bss(bssid2
, freq
="2412")
320 interworking_select(dev
[0], None, "home", freq
="2412")
321 dev
[0].dump_monitor()
323 with
alloc_fail(dev
[0], 1, "wpa_bss_anqp_clone"):
324 dev
[0].request("ANQP_GET " + bssid
+ " 263")
325 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
327 raise Exception("ANQP operation timed out")
329 def test_ap_nai_home_realm_query(dev
, apdev
):
330 """NAI Home Realm Query"""
331 check_eap_capa(dev
[0], "MSCHAPV2")
332 bssid
= apdev
[0]['bssid']
333 params
= hs20_ap_params()
334 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]",
335 "0,another.example.org"]
336 hostapd
.add_ap(apdev
[0], params
)
338 dev
[0].scan(freq
="2412")
339 dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " realm=example.com")
340 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
342 raise Exception("ANQP operation timed out")
343 nai1
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
344 dev
[0].dump_monitor()
346 dev
[0].request("ANQP_GET " + bssid
+ " 263")
347 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
349 raise Exception("ANQP operation timed out")
350 nai2
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
352 if len(nai1
) >= len(nai2
):
353 raise Exception("Unexpected NAI Realm list response lengths")
354 if binascii
.hexlify(b
"example.com").decode() not in nai1
:
355 raise Exception("Home realm not reported")
356 if binascii
.hexlify(b
"example.org").decode() in nai1
:
357 raise Exception("Non-home realm reported")
358 if binascii
.hexlify(b
"example.com").decode() not in nai2
:
359 raise Exception("Home realm not reported in wildcard query")
360 if binascii
.hexlify(b
"example.org").decode() not in nai2
:
361 raise Exception("Non-home realm not reported in wildcard query ")
364 "00:11:22:33:44:55 123",
365 "00:11:22:33:44:55 qq"]
367 if "FAIL" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd
):
368 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd
)
370 dev
[0].dump_monitor()
371 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
372 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
373 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
375 raise Exception("ANQP operation timed out")
376 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=0.1)
378 raise Exception("Unexpected ANQP response: " + ev
)
380 dev
[0].dump_monitor()
381 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " 01000b6578616d706c652e636f6d"):
382 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
383 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
385 raise Exception("No ANQP response")
386 if "NAI Realm list" not in ev
:
387 raise Exception("Missing NAI Realm list: " + ev
)
389 dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
390 'password': "secret",
391 'domain': "example.com"})
392 dev
[0].dump_monitor()
393 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
394 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
395 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
397 raise Exception("No ANQP response")
398 if "NAI Realm list" not in ev
:
399 raise Exception("Missing NAI Realm list: " + ev
)
402 def test_ap_interworking_scan_filtering(dev
, apdev
):
403 """Interworking scan filtering with HESSID and access network type"""
405 _test_ap_interworking_scan_filtering(dev
, apdev
)
407 dev
[0].request("SET hessid 00:00:00:00:00:00")
408 dev
[0].request("SET access_network_type 15")
410 def _test_ap_interworking_scan_filtering(dev
, apdev
):
411 bssid
= apdev
[0]['bssid']
412 params
= hs20_ap_params()
413 ssid
= "test-hs20-ap1"
414 params
['ssid'] = ssid
415 params
['hessid'] = bssid
416 hapd0
= hostapd
.add_ap(apdev
[0], params
)
418 bssid2
= apdev
[1]['bssid']
419 params
= hs20_ap_params()
420 ssid2
= "test-hs20-ap2"
421 params
['ssid'] = ssid2
422 params
['hessid'] = bssid2
423 params
['access_network_type'] = "1"
424 del params
['venue_group']
425 del params
['venue_type']
426 hostapd
.add_ap(apdev
[1], params
)
430 Wlantest
.setup(hapd0
)
434 # Make sure wlantest has seen both BSSs to avoid issues in trying to clear
435 # counters for non-existing BSS.
436 dev
[0].scan_for_bss(bssid
, freq
="2412")
437 dev
[0].scan_for_bss(bssid2
, freq
="2412")
438 wt
.clear_bss_counters(bssid
)
439 wt
.clear_bss_counters(bssid2
)
441 logger
.info("Check probe request filtering based on HESSID")
443 dev
[0].request("SET hessid " + bssid2
)
444 dev
[0].scan(freq
="2412")
446 check_probe_resp(wt
, bssid
, bssid2
)
448 logger
.info("Check probe request filtering based on access network type")
450 wt
.clear_bss_counters(bssid
)
451 wt
.clear_bss_counters(bssid2
)
452 dev
[0].request("SET hessid 00:00:00:00:00:00")
453 dev
[0].request("SET access_network_type 14")
454 dev
[0].scan(freq
="2412")
456 check_probe_resp(wt
, bssid2
, bssid
)
458 wt
.clear_bss_counters(bssid
)
459 wt
.clear_bss_counters(bssid2
)
460 dev
[0].request("SET hessid 00:00:00:00:00:00")
461 dev
[0].request("SET access_network_type 1")
462 dev
[0].scan(freq
="2412")
464 check_probe_resp(wt
, bssid
, bssid2
)
466 logger
.info("Check probe request filtering based on HESSID and ANT")
468 wt
.clear_bss_counters(bssid
)
469 wt
.clear_bss_counters(bssid2
)
470 dev
[0].request("SET hessid " + bssid
)
471 dev
[0].request("SET access_network_type 14")
472 dev
[0].scan(freq
="2412")
474 check_probe_resp(wt
, bssid2
, bssid
)
476 wt
.clear_bss_counters(bssid
)
477 wt
.clear_bss_counters(bssid2
)
478 dev
[0].request("SET hessid " + bssid2
)
479 dev
[0].request("SET access_network_type 14")
480 dev
[0].scan(freq
="2412")
482 check_probe_resp(wt
, bssid
, None)
483 check_probe_resp(wt
, bssid2
, None)
485 wt
.clear_bss_counters(bssid
)
486 wt
.clear_bss_counters(bssid2
)
487 dev
[0].request("SET hessid " + bssid
)
488 dev
[0].request("SET access_network_type 1")
489 dev
[0].scan(freq
="2412")
491 check_probe_resp(wt
, bssid
, None)
492 check_probe_resp(wt
, bssid2
, None)
494 def test_ap_hs20_select(dev
, apdev
):
495 """Hotspot 2.0 network selection"""
496 bssid
= apdev
[0]['bssid']
497 params
= hs20_ap_params()
498 params
['hessid'] = bssid
499 hostapd
.add_ap(apdev
[0], params
)
502 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
503 'password': "secret",
504 'domain': "example.com"})
505 interworking_select(dev
[0], bssid
, "home")
507 dev
[0].remove_cred(id)
508 id = dev
[0].add_cred_values({'realm': "example.com", 'username': "test",
509 'password': "secret",
510 'domain': "no.match.example.com"})
511 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
513 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com")
514 interworking_select(dev
[0], bssid
, no_match
=True, freq
="2412")
516 res
= dev
[0].request("SCAN_RESULTS")
517 if "[HS20]" not in res
:
518 raise Exception("HS20 flag missing from scan results: " + res
)
520 bssid2
= apdev
[1]['bssid']
521 params
= hs20_ap_params()
522 params
['nai_realm'] = ["0,example.org,21"]
523 params
['hessid'] = bssid2
524 params
['domain_name'] = "example.org"
525 hostapd
.add_ap(apdev
[1], params
)
526 dev
[0].remove_cred(id)
527 id = dev
[0].add_cred_values({'realm': "example.org", 'username': "test",
528 'password': "secret",
529 'domain': "example.org"})
530 interworking_select(dev
[0], bssid2
, "home", freq
="2412")
532 def hs20_simulated_sim(dev
, ap
, method
):
534 params
= hs20_ap_params()
535 params
['hessid'] = bssid
536 params
['anqp_3gpp_cell_net'] = "555,444"
537 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
538 hostapd
.add_ap(ap
, params
)
541 dev
.add_cred_values({'imsi': "555444-333222111", 'eap': method
,
542 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
543 interworking_select(dev
, bssid
, "home", freq
="2412")
544 interworking_connect(dev
, bssid
, method
)
545 check_sp_type(dev
, "home")
547 def test_ap_hs20_sim(dev
, apdev
):
548 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
549 hlr_auc_gw_available()
550 hs20_simulated_sim(dev
[0], apdev
[0], "SIM")
551 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
552 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
554 raise Exception("Timeout on already-connected event")
556 def test_ap_hs20_sim_invalid(dev
, apdev
):
557 """Hotspot 2.0 with simulated SIM and EAP-SIM - invalid IMSI"""
558 hlr_auc_gw_available()
559 bssid
= apdev
[0]['bssid']
560 params
= hs20_ap_params()
561 params
['hessid'] = bssid
562 params
['anqp_3gpp_cell_net'] = "555,444"
563 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
564 hostapd
.add_ap(apdev
[0], params
)
567 dev
[0].add_cred_values({'imsi': "555444-3332221110", 'eap': "SIM",
568 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
569 # This hits "No valid IMSI available" in build_root_nai()
570 interworking_select(dev
[0], bssid
, freq
="2412")
572 def test_ap_hs20_sim_oom(dev
, apdev
):
573 """Hotspot 2.0 with simulated SIM and EAP-SIM - OOM"""
574 hlr_auc_gw_available()
575 bssid
= apdev
[0]['bssid']
576 params
= hs20_ap_params()
577 params
['hessid'] = bssid
578 params
['anqp_3gpp_cell_net'] = "555,444"
579 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
580 hostapd
.add_ap(apdev
[0], params
)
583 dev
[0].add_cred_values({'imsi': "555444-333222111", 'eap': "SIM",
584 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
585 dev
[0].scan_for_bss(bssid
, freq
=2412)
586 interworking_select(dev
[0], bssid
, freq
="2412")
588 with
alloc_fail(dev
[0], 1, "wpa_config_add_network;interworking_connect_3gpp"):
589 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
590 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
592 with
alloc_fail(dev
[0], 1, "=interworking_connect_3gpp"):
593 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
594 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
596 def test_ap_hs20_aka(dev
, apdev
):
597 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
598 hlr_auc_gw_available()
599 hs20_simulated_sim(dev
[0], apdev
[0], "AKA")
601 def test_ap_hs20_aka_prime(dev
, apdev
):
602 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
603 hlr_auc_gw_available()
604 hs20_simulated_sim(dev
[0], apdev
[0], "AKA'")
606 def test_ap_hs20_ext_sim(dev
, apdev
):
607 """Hotspot 2.0 with external SIM processing"""
608 hlr_auc_gw_available()
609 bssid
= apdev
[0]['bssid']
610 params
= hs20_ap_params()
611 params
['hessid'] = bssid
612 params
['anqp_3gpp_cell_net'] = "232,01"
613 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
614 hostapd
.add_ap(apdev
[0], params
)
618 dev
[0].request("SET external_sim 1")
619 dev
[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM"})
620 interworking_select(dev
[0], bssid
, "home", freq
="2412")
621 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
622 check_sp_type(dev
[0], "home")
624 dev
[0].request("SET external_sim 0")
626 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
627 """Hotspot 2.0 with external SIM processing in roaming network"""
628 hlr_auc_gw_available()
629 bssid
= apdev
[0]['bssid']
630 params
= hs20_ap_params()
631 params
['hessid'] = bssid
632 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
633 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
634 hostapd
.add_ap(apdev
[0], params
)
638 dev
[0].request("SET external_sim 1")
639 dev
[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM"})
640 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
641 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
642 check_sp_type(dev
[0], "roaming")
644 dev
[0].request("SET external_sim 0")
646 def test_ap_hs20_username(dev
, apdev
):
647 """Hotspot 2.0 connection in username/password credential"""
648 check_eap_capa(dev
[0], "MSCHAPV2")
649 bssid
= apdev
[0]['bssid']
650 params
= hs20_ap_params()
651 params
['hessid'] = bssid
652 params
['disable_dgaf'] = '1'
653 hostapd
.add_ap(apdev
[0], params
)
656 id = dev
[0].add_cred_values({'realm': "example.com",
657 'username': "hs20-test",
658 'password': "password",
659 'ca_cert': "auth_serv/ca.pem",
660 'domain': "example.com",
661 'update_identifier': "1234"})
662 interworking_select(dev
[0], bssid
, "home", freq
="2412")
663 interworking_connect(dev
[0], bssid
, "TTLS")
664 check_sp_type(dev
[0], "home")
665 status
= dev
[0].get_status()
666 if status
['pairwise_cipher'] != "CCMP":
667 raise Exception("Unexpected pairwise cipher")
668 if status
['hs20'] != "3":
669 raise Exception("Unexpected HS 2.0 support indication")
671 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
672 identity
="hs20-test", password
="password",
673 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
676 def test_ap_hs20_connect_api(dev
, apdev
):
677 """Hotspot 2.0 connection with connect API"""
678 check_eap_capa(dev
[0], "MSCHAPV2")
679 bssid
= apdev
[0]['bssid']
680 params
= hs20_ap_params()
681 params
['hessid'] = bssid
682 params
['disable_dgaf'] = '1'
683 hostapd
.add_ap(apdev
[0], params
)
685 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
686 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
688 wpas
.flush_scan_cache()
689 id = wpas
.add_cred_values({'realm': "example.com",
690 'username': "hs20-test",
691 'password': "password",
692 'ca_cert': "auth_serv/ca.pem",
693 'domain': "example.com",
694 'update_identifier': "1234"})
695 interworking_select(wpas
, bssid
, "home", freq
="2412")
696 interworking_connect(wpas
, bssid
, "TTLS")
697 check_sp_type(wpas
, "home")
698 status
= wpas
.get_status()
699 if status
['pairwise_cipher'] != "CCMP":
700 raise Exception("Unexpected pairwise cipher")
701 if status
['hs20'] != "3":
702 raise Exception("Unexpected HS 2.0 support indication")
704 def test_ap_hs20_auto_interworking(dev
, apdev
):
705 """Hotspot 2.0 connection with auto_interworking=1"""
706 check_eap_capa(dev
[0], "MSCHAPV2")
707 bssid
= apdev
[0]['bssid']
708 params
= hs20_ap_params()
709 params
['hessid'] = bssid
710 params
['disable_dgaf'] = '1'
711 hostapd
.add_ap(apdev
[0], params
)
713 dev
[0].hs20_enable(auto_interworking
=True)
714 id = dev
[0].add_cred_values({'realm': "example.com",
715 'username': "hs20-test",
716 'password': "password",
717 'ca_cert': "auth_serv/ca.pem",
718 'domain': "example.com",
719 'update_identifier': "1234"})
720 dev
[0].request("REASSOCIATE")
721 dev
[0].wait_connected(timeout
=15)
722 check_sp_type(dev
[0], "home")
723 status
= dev
[0].get_status()
724 if status
['pairwise_cipher'] != "CCMP":
725 raise Exception("Unexpected pairwise cipher")
726 if status
['hs20'] != "3":
727 raise Exception("Unexpected HS 2.0 support indication")
730 def test_ap_hs20_auto_interworking_no_match(dev
, apdev
):
731 """Hotspot 2.0 connection with auto_interworking=1 and no matching network"""
732 hapd
= hostapd
.add_ap(apdev
[0], {"ssid": "mismatch"})
734 dev
[0].hs20_enable(auto_interworking
=True)
735 id = dev
[0].connect("mismatch", psk
="12345678", scan_freq
="2412",
736 only_add_network
=True)
737 dev
[0].request("ENABLE_NETWORK " + str(id) + " no-connect")
739 id = dev
[0].add_cred_values({'realm': "example.com",
740 'username': "hs20-test",
741 'password': "password",
742 'ca_cert': "auth_serv/ca.pem",
743 'domain': "example.com",
744 'update_identifier': "1234"})
745 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
747 dev
[0].dump_monitor()
749 logger
.info("start ping")
750 if "PONG" not in dev
[0].ctrl
.request("PING", timeout
=2):
751 raise Exception("PING failed")
752 logger
.info("ping done")
756 ev
= dev
[0].wait_event(["ANQP fetch completed",
757 "CTRL-EVENT-SCAN-RESULTS"], timeout
=0.05)
760 if "ANQP fetch completed" in ev
:
764 if fetch
> 2 * scan
+ 3:
765 raise Exception("Too many ANQP fetch iterations")
766 dev
[0].dump_monitor()
767 dev
[0].request("DISCONNECT")
770 def test_ap_hs20_auto_interworking_no_cred_match(dev
, apdev
):
771 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
772 bssid
= apdev
[0]['bssid']
773 params
= {"ssid": "test"}
774 hostapd
.add_ap(apdev
[0], params
)
776 dev
[0].hs20_enable(auto_interworking
=True)
777 dev
[0].add_cred_values({'realm': "example.com",
778 'username': "hs20-test",
779 'password': "password",
780 'ca_cert': "auth_serv/ca.pem",
781 'domain': "example.com"})
783 id = dev
[0].connect("test", psk
="12345678", only_add_network
=True)
784 dev
[0].request("ENABLE_NETWORK %s" % id)
785 logger
.info("Verify that scanning continues when there is partial network block match")
786 for i
in range(0, 2):
787 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
789 raise Exception("Scan timed out")
790 logger
.info("Scan completed")
792 def eap_test(dev
, ap
, eap_params
, method
, user
, release
=0):
794 params
= hs20_ap_params()
795 params
['nai_realm'] = ["0,example.com," + eap_params
]
797 params
['hs20_release'] = str(release
)
798 hapd
= hostapd
.add_ap(ap
, params
)
801 dev
.add_cred_values({'realm': "example.com",
802 'ca_cert': "auth_serv/ca.pem",
804 'password': "password"})
805 interworking_select(dev
, bssid
, freq
="2412")
806 interworking_connect(dev
, bssid
, method
)
810 def test_ap_hs20_eap_unknown(dev
, apdev
):
811 """Hotspot 2.0 connection with unknown EAP method"""
812 bssid
= apdev
[0]['bssid']
813 params
= hs20_ap_params()
814 params
['nai_realm'] = "0,example.com,99"
815 hostapd
.add_ap(apdev
[0], params
)
818 dev
[0].add_cred_values(default_cred())
819 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
821 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
822 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
823 check_eap_capa(dev
[0], "MSCHAPV2")
824 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
826 def test_ap_hs20_eap_peap_default(dev
, apdev
):
827 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
828 check_eap_capa(dev
[0], "MSCHAPV2")
829 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
831 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
832 """Hotspot 2.0 connection with PEAP/GTC"""
833 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
836 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
837 """Hotspot 2.0 connection with PEAP/unknown"""
838 bssid
= apdev
[0]['bssid']
839 params
= hs20_ap_params()
840 params
['nai_realm'] = "0,example.com,25[3:99]"
841 hostapd
.add_ap(apdev
[0], params
)
844 dev
[0].add_cred_values(default_cred())
845 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
847 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
848 """Hotspot 2.0 connection with TTLS/CHAP"""
849 skip_with_fips(dev
[0])
850 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
852 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
853 """Hotspot 2.0 connection with TTLS/MSCHAP"""
854 skip_with_fips(dev
[0])
855 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
857 def test_ap_hs20_eap_ttls_default(dev
, apdev
):
858 """Hotspot 2.0 connection with TTLS/default"""
859 skip_with_fips(dev
[0])
860 eap_test(dev
[0], apdev
[0], "21", "TTLS", "hs20-test")
862 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
863 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
864 check_eap_capa(dev
[0], "MSCHAPV2")
865 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
868 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
869 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
870 bssid
= apdev
[0]['bssid']
871 params
= hs20_ap_params()
872 params
['nai_realm'] = "0,example.com,21[3:99]"
873 hostapd
.add_ap(apdev
[0], params
)
876 dev
[0].add_cred_values(default_cred())
877 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
880 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
881 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
882 bssid
= apdev
[0]['bssid']
883 params
= hs20_ap_params()
884 params
['nai_realm'] = "0,example.com,21[3:5]"
885 hostapd
.add_ap(apdev
[0], params
)
888 dev
[0].add_cred_values(default_cred())
889 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
892 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
893 """Hotspot 2.0 connection with TTLS/unknown"""
894 bssid
= apdev
[0]['bssid']
895 params
= hs20_ap_params()
896 params
['nai_realm'] = "0,example.com,21[2:5]"
897 hostapd
.add_ap(apdev
[0], params
)
900 dev
[0].add_cred_values(default_cred())
901 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
903 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
904 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
905 check_eap_capa(dev
[0], "FAST")
906 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
908 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
909 """Hotspot 2.0 connection with FAST/EAP-GTC"""
910 check_eap_capa(dev
[0], "FAST")
911 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
913 def test_ap_hs20_eap_tls(dev
, apdev
):
914 """Hotspot 2.0 connection with EAP-TLS"""
915 bssid
= apdev
[0]['bssid']
916 params
= hs20_ap_params()
917 params
['nai_realm'] = ["0,example.com,13[5:6]"]
918 hostapd
.add_ap(apdev
[0], params
)
921 dev
[0].add_cred_values({'realm': "example.com",
922 'username': "certificate-user",
923 'ca_cert': "auth_serv/ca.pem",
924 'client_cert': "auth_serv/user.pem",
925 'private_key': "auth_serv/user.key"})
926 interworking_select(dev
[0], bssid
, freq
="2412")
927 interworking_connect(dev
[0], bssid
, "TLS")
930 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
931 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
932 bssid
= apdev
[0]['bssid']
933 params
= hs20_ap_params()
934 params
['nai_realm'] = ["0,example.com,99[5:6]"]
935 hostapd
.add_ap(apdev
[0], params
)
938 dev
[0].add_cred_values({'realm': "example.com",
939 'username': "certificate-user",
940 'ca_cert': "auth_serv/ca.pem",
941 'client_cert': "auth_serv/user.pem",
942 'private_key': "auth_serv/user.key"})
943 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
946 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
947 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
948 bssid
= apdev
[0]['bssid']
949 params
= hs20_ap_params()
950 params
['nai_realm'] = ["0,example.com,21[5:6]"]
951 hostapd
.add_ap(apdev
[0], params
)
954 dev
[0].add_cred_values({'realm': "example.com",
955 'username': "certificate-user",
956 'ca_cert': "auth_serv/ca.pem",
957 'client_cert': "auth_serv/user.pem",
958 'private_key': "auth_serv/user.key"})
959 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
962 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
963 """Hotspot 2.0 connection with invalid cred configuration"""
964 bssid
= apdev
[0]['bssid']
965 params
= hs20_ap_params()
966 hostapd
.add_ap(apdev
[0], params
)
969 dev
[0].add_cred_values({'realm': "example.com",
970 'username': "certificate-user",
971 'client_cert': "auth_serv/user.pem"})
972 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
974 def test_ap_hs20_nai_realms(dev
, apdev
):
975 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
976 bssid
= apdev
[0]['bssid']
977 params
= hs20_ap_params()
978 params
['hessid'] = bssid
979 params
['nai_realm'] = ["0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]"]
980 hostapd
.add_ap(apdev
[0], params
)
983 id = dev
[0].add_cred_values({'realm': "example.com",
984 'ca_cert': "auth_serv/ca.pem",
985 'username': "pap user",
986 'password': "password",
987 'domain': "example.com"})
988 interworking_select(dev
[0], bssid
, "home", freq
="2412")
989 interworking_connect(dev
[0], bssid
, "TTLS")
990 check_sp_type(dev
[0], "home")
992 def test_ap_hs20_roaming_consortium(dev
, apdev
):
993 """Hotspot 2.0 connection based on roaming consortium match"""
994 bssid
= apdev
[0]['bssid']
995 params
= hs20_ap_params()
996 params
['hessid'] = bssid
997 hostapd
.add_ap(apdev
[0], params
)
1000 for consortium
in ["112233", "1020304050", "010203040506", "fedcba"]:
1001 id = dev
[0].add_cred_values({'username': "user",
1002 'password': "password",
1003 'domain': "example.com",
1004 'ca_cert': "auth_serv/ca.pem",
1005 'roaming_consortium': consortium
,
1007 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1008 interworking_connect(dev
[0], bssid
, "PEAP")
1009 check_sp_type(dev
[0], "home")
1010 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1011 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
1013 raise Exception("Timeout on already-connected event")
1014 dev
[0].remove_cred(id)
1016 def test_ap_hs20_roaming_consortiums_match(dev
, apdev
):
1017 """Hotspot 2.0 connection based on roaming_consortiums match"""
1018 bssid
= apdev
[0]['bssid']
1019 params
= hs20_ap_params()
1020 params
['hessid'] = bssid
1021 hostapd
.add_ap(apdev
[0], params
)
1023 dev
[0].hs20_enable()
1024 tests
= [("112233", "112233"),
1025 ("ffffff,1020304050,eeeeee", "1020304050")]
1026 for consortium
, selected
in tests
:
1027 id = dev
[0].add_cred_values({'username': "user",
1028 'password': "password",
1029 'domain': "my.home.example.com",
1030 'ca_cert': "auth_serv/ca.pem",
1031 'roaming_consortiums': consortium
,
1033 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1034 interworking_connect(dev
[0], bssid
, "PEAP")
1035 check_sp_type(dev
[0], "roaming")
1036 network_id
= dev
[0].get_status_field("id")
1037 sel
= dev
[0].get_network(network_id
, "roaming_consortium_selection")
1039 raise Exception("Unexpected roaming_consortium_selection value: " +
1041 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1042 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
1044 raise Exception("Timeout on already-connected event")
1045 dev
[0].remove_cred(id)
1047 def test_ap_hs20_max_roaming_consortiums(dev
, apdev
):
1048 """Maximum number of cred roaming_consortiums"""
1049 id = dev
[0].add_cred()
1050 consortium
= (36*",ffffff")[1:]
1051 if "OK" not in dev
[0].request('SET_CRED %d roaming_consortiums "%s"' % (id, consortium
)):
1052 raise Exception("Maximum number of consortium OIs rejected")
1053 consortium
= (37*",ffffff")[1:]
1054 if "FAIL" not in dev
[0].request('SET_CRED %d roaming_consortiums "%s"' % (id, consortium
)):
1055 raise Exception("Over maximum number of consortium OIs accepted")
1056 dev
[0].remove_cred(id)
1058 def test_ap_hs20_roaming_consortium_invalid(dev
, apdev
):
1059 """Hotspot 2.0 connection and invalid roaming consortium ANQP-element"""
1060 bssid
= apdev
[0]['bssid']
1061 params
= hs20_ap_params()
1062 params
['hessid'] = bssid
1063 # Override Roaming Consortium ANQP-element with an incorrectly encoded
1065 params
['anqp_elem'] = "261:04fedcba"
1066 hostapd
.add_ap(apdev
[0], params
)
1068 dev
[0].hs20_enable()
1069 id = dev
[0].add_cred_values({'username': "user",
1070 'password': "password",
1071 'domain': "example.com",
1072 'ca_cert': "auth_serv/ca.pem",
1073 'roaming_consortium': "fedcba",
1075 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1077 def test_ap_hs20_roaming_consortium_element(dev
, apdev
):
1078 """Hotspot 2.0 connection and invalid roaming consortium element"""
1079 bssid
= apdev
[0]['bssid']
1080 params
= hs20_ap_params()
1081 params
['hessid'] = bssid
1082 del params
['roaming_consortium']
1083 params
['vendor_elements'] = '6f00'
1084 hapd
= hostapd
.add_ap(apdev
[0], params
)
1086 dev
[0].hs20_enable()
1087 dev
[0].scan_for_bss(bssid
, freq
="2412")
1088 id = dev
[0].add_cred_values({'username': "user",
1089 'password': "password",
1090 'domain': "example.com",
1091 'ca_cert': "auth_serv/ca.pem",
1092 'roaming_consortium': "112233",
1094 interworking_select(dev
[0], bssid
, freq
="2412", no_match
=True)
1096 hapd
.set('vendor_elements', '6f020001')
1097 if "OK" not in hapd
.request("UPDATE_BEACON"):
1098 raise Exception("UPDATE_BEACON failed")
1099 dev
[0].request("BSS_FLUSH 0")
1100 dev
[0].scan_for_bss(bssid
, freq
="2412", force_scan
=True)
1101 interworking_select(dev
[0], bssid
, freq
="2412", no_match
=True)
1103 def test_ap_hs20_roaming_consortium_constraints(dev
, apdev
):
1104 """Hotspot 2.0 connection and roaming consortium constraints"""
1105 bssid
= apdev
[0]['bssid']
1106 params
= hs20_ap_params()
1107 params
['hessid'] = bssid
1108 params
['bss_load_test'] = "12:200:20000"
1109 hostapd
.add_ap(apdev
[0], params
)
1111 dev
[0].hs20_enable()
1113 vals
= {'username': "user",
1114 'password': "password",
1115 'domain': "example.com",
1116 'ca_cert': "auth_serv/ca.pem",
1117 'roaming_consortium': "fedcba",
1120 vals2
['required_roaming_consortium'] = "223344"
1121 id = dev
[0].add_cred_values(vals2
)
1122 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1123 dev
[0].remove_cred(id)
1126 vals2
['min_dl_bandwidth_home'] = "65500"
1127 id = dev
[0].add_cred_values(vals2
)
1128 dev
[0].request("INTERWORKING_SELECT freq=2412")
1129 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1131 raise Exception("No AP found")
1132 if "below_min_backhaul=1" not in ev
:
1133 raise Exception("below_min_backhaul not reported")
1134 dev
[0].remove_cred(id)
1137 vals2
['max_bss_load'] = "100"
1138 id = dev
[0].add_cred_values(vals2
)
1139 dev
[0].request("INTERWORKING_SELECT freq=2412")
1140 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1142 raise Exception("No AP found")
1143 if "over_max_bss_load=1" not in ev
:
1144 raise Exception("over_max_bss_load not reported")
1145 dev
[0].remove_cred(id)
1148 vals2
['req_conn_capab'] = "6:1234"
1149 vals2
['domain'] = 'example.org'
1150 id = dev
[0].add_cred_values(vals2
)
1152 dev
[0].request("INTERWORKING_SELECT freq=2412")
1153 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1155 raise Exception("No AP found")
1156 if "conn_capab_missing=1" not in ev
:
1157 raise Exception("conn_capab_missing not reported")
1158 dev
[0].remove_cred(id)
1160 values
= default_cred()
1161 values
['roaming_consortium'] = "fedcba"
1162 id3
= dev
[0].add_cred_values(values
)
1165 vals2
['roaming_consortium'] = "fedcba"
1166 vals2
['priority'] = "2"
1167 id = dev
[0].add_cred_values(vals2
)
1169 values
= default_cred()
1170 values
['roaming_consortium'] = "fedcba"
1171 id2
= dev
[0].add_cred_values(values
)
1173 dev
[0].request("INTERWORKING_SELECT freq=2412")
1174 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1176 raise Exception("No AP found")
1177 dev
[0].remove_cred(id)
1178 dev
[0].remove_cred(id2
)
1179 dev
[0].remove_cred(id3
)
1181 def test_ap_hs20_3gpp_constraints(dev
, apdev
):
1182 """Hotspot 2.0 connection and 3GPP credential constraints"""
1183 bssid
= apdev
[0]['bssid']
1184 params
= hs20_ap_params()
1185 params
['hessid'] = bssid
1186 params
['anqp_3gpp_cell_net'] = "555,444"
1187 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1188 params
['bss_load_test'] = "12:200:20000"
1189 hapd
= hostapd
.add_ap(apdev
[0], params
)
1191 dev
[0].hs20_enable()
1193 vals
= {'imsi': "555444-333222111",
1195 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"}
1197 vals2
['required_roaming_consortium'] = "223344"
1198 id = dev
[0].add_cred_values(vals2
)
1199 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1200 dev
[0].remove_cred(id)
1203 vals2
['min_dl_bandwidth_home'] = "65500"
1204 id = dev
[0].add_cred_values(vals2
)
1205 dev
[0].request("INTERWORKING_SELECT freq=2412")
1206 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1208 raise Exception("No AP found")
1209 if "below_min_backhaul=1" not in ev
:
1210 raise Exception("below_min_backhaul not reported")
1211 dev
[0].remove_cred(id)
1214 vals2
['max_bss_load'] = "100"
1215 id = dev
[0].add_cred_values(vals2
)
1216 dev
[0].request("INTERWORKING_SELECT freq=2412")
1217 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1219 raise Exception("No AP found")
1220 if "over_max_bss_load=1" not in ev
:
1221 raise Exception("over_max_bss_load not reported")
1222 dev
[0].remove_cred(id)
1224 values
= default_cred()
1225 values
['roaming_consortium'] = "fedcba"
1226 id3
= dev
[0].add_cred_values(values
)
1229 vals2
['roaming_consortium'] = "fedcba"
1230 vals2
['priority'] = "2"
1231 id = dev
[0].add_cred_values(vals2
)
1233 values
= default_cred()
1234 values
['roaming_consortium'] = "fedcba"
1235 id2
= dev
[0].add_cred_values(values
)
1237 dev
[0].request("INTERWORKING_SELECT freq=2412")
1238 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1240 raise Exception("No AP found")
1241 dev
[0].remove_cred(id)
1242 dev
[0].remove_cred(id2
)
1243 dev
[0].remove_cred(id3
)
1246 params
= hs20_ap_params()
1247 params
['hessid'] = bssid
1248 params
['anqp_3gpp_cell_net'] = "555,444"
1249 params
['bss_load_test'] = "12:200:20000"
1250 hapd
= hostapd
.add_ap(apdev
[0], params
)
1252 vals2
['req_conn_capab'] = "6:1234"
1253 id = dev
[0].add_cred_values(vals2
)
1254 dev
[0].request("INTERWORKING_SELECT freq=2412")
1255 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1257 raise Exception("No AP found")
1258 if "conn_capab_missing=1" not in ev
:
1259 raise Exception("conn_capab_missing not reported")
1260 dev
[0].remove_cred(id)
1262 def test_ap_hs20_connect_no_full_match(dev
, apdev
):
1263 """Hotspot 2.0 connection and no full match"""
1264 bssid
= apdev
[0]['bssid']
1265 params
= hs20_ap_params()
1266 params
['hessid'] = bssid
1267 params
['anqp_3gpp_cell_net'] = "555,444"
1268 hostapd
.add_ap(apdev
[0], params
)
1270 dev
[0].hs20_enable()
1272 vals
= {'username': "user",
1273 'password': "password",
1274 'domain': "example.com",
1275 'ca_cert': "auth_serv/ca.pem",
1276 'roaming_consortium': "fedcba",
1278 'min_dl_bandwidth_home': "65500"}
1279 id = dev
[0].add_cred_values(vals
)
1280 dev
[0].request("INTERWORKING_SELECT freq=2412")
1281 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1283 raise Exception("No AP found")
1284 if "below_min_backhaul=1" not in ev
:
1285 raise Exception("below_min_backhaul not reported")
1286 interworking_connect(dev
[0], bssid
, "TTLS")
1287 dev
[0].remove_cred(id)
1288 dev
[0].wait_disconnected()
1290 vals
= {'imsi': "555444-333222111", 'eap': "SIM",
1291 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1292 'min_dl_bandwidth_roaming': "65500"}
1293 id = dev
[0].add_cred_values(vals
)
1294 dev
[0].request("INTERWORKING_SELECT freq=2412")
1295 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1297 raise Exception("No AP found")
1298 if "below_min_backhaul=1" not in ev
:
1299 raise Exception("below_min_backhaul not reported")
1300 interworking_connect(dev
[0], bssid
, "SIM")
1301 dev
[0].remove_cred(id)
1302 dev
[0].wait_disconnected()
1304 def test_ap_hs20_username_roaming(dev
, apdev
):
1305 """Hotspot 2.0 connection in username/password credential (roaming)"""
1306 check_eap_capa(dev
[0], "MSCHAPV2")
1307 bssid
= apdev
[0]['bssid']
1308 params
= hs20_ap_params()
1309 params
['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]",
1310 "0,roaming.example.com,21[2:4][5:7]",
1311 "0,another.example.com"]
1312 params
['domain_name'] = "another.example.com"
1313 params
['hessid'] = bssid
1314 hostapd
.add_ap(apdev
[0], params
)
1316 dev
[0].hs20_enable()
1317 id = dev
[0].add_cred_values({'realm': "roaming.example.com",
1318 'username': "hs20-test",
1319 'password': "password",
1320 'ca_cert': "auth_serv/ca.pem",
1321 'domain': "example.com"})
1322 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1323 interworking_connect(dev
[0], bssid
, "TTLS")
1324 check_sp_type(dev
[0], "roaming")
1326 def test_ap_hs20_username_unknown(dev
, apdev
):
1327 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
1328 check_eap_capa(dev
[0], "MSCHAPV2")
1329 bssid
= apdev
[0]['bssid']
1330 params
= hs20_ap_params()
1331 params
['hessid'] = bssid
1332 hostapd
.add_ap(apdev
[0], params
)
1334 dev
[0].hs20_enable()
1335 id = dev
[0].add_cred_values({'realm': "example.com",
1336 'ca_cert': "auth_serv/ca.pem",
1337 'username': "hs20-test",
1338 'password': "password"})
1339 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
1340 interworking_connect(dev
[0], bssid
, "TTLS")
1341 check_sp_type(dev
[0], "unknown")
1343 def test_ap_hs20_username_unknown2(dev
, apdev
):
1344 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
1345 check_eap_capa(dev
[0], "MSCHAPV2")
1346 bssid
= apdev
[0]['bssid']
1347 params
= hs20_ap_params()
1348 params
['hessid'] = bssid
1349 del params
['domain_name']
1350 hostapd
.add_ap(apdev
[0], params
)
1352 dev
[0].hs20_enable()
1353 id = dev
[0].add_cred_values({'realm': "example.com",
1354 'ca_cert': "auth_serv/ca.pem",
1355 'username': "hs20-test",
1356 'password': "password",
1357 'domain': "example.com"})
1358 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
1359 interworking_connect(dev
[0], bssid
, "TTLS")
1360 check_sp_type(dev
[0], "unknown")
1362 def test_ap_hs20_gas_while_associated(dev
, apdev
):
1363 """Hotspot 2.0 connection with GAS query while associated"""
1364 check_eap_capa(dev
[0], "MSCHAPV2")
1365 bssid
= apdev
[0]['bssid']
1366 params
= hs20_ap_params()
1367 params
['hessid'] = bssid
1368 hostapd
.add_ap(apdev
[0], params
)
1370 dev
[0].hs20_enable()
1371 id = dev
[0].add_cred_values({'realm': "example.com",
1372 'ca_cert': "auth_serv/ca.pem",
1373 'username': "hs20-test",
1374 'password': "password",
1375 'domain': "example.com"})
1376 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1377 interworking_connect(dev
[0], bssid
, "TTLS")
1379 logger
.info("Verifying GAS query while associated")
1380 dev
[0].request("FETCH_ANQP")
1381 for i
in range(0, 6):
1382 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1384 raise Exception("Operation timed out")
1386 def test_ap_hs20_gas_with_another_ap_while_associated(dev
, apdev
):
1387 """GAS query with another AP while associated"""
1388 check_eap_capa(dev
[0], "MSCHAPV2")
1389 bssid
= apdev
[0]['bssid']
1390 params
= hs20_ap_params()
1391 params
['hessid'] = bssid
1392 hostapd
.add_ap(apdev
[0], params
)
1394 bssid2
= apdev
[1]['bssid']
1395 params
= hs20_ap_params()
1396 params
['hessid'] = bssid2
1397 params
['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"]
1398 hostapd
.add_ap(apdev
[1], params
)
1400 dev
[0].hs20_enable()
1401 id = dev
[0].add_cred_values({'realm': "example.com",
1402 'ca_cert': "auth_serv/ca.pem",
1403 'username': "hs20-test",
1404 'password': "password",
1405 'domain': "example.com"})
1406 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1407 interworking_connect(dev
[0], bssid
, "TTLS")
1408 dev
[0].dump_monitor()
1410 logger
.info("Verifying GAS query with same AP while associated")
1411 dev
[0].request("ANQP_GET " + bssid
+ " 263")
1412 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1414 raise Exception("ANQP operation timed out")
1415 dev
[0].dump_monitor()
1417 logger
.info("Verifying GAS query with another AP while associated")
1418 dev
[0].scan_for_bss(bssid2
, 2412)
1419 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
1420 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1422 raise Exception("ANQP operation timed out")
1424 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
1425 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
1426 check_eap_capa(dev
[0], "MSCHAPV2")
1428 _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
)
1430 dev
[0].request("SET pmf 0")
1432 def _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
1433 bssid
= apdev
[0]['bssid']
1434 params
= hs20_ap_params()
1435 params
['hessid'] = bssid
1436 hostapd
.add_ap(apdev
[0], params
)
1438 bssid2
= apdev
[1]['bssid']
1439 params
= hs20_ap_params()
1440 params
['hessid'] = bssid2
1441 params
['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"]
1442 hostapd
.add_ap(apdev
[1], params
)
1444 dev
[0].hs20_enable()
1445 dev
[0].request("SET pmf 2")
1446 id = dev
[0].add_cred_values({'realm': "example.com",
1447 'ca_cert': "auth_serv/ca.pem",
1448 'username': "hs20-test",
1449 'password': "password",
1450 'domain': "example.com"})
1451 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1452 interworking_connect(dev
[0], bssid
, "TTLS")
1454 logger
.info("Verifying GAS query while associated")
1455 dev
[0].request("FETCH_ANQP")
1456 for i
in range(0, 2 * 6):
1457 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1459 raise Exception("Operation timed out")
1461 def test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1462 """GAS query with another AP while associated and using PMF"""
1463 check_eap_capa(dev
[0], "MSCHAPV2")
1465 _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
)
1467 dev
[0].request("SET pmf 0")
1469 def _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1470 bssid
= apdev
[0]['bssid']
1471 params
= hs20_ap_params()
1472 params
['hessid'] = bssid
1473 hapd
= hostapd
.add_ap(apdev
[0], params
)
1475 bssid2
= apdev
[1]['bssid']
1476 params
= hs20_ap_params()
1477 params
['hessid'] = bssid2
1478 params
['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"]
1479 hostapd
.add_ap(apdev
[1], params
)
1481 dev
[0].hs20_enable()
1482 dev
[0].request("SET pmf 2")
1483 id = dev
[0].add_cred_values({'realm': "example.com",
1484 'ca_cert': "auth_serv/ca.pem",
1485 'username': "hs20-test",
1486 'password': "password",
1487 'domain': "example.com"})
1488 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1489 interworking_connect(dev
[0], bssid
, "TTLS")
1490 dev
[0].dump_monitor()
1493 logger
.info("Verifying GAS query with same AP while associated")
1494 dev
[0].request("ANQP_GET " + bssid
+ " 263")
1495 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1497 raise Exception("ANQP operation timed out")
1498 dev
[0].dump_monitor()
1500 logger
.info("Verifying GAS query with another AP while associated")
1501 dev
[0].scan_for_bss(bssid2
, 2412)
1502 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
1503 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1505 raise Exception("ANQP operation timed out")
1507 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
1508 """Hotspot 2.0 connection with fragmented GAS query while associated"""
1509 check_eap_capa(dev
[0], "MSCHAPV2")
1510 bssid
= apdev
[0]['bssid']
1511 params
= hs20_ap_params()
1512 params
['hessid'] = bssid
1513 hapd
= hostapd
.add_ap(apdev
[0], params
)
1514 hapd
.set("gas_frag_limit", "50")
1516 dev
[0].hs20_enable()
1517 id = dev
[0].add_cred_values({'realm': "example.com",
1518 'ca_cert': "auth_serv/ca.pem",
1519 'username': "hs20-test",
1520 'password': "password",
1521 'domain': "example.com"})
1522 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1523 interworking_connect(dev
[0], bssid
, "TTLS")
1526 logger
.info("Verifying GAS query while associated")
1527 dev
[0].request("FETCH_ANQP")
1528 for i
in range(0, 6):
1529 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1531 raise Exception("Operation timed out")
1533 def test_ap_hs20_multiple_connects(dev
, apdev
):
1534 """Hotspot 2.0 connection through multiple network selections"""
1535 check_eap_capa(dev
[0], "MSCHAPV2")
1536 bssid
= apdev
[0]['bssid']
1537 params
= hs20_ap_params()
1538 params
['hessid'] = bssid
1539 hostapd
.add_ap(apdev
[0], params
)
1541 dev
[0].hs20_enable()
1542 values
= {'realm': "example.com",
1543 'ca_cert': "auth_serv/ca.pem",
1544 'username': "hs20-test",
1545 'password': "password",
1546 'domain': "example.com"}
1547 id = dev
[0].add_cred_values(values
)
1549 dev
[0].scan_for_bss(bssid
, freq
="2412")
1551 for i
in range(0, 3):
1552 logger
.info("Starting Interworking network selection")
1553 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1555 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1556 "INTERWORKING-ALREADY-CONNECTED",
1557 "CTRL-EVENT-CONNECTED"], timeout
=15)
1559 raise Exception("Connection timed out")
1560 if "INTERWORKING-NO-MATCH" in ev
:
1561 raise Exception("Matching AP not found")
1562 if "CTRL-EVENT-CONNECTED" in ev
:
1564 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
1567 dev
[0].request("DISCONNECT")
1568 dev
[0].dump_monitor()
1570 networks
= dev
[0].list_networks()
1571 if len(networks
) > 1:
1572 raise Exception("Duplicated network block detected")
1574 def test_ap_hs20_disallow_aps(dev
, apdev
):
1575 """Hotspot 2.0 connection and disallow_aps"""
1576 bssid
= apdev
[0]['bssid']
1577 params
= hs20_ap_params()
1578 params
['hessid'] = bssid
1579 hostapd
.add_ap(apdev
[0], params
)
1581 dev
[0].hs20_enable()
1582 values
= {'realm': "example.com",
1583 'ca_cert': "auth_serv/ca.pem",
1584 'username': "hs20-test",
1585 'password': "password",
1586 'domain': "example.com"}
1587 id = dev
[0].add_cred_values(values
)
1589 dev
[0].scan_for_bss(bssid
, freq
="2412")
1591 logger
.info("Verify disallow_aps bssid")
1592 dev
[0].request("SET disallow_aps bssid " + bssid
.replace(':', ''))
1593 dev
[0].request("INTERWORKING_SELECT auto")
1594 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1596 raise Exception("Network selection timed out")
1597 dev
[0].dump_monitor()
1599 logger
.info("Verify disallow_aps ssid")
1600 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
1601 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1602 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1604 raise Exception("Network selection timed out")
1605 dev
[0].dump_monitor()
1607 logger
.info("Verify disallow_aps clear")
1608 dev
[0].request("SET disallow_aps ")
1609 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1611 dev
[0].request("SET disallow_aps bssid " + bssid
.replace(':', ''))
1612 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1613 if "FAIL" not in ret
:
1614 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
1616 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
1617 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1618 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
1619 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1621 def policy_test(dev
, ap
, values
, only_one
=True):
1624 logger
.info("Verify network selection to AP " + ap
['ifname'])
1626 dev
.scan_for_bss(bssid
, freq
="2412")
1628 logger
.info("Verify network selection")
1631 id = dev
.add_cred_values(values
)
1632 dev
.request("INTERWORKING_SELECT auto freq=2412")
1635 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1636 "INTERWORKING-BLACKLISTED",
1637 "INTERWORKING-SELECTED"], timeout
=15)
1639 raise Exception("Network selection timed out")
1641 if "INTERWORKING-NO-MATCH" in ev
:
1642 raise Exception("Matching AP not found")
1643 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1644 raise Exception("Unexpected AP claimed acceptable")
1645 if "INTERWORKING-SELECTED" in ev
:
1646 if bssid
and bssid
not in ev
:
1647 raise Exception("Selected incorrect BSS")
1650 ev
= dev
.wait_connected(timeout
=15)
1651 if bssid
and bssid
not in ev
:
1652 raise Exception("Connected to incorrect BSS")
1654 conn_bssid
= dev
.get_status_field("bssid")
1655 if bssid
and conn_bssid
!= bssid
:
1656 raise Exception("bssid information points to incorrect BSS")
1662 def default_cred(domain
=None, user
="hs20-test"):
1663 cred
= {'realm': "example.com",
1664 'ca_cert': "auth_serv/ca.pem",
1666 'password': "password"}
1668 cred
['domain'] = domain
1671 def test_ap_hs20_prefer_home(dev
, apdev
):
1672 """Hotspot 2.0 required roaming consortium"""
1673 check_eap_capa(dev
[0], "MSCHAPV2")
1674 params
= hs20_ap_params()
1675 params
['domain_name'] = "example.org"
1676 hostapd
.add_ap(apdev
[0], params
)
1678 params
= hs20_ap_params()
1679 params
['ssid'] = "test-hs20-other"
1680 params
['domain_name'] = "example.com"
1681 hostapd
.add_ap(apdev
[1], params
)
1683 values
= default_cred()
1684 values
['domain'] = "example.com"
1685 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1686 values
['domain'] = "example.org"
1687 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1689 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1690 """Hotspot 2.0 required roaming consortium"""
1691 check_eap_capa(dev
[0], "MSCHAPV2")
1692 params
= hs20_ap_params()
1693 hostapd
.add_ap(apdev
[0], params
)
1695 params
= hs20_ap_params()
1696 params
['ssid'] = "test-hs20-other"
1697 params
['roaming_consortium'] = ["223344"]
1698 hostapd
.add_ap(apdev
[1], params
)
1700 values
= default_cred()
1701 values
['required_roaming_consortium'] = "223344"
1702 policy_test(dev
[0], apdev
[1], values
)
1703 values
['required_roaming_consortium'] = "112233"
1704 policy_test(dev
[0], apdev
[0], values
)
1706 id = dev
[0].add_cred()
1707 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1708 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1710 for val
in ["", "1", "11", "1122", "1122334",
1711 "112233445566778899aabbccddeeff00"]:
1712 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1713 raise Exception("Invalid roaming consortium value accepted: " + val
)
1715 def test_ap_hs20_req_roaming_consortium_no_match(dev
, apdev
):
1716 """Hotspot 2.0 required roaming consortium and no match"""
1717 check_eap_capa(dev
[0], "MSCHAPV2")
1718 params
= hs20_ap_params()
1719 del params
['roaming_consortium']
1720 hostapd
.add_ap(apdev
[0], params
)
1722 params
= hs20_ap_params()
1723 params
['ssid'] = "test-hs20-other"
1724 params
['roaming_consortium'] = ["223345"]
1725 hostapd
.add_ap(apdev
[1], params
)
1727 values
= default_cred()
1728 values
['required_roaming_consortium'] = "223344"
1729 dev
[0].hs20_enable()
1730 id = dev
[0].add_cred_values(values
)
1731 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1732 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=10)
1734 raise Exception("INTERWORKING-NO-MATCH not reported")
1736 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1737 """Hotspot 2.0 exclusion based on SSID"""
1738 check_eap_capa(dev
[0], "MSCHAPV2")
1739 params
= hs20_ap_params()
1740 params
['roaming_consortium'] = ["223344"]
1741 params
['anqp_3gpp_cell_net'] = "555,444"
1742 hostapd
.add_ap(apdev
[0], params
)
1744 params
= hs20_ap_params()
1745 params
['ssid'] = "test-hs20-other"
1746 params
['roaming_consortium'] = ["223344"]
1747 params
['anqp_3gpp_cell_net'] = "555,444"
1748 hostapd
.add_ap(apdev
[1], params
)
1750 values
= default_cred()
1751 values
['excluded_ssid'] = "test-hs20"
1752 events
= policy_test(dev
[0], apdev
[1], values
)
1753 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1755 raise Exception("Excluded network not reported")
1756 values
['excluded_ssid'] = "test-hs20-other"
1757 events
= policy_test(dev
[0], apdev
[0], values
)
1758 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1760 raise Exception("Excluded network not reported")
1762 values
= default_cred()
1763 values
['roaming_consortium'] = "223344"
1764 values
['eap'] = "TTLS"
1765 values
['phase2'] = "auth=MSCHAPV2"
1766 values
['excluded_ssid'] = "test-hs20"
1767 events
= policy_test(dev
[0], apdev
[1], values
)
1768 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1770 raise Exception("Excluded network not reported")
1772 values
= {'imsi': "555444-333222111", 'eap': "SIM",
1773 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1774 'excluded_ssid': "test-hs20"}
1775 events
= policy_test(dev
[0], apdev
[1], values
)
1776 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1778 raise Exception("Excluded network not reported")
1780 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1781 """Hotspot 2.0 and roaming from current to higher priority network"""
1782 check_eap_capa(dev
[0], "MSCHAPV2")
1783 bssid
= apdev
[0]['bssid']
1784 params
= hs20_ap_params(ssid
="test-hs20-visited")
1785 params
['domain_name'] = "visited.example.org"
1786 hostapd
.add_ap(apdev
[0], params
)
1788 dev
[0].hs20_enable()
1789 id = dev
[0].add_cred_values({'realm': "example.com",
1790 'ca_cert': "auth_serv/ca.pem",
1791 'username': "hs20-test",
1792 'password': "password",
1793 'domain': "example.com"})
1794 logger
.info("Connect to the only network option")
1795 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1796 dev
[0].dump_monitor()
1797 interworking_connect(dev
[0], bssid
, "TTLS")
1799 logger
.info("Start another AP (home operator) and reconnect")
1800 bssid2
= apdev
[1]['bssid']
1801 params
= hs20_ap_params(ssid
="test-hs20-home")
1802 params
['domain_name'] = "example.com"
1803 hostapd
.add_ap(apdev
[1], params
)
1805 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1806 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1807 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1808 "INTERWORKING-ALREADY-CONNECTED",
1809 "CTRL-EVENT-CONNECTED"], timeout
=15)
1811 raise Exception("Connection timed out")
1812 if "INTERWORKING-NO-MATCH" in ev
:
1813 raise Exception("Matching AP not found")
1814 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1815 raise Exception("Unexpected AP selected")
1816 if bssid2
not in ev
:
1817 raise Exception("Unexpected BSSID after reconnection")
1819 def test_ap_hs20_domain_suffix_match_full(dev
, apdev
):
1820 """Hotspot 2.0 and domain_suffix_match"""
1821 check_domain_match_full(dev
[0])
1822 check_eap_capa(dev
[0], "MSCHAPV2")
1823 bssid
= apdev
[0]['bssid']
1824 params
= hs20_ap_params()
1825 hostapd
.add_ap(apdev
[0], params
)
1827 dev
[0].hs20_enable()
1828 id = dev
[0].add_cred_values({'realm': "example.com",
1829 'username': "hs20-test",
1830 'password': "password",
1831 'ca_cert': "auth_serv/ca.pem",
1832 'domain': "example.com",
1833 'domain_suffix_match': "server.w1.fi"})
1834 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1835 dev
[0].dump_monitor()
1836 interworking_connect(dev
[0], bssid
, "TTLS")
1837 dev
[0].request("REMOVE_NETWORK all")
1838 dev
[0].dump_monitor()
1840 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1841 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1842 dev
[0].dump_monitor()
1843 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1844 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1846 raise Exception("TLS certificate error not reported")
1847 if "Domain suffix mismatch" not in ev
:
1848 raise Exception("Domain suffix mismatch not reported")
1850 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1851 """Hotspot 2.0 and domain_suffix_match"""
1852 check_eap_capa(dev
[0], "MSCHAPV2")
1853 check_domain_match_full(dev
[0])
1854 bssid
= apdev
[0]['bssid']
1855 params
= hs20_ap_params()
1856 hostapd
.add_ap(apdev
[0], params
)
1858 dev
[0].hs20_enable()
1859 id = dev
[0].add_cred_values({'realm': "example.com",
1860 'username': "hs20-test",
1861 'password': "password",
1862 'ca_cert': "auth_serv/ca.pem",
1863 'domain': "example.com",
1864 'domain_suffix_match': "w1.fi"})
1865 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1866 dev
[0].dump_monitor()
1867 interworking_connect(dev
[0], bssid
, "TTLS")
1869 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1870 """Hotspot 2.0 and roaming partner preference"""
1871 check_eap_capa(dev
[0], "MSCHAPV2")
1872 params
= hs20_ap_params()
1873 params
['domain_name'] = "roaming.example.org"
1874 hostapd
.add_ap(apdev
[0], params
)
1876 params
= hs20_ap_params()
1877 params
['ssid'] = "test-hs20-other"
1878 params
['domain_name'] = "roaming.example.net"
1879 hostapd
.add_ap(apdev
[1], params
)
1881 logger
.info("Verify default vs. specified preference")
1882 values
= default_cred()
1883 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1884 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1885 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1886 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1888 logger
.info("Verify partial FQDN match")
1889 values
['roaming_partner'] = "example.net,0,0,*"
1890 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1891 values
['roaming_partner'] = "example.net,0,255,*"
1892 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1894 def test_ap_hs20_max_bss_load(dev
, apdev
):
1895 """Hotspot 2.0 and maximum BSS load"""
1896 check_eap_capa(dev
[0], "MSCHAPV2")
1897 params
= hs20_ap_params()
1898 params
['bss_load_test'] = "12:200:20000"
1899 hostapd
.add_ap(apdev
[0], params
)
1901 params
= hs20_ap_params()
1902 params
['ssid'] = "test-hs20-other"
1903 params
['bss_load_test'] = "5:20:10000"
1904 hostapd
.add_ap(apdev
[1], params
)
1906 logger
.info("Verify maximum BSS load constraint")
1907 values
= default_cred()
1908 values
['domain'] = "example.com"
1909 values
['max_bss_load'] = "100"
1910 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1912 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1913 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1914 raise Exception("Maximum BSS Load case not noticed")
1915 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1916 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1917 raise Exception("Maximum BSS Load case reported incorrectly")
1919 logger
.info("Verify maximum BSS load does not prevent connection")
1920 values
['max_bss_load'] = "1"
1921 events
= policy_test(dev
[0], None, values
)
1923 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1924 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1925 raise Exception("Maximum BSS Load case not noticed")
1926 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1927 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1928 raise Exception("Maximum BSS Load case not noticed")
1930 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1931 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1932 check_eap_capa(dev
[0], "MSCHAPV2")
1933 params
= hs20_ap_params()
1934 params
['bss_load_test'] = "12:200:20000"
1935 hostapd
.add_ap(apdev
[0], params
)
1937 params
= hs20_ap_params()
1938 params
['ssid'] = "test-hs20-other"
1939 hostapd
.add_ap(apdev
[1], params
)
1941 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1942 values
= default_cred()
1943 values
['domain'] = "example.com"
1944 values
['max_bss_load'] = "100"
1945 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1947 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1948 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1949 raise Exception("Maximum BSS Load case not noticed")
1950 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1951 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1952 raise Exception("Maximum BSS Load case reported incorrectly")
1954 def test_ap_hs20_max_bss_load_roaming(dev
, apdev
):
1955 """Hotspot 2.0 and maximum BSS load (roaming)"""
1956 check_eap_capa(dev
[0], "MSCHAPV2")
1957 params
= hs20_ap_params()
1958 params
['bss_load_test'] = "12:200:20000"
1959 hostapd
.add_ap(apdev
[0], params
)
1961 values
= default_cred()
1962 values
['domain'] = "roaming.example.com"
1963 values
['max_bss_load'] = "100"
1964 events
= policy_test(dev
[0], apdev
[0], values
, only_one
=True)
1965 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1967 raise Exception("No INTERWORKING-AP event")
1968 if "over_max_bss_load=1" in ev
[0]:
1969 raise Exception("Maximum BSS Load reported for roaming")
1971 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1972 """Hotspot 2.0 multi-cred sp_priority"""
1973 check_eap_capa(dev
[0], "MSCHAPV2")
1975 _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1977 dev
[0].request("SET external_sim 0")
1979 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1980 hlr_auc_gw_available()
1981 bssid
= apdev
[0]['bssid']
1982 params
= hs20_ap_params()
1983 params
['hessid'] = bssid
1984 del params
['domain_name']
1985 params
['anqp_3gpp_cell_net'] = "232,01"
1986 hostapd
.add_ap(apdev
[0], params
)
1988 dev
[0].hs20_enable()
1989 dev
[0].scan_for_bss(bssid
, freq
="2412")
1990 dev
[0].request("SET external_sim 1")
1991 id1
= dev
[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM",
1992 'provisioning_sp': "example.com",
1993 'sp_priority' :"1"})
1994 id2
= dev
[0].add_cred_values({'realm': "example.com",
1995 'ca_cert': "auth_serv/ca.pem",
1996 'username': "hs20-test",
1997 'password': "password",
1998 'domain': "example.com",
1999 'provisioning_sp': "example.com",
2000 'sp_priority': "2"})
2001 dev
[0].dump_monitor()
2002 dev
[0].scan_for_bss(bssid
, freq
="2412")
2003 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2004 interworking_ext_sim_auth(dev
[0], "SIM")
2005 check_sp_type(dev
[0], "unknown")
2006 dev
[0].request("REMOVE_NETWORK all")
2008 dev
[0].set_cred(id1
, "sp_priority", "2")
2009 dev
[0].set_cred(id2
, "sp_priority", "1")
2010 dev
[0].dump_monitor()
2011 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2012 interworking_auth(dev
[0], "TTLS")
2013 check_sp_type(dev
[0], "unknown")
2015 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
2016 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
2017 check_eap_capa(dev
[0], "MSCHAPV2")
2019 _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
2021 dev
[0].request("SET external_sim 0")
2023 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
2024 hlr_auc_gw_available()
2025 bssid
= apdev
[0]['bssid']
2026 params
= hs20_ap_params()
2027 params
['hessid'] = bssid
2028 del params
['nai_realm']
2029 del params
['domain_name']
2030 params
['anqp_3gpp_cell_net'] = "232,01"
2031 hostapd
.add_ap(apdev
[0], params
)
2033 bssid2
= apdev
[1]['bssid']
2034 params
= hs20_ap_params()
2035 params
['ssid'] = "test-hs20-other"
2036 params
['hessid'] = bssid2
2037 del params
['domain_name']
2038 del params
['anqp_3gpp_cell_net']
2039 hostapd
.add_ap(apdev
[1], params
)
2041 dev
[0].hs20_enable()
2042 dev
[0].request("SET external_sim 1")
2043 id1
= dev
[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM",
2044 'provisioning_sp': "example.com",
2045 'sp_priority': "1"})
2046 id2
= dev
[0].add_cred_values({'realm': "example.com",
2047 'ca_cert': "auth_serv/ca.pem",
2048 'username': "hs20-test",
2049 'password': "password",
2050 'domain': "example.com",
2051 'provisioning_sp': "example.com",
2052 'sp_priority': "2"})
2053 dev
[0].dump_monitor()
2054 dev
[0].scan_for_bss(bssid
, freq
="2412")
2055 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2056 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2057 interworking_ext_sim_auth(dev
[0], "SIM")
2058 check_sp_type(dev
[0], "unknown")
2059 conn_bssid
= dev
[0].get_status_field("bssid")
2060 if conn_bssid
!= bssid
:
2061 raise Exception("Connected to incorrect BSS")
2062 dev
[0].request("REMOVE_NETWORK all")
2064 dev
[0].set_cred(id1
, "sp_priority", "2")
2065 dev
[0].set_cred(id2
, "sp_priority", "1")
2066 dev
[0].dump_monitor()
2067 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2068 interworking_auth(dev
[0], "TTLS")
2069 check_sp_type(dev
[0], "unknown")
2070 conn_bssid
= dev
[0].get_status_field("bssid")
2071 if conn_bssid
!= bssid2
:
2072 raise Exception("Connected to incorrect BSS")
2074 def test_ap_hs20_multi_cred_sp_prio_same(dev
, apdev
):
2075 """Hotspot 2.0 multi-cred and same sp_priority"""
2076 check_eap_capa(dev
[0], "MSCHAPV2")
2077 hlr_auc_gw_available()
2078 bssid
= apdev
[0]['bssid']
2079 params
= hs20_ap_params()
2080 params
['hessid'] = bssid
2081 del params
['domain_name']
2082 params
['anqp_3gpp_cell_net'] = "232,01"
2083 hostapd
.add_ap(apdev
[0], params
)
2085 dev
[0].hs20_enable()
2086 dev
[0].scan_for_bss(bssid
, freq
="2412")
2087 id1
= dev
[0].add_cred_values({'realm': "example.com",
2088 'ca_cert': "auth_serv/ca.pem",
2089 'username': "hs20-test",
2090 'password': "password",
2091 'domain': "domain1.example.com",
2092 'provisioning_sp': "example.com",
2093 'sp_priority': "1"})
2094 id2
= dev
[0].add_cred_values({'realm': "example.com",
2095 'ca_cert': "auth_serv/ca.pem",
2096 'username': "hs20-test",
2097 'password': "password",
2098 'domain': "domain2.example.com",
2099 'provisioning_sp': "example.com",
2100 'sp_priority': "1"})
2101 dev
[0].dump_monitor()
2102 dev
[0].scan_for_bss(bssid
, freq
="2412")
2103 check_auto_select(dev
[0], bssid
)
2105 def check_conn_capab_selection(dev
, type, missing
):
2106 dev
.request("INTERWORKING_SELECT freq=2412")
2107 ev
= dev
.wait_event(["INTERWORKING-AP"])
2109 raise Exception("Network selection timed out")
2110 if "type=" + type not in ev
:
2111 raise Exception("Unexpected network type")
2112 if missing
and "conn_capab_missing=1" not in ev
:
2113 raise Exception("conn_capab_missing not reported")
2114 if not missing
and "conn_capab_missing=1" in ev
:
2115 raise Exception("conn_capab_missing reported unexpectedly")
2117 def conn_capab_cred(domain
=None, req_conn_capab
=None):
2118 cred
= default_cred(domain
=domain
)
2120 cred
['req_conn_capab'] = req_conn_capab
2123 def test_ap_hs20_req_conn_capab(dev
, apdev
):
2124 """Hotspot 2.0 network selection with req_conn_capab"""
2125 check_eap_capa(dev
[0], "MSCHAPV2")
2126 bssid
= apdev
[0]['bssid']
2127 params
= hs20_ap_params()
2128 hostapd
.add_ap(apdev
[0], params
)
2130 dev
[0].hs20_enable()
2131 dev
[0].scan_for_bss(bssid
, freq
="2412")
2132 logger
.info("Not used in home network")
2133 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
2134 id = dev
[0].add_cred_values(values
)
2135 check_conn_capab_selection(dev
[0], "home", False)
2137 logger
.info("Used in roaming network")
2138 dev
[0].remove_cred(id)
2139 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
2140 id = dev
[0].add_cred_values(values
)
2141 check_conn_capab_selection(dev
[0], "roaming", True)
2143 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
2144 check_auto_select(dev
[0], bssid
)
2146 logger
.info("Additional req_conn_capab checks")
2148 dev
[0].remove_cred(id)
2149 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
2150 id = dev
[0].add_cred_values(values
)
2151 check_conn_capab_selection(dev
[0], "roaming", True)
2153 dev
[0].remove_cred(id)
2154 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
2155 id = dev
[0].add_cred_values(values
)
2156 check_conn_capab_selection(dev
[0], "roaming", True)
2158 bssid2
= apdev
[1]['bssid']
2159 params
= hs20_ap_params(ssid
="test-hs20b")
2160 params
['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0", "50:0:1"]
2161 hostapd
.add_ap(apdev
[1], params
)
2163 dev
[0].remove_cred(id)
2164 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
2165 id = dev
[0].add_cred_values(values
)
2166 dev
[0].set_cred(id, "req_conn_capab", "6:22")
2167 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2168 dev
[0].request("INTERWORKING_SELECT freq=2412")
2169 for i
in range(0, 2):
2170 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
2172 raise Exception("Network selection timed out")
2173 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
2174 raise Exception("Missing protocol connection capability not reported")
2175 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
2176 raise Exception("Protocol connection capability not reported correctly")
2178 def test_ap_hs20_req_conn_capab2(dev
, apdev
):
2179 """Hotspot 2.0 network selection with req_conn_capab (not present)"""
2180 check_eap_capa(dev
[0], "MSCHAPV2")
2181 bssid
= apdev
[0]['bssid']
2182 params
= hs20_ap_params()
2183 del params
['hs20_conn_capab']
2184 hostapd
.add_ap(apdev
[0], params
)
2186 dev
[0].hs20_enable()
2187 dev
[0].scan_for_bss(bssid
, freq
="2412")
2188 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
2189 id = dev
[0].add_cred_values(values
)
2190 check_conn_capab_selection(dev
[0], "roaming", False)
2192 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
2193 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
2194 check_eap_capa(dev
[0], "MSCHAPV2")
2195 bssid
= apdev
[0]['bssid']
2196 params
= hs20_ap_params()
2197 params
['domain_name'] = "roaming.example.org"
2198 params
['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0", "50:0:1"]
2199 hostapd
.add_ap(apdev
[0], params
)
2201 bssid2
= apdev
[1]['bssid']
2202 params
= hs20_ap_params(ssid
="test-hs20-b")
2203 params
['domain_name'] = "roaming.example.net"
2204 hostapd
.add_ap(apdev
[1], params
)
2206 values
= default_cred()
2207 values
['roaming_partner'] = "roaming.example.net,1,127,*"
2208 id = dev
[0].add_cred_values(values
)
2209 check_auto_select(dev
[0], bssid2
)
2211 dev
[0].set_cred(id, "req_conn_capab", "50")
2212 check_auto_select(dev
[0], bssid
)
2214 dev
[0].remove_cred(id)
2215 id = dev
[0].add_cred_values(values
)
2216 dev
[0].set_cred(id, "req_conn_capab", "51")
2217 check_auto_select(dev
[0], bssid2
)
2219 def check_bandwidth_selection(dev
, type, below
):
2220 dev
.request("INTERWORKING_SELECT freq=2412")
2221 ev
= dev
.wait_event(["INTERWORKING-AP"])
2223 raise Exception("Network selection timed out")
2224 logger
.debug("BSS entries:\n" + dev
.request("BSS RANGE=ALL"))
2225 if "type=" + type not in ev
:
2226 raise Exception("Unexpected network type")
2227 if below
and "below_min_backhaul=1" not in ev
:
2228 raise Exception("below_min_backhaul not reported")
2229 if not below
and "below_min_backhaul=1" in ev
:
2230 raise Exception("below_min_backhaul reported unexpectedly")
2232 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
2233 cred
= default_cred(domain
=domain
)
2235 cred
['min_dl_bandwidth_home'] = str(dl_home
)
2237 cred
['min_ul_bandwidth_home'] = str(ul_home
)
2239 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
2241 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
2244 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
2245 """Hotspot 2.0 network selection with min bandwidth (home)"""
2246 check_eap_capa(dev
[0], "MSCHAPV2")
2247 bssid
= apdev
[0]['bssid']
2248 params
= hs20_ap_params()
2249 hostapd
.add_ap(apdev
[0], params
)
2251 dev
[0].hs20_enable()
2252 dev
[0].scan_for_bss(bssid
, freq
="2412")
2253 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2254 id = dev
[0].add_cred_values(values
)
2255 check_bandwidth_selection(dev
[0], "home", False)
2256 dev
[0].remove_cred(id)
2258 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
2259 id = dev
[0].add_cred_values(values
)
2260 check_bandwidth_selection(dev
[0], "home", True)
2261 dev
[0].remove_cred(id)
2263 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
2264 id = dev
[0].add_cred_values(values
)
2265 check_bandwidth_selection(dev
[0], "home", True)
2266 dev
[0].remove_cred(id)
2268 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
2269 id = dev
[0].add_cred_values(values
)
2270 check_bandwidth_selection(dev
[0], "home", True)
2271 check_auto_select(dev
[0], bssid
)
2273 bssid2
= apdev
[1]['bssid']
2274 params
= hs20_ap_params(ssid
="test-hs20-b")
2275 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2276 hostapd
.add_ap(apdev
[1], params
)
2278 check_auto_select(dev
[0], bssid2
)
2280 def test_ap_hs20_min_bandwidth_home2(dev
, apdev
):
2281 """Hotspot 2.0 network selection with min bandwidth - special cases"""
2282 check_eap_capa(dev
[0], "MSCHAPV2")
2283 bssid
= apdev
[0]['bssid']
2284 params
= hs20_ap_params()
2285 hapd
= hostapd
.add_ap(apdev
[0], params
)
2287 dev
[0].hs20_enable()
2288 dev
[0].scan_for_bss(bssid
, freq
="2412")
2289 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2290 id = dev
[0].add_cred_values(values
)
2291 check_bandwidth_selection(dev
[0], "home", False)
2293 logger
.info("WAN link at capacity")
2294 hapd
.set('hs20_wan_metrics', "09:8000:1000:80:240:3000")
2295 check_bandwidth_selection(dev
[0], "home", True)
2297 logger
.info("Downlink/Uplink Load was not measured")
2298 hapd
.set('hs20_wan_metrics', "01:8000:1000:80:240:0")
2299 check_bandwidth_selection(dev
[0], "home", False)
2301 logger
.info("Uplink and Downlink max values")
2302 hapd
.set('hs20_wan_metrics', "01:4294967295:4294967295:80:240:3000")
2303 check_bandwidth_selection(dev
[0], "home", False)
2305 dev
[0].remove_cred(id)
2307 def test_ap_hs20_min_bandwidth_home_hidden_ssid_in_scan_res(dev
, apdev
):
2308 """Hotspot 2.0 network selection with min bandwidth (home) while hidden SSID is included in scan results"""
2309 check_eap_capa(dev
[0], "MSCHAPV2")
2310 bssid
= apdev
[0]['bssid']
2312 hapd
= hostapd
.add_ap(apdev
[0], {"ssid": 'secret',
2313 "ignore_broadcast_ssid": "1"})
2314 dev
[0].scan_for_bss(bssid
, freq
=2412)
2316 hapd_global
= hostapd
.HostapdGlobal(apdev
[0])
2318 hapd_global
.remove(apdev
[0]['ifname'])
2320 params
= hs20_ap_params()
2321 hostapd
.add_ap(apdev
[0], params
)
2323 dev
[0].hs20_enable()
2324 dev
[0].scan_for_bss(bssid
, freq
="2412")
2325 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2326 id = dev
[0].add_cred_values(values
)
2327 check_bandwidth_selection(dev
[0], "home", False)
2328 dev
[0].remove_cred(id)
2330 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
2331 id = dev
[0].add_cred_values(values
)
2332 check_bandwidth_selection(dev
[0], "home", True)
2333 dev
[0].remove_cred(id)
2335 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
2336 id = dev
[0].add_cred_values(values
)
2337 check_bandwidth_selection(dev
[0], "home", True)
2338 dev
[0].remove_cred(id)
2340 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
2341 id = dev
[0].add_cred_values(values
)
2342 check_bandwidth_selection(dev
[0], "home", True)
2343 check_auto_select(dev
[0], bssid
)
2345 bssid2
= apdev
[1]['bssid']
2346 params
= hs20_ap_params(ssid
="test-hs20-b")
2347 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2348 hostapd
.add_ap(apdev
[1], params
)
2350 check_auto_select(dev
[0], bssid2
)
2352 dev
[0].flush_scan_cache()
2354 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
2355 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
2356 check_eap_capa(dev
[0], "MSCHAPV2")
2357 bssid
= apdev
[0]['bssid']
2358 params
= hs20_ap_params()
2359 hostapd
.add_ap(apdev
[0], params
)
2361 dev
[0].hs20_enable()
2362 dev
[0].scan_for_bss(bssid
, freq
="2412")
2363 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
2364 id = dev
[0].add_cred_values(values
)
2365 check_bandwidth_selection(dev
[0], "roaming", False)
2366 dev
[0].remove_cred(id)
2368 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
2369 id = dev
[0].add_cred_values(values
)
2370 check_bandwidth_selection(dev
[0], "roaming", True)
2371 dev
[0].remove_cred(id)
2373 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
2374 id = dev
[0].add_cred_values(values
)
2375 check_bandwidth_selection(dev
[0], "roaming", True)
2376 dev
[0].remove_cred(id)
2378 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
2379 id = dev
[0].add_cred_values(values
)
2380 check_bandwidth_selection(dev
[0], "roaming", True)
2381 check_auto_select(dev
[0], bssid
)
2383 bssid2
= apdev
[1]['bssid']
2384 params
= hs20_ap_params(ssid
="test-hs20-b")
2385 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2386 hostapd
.add_ap(apdev
[1], params
)
2388 check_auto_select(dev
[0], bssid2
)
2390 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
2391 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
2392 check_eap_capa(dev
[0], "MSCHAPV2")
2393 bssid
= apdev
[0]['bssid']
2394 params
= hs20_ap_params()
2395 params
['domain_name'] = "roaming.example.org"
2396 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2397 hostapd
.add_ap(apdev
[0], params
)
2399 bssid2
= apdev
[1]['bssid']
2400 params
= hs20_ap_params(ssid
="test-hs20-b")
2401 params
['domain_name'] = "roaming.example.net"
2402 hostapd
.add_ap(apdev
[1], params
)
2404 values
= default_cred()
2405 values
['roaming_partner'] = "roaming.example.net,1,127,*"
2406 id = dev
[0].add_cred_values(values
)
2407 check_auto_select(dev
[0], bssid2
)
2409 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
2410 check_auto_select(dev
[0], bssid
)
2412 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
2413 check_auto_select(dev
[0], bssid2
)
2415 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
2416 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
2417 bssid
= apdev
[0]['bssid']
2418 params
= hs20_ap_params()
2419 del params
['hs20_wan_metrics']
2420 hostapd
.add_ap(apdev
[0], params
)
2422 dev
[0].hs20_enable()
2423 dev
[0].scan_for_bss(bssid
, freq
="2412")
2424 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
2425 dl_roaming
=10000, ul_roaming
=10000)
2426 dev
[0].add_cred_values(values
)
2427 check_bandwidth_selection(dev
[0], "home", False)
2429 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
2430 """Hotspot 2.0 connection and deauthentication request for ESS"""
2431 check_eap_capa(dev
[0], "MSCHAPV2")
2433 _test_ap_hs20_deauth_req_ess(dev
, apdev
)
2435 dev
[0].request("SET pmf 0")
2437 def _test_ap_hs20_deauth_req_ess(dev
, apdev
):
2438 dev
[0].request("SET pmf 2")
2439 hapd
= eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
2440 dev
[0].dump_monitor()
2441 addr
= dev
[0].p2p_interface_addr()
2443 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
2444 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
2446 raise Exception("Timeout on deauth imminent notice")
2447 if "1 120 http://example.com/" not in ev
:
2448 raise Exception("Unexpected deauth imminent notice: " + ev
)
2449 hapd
.request("DEAUTHENTICATE " + addr
)
2450 dev
[0].wait_disconnected(timeout
=10)
2451 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
2452 raise Exception("Network not marked temporarily disabled")
2453 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
2454 "Trying to associate",
2455 "CTRL-EVENT-CONNECTED"], timeout
=5)
2457 raise Exception("Unexpected connection attempt")
2459 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
2460 """Hotspot 2.0 connection and deauthentication request for BSS"""
2461 check_eap_capa(dev
[0], "MSCHAPV2")
2463 _test_ap_hs20_deauth_req_bss(dev
, apdev
)
2465 dev
[0].request("SET pmf 0")
2467 def _test_ap_hs20_deauth_req_bss(dev
, apdev
):
2468 dev
[0].request("SET pmf 2")
2469 hapd
= eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
2470 dev
[0].dump_monitor()
2471 addr
= dev
[0].p2p_interface_addr()
2473 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
2474 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
2476 raise Exception("Timeout on deauth imminent notice")
2477 if "0 120 http://example.com/" not in ev
:
2478 raise Exception("Unexpected deauth imminent notice: " + ev
)
2479 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
2480 ev
= dev
[0].wait_disconnected(timeout
=10)
2481 if "reason=4" not in ev
:
2482 raise Exception("Unexpected disconnection reason")
2483 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
2484 raise Exception("Network not marked temporarily disabled")
2485 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
2486 "Trying to associate",
2487 "CTRL-EVENT-CONNECTED"], timeout
=5)
2489 raise Exception("Unexpected connection attempt")
2491 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
2492 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
2493 check_eap_capa(dev
[0], "MSCHAPV2")
2495 _test_ap_hs20_deauth_req_from_radius(dev
, apdev
)
2497 dev
[0].request("SET pmf 0")
2499 def _test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
2500 bssid
= apdev
[0]['bssid']
2501 params
= hs20_ap_params()
2502 params
['nai_realm'] = ["0,example.com,21[2:4]"]
2503 params
['hs20_deauth_req_timeout'] = "2"
2504 hostapd
.add_ap(apdev
[0], params
)
2506 dev
[0].request("SET pmf 2")
2507 dev
[0].hs20_enable()
2508 dev
[0].add_cred_values({'realm': "example.com",
2509 'username': "hs20-deauth-test",
2510 'password': "password"})
2511 interworking_select(dev
[0], bssid
, freq
="2412")
2512 interworking_connect(dev
[0], bssid
, "TTLS")
2513 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
2515 raise Exception("Timeout on deauth imminent notice")
2516 if " 1 100" not in ev
:
2517 raise Exception("Unexpected deauth imminent contents")
2518 dev
[0].wait_disconnected(timeout
=3)
2520 def test_ap_hs20_deauth_req_without_pmf(dev
, apdev
):
2521 """Hotspot 2.0 connection and deauthentication request without PMF"""
2522 check_eap_capa(dev
[0], "MSCHAPV2")
2523 dev
[0].request("SET pmf 0")
2524 hapd
= eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user", release
=1)
2525 dev
[0].dump_monitor()
2526 id = int(dev
[0].get_status_field("id"))
2527 dev
[0].set_network(id, "ieee80211w", "0")
2528 dev
[0].request("DISCONNECT")
2529 dev
[0].wait_disconnected()
2530 dev
[0].select_network(id, freq
=2412)
2531 dev
[0].wait_connected()
2532 addr
= dev
[0].own_addr()
2534 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
2535 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=0.2)
2537 raise Exception("Deauth imminent notice without PMF accepted")
2538 with
alloc_fail(hapd
, 1, "wpabuf_alloc;hostapd_ctrl_iface_hs20_deauth_req"):
2539 if "FAIL" not in hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/"):
2540 raise Exception("HS20_DEAUTH_REQ accepted during OOM")
2542 def test_ap_hs20_remediation_required(dev
, apdev
):
2543 """Hotspot 2.0 connection and remediation required from RADIUS"""
2544 check_eap_capa(dev
[0], "MSCHAPV2")
2546 _test_ap_hs20_remediation_required(dev
, apdev
)
2548 dev
[0].request("SET pmf 0")
2550 def _test_ap_hs20_remediation_required(dev
, apdev
):
2551 bssid
= apdev
[0]['bssid']
2552 params
= hs20_ap_params()
2553 params
['nai_realm'] = ["0,example.com,21[2:4]"]
2554 hostapd
.add_ap(apdev
[0], params
)
2556 dev
[0].request("SET pmf 1")
2557 dev
[0].hs20_enable()
2558 dev
[0].add_cred_values({'realm': "example.com",
2559 'username': "hs20-subrem-test",
2560 'password': "password"})
2561 interworking_select(dev
[0], bssid
, freq
="2412")
2562 interworking_connect(dev
[0], bssid
, "TTLS")
2563 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2565 raise Exception("Timeout on subscription remediation notice")
2566 if " 1 https://example.com/" not in ev
:
2567 raise Exception("Unexpected subscription remediation event contents")
2569 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
2570 """Hotspot 2.0 connection and subrem from ctrl_iface"""
2571 check_eap_capa(dev
[0], "MSCHAPV2")
2573 _test_ap_hs20_remediation_required_ctrl(dev
, apdev
)
2575 dev
[0].request("SET pmf 0")
2577 def _test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
2578 bssid
= apdev
[0]['bssid']
2579 addr
= dev
[0].own_addr()
2580 params
= hs20_ap_params()
2581 params
['nai_realm'] = ["0,example.com,21[2:4]"]
2582 hapd
= hostapd
.add_ap(apdev
[0], params
)
2584 dev
[0].request("SET pmf 1")
2585 dev
[0].hs20_enable()
2586 dev
[0].add_cred_values(default_cred())
2587 interworking_select(dev
[0], bssid
, freq
="2412")
2588 interworking_connect(dev
[0], bssid
, "TTLS")
2590 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
2591 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2593 raise Exception("Timeout on subscription remediation notice")
2594 if " 1 https://example.com/" not in ev
:
2595 raise Exception("Unexpected subscription remediation event contents")
2597 hapd
.request("HS20_WNM_NOTIF " + addr
)
2598 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2600 raise Exception("Timeout on subscription remediation notice")
2601 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
2602 raise Exception("Unexpected subscription remediation event contents: " + ev
)
2604 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
2605 raise Exception("Unexpected HS20_WNM_NOTIF success")
2606 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
2607 raise Exception("Unexpected HS20_WNM_NOTIF success")
2608 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
2609 raise Exception("Unexpected HS20_WNM_NOTIF success")
2610 if "OK" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " "):
2611 raise Exception("HS20_WNM_NOTIF failed with empty URL")
2613 def test_ap_hs20_session_info(dev
, apdev
):
2614 """Hotspot 2.0 connection and session information from RADIUS"""
2615 check_eap_capa(dev
[0], "MSCHAPV2")
2617 _test_ap_hs20_session_info(dev
, apdev
)
2619 dev
[0].request("SET pmf 0")
2621 def _test_ap_hs20_session_info(dev
, apdev
):
2622 bssid
= apdev
[0]['bssid']
2623 params
= hs20_ap_params()
2624 params
['nai_realm'] = ["0,example.com,21[2:4]"]
2625 hostapd
.add_ap(apdev
[0], params
)
2627 dev
[0].request("SET pmf 1")
2628 dev
[0].hs20_enable()
2629 dev
[0].add_cred_values({'realm': "example.com",
2630 'username': "hs20-session-info-test",
2631 'password': "password"})
2632 interworking_select(dev
[0], bssid
, freq
="2412")
2633 interworking_connect(dev
[0], bssid
, "TTLS")
2634 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
2636 raise Exception("Timeout on ESS disassociation imminent notice")
2637 if " 1 59904 https://example.com/" not in ev
:
2638 raise Exception("Unexpected ESS disassociation imminent event contents")
2639 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
2641 raise Exception("Scan not started")
2642 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
2644 raise Exception("Scan not completed")
2646 def test_ap_hs20_osen(dev
, apdev
):
2647 """Hotspot 2.0 OSEN connection"""
2648 params
= {'ssid': "osen",
2650 'auth_server_addr': "127.0.0.1",
2651 'auth_server_port': "1812",
2652 'auth_server_shared_secret': "radius"}
2653 hostapd
.add_ap(apdev
[0], params
)
2655 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
2657 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
2658 scan_freq
="2412", wait_connect
=False)
2659 dev
[0].flush_scan_cache()
2660 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2661 group
="GTK_NOT_USED CCMP",
2662 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2663 ca_cert
="auth_serv/ca.pem",
2665 res
= dev
[0].get_bss(apdev
[0]['bssid'])['flags']
2666 if "[OSEN-OSEN-CCMP]" not in res
:
2667 raise Exception("OSEN not reported in BSS")
2669 raise Exception("WEP reported in BSS")
2670 res
= dev
[0].request("SCAN_RESULTS")
2671 if "[OSEN-OSEN-CCMP]" not in res
:
2672 raise Exception("OSEN not reported in SCAN_RESULTS")
2674 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2675 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
2676 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2677 group
="GTK_NOT_USED CCMP",
2678 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2679 ca_cert
="auth_serv/ca.pem",
2681 wpas
.request("DISCONNECT")
2683 def test_ap_hs20_osen_single_ssid(dev
, apdev
):
2684 """Hotspot 2.0 OSEN-single-SSID connection"""
2685 bssid
= apdev
[0]['bssid']
2686 params
= hs20_ap_params()
2687 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
2688 params
['hessid'] = bssid
2689 hapd
= hostapd
.add_ap(apdev
[0], params
)
2691 # RSN-OSEN (for OSU)
2692 dev
[0].connect("test-hs20", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2693 group
="CCMP GTK_NOT_USED",
2694 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2695 ca_cert
="auth_serv/ca.pem", ieee80211w
='2',
2697 # RSN-EAP (for data connection)
2698 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2699 identity
="hs20-test", password
="password",
2700 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2701 pairwise
="CCMP", group
="CCMP",
2702 ieee80211w
='2', scan_freq
="2412")
2704 res
= dev
[0].get_bss(apdev
[0]['bssid'])['flags']
2705 if "[WPA2-EAP+OSEN-CCMP]" not in res
:
2706 raise Exception("OSEN not reported in BSS")
2708 raise Exception("WEP reported in BSS")
2709 res
= dev
[0].request("SCAN_RESULTS")
2710 if "[WPA2-EAP+OSEN-CCMP]" not in res
:
2711 raise Exception("OSEN not reported in SCAN_RESULTS")
2713 hwsim_utils
.test_connectivity(dev
[1], hapd
)
2714 hwsim_utils
.test_connectivity(dev
[0], hapd
, broadcast
=False)
2715 hwsim_utils
.test_connectivity(dev
[0], hapd
, timeout
=1,
2716 success_expected
=False)
2718 def test_ap_hs20_network_preference(dev
, apdev
):
2719 """Hotspot 2.0 network selection with preferred home network"""
2720 check_eap_capa(dev
[0], "MSCHAPV2")
2721 bssid
= apdev
[0]['bssid']
2722 params
= hs20_ap_params()
2723 hostapd
.add_ap(apdev
[0], params
)
2725 dev
[0].hs20_enable()
2726 values
= {'realm': "example.com",
2727 'username': "hs20-test",
2728 'password': "password",
2729 'domain': "example.com"}
2730 dev
[0].add_cred_values(values
)
2732 id = dev
[0].add_network()
2733 dev
[0].set_network_quoted(id, "ssid", "home")
2734 dev
[0].set_network_quoted(id, "psk", "12345678")
2735 dev
[0].set_network(id, "priority", "1")
2736 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2738 dev
[0].scan_for_bss(bssid
, freq
="2412")
2739 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2740 ev
= dev
[0].wait_connected(timeout
=15)
2742 raise Exception("Unexpected network selected")
2744 bssid2
= apdev
[1]['bssid']
2745 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2746 hostapd
.add_ap(apdev
[1], params
)
2748 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2749 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2750 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2751 "INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
2753 raise Exception("Connection timed out")
2754 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2755 raise Exception("No roam to higher priority network")
2756 if bssid2
not in ev
:
2757 raise Exception("Unexpected network selected")
2759 def test_ap_hs20_network_preference2(dev
, apdev
):
2760 """Hotspot 2.0 network selection with preferred credential"""
2761 check_eap_capa(dev
[0], "MSCHAPV2")
2762 bssid2
= apdev
[1]['bssid']
2763 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2764 hostapd
.add_ap(apdev
[1], params
)
2766 dev
[0].hs20_enable()
2767 values
= {'realm': "example.com",
2768 'username': "hs20-test",
2769 'password': "password",
2770 'domain': "example.com",
2772 dev
[0].add_cred_values(values
)
2774 id = dev
[0].add_network()
2775 dev
[0].set_network_quoted(id, "ssid", "home")
2776 dev
[0].set_network_quoted(id, "psk", "12345678")
2777 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2779 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2780 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2781 ev
= dev
[0].wait_connected(timeout
=15)
2782 if bssid2
not in ev
:
2783 raise Exception("Unexpected network selected")
2785 bssid
= apdev
[0]['bssid']
2786 params
= hs20_ap_params()
2787 hostapd
.add_ap(apdev
[0], params
)
2789 dev
[0].scan_for_bss(bssid
, freq
="2412")
2790 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2791 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2792 "INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
2794 raise Exception("Connection timed out")
2795 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2796 raise Exception("No roam to higher priority network")
2798 raise Exception("Unexpected network selected")
2800 def test_ap_hs20_network_preference3(dev
, apdev
):
2801 """Hotspot 2.0 network selection with two credential (one preferred)"""
2802 check_eap_capa(dev
[0], "MSCHAPV2")
2803 bssid
= apdev
[0]['bssid']
2804 params
= hs20_ap_params()
2805 hostapd
.add_ap(apdev
[0], params
)
2807 bssid2
= apdev
[1]['bssid']
2808 params
= hs20_ap_params(ssid
="test-hs20b")
2809 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
2810 hostapd
.add_ap(apdev
[1], params
)
2812 dev
[0].hs20_enable()
2813 values
= {'realm': "example.com",
2814 'username': "hs20-test",
2815 'password': "password",
2817 dev
[0].add_cred_values(values
)
2818 values
= {'realm': "example.org",
2819 'username': "hs20-test",
2820 'password': "password"}
2821 id = dev
[0].add_cred_values(values
)
2823 dev
[0].scan_for_bss(bssid
, freq
="2412")
2824 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2825 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2826 ev
= dev
[0].wait_connected(timeout
=15)
2828 raise Exception("Unexpected network selected")
2830 dev
[0].set_cred(id, "priority", "2")
2831 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2832 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2833 "INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
2835 raise Exception("Connection timed out")
2836 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2837 raise Exception("No roam to higher priority network")
2838 if bssid2
not in ev
:
2839 raise Exception("Unexpected network selected")
2841 def test_ap_hs20_network_preference4(dev
, apdev
):
2842 """Hotspot 2.0 network selection with username vs. SIM credential"""
2843 check_eap_capa(dev
[0], "MSCHAPV2")
2844 bssid
= apdev
[0]['bssid']
2845 params
= hs20_ap_params()
2846 hostapd
.add_ap(apdev
[0], params
)
2848 bssid2
= apdev
[1]['bssid']
2849 params
= hs20_ap_params(ssid
="test-hs20b")
2850 params
['hessid'] = bssid2
2851 params
['anqp_3gpp_cell_net'] = "555,444"
2852 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
2853 hostapd
.add_ap(apdev
[1], params
)
2855 dev
[0].hs20_enable()
2856 values
= {'realm': "example.com",
2857 'username': "hs20-test",
2858 'password': "password",
2860 dev
[0].add_cred_values(values
)
2861 values
= {'imsi': "555444-333222111",
2863 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"}
2864 id = dev
[0].add_cred_values(values
)
2866 dev
[0].scan_for_bss(bssid
, freq
="2412")
2867 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2868 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2869 ev
= dev
[0].wait_connected(timeout
=15)
2871 raise Exception("Unexpected network selected")
2873 dev
[0].set_cred(id, "priority", "2")
2874 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2875 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2876 "INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
2878 raise Exception("Connection timed out")
2879 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2880 raise Exception("No roam to higher priority network")
2881 if bssid2
not in ev
:
2882 raise Exception("Unexpected network selected")
2884 def test_ap_hs20_interworking_select_blocking_scan(dev
, apdev
):
2885 """Ongoing INTERWORKING_SELECT blocking SCAN"""
2886 check_eap_capa(dev
[0], "MSCHAPV2")
2887 bssid
= apdev
[0]['bssid']
2888 params
= hs20_ap_params()
2889 hostapd
.add_ap(apdev
[0], params
)
2891 dev
[0].hs20_enable()
2892 values
= {'realm': "example.com",
2893 'username': "hs20-test",
2894 'password': "password",
2895 'domain': "example.com"}
2896 dev
[0].add_cred_values(values
)
2898 dev
[0].scan_for_bss(bssid
, freq
="2412")
2899 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2900 if "FAIL-BUSY" not in dev
[0].request("SCAN"):
2901 raise Exception("Unexpected SCAN command result")
2902 dev
[0].wait_connected(timeout
=15)
2904 def test_ap_hs20_fetch_osu(dev
, apdev
):
2905 """Hotspot 2.0 OSU provider and icon fetch"""
2906 bssid
= apdev
[0]['bssid']
2907 params
= hs20_ap_params()
2908 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2909 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2910 params
['osu_method_list'] = "1"
2911 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
2912 params
['osu_icon'] = "w1fi_logo"
2913 params
['osu_service_desc'] = ["eng:Example services", "fin:Esimerkkipalveluja"]
2914 params
['osu_server_uri'] = "https://example.com/osu/"
2915 hostapd
.add_ap(apdev
[0], params
)
2917 bssid2
= apdev
[1]['bssid']
2918 params
= hs20_ap_params(ssid
="test-hs20b")
2919 params
['hessid'] = bssid2
2920 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2921 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2922 params
['osu_method_list'] = "0"
2923 params
['osu_nai'] = "osen@example.com"
2924 params
['osu_friendly_name'] = ["eng:Test2 OSU", "fin:Testi2-OSU"]
2925 params
['osu_icon'] = "w1fi_logo"
2926 params
['osu_service_desc'] = ["eng:Example services2", "fin:Esimerkkipalveluja2"]
2927 params
['osu_server_uri'] = "https://example.org/osu/"
2928 hostapd
.add_ap(apdev
[1], params
)
2930 with
open("w1fi_logo.png", "rb") as f
:
2931 orig_logo
= f
.read()
2932 dev
[0].hs20_enable()
2933 dir = "/tmp/osu-fetch"
2934 if os
.path
.isdir(dir):
2935 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
2937 os
.remove(dir + "/" + f
)
2944 dev
[1].scan_for_bss(bssid
, freq
="2412")
2945 dev
[2].scan_for_bss(bssid
, freq
="2412")
2946 dev
[0].request("SET osu_dir " + dir)
2947 dev
[0].request("FETCH_OSU")
2948 if "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2949 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2950 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2951 raise Exception("HS20_ICON_REQUEST failed")
2952 if "OK" not in dev
[2].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2953 raise Exception("REQ_HS20_ICON failed")
2956 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2957 "RX-HS20-ANQP-ICON"], timeout
=15)
2959 raise Exception("Timeout on OSU fetch")
2960 if "OSU provider fetch completed" in ev
:
2962 if "RX-HS20-ANQP-ICON" in ev
:
2963 with
open(ev
.split(' ')[1], "rb") as f
:
2965 if logo
== orig_logo
:
2968 with
open(dir + "/osu-providers.txt", "r") as f
:
2970 logger
.debug("osu-providers.txt: " + prov
)
2971 if "OSU-PROVIDER " + bssid
not in prov
:
2972 raise Exception("Missing OSU_PROVIDER(1)")
2973 if "OSU-PROVIDER " + bssid2
not in prov
:
2974 raise Exception("Missing OSU_PROVIDER(2)")
2976 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
2978 os
.remove(dir + "/" + f
)
2982 raise Exception("Unexpected number of icons fetched")
2984 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2986 raise Exception("Timeout on GAS-QUERY-DONE")
2987 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2989 raise Exception("Timeout on GAS-QUERY-DONE")
2990 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2991 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2992 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2994 raise Exception("Timeout on icon fetch")
2995 if "Icon Binary File" not in ev
:
2996 raise Exception("Unexpected ANQP element")
2998 ev
= dev
[2].wait_event(["RX-HS20-ICON"], timeout
=5)
3000 raise Exception("Timeout on RX-HS20-ICON")
3001 event_icon_len
= ev
.split(' ')[3]
3002 if " w1fi_logo " not in ev
:
3003 raise Exception("RX-HS20-ICON did not have the expected file name")
3005 raise Exception("RX-HS20-ICON did not have the expected BSSID")
3006 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 10"):
3007 raise Exception("GET_HS20_ICON 0..10 failed")
3008 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 5 10"):
3009 raise Exception("GET_HS20_ICON 5..15 failed")
3010 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 100000 10"):
3011 raise Exception("Unexpected success of GET_HS20_ICON with too large offset")
3012 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " no_such_logo 0 10"):
3013 raise Exception("GET_HS20_ICON for not existing icon succeeded")
3014 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 3070"):
3015 raise Exception("GET_HS20_ICON with too many output bytes to fit the buffer succeeded")
3016 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 0"):
3017 raise Exception("GET_HS20_ICON 0..0 succeeded")
3022 raise Exception("Unexpectedly long icon")
3023 res
= dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo %d 1000" % pos
)
3024 if res
.startswith("FAIL"):
3026 icon
+= base64
.b64decode(res
)
3028 hex = binascii
.hexlify(icon
).decode()
3029 if not hex.startswith("0009696d6167652f706e677d1d"):
3030 raise Exception("Unexpected beacon binary header: " + hex)
3031 with
open('w1fi_logo.png', 'rb') as f
:
3033 if icon
[13:] != data
:
3034 raise Exception("Unexpected icon data")
3035 if len(icon
) != int(event_icon_len
):
3036 raise Exception("Unexpected RX-HS20-ICON event length: " + event_icon_len
)
3039 if "OK" not in dev
[i
].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3040 raise Exception("REQ_HS20_ICON failed [2]")
3042 ev
= dev
[i
].wait_event(["RX-HS20-ICON"], timeout
=5)
3044 raise Exception("Timeout on RX-HS20-ICON [2]")
3046 if "FAIL" not in dev
[2].request("DEL_HS20_ICON foo w1fi_logo"):
3047 raise Exception("Invalid DEL_HS20_ICON accepted")
3048 if "OK" not in dev
[2].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3049 raise Exception("DEL_HS20_ICON failed")
3050 if "OK" not in dev
[1].request("DEL_HS20_ICON " + bssid
):
3051 raise Exception("DEL_HS20_ICON failed")
3052 if "OK" not in dev
[0].request("DEL_HS20_ICON "):
3053 raise Exception("DEL_HS20_ICON failed")
3055 if "FAIL" not in dev
[i
].request("DEL_HS20_ICON "):
3056 raise Exception("DEL_HS20_ICON accepted when no icons left")
3058 def test_ap_hs20_fetch_osu_no_info(dev
, apdev
):
3059 """Hotspot 2.0 OSU provider and no AP with info"""
3060 bssid
= apdev
[0]['bssid']
3061 params
= hs20_ap_params()
3062 hostapd
.add_ap(apdev
[0], params
)
3064 dev
[0].hs20_enable()
3065 dir = "/tmp/osu-fetch"
3066 if os
.path
.isdir(dir):
3067 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3069 os
.remove(dir + "/" + f
)
3075 dev
[0].scan_for_bss(bssid
, freq
="2412")
3077 dev
[0].request("SET osu_dir " + dir)
3078 dev
[0].request("FETCH_OSU")
3079 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3081 raise Exception("Timeout on OSU fetch")
3083 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3085 os
.remove(dir + "/" + f
)
3088 def test_ap_hs20_fetch_osu_no_icon(dev
, apdev
):
3089 """Hotspot 2.0 OSU provider and no icon found"""
3090 bssid
= apdev
[0]['bssid']
3091 params
= hs20_ap_params()
3092 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3093 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3094 params
['osu_method_list'] = "1"
3095 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3096 params
['osu_icon'] = "w1fi_logo"
3097 params
['osu_service_desc'] = ["eng:Example services",
3098 "fin:Esimerkkipalveluja"]
3099 params
['osu_server_uri'] = "https://example.com/osu/"
3100 hostapd
.add_ap(apdev
[0], params
)
3102 dev
[0].hs20_enable()
3103 dir = "/tmp/osu-fetch"
3104 if os
.path
.isdir(dir):
3105 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3107 os
.remove(dir + "/" + f
)
3113 dev
[0].scan_for_bss(bssid
, freq
="2412")
3115 dev
[0].request("SET osu_dir " + dir)
3116 dev
[0].request("FETCH_OSU")
3117 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3119 raise Exception("Timeout on OSU fetch")
3121 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3123 os
.remove(dir + "/" + f
)
3126 def test_ap_hs20_fetch_osu_single_ssid(dev
, apdev
):
3127 """Hotspot 2.0 OSU provider and single SSID"""
3128 bssid
= apdev
[0]['bssid']
3129 params
= hs20_ap_params()
3130 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3131 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3132 params
['osu_method_list'] = "1"
3133 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3134 params
['osu_nai2'] = "osen@example.com"
3135 params
['osu_icon'] = "w1fi_logo"
3136 params
['osu_service_desc'] = ["eng:Example services",
3137 "fin:Esimerkkipalveluja"]
3138 params
['osu_server_uri'] = "https://example.com/osu/"
3139 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
3140 hostapd
.add_ap(apdev
[0], params
)
3142 dev
[0].hs20_enable()
3143 dir = "/tmp/osu-fetch"
3144 if os
.path
.isdir(dir):
3145 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3147 os
.remove(dir + "/" + f
)
3153 dev
[0].scan_for_bss(bssid
, freq
="2412")
3155 dev
[0].request("SET osu_dir " + dir)
3156 dev
[0].request("FETCH_OSU")
3157 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3159 raise Exception("Timeout on OSU fetch")
3164 with
open(os
.path
.join(dir, "osu-providers.txt"), "r") as f
:
3165 for l
in f
.readlines():
3166 logger
.info(l
.strip())
3167 if l
.strip() == "osu_ssid=HS 2.0 OSU open":
3169 if l
.strip() == "osu_ssid2=test-hs20":
3171 if l
.strip().startswith("osu_nai="):
3173 if l
.strip() == "osu_nai2=osen@example.com":
3176 raise Exception("osu_ssid not reported")
3178 raise Exception("osu_ssid2 not reported")
3180 raise Exception("osu_nai reported unexpectedly")
3182 raise Exception("osu_nai2 not reported")
3184 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3186 os
.remove(dir + "/" + f
)
3189 def test_ap_hs20_fetch_osu_single_ssid2(dev
, apdev
):
3190 """Hotspot 2.0 OSU provider and single SSID (two OSU providers)"""
3191 bssid
= apdev
[0]['bssid']
3192 params
= hs20_ap_params()
3193 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3194 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3195 params
['osu_method_list'] = "1"
3196 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3197 params
['osu_nai2'] = "osen@example.com"
3198 params
['osu_icon'] = "w1fi_logo"
3199 params
['osu_service_desc'] = ["eng:Example services",
3200 "fin:Esimerkkipalveluja"]
3201 params
['osu_server_uri'] = "https://example.com/osu/"
3202 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
3203 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
3205 hapd
.set('osu_server_uri', 'https://another.example.com/osu/')
3206 hapd
.set('osu_method_list', "1")
3207 hapd
.set('osu_nai2', "osen@another.example.com")
3210 dev
[0].hs20_enable()
3211 dir = "/tmp/osu-fetch"
3212 if os
.path
.isdir(dir):
3213 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3215 os
.remove(dir + "/" + f
)
3221 dev
[0].scan_for_bss(bssid
, freq
="2412")
3223 dev
[0].request("SET osu_dir " + dir)
3224 dev
[0].request("FETCH_OSU")
3225 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3227 raise Exception("Timeout on OSU fetch")
3233 with
open(os
.path
.join(dir, "osu-providers.txt"), "r") as f
:
3234 for l
in f
.readlines():
3235 logger
.info(l
.strip())
3236 if l
.strip() == "osu_ssid=HS 2.0 OSU open":
3238 if l
.strip() == "osu_ssid2=test-hs20":
3240 if l
.strip().startswith("osu_nai="):
3242 if l
.strip() == "osu_nai2=osen@example.com":
3244 if l
.strip() == "osu_nai2=osen@another.example.com":
3247 raise Exception("osu_ssid not reported")
3249 raise Exception("osu_ssid2 not reported")
3251 raise Exception("osu_nai reported unexpectedly")
3253 raise Exception("osu_nai2 not reported")
3255 raise Exception("osu_nai2b not reported")
3257 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3259 os
.remove(dir + "/" + f
)
3262 def get_icon(dev
, bssid
, iconname
):
3267 raise Exception("Unexpectedly long icon")
3268 res
= dev
.request("GET_HS20_ICON " + bssid
+ " " + iconname
+ " %d 3000" % pos
)
3269 if res
.startswith("FAIL"):
3271 icon
+= base64
.b64decode(res
)
3274 raise Exception("Too short GET_HS20_ICON response")
3275 return icon
[0:13], icon
[13:]
3277 def test_ap_hs20_req_hs20_icon(dev
, apdev
):
3278 """Hotspot 2.0 OSU provider and multi-icon fetch with REQ_HS20_ICON"""
3279 bssid
= apdev
[0]['bssid']
3280 params
= hs20_ap_params()
3281 params
['hs20_icon'] = ["128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3282 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem"]
3283 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3284 params
['osu_method_list'] = "1"
3285 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3286 params
['osu_icon'] = ["w1fi_logo", "w1fi_logo2"]
3287 params
['osu_service_desc'] = ["eng:Example services",
3288 "fin:Esimerkkipalveluja"]
3289 params
['osu_server_uri'] = "https://example.com/osu/"
3290 hostapd
.add_ap(apdev
[0], params
)
3292 dev
[0].scan_for_bss(bssid
, freq
="2412")
3293 run_req_hs20_icon(dev
, bssid
)
3295 def run_req_hs20_icon(dev
, bssid
):
3296 # First, fetch two icons from the AP to wpa_supplicant
3298 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3299 raise Exception("REQ_HS20_ICON failed")
3300 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3302 raise Exception("Timeout on RX-HS20-ICON (1)")
3304 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_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 (2)")
3310 # Then, fetch the icons from wpa_supplicant for validation
3312 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
3313 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
3315 with
open('w1fi_logo.png', 'rb') as f
:
3318 raise Exception("Unexpected icon data (1)")
3320 with
open('auth_serv/sha512-server.pem', 'rb') as f
:
3323 raise Exception("Unexpected icon data (2)")
3325 # Finally, delete the icons from wpa_supplicant
3327 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3328 raise Exception("DEL_HS20_ICON failed")
3329 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
3330 raise Exception("DEL_HS20_ICON failed")
3332 def test_ap_hs20_req_operator_icon(dev
, apdev
):
3333 """Hotspot 2.0 operator icons"""
3334 bssid
= apdev
[0]['bssid']
3335 params
= hs20_ap_params()
3336 params
['hs20_icon'] = ["128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3337 "500:300:fi:image/png:test_logo:auth_serv/sha512-server.pem"]
3338 params
['operator_icon'] = ["w1fi_logo", "unknown_logo", "test_logo"]
3339 hostapd
.add_ap(apdev
[0], params
)
3341 value
= struct
.pack('<HH', 128, 80) + b
"zxx"
3342 value
+= struct
.pack('B', 9) + b
"image/png"
3343 value
+= struct
.pack('B', 9) + b
"w1fi_logo"
3345 value
+= struct
.pack('<HH', 500, 300) + b
"fi\0"
3346 value
+= struct
.pack('B', 9) + b
"image/png"
3347 value
+= struct
.pack('B', 9) + b
"test_logo"
3349 dev
[0].scan_for_bss(bssid
, freq
="2412")
3351 if "OK" not in dev
[0].request("ANQP_GET " + bssid
+ " hs20:12"):
3352 raise Exception("ANQP_GET command failed")
3354 ev
= dev
[0].wait_event(["GAS-QUERY-START"], timeout
=5)
3356 raise Exception("GAS query start timed out")
3358 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
3360 raise Exception("GAS query timed out")
3362 ev
= dev
[0].wait_event(["RX-HS20-ANQP"], timeout
=1)
3363 if ev
is None or "Operator Icon Metadata" not in ev
:
3364 raise Exception("Did not receive Operator Icon Metadata")
3366 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=10)
3368 raise Exception("ANQP-QUERY-DONE event not seen")
3369 if "result=SUCCESS" not in ev
:
3370 raise Exception("Unexpected result: " + ev
)
3372 bss
= dev
[0].get_bss(bssid
)
3373 if "hs20_operator_icon_metadata" not in bss
:
3374 raise Exception("hs20_operator_icon_metadata missing from BSS entry")
3375 if bss
["hs20_operator_icon_metadata"] != binascii
.hexlify(value
).decode():
3376 raise Exception("Unexpected hs20_operator_icon_metadata value: " +
3377 bss
["hs20_operator_icon_metadata"])
3379 run_req_hs20_icon(dev
, bssid
)
3381 def test_ap_hs20_req_hs20_icon_oom(dev
, apdev
):
3382 """Hotspot 2.0 icon fetch OOM with REQ_HS20_ICON"""
3383 bssid
= apdev
[0]['bssid']
3384 params
= hs20_ap_params()
3385 params
['hs20_icon'] = ["128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3386 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem"]
3387 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3388 params
['osu_method_list'] = "1"
3389 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3390 params
['osu_icon'] = ["w1fi_logo", "w1fi_logo2"]
3391 params
['osu_service_desc'] = ["eng:Example services",
3392 "fin:Esimerkkipalveluja"]
3393 params
['osu_server_uri'] = "https://example.com/osu/"
3394 hostapd
.add_ap(apdev
[0], params
)
3396 dev
[0].scan_for_bss(bssid
, freq
="2412")
3398 if "FAIL" not in dev
[0].request("REQ_HS20_ICON 11:22:33:44:55:66 w1fi_logo"):
3399 raise Exception("REQ_HS20_ICON succeeded with unknown BSSID")
3401 with
alloc_fail(dev
[0], 1, "hs20_build_anqp_req;hs20_anqp_send_req"):
3402 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3403 raise Exception("REQ_HS20_ICON succeeded during OOM")
3405 with
alloc_fail(dev
[0], 1, "gas_query_req;hs20_anqp_send_req"):
3406 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3407 raise Exception("REQ_HS20_ICON succeeded during OOM")
3409 with
alloc_fail(dev
[0], 1, "=hs20_anqp_send_req"):
3410 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3411 raise Exception("REQ_HS20_ICON succeeded during OOM")
3412 with
alloc_fail(dev
[0], 2, "=hs20_anqp_send_req"):
3413 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3414 raise Exception("REQ_HS20_ICON succeeded during OOM")
3416 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3417 raise Exception("REQ_HS20_ICON failed")
3418 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3420 raise Exception("Timeout on RX-HS20-ICON (1)")
3422 with
alloc_fail(dev
[0], 1, "hs20_get_icon"):
3423 if "FAIL" not in dev
[0].request("GET_HS20_ICON " + bssid
+ "w1fi_logo 0 100"):
3424 raise Exception("GET_HS20_ICON succeeded during OOM")
3426 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3427 raise Exception("DEL_HS20_ICON failed")
3429 with
alloc_fail(dev
[0], 1, "=hs20_process_icon_binary_file"):
3430 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3431 raise Exception("REQ_HS20_ICON failed")
3432 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
3434 def test_ap_hs20_req_hs20_icon_parallel(dev
, apdev
):
3435 """Hotspot 2.0 OSU provider and multi-icon parallel fetch with REQ_HS20_ICON"""
3436 bssid
= apdev
[0]['bssid']
3437 params
= hs20_ap_params()
3438 params
['hs20_icon'] = ["128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3439 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem"]
3440 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3441 params
['osu_method_list'] = "1"
3442 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3443 params
['osu_icon'] = ["w1fi_logo", "w1fi_logo2"]
3444 params
['osu_service_desc'] = ["eng:Example services",
3445 "fin:Esimerkkipalveluja"]
3446 params
['osu_server_uri'] = "https://example.com/osu/"
3447 hostapd
.add_ap(apdev
[0], params
)
3449 dev
[0].scan_for_bss(bssid
, freq
="2412")
3451 # First, fetch two icons from the AP to wpa_supplicant
3453 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3454 raise Exception("REQ_HS20_ICON failed")
3456 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
3457 raise Exception("REQ_HS20_ICON failed")
3458 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3460 raise Exception("Timeout on RX-HS20-ICON (1)")
3461 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3463 raise Exception("Timeout on RX-HS20-ICON (2)")
3465 # Then, fetch the icons from wpa_supplicant for validation
3467 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
3468 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
3470 with
open('w1fi_logo.png', 'rb') as f
:
3473 raise Exception("Unexpected icon data (1)")
3475 with
open('auth_serv/sha512-server.pem', 'rb') as f
:
3478 raise Exception("Unexpected icon data (2)")
3480 # Finally, delete the icons from wpa_supplicant
3482 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3483 raise Exception("DEL_HS20_ICON failed")
3484 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
3485 raise Exception("DEL_HS20_ICON failed")
3487 def test_ap_hs20_fetch_osu_stop(dev
, apdev
):
3488 """Hotspot 2.0 OSU provider fetch stopped"""
3489 bssid
= apdev
[0]['bssid']
3490 params
= hs20_ap_params()
3491 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3492 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3493 params
['osu_method_list'] = "1"
3494 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3495 params
['osu_icon'] = "w1fi_logo"
3496 params
['osu_service_desc'] = ["eng:Example services",
3497 "fin:Esimerkkipalveluja"]
3498 params
['osu_server_uri'] = "https://example.com/osu/"
3499 hapd
= hostapd
.add_ap(apdev
[0], params
)
3501 dev
[0].hs20_enable()
3502 dir = "/tmp/osu-fetch"
3503 if os
.path
.isdir(dir):
3504 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3506 os
.remove(dir + "/" + f
)
3513 dev
[0].request("SET osu_dir " + dir)
3514 dev
[0].request("SCAN freq=2412-2462")
3515 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=10)
3517 raise Exception("Scan did not start")
3518 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3519 raise Exception("FETCH_OSU accepted while scanning")
3520 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
3522 raise Exception("Scan timed out")
3523 hapd
.set("ext_mgmt_frame_handling", "1")
3524 dev
[0].request("FETCH_ANQP")
3525 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3526 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
3527 dev
[0].request("STOP_FETCH_ANQP")
3528 dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=5)
3529 dev
[0].dump_monitor()
3531 dev
[0].request("INTERWORKING_SELECT freq=2412")
3533 msg
= hapd
.mgmt_rx()
3534 if msg
['subtype'] == 13:
3536 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3537 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
3538 ev
= dev
[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
3541 raise Exception("Network selection timed out")
3543 dev
[0].dump_monitor()
3544 if "OK" not in dev
[0].request("FETCH_OSU"):
3545 raise Exception("FETCH_OSU failed")
3546 dev
[0].request("CANCEL_FETCH_OSU")
3550 if dev
[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
3553 dev
[0].dump_monitor()
3554 if "OK" not in dev
[0].request("FETCH_OSU"):
3555 raise Exception("FETCH_OSU failed")
3556 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3557 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
3558 ev
= dev
[0].wait_event(["GAS-QUERY-START"], 10)
3560 raise Exception("GAS timed out")
3561 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3562 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
3563 dev
[0].request("CANCEL_FETCH_OSU")
3564 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], 10)
3566 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
3568 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3570 os
.remove(dir + "/" + f
)
3573 def test_ap_hs20_fetch_osu_proto(dev
, apdev
):
3574 """Hotspot 2.0 OSU provider and protocol testing"""
3575 bssid
= apdev
[0]['bssid']
3576 params
= hs20_ap_params()
3577 hapd
= hostapd
.add_ap(apdev
[0], params
)
3579 dev
[0].hs20_enable()
3580 dir = "/tmp/osu-fetch"
3581 if os
.path
.isdir(dir):
3582 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3584 os
.remove(dir + "/" + f
)
3591 tests
= [("Empty provider list (no OSU SSID field)", b
''),
3592 ("HS 2.0: Not enough room for OSU SSID",
3593 binascii
.unhexlify('01')),
3594 ("HS 2.0: Invalid OSU SSID Length 33",
3595 binascii
.unhexlify('21') + 33*b
'A'),
3596 ("HS 2.0: Not enough room for Number of OSU Providers",
3597 binascii
.unhexlify('0130')),
3598 ("Truncated OSU Provider",
3599 binascii
.unhexlify('013001020000')),
3600 ("HS 2.0: Ignored 5 bytes of extra data after OSU Providers",
3601 binascii
.unhexlify('0130001122334455')),
3602 ("HS 2.0: Not enough room for OSU Friendly Name Length",
3603 binascii
.unhexlify('013001000000')),
3604 ("HS 2.0: Not enough room for OSU Friendly Name Duples",
3605 build_prov('0100')),
3606 ("Invalid OSU Friendly Name", build_prov('040000000000')),
3607 ("Invalid OSU Friendly Name(2)", build_prov('040004000000')),
3608 ("HS 2.0: Not enough room for OSU Server URI length",
3609 build_prov('0000')),
3610 ("HS 2.0: Not enough room for OSU Server URI",
3611 build_prov('000001')),
3612 ("HS 2.0: Not enough room for OSU Method list length",
3613 build_prov('000000')),
3614 ("HS 2.0: Not enough room for OSU Method list",
3615 build_prov('00000001')),
3616 ("HS 2.0: Not enough room for Icons Available Length",
3617 build_prov('00000000')),
3618 ("HS 2.0: Not enough room for Icons Available Length(2)",
3619 build_prov('00000001ff00')),
3620 ("HS 2.0: Not enough room for Icons Available",
3621 build_prov('000000000100')),
3622 ("HS 2.0: Invalid Icon Metadata",
3623 build_prov('00000000010000')),
3624 ("HS 2.0: Not room for Icon Type",
3625 build_prov('000000000900111122223333330200')),
3626 ("HS 2.0: Not room for Icon Filename length",
3627 build_prov('000000000900111122223333330100')),
3628 ("HS 2.0: Not room for Icon Filename",
3629 build_prov('000000000900111122223333330001')),
3630 ("HS 2.0: Not enough room for OSU_NAI",
3631 build_prov('000000000000')),
3632 ("HS 2.0: Not enough room for OSU_NAI(2)",
3633 build_prov('00000000000001')),
3634 ("HS 2.0: Not enough room for OSU Service Description Length",
3635 build_prov('00000000000000')),
3636 ("HS 2.0: Not enough room for OSU Service Description Length(2)",
3637 build_prov('0000000000000000')),
3638 ("HS 2.0: Not enough room for OSU Service Description Duples",
3639 build_prov('000000000000000100')),
3640 ("Invalid OSU Service Description",
3641 build_prov('00000000000000040000000000')),
3642 ("Invalid OSU Service Description(2)",
3643 build_prov('00000000000000040004000000'))]
3646 dev
[0].request("SET osu_dir " + dir)
3647 run_fetch_osu_icon_failure(hapd
, dev
, bssid
)
3648 for note
, prov
in tests
:
3649 run_fetch_osu(hapd
, dev
, bssid
, note
, prov
)
3651 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3653 os
.remove(dir + "/" + f
)
3656 def test_ap_hs20_fetch_osu_invalid_dir(dev
, apdev
):
3657 """Hotspot 2.0 OSU provider and invalid directory"""
3658 bssid
= apdev
[0]['bssid']
3659 params
= hs20_ap_params()
3660 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3661 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3662 params
['osu_method_list'] = "1"
3663 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3664 params
['osu_icon'] = "w1fi_logo"
3665 params
['osu_service_desc'] = ["eng:Example services",
3666 "fin:Esimerkkipalveluja"]
3667 params
['osu_server_uri'] = "https://example.com/osu/"
3668 hostapd
.add_ap(apdev
[0], params
)
3670 dev
[0].hs20_enable()
3671 dir = "/tmp/osu-fetch-no-such-dir"
3672 dev
[0].scan_for_bss(bssid
, freq
="2412")
3673 dev
[0].request("SET osu_dir " + dir)
3674 dev
[0].request("FETCH_OSU no-scan")
3675 ev
= dev
[0].wait_event(["Could not write OSU provider information"],
3678 raise Exception("Timeout on OSU fetch")
3680 def test_ap_hs20_fetch_osu_oom(dev
, apdev
):
3681 """Hotspot 2.0 OSU provider and OOM"""
3682 bssid
= apdev
[0]['bssid']
3683 params
= hs20_ap_params()
3684 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3685 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3686 params
['osu_method_list'] = "1"
3687 params
['osu_friendly_name'] = ["eng:Test OSU", "fin:Testi-OSU"]
3688 params
['osu_icon'] = "w1fi_logo"
3689 params
['osu_service_desc'] = ["eng:Example services",
3690 "fin:Esimerkkipalveluja"]
3691 params
['osu_server_uri'] = "https://example.com/osu/"
3692 hostapd
.add_ap(apdev
[0], params
)
3694 dev
[0].hs20_enable()
3695 dir = "/tmp/osu-fetch"
3696 if os
.path
.isdir(dir):
3697 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3699 os
.remove(dir + "/" + f
)
3705 dev
[0].scan_for_bss(bssid
, freq
="2412")
3707 dev
[0].request("SET osu_dir " + dir)
3708 with
alloc_fail(dev
[0], 1, "=hs20_osu_add_prov"):
3709 dev
[0].request("FETCH_OSU no-scan")
3710 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3712 raise Exception("Timeout on OSU fetch")
3713 with
alloc_fail(dev
[0], 1, "hs20_anqp_send_req;hs20_next_osu_icon"):
3714 dev
[0].request("FETCH_OSU no-scan")
3715 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3717 raise Exception("Timeout on OSU fetch")
3719 files
= [f
for f
in os
.listdir(dir) if f
.startswith("osu-")]
3721 os
.remove(dir + "/" + f
)
3724 def build_prov(prov
):
3725 data
= binascii
.unhexlify(prov
)
3726 return binascii
.unhexlify('013001') + struct
.pack('<H', len(data
)) + data
3728 def handle_osu_prov_fetch(hapd
, dev
, prov
):
3729 # GAS/ANQP query for OSU Providers List
3730 query
= gas_rx(hapd
)
3731 gas
= parse_gas(query
['payload'])
3732 dialog_token
= gas
['dialog_token']
3734 resp
= action_response(query
)
3735 osu_prov
= struct
.pack('<HH', 0xdddd, len(prov
) + 6) + binascii
.unhexlify('506f9a110800') + prov
3736 data
= struct
.pack('<H', len(osu_prov
)) + osu_prov
3737 resp
['payload'] = anqp_initial_resp(dialog_token
, 0) + data
3738 send_gas_resp(hapd
, resp
)
3740 ev
= dev
[0].wait_event(["RX-HS20-ANQP"], timeout
=5)
3742 raise Exception("ANQP query response for OSU Providers not received")
3743 if "OSU Providers list" not in ev
:
3744 raise Exception("ANQP query response for OSU Providers not received(2)")
3745 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
3747 raise Exception("ANQP query for OSU Providers list not completed")
3749 def start_osu_fetch(hapd
, dev
, bssid
, note
):
3750 hapd
.set("ext_mgmt_frame_handling", "0")
3751 dev
[0].request("BSS_FLUSH 0")
3752 dev
[0].scan_for_bss(bssid
, freq
="2412")
3753 hapd
.set("ext_mgmt_frame_handling", "1")
3754 dev
[0].dump_monitor()
3755 dev
[0].request("NOTE " + note
)
3756 dev
[0].request("FETCH_OSU no-scan")
3758 def wait_osu_fetch_completed(dev
):
3759 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=5)
3761 raise Exception("Timeout on OSU fetch")
3763 def run_fetch_osu_icon_failure(hapd
, dev
, bssid
):
3764 start_osu_fetch(hapd
, dev
, bssid
, "Icon fetch failure")
3766 prov
= binascii
.unhexlify('01ff' + '01' + '800019000b656e6754657374204f53550c66696e54657374692d4f53551868747470733a2f2f6578616d706c652e636f6d2f6f73752f01011b00800050007a787809696d6167652f706e6709773166695f6c6f676f002a0013656e674578616d706c652073657276696365731566696e4573696d65726b6b6970616c76656c756a61')
3767 handle_osu_prov_fetch(hapd
, dev
, prov
)
3769 # GAS/ANQP query for icon
3770 query
= gas_rx(hapd
)
3771 gas
= parse_gas(query
['payload'])
3772 dialog_token
= gas
['dialog_token']
3774 resp
= action_response(query
)
3775 # Unexpected Advertisement Protocol in response
3776 adv_proto
= struct
.pack('8B', 108, 6, 127, 0xdd, 0x00, 0x11, 0x22, 0x33)
3777 data
= struct
.pack('<H', 0)
3778 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
3779 GAS_INITIAL_RESPONSE
,
3780 gas
['dialog_token'], 0, 0) + adv_proto
+ data
3781 send_gas_resp(hapd
, resp
)
3783 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
3785 raise Exception("ANQP query for icon not completed")
3787 wait_osu_fetch_completed(dev
)
3789 def run_fetch_osu(hapd
, dev
, bssid
, note
, prov
):
3790 start_osu_fetch(hapd
, dev
, bssid
, note
)
3791 handle_osu_prov_fetch(hapd
, dev
, prov
)
3792 wait_osu_fetch_completed(dev
)
3794 def test_ap_hs20_ft(dev
, apdev
):
3795 """Hotspot 2.0 connection with FT"""
3796 check_eap_capa(dev
[0], "MSCHAPV2")
3797 bssid
= apdev
[0]['bssid']
3798 params
= hs20_ap_params()
3799 params
['wpa_key_mgmt'] = "FT-EAP"
3800 params
['nas_identifier'] = "nas1.w1.fi"
3801 params
['r1_key_holder'] = "000102030405"
3802 params
["mobility_domain"] = "a1b2"
3803 params
["reassociation_deadline"] = "1000"
3804 hapd
= hostapd
.add_ap(apdev
[0], params
)
3806 dev
[0].hs20_enable()
3807 id = dev
[0].add_cred_values({'realm': "example.com",
3808 'username': "hs20-test",
3809 'password': "password",
3810 'ca_cert': "auth_serv/ca.pem",
3811 'domain': "example.com",
3812 'update_identifier': "1234"})
3813 interworking_select(dev
[0], bssid
, "home", freq
="2412")
3814 interworking_connect(dev
[0], bssid
, "TTLS")
3815 dev
[0].dump_monitor()
3816 key_mgmt
= dev
[0].get_status_field("key_mgmt")
3817 if key_mgmt
!= "FT-EAP":
3818 raise Exception("Unexpected key_mgmt: " + key_mgmt
)
3819 # speed up testing by avoiding unnecessary scanning of other channels
3820 nid
= dev
[0].get_status_field("id")
3821 dev
[0].set_network(nid
, "scan_freq", "2412")
3823 params
= hs20_ap_params()
3824 hapd2
= hostapd
.add_ap(apdev
[1], params
)
3827 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=10)
3829 raise Exception("Disconnection not reported")
3830 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=5)
3832 raise Exception("Connection to AP2 not reported")
3833 key_mgmt
= dev
[0].get_status_field("key_mgmt")
3834 if key_mgmt
!= "WPA2/IEEE 802.1X/EAP":
3835 raise Exception("Unexpected key_mgmt: " + key_mgmt
)
3837 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
3838 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
3839 check_eap_capa(dev
[0], "MSCHAPV2")
3843 raise HwsimSkip("No sqlite3 module available")
3844 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
3849 con
= sqlite3
.connect(dbfile
)
3852 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
3853 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
3854 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
3855 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
3856 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
3859 params
= {"ssid": "as", "beacon_int": "2000",
3860 "radius_server_clients": "auth_serv/radius_clients.conf",
3861 "radius_server_auth_port": '18128',
3863 "eap_user_file": "sqlite:" + dbfile
,
3864 "ca_cert": "auth_serv/ca.pem",
3865 "server_cert": "auth_serv/server.pem",
3866 "private_key": "auth_serv/server.key",
3867 "subscr_remediation_url": "https://example.org/",
3868 "subscr_remediation_method": "1"}
3869 hostapd
.add_ap(apdev
[1], params
)
3871 bssid
= apdev
[0]['bssid']
3872 params
= hs20_ap_params()
3873 params
['auth_server_port'] = "18128"
3874 hostapd
.add_ap(apdev
[0], params
)
3876 dev
[0].request("SET pmf 1")
3877 dev
[0].hs20_enable()
3878 id = dev
[0].add_cred_values({'realm': "example.com",
3879 'username': "user-mschapv2",
3880 'password': "password",
3881 'ca_cert': "auth_serv/ca.pem"})
3882 interworking_select(dev
[0], bssid
, freq
="2412")
3883 interworking_connect(dev
[0], bssid
, "TTLS")
3884 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
3886 raise Exception("Timeout on subscription remediation notice")
3887 if " 1 https://example.org/" not in ev
:
3888 raise Exception("Unexpected subscription remediation event contents")
3892 cur
.execute("SELECT * from authlog")
3893 rows
= cur
.fetchall()
3895 raise Exception("No authlog entries")
3899 dev
[0].request("SET pmf 0")
3901 def test_ap_hs20_sim_provisioning(dev
, apdev
, params
):
3902 """Hotspot 2.0 AAA server behavior for SIM provisioning"""
3903 check_eap_capa(dev
[0], "SIM")
3907 raise HwsimSkip("No sqlite3 module available")
3908 dbfile
= os
.path
.join(params
['logdir'], "ap_hs20_sim_provisioning-eap-user.db")
3913 con
= sqlite3
.connect(dbfile
)
3916 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER, last_msk TEXT)")
3917 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
3918 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('1','SIM')")
3919 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
3920 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)")
3923 params
= {"ssid": "as", "beacon_int": "2000",
3924 "radius_server_clients": "auth_serv/radius_clients.conf",
3925 "radius_server_auth_port": '18128',
3927 "eap_user_file": "sqlite:" + dbfile
,
3928 "eap_sim_db": "unix:/tmp/hlr_auc_gw.sock",
3929 "ca_cert": "auth_serv/ca.pem",
3930 "server_cert": "auth_serv/server.pem",
3931 "private_key": "auth_serv/server.key",
3932 "hs20_sim_provisioning_url":
3933 "https://example.org/?hotspot2dot0-mobile-identifier-hash=",
3934 "subscr_remediation_method": "1"}
3935 hostapd
.add_ap(apdev
[1], params
)
3937 bssid
= apdev
[0]['bssid']
3938 params
= hs20_ap_params()
3939 params
['auth_server_port'] = "18128"
3940 hostapd
.add_ap(apdev
[0], params
)
3942 dev
[0].request("SET pmf 1")
3943 dev
[0].hs20_enable()
3944 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="SIM",
3946 identity
="1232010000000000",
3947 password
="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
3948 scan_freq
="2412", update_identifier
="54321")
3949 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=0.5)
3951 raise Exception("Unexpected subscription remediation notice")
3952 dev
[0].request("REMOVE_NETWORK all")
3953 dev
[0].wait_disconnected()
3954 dev
[0].dump_monitor()
3956 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="SIM",
3958 identity
="1232010000000000",
3959 password
="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
3960 scan_freq
="2412", update_identifier
="0")
3961 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
3963 raise Exception("Timeout on subscription remediation notice")
3964 if " 1 https://example.org/?hotspot2dot0-mobile-identifier-hash=" not in ev
:
3965 raise Exception("Unexpected subscription remediation event contents: " + ev
)
3966 id_hash
= ev
.split(' ')[2].split('=')[1]
3970 cur
.execute("SELECT * from authlog")
3971 rows
= cur
.fetchall()
3973 raise Exception("No authlog entries")
3977 cur
.execute("SELECT * from sim_provisioning")
3978 rows
= cur
.fetchall()
3980 raise Exeception("Unexpected number of rows in sim_provisioning (%d; expected %d)" % (len(rows
), 1))
3981 logger
.info("sim_provisioning: " + str(rows
))
3982 if len(rows
[0][0]) != 32:
3983 raise Exception("Unexpected mobile_identifier_hash length in DB")
3984 if rows
[0][1] != "232010000000000":
3985 raise Exception("Unexpected IMSI in DB")
3986 if rows
[0][2] != dev
[0].own_addr():
3987 raise Exception("Unexpected MAC address in DB")
3988 if rows
[0][0] != id_hash
:
3989 raise Exception("hotspot2dot0-mobile-identifier-hash mismatch")
3991 dev
[0].request("SET pmf 0")
3993 def test_ap_hs20_external_selection(dev
, apdev
):
3994 """Hotspot 2.0 connection using external network selection and creation"""
3995 check_eap_capa(dev
[0], "MSCHAPV2")
3996 bssid
= apdev
[0]['bssid']
3997 params
= hs20_ap_params()
3998 params
['hessid'] = bssid
3999 params
['disable_dgaf'] = '1'
4000 hostapd
.add_ap(apdev
[0], params
)
4002 dev
[0].hs20_enable()
4003 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
4005 identity
="hs20-test", password
="password",
4006 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
4007 scan_freq
="2412", update_identifier
="54321",
4008 roaming_consortium_selection
="1020304050")
4009 if dev
[0].get_status_field("hs20") != "3":
4010 raise Exception("Unexpected hs20 indication")
4011 network_id
= dev
[0].get_status_field("id")
4012 sel
= dev
[0].get_network(network_id
, "roaming_consortium_selection")
4013 if sel
!= "1020304050":
4014 raise Exception("Unexpected roaming_consortium_selection value: " + sel
)
4016 def test_ap_hs20_random_mac_addr(dev
, apdev
):
4017 """Hotspot 2.0 connection with random MAC address"""
4018 check_eap_capa(dev
[0], "MSCHAPV2")
4019 bssid
= apdev
[0]['bssid']
4020 params
= hs20_ap_params()
4021 params
['hessid'] = bssid
4022 params
['disable_dgaf'] = '1'
4023 hapd
= hostapd
.add_ap(apdev
[0], params
)
4025 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
4026 wpas
.interface_add("wlan5")
4027 addr
= wpas
.p2p_interface_addr()
4028 wpas
.request("SET mac_addr 1")
4029 wpas
.request("SET preassoc_mac_addr 1")
4030 wpas
.request("SET rand_addr_lifetime 60")
4032 wpas
.flush_scan_cache()
4033 id = wpas
.add_cred_values({'realm': "example.com",
4034 'username': "hs20-test",
4035 'password': "password",
4036 'ca_cert': "auth_serv/ca.pem",
4037 'domain': "example.com",
4038 'update_identifier': "1234"})
4039 interworking_select(wpas
, bssid
, "home", freq
="2412")
4040 interworking_connect(wpas
, bssid
, "TTLS")
4041 addr1
= wpas
.get_driver_status_field("addr")
4043 raise Exception("Did not use random MAC address")
4045 sta
= hapd
.get_sta(addr
)
4046 if sta
['addr'] != "FAIL":
4047 raise Exception("Unexpected STA association with permanent address")
4048 sta
= hapd
.get_sta(addr1
)
4049 if sta
['addr'] != addr1
:
4050 raise Exception("STA association with random address not found")
4052 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
4053 """Multiple networks and cred removal"""
4054 check_eap_capa(dev
[0], "MSCHAPV2")
4055 bssid
= apdev
[0]['bssid']
4056 params
= hs20_ap_params()
4057 params
['nai_realm'] = ["0,example.com,25[3:26]"]
4058 hapd
= hostapd
.add_ap(apdev
[0], params
)
4060 dev
[0].add_network()
4061 dev
[0].hs20_enable()
4062 id = dev
[0].add_cred_values({'realm': "example.com",
4064 'password': "password"})
4065 interworking_select(dev
[0], bssid
, freq
="2412")
4066 interworking_connect(dev
[0], bssid
, "PEAP")
4067 dev
[0].add_network()
4069 dev
[0].request("DISCONNECT")
4070 dev
[0].wait_disconnected(timeout
=10)
4073 hapd
.set("ssid", "another ssid")
4076 interworking_select(dev
[0], bssid
, freq
="2412")
4077 interworking_connect(dev
[0], bssid
, "PEAP")
4078 dev
[0].add_network()
4079 if len(dev
[0].list_networks()) != 5:
4080 raise Exception("Unexpected number of networks prior to remove_crec")
4082 dev
[0].dump_monitor()
4083 dev
[0].remove_cred(id)
4084 if len(dev
[0].list_networks()) != 3:
4085 raise Exception("Unexpected number of networks after to remove_crec")
4086 dev
[0].wait_disconnected(timeout
=10)
4088 def test_ap_hs20_interworking_add_network(dev
, apdev
):
4089 """Hotspot 2.0 connection using INTERWORKING_ADD_NETWORK"""
4090 check_eap_capa(dev
[0], "MSCHAPV2")
4091 bssid
= apdev
[0]['bssid']
4092 params
= hs20_ap_params()
4093 params
['nai_realm'] = ["0,example.com,21[3:26][6:7][99:99]"]
4094 hostapd
.add_ap(apdev
[0], params
)
4096 dev
[0].hs20_enable()
4097 dev
[0].add_cred_values(default_cred(user
="user"))
4098 interworking_select(dev
[0], bssid
, freq
=2412)
4099 id = dev
[0].interworking_add_network(bssid
)
4100 dev
[0].select_network(id, freq
=2412)
4101 dev
[0].wait_connected()
4103 def _test_ap_hs20_proxyarp(dev
, apdev
):
4104 bssid
= apdev
[0]['bssid']
4105 params
= hs20_ap_params()
4106 params
['hessid'] = bssid
4107 params
['disable_dgaf'] = '0'
4108 params
['proxy_arp'] = '1'
4109 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4110 if "OK" in hapd
.request("ENABLE"):
4111 raise Exception("Incomplete hostapd configuration was accepted")
4112 hapd
.set("ap_isolate", "1")
4113 if "OK" in hapd
.request("ENABLE"):
4114 raise Exception("Incomplete hostapd configuration was accepted")
4115 hapd
.set('bridge', 'ap-br0')
4120 # For now, do not report failures due to missing kernel support
4121 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4122 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4124 raise Exception("AP startup timed out")
4125 if "AP-ENABLED" not in ev
:
4126 raise Exception("AP startup failed")
4128 dev
[0].hs20_enable()
4129 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4130 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4132 id = dev
[0].add_cred_values({'realm': "example.com",
4133 'username': "hs20-test",
4134 'password': "password",
4135 'ca_cert': "auth_serv/ca.pem",
4136 'domain': "example.com",
4137 'update_identifier': "1234"})
4138 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4139 interworking_connect(dev
[0], bssid
, "TTLS")
4141 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
4142 identity
="hs20-test", password
="password",
4143 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
4147 addr0
= dev
[0].p2p_interface_addr()
4148 addr1
= dev
[1].p2p_interface_addr()
4150 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':', ''))
4151 src_ll_opt1
= b
"\x01\x01" + binascii
.unhexlify(addr1
.replace(':', ''))
4153 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
4154 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
4156 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4157 raise Exception("DATA_TEST_FRAME failed")
4159 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
4160 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
4162 if "OK" not in dev
[1].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:eeee::2",
4166 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
4168 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4169 raise Exception("DATA_TEST_FRAME failed")
4171 matches
= get_permanent_neighbors("ap-br0")
4172 logger
.info("After connect: " + str(matches
))
4173 if len(matches
) != 3:
4174 raise Exception("Unexpected number of neighbor entries after connect")
4175 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4176 raise Exception("dev0 addr missing")
4177 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
4178 raise Exception("dev1 addr(1) missing")
4179 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
4180 raise Exception("dev1 addr(2) missing")
4181 dev
[0].request("DISCONNECT")
4182 dev
[1].request("DISCONNECT")
4184 matches
= get_permanent_neighbors("ap-br0")
4185 logger
.info("After disconnect: " + str(matches
))
4186 if len(matches
) > 0:
4187 raise Exception("Unexpected neighbor entries after disconnect")
4189 def test_ap_hs20_hidden_ssid_in_scan_res(dev
, apdev
):
4190 """Hotspot 2.0 connection with hidden SSId in scan results"""
4191 check_eap_capa(dev
[0], "MSCHAPV2")
4192 bssid
= apdev
[0]['bssid']
4194 hapd
= hostapd
.add_ap(apdev
[0], {"ssid": 'secret',
4195 "ignore_broadcast_ssid": "1"})
4196 dev
[0].scan_for_bss(bssid
, freq
=2412)
4198 hapd_global
= hostapd
.HostapdGlobal(apdev
[0])
4200 hapd_global
.remove(apdev
[0]['ifname'])
4202 params
= hs20_ap_params()
4203 params
['hessid'] = bssid
4204 hapd
= hostapd
.add_ap(apdev
[0], params
)
4206 dev
[0].hs20_enable()
4207 id = dev
[0].add_cred_values({'realm': "example.com",
4208 'username': "hs20-test",
4209 'password': "password",
4210 'ca_cert': "auth_serv/ca.pem",
4211 'domain': "example.com"})
4212 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4213 interworking_connect(dev
[0], bssid
, "TTLS")
4215 # clear BSS table to avoid issues in following test cases
4216 dev
[0].request("DISCONNECT")
4217 dev
[0].wait_disconnected()
4219 dev
[0].flush_scan_cache()
4220 dev
[0].flush_scan_cache()
4222 def test_ap_hs20_proxyarp(dev
, apdev
):
4223 """Hotspot 2.0 and ProxyARP"""
4224 check_eap_capa(dev
[0], "MSCHAPV2")
4226 _test_ap_hs20_proxyarp(dev
, apdev
)
4228 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4229 stderr
=open('/dev/null', 'w'))
4230 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4231 stderr
=open('/dev/null', 'w'))
4233 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
4234 bssid
= apdev
[0]['bssid']
4235 params
= hs20_ap_params()
4236 params
['hessid'] = bssid
4237 params
['disable_dgaf'] = '1' if disabled
else '0'
4238 params
['proxy_arp'] = '1'
4239 params
['na_mcast_to_ucast'] = '1'
4240 params
['ap_isolate'] = '1'
4241 params
['bridge'] = 'ap-br0'
4242 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4246 # For now, do not report failures due to missing kernel support
4247 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4248 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
4250 raise Exception("AP startup timed out")
4252 dev
[0].hs20_enable()
4253 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4254 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4256 id = dev
[0].add_cred_values({'realm': "example.com",
4257 'username': "hs20-test",
4258 'password': "password",
4259 'ca_cert': "auth_serv/ca.pem",
4260 'domain': "example.com",
4261 'update_identifier': "1234"})
4262 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4263 interworking_connect(dev
[0], bssid
, "TTLS")
4265 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
4266 identity
="hs20-test", password
="password",
4267 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
4271 addr0
= dev
[0].p2p_interface_addr()
4273 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':', ''))
4275 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
4276 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
4278 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4279 raise Exception("DATA_TEST_FRAME failed")
4281 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
4283 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4284 raise Exception("DATA_TEST_FRAME failed")
4286 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
4287 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
4288 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4289 raise Exception("DATA_TEST_FRAME failed")
4291 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4292 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4293 yiaddr
="192.168.1.123", chaddr
=addr0
)
4294 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4295 raise Exception("DATA_TEST_FRAME failed")
4296 # another copy for additional code coverage
4297 pkt
= build_dhcp_ack(dst_ll
=addr0
, 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")
4303 matches
= get_permanent_neighbors("ap-br0")
4304 logger
.info("After connect: " + str(matches
))
4305 if len(matches
) != 2:
4306 raise Exception("Unexpected number of neighbor entries after connect")
4307 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4308 raise Exception("dev0 addr missing")
4309 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4310 raise Exception("dev0 IPv4 addr missing")
4311 dev
[0].request("DISCONNECT")
4312 dev
[1].request("DISCONNECT")
4314 matches
= get_permanent_neighbors("ap-br0")
4315 logger
.info("After disconnect: " + str(matches
))
4316 if len(matches
) > 0:
4317 raise Exception("Unexpected neighbor entries after disconnect")
4319 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
4320 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
4321 check_eap_capa(dev
[0], "MSCHAPV2")
4323 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
4325 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4326 stderr
=open('/dev/null', 'w'))
4327 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4328 stderr
=open('/dev/null', 'w'))
4330 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
4331 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
4332 check_eap_capa(dev
[0], "MSCHAPV2")
4334 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
4336 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4337 stderr
=open('/dev/null', 'w'))
4338 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4339 stderr
=open('/dev/null', 'w'))
4341 def ip_checksum(buf
):
4345 for i
in range(0, len(buf
), 2):
4346 val
, = struct
.unpack('H', buf
[i
:i
+2])
4349 sum = (sum & 0xffff) + (sum >> 16)
4350 return struct
.pack('H', ~
sum & 0xffff)
4352 def ipv6_solicited_node_mcaddr(target
):
4353 prefix
= socket
.inet_pton(socket
.AF_INET6
, "ff02::1:ff00:0")
4354 mask
= socket
.inet_pton(socket
.AF_INET6
, "::ff:ffff")
4355 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4356 p
= struct
.unpack('4I', prefix
)
4357 m
= struct
.unpack('4I', mask
)
4358 t
= struct
.unpack('4I', _target
)
4359 res
= (p
[0] |
(t
[0] & m
[0]),
4360 p
[1] |
(t
[1] & m
[1]),
4361 p
[2] |
(t
[2] & m
[2]),
4362 p
[3] |
(t
[3] & m
[3]))
4363 return socket
.inet_ntop(socket
.AF_INET6
, struct
.pack('4I', *res
))
4365 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
4366 start
= struct
.pack("BB", type, code
)
4368 icmp
= start
+ b
'\x00\x00' + end
4369 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
4370 csum
= ip_checksum(pseudo
+ icmp
)
4371 return start
+ csum
+ end
4373 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
4374 reachable_time
=0, retrans_timer
=0, opt
=None):
4375 link_mc
= binascii
.unhexlify("3333ff000002")
4376 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4378 ehdr
= link_mc
+ _src_ll
+ proto
4379 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4380 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4382 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
4383 reachable_time
, retrans_timer
)
4388 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
4390 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4391 ipv6
+= _ip_src
+ _ip_dst
4393 return ehdr
+ ipv6
+ icmp
4395 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
4396 link_mc
= binascii
.unhexlify("3333ff000002")
4397 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4399 ehdr
= link_mc
+ _src_ll
+ proto
4400 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4402 ip_dst
= ipv6_solicited_node_mcaddr(target
)
4403 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4405 reserved
= b
'\x00\x00\x00\x00'
4406 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4408 payload
= reserved
+ _target
+ opt
4410 payload
= reserved
+ _target
4411 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
4413 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4414 ipv6
+= _ip_src
+ _ip_dst
4416 return ehdr
+ ipv6
+ icmp
4418 def send_ns(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
4423 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4426 src_ll
= dev
.p2p_interface_addr()
4427 cmd
= "DATA_TEST_FRAME "
4430 opt
= b
"\x01\x01" + binascii
.unhexlify(src_ll
.replace(':', ''))
4432 pkt
= build_ns(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
4434 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4435 raise Exception("DATA_TEST_FRAME failed")
4437 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None, flags
=0):
4438 link_mc
= binascii
.unhexlify("3333ff000002")
4439 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4441 ehdr
= link_mc
+ _src_ll
+ proto
4442 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4443 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4445 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4447 payload
= struct
.pack('>Bxxx', flags
) + _target
+ opt
4449 payload
= struct
.pack('>Bxxx', flags
) + _target
4450 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
4452 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4453 ipv6
+= _ip_src
+ _ip_dst
4455 return ehdr
+ ipv6
+ icmp
4457 def send_na(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
4462 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4465 src_ll
= dev
.p2p_interface_addr()
4466 cmd
= "DATA_TEST_FRAME "
4468 pkt
= build_na(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
4470 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4471 raise Exception("DATA_TEST_FRAME failed")
4473 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
4474 subnet_mask
="255.255.255.0", truncated_opt
=False,
4475 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False,
4477 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':', ''))
4478 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4480 ehdr
= _dst_ll
+ _src_ll
+ proto
4481 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
4482 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
4483 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
4485 _ciaddr
= b
'\x00\x00\x00\x00'
4486 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
4487 _siaddr
= b
'\x00\x00\x00\x00'
4488 _giaddr
= b
'\x00\x00\x00\x00'
4489 _chaddr
= binascii
.unhexlify(chaddr
.replace(':', '') + "00000000000000000000")
4490 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
4491 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*b
'\x00'
4494 payload
+= b
'\x63\x82\x53\x00'
4496 payload
+= b
'\x63\x82\x53\x63'
4498 payload
+= b
'\x22\xff\x00'
4499 # Option: DHCP Message Type = ACK
4500 payload
+= b
'\x35\x01\x05'
4503 # Option: Subnet Mask
4504 payload
+= b
'\x01\x04' + _subnet_mask
4505 # Option: Time Offset
4506 payload
+= struct
.pack('>BBL', 2, 4, 0)
4510 payload
+= b
'\x00\x00\x00\x00'
4513 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
4514 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*b
'\x00'
4517 pseudohdr
= _ip_src
+ _ip_dst
+ struct
.pack('>BBH', 0, 17,
4519 udphdr
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0)
4520 checksum
, = struct
.unpack('>H', ip_checksum(pseudohdr
+ udphdr
+ payload
))
4523 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), checksum
) + payload
4526 tot_len
= force_tot_len
4528 tot_len
= 20 + len(udp
)
4529 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
4530 ipv4
= start
+ b
'\x00\x00' + _ip_src
+ _ip_dst
4531 csum
= ip_checksum(ipv4
)
4532 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
4534 return ehdr
+ ipv4
+ udp
4536 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
4537 target_mac
, target_ip
):
4538 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':', ''))
4539 _src_ll
= binascii
.unhexlify(src_ll
.replace(':', ''))
4541 ehdr
= _dst_ll
+ _src_ll
+ proto
4543 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':', ''))
4544 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
4545 _target_mac
= binascii
.unhexlify(target_mac
.replace(':', ''))
4546 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
4548 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
4549 arp
+= _sender_mac
+ _sender_ip
4550 arp
+= _target_mac
+ _target_ip
4554 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
4555 sender_mac
=None, sender_ip
="0.0.0.0",
4556 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
4561 if sender_mac
is None:
4562 sender_mac
= hapd_bssid
4563 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4566 src_ll
= dev
.p2p_interface_addr()
4567 if sender_mac
is None:
4568 sender_mac
= dev
.p2p_interface_addr()
4569 cmd
= "DATA_TEST_FRAME "
4571 pkt
= build_arp(dst_ll
=dst_ll
, src_ll
=src_ll
, opcode
=opcode
,
4572 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
4573 target_mac
=target_mac
, target_ip
=target_ip
)
4574 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4575 raise Exception("DATA_TEST_FRAME failed")
4577 def get_permanent_neighbors(ifname
):
4578 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
4579 res
= cmd
.stdout
.read().decode()
4581 return [line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
4583 def get_bridge_macs(ifname
):
4584 cmd
= subprocess
.Popen(['brctl', 'showmacs', ifname
],
4585 stdout
=subprocess
.PIPE
)
4586 res
= cmd
.stdout
.read()
4590 def tshark_get_arp(cap
, filter):
4591 res
= run_tshark(cap
, filter,
4592 ["eth.dst", "eth.src",
4593 "arp.src.hw_mac", "arp.src.proto_ipv4",
4594 "arp.dst.hw_mac", "arp.dst.proto_ipv4"],
4597 for l
in res
.splitlines():
4598 frames
.append(l
.split('\t'))
4601 def tshark_get_ns(cap
):
4602 res
= run_tshark(cap
, "icmpv6.type == 135",
4603 ["eth.dst", "eth.src",
4604 "ipv6.src", "ipv6.dst",
4605 "icmpv6.nd.ns.target_address",
4606 "icmpv6.opt.linkaddr"],
4609 for l
in res
.splitlines():
4610 frames
.append(l
.split('\t'))
4613 def tshark_get_na(cap
):
4614 res
= run_tshark(cap
, "icmpv6.type == 136",
4615 ["eth.dst", "eth.src",
4616 "ipv6.src", "ipv6.dst",
4617 "icmpv6.nd.na.target_address",
4618 "icmpv6.opt.linkaddr"],
4621 for l
in res
.splitlines():
4622 frames
.append(l
.split('\t'))
4625 def _test_proxyarp_open(dev
, apdev
, params
, ebtables
=False):
4626 prefix
= "proxyarp_open"
4628 prefix
+= "_ebtables"
4629 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
4630 cap_dev0
= os
.path
.join(params
['logdir'],
4631 prefix
+ ".%s.pcap" % dev
[0].ifname
)
4632 cap_dev1
= os
.path
.join(params
['logdir'],
4633 prefix
+ ".%s.pcap" % dev
[1].ifname
)
4634 cap_dev2
= os
.path
.join(params
['logdir'],
4635 prefix
+ ".%s.pcap" % dev
[2].ifname
)
4637 bssid
= apdev
[0]['bssid']
4638 params
= {'ssid': 'open'}
4639 params
['proxy_arp'] = '1'
4640 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4641 hapd
.set("ap_isolate", "1")
4642 hapd
.set('bridge', 'ap-br0')
4647 # For now, do not report failures due to missing kernel support
4648 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4649 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4651 raise Exception("AP startup timed out")
4652 if "AP-ENABLED" not in ev
:
4653 raise Exception("AP startup failed")
4655 params2
= {'ssid': 'another'}
4656 hapd2
= hostapd
.add_ap(apdev
[1], params2
, no_enable
=True)
4657 hapd2
.set('bridge', 'ap-br0')
4660 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4661 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4664 for chain
in ['FORWARD', 'OUTPUT']:
4666 subprocess
.call(['ebtables', '-A', chain
, '-p', 'ARP',
4667 '-d', 'Broadcast', '-o', apdev
[0]['ifname'],
4670 raise HwsimSkip("No ebtables available")
4674 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
4675 '-w', cap_br
, '-s', '2000'],
4676 stderr
=open('/dev/null', 'w'))
4677 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
4678 '-w', cap_dev0
, '-s', '2000'],
4679 stderr
=open('/dev/null', 'w'))
4680 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
4681 '-w', cap_dev1
, '-s', '2000'],
4682 stderr
=open('/dev/null', 'w'))
4683 cmd
[3] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[2].ifname
,
4684 '-w', cap_dev2
, '-s', '2000'],
4685 stderr
=open('/dev/null', 'w'))
4687 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
4688 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
4689 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
4692 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
4693 res
= brcmd
.stdout
.read().decode()
4694 brcmd
.stdout
.close()
4695 logger
.info("Bridge setup: " + res
)
4697 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
4698 stdout
=subprocess
.PIPE
)
4699 res
= brcmd
.stdout
.read().decode()
4700 brcmd
.stdout
.close()
4701 logger
.info("Bridge showstp: " + res
)
4703 addr0
= dev
[0].p2p_interface_addr()
4704 addr1
= dev
[1].p2p_interface_addr()
4705 addr2
= dev
[2].p2p_interface_addr()
4707 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4708 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4709 yiaddr
="192.168.1.124", chaddr
=addr0
)
4710 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4711 raise Exception("DATA_TEST_FRAME failed")
4712 # Change address and verify unicast
4713 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
4714 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4715 yiaddr
="192.168.1.123", chaddr
=addr0
,
4717 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4718 raise Exception("DATA_TEST_FRAME failed")
4720 # Not-associated client MAC address
4721 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4722 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4723 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
4724 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4725 raise Exception("DATA_TEST_FRAME failed")
4728 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4729 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4730 yiaddr
="0.0.0.0", chaddr
=addr1
)
4731 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4732 raise Exception("DATA_TEST_FRAME failed")
4735 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4736 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4737 yiaddr
="192.168.1.126", chaddr
=addr1
,
4738 subnet_mask
="0.0.0.0")
4739 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4740 raise Exception("DATA_TEST_FRAME failed")
4743 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4744 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4745 yiaddr
="192.168.1.127", chaddr
=addr1
,
4747 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4748 raise Exception("DATA_TEST_FRAME failed")
4751 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4752 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4753 yiaddr
="192.168.1.128", chaddr
=addr1
,
4755 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4756 raise Exception("DATA_TEST_FRAME failed")
4758 # Wrong IPv4 total length
4759 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4760 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4761 yiaddr
="192.168.1.129", chaddr
=addr1
,
4763 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4764 raise Exception("DATA_TEST_FRAME failed")
4767 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4768 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4769 yiaddr
="192.168.1.129", chaddr
=addr1
,
4771 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4772 raise Exception("DATA_TEST_FRAME failed")
4774 macs
= get_bridge_macs("ap-br0")
4775 logger
.info("After connect (showmacs): " + str(macs
))
4777 matches
= get_permanent_neighbors("ap-br0")
4778 logger
.info("After connect: " + str(matches
))
4779 if len(matches
) != 1:
4780 raise Exception("Unexpected number of neighbor entries after connect")
4781 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4782 raise Exception("dev0 IPv4 addr missing")
4784 targets
= ["192.168.1.123", "192.168.1.124", "192.168.1.125",
4786 for target
in targets
:
4787 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
4789 for target
in targets
:
4790 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
4793 for target
in targets
:
4794 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
=target
)
4796 # ARP Probe from wireless STA
4797 send_arp(dev
[1], target_ip
="192.168.1.127")
4798 # ARP Announcement from wireless STA
4799 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
4800 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
4803 macs
= get_bridge_macs("ap-br0")
4804 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
4806 matches
= get_permanent_neighbors("ap-br0")
4807 logger
.info("After ARP Probe + Announcement: " + str(matches
))
4809 # ARP Request for the newly introduced IP address from wireless STA
4810 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
4812 # ARP Request for the newly introduced IP address from bridge
4813 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
4814 target_ip
="192.168.1.127")
4815 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
="192.168.1.127")
4817 # ARP Probe from bridge
4818 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.130")
4819 send_arp(dev
[2], target_ip
="192.168.1.131")
4820 # ARP Announcement from bridge (not to be learned by AP for proxyarp)
4821 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
4822 target_ip
="192.168.1.130")
4823 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
4824 target_ip
="192.168.1.130", opcode
=2)
4825 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131")
4826 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131",
4829 macs
= get_bridge_macs("ap-br0")
4830 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
4832 matches
= get_permanent_neighbors("ap-br0")
4833 logger
.info("After ARP Probe + Announcement: " + str(matches
))
4835 # ARP Request for the newly introduced IP address from wireless STA
4836 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.130")
4837 # ARP Response from bridge (AP does not proxy for non-wireless devices)
4838 send_arp(hapd
, hapd_bssid
=bssid
, dst_ll
=addr0
, sender_ip
="192.168.1.130",
4839 target_ip
="192.168.1.123", opcode
=2)
4841 # ARP Request for the newly introduced IP address from wireless STA
4842 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.131")
4843 # ARP Response from bridge (AP does not proxy for non-wireless devices)
4844 send_arp(dev
[2], dst_ll
=addr0
, sender_ip
="192.168.1.131",
4845 target_ip
="192.168.1.123", opcode
=2)
4847 # ARP Request for the newly introduced IP address from bridge
4848 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
4849 target_ip
="192.168.1.130")
4850 send_arp(dev
[2], sender_ip
="192.168.1.104", target_ip
="192.168.1.131")
4852 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
4853 send_arp(dev
[1], target_ip
="192.168.1.123")
4854 # ARP Probe from wireless STA (duplicate address; learned through ARP)
4855 send_arp(dev
[0], target_ip
="192.168.1.127")
4857 # Gratuitous ARP Reply for another STA's IP address
4858 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
4859 target_mac
=addr1
, target_ip
="192.168.1.127")
4860 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
4861 target_mac
=addr0
, target_ip
="192.168.1.123")
4862 # ARP Request to verify previous mapping
4863 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
4864 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
4867 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
4868 except Exception as e
:
4869 logger
.info("test_connectibity_iface failed: " + str(e
))
4870 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
4871 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
4872 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
4874 dev
[0].request("DISCONNECT")
4875 dev
[1].request("DISCONNECT")
4877 for i
in range(len(cmd
)):
4880 macs
= get_bridge_macs("ap-br0")
4881 logger
.info("After disconnect (showmacs): " + str(macs
))
4882 matches
= get_permanent_neighbors("ap-br0")
4883 logger
.info("After disconnect: " + str(matches
))
4884 if len(matches
) > 0:
4885 raise Exception("Unexpected neighbor entries after disconnect")
4887 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
4888 stdout
=subprocess
.PIPE
)
4889 res
= cmd
.stdout
.read().decode()
4891 logger
.info("ebtables results:\n" + res
)
4893 # Verify that expected ARP messages were seen and no unexpected
4894 # ARP messages were seen.
4896 arp_req
= tshark_get_arp(cap_dev0
, "arp.opcode == 1")
4897 arp_reply
= tshark_get_arp(cap_dev0
, "arp.opcode == 2")
4898 logger
.info("dev0 seen ARP requests:\n" + str(arp_req
))
4899 logger
.info("dev0 seen ARP replies:\n" + str(arp_reply
))
4901 if ['ff:ff:ff:ff:ff:ff', addr1
,
4902 addr1
, '192.168.1.100',
4903 '00:00:00:00:00:00', '192.168.1.123'] in arp_req
:
4904 raise Exception("dev0 saw ARP request from dev1")
4905 if ['ff:ff:ff:ff:ff:ff', addr2
,
4906 addr2
, '192.168.1.103',
4907 '00:00:00:00:00:00', '192.168.1.123'] in arp_req
:
4908 raise Exception("dev0 saw ARP request from dev2")
4909 # TODO: Uncomment once fixed in kernel
4910 #if ['ff:ff:ff:ff:ff:ff', bssid,
4911 # bssid, '192.168.1.101',
4912 # '00:00:00:00:00:00', '192.168.1.123'] in arp_req:
4913 # raise Exception("dev0 saw ARP request from br")
4918 raise Exception("Unexpected foreign ARP request on dev0")
4920 arp_req
= tshark_get_arp(cap_dev1
, "arp.opcode == 1")
4921 arp_reply
= tshark_get_arp(cap_dev1
, "arp.opcode == 2")
4922 logger
.info("dev1 seen ARP requests:\n" + str(arp_req
))
4923 logger
.info("dev1 seen ARP replies:\n" + str(arp_reply
))
4925 if ['ff:ff:ff:ff:ff:ff', addr2
,
4926 addr2
, '192.168.1.103',
4927 '00:00:00:00:00:00', '192.168.1.123'] in arp_req
:
4928 raise Exception("dev1 saw ARP request from dev2")
4929 if [addr1
, addr0
, addr0
, '192.168.1.123', addr1
, '192.168.1.100'] not in arp_reply
:
4930 raise Exception("dev1 did not get ARP response for 192.168.1.123")
4935 raise Exception("Unexpected foreign ARP request on dev1")
4937 arp_req
= tshark_get_arp(cap_dev2
, "arp.opcode == 1")
4938 arp_reply
= tshark_get_arp(cap_dev2
, "arp.opcode == 2")
4939 logger
.info("dev2 seen ARP requests:\n" + str(arp_req
))
4940 logger
.info("dev2 seen ARP replies:\n" + str(arp_reply
))
4943 addr0
, '192.168.1.123',
4944 addr2
, '192.168.1.103'] not in arp_reply
:
4945 raise Exception("dev2 did not get ARP response for 192.168.1.123")
4947 arp_req
= tshark_get_arp(cap_br
, "arp.opcode == 1")
4948 arp_reply
= tshark_get_arp(cap_br
, "arp.opcode == 2")
4949 logger
.info("br seen ARP requests:\n" + str(arp_req
))
4950 logger
.info("br seen ARP replies:\n" + str(arp_reply
))
4952 # TODO: Uncomment once fixed in kernel
4954 # addr0, '192.168.1.123',
4955 # bssid, '192.168.1.101'] not in arp_reply:
4956 # raise Exception("br did not get ARP response for 192.168.1.123")
4958 def _test_proxyarp_open_ipv6(dev
, apdev
, params
, ebtables
=False):
4959 prefix
= "proxyarp_open"
4961 prefix
+= "_ebtables"
4963 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
4964 cap_dev0
= os
.path
.join(params
['logdir'],
4965 prefix
+ ".%s.pcap" % dev
[0].ifname
)
4966 cap_dev1
= os
.path
.join(params
['logdir'],
4967 prefix
+ ".%s.pcap" % dev
[1].ifname
)
4968 cap_dev2
= os
.path
.join(params
['logdir'],
4969 prefix
+ ".%s.pcap" % dev
[2].ifname
)
4971 bssid
= apdev
[0]['bssid']
4972 params
= {'ssid': 'open'}
4973 params
['proxy_arp'] = '1'
4974 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4975 hapd
.set("ap_isolate", "1")
4976 hapd
.set('bridge', 'ap-br0')
4981 # For now, do not report failures due to missing kernel support
4982 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4983 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4985 raise Exception("AP startup timed out")
4986 if "AP-ENABLED" not in ev
:
4987 raise Exception("AP startup failed")
4989 params2
= {'ssid': 'another'}
4990 hapd2
= hostapd
.add_ap(apdev
[1], params2
, no_enable
=True)
4991 hapd2
.set('bridge', 'ap-br0')
4994 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4995 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4998 for chain
in ['FORWARD', 'OUTPUT']:
5000 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
5001 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5002 '--ip6-icmp-type', 'neighbor-solicitation',
5003 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5004 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
5005 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5006 '--ip6-icmp-type', 'neighbor-advertisement',
5007 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5008 subprocess
.call(['ebtables', '-A', chain
,
5009 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5010 '--ip6-icmp-type', 'router-solicitation',
5011 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5012 # Multicast Listener Report Message
5013 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
5014 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5015 '--ip6-icmp-type', '143',
5016 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5018 raise HwsimSkip("No ebtables available")
5022 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
5023 '-w', cap_br
, '-s', '2000'],
5024 stderr
=open('/dev/null', 'w'))
5025 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
5026 '-w', cap_dev0
, '-s', '2000'],
5027 stderr
=open('/dev/null', 'w'))
5028 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
5029 '-w', cap_dev1
, '-s', '2000'],
5030 stderr
=open('/dev/null', 'w'))
5031 cmd
[3] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[2].ifname
,
5032 '-w', cap_dev2
, '-s', '2000'],
5033 stderr
=open('/dev/null', 'w'))
5035 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
5036 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
5037 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
5040 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
5041 res
= brcmd
.stdout
.read().decode()
5042 brcmd
.stdout
.close()
5043 logger
.info("Bridge setup: " + res
)
5045 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
5046 stdout
=subprocess
.PIPE
)
5047 res
= brcmd
.stdout
.read().decode()
5048 brcmd
.stdout
.close()
5049 logger
.info("Bridge showstp: " + res
)
5051 addr0
= dev
[0].p2p_interface_addr()
5052 addr1
= dev
[1].p2p_interface_addr()
5053 addr2
= dev
[2].p2p_interface_addr()
5055 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':', ''))
5056 src_ll_opt1
= b
"\x01\x01" + binascii
.unhexlify(addr1
.replace(':', ''))
5059 send_ns(dev
[0], ip_src
="::", target
="aaaa:bbbb:cccc::2")
5061 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2")
5062 # test frame without source link-layer address option
5063 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5065 # test frame with bogus option
5066 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5067 opt
=b
"\x70\x01\x01\x02\x03\x04\x05\x05")
5068 # test frame with truncated source link-layer address option
5069 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5070 opt
=b
"\x01\x01\x01\x02\x03\x04")
5071 # test frame with foreign source link-layer address option
5072 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5073 opt
=b
"\x01\x01\x01\x02\x03\x04\x05\x06")
5075 send_ns(dev
[1], ip_src
="aaaa:bbbb:dddd::2", target
="aaaa:bbbb:dddd::2")
5077 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
5078 # another copy for additional code coverage
5079 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
5081 macs
= get_bridge_macs("ap-br0")
5082 logger
.info("After connect (showmacs): " + str(macs
))
5084 matches
= get_permanent_neighbors("ap-br0")
5085 logger
.info("After connect: " + str(matches
))
5086 if len(matches
) != 3:
5087 raise Exception("Unexpected number of neighbor entries after connect")
5088 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
5089 raise Exception("dev0 addr missing")
5090 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
5091 raise Exception("dev1 addr(1) missing")
5092 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
5093 raise Exception("dev1 addr(2) missing")
5095 send_ns(dev
[0], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:cccc::2")
5097 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:dddd::2")
5099 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:dddd::2",
5100 ip_src
="aaaa:bbbb:ffff::2")
5102 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:ff00::2")
5104 send_ns(dev
[2], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:ff00::2")
5106 send_ns(dev
[2], target
="aaaa:bbbb:eeee::2", ip_src
="aaaa:bbbb:ff00::2")
5109 # Try to probe for an already assigned address
5110 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="::")
5112 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc::2", ip_src
="::")
5114 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="::")
5118 send_na(dev
[1], target
="aaaa:bbbb:cccc:aeae::3",
5119 ip_src
="aaaa:bbbb:cccc:aeae::3", ip_dst
="ff02::1")
5120 send_na(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc:aeae::4",
5121 ip_src
="aaaa:bbbb:cccc:aeae::4", ip_dst
="ff02::1")
5122 send_na(dev
[2], target
="aaaa:bbbb:cccc:aeae::5",
5123 ip_src
="aaaa:bbbb:cccc:aeae::5", ip_dst
="ff02::1")
5126 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
5127 except Exception as e
:
5128 logger
.info("test_connectibity_iface failed: " + str(e
))
5129 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
5130 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
5131 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
5133 dev
[0].request("DISCONNECT")
5134 dev
[1].request("DISCONNECT")
5136 for i
in range(len(cmd
)):
5138 macs
= get_bridge_macs("ap-br0")
5139 logger
.info("After disconnect (showmacs): " + str(macs
))
5140 matches
= get_permanent_neighbors("ap-br0")
5141 logger
.info("After disconnect: " + str(matches
))
5142 if len(matches
) > 0:
5143 raise Exception("Unexpected neighbor entries after disconnect")
5145 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
5146 stdout
=subprocess
.PIPE
)
5147 res
= cmd
.stdout
.read().decode()
5149 logger
.info("ebtables results:\n" + res
)
5151 ns
= tshark_get_ns(cap_dev0
)
5152 logger
.info("dev0 seen NS: " + str(ns
))
5153 na
= tshark_get_na(cap_dev0
)
5154 logger
.info("dev0 seen NA: " + str(na
))
5156 if [addr0
, addr1
, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2',
5157 'aaaa:bbbb:dddd::2', addr1
] not in na
:
5158 # For now, skip the test instead of reporting the error since the IPv6
5159 # proxyarp support is not yet in the upstream kernel tree.
5160 #raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
5161 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp (IPv6)")
5166 raise Exception("Unexpected foreign NS on dev0: " + str(req
))
5168 ns
= tshark_get_ns(cap_dev1
)
5169 logger
.info("dev1 seen NS: " + str(ns
))
5170 na
= tshark_get_na(cap_dev1
)
5171 logger
.info("dev1 seen NA: " + str(na
))
5173 if [addr1
, addr0
, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:dddd::2',
5174 'aaaa:bbbb:cccc::2', addr0
] not in na
:
5175 raise Exception("dev1 did not get NA for aaaa:bbbb:cccc::2")
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, no_match
=True)
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")