2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
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 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
)
809 def test_ap_hs20_eap_unknown(dev
, apdev
):
810 """Hotspot 2.0 connection with unknown EAP method"""
811 bssid
= apdev
[0]['bssid']
812 params
= hs20_ap_params()
813 params
['nai_realm'] = "0,example.com,99"
814 hostapd
.add_ap(apdev
[0], params
)
817 dev
[0].add_cred_values(default_cred())
818 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
820 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
821 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
822 check_eap_capa(dev
[0], "MSCHAPV2")
823 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
825 def test_ap_hs20_eap_peap_default(dev
, apdev
):
826 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
827 check_eap_capa(dev
[0], "MSCHAPV2")
828 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
830 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
831 """Hotspot 2.0 connection with PEAP/GTC"""
832 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
835 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
836 """Hotspot 2.0 connection with PEAP/unknown"""
837 bssid
= apdev
[0]['bssid']
838 params
= hs20_ap_params()
839 params
['nai_realm'] = "0,example.com,25[3:99]"
840 hostapd
.add_ap(apdev
[0], params
)
843 dev
[0].add_cred_values(default_cred())
844 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
846 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
847 """Hotspot 2.0 connection with TTLS/CHAP"""
848 skip_with_fips(dev
[0])
849 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
851 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
852 """Hotspot 2.0 connection with TTLS/MSCHAP"""
853 skip_with_fips(dev
[0])
854 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
856 def test_ap_hs20_eap_ttls_default(dev
, apdev
):
857 """Hotspot 2.0 connection with TTLS/default"""
858 skip_with_fips(dev
[0])
859 eap_test(dev
[0], apdev
[0], "21", "TTLS", "hs20-test")
861 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
862 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
863 check_eap_capa(dev
[0], "MSCHAPV2")
864 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
867 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
868 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
869 bssid
= apdev
[0]['bssid']
870 params
= hs20_ap_params()
871 params
['nai_realm'] = "0,example.com,21[3:99]"
872 hostapd
.add_ap(apdev
[0], params
)
875 dev
[0].add_cred_values(default_cred())
876 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
879 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
880 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
881 bssid
= apdev
[0]['bssid']
882 params
= hs20_ap_params()
883 params
['nai_realm'] = "0,example.com,21[3:5]"
884 hostapd
.add_ap(apdev
[0], params
)
887 dev
[0].add_cred_values(default_cred())
888 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
891 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
892 """Hotspot 2.0 connection with TTLS/unknown"""
893 bssid
= apdev
[0]['bssid']
894 params
= hs20_ap_params()
895 params
['nai_realm'] = "0,example.com,21[2:5]"
896 hostapd
.add_ap(apdev
[0], params
)
899 dev
[0].add_cred_values(default_cred())
900 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
902 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
903 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
904 check_eap_capa(dev
[0], "FAST")
905 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
907 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
908 """Hotspot 2.0 connection with FAST/EAP-GTC"""
909 check_eap_capa(dev
[0], "FAST")
910 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
912 def test_ap_hs20_eap_tls(dev
, apdev
):
913 """Hotspot 2.0 connection with EAP-TLS"""
914 bssid
= apdev
[0]['bssid']
915 params
= hs20_ap_params()
916 params
['nai_realm'] = [ "0,example.com,13[5:6]" ]
917 hostapd
.add_ap(apdev
[0], params
)
920 dev
[0].add_cred_values({ 'realm': "example.com",
921 'username': "certificate-user",
922 'ca_cert': "auth_serv/ca.pem",
923 'client_cert': "auth_serv/user.pem",
924 'private_key': "auth_serv/user.key"})
925 interworking_select(dev
[0], bssid
, freq
="2412")
926 interworking_connect(dev
[0], bssid
, "TLS")
929 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
930 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
931 bssid
= apdev
[0]['bssid']
932 params
= hs20_ap_params()
933 params
['nai_realm'] = [ "0,example.com,99[5:6]" ]
934 hostapd
.add_ap(apdev
[0], params
)
937 dev
[0].add_cred_values({ 'realm': "example.com",
938 'username': "certificate-user",
939 'ca_cert': "auth_serv/ca.pem",
940 'client_cert': "auth_serv/user.pem",
941 'private_key': "auth_serv/user.key"})
942 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
945 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
946 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
947 bssid
= apdev
[0]['bssid']
948 params
= hs20_ap_params()
949 params
['nai_realm'] = [ "0,example.com,21[5:6]" ]
950 hostapd
.add_ap(apdev
[0], params
)
953 dev
[0].add_cred_values({ 'realm': "example.com",
954 'username': "certificate-user",
955 'ca_cert': "auth_serv/ca.pem",
956 'client_cert': "auth_serv/user.pem",
957 'private_key': "auth_serv/user.key"})
958 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
961 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
962 """Hotspot 2.0 connection with invalid cred configuration"""
963 bssid
= apdev
[0]['bssid']
964 params
= hs20_ap_params()
965 hostapd
.add_ap(apdev
[0], params
)
968 dev
[0].add_cred_values({ 'realm': "example.com",
969 'username': "certificate-user",
970 'client_cert': "auth_serv/user.pem" })
971 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
973 def test_ap_hs20_nai_realms(dev
, apdev
):
974 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
975 bssid
= apdev
[0]['bssid']
976 params
= hs20_ap_params()
977 params
['hessid'] = bssid
978 params
['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
979 hostapd
.add_ap(apdev
[0], params
)
982 id = dev
[0].add_cred_values({ 'realm': "example.com",
983 'ca_cert': "auth_serv/ca.pem",
984 'username': "pap user",
985 'password': "password",
986 'domain': "example.com" })
987 interworking_select(dev
[0], bssid
, "home", freq
="2412")
988 interworking_connect(dev
[0], bssid
, "TTLS")
989 check_sp_type(dev
[0], "home")
991 def test_ap_hs20_roaming_consortium(dev
, apdev
):
992 """Hotspot 2.0 connection based on roaming consortium match"""
993 bssid
= apdev
[0]['bssid']
994 params
= hs20_ap_params()
995 params
['hessid'] = bssid
996 hostapd
.add_ap(apdev
[0], params
)
999 for consortium
in [ "112233", "1020304050", "010203040506", "fedcba" ]:
1000 id = dev
[0].add_cred_values({ 'username': "user",
1001 'password': "password",
1002 'domain': "example.com",
1003 'ca_cert': "auth_serv/ca.pem",
1004 'roaming_consortium': consortium
,
1006 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1007 interworking_connect(dev
[0], bssid
, "PEAP")
1008 check_sp_type(dev
[0], "home")
1009 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1010 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
1012 raise Exception("Timeout on already-connected event")
1013 dev
[0].remove_cred(id)
1015 def test_ap_hs20_roaming_consortiums_match(dev
, apdev
):
1016 """Hotspot 2.0 connection based on roaming_consortiums match"""
1017 bssid
= apdev
[0]['bssid']
1018 params
= hs20_ap_params()
1019 params
['hessid'] = bssid
1020 hostapd
.add_ap(apdev
[0], params
)
1022 dev
[0].hs20_enable()
1023 tests
= [ ("112233", "112233"),
1024 ("ffffff,1020304050,eeeeee", "1020304050") ]
1025 for consortium
,selected
in tests
:
1026 id = dev
[0].add_cred_values({ 'username': "user",
1027 'password': "password",
1028 'domain': "my.home.example.com",
1029 'ca_cert': "auth_serv/ca.pem",
1030 'roaming_consortiums': consortium
,
1032 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1033 interworking_connect(dev
[0], bssid
, "PEAP")
1034 check_sp_type(dev
[0], "roaming")
1035 network_id
= dev
[0].get_status_field("id")
1036 sel
= dev
[0].get_network(network_id
, "roaming_consortium_selection")
1038 raise Exception("Unexpected roaming_consortium_selection value: " +
1040 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1041 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
1043 raise Exception("Timeout on already-connected event")
1044 dev
[0].remove_cred(id)
1046 def test_ap_hs20_max_roaming_consortiums(dev
, apdev
):
1047 """Maximum number of cred roaming_consortiums"""
1048 id = dev
[0].add_cred()
1049 consortium
= (36*",ffffff")[1:]
1050 if "OK" not in dev
[0].request('SET_CRED %d roaming_consortiums "%s"' % (id, consortium
)):
1051 raise Exception("Maximum number of consortium OIs rejected")
1052 consortium
= (37*",ffffff")[1:]
1053 if "FAIL" not in dev
[0].request('SET_CRED %d roaming_consortiums "%s"' % (id, consortium
)):
1054 raise Exception("Over maximum number of consortium OIs accepted")
1055 dev
[0].remove_cred(id)
1057 def test_ap_hs20_roaming_consortium_invalid(dev
, apdev
):
1058 """Hotspot 2.0 connection and invalid roaming consortium ANQP-element"""
1059 bssid
= apdev
[0]['bssid']
1060 params
= hs20_ap_params()
1061 params
['hessid'] = bssid
1062 # Override Roaming Consortium ANQP-element with an incorrectly encoded
1064 params
['anqp_elem'] = "261:04fedcba"
1065 hostapd
.add_ap(apdev
[0], params
)
1067 dev
[0].hs20_enable()
1068 id = dev
[0].add_cred_values({ 'username': "user",
1069 'password': "password",
1070 'domain': "example.com",
1071 'ca_cert': "auth_serv/ca.pem",
1072 'roaming_consortium': "fedcba",
1074 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1076 def test_ap_hs20_roaming_consortium_element(dev
, apdev
):
1077 """Hotspot 2.0 connection and invalid roaming consortium element"""
1078 bssid
= apdev
[0]['bssid']
1079 params
= hs20_ap_params()
1080 params
['hessid'] = bssid
1081 del params
['roaming_consortium']
1082 params
['vendor_elements'] = '6f00'
1083 hapd
= hostapd
.add_ap(apdev
[0], params
)
1085 dev
[0].hs20_enable()
1086 dev
[0].scan_for_bss(bssid
, freq
="2412")
1087 id = dev
[0].add_cred_values({ 'username': "user",
1088 'password': "password",
1089 'domain': "example.com",
1090 'ca_cert': "auth_serv/ca.pem",
1091 'roaming_consortium': "112233",
1093 interworking_select(dev
[0], bssid
, freq
="2412", no_match
=True)
1095 hapd
.set('vendor_elements', '6f020001')
1096 if "OK" not in hapd
.request("UPDATE_BEACON"):
1097 raise Exception("UPDATE_BEACON failed")
1098 dev
[0].request("BSS_FLUSH 0")
1099 dev
[0].scan_for_bss(bssid
, freq
="2412", force_scan
=True)
1100 interworking_select(dev
[0], bssid
, freq
="2412", no_match
=True)
1102 def test_ap_hs20_roaming_consortium_constraints(dev
, apdev
):
1103 """Hotspot 2.0 connection and roaming consortium constraints"""
1104 bssid
= apdev
[0]['bssid']
1105 params
= hs20_ap_params()
1106 params
['hessid'] = bssid
1107 params
['bss_load_test'] = "12:200:20000"
1108 hostapd
.add_ap(apdev
[0], params
)
1110 dev
[0].hs20_enable()
1112 vals
= { 'username': "user",
1113 'password': "password",
1114 'domain': "example.com",
1115 'ca_cert': "auth_serv/ca.pem",
1116 'roaming_consortium': "fedcba",
1119 vals2
['required_roaming_consortium'] = "223344"
1120 id = dev
[0].add_cred_values(vals2
)
1121 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1122 dev
[0].remove_cred(id)
1125 vals2
['min_dl_bandwidth_home'] = "65500"
1126 id = dev
[0].add_cred_values(vals2
)
1127 dev
[0].request("INTERWORKING_SELECT freq=2412")
1128 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1130 raise Exception("No AP found")
1131 if "below_min_backhaul=1" not in ev
:
1132 raise Exception("below_min_backhaul not reported")
1133 dev
[0].remove_cred(id)
1136 vals2
['max_bss_load'] = "100"
1137 id = dev
[0].add_cred_values(vals2
)
1138 dev
[0].request("INTERWORKING_SELECT freq=2412")
1139 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1141 raise Exception("No AP found")
1142 if "over_max_bss_load=1" not in ev
:
1143 raise Exception("over_max_bss_load not reported")
1144 dev
[0].remove_cred(id)
1147 vals2
['req_conn_capab'] = "6:1234"
1148 vals2
['domain'] = 'example.org'
1149 id = dev
[0].add_cred_values(vals2
)
1151 dev
[0].request("INTERWORKING_SELECT freq=2412")
1152 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1154 raise Exception("No AP found")
1155 if "conn_capab_missing=1" not in ev
:
1156 raise Exception("conn_capab_missing not reported")
1157 dev
[0].remove_cred(id)
1159 values
= default_cred()
1160 values
['roaming_consortium'] = "fedcba"
1161 id3
= dev
[0].add_cred_values(values
)
1164 vals2
['roaming_consortium'] = "fedcba"
1165 vals2
['priority'] = "2"
1166 id = dev
[0].add_cred_values(vals2
)
1168 values
= default_cred()
1169 values
['roaming_consortium'] = "fedcba"
1170 id2
= dev
[0].add_cred_values(values
)
1172 dev
[0].request("INTERWORKING_SELECT freq=2412")
1173 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1175 raise Exception("No AP found")
1176 dev
[0].remove_cred(id)
1177 dev
[0].remove_cred(id2
)
1178 dev
[0].remove_cred(id3
)
1180 def test_ap_hs20_3gpp_constraints(dev
, apdev
):
1181 """Hotspot 2.0 connection and 3GPP credential constraints"""
1182 bssid
= apdev
[0]['bssid']
1183 params
= hs20_ap_params()
1184 params
['hessid'] = bssid
1185 params
['anqp_3gpp_cell_net'] = "555,444"
1186 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1187 params
['bss_load_test'] = "12:200:20000"
1188 hapd
= hostapd
.add_ap(apdev
[0], params
)
1190 dev
[0].hs20_enable()
1192 vals
= { 'imsi': "555444-333222111",
1194 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1196 vals2
['required_roaming_consortium'] = "223344"
1197 id = dev
[0].add_cred_values(vals2
)
1198 interworking_select(dev
[0], bssid
, "home", freq
="2412", no_match
=True)
1199 dev
[0].remove_cred(id)
1202 vals2
['min_dl_bandwidth_home'] = "65500"
1203 id = dev
[0].add_cred_values(vals2
)
1204 dev
[0].request("INTERWORKING_SELECT freq=2412")
1205 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1207 raise Exception("No AP found")
1208 if "below_min_backhaul=1" not in ev
:
1209 raise Exception("below_min_backhaul not reported")
1210 dev
[0].remove_cred(id)
1213 vals2
['max_bss_load'] = "100"
1214 id = dev
[0].add_cred_values(vals2
)
1215 dev
[0].request("INTERWORKING_SELECT freq=2412")
1216 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1218 raise Exception("No AP found")
1219 if "over_max_bss_load=1" not in ev
:
1220 raise Exception("over_max_bss_load not reported")
1221 dev
[0].remove_cred(id)
1223 values
= default_cred()
1224 values
['roaming_consortium'] = "fedcba"
1225 id3
= dev
[0].add_cred_values(values
)
1228 vals2
['roaming_consortium'] = "fedcba"
1229 vals2
['priority'] = "2"
1230 id = dev
[0].add_cred_values(vals2
)
1232 values
= default_cred()
1233 values
['roaming_consortium'] = "fedcba"
1234 id2
= dev
[0].add_cred_values(values
)
1236 dev
[0].request("INTERWORKING_SELECT freq=2412")
1237 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1239 raise Exception("No AP found")
1240 dev
[0].remove_cred(id)
1241 dev
[0].remove_cred(id2
)
1242 dev
[0].remove_cred(id3
)
1245 params
= hs20_ap_params()
1246 params
['hessid'] = bssid
1247 params
['anqp_3gpp_cell_net'] = "555,444"
1248 params
['bss_load_test'] = "12:200:20000"
1249 hapd
= hostapd
.add_ap(apdev
[0], params
)
1251 vals2
['req_conn_capab'] = "6:1234"
1252 id = dev
[0].add_cred_values(vals2
)
1253 dev
[0].request("INTERWORKING_SELECT freq=2412")
1254 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1256 raise Exception("No AP found")
1257 if "conn_capab_missing=1" not in ev
:
1258 raise Exception("conn_capab_missing not reported")
1259 dev
[0].remove_cred(id)
1261 def test_ap_hs20_connect_no_full_match(dev
, apdev
):
1262 """Hotspot 2.0 connection and no full match"""
1263 bssid
= apdev
[0]['bssid']
1264 params
= hs20_ap_params()
1265 params
['hessid'] = bssid
1266 params
['anqp_3gpp_cell_net'] = "555,444"
1267 hostapd
.add_ap(apdev
[0], params
)
1269 dev
[0].hs20_enable()
1271 vals
= { 'username': "user",
1272 'password': "password",
1273 'domain': "example.com",
1274 'ca_cert': "auth_serv/ca.pem",
1275 'roaming_consortium': "fedcba",
1277 'min_dl_bandwidth_home': "65500" }
1278 id = dev
[0].add_cred_values(vals
)
1279 dev
[0].request("INTERWORKING_SELECT freq=2412")
1280 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1282 raise Exception("No AP found")
1283 if "below_min_backhaul=1" not in ev
:
1284 raise Exception("below_min_backhaul not reported")
1285 interworking_connect(dev
[0], bssid
, "TTLS")
1286 dev
[0].remove_cred(id)
1287 dev
[0].wait_disconnected()
1289 vals
= { 'imsi': "555444-333222111", 'eap': "SIM",
1290 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1291 'min_dl_bandwidth_roaming': "65500" }
1292 id = dev
[0].add_cred_values(vals
)
1293 dev
[0].request("INTERWORKING_SELECT freq=2412")
1294 ev
= dev
[0].wait_event(["INTERWORKING-AP"], timeout
=15)
1296 raise Exception("No AP found")
1297 if "below_min_backhaul=1" not in ev
:
1298 raise Exception("below_min_backhaul not reported")
1299 interworking_connect(dev
[0], bssid
, "SIM")
1300 dev
[0].remove_cred(id)
1301 dev
[0].wait_disconnected()
1303 def test_ap_hs20_username_roaming(dev
, apdev
):
1304 """Hotspot 2.0 connection in username/password credential (roaming)"""
1305 check_eap_capa(dev
[0], "MSCHAPV2")
1306 bssid
= apdev
[0]['bssid']
1307 params
= hs20_ap_params()
1308 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
1309 "0,roaming.example.com,21[2:4][5:7]",
1310 "0,another.example.com" ]
1311 params
['domain_name'] = "another.example.com"
1312 params
['hessid'] = bssid
1313 hostapd
.add_ap(apdev
[0], params
)
1315 dev
[0].hs20_enable()
1316 id = dev
[0].add_cred_values({ 'realm': "roaming.example.com",
1317 'username': "hs20-test",
1318 'password': "password",
1319 'ca_cert': "auth_serv/ca.pem",
1320 'domain': "example.com" })
1321 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1322 interworking_connect(dev
[0], bssid
, "TTLS")
1323 check_sp_type(dev
[0], "roaming")
1325 def test_ap_hs20_username_unknown(dev
, apdev
):
1326 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
1327 check_eap_capa(dev
[0], "MSCHAPV2")
1328 bssid
= apdev
[0]['bssid']
1329 params
= hs20_ap_params()
1330 params
['hessid'] = bssid
1331 hostapd
.add_ap(apdev
[0], params
)
1333 dev
[0].hs20_enable()
1334 id = dev
[0].add_cred_values({ 'realm': "example.com",
1335 'ca_cert': "auth_serv/ca.pem",
1336 'username': "hs20-test",
1337 'password': "password" })
1338 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
1339 interworking_connect(dev
[0], bssid
, "TTLS")
1340 check_sp_type(dev
[0], "unknown")
1342 def test_ap_hs20_username_unknown2(dev
, apdev
):
1343 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
1344 check_eap_capa(dev
[0], "MSCHAPV2")
1345 bssid
= apdev
[0]['bssid']
1346 params
= hs20_ap_params()
1347 params
['hessid'] = bssid
1348 del params
['domain_name']
1349 hostapd
.add_ap(apdev
[0], params
)
1351 dev
[0].hs20_enable()
1352 id = dev
[0].add_cred_values({ 'realm': "example.com",
1353 'ca_cert': "auth_serv/ca.pem",
1354 'username': "hs20-test",
1355 'password': "password",
1356 'domain': "example.com" })
1357 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
1358 interworking_connect(dev
[0], bssid
, "TTLS")
1359 check_sp_type(dev
[0], "unknown")
1361 def test_ap_hs20_gas_while_associated(dev
, apdev
):
1362 """Hotspot 2.0 connection with GAS query while associated"""
1363 check_eap_capa(dev
[0], "MSCHAPV2")
1364 bssid
= apdev
[0]['bssid']
1365 params
= hs20_ap_params()
1366 params
['hessid'] = bssid
1367 hostapd
.add_ap(apdev
[0], params
)
1369 dev
[0].hs20_enable()
1370 id = dev
[0].add_cred_values({ 'realm': "example.com",
1371 'ca_cert': "auth_serv/ca.pem",
1372 'username': "hs20-test",
1373 'password': "password",
1374 'domain': "example.com" })
1375 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1376 interworking_connect(dev
[0], bssid
, "TTLS")
1378 logger
.info("Verifying GAS query while associated")
1379 dev
[0].request("FETCH_ANQP")
1380 for i
in range(0, 6):
1381 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1383 raise Exception("Operation timed out")
1385 def test_ap_hs20_gas_with_another_ap_while_associated(dev
, apdev
):
1386 """GAS query with another AP while associated"""
1387 check_eap_capa(dev
[0], "MSCHAPV2")
1388 bssid
= apdev
[0]['bssid']
1389 params
= hs20_ap_params()
1390 params
['hessid'] = bssid
1391 hostapd
.add_ap(apdev
[0], params
)
1393 bssid2
= apdev
[1]['bssid']
1394 params
= hs20_ap_params()
1395 params
['hessid'] = bssid2
1396 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
1397 hostapd
.add_ap(apdev
[1], params
)
1399 dev
[0].hs20_enable()
1400 id = dev
[0].add_cred_values({ 'realm': "example.com",
1401 'ca_cert': "auth_serv/ca.pem",
1402 'username': "hs20-test",
1403 'password': "password",
1404 'domain': "example.com" })
1405 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1406 interworking_connect(dev
[0], bssid
, "TTLS")
1407 dev
[0].dump_monitor()
1409 logger
.info("Verifying GAS query with same AP while associated")
1410 dev
[0].request("ANQP_GET " + bssid
+ " 263")
1411 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1413 raise Exception("ANQP operation timed out")
1414 dev
[0].dump_monitor()
1416 logger
.info("Verifying GAS query with another AP while associated")
1417 dev
[0].scan_for_bss(bssid2
, 2412)
1418 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
1419 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1421 raise Exception("ANQP operation timed out")
1423 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
1424 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
1425 check_eap_capa(dev
[0], "MSCHAPV2")
1427 _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
)
1429 dev
[0].request("SET pmf 0")
1431 def _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
1432 bssid
= apdev
[0]['bssid']
1433 params
= hs20_ap_params()
1434 params
['hessid'] = bssid
1435 hostapd
.add_ap(apdev
[0], params
)
1437 bssid2
= apdev
[1]['bssid']
1438 params
= hs20_ap_params()
1439 params
['hessid'] = bssid2
1440 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
1441 hostapd
.add_ap(apdev
[1], params
)
1443 dev
[0].hs20_enable()
1444 dev
[0].request("SET pmf 2")
1445 id = dev
[0].add_cred_values({ 'realm': "example.com",
1446 'ca_cert': "auth_serv/ca.pem",
1447 'username': "hs20-test",
1448 'password': "password",
1449 'domain': "example.com" })
1450 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1451 interworking_connect(dev
[0], bssid
, "TTLS")
1453 logger
.info("Verifying GAS query while associated")
1454 dev
[0].request("FETCH_ANQP")
1455 for i
in range(0, 2 * 6):
1456 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1458 raise Exception("Operation timed out")
1460 def test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1461 """GAS query with another AP while associated and using PMF"""
1462 check_eap_capa(dev
[0], "MSCHAPV2")
1464 _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
)
1466 dev
[0].request("SET pmf 0")
1468 def _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev
, apdev
):
1469 bssid
= apdev
[0]['bssid']
1470 params
= hs20_ap_params()
1471 params
['hessid'] = bssid
1472 hostapd
.add_ap(apdev
[0], params
)
1474 bssid2
= apdev
[1]['bssid']
1475 params
= hs20_ap_params()
1476 params
['hessid'] = bssid2
1477 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
1478 hostapd
.add_ap(apdev
[1], params
)
1480 dev
[0].hs20_enable()
1481 dev
[0].request("SET pmf 2")
1482 id = dev
[0].add_cred_values({ 'realm': "example.com",
1483 'ca_cert': "auth_serv/ca.pem",
1484 'username': "hs20-test",
1485 'password': "password",
1486 'domain': "example.com" })
1487 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1488 interworking_connect(dev
[0], bssid
, "TTLS")
1489 dev
[0].dump_monitor()
1491 logger
.info("Verifying GAS query with same AP while associated")
1492 dev
[0].request("ANQP_GET " + bssid
+ " 263")
1493 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1495 raise Exception("ANQP operation timed out")
1496 dev
[0].dump_monitor()
1498 logger
.info("Verifying GAS query with another AP while associated")
1499 dev
[0].scan_for_bss(bssid2
, 2412)
1500 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
1501 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1503 raise Exception("ANQP operation timed out")
1505 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
1506 """Hotspot 2.0 connection with fragmented GAS query while associated"""
1507 check_eap_capa(dev
[0], "MSCHAPV2")
1508 bssid
= apdev
[0]['bssid']
1509 params
= hs20_ap_params()
1510 params
['hessid'] = bssid
1511 hapd
= hostapd
.add_ap(apdev
[0], params
)
1512 hapd
.set("gas_frag_limit", "50")
1514 dev
[0].hs20_enable()
1515 id = dev
[0].add_cred_values({ 'realm': "example.com",
1516 'ca_cert': "auth_serv/ca.pem",
1517 'username': "hs20-test",
1518 'password': "password",
1519 'domain': "example.com" })
1520 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1521 interworking_connect(dev
[0], bssid
, "TTLS")
1523 logger
.info("Verifying GAS query while associated")
1524 dev
[0].request("FETCH_ANQP")
1525 for i
in range(0, 6):
1526 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
1528 raise Exception("Operation timed out")
1530 def test_ap_hs20_multiple_connects(dev
, apdev
):
1531 """Hotspot 2.0 connection through multiple network selections"""
1532 check_eap_capa(dev
[0], "MSCHAPV2")
1533 bssid
= apdev
[0]['bssid']
1534 params
= hs20_ap_params()
1535 params
['hessid'] = bssid
1536 hostapd
.add_ap(apdev
[0], params
)
1538 dev
[0].hs20_enable()
1539 values
= { 'realm': "example.com",
1540 'ca_cert': "auth_serv/ca.pem",
1541 'username': "hs20-test",
1542 'password': "password",
1543 'domain': "example.com" }
1544 id = dev
[0].add_cred_values(values
)
1546 dev
[0].scan_for_bss(bssid
, freq
="2412")
1548 for i
in range(0, 3):
1549 logger
.info("Starting Interworking network selection")
1550 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1552 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1553 "INTERWORKING-ALREADY-CONNECTED",
1554 "CTRL-EVENT-CONNECTED"], timeout
=15)
1556 raise Exception("Connection timed out")
1557 if "INTERWORKING-NO-MATCH" in ev
:
1558 raise Exception("Matching AP not found")
1559 if "CTRL-EVENT-CONNECTED" in ev
:
1561 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
1564 dev
[0].request("DISCONNECT")
1565 dev
[0].dump_monitor()
1567 networks
= dev
[0].list_networks()
1568 if len(networks
) > 1:
1569 raise Exception("Duplicated network block detected")
1571 def test_ap_hs20_disallow_aps(dev
, apdev
):
1572 """Hotspot 2.0 connection and disallow_aps"""
1573 bssid
= apdev
[0]['bssid']
1574 params
= hs20_ap_params()
1575 params
['hessid'] = bssid
1576 hostapd
.add_ap(apdev
[0], params
)
1578 dev
[0].hs20_enable()
1579 values
= { 'realm': "example.com",
1580 'ca_cert': "auth_serv/ca.pem",
1581 'username': "hs20-test",
1582 'password': "password",
1583 'domain': "example.com" }
1584 id = dev
[0].add_cred_values(values
)
1586 dev
[0].scan_for_bss(bssid
, freq
="2412")
1588 logger
.info("Verify disallow_aps bssid")
1589 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
1590 dev
[0].request("INTERWORKING_SELECT auto")
1591 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1593 raise Exception("Network selection timed out")
1594 dev
[0].dump_monitor()
1596 logger
.info("Verify disallow_aps ssid")
1597 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
1598 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1599 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1601 raise Exception("Network selection timed out")
1602 dev
[0].dump_monitor()
1604 logger
.info("Verify disallow_aps clear")
1605 dev
[0].request("SET disallow_aps ")
1606 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1608 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
1609 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1610 if "FAIL" not in ret
:
1611 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
1613 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
1614 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1615 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
1616 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1618 def policy_test(dev
, ap
, values
, only_one
=True):
1621 logger
.info("Verify network selection to AP " + ap
['ifname'])
1623 dev
.scan_for_bss(bssid
, freq
="2412")
1625 logger
.info("Verify network selection")
1628 id = dev
.add_cred_values(values
)
1629 dev
.request("INTERWORKING_SELECT auto freq=2412")
1632 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1633 "INTERWORKING-BLACKLISTED",
1634 "INTERWORKING-SELECTED"], timeout
=15)
1636 raise Exception("Network selection timed out")
1638 if "INTERWORKING-NO-MATCH" in ev
:
1639 raise Exception("Matching AP not found")
1640 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1641 raise Exception("Unexpected AP claimed acceptable")
1642 if "INTERWORKING-SELECTED" in ev
:
1643 if bssid
and bssid
not in ev
:
1644 raise Exception("Selected incorrect BSS")
1647 ev
= dev
.wait_connected(timeout
=15)
1648 if bssid
and bssid
not in ev
:
1649 raise Exception("Connected to incorrect BSS")
1651 conn_bssid
= dev
.get_status_field("bssid")
1652 if bssid
and conn_bssid
!= bssid
:
1653 raise Exception("bssid information points to incorrect BSS")
1659 def default_cred(domain
=None, user
="hs20-test"):
1660 cred
= { 'realm': "example.com",
1661 'ca_cert': "auth_serv/ca.pem",
1663 'password': "password" }
1665 cred
['domain'] = domain
1668 def test_ap_hs20_prefer_home(dev
, apdev
):
1669 """Hotspot 2.0 required roaming consortium"""
1670 check_eap_capa(dev
[0], "MSCHAPV2")
1671 params
= hs20_ap_params()
1672 params
['domain_name'] = "example.org"
1673 hostapd
.add_ap(apdev
[0], params
)
1675 params
= hs20_ap_params()
1676 params
['ssid'] = "test-hs20-other"
1677 params
['domain_name'] = "example.com"
1678 hostapd
.add_ap(apdev
[1], params
)
1680 values
= default_cred()
1681 values
['domain'] = "example.com"
1682 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1683 values
['domain'] = "example.org"
1684 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1686 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1687 """Hotspot 2.0 required roaming consortium"""
1688 check_eap_capa(dev
[0], "MSCHAPV2")
1689 params
= hs20_ap_params()
1690 hostapd
.add_ap(apdev
[0], params
)
1692 params
= hs20_ap_params()
1693 params
['ssid'] = "test-hs20-other"
1694 params
['roaming_consortium'] = [ "223344" ]
1695 hostapd
.add_ap(apdev
[1], params
)
1697 values
= default_cred()
1698 values
['required_roaming_consortium'] = "223344"
1699 policy_test(dev
[0], apdev
[1], values
)
1700 values
['required_roaming_consortium'] = "112233"
1701 policy_test(dev
[0], apdev
[0], values
)
1703 id = dev
[0].add_cred()
1704 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1705 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1707 for val
in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1708 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1709 raise Exception("Invalid roaming consortium value accepted: " + val
)
1711 def test_ap_hs20_req_roaming_consortium_no_match(dev
, apdev
):
1712 """Hotspot 2.0 required roaming consortium and no match"""
1713 check_eap_capa(dev
[0], "MSCHAPV2")
1714 params
= hs20_ap_params()
1715 del params
['roaming_consortium']
1716 hostapd
.add_ap(apdev
[0], params
)
1718 params
= hs20_ap_params()
1719 params
['ssid'] = "test-hs20-other"
1720 params
['roaming_consortium'] = [ "223345" ]
1721 hostapd
.add_ap(apdev
[1], params
)
1723 values
= default_cred()
1724 values
['required_roaming_consortium'] = "223344"
1725 dev
[0].hs20_enable()
1726 id = dev
[0].add_cred_values(values
)
1727 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1728 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=10)
1730 raise Exception("INTERWORKING-NO-MATCH not reported")
1732 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1733 """Hotspot 2.0 exclusion based on SSID"""
1734 check_eap_capa(dev
[0], "MSCHAPV2")
1735 params
= hs20_ap_params()
1736 params
['roaming_consortium'] = [ "223344" ]
1737 params
['anqp_3gpp_cell_net'] = "555,444"
1738 hostapd
.add_ap(apdev
[0], params
)
1740 params
= hs20_ap_params()
1741 params
['ssid'] = "test-hs20-other"
1742 params
['roaming_consortium'] = [ "223344" ]
1743 params
['anqp_3gpp_cell_net'] = "555,444"
1744 hostapd
.add_ap(apdev
[1], params
)
1746 values
= default_cred()
1747 values
['excluded_ssid'] = "test-hs20"
1748 events
= policy_test(dev
[0], apdev
[1], values
)
1749 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1751 raise Exception("Excluded network not reported")
1752 values
['excluded_ssid'] = "test-hs20-other"
1753 events
= policy_test(dev
[0], apdev
[0], values
)
1754 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1756 raise Exception("Excluded network not reported")
1758 values
= default_cred()
1759 values
['roaming_consortium'] = "223344"
1760 values
['eap'] = "TTLS"
1761 values
['phase2'] = "auth=MSCHAPV2"
1762 values
['excluded_ssid'] = "test-hs20"
1763 events
= policy_test(dev
[0], apdev
[1], values
)
1764 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1766 raise Exception("Excluded network not reported")
1768 values
= { 'imsi': "555444-333222111", 'eap': "SIM",
1769 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1770 'excluded_ssid': "test-hs20" }
1771 events
= policy_test(dev
[0], apdev
[1], values
)
1772 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1774 raise Exception("Excluded network not reported")
1776 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1777 """Hotspot 2.0 and roaming from current to higher priority network"""
1778 check_eap_capa(dev
[0], "MSCHAPV2")
1779 bssid
= apdev
[0]['bssid']
1780 params
= hs20_ap_params(ssid
="test-hs20-visited")
1781 params
['domain_name'] = "visited.example.org"
1782 hostapd
.add_ap(apdev
[0], params
)
1784 dev
[0].hs20_enable()
1785 id = dev
[0].add_cred_values({ 'realm': "example.com",
1786 'ca_cert': "auth_serv/ca.pem",
1787 'username': "hs20-test",
1788 'password': "password",
1789 'domain': "example.com" })
1790 logger
.info("Connect to the only network option")
1791 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1792 dev
[0].dump_monitor()
1793 interworking_connect(dev
[0], bssid
, "TTLS")
1795 logger
.info("Start another AP (home operator) and reconnect")
1796 bssid2
= apdev
[1]['bssid']
1797 params
= hs20_ap_params(ssid
="test-hs20-home")
1798 params
['domain_name'] = "example.com"
1799 hostapd
.add_ap(apdev
[1], params
)
1801 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1802 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1803 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1804 "INTERWORKING-ALREADY-CONNECTED",
1805 "CTRL-EVENT-CONNECTED"], timeout
=15)
1807 raise Exception("Connection timed out")
1808 if "INTERWORKING-NO-MATCH" in ev
:
1809 raise Exception("Matching AP not found")
1810 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1811 raise Exception("Unexpected AP selected")
1812 if bssid2
not in ev
:
1813 raise Exception("Unexpected BSSID after reconnection")
1815 def test_ap_hs20_domain_suffix_match_full(dev
, apdev
):
1816 """Hotspot 2.0 and domain_suffix_match"""
1817 check_domain_match_full(dev
[0])
1818 check_eap_capa(dev
[0], "MSCHAPV2")
1819 bssid
= apdev
[0]['bssid']
1820 params
= hs20_ap_params()
1821 hostapd
.add_ap(apdev
[0], params
)
1823 dev
[0].hs20_enable()
1824 id = dev
[0].add_cred_values({ 'realm': "example.com",
1825 'username': "hs20-test",
1826 'password': "password",
1827 'ca_cert': "auth_serv/ca.pem",
1828 'domain': "example.com",
1829 'domain_suffix_match': "server.w1.fi" })
1830 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1831 dev
[0].dump_monitor()
1832 interworking_connect(dev
[0], bssid
, "TTLS")
1833 dev
[0].request("REMOVE_NETWORK all")
1834 dev
[0].dump_monitor()
1836 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1837 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1838 dev
[0].dump_monitor()
1839 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1840 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1842 raise Exception("TLS certificate error not reported")
1843 if "Domain suffix mismatch" not in ev
:
1844 raise Exception("Domain suffix mismatch not reported")
1846 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1847 """Hotspot 2.0 and domain_suffix_match"""
1848 check_eap_capa(dev
[0], "MSCHAPV2")
1849 check_domain_match_full(dev
[0])
1850 bssid
= apdev
[0]['bssid']
1851 params
= hs20_ap_params()
1852 hostapd
.add_ap(apdev
[0], params
)
1854 dev
[0].hs20_enable()
1855 id = dev
[0].add_cred_values({ 'realm': "example.com",
1856 'username': "hs20-test",
1857 'password': "password",
1858 'ca_cert': "auth_serv/ca.pem",
1859 'domain': "example.com",
1860 'domain_suffix_match': "w1.fi" })
1861 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1862 dev
[0].dump_monitor()
1863 interworking_connect(dev
[0], bssid
, "TTLS")
1865 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1866 """Hotspot 2.0 and roaming partner preference"""
1867 check_eap_capa(dev
[0], "MSCHAPV2")
1868 params
= hs20_ap_params()
1869 params
['domain_name'] = "roaming.example.org"
1870 hostapd
.add_ap(apdev
[0], params
)
1872 params
= hs20_ap_params()
1873 params
['ssid'] = "test-hs20-other"
1874 params
['domain_name'] = "roaming.example.net"
1875 hostapd
.add_ap(apdev
[1], params
)
1877 logger
.info("Verify default vs. specified preference")
1878 values
= default_cred()
1879 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1880 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1881 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1882 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1884 logger
.info("Verify partial FQDN match")
1885 values
['roaming_partner'] = "example.net,0,0,*"
1886 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1887 values
['roaming_partner'] = "example.net,0,255,*"
1888 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1890 def test_ap_hs20_max_bss_load(dev
, apdev
):
1891 """Hotspot 2.0 and maximum BSS load"""
1892 check_eap_capa(dev
[0], "MSCHAPV2")
1893 params
= hs20_ap_params()
1894 params
['bss_load_test'] = "12:200:20000"
1895 hostapd
.add_ap(apdev
[0], params
)
1897 params
= hs20_ap_params()
1898 params
['ssid'] = "test-hs20-other"
1899 params
['bss_load_test'] = "5:20:10000"
1900 hostapd
.add_ap(apdev
[1], params
)
1902 logger
.info("Verify maximum BSS load constraint")
1903 values
= default_cred()
1904 values
['domain'] = "example.com"
1905 values
['max_bss_load'] = "100"
1906 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1908 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1909 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1910 raise Exception("Maximum BSS Load case not noticed")
1911 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1912 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1913 raise Exception("Maximum BSS Load case reported incorrectly")
1915 logger
.info("Verify maximum BSS load does not prevent connection")
1916 values
['max_bss_load'] = "1"
1917 events
= policy_test(dev
[0], None, values
)
1919 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1920 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1921 raise Exception("Maximum BSS Load case not noticed")
1922 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1923 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1924 raise Exception("Maximum BSS Load case not noticed")
1926 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1927 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1928 check_eap_capa(dev
[0], "MSCHAPV2")
1929 params
= hs20_ap_params()
1930 params
['bss_load_test'] = "12:200:20000"
1931 hostapd
.add_ap(apdev
[0], params
)
1933 params
= hs20_ap_params()
1934 params
['ssid'] = "test-hs20-other"
1935 hostapd
.add_ap(apdev
[1], params
)
1937 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1938 values
= default_cred()
1939 values
['domain'] = "example.com"
1940 values
['max_bss_load'] = "100"
1941 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1943 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1944 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1945 raise Exception("Maximum BSS Load case not noticed")
1946 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1947 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1948 raise Exception("Maximum BSS Load case reported incorrectly")
1950 def test_ap_hs20_max_bss_load_roaming(dev
, apdev
):
1951 """Hotspot 2.0 and maximum BSS load (roaming)"""
1952 check_eap_capa(dev
[0], "MSCHAPV2")
1953 params
= hs20_ap_params()
1954 params
['bss_load_test'] = "12:200:20000"
1955 hostapd
.add_ap(apdev
[0], params
)
1957 values
= default_cred()
1958 values
['domain'] = "roaming.example.com"
1959 values
['max_bss_load'] = "100"
1960 events
= policy_test(dev
[0], apdev
[0], values
, only_one
=True)
1961 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1963 raise Exception("No INTERWORKING-AP event")
1964 if "over_max_bss_load=1" in ev
[0]:
1965 raise Exception("Maximum BSS Load reported for roaming")
1967 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1968 """Hotspot 2.0 multi-cred sp_priority"""
1969 check_eap_capa(dev
[0], "MSCHAPV2")
1971 _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1973 dev
[0].request("SET external_sim 0")
1975 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1976 hlr_auc_gw_available()
1977 bssid
= apdev
[0]['bssid']
1978 params
= hs20_ap_params()
1979 params
['hessid'] = bssid
1980 del params
['domain_name']
1981 params
['anqp_3gpp_cell_net'] = "232,01"
1982 hostapd
.add_ap(apdev
[0], params
)
1984 dev
[0].hs20_enable()
1985 dev
[0].scan_for_bss(bssid
, freq
="2412")
1986 dev
[0].request("SET external_sim 1")
1987 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1988 'provisioning_sp': "example.com",
1989 'sp_priority' :"1" })
1990 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1991 'ca_cert': "auth_serv/ca.pem",
1992 'username': "hs20-test",
1993 'password': "password",
1994 'domain': "example.com",
1995 'provisioning_sp': "example.com",
1996 'sp_priority': "2" })
1997 dev
[0].dump_monitor()
1998 dev
[0].scan_for_bss(bssid
, freq
="2412")
1999 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2000 interworking_ext_sim_auth(dev
[0], "SIM")
2001 check_sp_type(dev
[0], "unknown")
2002 dev
[0].request("REMOVE_NETWORK all")
2004 dev
[0].set_cred(id1
, "sp_priority", "2")
2005 dev
[0].set_cred(id2
, "sp_priority", "1")
2006 dev
[0].dump_monitor()
2007 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2008 interworking_auth(dev
[0], "TTLS")
2009 check_sp_type(dev
[0], "unknown")
2011 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
2012 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
2013 check_eap_capa(dev
[0], "MSCHAPV2")
2015 _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
2017 dev
[0].request("SET external_sim 0")
2019 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
2020 hlr_auc_gw_available()
2021 bssid
= apdev
[0]['bssid']
2022 params
= hs20_ap_params()
2023 params
['hessid'] = bssid
2024 del params
['nai_realm']
2025 del params
['domain_name']
2026 params
['anqp_3gpp_cell_net'] = "232,01"
2027 hostapd
.add_ap(apdev
[0], params
)
2029 bssid2
= apdev
[1]['bssid']
2030 params
= hs20_ap_params()
2031 params
['ssid'] = "test-hs20-other"
2032 params
['hessid'] = bssid2
2033 del params
['domain_name']
2034 del params
['anqp_3gpp_cell_net']
2035 hostapd
.add_ap(apdev
[1], params
)
2037 dev
[0].hs20_enable()
2038 dev
[0].request("SET external_sim 1")
2039 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
2040 'provisioning_sp': "example.com",
2041 'sp_priority': "1" })
2042 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
2043 'ca_cert': "auth_serv/ca.pem",
2044 'username': "hs20-test",
2045 'password': "password",
2046 'domain': "example.com",
2047 'provisioning_sp': "example.com",
2048 'sp_priority': "2" })
2049 dev
[0].dump_monitor()
2050 dev
[0].scan_for_bss(bssid
, freq
="2412")
2051 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2052 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2053 interworking_ext_sim_auth(dev
[0], "SIM")
2054 check_sp_type(dev
[0], "unknown")
2055 conn_bssid
= dev
[0].get_status_field("bssid")
2056 if conn_bssid
!= bssid
:
2057 raise Exception("Connected to incorrect BSS")
2058 dev
[0].request("REMOVE_NETWORK all")
2060 dev
[0].set_cred(id1
, "sp_priority", "2")
2061 dev
[0].set_cred(id2
, "sp_priority", "1")
2062 dev
[0].dump_monitor()
2063 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2064 interworking_auth(dev
[0], "TTLS")
2065 check_sp_type(dev
[0], "unknown")
2066 conn_bssid
= dev
[0].get_status_field("bssid")
2067 if conn_bssid
!= bssid2
:
2068 raise Exception("Connected to incorrect BSS")
2070 def test_ap_hs20_multi_cred_sp_prio_same(dev
, apdev
):
2071 """Hotspot 2.0 multi-cred and same sp_priority"""
2072 check_eap_capa(dev
[0], "MSCHAPV2")
2073 hlr_auc_gw_available()
2074 bssid
= apdev
[0]['bssid']
2075 params
= hs20_ap_params()
2076 params
['hessid'] = bssid
2077 del params
['domain_name']
2078 params
['anqp_3gpp_cell_net'] = "232,01"
2079 hostapd
.add_ap(apdev
[0], params
)
2081 dev
[0].hs20_enable()
2082 dev
[0].scan_for_bss(bssid
, freq
="2412")
2083 id1
= dev
[0].add_cred_values({ 'realm': "example.com",
2084 'ca_cert': "auth_serv/ca.pem",
2085 'username': "hs20-test",
2086 'password': "password",
2087 'domain': "domain1.example.com",
2088 'provisioning_sp': "example.com",
2089 'sp_priority': "1" })
2090 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
2091 'ca_cert': "auth_serv/ca.pem",
2092 'username': "hs20-test",
2093 'password': "password",
2094 'domain': "domain2.example.com",
2095 'provisioning_sp': "example.com",
2096 'sp_priority': "1" })
2097 dev
[0].dump_monitor()
2098 dev
[0].scan_for_bss(bssid
, freq
="2412")
2099 check_auto_select(dev
[0], bssid
)
2101 def check_conn_capab_selection(dev
, type, missing
):
2102 dev
.request("INTERWORKING_SELECT freq=2412")
2103 ev
= dev
.wait_event(["INTERWORKING-AP"])
2105 raise Exception("Network selection timed out")
2106 if "type=" + type not in ev
:
2107 raise Exception("Unexpected network type")
2108 if missing
and "conn_capab_missing=1" not in ev
:
2109 raise Exception("conn_capab_missing not reported")
2110 if not missing
and "conn_capab_missing=1" in ev
:
2111 raise Exception("conn_capab_missing reported unexpectedly")
2113 def conn_capab_cred(domain
=None, req_conn_capab
=None):
2114 cred
= default_cred(domain
=domain
)
2116 cred
['req_conn_capab'] = req_conn_capab
2119 def test_ap_hs20_req_conn_capab(dev
, apdev
):
2120 """Hotspot 2.0 network selection with req_conn_capab"""
2121 check_eap_capa(dev
[0], "MSCHAPV2")
2122 bssid
= apdev
[0]['bssid']
2123 params
= hs20_ap_params()
2124 hostapd
.add_ap(apdev
[0], params
)
2126 dev
[0].hs20_enable()
2127 dev
[0].scan_for_bss(bssid
, freq
="2412")
2128 logger
.info("Not used in home network")
2129 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
2130 id = dev
[0].add_cred_values(values
)
2131 check_conn_capab_selection(dev
[0], "home", False)
2133 logger
.info("Used in roaming network")
2134 dev
[0].remove_cred(id)
2135 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
2136 id = dev
[0].add_cred_values(values
)
2137 check_conn_capab_selection(dev
[0], "roaming", True)
2139 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
2140 check_auto_select(dev
[0], bssid
)
2142 logger
.info("Additional req_conn_capab checks")
2144 dev
[0].remove_cred(id)
2145 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
2146 id = dev
[0].add_cred_values(values
)
2147 check_conn_capab_selection(dev
[0], "roaming", True)
2149 dev
[0].remove_cred(id)
2150 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
2151 id = dev
[0].add_cred_values(values
)
2152 check_conn_capab_selection(dev
[0], "roaming", True)
2154 bssid2
= apdev
[1]['bssid']
2155 params
= hs20_ap_params(ssid
="test-hs20b")
2156 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
2157 hostapd
.add_ap(apdev
[1], params
)
2159 dev
[0].remove_cred(id)
2160 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
2161 id = dev
[0].add_cred_values(values
)
2162 dev
[0].set_cred(id, "req_conn_capab", "6:22")
2163 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2164 dev
[0].request("INTERWORKING_SELECT freq=2412")
2165 for i
in range(0, 2):
2166 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
2168 raise Exception("Network selection timed out")
2169 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
2170 raise Exception("Missing protocol connection capability not reported")
2171 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
2172 raise Exception("Protocol connection capability not reported correctly")
2174 def test_ap_hs20_req_conn_capab2(dev
, apdev
):
2175 """Hotspot 2.0 network selection with req_conn_capab (not present)"""
2176 check_eap_capa(dev
[0], "MSCHAPV2")
2177 bssid
= apdev
[0]['bssid']
2178 params
= hs20_ap_params()
2179 del params
['hs20_conn_capab']
2180 hostapd
.add_ap(apdev
[0], params
)
2182 dev
[0].hs20_enable()
2183 dev
[0].scan_for_bss(bssid
, freq
="2412")
2184 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
2185 id = dev
[0].add_cred_values(values
)
2186 check_conn_capab_selection(dev
[0], "roaming", False)
2188 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
2189 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
2190 check_eap_capa(dev
[0], "MSCHAPV2")
2191 bssid
= apdev
[0]['bssid']
2192 params
= hs20_ap_params()
2193 params
['domain_name'] = "roaming.example.org"
2194 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
2195 hostapd
.add_ap(apdev
[0], params
)
2197 bssid2
= apdev
[1]['bssid']
2198 params
= hs20_ap_params(ssid
="test-hs20-b")
2199 params
['domain_name'] = "roaming.example.net"
2200 hostapd
.add_ap(apdev
[1], params
)
2202 values
= default_cred()
2203 values
['roaming_partner'] = "roaming.example.net,1,127,*"
2204 id = dev
[0].add_cred_values(values
)
2205 check_auto_select(dev
[0], bssid2
)
2207 dev
[0].set_cred(id, "req_conn_capab", "50")
2208 check_auto_select(dev
[0], bssid
)
2210 dev
[0].remove_cred(id)
2211 id = dev
[0].add_cred_values(values
)
2212 dev
[0].set_cred(id, "req_conn_capab", "51")
2213 check_auto_select(dev
[0], bssid2
)
2215 def check_bandwidth_selection(dev
, type, below
):
2216 dev
.request("INTERWORKING_SELECT freq=2412")
2217 ev
= dev
.wait_event(["INTERWORKING-AP"])
2219 raise Exception("Network selection timed out")
2220 logger
.debug("BSS entries:\n" + dev
.request("BSS RANGE=ALL"))
2221 if "type=" + type not in ev
:
2222 raise Exception("Unexpected network type")
2223 if below
and "below_min_backhaul=1" not in ev
:
2224 raise Exception("below_min_backhaul not reported")
2225 if not below
and "below_min_backhaul=1" in ev
:
2226 raise Exception("below_min_backhaul reported unexpectedly")
2228 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
2229 cred
= default_cred(domain
=domain
)
2231 cred
['min_dl_bandwidth_home'] = str(dl_home
)
2233 cred
['min_ul_bandwidth_home'] = str(ul_home
)
2235 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
2237 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
2240 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
2241 """Hotspot 2.0 network selection with min bandwidth (home)"""
2242 check_eap_capa(dev
[0], "MSCHAPV2")
2243 bssid
= apdev
[0]['bssid']
2244 params
= hs20_ap_params()
2245 hostapd
.add_ap(apdev
[0], params
)
2247 dev
[0].hs20_enable()
2248 dev
[0].scan_for_bss(bssid
, freq
="2412")
2249 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2250 id = dev
[0].add_cred_values(values
)
2251 check_bandwidth_selection(dev
[0], "home", False)
2252 dev
[0].remove_cred(id)
2254 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
2255 id = dev
[0].add_cred_values(values
)
2256 check_bandwidth_selection(dev
[0], "home", True)
2257 dev
[0].remove_cred(id)
2259 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
2260 id = dev
[0].add_cred_values(values
)
2261 check_bandwidth_selection(dev
[0], "home", True)
2262 dev
[0].remove_cred(id)
2264 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
2265 id = dev
[0].add_cred_values(values
)
2266 check_bandwidth_selection(dev
[0], "home", True)
2267 check_auto_select(dev
[0], bssid
)
2269 bssid2
= apdev
[1]['bssid']
2270 params
= hs20_ap_params(ssid
="test-hs20-b")
2271 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2272 hostapd
.add_ap(apdev
[1], params
)
2274 check_auto_select(dev
[0], bssid2
)
2276 def test_ap_hs20_min_bandwidth_home2(dev
, apdev
):
2277 """Hotspot 2.0 network selection with min bandwidth - special cases"""
2278 check_eap_capa(dev
[0], "MSCHAPV2")
2279 bssid
= apdev
[0]['bssid']
2280 params
= hs20_ap_params()
2281 hapd
= hostapd
.add_ap(apdev
[0], params
)
2283 dev
[0].hs20_enable()
2284 dev
[0].scan_for_bss(bssid
, freq
="2412")
2285 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2286 id = dev
[0].add_cred_values(values
)
2287 check_bandwidth_selection(dev
[0], "home", False)
2289 logger
.info("WAN link at capacity")
2290 hapd
.set('hs20_wan_metrics', "09:8000:1000:80:240:3000")
2291 check_bandwidth_selection(dev
[0], "home", True)
2293 logger
.info("Downlink/Uplink Load was not measured")
2294 hapd
.set('hs20_wan_metrics', "01:8000:1000:80:240:0")
2295 check_bandwidth_selection(dev
[0], "home", False)
2297 logger
.info("Uplink and Downlink max values")
2298 hapd
.set('hs20_wan_metrics', "01:4294967295:4294967295:80:240:3000")
2299 check_bandwidth_selection(dev
[0], "home", False)
2301 dev
[0].remove_cred(id)
2303 def test_ap_hs20_min_bandwidth_home_hidden_ssid_in_scan_res(dev
, apdev
):
2304 """Hotspot 2.0 network selection with min bandwidth (home) while hidden SSID is included in scan results"""
2305 check_eap_capa(dev
[0], "MSCHAPV2")
2306 bssid
= apdev
[0]['bssid']
2308 hapd
= hostapd
.add_ap(apdev
[0], { "ssid": 'secret',
2309 "ignore_broadcast_ssid": "1" })
2310 dev
[0].scan_for_bss(bssid
, freq
=2412)
2312 hapd_global
= hostapd
.HostapdGlobal(apdev
[0])
2314 hapd_global
.remove(apdev
[0]['ifname'])
2316 params
= hs20_ap_params()
2317 hostapd
.add_ap(apdev
[0], params
)
2319 dev
[0].hs20_enable()
2320 dev
[0].scan_for_bss(bssid
, freq
="2412")
2321 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
2322 id = dev
[0].add_cred_values(values
)
2323 check_bandwidth_selection(dev
[0], "home", False)
2324 dev
[0].remove_cred(id)
2326 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
2327 id = dev
[0].add_cred_values(values
)
2328 check_bandwidth_selection(dev
[0], "home", True)
2329 dev
[0].remove_cred(id)
2331 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
2332 id = dev
[0].add_cred_values(values
)
2333 check_bandwidth_selection(dev
[0], "home", True)
2334 dev
[0].remove_cred(id)
2336 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
2337 id = dev
[0].add_cred_values(values
)
2338 check_bandwidth_selection(dev
[0], "home", True)
2339 check_auto_select(dev
[0], bssid
)
2341 bssid2
= apdev
[1]['bssid']
2342 params
= hs20_ap_params(ssid
="test-hs20-b")
2343 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2344 hostapd
.add_ap(apdev
[1], params
)
2346 check_auto_select(dev
[0], bssid2
)
2348 dev
[0].flush_scan_cache()
2350 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
2351 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
2352 check_eap_capa(dev
[0], "MSCHAPV2")
2353 bssid
= apdev
[0]['bssid']
2354 params
= hs20_ap_params()
2355 hostapd
.add_ap(apdev
[0], params
)
2357 dev
[0].hs20_enable()
2358 dev
[0].scan_for_bss(bssid
, freq
="2412")
2359 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
2360 id = dev
[0].add_cred_values(values
)
2361 check_bandwidth_selection(dev
[0], "roaming", False)
2362 dev
[0].remove_cred(id)
2364 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
2365 id = dev
[0].add_cred_values(values
)
2366 check_bandwidth_selection(dev
[0], "roaming", True)
2367 dev
[0].remove_cred(id)
2369 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
2370 id = dev
[0].add_cred_values(values
)
2371 check_bandwidth_selection(dev
[0], "roaming", True)
2372 dev
[0].remove_cred(id)
2374 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
2375 id = dev
[0].add_cred_values(values
)
2376 check_bandwidth_selection(dev
[0], "roaming", True)
2377 check_auto_select(dev
[0], bssid
)
2379 bssid2
= apdev
[1]['bssid']
2380 params
= hs20_ap_params(ssid
="test-hs20-b")
2381 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2382 hostapd
.add_ap(apdev
[1], params
)
2384 check_auto_select(dev
[0], bssid2
)
2386 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
2387 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
2388 check_eap_capa(dev
[0], "MSCHAPV2")
2389 bssid
= apdev
[0]['bssid']
2390 params
= hs20_ap_params()
2391 params
['domain_name'] = "roaming.example.org"
2392 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
2393 hostapd
.add_ap(apdev
[0], params
)
2395 bssid2
= apdev
[1]['bssid']
2396 params
= hs20_ap_params(ssid
="test-hs20-b")
2397 params
['domain_name'] = "roaming.example.net"
2398 hostapd
.add_ap(apdev
[1], params
)
2400 values
= default_cred()
2401 values
['roaming_partner'] = "roaming.example.net,1,127,*"
2402 id = dev
[0].add_cred_values(values
)
2403 check_auto_select(dev
[0], bssid2
)
2405 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
2406 check_auto_select(dev
[0], bssid
)
2408 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
2409 check_auto_select(dev
[0], bssid2
)
2411 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
2412 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
2413 bssid
= apdev
[0]['bssid']
2414 params
= hs20_ap_params()
2415 del params
['hs20_wan_metrics']
2416 hostapd
.add_ap(apdev
[0], params
)
2418 dev
[0].hs20_enable()
2419 dev
[0].scan_for_bss(bssid
, freq
="2412")
2420 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
2421 dl_roaming
=10000, ul_roaming
=10000)
2422 dev
[0].add_cred_values(values
)
2423 check_bandwidth_selection(dev
[0], "home", False)
2425 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
2426 """Hotspot 2.0 connection and deauthentication request for ESS"""
2427 check_eap_capa(dev
[0], "MSCHAPV2")
2429 _test_ap_hs20_deauth_req_ess(dev
, apdev
)
2431 dev
[0].request("SET pmf 0")
2433 def _test_ap_hs20_deauth_req_ess(dev
, apdev
):
2434 dev
[0].request("SET pmf 2")
2435 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
2436 dev
[0].dump_monitor()
2437 addr
= dev
[0].p2p_interface_addr()
2438 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
2439 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
2440 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
2442 raise Exception("Timeout on deauth imminent notice")
2443 if "1 120 http://example.com/" not in ev
:
2444 raise Exception("Unexpected deauth imminent notice: " + ev
)
2445 hapd
.request("DEAUTHENTICATE " + addr
)
2446 dev
[0].wait_disconnected(timeout
=10)
2447 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
2448 raise Exception("Network not marked temporarily disabled")
2449 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
2450 "Trying to associate",
2451 "CTRL-EVENT-CONNECTED"], timeout
=5)
2453 raise Exception("Unexpected connection attempt")
2455 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
2456 """Hotspot 2.0 connection and deauthentication request for BSS"""
2457 check_eap_capa(dev
[0], "MSCHAPV2")
2459 _test_ap_hs20_deauth_req_bss(dev
, apdev
)
2461 dev
[0].request("SET pmf 0")
2463 def _test_ap_hs20_deauth_req_bss(dev
, apdev
):
2464 dev
[0].request("SET pmf 2")
2465 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
2466 dev
[0].dump_monitor()
2467 addr
= dev
[0].p2p_interface_addr()
2468 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
2469 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
2470 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
2472 raise Exception("Timeout on deauth imminent notice")
2473 if "0 120 http://example.com/" not in ev
:
2474 raise Exception("Unexpected deauth imminent notice: " + ev
)
2475 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
2476 ev
= dev
[0].wait_disconnected(timeout
=10)
2477 if "reason=4" not in ev
:
2478 raise Exception("Unexpected disconnection reason")
2479 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
2480 raise Exception("Network not marked temporarily disabled")
2481 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
2482 "Trying to associate",
2483 "CTRL-EVENT-CONNECTED"], timeout
=5)
2485 raise Exception("Unexpected connection attempt")
2487 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
2488 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
2489 check_eap_capa(dev
[0], "MSCHAPV2")
2491 _test_ap_hs20_deauth_req_from_radius(dev
, apdev
)
2493 dev
[0].request("SET pmf 0")
2495 def _test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
2496 bssid
= apdev
[0]['bssid']
2497 params
= hs20_ap_params()
2498 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
2499 params
['hs20_deauth_req_timeout'] = "2"
2500 hostapd
.add_ap(apdev
[0], params
)
2502 dev
[0].request("SET pmf 2")
2503 dev
[0].hs20_enable()
2504 dev
[0].add_cred_values({ 'realm': "example.com",
2505 'username': "hs20-deauth-test",
2506 'password': "password" })
2507 interworking_select(dev
[0], bssid
, freq
="2412")
2508 interworking_connect(dev
[0], bssid
, "TTLS")
2509 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
2511 raise Exception("Timeout on deauth imminent notice")
2512 if " 1 100" not in ev
:
2513 raise Exception("Unexpected deauth imminent contents")
2514 dev
[0].wait_disconnected(timeout
=3)
2516 def test_ap_hs20_deauth_req_without_pmf(dev
, apdev
):
2517 """Hotspot 2.0 connection and deauthentication request without PMF"""
2518 check_eap_capa(dev
[0], "MSCHAPV2")
2519 dev
[0].request("SET pmf 0")
2520 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user", release
=1)
2521 dev
[0].dump_monitor()
2522 id = int(dev
[0].get_status_field("id"))
2523 dev
[0].set_network(id, "ieee80211w", "0")
2524 dev
[0].request("DISCONNECT")
2525 dev
[0].wait_disconnected()
2526 dev
[0].select_network(id, freq
=2412)
2527 dev
[0].wait_connected()
2528 addr
= dev
[0].own_addr()
2529 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
2530 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
2531 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=0.2)
2533 raise Exception("Deauth imminent notice without PMF accepted")
2534 with
alloc_fail(hapd
, 1, "wpabuf_alloc;hostapd_ctrl_iface_hs20_deauth_req"):
2535 if "FAIL" not in hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/"):
2536 raise Exception("HS20_DEAUTH_REQ accepted during OOM")
2538 def test_ap_hs20_remediation_required(dev
, apdev
):
2539 """Hotspot 2.0 connection and remediation required from RADIUS"""
2540 check_eap_capa(dev
[0], "MSCHAPV2")
2542 _test_ap_hs20_remediation_required(dev
, apdev
)
2544 dev
[0].request("SET pmf 0")
2546 def _test_ap_hs20_remediation_required(dev
, apdev
):
2547 bssid
= apdev
[0]['bssid']
2548 params
= hs20_ap_params()
2549 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
2550 hostapd
.add_ap(apdev
[0], params
)
2552 dev
[0].request("SET pmf 1")
2553 dev
[0].hs20_enable()
2554 dev
[0].add_cred_values({ 'realm': "example.com",
2555 'username': "hs20-subrem-test",
2556 'password': "password" })
2557 interworking_select(dev
[0], bssid
, freq
="2412")
2558 interworking_connect(dev
[0], bssid
, "TTLS")
2559 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2561 raise Exception("Timeout on subscription remediation notice")
2562 if " 1 https://example.com/" not in ev
:
2563 raise Exception("Unexpected subscription remediation event contents")
2565 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
2566 """Hotspot 2.0 connection and subrem from ctrl_iface"""
2567 check_eap_capa(dev
[0], "MSCHAPV2")
2569 _test_ap_hs20_remediation_required_ctrl(dev
, apdev
)
2571 dev
[0].request("SET pmf 0")
2573 def _test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
2574 bssid
= apdev
[0]['bssid']
2575 addr
= dev
[0].own_addr()
2576 params
= hs20_ap_params()
2577 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
2578 hapd
= hostapd
.add_ap(apdev
[0], params
)
2580 dev
[0].request("SET pmf 1")
2581 dev
[0].hs20_enable()
2582 dev
[0].add_cred_values(default_cred())
2583 interworking_select(dev
[0], bssid
, freq
="2412")
2584 interworking_connect(dev
[0], bssid
, "TTLS")
2586 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
2587 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2589 raise Exception("Timeout on subscription remediation notice")
2590 if " 1 https://example.com/" not in ev
:
2591 raise Exception("Unexpected subscription remediation event contents")
2593 hapd
.request("HS20_WNM_NOTIF " + addr
)
2594 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2596 raise Exception("Timeout on subscription remediation notice")
2597 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
2598 raise Exception("Unexpected subscription remediation event contents: " + ev
)
2600 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
2601 raise Exception("Unexpected HS20_WNM_NOTIF success")
2602 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
2603 raise Exception("Unexpected HS20_WNM_NOTIF success")
2604 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
2605 raise Exception("Unexpected HS20_WNM_NOTIF success")
2606 if "OK" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " "):
2607 raise Exception("HS20_WNM_NOTIF failed with empty URL")
2609 def test_ap_hs20_session_info(dev
, apdev
):
2610 """Hotspot 2.0 connection and session information from RADIUS"""
2611 check_eap_capa(dev
[0], "MSCHAPV2")
2613 _test_ap_hs20_session_info(dev
, apdev
)
2615 dev
[0].request("SET pmf 0")
2617 def _test_ap_hs20_session_info(dev
, apdev
):
2618 bssid
= apdev
[0]['bssid']
2619 params
= hs20_ap_params()
2620 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
2621 hostapd
.add_ap(apdev
[0], params
)
2623 dev
[0].request("SET pmf 1")
2624 dev
[0].hs20_enable()
2625 dev
[0].add_cred_values({ 'realm': "example.com",
2626 'username': "hs20-session-info-test",
2627 'password': "password" })
2628 interworking_select(dev
[0], bssid
, freq
="2412")
2629 interworking_connect(dev
[0], bssid
, "TTLS")
2630 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
2632 raise Exception("Timeout on ESS disassociation imminent notice")
2633 if " 1 59904 https://example.com/" not in ev
:
2634 raise Exception("Unexpected ESS disassociation imminent event contents")
2635 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
2637 raise Exception("Scan not started")
2638 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
2640 raise Exception("Scan not completed")
2642 def test_ap_hs20_osen(dev
, apdev
):
2643 """Hotspot 2.0 OSEN connection"""
2644 params
= { 'ssid': "osen",
2646 'auth_server_addr': "127.0.0.1",
2647 'auth_server_port': "1812",
2648 'auth_server_shared_secret': "radius" }
2649 hostapd
.add_ap(apdev
[0], params
)
2651 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
2653 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
2654 scan_freq
="2412", wait_connect
=False)
2655 dev
[0].flush_scan_cache()
2656 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2657 group
="GTK_NOT_USED CCMP",
2658 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2659 ca_cert
="auth_serv/ca.pem",
2661 res
= dev
[0].get_bss(apdev
[0]['bssid'])['flags']
2662 if "[OSEN-OSEN-CCMP]" not in res
:
2663 raise Exception("OSEN not reported in BSS")
2665 raise Exception("WEP reported in BSS")
2666 res
= dev
[0].request("SCAN_RESULTS")
2667 if "[OSEN-OSEN-CCMP]" not in res
:
2668 raise Exception("OSEN not reported in SCAN_RESULTS")
2670 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2671 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
2672 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2673 group
="GTK_NOT_USED CCMP",
2674 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2675 ca_cert
="auth_serv/ca.pem",
2677 wpas
.request("DISCONNECT")
2679 def test_ap_hs20_osen_single_ssid(dev
, apdev
):
2680 """Hotspot 2.0 OSEN-single-SSID connection"""
2681 bssid
= apdev
[0]['bssid']
2682 params
= hs20_ap_params()
2683 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
2684 params
['hessid'] = bssid
2685 hapd
= hostapd
.add_ap(apdev
[0], params
)
2687 # RSN-OSEN (for OSU)
2688 dev
[0].connect("test-hs20", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
2689 group
="CCMP GTK_NOT_USED",
2690 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
2691 ca_cert
="auth_serv/ca.pem", ieee80211w
='2',
2693 # RSN-EAP (for data connection)
2694 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2695 identity
="hs20-test", password
="password",
2696 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2697 pairwise
="CCMP", group
="CCMP",
2698 ieee80211w
='2', scan_freq
="2412")
2700 res
= dev
[0].get_bss(apdev
[0]['bssid'])['flags']
2701 if "[WPA2-EAP+OSEN-CCMP]" not in res
:
2702 raise Exception("OSEN not reported in BSS")
2704 raise Exception("WEP reported in BSS")
2705 res
= dev
[0].request("SCAN_RESULTS")
2706 if "[WPA2-EAP+OSEN-CCMP]" not in res
:
2707 raise Exception("OSEN not reported in SCAN_RESULTS")
2709 hwsim_utils
.test_connectivity(dev
[1], hapd
)
2710 hwsim_utils
.test_connectivity(dev
[0], hapd
, broadcast
=False)
2711 hwsim_utils
.test_connectivity(dev
[0], hapd
, timeout
=1,
2712 success_expected
=False)
2714 def test_ap_hs20_network_preference(dev
, apdev
):
2715 """Hotspot 2.0 network selection with preferred home network"""
2716 check_eap_capa(dev
[0], "MSCHAPV2")
2717 bssid
= apdev
[0]['bssid']
2718 params
= hs20_ap_params()
2719 hostapd
.add_ap(apdev
[0], params
)
2721 dev
[0].hs20_enable()
2722 values
= { 'realm': "example.com",
2723 'username': "hs20-test",
2724 'password': "password",
2725 'domain': "example.com" }
2726 dev
[0].add_cred_values(values
)
2728 id = dev
[0].add_network()
2729 dev
[0].set_network_quoted(id, "ssid", "home")
2730 dev
[0].set_network_quoted(id, "psk", "12345678")
2731 dev
[0].set_network(id, "priority", "1")
2732 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2734 dev
[0].scan_for_bss(bssid
, freq
="2412")
2735 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2736 ev
= dev
[0].wait_connected(timeout
=15)
2738 raise Exception("Unexpected network selected")
2740 bssid2
= apdev
[1]['bssid']
2741 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2742 hostapd
.add_ap(apdev
[1], params
)
2744 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2745 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2746 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2747 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2749 raise Exception("Connection timed out")
2750 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2751 raise Exception("No roam to higher priority network")
2752 if bssid2
not in ev
:
2753 raise Exception("Unexpected network selected")
2755 def test_ap_hs20_network_preference2(dev
, apdev
):
2756 """Hotspot 2.0 network selection with preferred credential"""
2757 check_eap_capa(dev
[0], "MSCHAPV2")
2758 bssid2
= apdev
[1]['bssid']
2759 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
2760 hostapd
.add_ap(apdev
[1], params
)
2762 dev
[0].hs20_enable()
2763 values
= { 'realm': "example.com",
2764 'username': "hs20-test",
2765 'password': "password",
2766 'domain': "example.com",
2768 dev
[0].add_cred_values(values
)
2770 id = dev
[0].add_network()
2771 dev
[0].set_network_quoted(id, "ssid", "home")
2772 dev
[0].set_network_quoted(id, "psk", "12345678")
2773 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2775 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2776 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2777 ev
= dev
[0].wait_connected(timeout
=15)
2778 if bssid2
not in ev
:
2779 raise Exception("Unexpected network selected")
2781 bssid
= apdev
[0]['bssid']
2782 params
= hs20_ap_params()
2783 hostapd
.add_ap(apdev
[0], params
)
2785 dev
[0].scan_for_bss(bssid
, freq
="2412")
2786 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2787 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2788 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2790 raise Exception("Connection timed out")
2791 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2792 raise Exception("No roam to higher priority network")
2794 raise Exception("Unexpected network selected")
2796 def test_ap_hs20_network_preference3(dev
, apdev
):
2797 """Hotspot 2.0 network selection with two credential (one preferred)"""
2798 check_eap_capa(dev
[0], "MSCHAPV2")
2799 bssid
= apdev
[0]['bssid']
2800 params
= hs20_ap_params()
2801 hostapd
.add_ap(apdev
[0], params
)
2803 bssid2
= apdev
[1]['bssid']
2804 params
= hs20_ap_params(ssid
="test-hs20b")
2805 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
2806 hostapd
.add_ap(apdev
[1], params
)
2808 dev
[0].hs20_enable()
2809 values
= { 'realm': "example.com",
2810 'username': "hs20-test",
2811 'password': "password",
2813 dev
[0].add_cred_values(values
)
2814 values
= { 'realm': "example.org",
2815 'username': "hs20-test",
2816 'password': "password" }
2817 id = dev
[0].add_cred_values(values
)
2819 dev
[0].scan_for_bss(bssid
, freq
="2412")
2820 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2821 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2822 ev
= dev
[0].wait_connected(timeout
=15)
2824 raise Exception("Unexpected network selected")
2826 dev
[0].set_cred(id, "priority", "2")
2827 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2828 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2829 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2831 raise Exception("Connection timed out")
2832 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2833 raise Exception("No roam to higher priority network")
2834 if bssid2
not in ev
:
2835 raise Exception("Unexpected network selected")
2837 def test_ap_hs20_network_preference4(dev
, apdev
):
2838 """Hotspot 2.0 network selection with username vs. SIM credential"""
2839 check_eap_capa(dev
[0], "MSCHAPV2")
2840 bssid
= apdev
[0]['bssid']
2841 params
= hs20_ap_params()
2842 hostapd
.add_ap(apdev
[0], params
)
2844 bssid2
= apdev
[1]['bssid']
2845 params
= hs20_ap_params(ssid
="test-hs20b")
2846 params
['hessid'] = bssid2
2847 params
['anqp_3gpp_cell_net'] = "555,444"
2848 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
2849 hostapd
.add_ap(apdev
[1], params
)
2851 dev
[0].hs20_enable()
2852 values
= { 'realm': "example.com",
2853 'username': "hs20-test",
2854 'password': "password",
2856 dev
[0].add_cred_values(values
)
2857 values
= { 'imsi': "555444-333222111",
2859 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
2860 id = dev
[0].add_cred_values(values
)
2862 dev
[0].scan_for_bss(bssid
, freq
="2412")
2863 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2864 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2865 ev
= dev
[0].wait_connected(timeout
=15)
2867 raise Exception("Unexpected network selected")
2869 dev
[0].set_cred(id, "priority", "2")
2870 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2871 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2872 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2874 raise Exception("Connection timed out")
2875 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2876 raise Exception("No roam to higher priority network")
2877 if bssid2
not in ev
:
2878 raise Exception("Unexpected network selected")
2880 def test_ap_hs20_interworking_select_blocking_scan(dev
, apdev
):
2881 """Ongoing INTERWORKING_SELECT blocking SCAN"""
2882 check_eap_capa(dev
[0], "MSCHAPV2")
2883 bssid
= apdev
[0]['bssid']
2884 params
= hs20_ap_params()
2885 hostapd
.add_ap(apdev
[0], params
)
2887 dev
[0].hs20_enable()
2888 values
= { 'realm': "example.com",
2889 'username': "hs20-test",
2890 'password': "password",
2891 'domain': "example.com" }
2892 dev
[0].add_cred_values(values
)
2894 dev
[0].scan_for_bss(bssid
, freq
="2412")
2895 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2896 if "FAIL-BUSY" not in dev
[0].request("SCAN"):
2897 raise Exception("Unexpected SCAN command result")
2898 dev
[0].wait_connected(timeout
=15)
2900 def test_ap_hs20_fetch_osu(dev
, apdev
):
2901 """Hotspot 2.0 OSU provider and icon fetch"""
2902 bssid
= apdev
[0]['bssid']
2903 params
= hs20_ap_params()
2904 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2905 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2906 params
['osu_method_list'] = "1"
2907 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2908 params
['osu_icon'] = "w1fi_logo"
2909 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2910 params
['osu_server_uri'] = "https://example.com/osu/"
2911 hostapd
.add_ap(apdev
[0], params
)
2913 bssid2
= apdev
[1]['bssid']
2914 params
= hs20_ap_params(ssid
="test-hs20b")
2915 params
['hessid'] = bssid2
2916 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2917 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2918 params
['osu_method_list'] = "0"
2919 params
['osu_nai'] = "osen@example.com"
2920 params
['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
2921 params
['osu_icon'] = "w1fi_logo"
2922 params
['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
2923 params
['osu_server_uri'] = "https://example.org/osu/"
2924 hostapd
.add_ap(apdev
[1], params
)
2926 with
open("w1fi_logo.png", "r") as f
:
2927 orig_logo
= f
.read()
2928 dev
[0].hs20_enable()
2929 dir = "/tmp/osu-fetch"
2930 if os
.path
.isdir(dir):
2931 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2933 os
.remove(dir + "/" + f
)
2940 dev
[1].scan_for_bss(bssid
, freq
="2412")
2941 dev
[2].scan_for_bss(bssid
, freq
="2412")
2942 dev
[0].request("SET osu_dir " + dir)
2943 dev
[0].request("FETCH_OSU")
2944 if "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2945 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2946 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2947 raise Exception("HS20_ICON_REQUEST failed")
2948 if "OK" not in dev
[2].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
2949 raise Exception("REQ_HS20_ICON failed")
2952 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2953 "RX-HS20-ANQP-ICON"], timeout
=15)
2955 raise Exception("Timeout on OSU fetch")
2956 if "OSU provider fetch completed" in ev
:
2958 if "RX-HS20-ANQP-ICON" in ev
:
2959 with
open(ev
.split(' ')[1], "r") as f
:
2961 if logo
== orig_logo
:
2964 with
open(dir + "/osu-providers.txt", "r") as f
:
2966 logger
.debug("osu-providers.txt: " + prov
)
2967 if "OSU-PROVIDER " + bssid
not in prov
:
2968 raise Exception("Missing OSU_PROVIDER(1)")
2969 if "OSU-PROVIDER " + bssid2
not in prov
:
2970 raise Exception("Missing OSU_PROVIDER(2)")
2972 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2974 os
.remove(dir + "/" + f
)
2978 raise Exception("Unexpected number of icons fetched")
2980 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2982 raise Exception("Timeout on GAS-QUERY-DONE")
2983 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2985 raise Exception("Timeout on GAS-QUERY-DONE")
2986 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2987 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2988 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2990 raise Exception("Timeout on icon fetch")
2991 if "Icon Binary File" not in ev
:
2992 raise Exception("Unexpected ANQP element")
2994 ev
= dev
[2].wait_event(["RX-HS20-ICON"], timeout
=5)
2996 raise Exception("Timeout on RX-HS20-ICON")
2997 event_icon_len
= ev
.split(' ')[3]
2998 if " w1fi_logo " not in ev
:
2999 raise Exception("RX-HS20-ICON did not have the expected file name")
3001 raise Exception("RX-HS20-ICON did not have the expected BSSID")
3002 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 10"):
3003 raise Exception("GET_HS20_ICON 0..10 failed")
3004 if "FAIL" in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 5 10"):
3005 raise Exception("GET_HS20_ICON 5..15 failed")
3006 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 100000 10"):
3007 raise Exception("Unexpected success of GET_HS20_ICON with too large offset")
3008 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " no_such_logo 0 10"):
3009 raise Exception("GET_HS20_ICON for not existing icon succeeded")
3010 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 3070"):
3011 raise Exception("GET_HS20_ICON with too many output bytes to fit the buffer succeeded")
3012 if "FAIL" not in dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo 0 0"):
3013 raise Exception("GET_HS20_ICON 0..0 succeeded")
3018 raise Exception("Unexpectedly long icon")
3019 res
= dev
[2].request("GET_HS20_ICON " + bssid
+ " w1fi_logo %d 1000" % pos
)
3020 if res
.startswith("FAIL"):
3022 icon
+= base64
.b64decode(res
)
3024 hex = binascii
.hexlify(icon
).decode()
3025 if not hex.startswith("0009696d6167652f706e677d1d"):
3026 raise Exception("Unexpected beacon binary header: " + hex)
3027 with
open('w1fi_logo.png', 'r') as f
:
3029 if icon
[13:] != data
:
3030 raise Exception("Unexpected icon data")
3031 if len(icon
) != int(event_icon_len
):
3032 raise Exception("Unexpected RX-HS20-ICON event length: " + event_icon_len
)
3035 if "OK" not in dev
[i
].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3036 raise Exception("REQ_HS20_ICON failed [2]")
3038 ev
= dev
[i
].wait_event(["RX-HS20-ICON"], timeout
=5)
3040 raise Exception("Timeout on RX-HS20-ICON [2]")
3042 if "FAIL" not in dev
[2].request("DEL_HS20_ICON foo w1fi_logo"):
3043 raise Exception("Invalid DEL_HS20_ICON accepted")
3044 if "OK" not in dev
[2].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3045 raise Exception("DEL_HS20_ICON failed")
3046 if "OK" not in dev
[1].request("DEL_HS20_ICON " + bssid
):
3047 raise Exception("DEL_HS20_ICON failed")
3048 if "OK" not in dev
[0].request("DEL_HS20_ICON "):
3049 raise Exception("DEL_HS20_ICON failed")
3051 if "FAIL" not in dev
[i
].request("DEL_HS20_ICON "):
3052 raise Exception("DEL_HS20_ICON accepted when no icons left")
3054 def test_ap_hs20_fetch_osu_no_info(dev
, apdev
):
3055 """Hotspot 2.0 OSU provider and no AP with info"""
3056 bssid
= apdev
[0]['bssid']
3057 params
= hs20_ap_params()
3058 hostapd
.add_ap(apdev
[0], params
)
3060 dev
[0].hs20_enable()
3061 dir = "/tmp/osu-fetch"
3062 if os
.path
.isdir(dir):
3063 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3065 os
.remove(dir + "/" + f
)
3071 dev
[0].scan_for_bss(bssid
, freq
="2412")
3073 dev
[0].request("SET osu_dir " + dir)
3074 dev
[0].request("FETCH_OSU")
3075 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3077 raise Exception("Timeout on OSU fetch")
3079 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3081 os
.remove(dir + "/" + f
)
3084 def test_ap_hs20_fetch_osu_no_icon(dev
, apdev
):
3085 """Hotspot 2.0 OSU provider and no icon found"""
3086 bssid
= apdev
[0]['bssid']
3087 params
= hs20_ap_params()
3088 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3089 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3090 params
['osu_method_list'] = "1"
3091 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3092 params
['osu_icon'] = "w1fi_logo"
3093 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3094 params
['osu_server_uri'] = "https://example.com/osu/"
3095 hostapd
.add_ap(apdev
[0], params
)
3097 dev
[0].hs20_enable()
3098 dir = "/tmp/osu-fetch"
3099 if os
.path
.isdir(dir):
3100 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3102 os
.remove(dir + "/" + f
)
3108 dev
[0].scan_for_bss(bssid
, freq
="2412")
3110 dev
[0].request("SET osu_dir " + dir)
3111 dev
[0].request("FETCH_OSU")
3112 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3114 raise Exception("Timeout on OSU fetch")
3116 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3118 os
.remove(dir + "/" + f
)
3121 def test_ap_hs20_fetch_osu_single_ssid(dev
, apdev
):
3122 """Hotspot 2.0 OSU provider and single SSID"""
3123 bssid
= apdev
[0]['bssid']
3124 params
= hs20_ap_params()
3125 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3126 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3127 params
['osu_method_list'] = "1"
3128 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3129 params
['osu_nai2'] = "osen@example.com"
3130 params
['osu_icon'] = "w1fi_logo"
3131 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3132 params
['osu_server_uri'] = "https://example.com/osu/"
3133 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
3134 hostapd
.add_ap(apdev
[0], params
)
3136 dev
[0].hs20_enable()
3137 dir = "/tmp/osu-fetch"
3138 if os
.path
.isdir(dir):
3139 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3141 os
.remove(dir + "/" + f
)
3147 dev
[0].scan_for_bss(bssid
, freq
="2412")
3149 dev
[0].request("SET osu_dir " + dir)
3150 dev
[0].request("FETCH_OSU")
3151 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3153 raise Exception("Timeout on OSU fetch")
3158 with
open(os
.path
.join(dir, "osu-providers.txt"), "r") as f
:
3159 for l
in f
.readlines():
3160 logger
.info(l
.strip())
3161 if l
.strip() == "osu_ssid=HS 2.0 OSU open":
3163 if l
.strip() == "osu_ssid2=test-hs20":
3165 if l
.strip().startswith("osu_nai="):
3167 if l
.strip() == "osu_nai2=osen@example.com":
3170 raise Exception("osu_ssid not reported")
3172 raise Exception("osu_ssid2 not reported")
3174 raise Exception("osu_nai reported unexpectedly")
3176 raise Exception("osu_nai2 not reported")
3178 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3180 os
.remove(dir + "/" + f
)
3183 def test_ap_hs20_fetch_osu_single_ssid2(dev
, apdev
):
3184 """Hotspot 2.0 OSU provider and single SSID (two OSU providers)"""
3185 bssid
= apdev
[0]['bssid']
3186 params
= hs20_ap_params()
3187 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo-no-file.png"
3188 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3189 params
['osu_method_list'] = "1"
3190 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3191 params
['osu_nai2'] = "osen@example.com"
3192 params
['osu_icon'] = "w1fi_logo"
3193 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3194 params
['osu_server_uri'] = "https://example.com/osu/"
3195 params
['wpa_key_mgmt'] = "WPA-EAP OSEN"
3196 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
3198 hapd
.set('osu_server_uri', 'https://another.example.com/osu/')
3199 hapd
.set('osu_method_list', "1")
3200 hapd
.set('osu_nai2', "osen@another.example.com")
3203 dev
[0].hs20_enable()
3204 dir = "/tmp/osu-fetch"
3205 if os
.path
.isdir(dir):
3206 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3208 os
.remove(dir + "/" + f
)
3214 dev
[0].scan_for_bss(bssid
, freq
="2412")
3216 dev
[0].request("SET osu_dir " + dir)
3217 dev
[0].request("FETCH_OSU")
3218 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3220 raise Exception("Timeout on OSU fetch")
3226 with
open(os
.path
.join(dir, "osu-providers.txt"), "r") as f
:
3227 for l
in f
.readlines():
3228 logger
.info(l
.strip())
3229 if l
.strip() == "osu_ssid=HS 2.0 OSU open":
3231 if l
.strip() == "osu_ssid2=test-hs20":
3233 if l
.strip().startswith("osu_nai="):
3235 if l
.strip() == "osu_nai2=osen@example.com":
3237 if l
.strip() == "osu_nai2=osen@another.example.com":
3240 raise Exception("osu_ssid not reported")
3242 raise Exception("osu_ssid2 not reported")
3244 raise Exception("osu_nai reported unexpectedly")
3246 raise Exception("osu_nai2 not reported")
3248 raise Exception("osu_nai2b not reported")
3250 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3252 os
.remove(dir + "/" + f
)
3255 def get_icon(dev
, bssid
, iconname
):
3260 raise Exception("Unexpectedly long icon")
3261 res
= dev
.request("GET_HS20_ICON " + bssid
+ " " + iconname
+ " %d 3000" % pos
)
3262 if res
.startswith("FAIL"):
3264 icon
+= base64
.b64decode(res
)
3267 raise Exception("Too short GET_HS20_ICON response")
3268 return icon
[0:13], icon
[13:]
3270 def test_ap_hs20_req_hs20_icon(dev
, apdev
):
3271 """Hotspot 2.0 OSU provider and multi-icon fetch with REQ_HS20_ICON"""
3272 bssid
= apdev
[0]['bssid']
3273 params
= hs20_ap_params()
3274 params
['hs20_icon'] = [ "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3275 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem" ]
3276 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3277 params
['osu_method_list'] = "1"
3278 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3279 params
['osu_icon'] = [ "w1fi_logo", "w1fi_logo2" ]
3280 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3281 params
['osu_server_uri'] = "https://example.com/osu/"
3282 hostapd
.add_ap(apdev
[0], params
)
3284 dev
[0].scan_for_bss(bssid
, freq
="2412")
3285 run_req_hs20_icon(dev
, bssid
)
3287 def run_req_hs20_icon(dev
, bssid
):
3288 # First, fetch two icons from the AP to wpa_supplicant
3290 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3291 raise Exception("REQ_HS20_ICON failed")
3292 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3294 raise Exception("Timeout on RX-HS20-ICON (1)")
3296 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
3297 raise Exception("REQ_HS20_ICON failed")
3298 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3300 raise Exception("Timeout on RX-HS20-ICON (2)")
3302 # Then, fetch the icons from wpa_supplicant for validation
3304 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
3305 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
3307 with
open('w1fi_logo.png', 'r') as f
:
3310 raise Exception("Unexpected icon data (1)")
3312 with
open('auth_serv/sha512-server.pem', 'r') as f
:
3315 raise Exception("Unexpected icon data (2)")
3317 # Finally, delete the icons from wpa_supplicant
3319 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3320 raise Exception("DEL_HS20_ICON failed")
3321 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
3322 raise Exception("DEL_HS20_ICON failed")
3324 def test_ap_hs20_req_operator_icon(dev
, apdev
):
3325 """Hotspot 2.0 operator icons"""
3326 bssid
= apdev
[0]['bssid']
3327 params
= hs20_ap_params()
3328 params
['hs20_icon'] = [ "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3329 "500:300:fi:image/png:test_logo:auth_serv/sha512-server.pem" ]
3330 params
['operator_icon'] = [ "w1fi_logo", "unknown_logo", "test_logo" ]
3331 hostapd
.add_ap(apdev
[0], params
)
3333 value
= struct
.pack('<HH', 128, 80) + b
"zxx"
3334 value
+= struct
.pack('B', 9) + b
"image/png"
3335 value
+= struct
.pack('B', 9) + b
"w1fi_logo"
3337 value
+= struct
.pack('<HH', 500, 300) + b
"fi\0"
3338 value
+= struct
.pack('B', 9) + b
"image/png"
3339 value
+= struct
.pack('B', 9) + b
"test_logo"
3341 dev
[0].scan_for_bss(bssid
, freq
="2412")
3343 if "OK" not in dev
[0].request("ANQP_GET " + bssid
+ " hs20:12"):
3344 raise Exception("ANQP_GET command failed")
3346 ev
= dev
[0].wait_event(["GAS-QUERY-START"], timeout
=5)
3348 raise Exception("GAS query start timed out")
3350 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
3352 raise Exception("GAS query timed out")
3354 ev
= dev
[0].wait_event(["RX-HS20-ANQP"], timeout
=1)
3355 if ev
is None or "Operator Icon Metadata" not in ev
:
3356 raise Exception("Did not receive Operator Icon Metadata")
3358 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=10)
3360 raise Exception("ANQP-QUERY-DONE event not seen")
3361 if "result=SUCCESS" not in ev
:
3362 raise Exception("Unexpected result: " + ev
)
3364 bss
= dev
[0].get_bss(bssid
)
3365 if "hs20_operator_icon_metadata" not in bss
:
3366 raise Exception("hs20_operator_icon_metadata missing from BSS entry")
3367 if bss
["hs20_operator_icon_metadata"] != binascii
.hexlify(value
).decode():
3368 print(binascii
.hexlify(value
))
3369 raise Exception("Unexpected hs20_operator_icon_metadata value: " +
3370 bss
["hs20_operator_icon_metadata"])
3372 run_req_hs20_icon(dev
, bssid
)
3374 def test_ap_hs20_req_hs20_icon_oom(dev
, apdev
):
3375 """Hotspot 2.0 icon fetch OOM with REQ_HS20_ICON"""
3376 bssid
= apdev
[0]['bssid']
3377 params
= hs20_ap_params()
3378 params
['hs20_icon'] = [ "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3379 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem" ]
3380 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3381 params
['osu_method_list'] = "1"
3382 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3383 params
['osu_icon'] = [ "w1fi_logo", "w1fi_logo2" ]
3384 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3385 params
['osu_server_uri'] = "https://example.com/osu/"
3386 hostapd
.add_ap(apdev
[0], params
)
3388 dev
[0].scan_for_bss(bssid
, freq
="2412")
3390 if "FAIL" not in dev
[0].request("REQ_HS20_ICON 11:22:33:44:55:66 w1fi_logo"):
3391 raise Exception("REQ_HS20_ICON succeeded with unknown BSSID")
3393 with
alloc_fail(dev
[0], 1, "hs20_build_anqp_req;hs20_anqp_send_req"):
3394 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3395 raise Exception("REQ_HS20_ICON succeeded during OOM")
3397 with
alloc_fail(dev
[0], 1, "gas_query_req;hs20_anqp_send_req"):
3398 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3399 raise Exception("REQ_HS20_ICON succeeded during OOM")
3401 with
alloc_fail(dev
[0], 1, "=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")
3404 with
alloc_fail(dev
[0], 2, "=hs20_anqp_send_req"):
3405 if "FAIL" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3406 raise Exception("REQ_HS20_ICON succeeded during OOM")
3408 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3409 raise Exception("REQ_HS20_ICON failed")
3410 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3412 raise Exception("Timeout on RX-HS20-ICON (1)")
3414 with
alloc_fail(dev
[0], 1, "hs20_get_icon"):
3415 if "FAIL" not in dev
[0].request("GET_HS20_ICON " + bssid
+ "w1fi_logo 0 100"):
3416 raise Exception("GET_HS20_ICON succeeded during OOM")
3418 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3419 raise Exception("DEL_HS20_ICON failed")
3421 with
alloc_fail(dev
[0], 1, "=hs20_process_icon_binary_file"):
3422 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3423 raise Exception("REQ_HS20_ICON failed")
3424 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
3426 def test_ap_hs20_req_hs20_icon_parallel(dev
, apdev
):
3427 """Hotspot 2.0 OSU provider and multi-icon parallel fetch with REQ_HS20_ICON"""
3428 bssid
= apdev
[0]['bssid']
3429 params
= hs20_ap_params()
3430 params
['hs20_icon'] = [ "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png",
3431 "128:80:zxx:image/png:test_logo:auth_serv/sha512-server.pem" ]
3432 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3433 params
['osu_method_list'] = "1"
3434 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3435 params
['osu_icon'] = [ "w1fi_logo", "w1fi_logo2" ]
3436 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3437 params
['osu_server_uri'] = "https://example.com/osu/"
3438 hostapd
.add_ap(apdev
[0], params
)
3440 dev
[0].scan_for_bss(bssid
, freq
="2412")
3442 # First, fetch two icons from the AP to wpa_supplicant
3444 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " w1fi_logo"):
3445 raise Exception("REQ_HS20_ICON failed")
3447 if "OK" not in dev
[0].request("REQ_HS20_ICON " + bssid
+ " test_logo"):
3448 raise Exception("REQ_HS20_ICON failed")
3449 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3451 raise Exception("Timeout on RX-HS20-ICON (1)")
3452 ev
= dev
[0].wait_event(["RX-HS20-ICON"], timeout
=5)
3454 raise Exception("Timeout on RX-HS20-ICON (2)")
3456 # Then, fetch the icons from wpa_supplicant for validation
3458 hdr
, data1
= get_icon(dev
[0], bssid
, "w1fi_logo")
3459 hdr
, data2
= get_icon(dev
[0], bssid
, "test_logo")
3461 with
open('w1fi_logo.png', 'r') as f
:
3464 raise Exception("Unexpected icon data (1)")
3466 with
open('auth_serv/sha512-server.pem', 'r') as f
:
3469 raise Exception("Unexpected icon data (2)")
3471 # Finally, delete the icons from wpa_supplicant
3473 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " w1fi_logo"):
3474 raise Exception("DEL_HS20_ICON failed")
3475 if "OK" not in dev
[0].request("DEL_HS20_ICON " + bssid
+ " test_logo"):
3476 raise Exception("DEL_HS20_ICON failed")
3478 def test_ap_hs20_fetch_osu_stop(dev
, apdev
):
3479 """Hotspot 2.0 OSU provider fetch stopped"""
3480 bssid
= apdev
[0]['bssid']
3481 params
= hs20_ap_params()
3482 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3483 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3484 params
['osu_method_list'] = "1"
3485 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3486 params
['osu_icon'] = "w1fi_logo"
3487 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3488 params
['osu_server_uri'] = "https://example.com/osu/"
3489 hapd
= hostapd
.add_ap(apdev
[0], params
)
3491 dev
[0].hs20_enable()
3492 dir = "/tmp/osu-fetch"
3493 if os
.path
.isdir(dir):
3494 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3496 os
.remove(dir + "/" + f
)
3503 dev
[0].request("SET osu_dir " + dir)
3504 dev
[0].request("SCAN freq=2412-2462")
3505 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=10)
3507 raise Exception("Scan did not start")
3508 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3509 raise Exception("FETCH_OSU accepted while scanning")
3510 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
3512 raise Exception("Scan timed out")
3513 hapd
.set("ext_mgmt_frame_handling", "1")
3514 dev
[0].request("FETCH_ANQP")
3515 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3516 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
3517 dev
[0].request("STOP_FETCH_ANQP")
3518 dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=5)
3519 dev
[0].dump_monitor()
3521 dev
[0].request("INTERWORKING_SELECT freq=2412")
3523 msg
= hapd
.mgmt_rx()
3524 if msg
['subtype'] == 13:
3526 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3527 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
3528 ev
= dev
[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
3531 raise Exception("Network selection timed out")
3533 dev
[0].dump_monitor()
3534 if "OK" not in dev
[0].request("FETCH_OSU"):
3535 raise Exception("FETCH_OSU failed")
3536 dev
[0].request("CANCEL_FETCH_OSU")
3540 if dev
[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
3543 dev
[0].dump_monitor()
3544 if "OK" not in dev
[0].request("FETCH_OSU"):
3545 raise Exception("FETCH_OSU failed")
3546 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3547 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
3548 ev
= dev
[0].wait_event(["GAS-QUERY-START"], 10)
3550 raise Exception("GAS timed out")
3551 if "FAIL" not in dev
[0].request("FETCH_OSU"):
3552 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
3553 dev
[0].request("CANCEL_FETCH_OSU")
3554 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], 10)
3556 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
3558 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3560 os
.remove(dir + "/" + f
)
3563 def test_ap_hs20_fetch_osu_proto(dev
, apdev
):
3564 """Hotspot 2.0 OSU provider and protocol testing"""
3565 bssid
= apdev
[0]['bssid']
3566 params
= hs20_ap_params()
3567 hapd
= hostapd
.add_ap(apdev
[0], params
)
3569 dev
[0].hs20_enable()
3570 dir = "/tmp/osu-fetch"
3571 if os
.path
.isdir(dir):
3572 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3574 os
.remove(dir + "/" + f
)
3581 tests
= [ ( "Empty provider list (no OSU SSID field)", b
'' ),
3582 ( "HS 2.0: Not enough room for OSU SSID",
3583 binascii
.unhexlify('01') ),
3584 ( "HS 2.0: Invalid OSU SSID Length 33",
3585 binascii
.unhexlify('21') + 33*b
'A' ),
3586 ( "HS 2.0: Not enough room for Number of OSU Providers",
3587 binascii
.unhexlify('0130') ),
3588 ( "Truncated OSU Provider",
3589 binascii
.unhexlify('013001020000') ),
3590 ( "HS 2.0: Ignored 5 bytes of extra data after OSU Providers",
3591 binascii
.unhexlify('0130001122334455') ),
3592 ( "HS 2.0: Not enough room for OSU Friendly Name Length",
3593 binascii
.unhexlify('013001000000') ),
3594 ( "HS 2.0: Not enough room for OSU Friendly Name Duples",
3595 build_prov('0100') ),
3596 ( "Invalid OSU Friendly Name", build_prov('040000000000') ),
3597 ( "Invalid OSU Friendly Name(2)", build_prov('040004000000') ),
3598 ( "HS 2.0: Not enough room for OSU Server URI length",
3599 build_prov('0000') ),
3600 ( "HS 2.0: Not enough room for OSU Server URI",
3601 build_prov('000001') ),
3602 ( "HS 2.0: Not enough room for OSU Method list length",
3603 build_prov('000000') ),
3604 ( "HS 2.0: Not enough room for OSU Method list",
3605 build_prov('00000001') ),
3606 ( "HS 2.0: Not enough room for Icons Available Length",
3607 build_prov('00000000') ),
3608 ( "HS 2.0: Not enough room for Icons Available Length(2)",
3609 build_prov('00000001ff00') ),
3610 ( "HS 2.0: Not enough room for Icons Available",
3611 build_prov('000000000100') ),
3612 ( "HS 2.0: Invalid Icon Metadata",
3613 build_prov('00000000010000') ),
3614 ( "HS 2.0: Not room for Icon Type",
3615 build_prov('000000000900111122223333330200') ),
3616 ( "HS 2.0: Not room for Icon Filename length",
3617 build_prov('000000000900111122223333330100') ),
3618 ( "HS 2.0: Not room for Icon Filename",
3619 build_prov('000000000900111122223333330001') ),
3620 ( "HS 2.0: Not enough room for OSU_NAI",
3621 build_prov('000000000000') ),
3622 ( "HS 2.0: Not enough room for OSU_NAI(2)",
3623 build_prov('00000000000001') ),
3624 ( "HS 2.0: Not enough room for OSU Service Description Length",
3625 build_prov('00000000000000') ),
3626 ( "HS 2.0: Not enough room for OSU Service Description Length(2)",
3627 build_prov('0000000000000000') ),
3628 ( "HS 2.0: Not enough room for OSU Service Description Duples",
3629 build_prov('000000000000000100') ),
3630 ( "Invalid OSU Service Description",
3631 build_prov('00000000000000040000000000') ),
3632 ( "Invalid OSU Service Description(2)",
3633 build_prov('00000000000000040004000000') ) ]
3636 dev
[0].request("SET osu_dir " + dir)
3637 run_fetch_osu_icon_failure(hapd
, dev
, bssid
)
3638 for note
, prov
in tests
:
3639 run_fetch_osu(hapd
, dev
, bssid
, note
, prov
)
3641 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3643 os
.remove(dir + "/" + f
)
3646 def test_ap_hs20_fetch_osu_invalid_dir(dev
, apdev
):
3647 """Hotspot 2.0 OSU provider and invalid directory"""
3648 bssid
= apdev
[0]['bssid']
3649 params
= hs20_ap_params()
3650 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3651 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3652 params
['osu_method_list'] = "1"
3653 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3654 params
['osu_icon'] = "w1fi_logo"
3655 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3656 params
['osu_server_uri'] = "https://example.com/osu/"
3657 hostapd
.add_ap(apdev
[0], params
)
3659 dev
[0].hs20_enable()
3660 dir = "/tmp/osu-fetch-no-such-dir"
3661 dev
[0].scan_for_bss(bssid
, freq
="2412")
3662 dev
[0].request("SET osu_dir " + dir)
3663 dev
[0].request("FETCH_OSU no-scan")
3664 ev
= dev
[0].wait_event(["Could not write OSU provider information"],
3667 raise Exception("Timeout on OSU fetch")
3669 def test_ap_hs20_fetch_osu_oom(dev
, apdev
):
3670 """Hotspot 2.0 OSU provider and OOM"""
3671 bssid
= apdev
[0]['bssid']
3672 params
= hs20_ap_params()
3673 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
3674 params
['osu_ssid'] = '"HS 2.0 OSU open"'
3675 params
['osu_method_list'] = "1"
3676 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
3677 params
['osu_icon'] = "w1fi_logo"
3678 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
3679 params
['osu_server_uri'] = "https://example.com/osu/"
3680 hostapd
.add_ap(apdev
[0], params
)
3682 dev
[0].hs20_enable()
3683 dir = "/tmp/osu-fetch"
3684 if os
.path
.isdir(dir):
3685 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3687 os
.remove(dir + "/" + f
)
3693 dev
[0].scan_for_bss(bssid
, freq
="2412")
3695 dev
[0].request("SET osu_dir " + dir)
3696 with
alloc_fail(dev
[0], 1, "=hs20_osu_add_prov"):
3697 dev
[0].request("FETCH_OSU no-scan")
3698 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3700 raise Exception("Timeout on OSU fetch")
3701 with
alloc_fail(dev
[0], 1, "hs20_anqp_send_req;hs20_next_osu_icon"):
3702 dev
[0].request("FETCH_OSU no-scan")
3703 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=30)
3705 raise Exception("Timeout on OSU fetch")
3707 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
3709 os
.remove(dir + "/" + f
)
3712 def build_prov(prov
):
3713 data
= binascii
.unhexlify(prov
)
3714 return binascii
.unhexlify('013001') + struct
.pack('<H', len(data
)) + data
3716 def handle_osu_prov_fetch(hapd
, dev
, prov
):
3717 # GAS/ANQP query for OSU Providers List
3718 query
= gas_rx(hapd
)
3719 gas
= parse_gas(query
['payload'])
3720 dialog_token
= gas
['dialog_token']
3722 resp
= action_response(query
)
3723 osu_prov
= struct
.pack('<HH', 0xdddd, len(prov
) + 6) + binascii
.unhexlify('506f9a110800') + prov
3724 data
= struct
.pack('<H', len(osu_prov
)) + osu_prov
3725 resp
['payload'] = anqp_initial_resp(dialog_token
, 0) + data
3726 send_gas_resp(hapd
, resp
)
3728 ev
= dev
[0].wait_event(["RX-HS20-ANQP"], timeout
=5)
3730 raise Exception("ANQP query response for OSU Providers not received")
3731 if "OSU Providers list" not in ev
:
3732 raise Exception("ANQP query response for OSU Providers not received(2)")
3733 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
3735 raise Exception("ANQP query for OSU Providers list not completed")
3737 def start_osu_fetch(hapd
, dev
, bssid
, note
):
3738 hapd
.set("ext_mgmt_frame_handling", "0")
3739 dev
[0].request("BSS_FLUSH 0")
3740 dev
[0].scan_for_bss(bssid
, freq
="2412")
3741 hapd
.set("ext_mgmt_frame_handling", "1")
3742 dev
[0].dump_monitor()
3743 dev
[0].request("NOTE " + note
)
3744 dev
[0].request("FETCH_OSU no-scan")
3746 def wait_osu_fetch_completed(dev
):
3747 ev
= dev
[0].wait_event(["OSU provider fetch completed"], timeout
=5)
3749 raise Exception("Timeout on OSU fetch")
3751 def run_fetch_osu_icon_failure(hapd
, dev
, bssid
):
3752 start_osu_fetch(hapd
, dev
, bssid
, "Icon fetch failure")
3754 prov
= binascii
.unhexlify('01ff' + '01' + '800019000b656e6754657374204f53550c66696e54657374692d4f53551868747470733a2f2f6578616d706c652e636f6d2f6f73752f01011b00800050007a787809696d6167652f706e6709773166695f6c6f676f002a0013656e674578616d706c652073657276696365731566696e4573696d65726b6b6970616c76656c756a61')
3755 handle_osu_prov_fetch(hapd
, dev
, prov
)
3757 # GAS/ANQP query for icon
3758 query
= gas_rx(hapd
)
3759 gas
= parse_gas(query
['payload'])
3760 dialog_token
= gas
['dialog_token']
3762 resp
= action_response(query
)
3763 # Unexpected Advertisement Protocol in response
3764 adv_proto
= struct
.pack('8B', 108, 6, 127, 0xdd, 0x00, 0x11, 0x22, 0x33)
3765 data
= struct
.pack('<H', 0)
3766 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
3767 GAS_INITIAL_RESPONSE
,
3768 gas
['dialog_token'], 0, 0) + adv_proto
+ data
3769 send_gas_resp(hapd
, resp
)
3771 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
3773 raise Exception("ANQP query for icon not completed")
3775 wait_osu_fetch_completed(dev
)
3777 def run_fetch_osu(hapd
, dev
, bssid
, note
, prov
):
3778 start_osu_fetch(hapd
, dev
, bssid
, note
)
3779 handle_osu_prov_fetch(hapd
, dev
, prov
)
3780 wait_osu_fetch_completed(dev
)
3782 def test_ap_hs20_ft(dev
, apdev
):
3783 """Hotspot 2.0 connection with FT"""
3784 check_eap_capa(dev
[0], "MSCHAPV2")
3785 bssid
= apdev
[0]['bssid']
3786 params
= hs20_ap_params()
3787 params
['wpa_key_mgmt'] = "FT-EAP"
3788 params
['nas_identifier'] = "nas1.w1.fi"
3789 params
['r1_key_holder'] = "000102030405"
3790 params
["mobility_domain"] = "a1b2"
3791 params
["reassociation_deadline"] = "1000"
3792 hapd
= hostapd
.add_ap(apdev
[0], params
)
3794 dev
[0].hs20_enable()
3795 id = dev
[0].add_cred_values({ 'realm': "example.com",
3796 'username': "hs20-test",
3797 'password': "password",
3798 'ca_cert': "auth_serv/ca.pem",
3799 'domain': "example.com",
3800 'update_identifier': "1234" })
3801 interworking_select(dev
[0], bssid
, "home", freq
="2412")
3802 interworking_connect(dev
[0], bssid
, "TTLS")
3803 dev
[0].dump_monitor()
3804 key_mgmt
= dev
[0].get_status_field("key_mgmt")
3805 if key_mgmt
!= "FT-EAP":
3806 raise Exception("Unexpected key_mgmt: " + key_mgmt
)
3807 # speed up testing by avoiding unnecessary scanning of other channels
3808 nid
= dev
[0].get_status_field("id")
3809 dev
[0].set_network(nid
, "scan_freq", "2412")
3811 params
= hs20_ap_params()
3812 hapd2
= hostapd
.add_ap(apdev
[1], params
)
3815 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=10)
3817 raise Exception("Disconnection not reported")
3818 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=5)
3820 raise Exception("Connection to AP2 not reported")
3821 key_mgmt
= dev
[0].get_status_field("key_mgmt")
3822 if key_mgmt
!= "WPA2/IEEE 802.1X/EAP":
3823 raise Exception("Unexpected key_mgmt: " + key_mgmt
)
3825 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
3826 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
3827 check_eap_capa(dev
[0], "MSCHAPV2")
3831 raise HwsimSkip("No sqlite3 module available")
3832 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
3837 con
= sqlite3
.connect(dbfile
)
3840 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
3841 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
3842 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
3843 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
3844 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
3847 params
= { "ssid": "as", "beacon_int": "2000",
3848 "radius_server_clients": "auth_serv/radius_clients.conf",
3849 "radius_server_auth_port": '18128',
3851 "eap_user_file": "sqlite:" + dbfile
,
3852 "ca_cert": "auth_serv/ca.pem",
3853 "server_cert": "auth_serv/server.pem",
3854 "private_key": "auth_serv/server.key",
3855 "subscr_remediation_url": "https://example.org/",
3856 "subscr_remediation_method": "1" }
3857 hostapd
.add_ap(apdev
[1], params
)
3859 bssid
= apdev
[0]['bssid']
3860 params
= hs20_ap_params()
3861 params
['auth_server_port'] = "18128"
3862 hostapd
.add_ap(apdev
[0], params
)
3864 dev
[0].request("SET pmf 1")
3865 dev
[0].hs20_enable()
3866 id = dev
[0].add_cred_values({ 'realm': "example.com",
3867 'username': "user-mschapv2",
3868 'password': "password",
3869 'ca_cert': "auth_serv/ca.pem" })
3870 interworking_select(dev
[0], bssid
, freq
="2412")
3871 interworking_connect(dev
[0], bssid
, "TTLS")
3872 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
3874 raise Exception("Timeout on subscription remediation notice")
3875 if " 1 https://example.org/" not in ev
:
3876 raise Exception("Unexpected subscription remediation event contents")
3880 cur
.execute("SELECT * from authlog")
3881 rows
= cur
.fetchall()
3883 raise Exception("No authlog entries")
3887 dev
[0].request("SET pmf 0")
3889 def test_ap_hs20_sim_provisioning(dev
, apdev
, params
):
3890 """Hotspot 2.0 AAA server behavior for SIM provisioning"""
3891 check_eap_capa(dev
[0], "SIM")
3895 raise HwsimSkip("No sqlite3 module available")
3896 dbfile
= os
.path
.join(params
['logdir'], "ap_hs20_sim_provisioning-eap-user.db")
3901 con
= sqlite3
.connect(dbfile
)
3904 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER, last_msk TEXT)")
3905 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
3906 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('1','SIM')")
3907 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
3908 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)")
3911 params
= { "ssid": "as", "beacon_int": "2000",
3912 "radius_server_clients": "auth_serv/radius_clients.conf",
3913 "radius_server_auth_port": '18128',
3915 "eap_user_file": "sqlite:" + dbfile
,
3916 "eap_sim_db": "unix:/tmp/hlr_auc_gw.sock",
3917 "ca_cert": "auth_serv/ca.pem",
3918 "server_cert": "auth_serv/server.pem",
3919 "private_key": "auth_serv/server.key",
3920 "hs20_sim_provisioning_url":
3921 "https://example.org/?hotspot2dot0-mobile-identifier-hash=",
3922 "subscr_remediation_method": "1" }
3923 hostapd
.add_ap(apdev
[1], params
)
3925 bssid
= apdev
[0]['bssid']
3926 params
= hs20_ap_params()
3927 params
['auth_server_port'] = "18128"
3928 hostapd
.add_ap(apdev
[0], params
)
3930 dev
[0].request("SET pmf 1")
3931 dev
[0].hs20_enable()
3932 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="SIM",
3934 identity
="1232010000000000",
3935 password
="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581",
3936 scan_freq
="2412", update_identifier
="54321")
3937 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=0.5)
3939 raise Exception("Unexpected subscription remediation notice")
3940 dev
[0].request("REMOVE_NETWORK all")
3941 dev
[0].wait_disconnected()
3942 dev
[0].dump_monitor()
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
="0")
3949 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
3951 raise Exception("Timeout on subscription remediation notice")
3952 if " 1 https://example.org/?hotspot2dot0-mobile-identifier-hash=" not in ev
:
3953 raise Exception("Unexpected subscription remediation event contents: " + ev
)
3954 id_hash
= ev
.split(' ')[2].split('=')[1]
3958 cur
.execute("SELECT * from authlog")
3959 rows
= cur
.fetchall()
3961 raise Exception("No authlog entries")
3965 cur
.execute("SELECT * from sim_provisioning")
3966 rows
= cur
.fetchall()
3968 raise Exeception("Unexpected number of rows in sim_provisioning (%d; expected %d)" % (len(rows
), 1))
3969 logger
.info("sim_provisioning: " + str(rows
))
3970 if len(rows
[0][0]) != 32:
3971 raise Exception("Unexpected mobile_identifier_hash length in DB")
3972 if rows
[0][1] != "232010000000000":
3973 raise Exception("Unexpected IMSI in DB")
3974 if rows
[0][2] != dev
[0].own_addr():
3975 raise Exception("Unexpected MAC address in DB")
3976 if rows
[0][0] != id_hash
:
3977 raise Exception("hotspot2dot0-mobile-identifier-hash mismatch")
3979 dev
[0].request("SET pmf 0")
3981 def test_ap_hs20_external_selection(dev
, apdev
):
3982 """Hotspot 2.0 connection using external network selection and creation"""
3983 check_eap_capa(dev
[0], "MSCHAPV2")
3984 bssid
= apdev
[0]['bssid']
3985 params
= hs20_ap_params()
3986 params
['hessid'] = bssid
3987 params
['disable_dgaf'] = '1'
3988 hostapd
.add_ap(apdev
[0], params
)
3990 dev
[0].hs20_enable()
3991 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
3993 identity
="hs20-test", password
="password",
3994 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
3995 scan_freq
="2412", update_identifier
="54321",
3996 roaming_consortium_selection
="1020304050")
3997 if dev
[0].get_status_field("hs20") != "3":
3998 raise Exception("Unexpected hs20 indication")
3999 network_id
= dev
[0].get_status_field("id")
4000 sel
= dev
[0].get_network(network_id
, "roaming_consortium_selection")
4001 if sel
!= "1020304050":
4002 raise Exception("Unexpected roaming_consortium_selection value: " + sel
)
4004 def test_ap_hs20_random_mac_addr(dev
, apdev
):
4005 """Hotspot 2.0 connection with random MAC address"""
4006 check_eap_capa(dev
[0], "MSCHAPV2")
4007 bssid
= apdev
[0]['bssid']
4008 params
= hs20_ap_params()
4009 params
['hessid'] = bssid
4010 params
['disable_dgaf'] = '1'
4011 hapd
= hostapd
.add_ap(apdev
[0], params
)
4013 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
4014 wpas
.interface_add("wlan5")
4015 addr
= wpas
.p2p_interface_addr()
4016 wpas
.request("SET mac_addr 1")
4017 wpas
.request("SET preassoc_mac_addr 1")
4018 wpas
.request("SET rand_addr_lifetime 60")
4020 wpas
.flush_scan_cache()
4021 id = wpas
.add_cred_values({ 'realm': "example.com",
4022 'username': "hs20-test",
4023 'password': "password",
4024 'ca_cert': "auth_serv/ca.pem",
4025 'domain': "example.com",
4026 'update_identifier': "1234" })
4027 interworking_select(wpas
, bssid
, "home", freq
="2412")
4028 interworking_connect(wpas
, bssid
, "TTLS")
4029 addr1
= wpas
.get_driver_status_field("addr")
4031 raise Exception("Did not use random MAC address")
4033 sta
= hapd
.get_sta(addr
)
4034 if sta
['addr'] != "FAIL":
4035 raise Exception("Unexpected STA association with permanent address")
4036 sta
= hapd
.get_sta(addr1
)
4037 if sta
['addr'] != addr1
:
4038 raise Exception("STA association with random address not found")
4040 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
4041 """Multiple networks and cred removal"""
4042 check_eap_capa(dev
[0], "MSCHAPV2")
4043 bssid
= apdev
[0]['bssid']
4044 params
= hs20_ap_params()
4045 params
['nai_realm'] = [ "0,example.com,25[3:26]"]
4046 hapd
= hostapd
.add_ap(apdev
[0], params
)
4048 dev
[0].add_network()
4049 dev
[0].hs20_enable()
4050 id = dev
[0].add_cred_values({ 'realm': "example.com",
4052 'password': "password" })
4053 interworking_select(dev
[0], bssid
, freq
="2412")
4054 interworking_connect(dev
[0], bssid
, "PEAP")
4055 dev
[0].add_network()
4057 dev
[0].request("DISCONNECT")
4058 dev
[0].wait_disconnected(timeout
=10)
4061 hapd
.set("ssid", "another ssid")
4064 interworking_select(dev
[0], bssid
, freq
="2412")
4065 interworking_connect(dev
[0], bssid
, "PEAP")
4066 dev
[0].add_network()
4067 if len(dev
[0].list_networks()) != 5:
4068 raise Exception("Unexpected number of networks prior to remove_crec")
4070 dev
[0].dump_monitor()
4071 dev
[0].remove_cred(id)
4072 if len(dev
[0].list_networks()) != 3:
4073 raise Exception("Unexpected number of networks after to remove_crec")
4074 dev
[0].wait_disconnected(timeout
=10)
4076 def test_ap_hs20_interworking_add_network(dev
, apdev
):
4077 """Hotspot 2.0 connection using INTERWORKING_ADD_NETWORK"""
4078 check_eap_capa(dev
[0], "MSCHAPV2")
4079 bssid
= apdev
[0]['bssid']
4080 params
= hs20_ap_params()
4081 params
['nai_realm'] = [ "0,example.com,21[3:26][6:7][99:99]" ]
4082 hostapd
.add_ap(apdev
[0], params
)
4084 dev
[0].hs20_enable()
4085 dev
[0].add_cred_values(default_cred(user
="user"))
4086 interworking_select(dev
[0], bssid
, freq
=2412)
4087 id = dev
[0].interworking_add_network(bssid
)
4088 dev
[0].select_network(id, freq
=2412)
4089 dev
[0].wait_connected()
4091 def _test_ap_hs20_proxyarp(dev
, apdev
):
4092 bssid
= apdev
[0]['bssid']
4093 params
= hs20_ap_params()
4094 params
['hessid'] = bssid
4095 params
['disable_dgaf'] = '0'
4096 params
['proxy_arp'] = '1'
4097 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4098 if "OK" in hapd
.request("ENABLE"):
4099 raise Exception("Incomplete hostapd configuration was accepted")
4100 hapd
.set("ap_isolate", "1")
4101 if "OK" in hapd
.request("ENABLE"):
4102 raise Exception("Incomplete hostapd configuration was accepted")
4103 hapd
.set('bridge', 'ap-br0')
4108 # For now, do not report failures due to missing kernel support
4109 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4110 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4112 raise Exception("AP startup timed out")
4113 if "AP-ENABLED" not in ev
:
4114 raise Exception("AP startup failed")
4116 dev
[0].hs20_enable()
4117 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4118 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4120 id = dev
[0].add_cred_values({ 'realm': "example.com",
4121 'username': "hs20-test",
4122 'password': "password",
4123 'ca_cert': "auth_serv/ca.pem",
4124 'domain': "example.com",
4125 'update_identifier': "1234" })
4126 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4127 interworking_connect(dev
[0], bssid
, "TTLS")
4129 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
4130 identity
="hs20-test", password
="password",
4131 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
4135 addr0
= dev
[0].p2p_interface_addr()
4136 addr1
= dev
[1].p2p_interface_addr()
4138 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
4139 src_ll_opt1
= b
"\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
4141 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
4142 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
4144 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4145 raise Exception("DATA_TEST_FRAME failed")
4147 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
4148 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
4150 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4151 raise Exception("DATA_TEST_FRAME failed")
4153 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
4154 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
4156 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4157 raise Exception("DATA_TEST_FRAME failed")
4159 matches
= get_permanent_neighbors("ap-br0")
4160 logger
.info("After connect: " + str(matches
))
4161 if len(matches
) != 3:
4162 raise Exception("Unexpected number of neighbor entries after connect")
4163 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4164 raise Exception("dev0 addr missing")
4165 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
4166 raise Exception("dev1 addr(1) missing")
4167 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
4168 raise Exception("dev1 addr(2) missing")
4169 dev
[0].request("DISCONNECT")
4170 dev
[1].request("DISCONNECT")
4172 matches
= get_permanent_neighbors("ap-br0")
4173 logger
.info("After disconnect: " + str(matches
))
4174 if len(matches
) > 0:
4175 raise Exception("Unexpected neighbor entries after disconnect")
4177 def test_ap_hs20_hidden_ssid_in_scan_res(dev
, apdev
):
4178 """Hotspot 2.0 connection with hidden SSId in scan results"""
4179 check_eap_capa(dev
[0], "MSCHAPV2")
4180 bssid
= apdev
[0]['bssid']
4182 hapd
= hostapd
.add_ap(apdev
[0], { "ssid": 'secret',
4183 "ignore_broadcast_ssid": "1" })
4184 dev
[0].scan_for_bss(bssid
, freq
=2412)
4186 hapd_global
= hostapd
.HostapdGlobal(apdev
[0])
4188 hapd_global
.remove(apdev
[0]['ifname'])
4190 params
= hs20_ap_params()
4191 params
['hessid'] = bssid
4192 hapd
= hostapd
.add_ap(apdev
[0], params
)
4194 dev
[0].hs20_enable()
4195 id = dev
[0].add_cred_values({ 'realm': "example.com",
4196 'username': "hs20-test",
4197 'password': "password",
4198 'ca_cert': "auth_serv/ca.pem",
4199 'domain': "example.com" })
4200 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4201 interworking_connect(dev
[0], bssid
, "TTLS")
4203 # clear BSS table to avoid issues in following test cases
4204 dev
[0].request("DISCONNECT")
4205 dev
[0].wait_disconnected()
4207 dev
[0].flush_scan_cache()
4208 dev
[0].flush_scan_cache()
4210 def test_ap_hs20_proxyarp(dev
, apdev
):
4211 """Hotspot 2.0 and ProxyARP"""
4212 check_eap_capa(dev
[0], "MSCHAPV2")
4214 _test_ap_hs20_proxyarp(dev
, apdev
)
4216 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4217 stderr
=open('/dev/null', 'w'))
4218 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4219 stderr
=open('/dev/null', 'w'))
4221 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
4222 bssid
= apdev
[0]['bssid']
4223 params
= hs20_ap_params()
4224 params
['hessid'] = bssid
4225 params
['disable_dgaf'] = '1' if disabled
else '0'
4226 params
['proxy_arp'] = '1'
4227 params
['na_mcast_to_ucast'] = '1'
4228 params
['ap_isolate'] = '1'
4229 params
['bridge'] = 'ap-br0'
4230 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4234 # For now, do not report failures due to missing kernel support
4235 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4236 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
4238 raise Exception("AP startup timed out")
4240 dev
[0].hs20_enable()
4241 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4242 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4244 id = dev
[0].add_cred_values({ 'realm': "example.com",
4245 'username': "hs20-test",
4246 'password': "password",
4247 'ca_cert': "auth_serv/ca.pem",
4248 'domain': "example.com",
4249 'update_identifier': "1234" })
4250 interworking_select(dev
[0], bssid
, "home", freq
="2412")
4251 interworking_connect(dev
[0], bssid
, "TTLS")
4253 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
4254 identity
="hs20-test", password
="password",
4255 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
4259 addr0
= dev
[0].p2p_interface_addr()
4261 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
4263 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
4264 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
4266 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
4267 raise Exception("DATA_TEST_FRAME failed")
4269 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
4271 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4272 raise Exception("DATA_TEST_FRAME failed")
4274 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
4275 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
4276 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4277 raise Exception("DATA_TEST_FRAME failed")
4279 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4280 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4281 yiaddr
="192.168.1.123", chaddr
=addr0
)
4282 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4283 raise Exception("DATA_TEST_FRAME failed")
4284 # another copy for additional code coverage
4285 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
4286 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4287 yiaddr
="192.168.1.123", chaddr
=addr0
)
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 matches
= get_permanent_neighbors("ap-br0")
4292 logger
.info("After connect: " + str(matches
))
4293 if len(matches
) != 2:
4294 raise Exception("Unexpected number of neighbor entries after connect")
4295 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4296 raise Exception("dev0 addr missing")
4297 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4298 raise Exception("dev0 IPv4 addr missing")
4299 dev
[0].request("DISCONNECT")
4300 dev
[1].request("DISCONNECT")
4302 matches
= get_permanent_neighbors("ap-br0")
4303 logger
.info("After disconnect: " + str(matches
))
4304 if len(matches
) > 0:
4305 raise Exception("Unexpected neighbor entries after disconnect")
4307 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
4308 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
4309 check_eap_capa(dev
[0], "MSCHAPV2")
4311 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
4313 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4314 stderr
=open('/dev/null', 'w'))
4315 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4316 stderr
=open('/dev/null', 'w'))
4318 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
4319 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
4320 check_eap_capa(dev
[0], "MSCHAPV2")
4322 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
4324 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
4325 stderr
=open('/dev/null', 'w'))
4326 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
4327 stderr
=open('/dev/null', 'w'))
4329 def ip_checksum(buf
):
4333 for i
in range(0, len(buf
), 2):
4334 val
, = struct
.unpack('H', buf
[i
:i
+2])
4337 sum = (sum & 0xffff) + (sum >> 16)
4338 return struct
.pack('H', ~
sum & 0xffff)
4340 def ipv6_solicited_node_mcaddr(target
):
4341 prefix
= socket
.inet_pton(socket
.AF_INET6
, "ff02::1:ff00:0")
4342 mask
= socket
.inet_pton(socket
.AF_INET6
, "::ff:ffff")
4343 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4344 p
= struct
.unpack('4I', prefix
)
4345 m
= struct
.unpack('4I', mask
)
4346 t
= struct
.unpack('4I', _target
)
4347 res
= (p
[0] |
(t
[0] & m
[0]),
4348 p
[1] |
(t
[1] & m
[1]),
4349 p
[2] |
(t
[2] & m
[2]),
4350 p
[3] |
(t
[3] & m
[3]))
4351 return socket
.inet_ntop(socket
.AF_INET6
, struct
.pack('4I', *res
))
4353 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
4354 start
= struct
.pack("BB", type, code
)
4356 icmp
= start
+ b
'\x00\x00' + end
4357 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
4358 csum
= ip_checksum(pseudo
+ icmp
)
4359 return start
+ csum
+ end
4361 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
4362 reachable_time
=0, retrans_timer
=0, opt
=None):
4363 link_mc
= binascii
.unhexlify("3333ff000002")
4364 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
4366 ehdr
= link_mc
+ _src_ll
+ proto
4367 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4368 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4370 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
4371 reachable_time
, retrans_timer
)
4376 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
4378 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4379 ipv6
+= _ip_src
+ _ip_dst
4381 return ehdr
+ ipv6
+ icmp
4383 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
4384 link_mc
= binascii
.unhexlify("3333ff000002")
4385 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
4387 ehdr
= link_mc
+ _src_ll
+ proto
4388 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4390 ip_dst
= ipv6_solicited_node_mcaddr(target
)
4391 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4393 reserved
= b
'\x00\x00\x00\x00'
4394 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4396 payload
= reserved
+ _target
+ opt
4398 payload
= reserved
+ _target
4399 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
4401 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4402 ipv6
+= _ip_src
+ _ip_dst
4404 return ehdr
+ ipv6
+ icmp
4406 def send_ns(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
4411 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4414 src_ll
= dev
.p2p_interface_addr()
4415 cmd
= "DATA_TEST_FRAME "
4418 opt
= b
"\x01\x01" + binascii
.unhexlify(src_ll
.replace(':',''))
4420 pkt
= build_ns(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
4422 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4423 raise Exception("DATA_TEST_FRAME failed")
4425 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None, flags
=0):
4426 link_mc
= binascii
.unhexlify("3333ff000002")
4427 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
4429 ehdr
= link_mc
+ _src_ll
+ proto
4430 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
4431 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
4433 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
4435 payload
= struct
.pack('>Bxxx', flags
) + _target
+ opt
4437 payload
= struct
.pack('>Bxxx', flags
) + _target
4438 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
4440 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
4441 ipv6
+= _ip_src
+ _ip_dst
4443 return ehdr
+ ipv6
+ icmp
4445 def send_na(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
4450 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4453 src_ll
= dev
.p2p_interface_addr()
4454 cmd
= "DATA_TEST_FRAME "
4456 pkt
= build_na(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
4458 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4459 raise Exception("DATA_TEST_FRAME failed")
4461 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
4462 subnet_mask
="255.255.255.0", truncated_opt
=False,
4463 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False,
4465 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
4466 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
4468 ehdr
= _dst_ll
+ _src_ll
+ proto
4469 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
4470 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
4471 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
4473 _ciaddr
= b
'\x00\x00\x00\x00'
4474 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
4475 _siaddr
= b
'\x00\x00\x00\x00'
4476 _giaddr
= b
'\x00\x00\x00\x00'
4477 _chaddr
= binascii
.unhexlify(chaddr
.replace(':','') + "00000000000000000000")
4478 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
4479 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*b
'\x00'
4482 payload
+= b
'\x63\x82\x53\x00'
4484 payload
+= b
'\x63\x82\x53\x63'
4486 payload
+= b
'\x22\xff\x00'
4487 # Option: DHCP Message Type = ACK
4488 payload
+= b
'\x35\x01\x05'
4491 # Option: Subnet Mask
4492 payload
+= b
'\x01\x04' + _subnet_mask
4493 # Option: Time Offset
4494 payload
+= struct
.pack('>BBL', 2, 4, 0)
4498 payload
+= b
'\x00\x00\x00\x00'
4501 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
4502 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*b
'\x00'
4505 pseudohdr
= _ip_src
+ _ip_dst
+ struct
.pack('>BBH', 0, 17,
4507 udphdr
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0)
4508 checksum
, = struct
.unpack('>H', ip_checksum(pseudohdr
+ udphdr
+ payload
))
4511 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), checksum
) + payload
4514 tot_len
= force_tot_len
4516 tot_len
= 20 + len(udp
)
4517 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
4518 ipv4
= start
+ b
'\x00\x00' + _ip_src
+ _ip_dst
4519 csum
= ip_checksum(ipv4
)
4520 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
4522 return ehdr
+ ipv4
+ udp
4524 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
4525 target_mac
, target_ip
):
4526 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
4527 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
4529 ehdr
= _dst_ll
+ _src_ll
+ proto
4531 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':',''))
4532 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
4533 _target_mac
= binascii
.unhexlify(target_mac
.replace(':',''))
4534 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
4536 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
4537 arp
+= _sender_mac
+ _sender_ip
4538 arp
+= _target_mac
+ _target_ip
4542 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
4543 sender_mac
=None, sender_ip
="0.0.0.0",
4544 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
4549 if sender_mac
is None:
4550 sender_mac
= hapd_bssid
4551 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
4554 src_ll
= dev
.p2p_interface_addr()
4555 if sender_mac
is None:
4556 sender_mac
= dev
.p2p_interface_addr()
4557 cmd
= "DATA_TEST_FRAME "
4559 pkt
= build_arp(dst_ll
=dst_ll
, src_ll
=src_ll
, opcode
=opcode
,
4560 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
4561 target_mac
=target_mac
, target_ip
=target_ip
)
4562 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
).decode()):
4563 raise Exception("DATA_TEST_FRAME failed")
4565 def get_permanent_neighbors(ifname
):
4566 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
4567 res
= cmd
.stdout
.read().decode()
4569 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
4571 def get_bridge_macs(ifname
):
4572 cmd
= subprocess
.Popen(['brctl', 'showmacs', ifname
],
4573 stdout
=subprocess
.PIPE
)
4574 res
= cmd
.stdout
.read()
4578 def tshark_get_arp(cap
, filter):
4579 res
= run_tshark(cap
, filter,
4580 [ "eth.dst", "eth.src",
4581 "arp.src.hw_mac", "arp.src.proto_ipv4",
4582 "arp.dst.hw_mac", "arp.dst.proto_ipv4" ],
4585 for l
in res
.splitlines():
4586 frames
.append(l
.split('\t'))
4589 def tshark_get_ns(cap
):
4590 res
= run_tshark(cap
, "icmpv6.type == 135",
4591 [ "eth.dst", "eth.src",
4592 "ipv6.src", "ipv6.dst",
4593 "icmpv6.nd.ns.target_address",
4594 "icmpv6.opt.linkaddr" ],
4597 for l
in res
.splitlines():
4598 frames
.append(l
.split('\t'))
4601 def tshark_get_na(cap
):
4602 res
= run_tshark(cap
, "icmpv6.type == 136",
4603 [ "eth.dst", "eth.src",
4604 "ipv6.src", "ipv6.dst",
4605 "icmpv6.nd.na.target_address",
4606 "icmpv6.opt.linkaddr" ],
4609 for l
in res
.splitlines():
4610 frames
.append(l
.split('\t'))
4613 def _test_proxyarp_open(dev
, apdev
, params
, ebtables
=False):
4614 prefix
= "proxyarp_open"
4616 prefix
+= "_ebtables"
4617 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
4618 cap_dev0
= os
.path
.join(params
['logdir'],
4619 prefix
+ ".%s.pcap" % dev
[0].ifname
)
4620 cap_dev1
= os
.path
.join(params
['logdir'],
4621 prefix
+ ".%s.pcap" % dev
[1].ifname
)
4622 cap_dev2
= os
.path
.join(params
['logdir'],
4623 prefix
+ ".%s.pcap" % dev
[2].ifname
)
4625 bssid
= apdev
[0]['bssid']
4626 params
= { 'ssid': 'open' }
4627 params
['proxy_arp'] = '1'
4628 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4629 hapd
.set("ap_isolate", "1")
4630 hapd
.set('bridge', 'ap-br0')
4635 # For now, do not report failures due to missing kernel support
4636 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4637 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4639 raise Exception("AP startup timed out")
4640 if "AP-ENABLED" not in ev
:
4641 raise Exception("AP startup failed")
4643 params2
= { 'ssid': 'another' }
4644 hapd2
= hostapd
.add_ap(apdev
[1], params2
, no_enable
=True)
4645 hapd2
.set('bridge', 'ap-br0')
4648 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4649 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4652 for chain
in [ 'FORWARD', 'OUTPUT' ]:
4654 subprocess
.call(['ebtables', '-A', chain
, '-p', 'ARP',
4655 '-d', 'Broadcast', '-o', apdev
[0]['ifname'],
4658 raise HwsimSkip("No ebtables available")
4662 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
4663 '-w', cap_br
, '-s', '2000'],
4664 stderr
=open('/dev/null', 'w'))
4665 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
4666 '-w', cap_dev0
, '-s', '2000'],
4667 stderr
=open('/dev/null', 'w'))
4668 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
4669 '-w', cap_dev1
, '-s', '2000'],
4670 stderr
=open('/dev/null', 'w'))
4671 cmd
[3] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[2].ifname
,
4672 '-w', cap_dev2
, '-s', '2000'],
4673 stderr
=open('/dev/null', 'w'))
4675 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
4676 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
4677 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
4680 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
4681 res
= brcmd
.stdout
.read().decode()
4682 brcmd
.stdout
.close()
4683 logger
.info("Bridge setup: " + res
)
4685 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
4686 stdout
=subprocess
.PIPE
)
4687 res
= brcmd
.stdout
.read().decode()
4688 brcmd
.stdout
.close()
4689 logger
.info("Bridge showstp: " + res
)
4691 addr0
= dev
[0].p2p_interface_addr()
4692 addr1
= dev
[1].p2p_interface_addr()
4693 addr2
= dev
[2].p2p_interface_addr()
4695 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4696 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4697 yiaddr
="192.168.1.124", chaddr
=addr0
)
4698 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4699 raise Exception("DATA_TEST_FRAME failed")
4700 # Change address and verify unicast
4701 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
4702 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4703 yiaddr
="192.168.1.123", chaddr
=addr0
,
4705 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4706 raise Exception("DATA_TEST_FRAME failed")
4708 # Not-associated client MAC address
4709 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
4710 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4711 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
4712 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4713 raise Exception("DATA_TEST_FRAME failed")
4716 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4717 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4718 yiaddr
="0.0.0.0", chaddr
=addr1
)
4719 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4720 raise Exception("DATA_TEST_FRAME failed")
4723 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4724 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4725 yiaddr
="192.168.1.126", chaddr
=addr1
,
4726 subnet_mask
="0.0.0.0")
4727 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4728 raise Exception("DATA_TEST_FRAME failed")
4731 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4732 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4733 yiaddr
="192.168.1.127", chaddr
=addr1
,
4735 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4736 raise Exception("DATA_TEST_FRAME failed")
4739 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4740 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4741 yiaddr
="192.168.1.128", chaddr
=addr1
,
4743 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4744 raise Exception("DATA_TEST_FRAME failed")
4746 # Wrong IPv4 total length
4747 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4748 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4749 yiaddr
="192.168.1.129", chaddr
=addr1
,
4751 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4752 raise Exception("DATA_TEST_FRAME failed")
4755 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
4756 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
4757 yiaddr
="192.168.1.129", chaddr
=addr1
,
4759 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
4760 raise Exception("DATA_TEST_FRAME failed")
4762 macs
= get_bridge_macs("ap-br0")
4763 logger
.info("After connect (showmacs): " + str(macs
))
4765 matches
= get_permanent_neighbors("ap-br0")
4766 logger
.info("After connect: " + str(matches
))
4767 if len(matches
) != 1:
4768 raise Exception("Unexpected number of neighbor entries after connect")
4769 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
4770 raise Exception("dev0 IPv4 addr missing")
4772 targets
= [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
4774 for target
in targets
:
4775 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
4777 for target
in targets
:
4778 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
4781 for target
in targets
:
4782 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
=target
)
4784 # ARP Probe from wireless STA
4785 send_arp(dev
[1], target_ip
="192.168.1.127")
4786 # ARP Announcement from wireless STA
4787 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
4788 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
4791 macs
= get_bridge_macs("ap-br0")
4792 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
4794 matches
= get_permanent_neighbors("ap-br0")
4795 logger
.info("After ARP Probe + Announcement: " + str(matches
))
4797 # ARP Request for the newly introduced IP address from wireless STA
4798 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
4800 # ARP Request for the newly introduced IP address from bridge
4801 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
4802 target_ip
="192.168.1.127")
4803 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
="192.168.1.127")
4805 # ARP Probe from bridge
4806 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.130")
4807 send_arp(dev
[2], target_ip
="192.168.1.131")
4808 # ARP Announcement from bridge (not to be learned by AP for proxyarp)
4809 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
4810 target_ip
="192.168.1.130")
4811 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
4812 target_ip
="192.168.1.130", opcode
=2)
4813 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131")
4814 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131",
4817 macs
= get_bridge_macs("ap-br0")
4818 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
4820 matches
= get_permanent_neighbors("ap-br0")
4821 logger
.info("After ARP Probe + Announcement: " + str(matches
))
4823 # ARP Request for the newly introduced IP address from wireless STA
4824 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.130")
4825 # ARP Response from bridge (AP does not proxy for non-wireless devices)
4826 send_arp(hapd
, hapd_bssid
=bssid
, dst_ll
=addr0
, sender_ip
="192.168.1.130",
4827 target_ip
="192.168.1.123", opcode
=2)
4829 # ARP Request for the newly introduced IP address from wireless STA
4830 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.131")
4831 # ARP Response from bridge (AP does not proxy for non-wireless devices)
4832 send_arp(dev
[2], dst_ll
=addr0
, sender_ip
="192.168.1.131",
4833 target_ip
="192.168.1.123", opcode
=2)
4835 # ARP Request for the newly introduced IP address from bridge
4836 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
4837 target_ip
="192.168.1.130")
4838 send_arp(dev
[2], sender_ip
="192.168.1.104", target_ip
="192.168.1.131")
4840 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
4841 send_arp(dev
[1], target_ip
="192.168.1.123")
4842 # ARP Probe from wireless STA (duplicate address; learned through ARP)
4843 send_arp(dev
[0], target_ip
="192.168.1.127")
4845 # Gratuitous ARP Reply for another STA's IP address
4846 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
4847 target_mac
=addr1
, target_ip
="192.168.1.127")
4848 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
4849 target_mac
=addr0
, target_ip
="192.168.1.123")
4850 # ARP Request to verify previous mapping
4851 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
4852 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
4855 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
4856 except Exception as e
:
4857 logger
.info("test_connectibity_iface failed: " + str(e
))
4858 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
4859 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
4860 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
4862 dev
[0].request("DISCONNECT")
4863 dev
[1].request("DISCONNECT")
4865 for i
in range(len(cmd
)):
4867 macs
= get_bridge_macs("ap-br0")
4868 logger
.info("After disconnect (showmacs): " + str(macs
))
4869 matches
= get_permanent_neighbors("ap-br0")
4870 logger
.info("After disconnect: " + str(matches
))
4871 if len(matches
) > 0:
4872 raise Exception("Unexpected neighbor entries after disconnect")
4874 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
4875 stdout
=subprocess
.PIPE
)
4876 res
= cmd
.stdout
.read().decode()
4878 logger
.info("ebtables results:\n" + res
)
4880 # Verify that expected ARP messages were seen and no unexpected
4881 # ARP messages were seen.
4883 arp_req
= tshark_get_arp(cap_dev0
, "arp.opcode == 1")
4884 arp_reply
= tshark_get_arp(cap_dev0
, "arp.opcode == 2")
4885 logger
.info("dev0 seen ARP requests:\n" + str(arp_req
))
4886 logger
.info("dev0 seen ARP replies:\n" + str(arp_reply
))
4888 if [ 'ff:ff:ff:ff:ff:ff', addr1
,
4889 addr1
, '192.168.1.100',
4890 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
4891 raise Exception("dev0 saw ARP request from dev1")
4892 if [ 'ff:ff:ff:ff:ff:ff', addr2
,
4893 addr2
, '192.168.1.103',
4894 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
4895 raise Exception("dev0 saw ARP request from dev2")
4896 # TODO: Uncomment once fixed in kernel
4897 #if [ 'ff:ff:ff:ff:ff:ff', bssid,
4898 # bssid, '192.168.1.101',
4899 # '00:00:00:00:00:00', '192.168.1.123' ] in arp_req:
4900 # raise Exception("dev0 saw ARP request from br")
4905 raise Exception("Unexpected foreign ARP request on dev0")
4907 arp_req
= tshark_get_arp(cap_dev1
, "arp.opcode == 1")
4908 arp_reply
= tshark_get_arp(cap_dev1
, "arp.opcode == 2")
4909 logger
.info("dev1 seen ARP requests:\n" + str(arp_req
))
4910 logger
.info("dev1 seen ARP replies:\n" + str(arp_reply
))
4912 if [ 'ff:ff:ff:ff:ff:ff', addr2
,
4913 addr2
, '192.168.1.103',
4914 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
4915 raise Exception("dev1 saw ARP request from dev2")
4916 if [addr1
, addr0
, addr0
, '192.168.1.123', addr1
, '192.168.1.100'] not in arp_reply
:
4917 raise Exception("dev1 did not get ARP response for 192.168.1.123")
4922 raise Exception("Unexpected foreign ARP request on dev1")
4924 arp_req
= tshark_get_arp(cap_dev2
, "arp.opcode == 1")
4925 arp_reply
= tshark_get_arp(cap_dev2
, "arp.opcode == 2")
4926 logger
.info("dev2 seen ARP requests:\n" + str(arp_req
))
4927 logger
.info("dev2 seen ARP replies:\n" + str(arp_reply
))
4930 addr0
, '192.168.1.123',
4931 addr2
, '192.168.1.103' ] not in arp_reply
:
4932 raise Exception("dev2 did not get ARP response for 192.168.1.123")
4934 arp_req
= tshark_get_arp(cap_br
, "arp.opcode == 1")
4935 arp_reply
= tshark_get_arp(cap_br
, "arp.opcode == 2")
4936 logger
.info("br seen ARP requests:\n" + str(arp_req
))
4937 logger
.info("br seen ARP replies:\n" + str(arp_reply
))
4939 # TODO: Uncomment once fixed in kernel
4941 # addr0, '192.168.1.123',
4942 # bssid, '192.168.1.101' ] not in arp_reply:
4943 # raise Exception("br did not get ARP response for 192.168.1.123")
4945 def _test_proxyarp_open_ipv6(dev
, apdev
, params
, ebtables
=False):
4946 prefix
= "proxyarp_open"
4948 prefix
+= "_ebtables"
4949 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
4950 cap_dev0
= os
.path
.join(params
['logdir'],
4951 prefix
+ ".%s.pcap" % dev
[0].ifname
)
4952 cap_dev1
= os
.path
.join(params
['logdir'],
4953 prefix
+ ".%s.pcap" % dev
[1].ifname
)
4954 cap_dev2
= os
.path
.join(params
['logdir'],
4955 prefix
+ ".%s.pcap" % dev
[2].ifname
)
4957 bssid
= apdev
[0]['bssid']
4958 params
= { 'ssid': 'open' }
4959 params
['proxy_arp'] = '1'
4960 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
4961 hapd
.set("ap_isolate", "1")
4962 hapd
.set('bridge', 'ap-br0')
4967 # For now, do not report failures due to missing kernel support
4968 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
4969 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
4971 raise Exception("AP startup timed out")
4972 if "AP-ENABLED" not in ev
:
4973 raise Exception("AP startup failed")
4975 params2
= { 'ssid': 'another' }
4976 hapd2
= hostapd
.add_ap(apdev
[1], params2
, no_enable
=True)
4977 hapd2
.set('bridge', 'ap-br0')
4980 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
4981 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
4984 for chain
in [ 'FORWARD', 'OUTPUT' ]:
4986 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
4987 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
4988 '--ip6-icmp-type', 'neighbor-solicitation',
4989 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
4990 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
4991 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
4992 '--ip6-icmp-type', 'neighbor-advertisement',
4993 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
4994 subprocess
.call(['ebtables', '-A', chain
,
4995 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
4996 '--ip6-icmp-type', 'router-solicitation',
4997 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
4998 # Multicast Listener Report Message
4999 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
5000 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
5001 '--ip6-icmp-type', '143',
5002 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
5004 raise HwsimSkip("No ebtables available")
5008 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
5009 '-w', cap_br
, '-s', '2000'],
5010 stderr
=open('/dev/null', 'w'))
5011 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
5012 '-w', cap_dev0
, '-s', '2000'],
5013 stderr
=open('/dev/null', 'w'))
5014 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
5015 '-w', cap_dev1
, '-s', '2000'],
5016 stderr
=open('/dev/null', 'w'))
5017 cmd
[3] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[2].ifname
,
5018 '-w', cap_dev2
, '-s', '2000'],
5019 stderr
=open('/dev/null', 'w'))
5021 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
5022 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
5023 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
5026 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
5027 res
= brcmd
.stdout
.read().decode()
5028 brcmd
.stdout
.close()
5029 logger
.info("Bridge setup: " + res
)
5031 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
5032 stdout
=subprocess
.PIPE
)
5033 res
= brcmd
.stdout
.read().decode()
5034 brcmd
.stdout
.close()
5035 logger
.info("Bridge showstp: " + res
)
5037 addr0
= dev
[0].p2p_interface_addr()
5038 addr1
= dev
[1].p2p_interface_addr()
5039 addr2
= dev
[2].p2p_interface_addr()
5041 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
5042 src_ll_opt1
= b
"\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
5045 send_ns(dev
[0], ip_src
="::", target
="aaaa:bbbb:cccc::2")
5047 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2")
5048 # test frame without source link-layer address option
5049 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5051 # test frame with bogus option
5052 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5053 opt
=b
"\x70\x01\x01\x02\x03\x04\x05\x05")
5054 # test frame with truncated source link-layer address option
5055 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5056 opt
=b
"\x01\x01\x01\x02\x03\x04")
5057 # test frame with foreign source link-layer address option
5058 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
5059 opt
=b
"\x01\x01\x01\x02\x03\x04\x05\x06")
5061 send_ns(dev
[1], ip_src
="aaaa:bbbb:dddd::2", target
="aaaa:bbbb:dddd::2")
5063 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
5064 # another copy for additional code coverage
5065 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
5067 macs
= get_bridge_macs("ap-br0")
5068 logger
.info("After connect (showmacs): " + str(macs
))
5070 matches
= get_permanent_neighbors("ap-br0")
5071 logger
.info("After connect: " + str(matches
))
5072 if len(matches
) != 3:
5073 raise Exception("Unexpected number of neighbor entries after connect")
5074 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
5075 raise Exception("dev0 addr missing")
5076 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
5077 raise Exception("dev1 addr(1) missing")
5078 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
5079 raise Exception("dev1 addr(2) missing")
5081 send_ns(dev
[0], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:cccc::2")
5083 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:dddd::2")
5085 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:dddd::2",
5086 ip_src
="aaaa:bbbb:ffff::2")
5088 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:ff00::2")
5090 send_ns(dev
[2], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:ff00::2")
5092 send_ns(dev
[2], target
="aaaa:bbbb:eeee::2", ip_src
="aaaa:bbbb:ff00::2")
5095 # Try to probe for an already assigned address
5096 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="::")
5098 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc::2", ip_src
="::")
5100 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="::")
5104 send_na(dev
[1], target
="aaaa:bbbb:cccc:aeae::3",
5105 ip_src
="aaaa:bbbb:cccc:aeae::3", ip_dst
="ff02::1")
5106 send_na(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc:aeae::4",
5107 ip_src
="aaaa:bbbb:cccc:aeae::4", ip_dst
="ff02::1")
5108 send_na(dev
[2], target
="aaaa:bbbb:cccc:aeae::5",
5109 ip_src
="aaaa:bbbb:cccc:aeae::5", ip_dst
="ff02::1")
5112 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
5113 except Exception as e
:
5114 logger
.info("test_connectibity_iface failed: " + str(e
))
5115 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
5116 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
5117 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
5119 dev
[0].request("DISCONNECT")
5120 dev
[1].request("DISCONNECT")
5122 for i
in range(len(cmd
)):
5124 macs
= get_bridge_macs("ap-br0")
5125 logger
.info("After disconnect (showmacs): " + str(macs
))
5126 matches
= get_permanent_neighbors("ap-br0")
5127 logger
.info("After disconnect: " + str(matches
))
5128 if len(matches
) > 0:
5129 raise Exception("Unexpected neighbor entries after disconnect")
5131 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
5132 stdout
=subprocess
.PIPE
)
5133 res
= cmd
.stdout
.read().decode()
5135 logger
.info("ebtables results:\n" + res
)
5137 ns
= tshark_get_ns(cap_dev0
)
5138 logger
.info("dev0 seen NS: " + str(ns
))
5139 na
= tshark_get_na(cap_dev0
)
5140 logger
.info("dev0 seen NA: " + str(na
))
5142 if [ addr0
, addr1
, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2',
5143 'aaaa:bbbb:dddd::2', addr1
] not in na
:
5144 # For now, skip the test instead of reporting the error since the IPv6
5145 # proxyarp support is not yet in the upstream kernel tree.
5146 #raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
5147 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp (IPv6)")
5152 raise Exception("Unexpected foreign NS on dev0: " + str(req
))
5154 ns
= tshark_get_ns(cap_dev1
)
5155 logger
.info("dev1 seen NS: " + str(ns
))
5156 na
= tshark_get_na(cap_dev1
)
5157 logger
.info("dev1 seen NA: " + str(na
))
5159 if [ addr1
, addr0
, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:dddd::2',
5160 'aaaa:bbbb:cccc::2', addr0
] not in na
:
5161 raise Exception("dev1 did not get NA for aaaa:bbbb:cccc::2")
5166 raise Exception("Unexpected foreign NS on dev1: " + str(req
))
5168 ns
= tshark_get_ns(cap_dev2
)
5169 logger
.info("dev2 seen NS: " + str(ns
))
5170 na
= tshark_get_na(cap_dev2
)
5171 logger
.info("dev2 seen NA: " + str(na
))
5173 # FIX: enable once kernel implementation for proxyarp IPv6 is fixed
5174 #if [ addr2, addr0, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:ff00::2',
5175 # 'aaaa:bbbb:cccc::2', addr0 ] not in na:
5176 # raise Exception("dev2 did not get NA for aaaa:bbbb:cccc::2")
5177 #if [ addr2, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:ff00::2',
5178 # 'aaaa:bbbb:dddd::2', addr1 ] not in na:
5179 # raise Exception("dev2 did not get NA for aaaa:bbbb:dddd::2")
5180 #if [ addr2, addr1, 'aaaa:bbbb:eeee::2', 'aaaa:bbbb:ff00::2',
5181 # 'aaaa:bbbb:eeee::2', addr1 ] not in na:
5182 # raise Exception("dev2 did not get NA for aaaa:bbbb:eeee::2")
5184 def test_proxyarp_open(dev
, apdev
, params
):
5185 """ProxyARP with open network"""
5187 _test_proxyarp_open(dev
, apdev
, params
)
5189 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5190 stderr
=open('/dev/null', 'w'))
5191 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5192 stderr
=open('/dev/null', 'w'))
5194 def test_proxyarp_open_ipv6(dev
, apdev
, params
):
5195 """ProxyARP with open network (IPv6)"""
5197 _test_proxyarp_open_ipv6(dev
, apdev
, params
)
5199 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5200 stderr
=open('/dev/null', 'w'))
5201 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5202 stderr
=open('/dev/null', 'w'))
5204 def test_proxyarp_open_ebtables(dev
, apdev
, params
):
5205 """ProxyARP with open network"""
5207 _test_proxyarp_open(dev
, apdev
, params
, ebtables
=True)
5210 subprocess
.call(['ebtables', '-F', 'FORWARD'])
5211 subprocess
.call(['ebtables', '-F', 'OUTPUT'])
5214 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5215 stderr
=open('/dev/null', 'w'))
5216 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5217 stderr
=open('/dev/null', 'w'))
5219 def test_proxyarp_open_ebtables_ipv6(dev
, apdev
, params
):
5220 """ProxyARP with open network (IPv6)"""
5222 _test_proxyarp_open_ipv6(dev
, apdev
, params
, ebtables
=True)
5225 subprocess
.call(['ebtables', '-F', 'FORWARD'])
5226 subprocess
.call(['ebtables', '-F', 'OUTPUT'])
5229 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5230 stderr
=open('/dev/null', 'w'))
5231 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5232 stderr
=open('/dev/null', 'w'))
5234 def test_proxyarp_errors(dev
, apdev
, params
):
5235 """ProxyARP error cases"""
5237 run_proxyarp_errors(dev
, apdev
, params
)
5239 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
5240 stderr
=open('/dev/null', 'w'))
5241 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
5242 stderr
=open('/dev/null', 'w'))
5244 def run_proxyarp_errors(dev
, apdev
, params
):
5245 params
= { 'ssid': 'open',
5249 'disable_dgaf': '1' }
5250 hapd
= hostapd
.add_ap(apdev
[0], params
, no_enable
=True)
5254 # For now, do not report failures due to missing kernel support
5255 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
5256 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
5258 raise Exception("AP startup timed out")
5259 if "AP-ENABLED" not in ev
:
5260 raise Exception("AP startup failed")
5263 with
alloc_fail(hapd
, 1, "l2_packet_init;x_snoop_get_l2_packet;dhcp_snoop_init"):
5264 if "FAIL" not in hapd
.request("ENABLE"):
5265 raise Exception("ENABLE accepted unexpectedly")
5266 with
alloc_fail(hapd
, 1, "l2_packet_init;x_snoop_get_l2_packet;ndisc_snoop_init"):
5267 if "FAIL" not in hapd
.request("ENABLE"):
5268 raise Exception("ENABLE accepted unexpectedly")
5269 with
fail_test(hapd
, 1, "l2_packet_set_packet_filter;x_snoop_get_l2_packet;ndisc_snoop_init"):
5270 if "FAIL" not in hapd
.request("ENABLE"):
5271 raise Exception("ENABLE accepted unexpectedly")
5272 with
fail_test(hapd
, 1, "l2_packet_set_packet_filter;x_snoop_get_l2_packet;dhcp_snoop_init"):
5273 if "FAIL" not in hapd
.request("ENABLE"):
5274 raise Exception("ENABLE accepted unexpectedly")
5277 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
5278 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
5280 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
5281 addr0
= dev
[0].own_addr()
5283 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
5285 with
fail_test(hapd
, 1, "x_snoop_mcast_to_ucast_convert_send"):
5286 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
).decode()):
5287 raise Exception("DATA_TEST_FRAME failed")
5288 wait_fail_trigger(dev
[0], "GET_FAIL")
5290 with
alloc_fail(hapd
, 1, "sta_ip6addr_add"):
5291 src_ll_opt0
= b
"\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
5292 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
5293 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
5295 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
).decode()):
5296 raise Exception("DATA_TEST_FRAME failed")
5297 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5299 def test_ap_hs20_connect_deinit(dev
, apdev
):
5300 """Hotspot 2.0 connection interrupted with deinit"""
5301 check_eap_capa(dev
[0], "MSCHAPV2")
5302 bssid
= apdev
[0]['bssid']
5303 params
= hs20_ap_params()
5304 params
['hessid'] = bssid
5305 hapd
= hostapd
.add_ap(apdev
[0], params
)
5307 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
5308 wpas
.interface_add("wlan5", drv_params
="")
5310 wpas
.flush_scan_cache()
5311 wpas
.add_cred_values({ 'realm': "example.com",
5312 'username': "hs20-test",
5313 'password': "password",
5314 'ca_cert': "auth_serv/ca.pem",
5315 'domain': "example.com" })
5317 wpas
.scan_for_bss(bssid
, freq
=2412)
5320 wpas
.request("INTERWORKING_SELECT freq=2412")
5322 id = wpas
.request("RADIO_WORK add block-work")
5323 ev
= wpas
.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout
=5)
5325 raise Exception("Timeout while waiting radio work to start")
5326 ev
= wpas
.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout
=5)
5328 raise Exception("Timeout while waiting radio work to start (2)")
5330 # Remove the interface while the gas-query radio work is still pending and
5331 # GAS query has not yet been started.
5332 wpas
.interface_remove("wlan5")
5334 def test_ap_hs20_anqp_format_errors(dev
, apdev
):
5335 """Interworking network selection and ANQP format errors"""
5336 bssid
= apdev
[0]['bssid']
5337 params
= hs20_ap_params()
5338 params
['hessid'] = bssid
5339 hapd
= hostapd
.add_ap(apdev
[0], params
)
5341 dev
[0].hs20_enable()
5342 values
= { 'realm': "example.com",
5343 'ca_cert': "auth_serv/ca.pem",
5344 'username': "hs20-test",
5345 'password': "password",
5346 'domain': "example.com" }
5347 id = dev
[0].add_cred_values(values
)
5349 dev
[0].scan_for_bss(bssid
, freq
="2412")
5351 tests
= [ "00", "ffff", "010011223344", "020008000005112233445500",
5352 "01000400000000", "01000000000000",
5353 "01000300000200", "0100040000ff0000", "01000300000100",
5355 "01000600000056112233",
5356 "01000900000002050001000111",
5357 "01000600000001000000", "01000600000001ff0000",
5358 "01000600000001020001",
5359 "010008000000010400010001", "0100080000000104000100ff",
5360 "010011000000010d00050200020100030005000600",
5363 hapd
.set("anqp_elem", "263:" + t
)
5364 dev
[0].request("INTERWORKING_SELECT freq=2412")
5365 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=5)
5367 raise Exception("Network selection timed out")
5368 dev
[0].dump_monitor()
5370 dev
[0].remove_cred(id)
5371 id = dev
[0].add_cred_values({ 'imsi': "555444-333222111", 'eap': "AKA",
5372 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
5374 tests
= [ "00", "0100", "0001", "00ff", "000200ff", "0003000101",
5377 hapd
.set("anqp_elem", "264:" + 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 def test_ap_hs20_cred_with_nai_realm(dev
, apdev
):
5385 """Hotspot 2.0 network selection and cred_with_nai_realm cred->realm"""
5386 bssid
= apdev
[0]['bssid']
5387 params
= hs20_ap_params()
5388 params
['hessid'] = bssid
5389 hostapd
.add_ap(apdev
[0], params
)
5391 dev
[0].hs20_enable()
5393 id = dev
[0].add_cred_values({ 'realm': "example.com",
5395 'password': "secret",
5396 'domain': "example.com",
5398 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5399 dev
[0].remove_cred(id)
5401 id = dev
[0].add_cred_values({ 'realm': "foo.com",
5403 'password': "secret",
5404 'domain': "example.com",
5405 'roaming_consortium': "112234",
5407 interworking_select(dev
[0], bssid
, "home", freq
=2412, no_match
=True)
5408 dev
[0].remove_cred(id)
5410 def test_ap_hs20_cred_and_no_roaming_consortium(dev
, apdev
):
5411 """Hotspot 2.0 network selection and no roaming consortium"""
5412 bssid
= apdev
[0]['bssid']
5413 params
= hs20_ap_params()
5414 params
['hessid'] = bssid
5415 del params
['roaming_consortium']
5416 hostapd
.add_ap(apdev
[0], params
)
5418 dev
[0].hs20_enable()
5420 id = dev
[0].add_cred_values({ 'realm': "example.com",
5422 'password': "secret",
5423 'domain': "example.com",
5424 'roaming_consortium': "112234",
5426 interworking_select(dev
[0], bssid
, "home", freq
=2412, no_match
=True)
5428 def test_ap_hs20_interworking_oom(dev
, apdev
):
5429 """Hotspot 2.0 network selection and OOM"""
5430 bssid
= apdev
[0]['bssid']
5431 params
= hs20_ap_params()
5432 params
['hessid'] = bssid
5433 params
['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]",
5434 "0,example.com,13[5:6],21[2:4][5:7]",
5435 "0,another.example.com" ]
5436 hostapd
.add_ap(apdev
[0], params
)
5438 dev
[0].hs20_enable()
5440 id = dev
[0].add_cred_values({ 'realm': "example.com",
5442 'password': "secret",
5443 'domain': "example.com",
5446 dev
[0].scan_for_bss(bssid
, freq
="2412")
5448 funcs
= [ "wpabuf_alloc;interworking_anqp_send_req",
5449 "anqp_build_req;interworking_anqp_send_req",
5450 "gas_query_req;interworking_anqp_send_req",
5451 "dup_binstr;nai_realm_parse_realm",
5452 "=nai_realm_parse_realm",
5454 "=nai_realm_match" ]
5456 with
alloc_fail(dev
[0], 1, func
):
5457 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
5458 ev
= dev
[0].wait_event(["Starting ANQP"], timeout
=5)
5460 raise Exception("ANQP did not start")
5461 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5463 def test_ap_hs20_no_cred_connect(dev
, apdev
):
5464 """Hotspot 2.0 and connect attempt without credential"""
5465 bssid
= apdev
[0]['bssid']
5466 params
= hs20_ap_params()
5467 params
['hessid'] = bssid
5468 hapd
= hostapd
.add_ap(apdev
[0], params
)
5470 dev
[0].hs20_enable()
5471 dev
[0].scan_for_bss(bssid
, freq
="2412")
5472 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT " + bssid
):
5473 raise Exception("Unexpected INTERWORKING_CONNECT success")
5475 def test_ap_hs20_no_rsn_connect(dev
, apdev
):
5476 """Hotspot 2.0 and connect attempt without RSN"""
5477 bssid
= apdev
[0]['bssid']
5478 params
= hostapd
.wpa_params(ssid
="test-hs20")
5479 params
['wpa_key_mgmt'] = "WPA-EAP"
5480 params
['ieee80211w'] = "1"
5481 params
['ieee8021x'] = "1"
5482 params
['auth_server_addr'] = "127.0.0.1"
5483 params
['auth_server_port'] = "1812"
5484 params
['auth_server_shared_secret'] = "radius"
5485 params
['interworking'] = "1"
5486 params
['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
5488 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
5489 "0,another.example.com" ]
5490 hapd
= hostapd
.add_ap(apdev
[0], params
)
5492 dev
[0].hs20_enable()
5493 dev
[0].scan_for_bss(bssid
, freq
="2412")
5495 id = dev
[0].add_cred_values({ 'realm': "example.com",
5497 'password': "secret",
5498 'domain': "example.com",
5499 'roaming_consortium': "112233",
5502 interworking_select(dev
[0], bssid
, freq
=2412, no_match
=True)
5503 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT " + bssid
):
5504 raise Exception("Unexpected INTERWORKING_CONNECT success")
5506 def test_ap_hs20_no_match_connect(dev
, apdev
):
5507 """Hotspot 2.0 and connect attempt without matching cred"""
5508 bssid
= apdev
[0]['bssid']
5509 params
= hs20_ap_params()
5510 hapd
= hostapd
.add_ap(apdev
[0], params
)
5512 dev
[0].hs20_enable()
5513 dev
[0].scan_for_bss(bssid
, freq
="2412")
5515 id = dev
[0].add_cred_values({ 'realm': "example.org",
5517 'password': "secret",
5518 'domain': "example.org",
5519 'roaming_consortium': "112234",
5522 interworking_select(dev
[0], bssid
, freq
=2412, no_match
=True)
5523 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT " + bssid
):
5524 raise Exception("Unexpected INTERWORKING_CONNECT success")
5526 def test_ap_hs20_multiple_home_cred(dev
, apdev
):
5527 """Hotspot 2.0 and select with multiple matching home credentials"""
5528 bssid
= apdev
[0]['bssid']
5529 params
= hs20_ap_params()
5530 params
['hessid'] = bssid
5531 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
5532 params
['domain_name'] = "example.com"
5533 hapd
= hostapd
.add_ap(apdev
[0], params
)
5535 bssid2
= apdev
[1]['bssid']
5536 params
= hs20_ap_params(ssid
="test-hs20-other")
5537 params
['hessid'] = bssid2
5538 params
['nai_realm'] = [ "0,example.org,13[5:6],21[2:4][5:7]" ]
5539 params
['domain_name'] = "example.org"
5540 hapd2
= hostapd
.add_ap(apdev
[1], params
)
5542 dev
[0].hs20_enable()
5543 dev
[0].scan_for_bss(bssid2
, freq
="2412")
5544 dev
[0].scan_for_bss(bssid
, freq
="2412")
5545 id = dev
[0].add_cred_values({ 'realm': "example.com",
5547 'username': "hs20-test",
5548 'password': "password",
5549 'domain': "example.com" })
5550 id2
= dev
[0].add_cred_values({ 'realm': "example.org",
5552 'username': "hs20-test",
5553 'password': "password",
5554 'domain': "example.org" })
5555 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
5556 ev
= dev
[0].wait_connected(timeout
=15)
5557 if bssid2
not in ev
:
5558 raise Exception("Connected to incorrect network")
5560 def test_ap_hs20_anqp_invalid_gas_response(dev
, apdev
):
5561 """Hotspot 2.0 network selection and invalid GAS response"""
5562 bssid
= apdev
[0]['bssid']
5563 params
= hs20_ap_params()
5564 params
['hessid'] = bssid
5565 hapd
= hostapd
.add_ap(apdev
[0], params
)
5567 dev
[0].scan_for_bss(bssid
, freq
="2412")
5568 hapd
.set("ext_mgmt_frame_handling", "1")
5570 dev
[0].hs20_enable()
5572 id = dev
[0].add_cred_values({ 'realm': "example.com",
5574 'password': "secret",
5575 'domain': "example.com",
5576 'roaming_consortium': "112234",
5578 dev
[0].request("INTERWORKING_SELECT freq=2412")
5580 query
= gas_rx(hapd
)
5581 gas
= parse_gas(query
['payload'])
5583 logger
.info("ANQP: Unexpected Advertisement Protocol in response")
5584 resp
= action_response(query
)
5585 adv_proto
= struct
.pack('8B', 108, 6, 127, 0xdd, 0x00, 0x11, 0x22, 0x33)
5586 data
= struct
.pack('<H', 0)
5587 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5588 GAS_INITIAL_RESPONSE
,
5589 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5590 send_gas_resp(hapd
, resp
)
5592 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5594 raise Exception("No ANQP-QUERY-DONE seen")
5595 if "result=INVALID_FRAME" not in ev
:
5596 raise Exception("Unexpected result: " + ev
)
5598 dev
[0].request("INTERWORKING_SELECT freq=2412")
5600 query
= gas_rx(hapd
)
5601 gas
= parse_gas(query
['payload'])
5603 logger
.info("ANQP: Invalid element length for Info ID 1234")
5604 resp
= action_response(query
)
5605 adv_proto
= struct
.pack('BBBB', 108, 2, 127, 0)
5606 elements
= struct
.pack('<HH', 1234, 1)
5607 data
= struct
.pack('<H', len(elements
)) + elements
5608 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5609 GAS_INITIAL_RESPONSE
,
5610 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5611 send_gas_resp(hapd
, resp
)
5613 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5615 raise Exception("No ANQP-QUERY-DONE seen")
5616 if "result=INVALID_FRAME" not in ev
:
5617 raise Exception("Unexpected result: " + ev
)
5619 with
alloc_fail(dev
[0], 1, "=anqp_add_extra"):
5620 dev
[0].request("INTERWORKING_SELECT freq=2412")
5622 query
= gas_rx(hapd
)
5623 gas
= parse_gas(query
['payload'])
5625 resp
= action_response(query
)
5626 elements
= struct
.pack('<HHHH', 1, 0, 1, 0)
5627 data
= struct
.pack('<H', len(elements
)) + elements
5628 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5629 GAS_INITIAL_RESPONSE
,
5630 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5631 send_gas_resp(hapd
, resp
)
5633 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5635 raise Exception("No ANQP-QUERY-DONE seen")
5636 if "result=SUCCESS" not in ev
:
5637 raise Exception("Unexpected result: " + ev
)
5639 with
alloc_fail(dev
[0], 1, "wpabuf_alloc_copy;anqp_add_extra"):
5640 dev
[0].request("INTERWORKING_SELECT freq=2412")
5642 query
= gas_rx(hapd
)
5643 gas
= parse_gas(query
['payload'])
5645 resp
= action_response(query
)
5646 elements
= struct
.pack('<HHHH', 1, 0, 1, 0)
5647 data
= struct
.pack('<H', len(elements
)) + elements
5648 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5649 GAS_INITIAL_RESPONSE
,
5650 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5651 send_gas_resp(hapd
, resp
)
5653 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5655 raise Exception("No ANQP-QUERY-DONE seen")
5656 if "result=SUCCESS" not in ev
:
5657 raise Exception("Unexpected result: " + ev
)
5659 tests
= [ struct
.pack('<HH', 0xdddd, 0),
5660 struct
.pack('<HH3B', 0xdddd, 3, 0x50, 0x6f, 0x9a),
5661 struct
.pack('<HH4B', 0xdddd, 4, 0x50, 0x6f, 0x9a, 0),
5662 struct
.pack('<HH4B', 0xdddd, 4, 0x11, 0x22, 0x33, 0),
5663 struct
.pack('<HHHH', 1, 0, 1, 0) ]
5664 for elements
in tests
:
5665 dev
[0].request("INTERWORKING_SELECT freq=2412")
5667 query
= gas_rx(hapd
)
5668 gas
= parse_gas(query
['payload'])
5670 resp
= action_response(query
)
5671 data
= struct
.pack('<H', len(elements
)) + elements
5672 resp
['payload'] = struct
.pack('<BBBHH', ACTION_CATEG_PUBLIC
,
5673 GAS_INITIAL_RESPONSE
,
5674 gas
['dialog_token'], 0, 0) + adv_proto
+ data
5675 send_gas_resp(hapd
, resp
)
5677 ev
= dev
[0].wait_event(["ANQP-QUERY-DONE"], timeout
=5)
5679 raise Exception("No ANQP-QUERY-DONE seen")
5680 if "result=SUCCESS" not in ev
:
5681 raise Exception("Unexpected result: " + ev
)
5683 def test_ap_hs20_set_profile_failures(dev
, apdev
):
5684 """Hotspot 2.0 and failures during profile configuration"""
5685 bssid
= apdev
[0]['bssid']
5686 params
= hs20_ap_params()
5687 params
['hessid'] = bssid
5688 params
['anqp_3gpp_cell_net'] = "555,444"
5689 hapd
= hostapd
.add_ap(apdev
[0], params
)
5691 dev
[0].hs20_enable()
5692 dev
[0].scan_for_bss(bssid
, freq
="2412")
5694 id = dev
[0].add_cred_values({ 'realm': "example.com",
5695 'domain': "example.com",
5697 'password': "secret",
5699 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5700 dev
[0].dump_monitor()
5701 dev
[0].request("NOTE ssid->eap.eap_methods = os_malloc()")
5702 with
alloc_fail(dev
[0], 1, "interworking_set_eap_params"):
5703 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5704 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5705 dev
[0].remove_cred(id)
5707 id = dev
[0].add_cred_values({ 'realm': "example.com",
5708 'domain': "example.com",
5709 'username': "hs20-test-with-domain@example.com",
5710 'password': "password" })
5711 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5712 dev
[0].dump_monitor()
5713 dev
[0].request("NOTE anon = os_malloc()")
5714 with
alloc_fail(dev
[0], 1, "interworking_set_eap_params"):
5715 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5716 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5717 dev
[0].request("NOTE Successful connection with cred->username including realm")
5718 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5719 dev
[0].wait_connected()
5720 dev
[0].remove_cred(id)
5721 dev
[0].wait_disconnected()
5723 id = dev
[0].add_cred_values({ 'realm': "example.com",
5724 'domain': "example.com",
5725 'username': "hs20-test",
5726 'password': "password" })
5727 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5728 dev
[0].dump_monitor()
5729 dev
[0].request("NOTE anon = os_malloc() (second)")
5730 with
alloc_fail(dev
[0], 1, "interworking_set_eap_params"):
5731 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5732 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5733 with
alloc_fail(dev
[0], 1, "wpa_config_add_network;interworking_connect"):
5734 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5735 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5736 with
alloc_fail(dev
[0], 1, "=interworking_connect"):
5737 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5738 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5739 dev
[0].request("NOTE wpa_config_set(eap)")
5740 with
alloc_fail(dev
[0], 1, "wpa_config_parse_eap;wpa_config_set;interworking_connect"):
5741 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5742 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5743 dev
[0].request("NOTE wpa_config_set(TTLS-NON_EAP_MSCHAPV2-phase2)")
5744 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5745 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5746 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5747 dev
[0].remove_cred(id)
5749 id = dev
[0].add_cred_values({ 'roaming_consortium': "112233",
5750 'domain': "example.com",
5751 'username': "hs20-test",
5752 'password': "password",
5754 'phase2': "auth=MSCHAPV2" })
5755 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5756 dev
[0].dump_monitor()
5757 dev
[0].request("NOTE anon = os_strdup()")
5758 with
alloc_fail(dev
[0], 2, "interworking_set_eap_params"):
5759 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5760 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5761 dev
[0].request("NOTE wpa_config_set_quoted(anonymous_identity)")
5762 with
alloc_fail(dev
[0], 1, "=wpa_config_set_quoted;interworking_set_eap_params"):
5763 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5764 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5765 dev
[0].request("NOTE Successful connection with cred->realm not included")
5766 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5767 dev
[0].wait_connected()
5768 dev
[0].remove_cred(id)
5769 dev
[0].wait_disconnected()
5771 id = dev
[0].add_cred_values({ 'roaming_consortium': "112233",
5772 'domain': "example.com",
5773 'realm': "example.com",
5775 'password': "password",
5777 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5778 dev
[0].dump_monitor()
5779 dev
[0].request("NOTE id = os_strdup()")
5780 with
alloc_fail(dev
[0], 2, "interworking_set_eap_params"):
5781 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5782 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5783 dev
[0].request("NOTE wpa_config_set_quoted(identity)")
5784 with
alloc_fail(dev
[0], 1, "=wpa_config_set_quoted;interworking_set_eap_params"):
5785 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5786 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5787 dev
[0].remove_cred(id)
5789 id = dev
[0].add_cred_values({ 'roaming_consortium': "112233",
5790 'domain': "example.com",
5791 'realm': "example.com",
5793 'password': "password",
5795 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5796 dev
[0].dump_monitor()
5797 dev
[0].request("NOTE wpa_config_set_quoted(identity) (second)")
5798 with
alloc_fail(dev
[0], 2, "=wpa_config_set_quoted;interworking_set_eap_params"):
5799 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5800 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5801 dev
[0].request("NOTE wpa_config_set_quoted(password)")
5802 with
alloc_fail(dev
[0], 3, "=wpa_config_set_quoted;interworking_set_eap_params"):
5803 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5804 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5805 with
alloc_fail(dev
[0], 1, "wpa_config_add_network;interworking_connect_roaming_consortium"):
5806 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5807 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5808 with
alloc_fail(dev
[0], 1, "=interworking_connect_roaming_consortium"):
5809 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5810 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5811 dev
[0].remove_cred(id)
5813 id = dev
[0].add_cred_values({ 'roaming_consortium': "112233",
5814 'domain': "example.com",
5815 'realm': "example.com",
5818 dev
[0].set_cred(id, "password", "ext:password")
5819 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5820 dev
[0].dump_monitor()
5821 dev
[0].request("NOTE wpa_config_set(password)")
5822 with
alloc_fail(dev
[0], 3, "wpa_config_set;interworking_set_eap_params"):
5823 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5824 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5825 with
alloc_fail(dev
[0], 1, "interworking_set_hs20_params"):
5826 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5827 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5828 dev
[0].remove_cred(id)
5830 id = dev
[0].add_cred_values({ 'realm': "example.com",
5831 'domain': "example.com",
5832 'username': "certificate-user",
5833 'phase1': "include_tls_length=0",
5834 'domain_suffix_match': "example.com",
5835 'ca_cert': "auth_serv/ca.pem",
5836 'client_cert': "auth_serv/user.pem",
5837 'private_key': "auth_serv/user.key",
5838 'private_key_passwd': "secret" })
5839 interworking_select(dev
[0], bssid
, "home", freq
=2412)
5840 dev
[0].dump_monitor()
5841 dev
[0].request("NOTE wpa_config_set_quoted(client_cert)")
5842 with
alloc_fail(dev
[0], 2, "=wpa_config_set_quoted;interworking_set_eap_params"):
5843 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5844 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5845 dev
[0].request("NOTE wpa_config_set_quoted(private_key)")
5846 with
alloc_fail(dev
[0], 3, "=wpa_config_set_quoted;interworking_set_eap_params"):
5847 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5848 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5849 dev
[0].request("NOTE wpa_config_set_quoted(private_key_passwd)")
5850 with
alloc_fail(dev
[0], 4, "=wpa_config_set_quoted;interworking_set_eap_params"):
5851 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5852 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5853 dev
[0].request("NOTE wpa_config_set_quoted(ca_cert)")
5854 with
alloc_fail(dev
[0], 5, "=wpa_config_set_quoted;interworking_set_eap_params"):
5855 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5856 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5857 dev
[0].request("NOTE wpa_config_set_quoted(domain_suffix_match)")
5858 with
alloc_fail(dev
[0], 6, "=wpa_config_set_quoted;interworking_set_eap_params"):
5859 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5860 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5861 with
alloc_fail(dev
[0], 1, "interworking_set_hs20_params"):
5862 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5863 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5864 dev
[0].remove_cred(id)
5866 id = dev
[0].add_cred_values({ 'imsi': "555444-333222111", 'eap': "SIM",
5867 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
5868 interworking_select(dev
[0], bssid
, freq
=2412)
5869 dev
[0].dump_monitor()
5870 with
alloc_fail(dev
[0], 1, "interworking_set_hs20_params"):
5871 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5872 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5873 dev
[0].request("NOTE wpa_config_set_quoted(password;milenage)")
5874 with
alloc_fail(dev
[0], 2, "=wpa_config_set_quoted;interworking_connect_3gpp"):
5875 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5876 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5877 dev
[0].request("NOTE wpa_config_set(eap)")
5878 with
alloc_fail(dev
[0], 1, "wpa_config_parse_eap;wpa_config_set;interworking_connect_3gpp"):
5879 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5880 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5881 dev
[0].request("NOTE set_root_nai:wpa_config_set(identity)")
5882 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;interworking_connect_3gpp"):
5883 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5884 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5885 dev
[0].remove_cred(id)
5887 id = dev
[0].add_cred_values({ 'roaming_consortium': "112233",
5888 'username': "user@example.com",
5889 'password': "password" })
5890 interworking_select(dev
[0], bssid
, freq
=2412)
5891 dev
[0].dump_monitor()
5892 dev
[0].request("NOTE Interworking: No EAP method set for credential using roaming consortium")
5893 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5894 dev
[0].remove_cred(id)
5897 params
= hs20_ap_params()
5898 params
['nai_realm'] = "0,example.com,25[3:26]"
5899 hapd
= hostapd
.add_ap(apdev
[0], params
)
5900 id = dev
[0].add_cred_values({ 'realm': "example.com",
5901 'domain': "example.com",
5902 'username': "hs20-test",
5903 'password': "password" })
5904 interworking_select(dev
[0], bssid
, freq
=2412)
5905 dev
[0].dump_monitor()
5906 dev
[0].request("NOTE wpa_config_set(PEAP/FAST-phase1)")
5907 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5908 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5909 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5910 dev
[0].request("NOTE wpa_config_set(PEAP/FAST-pac_interworking)")
5911 with
alloc_fail(dev
[0], 2, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5912 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5913 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5914 dev
[0].request("NOTE wpa_config_set(PEAP/FAST-phase2)")
5915 with
alloc_fail(dev
[0], 3, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5916 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5917 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5920 params
= hs20_ap_params()
5921 params
['nai_realm'] = "0,example.com,21"
5922 hapd
= hostapd
.add_ap(apdev
[0], params
)
5923 interworking_select(dev
[0], bssid
, freq
=2412)
5924 dev
[0].request("NOTE wpa_config_set(TTLS-defaults-phase2)")
5925 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5926 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5927 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5930 params
= hs20_ap_params()
5931 params
['nai_realm'] = "0,example.com,21[2:3]"
5932 hapd
= hostapd
.add_ap(apdev
[0], params
)
5933 interworking_select(dev
[0], bssid
, freq
=2412)
5934 dev
[0].request("NOTE wpa_config_set(TTLS-NON_EAP_MSCHAP-phase2)")
5935 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5936 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5937 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5940 params
= hs20_ap_params()
5941 params
['nai_realm'] = "0,example.com,21[2:2]"
5942 hapd
= hostapd
.add_ap(apdev
[0], params
)
5943 interworking_select(dev
[0], bssid
, freq
=2412)
5944 dev
[0].request("NOTE wpa_config_set(TTLS-NON_EAP_CHAP-phase2)")
5945 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5946 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5947 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5950 params
= hs20_ap_params()
5951 params
['nai_realm'] = "0,example.com,21[2:1]"
5952 hapd
= hostapd
.add_ap(apdev
[0], params
)
5953 interworking_select(dev
[0], bssid
, freq
=2412)
5954 dev
[0].request("NOTE wpa_config_set(TTLS-NON_EAP_PAP-phase2)")
5955 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5956 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5957 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5960 params
= hs20_ap_params()
5961 params
['nai_realm'] = "0,example.com,21[3:26]"
5962 hapd
= hostapd
.add_ap(apdev
[0], params
)
5963 interworking_select(dev
[0], bssid
, freq
=2412)
5964 dev
[0].request("NOTE wpa_config_set(TTLS-EAP-MSCHAPV2-phase2)")
5965 with
alloc_fail(dev
[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"):
5966 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
5967 wait_fail_trigger(dev
[0], "GET_ALLOC_FAIL")
5969 dev
[0].remove_cred(id)
5971 def test_ap_hs20_unexpected(dev
, apdev
):
5972 """Unexpected Hotspot 2.0 AP configuration"""
5973 check_eap_capa(dev
[0], "MSCHAPV2")
5974 bssid
= apdev
[0]['bssid']
5975 params
= hostapd
.wpa_eap_params(ssid
="test-hs20-fake")
5977 params
['wpa_pairwise'] = "TKIP CCMP"
5978 params
['rsn_pairwise'] = "CCMP"
5979 params
['ieee80211w'] = "1"
5980 #params['vendor_elements'] = 'dd07506f9a10140000'
5981 params
['vendor_elements'] = 'dd04506f9a10'
5982 hostapd
.add_ap(apdev
[0], params
)
5984 dev
[0].hs20_enable()
5985 dev
[0].scan_for_bss(bssid
, freq
="2412")
5986 dev
[0].connect("test-hs20-fake", key_mgmt
="WPA-EAP", eap
="TTLS",
5988 identity
="hs20-test", password
="password",
5989 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
5992 dev
[1].hs20_enable()
5993 dev
[1].scan_for_bss(bssid
, freq
="2412")
5994 dev
[1].connect("test-hs20-fake", key_mgmt
="WPA-EAP", eap
="TTLS",
5996 identity
="hs20-test", password
="password",
5997 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6000 dev
[2].hs20_enable()
6001 dev
[2].scan_for_bss(bssid
, freq
="2412")
6002 dev
[2].connect("test-hs20-fake", key_mgmt
="WPA-EAP", eap
="TTLS",
6004 proto
="RSN", pairwise
="CCMP",
6005 identity
="hs20-test", password
="password",
6006 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6009 def test_ap_interworking_element_update(dev
, apdev
):
6010 """Dynamic Interworking element update"""
6011 bssid
= apdev
[0]['bssid']
6012 params
= hs20_ap_params()
6013 params
['hessid'] = bssid
6014 hapd
= hostapd
.add_ap(apdev
[0], params
)
6016 dev
[0].hs20_enable()
6017 dev
[0].scan_for_bss(bssid
, freq
="2412")
6018 bss
= dev
[0].get_bss(bssid
)
6019 logger
.info("Before update: " + str(bss
))
6020 if '6b091e0701020000000300' not in bss
['ie']:
6021 raise Exception("Expected Interworking element not seen before update")
6023 # Update configuration parameters related to Interworking element
6024 hapd
.set('access_network_type', '2')
6025 hapd
.set('asra', '1')
6026 hapd
.set('esr', '1')
6027 hapd
.set('uesa', '1')
6028 hapd
.set('venue_group', '2')
6029 hapd
.set('venue_type', '8')
6030 if "OK" not in hapd
.request("UPDATE_BEACON"):
6031 raise Exception("UPDATE_BEACON failed")
6032 dev
[0].request("BSS_FLUSH 0")
6033 dev
[0].scan_for_bss(bssid
, freq
="2412", force_scan
=True)
6034 bss
= dev
[0].get_bss(bssid
)
6035 logger
.info("After update: " + str(bss
))
6036 if '6b09f20208020000000300' not in bss
['ie']:
6037 raise Exception("Expected Interworking element not seen after update")
6039 def test_ap_hs20_terms_and_conditions(dev
, apdev
):
6040 """Hotspot 2.0 Terms and Conditions signaling"""
6041 check_eap_capa(dev
[0], "MSCHAPV2")
6042 bssid
= apdev
[0]['bssid']
6043 params
= hs20_ap_params()
6044 params
['hessid'] = bssid
6045 params
['hs20_t_c_filename'] = 'terms-and-conditions'
6046 params
['hs20_t_c_timestamp'] = '123456789'
6048 hostapd
.add_ap(apdev
[0], params
)
6050 dev
[0].hs20_enable()
6051 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
6052 identity
="hs20-t-c-test", password
="password",
6053 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6054 ieee80211w
='2', scan_freq
="2412")
6055 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=5)
6057 raise Exception("Terms and Conditions Acceptance notification not received")
6058 url
= "https://example.com/t_and_c?addr=%s&ap=123" % dev
[0].own_addr()
6060 raise Exception("Unexpected URL: " + ev
)
6062 def test_ap_hs20_terms_and_conditions_coa(dev
, apdev
):
6063 """Hotspot 2.0 Terms and Conditions signaling - CoA"""
6067 import pyrad
.dictionary
6070 raise HwsimSkip("No pyrad modules available")
6072 check_eap_capa(dev
[0], "MSCHAPV2")
6073 bssid
= apdev
[0]['bssid']
6074 params
= hs20_ap_params()
6075 params
['hessid'] = bssid
6076 params
['hs20_t_c_filename'] = 'terms-and-conditions'
6077 params
['hs20_t_c_timestamp'] = '123456789'
6078 params
['own_ip_addr'] = "127.0.0.1"
6079 params
['radius_das_port'] = "3799"
6080 params
['radius_das_client'] = "127.0.0.1 secret"
6081 params
['radius_das_require_event_timestamp'] = "1"
6082 hapd
= hostapd
.add_ap(apdev
[0], params
)
6084 dev
[0].hs20_enable()
6085 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
6086 identity
="hs20-t-c-test", password
="password",
6087 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6088 ieee80211w
='2', scan_freq
="2412")
6090 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=5)
6092 raise Exception("Terms and Conditions filtering not enabled")
6093 if ev
.split(' ')[1] != dev
[0].own_addr():
6094 raise Exception("Unexpected STA address for filtering: " + ev
)
6096 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=5)
6098 raise Exception("Terms and Conditions Acceptance notification not received")
6099 url
= "https://example.com/t_and_c?addr=%s&ap=123" % dev
[0].own_addr()
6101 raise Exception("Unexpected URL: " + ev
)
6103 dict = pyrad
.dictionary
.Dictionary("dictionary.radius")
6105 srv
= pyrad
.client
.Client(server
="127.0.0.1", acctport
=3799,
6106 secret
="secret", dict=dict)
6110 sta
= hapd
.get_sta(dev
[0].own_addr())
6111 multi_sess_id
= sta
['authMultiSessionId']
6113 logger
.info("CoA-Request with matching Acct-Session-Id")
6114 vsa
= binascii
.unhexlify('00009f68090600000000')
6115 req
= radius_das
.CoAPacket(dict=dict, secret
="secret",
6116 NAS_IP_Address
="127.0.0.1",
6117 Acct_Multi_Session_Id
=multi_sess_id
,
6118 Chargeable_User_Identity
="hs20-cui",
6119 Event_Timestamp
=int(time
.time()),
6120 Vendor_Specific
=vsa
)
6121 reply
= srv
.SendPacket(req
)
6122 logger
.debug("RADIUS response from hostapd")
6123 for i
in list(reply
.keys()):
6124 logger
.debug("%s: %s" % (i
, reply
[i
]))
6125 if reply
.code
!= pyrad
.packet
.CoAACK
:
6126 raise Exception("CoA-Request failed")
6128 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-REMOVE"], timeout
=5)
6130 raise Exception("Terms and Conditions filtering not disabled")
6131 if ev
.split(' ')[1] != dev
[0].own_addr():
6132 raise Exception("Unexpected STA address for filtering: " + ev
)
6134 def test_ap_hs20_terms_and_conditions_sql(dev
, apdev
, params
):
6135 """Hotspot 2.0 Terms and Conditions using SQLite for user DB"""
6136 addr
= dev
[0].own_addr()
6137 run_ap_hs20_terms_and_conditions_sql(dev
, apdev
, params
,
6138 "https://example.com/t_and_c?addr=@1@&ap=123",
6139 "https://example.com/t_and_c?addr=" + addr
+ "&ap=123")
6141 def test_ap_hs20_terms_and_conditions_sql2(dev
, apdev
, params
):
6142 """Hotspot 2.0 Terms and Conditions using SQLite for user DB"""
6143 addr
= dev
[0].own_addr()
6144 run_ap_hs20_terms_and_conditions_sql(dev
, apdev
, params
,
6145 "https://example.com/t_and_c?addr=@1@",
6146 "https://example.com/t_and_c?addr=" + addr
)
6148 def run_ap_hs20_terms_and_conditions_sql(dev
, apdev
, params
, url_template
,
6150 check_eap_capa(dev
[0], "MSCHAPV2")
6154 raise HwsimSkip("No sqlite3 module available")
6155 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
6160 con
= sqlite3
.connect(dbfile
)
6163 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER, t_c_timestamp INTEGER)")
6164 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
6165 cur
.execute("INSERT INTO users(identity,methods,password,phase2) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1)")
6166 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
6167 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
6168 cur
.execute("CREATE TABLE pending_tc(mac_addr TEXT PRIMARY KEY, identity TEXT)")
6169 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)")
6173 params
= { "ssid": "as", "beacon_int": "2000",
6174 "radius_server_clients": "auth_serv/radius_clients.conf",
6175 "radius_server_auth_port": '18128',
6177 "eap_user_file": "sqlite:" + dbfile
,
6178 "ca_cert": "auth_serv/ca.pem",
6179 "server_cert": "auth_serv/server.pem",
6180 "private_key": "auth_serv/server.key" }
6181 params
['hs20_t_c_server_url'] = url_template
6182 authsrv
= hostapd
.add_ap(apdev
[1], params
)
6184 bssid
= apdev
[0]['bssid']
6185 params
= hs20_ap_params()
6186 params
['auth_server_port'] = "18128"
6187 params
['hs20_t_c_filename'] = 'terms-and-conditions'
6188 params
['hs20_t_c_timestamp'] = '123456789'
6189 params
['own_ip_addr'] = "127.0.0.1"
6190 params
['radius_das_port'] = "3799"
6191 params
['radius_das_client'] = "127.0.0.1 radius"
6192 params
['radius_das_require_event_timestamp'] = "1"
6193 params
['disable_pmksa_caching'] = '1'
6194 hapd
= hostapd
.add_ap(apdev
[0], params
)
6196 dev
[0].request("SET pmf 1")
6197 dev
[0].hs20_enable()
6198 id = dev
[0].add_cred_values({ 'realm': "example.com",
6199 'username': "user-mschapv2",
6200 'password': "password",
6201 'ca_cert': "auth_serv/ca.pem" })
6202 interworking_select(dev
[0], bssid
, freq
="2412")
6203 interworking_connect(dev
[0], bssid
, "TTLS")
6205 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=5)
6207 raise Exception("Terms and Conditions filtering not enabled")
6210 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=5)
6212 raise Exception("Terms and Conditions Acceptance notification not received")
6213 url
= ev
.split(' ')[1]
6214 if url
!= url_expected
:
6215 raise Exception("Unexpected URL delivered to the client: %s (expected %s)" % (url
, url_expected
))
6216 dev
[0].dump_monitor()
6220 cur
.execute("SELECT * from current_sessions")
6221 rows
= cur
.fetchall()
6223 raise Exeception("Unexpected number of rows in current_sessions (%d; expected %d)" % (len(rows
), 1))
6224 logger
.info("current_sessions: " + str(rows
))
6226 if "OK" not in authsrv
.request("DAC_REQUEST coa %s t_c_clear" % dev
[0].own_addr()):
6227 raise Exception("DAC_REQUEST failed")
6229 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-REMOVE"], timeout
=5)
6231 raise Exception("Terms and Conditions filtering not disabled")
6232 if ev
.split(' ')[1] != dev
[0].own_addr():
6233 raise Exception("Unexpected STA address for filtering: " + ev
)
6238 cur
.execute("SELECT * from current_sessions")
6239 rows
= cur
.fetchall()
6241 raise Exeception("Unexpected number of rows in current_sessions (%d; expected %d)" % (len(rows
), 1))
6242 logger
.info("current_sessions: " + str(rows
))
6243 if rows
[0][4] != 0 or rows
[0][5] != 0 or rows
[0][6] != 1:
6244 raise Exception("Unexpected current_sessions information after CoA-ACK")
6246 dev
[0].request("DISCONNECT")
6247 dev
[0].wait_disconnected()
6248 dev
[0].dump_monitor()
6250 # Simulate T&C server operation on user reading the updated version
6253 cur
.execute("SELECT identity FROM pending_tc WHERE mac_addr='" +
6254 dev
[0].own_addr() + "'")
6255 rows
= cur
.fetchall()
6257 raise Exception("No pending_tc entry found")
6258 if rows
[0][0] != 'user-mschapv2':
6259 raise Exception("Unexpected pending_tc identity value")
6261 cur
.execute("UPDATE users SET t_c_timestamp=123456789 WHERE identity='user-mschapv2'")
6263 dev
[0].request("RECONNECT")
6264 dev
[0].wait_connected()
6266 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=0.1)
6268 raise Exception("Terms and Conditions filtering enabled unexpectedly")
6271 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=0.1)
6273 raise Exception("Unexpected Terms and Conditions Acceptance notification")
6274 dev
[0].dump_monitor()
6276 dev
[0].request("DISCONNECT")
6277 dev
[0].wait_disconnected()
6278 dev
[0].dump_monitor()
6281 hapd
.set('hs20_t_c_timestamp', '123456790')
6283 dev
[0].request("RECONNECT")
6284 dev
[0].wait_connected()
6286 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=5)
6288 raise Exception("Terms and Conditions filtering not enabled")
6291 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=5)
6293 raise Exception("Terms and Conditions Acceptance notification not received (2)")
6294 dev
[0].dump_monitor()
6296 dev
[0].request("DISCONNECT")
6297 dev
[0].wait_disconnected()
6298 dev
[0].dump_monitor()
6300 # Simulate T&C server operation on user reading the updated version
6303 cur
.execute("UPDATE users SET t_c_timestamp=123456790 WHERE identity='user-mschapv2'")
6305 dev
[0].request("RECONNECT")
6306 dev
[0].wait_connected()
6308 ev
= hapd
.wait_event(["HS20-T-C-FILTERING-ADD"], timeout
=0.1)
6310 raise Exception("Terms and Conditions filtering enabled unexpectedly")
6313 ev
= dev
[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout
=0.1)
6315 raise Exception("Unexpected Terms and Conditions Acceptance notification (2)")
6316 dev
[0].dump_monitor()
6319 dev
[0].request("SET pmf 0")
6321 def test_ap_hs20_release_number_1(dev
, apdev
):
6322 """Hotspot 2.0 with AP claiming support for Release 1"""
6323 run_ap_hs20_release_number(dev
, apdev
, 1)
6325 def test_ap_hs20_release_number_2(dev
, apdev
):
6326 """Hotspot 2.0 with AP claiming support for Release 2"""
6327 run_ap_hs20_release_number(dev
, apdev
, 2)
6329 def test_ap_hs20_release_number_3(dev
, apdev
):
6330 """Hotspot 2.0 with AP claiming support for Release 3"""
6331 run_ap_hs20_release_number(dev
, apdev
, 3)
6333 def run_ap_hs20_release_number(dev
, apdev
, release
):
6334 check_eap_capa(dev
[0], "MSCHAPV2")
6335 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user",
6337 rel
= dev
[0].get_status_field('hs20')
6338 if rel
!= str(release
):
6339 raise Exception("Unexpected release number indicated: " + rel
)
6341 def test_ap_hs20_missing_pmf(dev
, apdev
):
6342 """Hotspot 2.0 connection attempt without PMF"""
6343 check_eap_capa(dev
[0], "MSCHAPV2")
6344 bssid
= apdev
[0]['bssid']
6345 params
= hs20_ap_params()
6346 params
['hessid'] = bssid
6347 params
['disable_dgaf'] = '1'
6348 hostapd
.add_ap(apdev
[0], params
)
6350 dev
[0].hs20_enable()
6351 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
6353 identity
="hs20-test", password
="password",
6354 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
6355 scan_freq
="2412", update_identifier
="54321",
6356 roaming_consortium_selection
="1020304050",
6358 ev
= dev
[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout
=10)
6359 dev
[0].request("DISCONNECT")
6361 raise Exception("Association rejection not reported")
6362 if "status_code=31" not in ev
:
6363 raise Exception("Unexpected rejection reason: " + ev
)