]>
git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_hs20.py
2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
12 logger
= logging
.getLogger()
19 from wlantest
import Wlantest
20 from wpasupplicant
import WpaSupplicant
22 def hs20_ap_params(ssid
="test-hs20"):
23 params
= hostapd
.wpa2_params(ssid
=ssid
)
24 params
['wpa_key_mgmt'] = "WPA-EAP"
25 params
['ieee80211w'] = "1"
26 params
['ieee8021x'] = "1"
27 params
['auth_server_addr'] = "127.0.0.1"
28 params
['auth_server_port'] = "1812"
29 params
['auth_server_shared_secret'] = "radius"
30 params
['interworking'] = "1"
31 params
['access_network_type'] = "14"
32 params
['internet'] = "1"
36 params
['venue_group'] = "7"
37 params
['venue_type'] = "1"
38 params
['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
39 params
['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
41 params
['domain_name'] = "example.com,another.example.com"
42 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
43 "0,another.example.com" ]
45 params
['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
46 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
47 params
['hs20_operating_class'] = "5173"
48 params
['anqp_3gpp_cell_net'] = "244,91"
51 def check_auto_select(dev
, bssid
):
52 dev
.scan_for_bss(bssid
, freq
="2412")
53 dev
.request("INTERWORKING_SELECT auto freq=2412")
54 ev
= dev
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
56 raise Exception("Connection timed out")
58 raise Exception("Connected to incorrect network")
59 dev
.request("REMOVE_NETWORK all")
61 def interworking_select(dev
, bssid
, type=None, no_match
=False, freq
=None):
63 if bssid
and freq
and not no_match
:
64 dev
.scan_for_bss(bssid
, freq
=freq
)
65 freq_extra
= " freq=" + freq
if freq
else ""
66 dev
.request("INTERWORKING_SELECT" + freq_extra
)
67 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
70 raise Exception("Network selection timed out");
72 if "INTERWORKING-NO-MATCH" not in ev
:
73 raise Exception("Unexpected network match")
75 if "INTERWORKING-NO-MATCH" in ev
:
76 logger
.info("Matching network not found - try again")
78 dev
.request("INTERWORKING_SELECT" + freq_extra
)
79 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
82 raise Exception("Network selection timed out");
83 if "INTERWORKING-NO-MATCH" in ev
:
84 raise Exception("Matching network not found")
85 if bssid
and bssid
not in ev
:
86 raise Exception("Unexpected BSSID in match")
87 if type and "type=" + type not in ev
:
88 raise Exception("Network type not recognized correctly")
90 def check_sp_type(dev
, sp_type
):
91 type = dev
.get_status_field("sp_type")
93 raise Exception("sp_type not available")
95 raise Exception("sp_type did not indicate home network")
97 def hlr_auc_gw_available():
98 if not os
.path
.exists("/tmp/hlr_auc_gw.sock"):
99 logger
.info("No hlr_auc_gw available");
101 if not os
.path
.exists("../../hostapd/hlr_auc_gw"):
102 logger
.info("No hlr_auc_gw available");
106 def interworking_ext_sim_connect(dev
, bssid
, method
):
107 dev
.request("INTERWORKING_CONNECT " + bssid
)
108 interworking_ext_sim_auth(dev
, method
)
110 def interworking_ext_sim_auth(dev
, method
):
111 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
113 raise Exception("Network connected timed out")
114 if "(" + method
+ ")" not in ev
:
115 raise Exception("Unexpected EAP method selection")
117 ev
= dev
.wait_event(["CTRL-REQ-SIM"], timeout
=15)
119 raise Exception("Wait for external SIM processing request timed out")
121 if p
[1] != "GSM-AUTH":
122 raise Exception("Unexpected CTRL-REQ-SIM type")
123 id = p
[0].split('-')[3]
124 rand
= p
[2].split(' ')[0]
126 res
= subprocess
.check_output(["../../hostapd/hlr_auc_gw",
128 "auth_serv/hlr_auc_gw.milenage_db",
129 "GSM-AUTH-REQ 232010000000000 " + rand
])
130 if "GSM-AUTH-RESP" not in res
:
131 raise Exception("Unexpected hlr_auc_gw response")
132 resp
= res
.split(' ')[2].rstrip()
134 dev
.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp
)
135 ev
= dev
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
137 raise Exception("Connection timed out")
139 def interworking_connect(dev
, bssid
, method
):
140 dev
.request("INTERWORKING_CONNECT " + bssid
)
141 interworking_auth(dev
, method
)
143 def interworking_auth(dev
, method
):
144 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
146 raise Exception("Network connected timed out")
147 if "(" + method
+ ")" not in ev
:
148 raise Exception("Unexpected EAP method selection")
150 ev
= dev
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
152 raise Exception("Connection timed out")
154 def check_probe_resp(wt
, bssid_unexpected
, bssid_expected
):
156 count
= wt
.get_bss_counter("probe_response", bssid_unexpected
)
158 raise Exception("Unexpected Probe Response frame from AP")
161 count
= wt
.get_bss_counter("probe_response", bssid_expected
)
163 raise Exception("No Probe Response frame from AP")
165 def test_ap_anqp_sharing(dev
, apdev
):
166 """ANQP sharing within ESS and explicit unshare"""
167 bssid
= apdev
[0]['bssid']
168 params
= hs20_ap_params()
169 params
['hessid'] = bssid
170 hostapd
.add_ap(apdev
[0]['ifname'], params
)
172 bssid2
= apdev
[1]['bssid']
173 params
= hs20_ap_params()
174 params
['hessid'] = bssid
175 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
176 hostapd
.add_ap(apdev
[1]['ifname'], params
)
179 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
180 'password': "secret",
181 'domain': "example.com" })
182 logger
.info("Normal network selection with shared ANQP results")
183 dev
[0].scan_for_bss(bssid
, freq
="2412")
184 dev
[0].scan_for_bss(bssid2
, freq
="2412")
185 interworking_select(dev
[0], None, "home", freq
="2412")
186 dev
[0].dump_monitor()
188 res1
= dev
[0].get_bss(bssid
)
189 res2
= dev
[0].get_bss(bssid2
)
190 if res1
['anqp_nai_realm'] != res2
['anqp_nai_realm']:
191 raise Exception("ANQP results were not shared between BSSes")
193 logger
.info("Explicit ANQP request to unshare ANQP results")
194 dev
[0].request("ANQP_GET " + bssid
+ " 263")
195 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
197 raise Exception("ANQP operation timed out")
199 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
200 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
202 raise Exception("ANQP operation timed out")
204 res1
= dev
[0].get_bss(bssid
)
205 res2
= dev
[0].get_bss(bssid2
)
206 if res1
['anqp_nai_realm'] == res2
['anqp_nai_realm']:
207 raise Exception("ANQP results were not unshared")
209 def test_ap_nai_home_realm_query(dev
, apdev
):
210 """NAI Home Realm Query"""
211 bssid
= apdev
[0]['bssid']
212 params
= hs20_ap_params()
213 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
214 "0,another.example.org" ]
215 hostapd
.add_ap(apdev
[0]['ifname'], params
)
217 dev
[0].scan(freq
="2412")
218 dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " realm=example.com")
219 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
221 raise Exception("ANQP operation timed out")
222 nai1
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
223 dev
[0].dump_monitor()
225 dev
[0].request("ANQP_GET " + bssid
+ " 263")
226 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
228 raise Exception("ANQP operation timed out")
229 nai2
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
231 if len(nai1
) >= len(nai2
):
232 raise Exception("Unexpected NAI Realm list response lengths")
233 if "example.com".encode('hex') not in nai1
:
234 raise Exception("Home realm not reported")
235 if "example.org".encode('hex') in nai1
:
236 raise Exception("Non-home realm reported")
237 if "example.com".encode('hex') not in nai2
:
238 raise Exception("Home realm not reported in wildcard query")
239 if "example.org".encode('hex') not in nai2
:
240 raise Exception("Non-home realm not reported in wildcard query ")
242 def test_ap_interworking_scan_filtering(dev
, apdev
):
243 """Interworking scan filtering with HESSID and access network type"""
244 bssid
= apdev
[0]['bssid']
245 params
= hs20_ap_params()
246 ssid
= "test-hs20-ap1"
247 params
['ssid'] = ssid
248 params
['hessid'] = bssid
249 hostapd
.add_ap(apdev
[0]['ifname'], params
)
251 bssid2
= apdev
[1]['bssid']
252 params
= hs20_ap_params()
253 ssid2
= "test-hs20-ap2"
254 params
['ssid'] = ssid2
255 params
['hessid'] = bssid2
256 params
['access_network_type'] = "1"
257 del params
['venue_group']
258 del params
['venue_type']
259 hostapd
.add_ap(apdev
[1]['ifname'], params
)
266 logger
.info("Check probe request filtering based on HESSID")
268 dev
[0].request("SET hessid " + bssid2
)
269 dev
[0].scan(freq
="2412")
271 check_probe_resp(wt
, bssid
, bssid2
)
273 logger
.info("Check probe request filtering based on access network type")
275 wt
.clear_bss_counters(bssid
)
276 wt
.clear_bss_counters(bssid2
)
277 dev
[0].request("SET hessid 00:00:00:00:00:00")
278 dev
[0].request("SET access_network_type 14")
279 dev
[0].scan(freq
="2412")
281 check_probe_resp(wt
, bssid2
, bssid
)
283 wt
.clear_bss_counters(bssid
)
284 wt
.clear_bss_counters(bssid2
)
285 dev
[0].request("SET hessid 00:00:00:00:00:00")
286 dev
[0].request("SET access_network_type 1")
287 dev
[0].scan(freq
="2412")
289 check_probe_resp(wt
, bssid
, bssid2
)
291 logger
.info("Check probe request filtering based on HESSID and ANT")
293 wt
.clear_bss_counters(bssid
)
294 wt
.clear_bss_counters(bssid2
)
295 dev
[0].request("SET hessid " + bssid
)
296 dev
[0].request("SET access_network_type 14")
297 dev
[0].scan(freq
="2412")
299 check_probe_resp(wt
, bssid2
, bssid
)
301 wt
.clear_bss_counters(bssid
)
302 wt
.clear_bss_counters(bssid2
)
303 dev
[0].request("SET hessid " + bssid2
)
304 dev
[0].request("SET access_network_type 14")
305 dev
[0].scan(freq
="2412")
307 check_probe_resp(wt
, bssid
, None)
308 check_probe_resp(wt
, bssid2
, None)
310 wt
.clear_bss_counters(bssid
)
311 wt
.clear_bss_counters(bssid2
)
312 dev
[0].request("SET hessid " + bssid
)
313 dev
[0].request("SET access_network_type 1")
314 dev
[0].scan(freq
="2412")
316 check_probe_resp(wt
, bssid
, None)
317 check_probe_resp(wt
, bssid2
, None)
319 def test_ap_hs20_select(dev
, apdev
):
320 """Hotspot 2.0 network selection"""
321 bssid
= apdev
[0]['bssid']
322 params
= hs20_ap_params()
323 params
['hessid'] = bssid
324 hostapd
.add_ap(apdev
[0]['ifname'], params
)
327 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
328 'password': "secret",
329 'domain': "example.com" })
330 interworking_select(dev
[0], bssid
, "home")
332 dev
[0].remove_cred(id)
333 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
334 'password': "secret",
335 'domain': "no.match.example.com" })
336 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
338 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com");
339 interworking_select(dev
[0], bssid
, no_match
=True, freq
="2412")
341 bssid2
= apdev
[1]['bssid']
342 params
= hs20_ap_params()
343 params
['nai_realm'] = [ "0,example.org,21" ]
344 params
['hessid'] = bssid2
345 params
['domain_name'] = "example.org"
346 hostapd
.add_ap(apdev
[1]['ifname'], params
)
347 dev
[0].remove_cred(id)
348 id = dev
[0].add_cred_values({ 'realm': "example.org", 'username': "test",
349 'password': "secret",
350 'domain': "example.org" })
351 interworking_select(dev
[0], bssid2
, "home", freq
="2412")
353 def hs20_simulated_sim(dev
, ap
, method
):
355 params
= hs20_ap_params()
356 params
['hessid'] = bssid
357 params
['anqp_3gpp_cell_net'] = "555,444"
358 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
359 hostapd
.add_ap(ap
['ifname'], params
)
362 dev
.add_cred_values({ 'imsi': "555444-333222111", 'eap': method
,
363 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
364 interworking_select(dev
, "home", freq
="2412")
365 interworking_connect(dev
, bssid
, method
)
366 check_sp_type(dev
, "home")
368 def test_ap_hs20_sim(dev
, apdev
):
369 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
370 if not hlr_auc_gw_available():
372 hs20_simulated_sim(dev
[0], apdev
[0], "SIM")
373 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
374 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
376 raise Exception("Timeout on already-connected event")
378 def test_ap_hs20_aka(dev
, apdev
):
379 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
380 if not hlr_auc_gw_available():
382 hs20_simulated_sim(dev
[0], apdev
[0], "AKA")
384 def test_ap_hs20_aka_prime(dev
, apdev
):
385 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
386 if not hlr_auc_gw_available():
388 hs20_simulated_sim(dev
[0], apdev
[0], "AKA'")
390 def test_ap_hs20_ext_sim(dev
, apdev
):
391 """Hotspot 2.0 with external SIM processing"""
392 if not hlr_auc_gw_available():
394 bssid
= apdev
[0]['bssid']
395 params
= hs20_ap_params()
396 params
['hessid'] = bssid
397 params
['anqp_3gpp_cell_net'] = "232,01"
398 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
399 hostapd
.add_ap(apdev
[0]['ifname'], params
)
402 dev
[0].request("SET external_sim 1")
403 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
404 interworking_select(dev
[0], "home", freq
="2412")
405 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
406 check_sp_type(dev
[0], "home")
408 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
409 """Hotspot 2.0 with external SIM processing in roaming network"""
410 if not hlr_auc_gw_available():
412 bssid
= apdev
[0]['bssid']
413 params
= hs20_ap_params()
414 params
['hessid'] = bssid
415 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
416 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
417 hostapd
.add_ap(apdev
[0]['ifname'], params
)
420 dev
[0].request("SET external_sim 1")
421 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
422 interworking_select(dev
[0], "roaming", freq
="2412")
423 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
424 check_sp_type(dev
[0], "roaming")
426 def test_ap_hs20_username(dev
, apdev
):
427 """Hotspot 2.0 connection in username/password credential"""
428 bssid
= apdev
[0]['bssid']
429 params
= hs20_ap_params()
430 params
['hessid'] = bssid
431 params
['disable_dgaf'] = '1'
432 hostapd
.add_ap(apdev
[0]['ifname'], params
)
435 id = dev
[0].add_cred_values({ 'realm': "example.com",
436 'username': "hs20-test",
437 'password': "password",
438 'ca_cert': "auth_serv/ca.pem",
439 'domain': "example.com",
440 'update_identifier': "1234" })
441 interworking_select(dev
[0], bssid
, "home", freq
="2412")
442 interworking_connect(dev
[0], bssid
, "TTLS")
443 check_sp_type(dev
[0], "home")
444 status
= dev
[0].get_status()
445 if status
['pairwise_cipher'] != "CCMP":
446 raise Exception("Unexpected pairwise cipher")
447 if status
['hs20'] != "2":
448 raise Exception("Unexpected HS 2.0 support indication")
450 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
451 identity
="hs20-test", password
="password",
452 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
455 def test_ap_hs20_connect_api(dev
, apdev
):
456 """Hotspot 2.0 connection with connect API"""
457 bssid
= apdev
[0]['bssid']
458 params
= hs20_ap_params()
459 params
['hessid'] = bssid
460 params
['disable_dgaf'] = '1'
461 hostapd
.add_ap(apdev
[0]['ifname'], params
)
463 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
464 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
466 id = wpas
.add_cred_values({ 'realm': "example.com",
467 'username': "hs20-test",
468 'password': "password",
469 'ca_cert': "auth_serv/ca.pem",
470 'domain': "example.com",
471 'update_identifier': "1234" })
472 interworking_select(wpas
, bssid
, "home", freq
="2412")
473 interworking_connect(wpas
, bssid
, "TTLS")
474 check_sp_type(wpas
, "home")
475 status
= wpas
.get_status()
476 if status
['pairwise_cipher'] != "CCMP":
477 raise Exception("Unexpected pairwise cipher")
478 if status
['hs20'] != "2":
479 raise Exception("Unexpected HS 2.0 support indication")
481 def test_ap_hs20_auto_interworking(dev
, apdev
):
482 """Hotspot 2.0 connection with auto_interworking=1"""
483 bssid
= apdev
[0]['bssid']
484 params
= hs20_ap_params()
485 params
['hessid'] = bssid
486 params
['disable_dgaf'] = '1'
487 hostapd
.add_ap(apdev
[0]['ifname'], params
)
489 dev
[0].hs20_enable(auto_interworking
=True)
490 id = dev
[0].add_cred_values({ 'realm': "example.com",
491 'username': "hs20-test",
492 'password': "password",
493 'ca_cert': "auth_serv/ca.pem",
494 'domain': "example.com",
495 'update_identifier': "1234" })
496 dev
[0].request("REASSOCIATE")
497 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
499 raise Exception("Connection timed out")
500 check_sp_type(dev
[0], "home")
501 status
= dev
[0].get_status()
502 if status
['pairwise_cipher'] != "CCMP":
503 raise Exception("Unexpected pairwise cipher")
504 if status
['hs20'] != "2":
505 raise Exception("Unexpected HS 2.0 support indication")
507 def test_ap_hs20_auto_interworking_no_cred_match(dev
, apdev
):
508 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
509 bssid
= apdev
[0]['bssid']
510 params
= { "ssid": "test" }
511 hostapd
.add_ap(apdev
[0]['ifname'], params
)
513 dev
[0].hs20_enable(auto_interworking
=True)
514 dev
[0].add_cred_values({ 'realm': "example.com",
515 'username': "hs20-test",
516 'password': "password",
517 'ca_cert': "auth_serv/ca.pem",
518 'domain': "example.com" })
520 id = dev
[0].connect("test", psk
="12345678", only_add_network
=True)
521 dev
[0].request("ENABLE_NETWORK %s" % id)
522 logger
.info("Verify that scanning continues when there is partial network block match")
523 for i
in range(0, 2):
524 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
526 raise Exception("Scan timed out")
527 logger
.info("Scan completed")
529 def eap_test(dev
, ap
, eap_params
, method
, user
):
531 params
= hs20_ap_params()
532 params
['nai_realm'] = [ "0,example.com," + eap_params
]
533 hostapd
.add_ap(ap
['ifname'], params
)
536 dev
.add_cred_values({ 'realm': "example.com",
538 'password': "password" })
539 interworking_select(dev
, bssid
, freq
="2412")
540 interworking_connect(dev
, bssid
, method
)
542 def test_ap_hs20_eap_unknown(dev
, apdev
):
543 """Hotspot 2.0 connection with unknown EAP method"""
544 bssid
= apdev
[0]['bssid']
545 params
= hs20_ap_params()
546 params
['nai_realm'] = "0,example.com,99"
547 hostapd
.add_ap(apdev
[0]['ifname'], params
)
550 dev
[0].add_cred_values(default_cred())
551 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
553 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
554 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
555 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
557 def test_ap_hs20_eap_peap_default(dev
, apdev
):
558 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
559 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
561 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
562 """Hotspot 2.0 connection with PEAP/GTC"""
563 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
565 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
566 """Hotspot 2.0 connection with PEAP/unknown"""
567 bssid
= apdev
[0]['bssid']
568 params
= hs20_ap_params()
569 params
['nai_realm'] = "0,example.com,25[3:99]"
570 hostapd
.add_ap(apdev
[0]['ifname'], params
)
573 dev
[0].add_cred_values(default_cred())
574 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
576 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
577 """Hotspot 2.0 connection with TTLS/CHAP"""
578 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
580 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
581 """Hotspot 2.0 connection with TTLS/MSCHAP"""
582 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
584 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
585 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
586 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
588 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
589 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
590 bssid
= apdev
[0]['bssid']
591 params
= hs20_ap_params()
592 params
['nai_realm'] = "0,example.com,21[3:99]"
593 hostapd
.add_ap(apdev
[0]['ifname'], params
)
596 dev
[0].add_cred_values(default_cred())
597 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
599 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
600 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
601 bssid
= apdev
[0]['bssid']
602 params
= hs20_ap_params()
603 params
['nai_realm'] = "0,example.com,21[3:5]"
604 hostapd
.add_ap(apdev
[0]['ifname'], params
)
607 dev
[0].add_cred_values(default_cred())
608 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
610 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
611 """Hotspot 2.0 connection with TTLS/unknown"""
612 bssid
= apdev
[0]['bssid']
613 params
= hs20_ap_params()
614 params
['nai_realm'] = "0,example.com,21[2:5]"
615 hostapd
.add_ap(apdev
[0]['ifname'], params
)
618 dev
[0].add_cred_values(default_cred())
619 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
621 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
622 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
623 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
625 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
626 """Hotspot 2.0 connection with FAST/EAP-GTC"""
627 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
629 def test_ap_hs20_eap_tls(dev
, apdev
):
630 """Hotspot 2.0 connection with EAP-TLS"""
631 bssid
= apdev
[0]['bssid']
632 params
= hs20_ap_params()
633 params
['nai_realm'] = [ "0,example.com,13[5:6]" ]
634 hostapd
.add_ap(apdev
[0]['ifname'], params
)
637 dev
[0].add_cred_values({ 'realm': "example.com",
638 'username': "certificate-user",
639 'ca_cert': "auth_serv/ca.pem",
640 'client_cert': "auth_serv/user.pem",
641 'private_key': "auth_serv/user.key"})
642 interworking_select(dev
[0], bssid
, freq
="2412")
643 interworking_connect(dev
[0], bssid
, "TLS")
645 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
646 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
647 bssid
= apdev
[0]['bssid']
648 params
= hs20_ap_params()
649 params
['nai_realm'] = [ "0,example.com,99[5:6]" ]
650 hostapd
.add_ap(apdev
[0]['ifname'], params
)
653 dev
[0].add_cred_values({ 'realm': "example.com",
654 'username': "certificate-user",
655 'ca_cert': "auth_serv/ca.pem",
656 'client_cert': "auth_serv/user.pem",
657 'private_key': "auth_serv/user.key"})
658 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
660 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
661 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
662 bssid
= apdev
[0]['bssid']
663 params
= hs20_ap_params()
664 params
['nai_realm'] = [ "0,example.com,21[5:6]" ]
665 hostapd
.add_ap(apdev
[0]['ifname'], params
)
668 dev
[0].add_cred_values({ 'realm': "example.com",
669 'username': "certificate-user",
670 'ca_cert': "auth_serv/ca.pem",
671 'client_cert': "auth_serv/user.pem",
672 'private_key': "auth_serv/user.key"})
673 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
675 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
676 """Hotspot 2.0 connection with invalid cred configuration"""
677 bssid
= apdev
[0]['bssid']
678 params
= hs20_ap_params()
679 hostapd
.add_ap(apdev
[0]['ifname'], params
)
682 dev
[0].add_cred_values({ 'realm': "example.com",
683 'username': "certificate-user",
684 'client_cert': "auth_serv/user.pem" })
685 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
687 def test_ap_hs20_nai_realms(dev
, apdev
):
688 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
689 bssid
= apdev
[0]['bssid']
690 params
= hs20_ap_params()
691 params
['hessid'] = bssid
692 params
['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
693 hostapd
.add_ap(apdev
[0]['ifname'], params
)
696 id = dev
[0].add_cred_values({ 'realm': "example.com",
697 'username': "pap user",
698 'password': "password",
699 'domain': "example.com" })
700 interworking_select(dev
[0], bssid
, "home", freq
="2412")
701 interworking_connect(dev
[0], bssid
, "TTLS")
702 check_sp_type(dev
[0], "home")
704 def test_ap_hs20_roaming_consortium(dev
, apdev
):
705 """Hotspot 2.0 connection based on roaming consortium match"""
706 bssid
= apdev
[0]['bssid']
707 params
= hs20_ap_params()
708 params
['hessid'] = bssid
709 hostapd
.add_ap(apdev
[0]['ifname'], params
)
712 for consortium
in [ "112233", "1020304050", "010203040506", "fedcba" ]:
713 id = dev
[0].add_cred_values({ 'username': "user",
714 'password': "password",
715 'domain': "example.com",
716 'roaming_consortium': consortium
,
718 interworking_select(dev
[0], bssid
, "home", freq
="2412")
719 interworking_connect(dev
[0], bssid
, "PEAP")
720 check_sp_type(dev
[0], "home")
721 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
722 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
724 raise Exception("Timeout on already-connected event")
725 dev
[0].remove_cred(id)
727 def test_ap_hs20_username_roaming(dev
, apdev
):
728 """Hotspot 2.0 connection in username/password credential (roaming)"""
729 bssid
= apdev
[0]['bssid']
730 params
= hs20_ap_params()
731 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
732 "0,roaming.example.com,21[2:4][5:7]",
733 "0,another.example.com" ]
734 params
['domain_name'] = "another.example.com"
735 params
['hessid'] = bssid
736 hostapd
.add_ap(apdev
[0]['ifname'], params
)
739 id = dev
[0].add_cred_values({ 'realm': "roaming.example.com",
740 'username': "hs20-test",
741 'password': "password",
742 'domain': "example.com" })
743 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
744 interworking_connect(dev
[0], bssid
, "TTLS")
745 check_sp_type(dev
[0], "roaming")
747 def test_ap_hs20_username_unknown(dev
, apdev
):
748 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
749 bssid
= apdev
[0]['bssid']
750 params
= hs20_ap_params()
751 params
['hessid'] = bssid
752 hostapd
.add_ap(apdev
[0]['ifname'], params
)
755 id = dev
[0].add_cred_values({ 'realm': "example.com",
756 'username': "hs20-test",
757 'password': "password" })
758 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
759 interworking_connect(dev
[0], bssid
, "TTLS")
760 check_sp_type(dev
[0], "unknown")
762 def test_ap_hs20_username_unknown2(dev
, apdev
):
763 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
764 bssid
= apdev
[0]['bssid']
765 params
= hs20_ap_params()
766 params
['hessid'] = bssid
767 del params
['domain_name']
768 hostapd
.add_ap(apdev
[0]['ifname'], params
)
771 id = dev
[0].add_cred_values({ 'realm': "example.com",
772 'username': "hs20-test",
773 'password': "password",
774 'domain': "example.com" })
775 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
776 interworking_connect(dev
[0], bssid
, "TTLS")
777 check_sp_type(dev
[0], "unknown")
779 def test_ap_hs20_gas_while_associated(dev
, apdev
):
780 """Hotspot 2.0 connection with GAS query while associated"""
781 bssid
= apdev
[0]['bssid']
782 params
= hs20_ap_params()
783 params
['hessid'] = bssid
784 hostapd
.add_ap(apdev
[0]['ifname'], params
)
787 id = dev
[0].add_cred_values({ 'realm': "example.com",
788 'username': "hs20-test",
789 'password': "password",
790 'domain': "example.com" })
791 interworking_select(dev
[0], bssid
, "home", freq
="2412")
792 interworking_connect(dev
[0], bssid
, "TTLS")
794 logger
.info("Verifying GAS query while associated")
795 dev
[0].request("FETCH_ANQP")
796 for i
in range(0, 6):
797 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
799 raise Exception("Operation timed out")
801 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
802 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
803 bssid
= apdev
[0]['bssid']
804 params
= hs20_ap_params()
805 params
['hessid'] = bssid
806 hostapd
.add_ap(apdev
[0]['ifname'], params
)
808 bssid2
= apdev
[1]['bssid']
809 params
= hs20_ap_params()
810 params
['hessid'] = bssid2
811 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
812 hostapd
.add_ap(apdev
[1]['ifname'], params
)
815 dev
[0].request("SET pmf 2")
816 id = dev
[0].add_cred_values({ 'realm': "example.com",
817 'username': "hs20-test",
818 'password': "password",
819 'domain': "example.com" })
820 interworking_select(dev
[0], bssid
, "home", freq
="2412")
821 interworking_connect(dev
[0], bssid
, "TTLS")
823 logger
.info("Verifying GAS query while associated")
824 dev
[0].request("FETCH_ANQP")
825 for i
in range(0, 2 * 6):
826 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
828 raise Exception("Operation timed out")
830 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
831 """Hotspot 2.0 connection with fragmented GAS query while associated"""
832 bssid
= apdev
[0]['bssid']
833 params
= hs20_ap_params()
834 params
['hessid'] = bssid
835 hostapd
.add_ap(apdev
[0]['ifname'], params
)
836 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
837 hapd
.set("gas_frag_limit", "50")
840 id = dev
[0].add_cred_values({ 'realm': "example.com",
841 'username': "hs20-test",
842 'password': "password",
843 'domain': "example.com" })
844 interworking_select(dev
[0], bssid
, "home", freq
="2412")
845 interworking_connect(dev
[0], bssid
, "TTLS")
847 logger
.info("Verifying GAS query while associated")
848 dev
[0].request("FETCH_ANQP")
849 for i
in range(0, 6):
850 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
852 raise Exception("Operation timed out")
854 def test_ap_hs20_multiple_connects(dev
, apdev
):
855 """Hotspot 2.0 connection through multiple network selections"""
856 bssid
= apdev
[0]['bssid']
857 params
= hs20_ap_params()
858 params
['hessid'] = bssid
859 hostapd
.add_ap(apdev
[0]['ifname'], params
)
862 values
= { 'realm': "example.com",
863 'username': "hs20-test",
864 'password': "password",
865 'domain': "example.com" }
866 id = dev
[0].add_cred_values(values
)
868 dev
[0].scan_for_bss(bssid
, freq
="2412")
870 for i
in range(0, 3):
871 logger
.info("Starting Interworking network selection")
872 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
874 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
875 "INTERWORKING-ALREADY-CONNECTED",
876 "CTRL-EVENT-CONNECTED"], timeout
=15)
878 raise Exception("Connection timed out")
879 if "INTERWORKING-NO-MATCH" in ev
:
880 raise Exception("Matching AP not found")
881 if "CTRL-EVENT-CONNECTED" in ev
:
883 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
886 dev
[0].request("DISCONNECT")
887 dev
[0].dump_monitor()
889 networks
= dev
[0].list_networks()
890 if len(networks
) > 1:
891 raise Exception("Duplicated network block detected")
893 def test_ap_hs20_disallow_aps(dev
, apdev
):
894 """Hotspot 2.0 connection and disallow_aps"""
895 bssid
= apdev
[0]['bssid']
896 params
= hs20_ap_params()
897 params
['hessid'] = bssid
898 hostapd
.add_ap(apdev
[0]['ifname'], params
)
901 values
= { 'realm': "example.com",
902 'username': "hs20-test",
903 'password': "password",
904 'domain': "example.com" }
905 id = dev
[0].add_cred_values(values
)
907 dev
[0].scan_for_bss(bssid
, freq
="2412")
909 logger
.info("Verify disallow_aps bssid")
910 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
911 dev
[0].request("INTERWORKING_SELECT auto")
912 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
914 raise Exception("Network selection timed out")
915 dev
[0].dump_monitor()
917 logger
.info("Verify disallow_aps ssid")
918 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
919 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
920 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
922 raise Exception("Network selection timed out")
923 dev
[0].dump_monitor()
925 logger
.info("Verify disallow_aps clear")
926 dev
[0].request("SET disallow_aps ")
927 interworking_select(dev
[0], bssid
, "home", freq
="2412")
929 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
930 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
931 if "FAIL" not in ret
:
932 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
934 def policy_test(dev
, ap
, values
, only_one
=True):
937 logger
.info("Verify network selection to AP " + ap
['ifname'])
939 dev
.scan_for_bss(bssid
, freq
="2412")
941 logger
.info("Verify network selection")
944 id = dev
.add_cred_values(values
)
945 dev
.request("INTERWORKING_SELECT auto freq=2412")
948 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
949 "INTERWORKING-BLACKLISTED",
950 "INTERWORKING-SELECTED"], timeout
=15)
952 raise Exception("Network selection timed out")
954 if "INTERWORKING-NO-MATCH" in ev
:
955 raise Exception("Matching AP not found")
956 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
957 raise Exception("Unexpected AP claimed acceptable")
958 if "INTERWORKING-SELECTED" in ev
:
959 if bssid
and bssid
not in ev
:
960 raise Exception("Selected incorrect BSS")
963 ev
= dev
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
965 raise Exception("Connection timed out")
966 if bssid
and bssid
not in ev
:
967 raise Exception("Connected to incorrect BSS")
969 conn_bssid
= dev
.get_status_field("bssid")
970 if bssid
and conn_bssid
!= bssid
:
971 raise Exception("bssid information points to incorrect BSS")
977 def default_cred(domain
=None):
978 cred
= { 'realm': "example.com",
979 'username': "hs20-test",
980 'password': "password" }
982 cred
['domain'] = domain
985 def test_ap_hs20_prefer_home(dev
, apdev
):
986 """Hotspot 2.0 required roaming consortium"""
987 params
= hs20_ap_params()
988 params
['domain_name'] = "example.org"
989 hostapd
.add_ap(apdev
[0]['ifname'], params
)
991 params
= hs20_ap_params()
992 params
['ssid'] = "test-hs20-other"
993 params
['domain_name'] = "example.com"
994 hostapd
.add_ap(apdev
[1]['ifname'], params
)
996 values
= default_cred()
997 values
['domain'] = "example.com"
998 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
999 values
['domain'] = "example.org"
1000 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1002 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1003 """Hotspot 2.0 required roaming consortium"""
1004 params
= hs20_ap_params()
1005 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1007 params
= hs20_ap_params()
1008 params
['ssid'] = "test-hs20-other"
1009 params
['roaming_consortium'] = [ "223344" ]
1010 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1012 values
= default_cred()
1013 values
['required_roaming_consortium'] = "223344"
1014 policy_test(dev
[0], apdev
[1], values
)
1015 values
['required_roaming_consortium'] = "112233"
1016 policy_test(dev
[0], apdev
[0], values
)
1018 id = dev
[0].add_cred()
1019 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1020 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1022 for val
in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1023 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1024 raise Exception("Invalid roaming consortium value accepted: " + val
)
1026 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1027 """Hotspot 2.0 exclusion based on SSID"""
1028 params
= hs20_ap_params()
1029 params
['roaming_consortium'] = [ "223344" ]
1030 params
['anqp_3gpp_cell_net'] = "555,444"
1031 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1033 params
= hs20_ap_params()
1034 params
['ssid'] = "test-hs20-other"
1035 params
['roaming_consortium'] = [ "223344" ]
1036 params
['anqp_3gpp_cell_net'] = "555,444"
1037 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1039 values
= default_cred()
1040 values
['excluded_ssid'] = "test-hs20"
1041 events
= policy_test(dev
[0], apdev
[1], values
)
1042 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1044 raise Exception("Excluded network not reported")
1045 values
['excluded_ssid'] = "test-hs20-other"
1046 events
= policy_test(dev
[0], apdev
[0], values
)
1047 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1049 raise Exception("Excluded network not reported")
1051 values
= default_cred()
1052 values
['roaming_consortium'] = "223344"
1053 values
['eap'] = "TTLS"
1054 values
['phase2'] = "auth=MSCHAPV2"
1055 values
['excluded_ssid'] = "test-hs20"
1056 events
= policy_test(dev
[0], apdev
[1], values
)
1057 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1059 raise Exception("Excluded network not reported")
1061 values
= { 'imsi': "555444-333222111", 'eap': "SIM",
1062 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1063 'excluded_ssid': "test-hs20" }
1064 events
= policy_test(dev
[0], apdev
[1], values
)
1065 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1067 raise Exception("Excluded network not reported")
1069 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1070 """Hotspot 2.0 and roaming from current to higher priority network"""
1071 bssid
= apdev
[0]['bssid']
1072 params
= hs20_ap_params(ssid
="test-hs20-visited")
1073 params
['domain_name'] = "visited.example.org"
1074 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1076 dev
[0].hs20_enable()
1077 id = dev
[0].add_cred_values({ 'realm': "example.com",
1078 'username': "hs20-test",
1079 'password': "password",
1080 'domain': "example.com" })
1081 logger
.info("Connect to the only network option")
1082 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1083 dev
[0].dump_monitor()
1084 interworking_connect(dev
[0], bssid
, "TTLS")
1086 logger
.info("Start another AP (home operator) and reconnect")
1087 bssid2
= apdev
[1]['bssid']
1088 params
= hs20_ap_params(ssid
="test-hs20-home")
1089 params
['domain_name'] = "example.com"
1090 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1092 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1093 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1094 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1095 "INTERWORKING-ALREADY-CONNECTED",
1096 "CTRL-EVENT-CONNECTED"], timeout
=15)
1098 raise Exception("Connection timed out")
1099 if "INTERWORKING-NO-MATCH" in ev
:
1100 raise Exception("Matching AP not found")
1101 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1102 raise Exception("Unexpected AP selected")
1103 if bssid2
not in ev
:
1104 raise Exception("Unexpected BSSID after reconnection")
1106 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1107 """Hotspot 2.0 and domain_suffix_match"""
1108 bssid
= apdev
[0]['bssid']
1109 params
= hs20_ap_params()
1110 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1112 dev
[0].hs20_enable()
1113 id = dev
[0].add_cred_values({ 'realm': "example.com",
1114 'username': "hs20-test",
1115 'password': "password",
1116 'domain': "example.com",
1117 'domain_suffix_match': "w1.fi" })
1118 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1119 dev
[0].dump_monitor()
1120 interworking_connect(dev
[0], bssid
, "TTLS")
1121 dev
[0].request("REMOVE_NETWORK all")
1122 dev
[0].dump_monitor()
1124 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1125 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1126 dev
[0].dump_monitor()
1127 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1128 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1130 raise Exception("TLS certificate error not reported")
1131 if "Domain suffix mismatch" not in ev
:
1132 raise Exception("Domain suffix mismatch not reported")
1134 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1135 """Hotspot 2.0 and roaming partner preference"""
1136 params
= hs20_ap_params()
1137 params
['domain_name'] = "roaming.example.org"
1138 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1140 params
= hs20_ap_params()
1141 params
['ssid'] = "test-hs20-other"
1142 params
['domain_name'] = "roaming.example.net"
1143 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1145 logger
.info("Verify default vs. specified preference")
1146 values
= default_cred()
1147 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1148 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1149 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1150 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1152 logger
.info("Verify partial FQDN match")
1153 values
['roaming_partner'] = "example.net,0,0,*"
1154 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1155 values
['roaming_partner'] = "example.net,0,255,*"
1156 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1158 def test_ap_hs20_max_bss_load(dev
, apdev
):
1159 """Hotspot 2.0 and maximum BSS load"""
1160 params
= hs20_ap_params()
1161 params
['bss_load_test'] = "12:200:20000"
1162 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1164 params
= hs20_ap_params()
1165 params
['ssid'] = "test-hs20-other"
1166 params
['bss_load_test'] = "5:20:10000"
1167 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1169 logger
.info("Verify maximum BSS load constraint")
1170 values
= default_cred()
1171 values
['domain'] = "example.com"
1172 values
['max_bss_load'] = "100"
1173 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1175 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1176 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1177 raise Exception("Maximum BSS Load case not noticed")
1178 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1179 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1180 raise Exception("Maximum BSS Load case reported incorrectly")
1182 logger
.info("Verify maximum BSS load does not prevent connection")
1183 values
['max_bss_load'] = "1"
1184 events
= policy_test(dev
[0], None, values
)
1186 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1187 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1188 raise Exception("Maximum BSS Load case not noticed")
1189 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1190 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1191 raise Exception("Maximum BSS Load case not noticed")
1193 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1194 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1195 params
= hs20_ap_params()
1196 params
['bss_load_test'] = "12:200:20000"
1197 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1199 params
= hs20_ap_params()
1200 params
['ssid'] = "test-hs20-other"
1201 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1203 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1204 values
= default_cred()
1205 values
['domain'] = "example.com"
1206 values
['max_bss_load'] = "100"
1207 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1209 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1210 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1211 raise Exception("Maximum BSS Load case not noticed")
1212 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1213 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1214 raise Exception("Maximum BSS Load case reported incorrectly")
1216 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1217 """Hotspot 2.0 multi-cred sp_priority"""
1218 if not hlr_auc_gw_available():
1220 bssid
= apdev
[0]['bssid']
1221 params
= hs20_ap_params()
1222 params
['hessid'] = bssid
1223 del params
['domain_name']
1224 params
['anqp_3gpp_cell_net'] = "232,01"
1225 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1227 dev
[0].hs20_enable()
1228 dev
[0].scan_for_bss(bssid
, freq
="2412")
1229 dev
[0].request("SET external_sim 1")
1230 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1231 'provisioning_sp': "example.com",
1232 'sp_priority' :"1" })
1233 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1234 'username': "hs20-test",
1235 'password': "password",
1236 'domain': "example.com",
1237 'provisioning_sp': "example.com",
1238 'sp_priority': "2" })
1239 dev
[0].dump_monitor()
1240 dev
[0].scan_for_bss(bssid
, freq
="2412")
1241 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1242 interworking_ext_sim_auth(dev
[0], "SIM")
1243 check_sp_type(dev
[0], "unknown")
1244 dev
[0].request("REMOVE_NETWORK all")
1246 dev
[0].set_cred(id1
, "sp_priority", "2")
1247 dev
[0].set_cred(id2
, "sp_priority", "1")
1248 dev
[0].dump_monitor()
1249 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1250 interworking_auth(dev
[0], "TTLS")
1251 check_sp_type(dev
[0], "unknown")
1253 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1254 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1255 if not hlr_auc_gw_available():
1257 bssid
= apdev
[0]['bssid']
1258 params
= hs20_ap_params()
1259 params
['hessid'] = bssid
1260 del params
['nai_realm']
1261 del params
['domain_name']
1262 params
['anqp_3gpp_cell_net'] = "232,01"
1263 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1265 bssid2
= apdev
[1]['bssid']
1266 params
= hs20_ap_params()
1267 params
['ssid'] = "test-hs20-other"
1268 params
['hessid'] = bssid2
1269 del params
['domain_name']
1270 del params
['anqp_3gpp_cell_net']
1271 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1273 dev
[0].hs20_enable()
1274 dev
[0].request("SET external_sim 1")
1275 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1276 'provisioning_sp': "example.com",
1277 'sp_priority': "1" })
1278 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1279 'username': "hs20-test",
1280 'password': "password",
1281 'domain': "example.com",
1282 'provisioning_sp': "example.com",
1283 'sp_priority': "2" })
1284 dev
[0].dump_monitor()
1285 dev
[0].scan_for_bss(bssid
, freq
="2412")
1286 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1287 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1288 interworking_ext_sim_auth(dev
[0], "SIM")
1289 check_sp_type(dev
[0], "unknown")
1290 conn_bssid
= dev
[0].get_status_field("bssid")
1291 if conn_bssid
!= bssid
:
1292 raise Exception("Connected to incorrect BSS")
1293 dev
[0].request("REMOVE_NETWORK all")
1295 dev
[0].set_cred(id1
, "sp_priority", "2")
1296 dev
[0].set_cred(id2
, "sp_priority", "1")
1297 dev
[0].dump_monitor()
1298 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1299 interworking_auth(dev
[0], "TTLS")
1300 check_sp_type(dev
[0], "unknown")
1301 conn_bssid
= dev
[0].get_status_field("bssid")
1302 if conn_bssid
!= bssid2
:
1303 raise Exception("Connected to incorrect BSS")
1305 def check_conn_capab_selection(dev
, type, missing
):
1306 dev
.request("INTERWORKING_SELECT freq=2412")
1307 ev
= dev
.wait_event(["INTERWORKING-AP"])
1309 raise Exception("Network selection timed out");
1310 if "type=" + type not in ev
:
1311 raise Exception("Unexpected network type")
1312 if missing
and "conn_capab_missing=1" not in ev
:
1313 raise Exception("conn_capab_missing not reported")
1314 if not missing
and "conn_capab_missing=1" in ev
:
1315 raise Exception("conn_capab_missing reported unexpectedly")
1317 def conn_capab_cred(domain
=None, req_conn_capab
=None):
1318 cred
= default_cred(domain
=domain
)
1320 cred
['req_conn_capab'] = req_conn_capab
1323 def test_ap_hs20_req_conn_capab(dev
, apdev
):
1324 """Hotspot 2.0 network selection with req_conn_capab"""
1325 bssid
= apdev
[0]['bssid']
1326 params
= hs20_ap_params()
1327 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1329 dev
[0].hs20_enable()
1330 dev
[0].scan_for_bss(bssid
, freq
="2412")
1331 logger
.info("Not used in home network")
1332 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
1333 id = dev
[0].add_cred_values(values
)
1334 check_conn_capab_selection(dev
[0], "home", False)
1336 logger
.info("Used in roaming network")
1337 dev
[0].remove_cred(id)
1338 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
1339 id = dev
[0].add_cred_values(values
)
1340 check_conn_capab_selection(dev
[0], "roaming", True)
1342 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1343 check_auto_select(dev
[0], bssid
)
1345 logger
.info("Additional req_conn_capab checks")
1347 dev
[0].remove_cred(id)
1348 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
1349 id = dev
[0].add_cred_values(values
)
1350 check_conn_capab_selection(dev
[0], "roaming", True)
1352 dev
[0].remove_cred(id)
1353 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
1354 id = dev
[0].add_cred_values(values
)
1355 check_conn_capab_selection(dev
[0], "roaming", True)
1357 bssid2
= apdev
[1]['bssid']
1358 params
= hs20_ap_params(ssid
="test-hs20b")
1359 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1360 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1362 dev
[0].remove_cred(id)
1363 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
1364 id = dev
[0].add_cred_values(values
)
1365 dev
[0].set_cred(id, "req_conn_capab", "6:22")
1366 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1367 dev
[0].request("INTERWORKING_SELECT freq=2412")
1368 for i
in range(0, 2):
1369 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
1371 raise Exception("Network selection timed out");
1372 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
1373 raise Exception("Missing protocol connection capability not reported")
1374 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
1375 raise Exception("Protocol connection capability not reported correctly")
1377 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
1378 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1379 bssid
= apdev
[0]['bssid']
1380 params
= hs20_ap_params()
1381 params
['domain_name'] = "roaming.example.org"
1382 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1383 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1385 bssid2
= apdev
[1]['bssid']
1386 params
= hs20_ap_params(ssid
="test-hs20-b")
1387 params
['domain_name'] = "roaming.example.net"
1388 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1390 values
= default_cred()
1391 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1392 id = dev
[0].add_cred_values(values
)
1393 check_auto_select(dev
[0], bssid2
)
1395 dev
[0].set_cred(id, "req_conn_capab", "50")
1396 check_auto_select(dev
[0], bssid
)
1398 dev
[0].remove_cred(id)
1399 id = dev
[0].add_cred_values(values
)
1400 dev
[0].set_cred(id, "req_conn_capab", "51")
1401 check_auto_select(dev
[0], bssid2
)
1403 def check_bandwidth_selection(dev
, type, below
):
1404 dev
.request("INTERWORKING_SELECT freq=2412")
1405 ev
= dev
.wait_event(["INTERWORKING-AP"])
1407 raise Exception("Network selection timed out");
1408 if "type=" + type not in ev
:
1409 raise Exception("Unexpected network type")
1410 if below
and "below_min_backhaul=1" not in ev
:
1411 raise Exception("below_min_backhaul not reported")
1412 if not below
and "below_min_backhaul=1" in ev
:
1413 raise Exception("below_min_backhaul reported unexpectedly")
1415 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
1416 cred
= default_cred(domain
=domain
)
1418 cred
['min_dl_bandwidth_home'] = str(dl_home
)
1420 cred
['min_ul_bandwidth_home'] = str(ul_home
)
1422 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
1424 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
1427 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
1428 """Hotspot 2.0 network selection with min bandwidth (home)"""
1429 bssid
= apdev
[0]['bssid']
1430 params
= hs20_ap_params()
1431 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1433 dev
[0].hs20_enable()
1434 dev
[0].scan_for_bss(bssid
, freq
="2412")
1435 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1436 id = dev
[0].add_cred_values(values
)
1437 check_bandwidth_selection(dev
[0], "home", False)
1438 dev
[0].remove_cred(id)
1440 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1441 id = dev
[0].add_cred_values(values
)
1442 check_bandwidth_selection(dev
[0], "home", True)
1443 dev
[0].remove_cred(id)
1445 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1446 id = dev
[0].add_cred_values(values
)
1447 check_bandwidth_selection(dev
[0], "home", True)
1448 dev
[0].remove_cred(id)
1450 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1451 id = dev
[0].add_cred_values(values
)
1452 check_bandwidth_selection(dev
[0], "home", True)
1453 check_auto_select(dev
[0], bssid
)
1455 bssid2
= apdev
[1]['bssid']
1456 params
= hs20_ap_params(ssid
="test-hs20-b")
1457 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1458 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1460 check_auto_select(dev
[0], bssid2
)
1462 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
1463 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1464 bssid
= apdev
[0]['bssid']
1465 params
= hs20_ap_params()
1466 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1468 dev
[0].hs20_enable()
1469 dev
[0].scan_for_bss(bssid
, freq
="2412")
1470 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
1471 id = dev
[0].add_cred_values(values
)
1472 check_bandwidth_selection(dev
[0], "roaming", False)
1473 dev
[0].remove_cred(id)
1475 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
1476 id = dev
[0].add_cred_values(values
)
1477 check_bandwidth_selection(dev
[0], "roaming", True)
1478 dev
[0].remove_cred(id)
1480 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
1481 id = dev
[0].add_cred_values(values
)
1482 check_bandwidth_selection(dev
[0], "roaming", True)
1483 dev
[0].remove_cred(id)
1485 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
1486 id = dev
[0].add_cred_values(values
)
1487 check_bandwidth_selection(dev
[0], "roaming", True)
1488 check_auto_select(dev
[0], bssid
)
1490 bssid2
= apdev
[1]['bssid']
1491 params
= hs20_ap_params(ssid
="test-hs20-b")
1492 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1493 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1495 check_auto_select(dev
[0], bssid2
)
1497 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
1498 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1499 bssid
= apdev
[0]['bssid']
1500 params
= hs20_ap_params()
1501 params
['domain_name'] = "roaming.example.org"
1502 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1503 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1505 bssid2
= apdev
[1]['bssid']
1506 params
= hs20_ap_params(ssid
="test-hs20-b")
1507 params
['domain_name'] = "roaming.example.net"
1508 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1510 values
= default_cred()
1511 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1512 id = dev
[0].add_cred_values(values
)
1513 check_auto_select(dev
[0], bssid2
)
1515 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1516 check_auto_select(dev
[0], bssid
)
1518 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1519 check_auto_select(dev
[0], bssid2
)
1521 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
1522 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1523 bssid
= apdev
[0]['bssid']
1524 params
= hs20_ap_params()
1525 del params
['hs20_wan_metrics']
1526 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1528 dev
[0].hs20_enable()
1529 dev
[0].scan_for_bss(bssid
, freq
="2412")
1530 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
1531 dl_roaming
=10000, ul_roaming
=10000)
1532 dev
[0].add_cred_values(values
)
1533 check_bandwidth_selection(dev
[0], "home", False)
1535 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
1536 """Hotspot 2.0 connection and deauthentication request for ESS"""
1537 dev
[0].request("SET pmf 2")
1538 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1539 dev
[0].dump_monitor()
1540 addr
= dev
[0].p2p_interface_addr()
1541 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1542 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
1543 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1545 raise Exception("Timeout on deauth imminent notice")
1546 if "1 120 http://example.com/" not in ev
:
1547 raise Exception("Unexpected deauth imminent notice: " + ev
)
1548 hapd
.request("DEAUTHENTICATE " + addr
)
1549 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1551 raise Exception("Timeout on disconnection")
1552 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1553 raise Exception("Network not marked temporarily disabled")
1554 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1555 "Trying to associate",
1556 "CTRL-EVENT-CONNECTED"], timeout
=5)
1558 raise Exception("Unexpected connection attempt")
1560 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
1561 """Hotspot 2.0 connection and deauthentication request for BSS"""
1562 dev
[0].request("SET pmf 2")
1563 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1564 dev
[0].dump_monitor()
1565 addr
= dev
[0].p2p_interface_addr()
1566 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1567 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
1568 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1570 raise Exception("Timeout on deauth imminent notice")
1571 if "0 120 http://example.com/" not in ev
:
1572 raise Exception("Unexpected deauth imminent notice: " + ev
)
1573 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
1574 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1576 raise Exception("Timeout on disconnection")
1577 if "reason=4" not in ev
:
1578 raise Exception("Unexpected disconnection reason")
1579 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1580 raise Exception("Network not marked temporarily disabled")
1581 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1582 "Trying to associate",
1583 "CTRL-EVENT-CONNECTED"], timeout
=5)
1585 raise Exception("Unexpected connection attempt")
1587 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1588 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1589 bssid
= apdev
[0]['bssid']
1590 params
= hs20_ap_params()
1591 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1592 params
['hs20_deauth_req_timeout'] = "2"
1593 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1595 dev
[0].request("SET pmf 2")
1596 dev
[0].hs20_enable()
1597 dev
[0].add_cred_values({ 'realm': "example.com",
1598 'username': "hs20-deauth-test",
1599 'password': "password" })
1600 interworking_select(dev
[0], bssid
, freq
="2412")
1601 interworking_connect(dev
[0], bssid
, "TTLS")
1602 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
1604 raise Exception("Timeout on deauth imminent notice")
1605 if " 1 100" not in ev
:
1606 raise Exception("Unexpected deauth imminent contents")
1607 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=3)
1609 raise Exception("Timeout on disconnection")
1611 def test_ap_hs20_remediation_required(dev
, apdev
):
1612 """Hotspot 2.0 connection and remediation required from RADIUS"""
1613 bssid
= apdev
[0]['bssid']
1614 params
= hs20_ap_params()
1615 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1616 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1618 dev
[0].request("SET pmf 1")
1619 dev
[0].hs20_enable()
1620 dev
[0].add_cred_values({ 'realm': "example.com",
1621 'username': "hs20-subrem-test",
1622 'password': "password" })
1623 interworking_select(dev
[0], bssid
, freq
="2412")
1624 interworking_connect(dev
[0], bssid
, "TTLS")
1625 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1627 raise Exception("Timeout on subscription remediation notice")
1628 if " 1 https://example.com/" not in ev
:
1629 raise Exception("Unexpected subscription remediation event contents")
1631 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1632 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1633 bssid
= apdev
[0]['bssid']
1634 addr
= dev
[0].p2p_dev_addr()
1635 params
= hs20_ap_params()
1636 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1637 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
1639 dev
[0].request("SET pmf 1")
1640 dev
[0].hs20_enable()
1641 dev
[0].add_cred_values(default_cred())
1642 interworking_select(dev
[0], bssid
, freq
="2412")
1643 interworking_connect(dev
[0], bssid
, "TTLS")
1645 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
1646 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1648 raise Exception("Timeout on subscription remediation notice")
1649 if " 1 https://example.com/" not in ev
:
1650 raise Exception("Unexpected subscription remediation event contents")
1652 hapd
.request("HS20_WNM_NOTIF " + addr
)
1653 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1655 raise Exception("Timeout on subscription remediation notice")
1656 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1657 raise Exception("Unexpected subscription remediation event contents: " + ev
)
1659 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
1660 raise Exception("Unexpected HS20_WNM_NOTIF success")
1661 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
1662 raise Exception("Unexpected HS20_WNM_NOTIF success")
1663 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1664 raise Exception("Unexpected HS20_WNM_NOTIF success")
1666 def test_ap_hs20_session_info(dev
, apdev
):
1667 """Hotspot 2.0 connection and session information from RADIUS"""
1668 bssid
= apdev
[0]['bssid']
1669 params
= hs20_ap_params()
1670 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1671 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1673 dev
[0].request("SET pmf 1")
1674 dev
[0].hs20_enable()
1675 dev
[0].add_cred_values({ 'realm': "example.com",
1676 'username': "hs20-session-info-test",
1677 'password': "password" })
1678 interworking_select(dev
[0], bssid
, freq
="2412")
1679 interworking_connect(dev
[0], bssid
, "TTLS")
1680 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
1682 raise Exception("Timeout on ESS disassociation imminent notice")
1683 if " 1 59904 https://example.com/" not in ev
:
1684 raise Exception("Unexpected ESS disassociation imminent event contents")
1685 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1687 raise Exception("Scan not started")
1688 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
1690 raise Exception("Scan not completed")
1692 def test_ap_hs20_osen(dev
, apdev
):
1693 """Hotspot 2.0 OSEN connection"""
1694 params
= { 'ssid': "osen",
1696 'auth_server_addr': "127.0.0.1",
1697 'auth_server_port': "1812",
1698 'auth_server_shared_secret': "radius" }
1699 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1701 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
1703 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
1704 scan_freq
="2412", wait_connect
=False)
1705 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1706 group
="GTK_NOT_USED",
1707 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1708 ca_cert
="auth_serv/ca.pem",
1711 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
1712 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
1713 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1714 group
="GTK_NOT_USED",
1715 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1716 ca_cert
="auth_serv/ca.pem",
1718 wpas
.request("DISCONNECT")
1720 def test_ap_hs20_network_preference(dev
, apdev
):
1721 """Hotspot 2.0 network selection with preferred home network"""
1722 bssid
= apdev
[0]['bssid']
1723 params
= hs20_ap_params()
1724 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1726 dev
[0].hs20_enable()
1727 values
= { 'realm': "example.com",
1728 'username': "hs20-test",
1729 'password': "password",
1730 'domain': "example.com" }
1731 dev
[0].add_cred_values(values
)
1733 id = dev
[0].add_network()
1734 dev
[0].set_network_quoted(id, "ssid", "home")
1735 dev
[0].set_network_quoted(id, "psk", "12345678")
1736 dev
[0].set_network(id, "priority", "1")
1737 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1739 dev
[0].scan_for_bss(bssid
, freq
="2412")
1740 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1741 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1743 raise Exception("Connection timed out")
1745 raise Exception("Unexpected network selected")
1747 bssid2
= apdev
[1]['bssid']
1748 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1749 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1751 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1752 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1753 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1754 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1756 raise Exception("Connection timed out")
1757 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1758 raise Exception("No roam to higher priority network")
1759 if bssid2
not in ev
:
1760 raise Exception("Unexpected network selected")
1762 def test_ap_hs20_network_preference2(dev
, apdev
):
1763 """Hotspot 2.0 network selection with preferred credential"""
1764 bssid2
= apdev
[1]['bssid']
1765 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1766 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1768 dev
[0].hs20_enable()
1769 values
= { 'realm': "example.com",
1770 'username': "hs20-test",
1771 'password': "password",
1772 'domain': "example.com",
1774 dev
[0].add_cred_values(values
)
1776 id = dev
[0].add_network()
1777 dev
[0].set_network_quoted(id, "ssid", "home")
1778 dev
[0].set_network_quoted(id, "psk", "12345678")
1779 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1781 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1782 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1783 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1785 raise Exception("Connection timed out")
1786 if bssid2
not in ev
:
1787 raise Exception("Unexpected network selected")
1789 bssid
= apdev
[0]['bssid']
1790 params
= hs20_ap_params()
1791 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1793 dev
[0].scan_for_bss(bssid
, freq
="2412")
1794 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1795 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1796 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1798 raise Exception("Connection timed out")
1799 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1800 raise Exception("No roam to higher priority network")
1802 raise Exception("Unexpected network selected")
1804 def test_ap_hs20_network_preference3(dev
, apdev
):
1805 """Hotspot 2.0 network selection with two credential (one preferred)"""
1806 bssid
= apdev
[0]['bssid']
1807 params
= hs20_ap_params()
1808 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1810 bssid2
= apdev
[1]['bssid']
1811 params
= hs20_ap_params(ssid
="test-hs20b")
1812 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
1813 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1815 dev
[0].hs20_enable()
1816 values
= { 'realm': "example.com",
1817 'username': "hs20-test",
1818 'password': "password",
1820 dev
[0].add_cred_values(values
)
1821 values
= { 'realm': "example.org",
1822 'username': "hs20-test",
1823 'password': "password" }
1824 id = dev
[0].add_cred_values(values
)
1826 dev
[0].scan_for_bss(bssid
, freq
="2412")
1827 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1828 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1829 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1831 raise Exception("Connection timed out")
1833 raise Exception("Unexpected network selected")
1835 dev
[0].set_cred(id, "priority", "2")
1836 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1837 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1838 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1840 raise Exception("Connection timed out")
1841 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1842 raise Exception("No roam to higher priority network")
1843 if bssid2
not in ev
:
1844 raise Exception("Unexpected network selected")
1846 def test_ap_hs20_network_preference4(dev
, apdev
):
1847 """Hotspot 2.0 network selection with username vs. SIM credential"""
1848 bssid
= apdev
[0]['bssid']
1849 params
= hs20_ap_params()
1850 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1852 bssid2
= apdev
[1]['bssid']
1853 params
= hs20_ap_params(ssid
="test-hs20b")
1854 params
['hessid'] = bssid2
1855 params
['anqp_3gpp_cell_net'] = "555,444"
1856 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1857 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1859 dev
[0].hs20_enable()
1860 values
= { 'realm': "example.com",
1861 'username': "hs20-test",
1862 'password': "password",
1864 dev
[0].add_cred_values(values
)
1865 values
= { 'imsi': "555444-333222111",
1867 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1868 id = dev
[0].add_cred_values(values
)
1870 dev
[0].scan_for_bss(bssid
, freq
="2412")
1871 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1872 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1873 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1875 raise Exception("Connection timed out")
1877 raise Exception("Unexpected network selected")
1879 dev
[0].set_cred(id, "priority", "2")
1880 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1881 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1882 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1884 raise Exception("Connection timed out")
1885 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1886 raise Exception("No roam to higher priority network")
1887 if bssid2
not in ev
:
1888 raise Exception("Unexpected network selected")
1890 def test_ap_hs20_fetch_osu(dev
, apdev
):
1891 """Hotspot 2.0 OSU provider and icon fetch"""
1892 bssid
= apdev
[0]['bssid']
1893 params
= hs20_ap_params()
1894 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1895 params
['osu_ssid'] = '"HS 2.0 OSU open"'
1896 params
['osu_method_list'] = "1"
1897 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
1898 params
['osu_icon'] = "w1fi_logo"
1899 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
1900 params
['osu_server_uri'] = "https://example.com/osu/"
1901 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1903 bssid2
= apdev
[1]['bssid']
1904 params
= hs20_ap_params(ssid
="test-hs20b")
1905 params
['hessid'] = bssid2
1906 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1907 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
1908 params
['osu_method_list'] = "0"
1909 params
['osu_nai'] = "osen@example.com"
1910 params
['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
1911 params
['osu_icon'] = "w1fi_logo"
1912 params
['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
1913 params
['osu_server_uri'] = "https://example.org/osu/"
1914 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1916 with
open("w1fi_logo.png", "r") as f
:
1917 orig_logo
= f
.read()
1918 dev
[0].hs20_enable()
1919 dir = "/tmp/osu-fetch"
1920 if os
.path
.isdir(dir):
1921 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
1923 os
.remove(dir + "/" + f
)
1930 dev
[1].scan_for_bss(bssid
, freq
="2412")
1931 dev
[0].request("SET osu_dir " + dir)
1932 dev
[0].request("FETCH_OSU")
1933 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
1934 raise Exception("HS20_ICON_REQUEST failed")
1937 ev
= dev
[0].wait_event(["OSU provider fetch completed",
1938 "RX-HS20-ANQP-ICON"], timeout
=15)
1940 raise Exception("Timeout on OSU fetch")
1941 if "OSU provider fetch completed" in ev
:
1943 if "RX-HS20-ANQP-ICON" in ev
:
1944 with
open(ev
.split(' ')[1], "r") as f
:
1946 if logo
== orig_logo
:
1949 with
open(dir + "/osu-providers.txt", "r") as f
:
1951 if "OSU-PROVIDER " + bssid
not in prov
:
1952 raise Exception("Missing OSU_PROVIDER")
1953 if "OSU-PROVIDER " + bssid2
not in prov
:
1954 raise Exception("Missing OSU_PROVIDER")
1956 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
1958 os
.remove(dir + "/" + f
)
1962 raise Exception("Unexpected number of icons fetched")
1964 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
1966 raise Exception("Timeout on GAS-QUERY-DONE")
1967 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
1969 raise Exception("Timeout on GAS-QUERY-DONE")
1970 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
1971 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
1972 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
1974 raise Exception("Timeout on icon fetch")
1975 if "Icon Binary File" not in ev
:
1976 raise Exception("Unexpected ANQP element")
1978 def test_ap_hs20_ft(dev
, apdev
):
1979 """Hotspot 2.0 connection with FT"""
1980 bssid
= apdev
[0]['bssid']
1981 params
= hs20_ap_params()
1982 params
['wpa_key_mgmt'] = "FT-EAP"
1983 params
['nas_identifier'] = "nas1.w1.fi"
1984 params
['r1_key_holder'] = "000102030405"
1985 params
["mobility_domain"] = "a1b2"
1986 params
["reassociation_deadline"] = "1000"
1987 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1989 dev
[0].hs20_enable()
1990 id = dev
[0].add_cred_values({ 'realm': "example.com",
1991 'username': "hs20-test",
1992 'password': "password",
1993 'ca_cert': "auth_serv/ca.pem",
1994 'domain': "example.com",
1995 'update_identifier': "1234" })
1996 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1997 interworking_connect(dev
[0], bssid
, "TTLS")
1999 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
2000 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2005 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
2010 con
= sqlite3
.connect(dbfile
)
2013 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2014 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2015 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2016 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2017 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2020 params
= { "ssid": "as", "beacon_int": "2000",
2021 "radius_server_clients": "auth_serv/radius_clients.conf",
2022 "radius_server_auth_port": '18128',
2024 "eap_user_file": "sqlite:" + dbfile
,
2025 "ca_cert": "auth_serv/ca.pem",
2026 "server_cert": "auth_serv/server.pem",
2027 "private_key": "auth_serv/server.key",
2028 "subscr_remediation_url": "https://example.org/",
2029 "subscr_remediation_method": "1" }
2030 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2032 bssid
= apdev
[0]['bssid']
2033 params
= hs20_ap_params()
2034 params
['auth_server_port'] = "18128"
2035 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2037 dev
[0].request("SET pmf 1")
2038 dev
[0].hs20_enable()
2039 id = dev
[0].add_cred_values({ 'realm': "example.com",
2040 'username': "user-mschapv2",
2041 'password': "password",
2042 'ca_cert': "auth_serv/ca.pem" })
2043 interworking_select(dev
[0], bssid
, freq
="2412")
2044 interworking_connect(dev
[0], bssid
, "TTLS")
2045 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2047 raise Exception("Timeout on subscription remediation notice")
2048 if " 1 https://example.org/" not in ev
:
2049 raise Exception("Unexpected subscription remediation event contents")
2053 cur
.execute("SELECT * from authlog")
2054 rows
= cur
.fetchall()
2056 raise Exception("No authlog entries")
2061 def test_ap_hs20_external_selection(dev
, apdev
):
2062 """Hotspot 2.0 connection using external network selection and creation"""
2063 bssid
= apdev
[0]['bssid']
2064 params
= hs20_ap_params()
2065 params
['hessid'] = bssid
2066 params
['disable_dgaf'] = '1'
2067 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2069 dev
[0].hs20_enable()
2070 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
2071 identity
="hs20-test", password
="password",
2072 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2073 scan_freq
="2412", update_identifier
="54321")
2074 if dev
[0].get_status_field("hs20") != "2":
2075 raise Exception("Unexpected hs20 indication")
2077 def test_ap_hs20_random_mac_addr(dev
, apdev
):
2078 """Hotspot 2.0 connection with random MAC address"""
2079 bssid
= apdev
[0]['bssid']
2080 params
= hs20_ap_params()
2081 params
['hessid'] = bssid
2082 params
['disable_dgaf'] = '1'
2083 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2085 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2086 wpas
.interface_add("wlan5")
2087 addr
= wpas
.p2p_interface_addr()
2088 wpas
.request("SET mac_addr 1")
2089 wpas
.request("SET preassoc_mac_addr 1")
2090 wpas
.request("SET rand_addr_lifetime 60")
2092 wpas
.scan(freq
="2412", only_new
=True)
2093 id = wpas
.add_cred_values({ 'realm': "example.com",
2094 'username': "hs20-test",
2095 'password': "password",
2096 'ca_cert': "auth_serv/ca.pem",
2097 'domain': "example.com",
2098 'update_identifier': "1234" })
2099 interworking_select(wpas
, bssid
, "home", freq
="2412")
2100 interworking_connect(wpas
, bssid
, "TTLS")
2101 addr1
= wpas
.get_driver_status_field("addr")
2103 raise Exception("Did not use random MAC address")
2105 sta
= hapd
.get_sta(addr
)
2106 if sta
['addr'] != "FAIL":
2107 raise Exception("Unexpected STA association with permanent address")
2108 sta
= hapd
.get_sta(addr1
)
2109 if sta
['addr'] != addr1
:
2110 raise Exception("STA association with random address not found")
2112 def _test_ap_hs20_proxyarp(dev
, apdev
):
2113 bssid
= apdev
[0]['bssid']
2114 params
= hs20_ap_params()
2115 params
['hessid'] = bssid
2116 params
['disable_dgaf'] = '0'
2117 params
['proxy_arp'] = '1'
2118 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2119 if "OK" in hapd
.request("ENABLE"):
2120 raise Exception("Incomplete hostapd configuration was accepted")
2121 hapd
.set("ap_isolate", "1")
2122 if "OK" in hapd
.request("ENABLE"):
2123 raise Exception("Incomplete hostapd configuration was accepted")
2124 hapd
.set('bridge', 'ap-br0')
2129 # For now, do not report failures due to missing kernel support
2130 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2132 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2134 raise Exception("AP startup timed out")
2135 if "AP-ENABLED" not in ev
:
2136 raise Exception("AP startup failed")
2138 dev
[0].hs20_enable()
2139 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2140 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2142 id = dev
[0].add_cred_values({ 'realm': "example.com",
2143 'username': "hs20-test",
2144 'password': "password",
2145 'ca_cert': "auth_serv/ca.pem",
2146 'domain': "example.com",
2147 'update_identifier': "1234" })
2148 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2149 interworking_connect(dev
[0], bssid
, "TTLS")
2151 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2152 identity
="hs20-test", password
="password",
2153 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2157 addr0
= dev
[0].p2p_interface_addr()
2158 addr1
= dev
[1].p2p_interface_addr()
2160 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2161 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2163 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2164 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2166 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2167 raise Exception("DATA_TEST_FRAME failed")
2169 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2170 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2172 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2173 raise Exception("DATA_TEST_FRAME failed")
2175 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2176 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2178 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2179 raise Exception("DATA_TEST_FRAME failed")
2181 matches
= get_permanent_neighbors("ap-br0")
2182 logger
.info("After connect: " + str(matches
))
2183 if len(matches
) != 3:
2184 raise Exception("Unexpected number of neighbor entries after connect")
2185 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2186 raise Exception("dev0 addr missing")
2187 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2188 raise Exception("dev1 addr(1) missing")
2189 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2190 raise Exception("dev1 addr(2) missing")
2191 dev
[0].request("DISCONNECT")
2192 dev
[1].request("DISCONNECT")
2194 matches
= get_permanent_neighbors("ap-br0")
2195 logger
.info("After disconnect: " + str(matches
))
2196 if len(matches
) > 0:
2197 raise Exception("Unexpected neighbor entries after disconnect")
2199 def test_ap_hs20_proxyarp(dev
, apdev
):
2200 """Hotspot 2.0 and ProxyARP"""
2203 res
= _test_ap_hs20_proxyarp(dev
, apdev
)
2205 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2206 stderr
=open('/dev/null', 'w'))
2207 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2208 stderr
=open('/dev/null', 'w'))
2212 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
2213 bssid
= apdev
[0]['bssid']
2214 params
= hs20_ap_params()
2215 params
['hessid'] = bssid
2216 params
['disable_dgaf'] = '1' if disabled
else '0'
2217 params
['proxy_arp'] = '1'
2218 params
['ap_isolate'] = '1'
2219 params
['bridge'] = 'ap-br0'
2220 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2224 # For now, do not report failures due to missing kernel support
2225 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2227 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
2229 raise Exception("AP startup timed out")
2231 dev
[0].hs20_enable()
2232 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2233 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2235 id = dev
[0].add_cred_values({ 'realm': "example.com",
2236 'username': "hs20-test",
2237 'password': "password",
2238 'ca_cert': "auth_serv/ca.pem",
2239 'domain': "example.com",
2240 'update_identifier': "1234" })
2241 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2242 interworking_connect(dev
[0], bssid
, "TTLS")
2244 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2245 identity
="hs20-test", password
="password",
2246 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2250 addr0
= dev
[0].p2p_interface_addr()
2252 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2254 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2255 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2257 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2258 raise Exception("DATA_TEST_FRAME failed")
2260 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
2262 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2263 raise Exception("DATA_TEST_FRAME failed")
2265 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
2266 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
2267 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2268 raise Exception("DATA_TEST_FRAME failed")
2270 matches
= get_permanent_neighbors("ap-br0")
2271 logger
.info("After connect: " + str(matches
))
2272 if len(matches
) != 1:
2273 raise Exception("Unexpected number of neighbor entries after connect")
2274 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2275 raise Exception("dev0 addr missing")
2276 dev
[0].request("DISCONNECT")
2277 dev
[1].request("DISCONNECT")
2279 matches
= get_permanent_neighbors("ap-br0")
2280 logger
.info("After disconnect: " + str(matches
))
2281 if len(matches
) > 0:
2282 raise Exception("Unexpected neighbor entries after disconnect")
2284 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
2285 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
2288 res
= _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
2290 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2291 stderr
=open('/dev/null', 'w'))
2292 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2293 stderr
=open('/dev/null', 'w'))
2297 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
2298 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
2301 res
= _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
2303 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2304 stderr
=open('/dev/null', 'w'))
2305 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2306 stderr
=open('/dev/null', 'w'))
2310 def ip_checksum(buf
):
2314 for i
in range(0, len(buf
), 2):
2315 val
, = struct
.unpack('H', buf
[i
:i
+2])
2318 sum = (sum & 0xffff) + (sum >> 16)
2319 return struct
.pack('H', ~
sum & 0xffff)
2321 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
2322 start
= struct
.pack("BB", type, code
)
2324 icmp
= start
+ '\x00\x00' + end
2325 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
2326 csum
= ip_checksum(pseudo
+ icmp
)
2327 return start
+ csum
+ end
2329 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
2330 reachable_time
=0, retrans_timer
=0, opt
=None):
2331 link_mc
= binascii
.unhexlify("3333ff000002")
2332 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2334 ehdr
= link_mc
+ _src_ll
+ proto
2335 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2336 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2338 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
2339 reachable_time
, retrans_timer
)
2344 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
2346 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2347 ipv6
+= _ip_src
+ _ip_dst
2349 return ehdr
+ ipv6
+ icmp
2351 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2352 link_mc
= binascii
.unhexlify("3333ff000002")
2353 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2355 ehdr
= link_mc
+ _src_ll
+ proto
2356 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2357 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2359 reserved
= '\x00\x00\x00\x00'
2360 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2362 payload
= reserved
+ _target
+ opt
2364 payload
= reserved
+ _target
2365 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
2367 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2368 ipv6
+= _ip_src
+ _ip_dst
2370 return ehdr
+ ipv6
+ icmp
2372 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2373 link_mc
= binascii
.unhexlify("3333ff000002")
2374 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2376 ehdr
= link_mc
+ _src_ll
+ proto
2377 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2378 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2380 reserved
= '\x00\x00\x00\x00'
2381 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2383 payload
= reserved
+ _target
+ opt
2385 payload
= reserved
+ _target
2386 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
2388 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2389 ipv6
+= _ip_src
+ _ip_dst
2391 return ehdr
+ ipv6
+ icmp
2393 def get_permanent_neighbors(ifname
):
2394 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
2395 res
= cmd
.stdout
.read()
2397 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
2399 def _test_proxyarp_open(dev
, apdev
):
2400 bssid
= apdev
[0]['bssid']
2401 params
= { 'ssid': 'open' }
2402 params
['proxy_arp'] = '1'
2403 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2404 hapd
.set("ap_isolate", "1")
2405 hapd
.set('bridge', 'ap-br0')
2410 # For now, do not report failures due to missing kernel support
2411 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2413 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2415 raise Exception("AP startup timed out")
2416 if "AP-ENABLED" not in ev
:
2417 raise Exception("AP startup failed")
2419 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2420 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2422 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2423 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2426 addr0
= dev
[0].p2p_interface_addr()
2427 addr1
= dev
[1].p2p_interface_addr()
2429 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2430 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2433 pkt
= build_ns(src_ll
=addr0
, ip_src
="::", ip_dst
="ff02::1:ff00:2",
2434 target
="aaaa:bbbb:cccc::2", opt
=src_ll_opt0
)
2435 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2436 raise Exception("DATA_TEST_FRAME failed")
2438 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2439 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2441 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2442 raise Exception("DATA_TEST_FRAME failed")
2443 # test frame without source link-layer address option
2444 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2445 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2")
2446 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2447 raise Exception("DATA_TEST_FRAME failed")
2448 # test frame with bogus option
2449 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2450 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2451 opt
="\x70\x01\x01\x02\x03\x04\x05\x05")
2452 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2453 raise Exception("DATA_TEST_FRAME failed")
2454 # test frame with truncated source link-layer address option
2455 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2456 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2457 opt
="\x01\x01\x01\x02\x03\x04")
2458 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2459 raise Exception("DATA_TEST_FRAME failed")
2460 # test frame with foreign source link-layer address option
2461 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2462 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2463 opt
="\x01\x01\x01\x02\x03\x04\x05\x06")
2464 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2465 raise Exception("DATA_TEST_FRAME failed")
2467 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2468 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2470 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2471 raise Exception("DATA_TEST_FRAME failed")
2473 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2474 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2476 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2477 raise Exception("DATA_TEST_FRAME failed")
2478 # another copy for additional code coverage
2479 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2480 raise Exception("DATA_TEST_FRAME failed")
2482 matches
= get_permanent_neighbors("ap-br0")
2483 logger
.info("After connect: " + str(matches
))
2484 if len(matches
) != 3:
2485 raise Exception("Unexpected number of neighbor entries after connect")
2486 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2487 raise Exception("dev0 addr missing")
2488 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2489 raise Exception("dev1 addr(1) missing")
2490 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2491 raise Exception("dev1 addr(2) missing")
2493 dev
[0].request("DISCONNECT")
2494 dev
[1].request("DISCONNECT")
2496 matches
= get_permanent_neighbors("ap-br0")
2497 logger
.info("After disconnect: " + str(matches
))
2498 if len(matches
) > 0:
2499 raise Exception("Unexpected neighbor entries after disconnect")
2501 def test_proxyarp_open(dev
, apdev
):
2502 """ProxyARP with open network"""
2505 res
= _test_proxyarp_open(dev
, apdev
)
2507 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2508 stderr
=open('/dev/null', 'w'))
2509 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2510 stderr
=open('/dev/null', 'w'))