]>
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 ")
243 "00:11:22:33:44:55 123",
244 "00:11:22:33:44:55 qq" ]
246 if "FAIL" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd
):
247 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd
)
249 dev
[0].dump_monitor()
250 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
251 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
252 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
254 raise Exception("ANQP operation timed out")
255 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=0.1)
257 raise Exception("Unexpected ANQP response: " + ev
)
259 dev
[0].dump_monitor()
260 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " 01000b6578616d706c652e636f6d"):
261 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
262 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
264 raise Exception("No ANQP response")
265 if "NAI Realm list" not in ev
:
266 raise Exception("Missing NAI Realm list: " + ev
)
268 dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
269 'password': "secret",
270 'domain': "example.com" })
271 dev
[0].dump_monitor()
272 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
273 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
274 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
276 raise Exception("No ANQP response")
277 if "NAI Realm list" not in ev
:
278 raise Exception("Missing NAI Realm list: " + ev
)
280 def test_ap_interworking_scan_filtering(dev
, apdev
):
281 """Interworking scan filtering with HESSID and access network type"""
283 return _test_ap_interworking_scan_filtering(dev
, apdev
)
285 dev
[0].request("SET hessid 00:00:00:00:00:00")
286 dev
[0].request("SET access_network_type 15")
288 def _test_ap_interworking_scan_filtering(dev
, apdev
):
289 bssid
= apdev
[0]['bssid']
290 params
= hs20_ap_params()
291 ssid
= "test-hs20-ap1"
292 params
['ssid'] = ssid
293 params
['hessid'] = bssid
294 hostapd
.add_ap(apdev
[0]['ifname'], params
)
296 bssid2
= apdev
[1]['bssid']
297 params
= hs20_ap_params()
298 ssid2
= "test-hs20-ap2"
299 params
['ssid'] = ssid2
300 params
['hessid'] = bssid2
301 params
['access_network_type'] = "1"
302 del params
['venue_group']
303 del params
['venue_type']
304 hostapd
.add_ap(apdev
[1]['ifname'], params
)
311 logger
.info("Check probe request filtering based on HESSID")
313 dev
[0].request("SET hessid " + bssid2
)
314 dev
[0].scan(freq
="2412")
316 check_probe_resp(wt
, bssid
, bssid2
)
318 logger
.info("Check probe request filtering based on access network type")
320 wt
.clear_bss_counters(bssid
)
321 wt
.clear_bss_counters(bssid2
)
322 dev
[0].request("SET hessid 00:00:00:00:00:00")
323 dev
[0].request("SET access_network_type 14")
324 dev
[0].scan(freq
="2412")
326 check_probe_resp(wt
, bssid2
, bssid
)
328 wt
.clear_bss_counters(bssid
)
329 wt
.clear_bss_counters(bssid2
)
330 dev
[0].request("SET hessid 00:00:00:00:00:00")
331 dev
[0].request("SET access_network_type 1")
332 dev
[0].scan(freq
="2412")
334 check_probe_resp(wt
, bssid
, bssid2
)
336 logger
.info("Check probe request filtering based on HESSID and ANT")
338 wt
.clear_bss_counters(bssid
)
339 wt
.clear_bss_counters(bssid2
)
340 dev
[0].request("SET hessid " + bssid
)
341 dev
[0].request("SET access_network_type 14")
342 dev
[0].scan(freq
="2412")
344 check_probe_resp(wt
, bssid2
, bssid
)
346 wt
.clear_bss_counters(bssid
)
347 wt
.clear_bss_counters(bssid2
)
348 dev
[0].request("SET hessid " + bssid2
)
349 dev
[0].request("SET access_network_type 14")
350 dev
[0].scan(freq
="2412")
352 check_probe_resp(wt
, bssid
, None)
353 check_probe_resp(wt
, bssid2
, None)
355 wt
.clear_bss_counters(bssid
)
356 wt
.clear_bss_counters(bssid2
)
357 dev
[0].request("SET hessid " + bssid
)
358 dev
[0].request("SET access_network_type 1")
359 dev
[0].scan(freq
="2412")
361 check_probe_resp(wt
, bssid
, None)
362 check_probe_resp(wt
, bssid2
, None)
364 def test_ap_hs20_select(dev
, apdev
):
365 """Hotspot 2.0 network selection"""
366 bssid
= apdev
[0]['bssid']
367 params
= hs20_ap_params()
368 params
['hessid'] = bssid
369 hostapd
.add_ap(apdev
[0]['ifname'], params
)
372 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
373 'password': "secret",
374 'domain': "example.com" })
375 interworking_select(dev
[0], bssid
, "home")
377 dev
[0].remove_cred(id)
378 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
379 'password': "secret",
380 'domain': "no.match.example.com" })
381 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
383 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com");
384 interworking_select(dev
[0], bssid
, no_match
=True, freq
="2412")
386 res
= dev
[0].request("SCAN_RESULTS")
387 if "[HS20]" not in res
:
388 raise Exception("HS20 flag missing from scan results: " + res
)
390 bssid2
= apdev
[1]['bssid']
391 params
= hs20_ap_params()
392 params
['nai_realm'] = [ "0,example.org,21" ]
393 params
['hessid'] = bssid2
394 params
['domain_name'] = "example.org"
395 hostapd
.add_ap(apdev
[1]['ifname'], params
)
396 dev
[0].remove_cred(id)
397 id = dev
[0].add_cred_values({ 'realm': "example.org", 'username': "test",
398 'password': "secret",
399 'domain': "example.org" })
400 interworking_select(dev
[0], bssid2
, "home", freq
="2412")
402 def hs20_simulated_sim(dev
, ap
, method
):
404 params
= hs20_ap_params()
405 params
['hessid'] = bssid
406 params
['anqp_3gpp_cell_net'] = "555,444"
407 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
408 hostapd
.add_ap(ap
['ifname'], params
)
411 dev
.add_cred_values({ 'imsi': "555444-333222111", 'eap': method
,
412 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
413 interworking_select(dev
, "home", freq
="2412")
414 interworking_connect(dev
, bssid
, method
)
415 check_sp_type(dev
, "home")
417 def test_ap_hs20_sim(dev
, apdev
):
418 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
419 if not hlr_auc_gw_available():
421 hs20_simulated_sim(dev
[0], apdev
[0], "SIM")
422 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
423 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
425 raise Exception("Timeout on already-connected event")
427 def test_ap_hs20_aka(dev
, apdev
):
428 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
429 if not hlr_auc_gw_available():
431 hs20_simulated_sim(dev
[0], apdev
[0], "AKA")
433 def test_ap_hs20_aka_prime(dev
, apdev
):
434 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
435 if not hlr_auc_gw_available():
437 hs20_simulated_sim(dev
[0], apdev
[0], "AKA'")
439 def test_ap_hs20_ext_sim(dev
, apdev
):
440 """Hotspot 2.0 with external SIM processing"""
441 if not hlr_auc_gw_available():
443 bssid
= apdev
[0]['bssid']
444 params
= hs20_ap_params()
445 params
['hessid'] = bssid
446 params
['anqp_3gpp_cell_net'] = "232,01"
447 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
448 hostapd
.add_ap(apdev
[0]['ifname'], params
)
452 dev
[0].request("SET external_sim 1")
453 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
454 interworking_select(dev
[0], "home", freq
="2412")
455 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
456 check_sp_type(dev
[0], "home")
458 dev
[0].request("SET external_sim 0")
460 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
461 """Hotspot 2.0 with external SIM processing in roaming network"""
462 if not hlr_auc_gw_available():
464 bssid
= apdev
[0]['bssid']
465 params
= hs20_ap_params()
466 params
['hessid'] = bssid
467 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
468 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
469 hostapd
.add_ap(apdev
[0]['ifname'], params
)
473 dev
[0].request("SET external_sim 1")
474 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
475 interworking_select(dev
[0], "roaming", freq
="2412")
476 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
477 check_sp_type(dev
[0], "roaming")
479 dev
[0].request("SET external_sim 0")
481 def test_ap_hs20_username(dev
, apdev
):
482 """Hotspot 2.0 connection in username/password credential"""
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
)
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 interworking_select(dev
[0], bssid
, "home", freq
="2412")
497 interworking_connect(dev
[0], bssid
, "TTLS")
498 check_sp_type(dev
[0], "home")
499 status
= dev
[0].get_status()
500 if status
['pairwise_cipher'] != "CCMP":
501 raise Exception("Unexpected pairwise cipher")
502 if status
['hs20'] != "2":
503 raise Exception("Unexpected HS 2.0 support indication")
505 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
506 identity
="hs20-test", password
="password",
507 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
510 def test_ap_hs20_connect_api(dev
, apdev
):
511 """Hotspot 2.0 connection with connect API"""
512 bssid
= apdev
[0]['bssid']
513 params
= hs20_ap_params()
514 params
['hessid'] = bssid
515 params
['disable_dgaf'] = '1'
516 hostapd
.add_ap(apdev
[0]['ifname'], params
)
518 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
519 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
521 wpas
.flush_scan_cache()
522 id = wpas
.add_cred_values({ 'realm': "example.com",
523 'username': "hs20-test",
524 'password': "password",
525 'ca_cert': "auth_serv/ca.pem",
526 'domain': "example.com",
527 'update_identifier': "1234" })
528 interworking_select(wpas
, bssid
, "home", freq
="2412")
529 interworking_connect(wpas
, bssid
, "TTLS")
530 check_sp_type(wpas
, "home")
531 status
= wpas
.get_status()
532 if status
['pairwise_cipher'] != "CCMP":
533 raise Exception("Unexpected pairwise cipher")
534 if status
['hs20'] != "2":
535 raise Exception("Unexpected HS 2.0 support indication")
537 def test_ap_hs20_auto_interworking(dev
, apdev
):
538 """Hotspot 2.0 connection with auto_interworking=1"""
539 bssid
= apdev
[0]['bssid']
540 params
= hs20_ap_params()
541 params
['hessid'] = bssid
542 params
['disable_dgaf'] = '1'
543 hostapd
.add_ap(apdev
[0]['ifname'], params
)
545 dev
[0].hs20_enable(auto_interworking
=True)
546 id = dev
[0].add_cred_values({ 'realm': "example.com",
547 'username': "hs20-test",
548 'password': "password",
549 'ca_cert': "auth_serv/ca.pem",
550 'domain': "example.com",
551 'update_identifier': "1234" })
552 dev
[0].request("REASSOCIATE")
553 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
555 raise Exception("Connection timed out")
556 check_sp_type(dev
[0], "home")
557 status
= dev
[0].get_status()
558 if status
['pairwise_cipher'] != "CCMP":
559 raise Exception("Unexpected pairwise cipher")
560 if status
['hs20'] != "2":
561 raise Exception("Unexpected HS 2.0 support indication")
563 def test_ap_hs20_auto_interworking_no_cred_match(dev
, apdev
):
564 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
565 bssid
= apdev
[0]['bssid']
566 params
= { "ssid": "test" }
567 hostapd
.add_ap(apdev
[0]['ifname'], params
)
569 dev
[0].hs20_enable(auto_interworking
=True)
570 dev
[0].add_cred_values({ 'realm': "example.com",
571 'username': "hs20-test",
572 'password': "password",
573 'ca_cert': "auth_serv/ca.pem",
574 'domain': "example.com" })
576 id = dev
[0].connect("test", psk
="12345678", only_add_network
=True)
577 dev
[0].request("ENABLE_NETWORK %s" % id)
578 logger
.info("Verify that scanning continues when there is partial network block match")
579 for i
in range(0, 2):
580 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
582 raise Exception("Scan timed out")
583 logger
.info("Scan completed")
585 def eap_test(dev
, ap
, eap_params
, method
, user
):
587 params
= hs20_ap_params()
588 params
['nai_realm'] = [ "0,example.com," + eap_params
]
589 hostapd
.add_ap(ap
['ifname'], params
)
592 dev
.add_cred_values({ 'realm': "example.com",
594 'password': "password" })
595 interworking_select(dev
, bssid
, freq
="2412")
596 interworking_connect(dev
, bssid
, method
)
598 def test_ap_hs20_eap_unknown(dev
, apdev
):
599 """Hotspot 2.0 connection with unknown EAP method"""
600 bssid
= apdev
[0]['bssid']
601 params
= hs20_ap_params()
602 params
['nai_realm'] = "0,example.com,99"
603 hostapd
.add_ap(apdev
[0]['ifname'], params
)
606 dev
[0].add_cred_values(default_cred())
607 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
609 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
610 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
611 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
613 def test_ap_hs20_eap_peap_default(dev
, apdev
):
614 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
615 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
617 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
618 """Hotspot 2.0 connection with PEAP/GTC"""
619 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
621 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
622 """Hotspot 2.0 connection with PEAP/unknown"""
623 bssid
= apdev
[0]['bssid']
624 params
= hs20_ap_params()
625 params
['nai_realm'] = "0,example.com,25[3:99]"
626 hostapd
.add_ap(apdev
[0]['ifname'], params
)
629 dev
[0].add_cred_values(default_cred())
630 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
632 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
633 """Hotspot 2.0 connection with TTLS/CHAP"""
634 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
636 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
637 """Hotspot 2.0 connection with TTLS/MSCHAP"""
638 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
640 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
641 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
642 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
644 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
645 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
646 bssid
= apdev
[0]['bssid']
647 params
= hs20_ap_params()
648 params
['nai_realm'] = "0,example.com,21[3:99]"
649 hostapd
.add_ap(apdev
[0]['ifname'], params
)
652 dev
[0].add_cred_values(default_cred())
653 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
655 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
656 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
657 bssid
= apdev
[0]['bssid']
658 params
= hs20_ap_params()
659 params
['nai_realm'] = "0,example.com,21[3:5]"
660 hostapd
.add_ap(apdev
[0]['ifname'], params
)
663 dev
[0].add_cred_values(default_cred())
664 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
666 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
667 """Hotspot 2.0 connection with TTLS/unknown"""
668 bssid
= apdev
[0]['bssid']
669 params
= hs20_ap_params()
670 params
['nai_realm'] = "0,example.com,21[2:5]"
671 hostapd
.add_ap(apdev
[0]['ifname'], params
)
674 dev
[0].add_cred_values(default_cred())
675 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
677 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
678 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
679 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
681 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
682 """Hotspot 2.0 connection with FAST/EAP-GTC"""
683 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
685 def test_ap_hs20_eap_tls(dev
, apdev
):
686 """Hotspot 2.0 connection with EAP-TLS"""
687 bssid
= apdev
[0]['bssid']
688 params
= hs20_ap_params()
689 params
['nai_realm'] = [ "0,example.com,13[5:6]" ]
690 hostapd
.add_ap(apdev
[0]['ifname'], params
)
693 dev
[0].add_cred_values({ 'realm': "example.com",
694 'username': "certificate-user",
695 'ca_cert': "auth_serv/ca.pem",
696 'client_cert': "auth_serv/user.pem",
697 'private_key': "auth_serv/user.key"})
698 interworking_select(dev
[0], bssid
, freq
="2412")
699 interworking_connect(dev
[0], bssid
, "TLS")
701 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
702 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
703 bssid
= apdev
[0]['bssid']
704 params
= hs20_ap_params()
705 params
['nai_realm'] = [ "0,example.com,99[5:6]" ]
706 hostapd
.add_ap(apdev
[0]['ifname'], params
)
709 dev
[0].add_cred_values({ 'realm': "example.com",
710 'username': "certificate-user",
711 'ca_cert': "auth_serv/ca.pem",
712 'client_cert': "auth_serv/user.pem",
713 'private_key': "auth_serv/user.key"})
714 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
716 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
717 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
718 bssid
= apdev
[0]['bssid']
719 params
= hs20_ap_params()
720 params
['nai_realm'] = [ "0,example.com,21[5:6]" ]
721 hostapd
.add_ap(apdev
[0]['ifname'], params
)
724 dev
[0].add_cred_values({ 'realm': "example.com",
725 'username': "certificate-user",
726 'ca_cert': "auth_serv/ca.pem",
727 'client_cert': "auth_serv/user.pem",
728 'private_key': "auth_serv/user.key"})
729 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
731 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
732 """Hotspot 2.0 connection with invalid cred configuration"""
733 bssid
= apdev
[0]['bssid']
734 params
= hs20_ap_params()
735 hostapd
.add_ap(apdev
[0]['ifname'], params
)
738 dev
[0].add_cred_values({ 'realm': "example.com",
739 'username': "certificate-user",
740 'client_cert': "auth_serv/user.pem" })
741 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
743 def test_ap_hs20_nai_realms(dev
, apdev
):
744 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
745 bssid
= apdev
[0]['bssid']
746 params
= hs20_ap_params()
747 params
['hessid'] = bssid
748 params
['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
749 hostapd
.add_ap(apdev
[0]['ifname'], params
)
752 id = dev
[0].add_cred_values({ 'realm': "example.com",
753 'username': "pap user",
754 'password': "password",
755 'domain': "example.com" })
756 interworking_select(dev
[0], bssid
, "home", freq
="2412")
757 interworking_connect(dev
[0], bssid
, "TTLS")
758 check_sp_type(dev
[0], "home")
760 def test_ap_hs20_roaming_consortium(dev
, apdev
):
761 """Hotspot 2.0 connection based on roaming consortium match"""
762 bssid
= apdev
[0]['bssid']
763 params
= hs20_ap_params()
764 params
['hessid'] = bssid
765 hostapd
.add_ap(apdev
[0]['ifname'], params
)
768 for consortium
in [ "112233", "1020304050", "010203040506", "fedcba" ]:
769 id = dev
[0].add_cred_values({ 'username': "user",
770 'password': "password",
771 'domain': "example.com",
772 'roaming_consortium': consortium
,
774 interworking_select(dev
[0], bssid
, "home", freq
="2412")
775 interworking_connect(dev
[0], bssid
, "PEAP")
776 check_sp_type(dev
[0], "home")
777 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
778 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
780 raise Exception("Timeout on already-connected event")
781 dev
[0].remove_cred(id)
783 def test_ap_hs20_username_roaming(dev
, apdev
):
784 """Hotspot 2.0 connection in username/password credential (roaming)"""
785 bssid
= apdev
[0]['bssid']
786 params
= hs20_ap_params()
787 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
788 "0,roaming.example.com,21[2:4][5:7]",
789 "0,another.example.com" ]
790 params
['domain_name'] = "another.example.com"
791 params
['hessid'] = bssid
792 hostapd
.add_ap(apdev
[0]['ifname'], params
)
795 id = dev
[0].add_cred_values({ 'realm': "roaming.example.com",
796 'username': "hs20-test",
797 'password': "password",
798 'domain': "example.com" })
799 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
800 interworking_connect(dev
[0], bssid
, "TTLS")
801 check_sp_type(dev
[0], "roaming")
803 def test_ap_hs20_username_unknown(dev
, apdev
):
804 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
805 bssid
= apdev
[0]['bssid']
806 params
= hs20_ap_params()
807 params
['hessid'] = bssid
808 hostapd
.add_ap(apdev
[0]['ifname'], params
)
811 id = dev
[0].add_cred_values({ 'realm': "example.com",
812 'username': "hs20-test",
813 'password': "password" })
814 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
815 interworking_connect(dev
[0], bssid
, "TTLS")
816 check_sp_type(dev
[0], "unknown")
818 def test_ap_hs20_username_unknown2(dev
, apdev
):
819 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
820 bssid
= apdev
[0]['bssid']
821 params
= hs20_ap_params()
822 params
['hessid'] = bssid
823 del params
['domain_name']
824 hostapd
.add_ap(apdev
[0]['ifname'], params
)
827 id = dev
[0].add_cred_values({ 'realm': "example.com",
828 'username': "hs20-test",
829 'password': "password",
830 'domain': "example.com" })
831 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
832 interworking_connect(dev
[0], bssid
, "TTLS")
833 check_sp_type(dev
[0], "unknown")
835 def test_ap_hs20_gas_while_associated(dev
, apdev
):
836 """Hotspot 2.0 connection with GAS query while associated"""
837 bssid
= apdev
[0]['bssid']
838 params
= hs20_ap_params()
839 params
['hessid'] = bssid
840 hostapd
.add_ap(apdev
[0]['ifname'], params
)
843 id = dev
[0].add_cred_values({ 'realm': "example.com",
844 'username': "hs20-test",
845 'password': "password",
846 'domain': "example.com" })
847 interworking_select(dev
[0], bssid
, "home", freq
="2412")
848 interworking_connect(dev
[0], bssid
, "TTLS")
850 logger
.info("Verifying GAS query while associated")
851 dev
[0].request("FETCH_ANQP")
852 for i
in range(0, 6):
853 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
855 raise Exception("Operation timed out")
857 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
858 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
860 _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
)
862 dev
[0].request("SET pmf 0")
864 def _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
865 bssid
= apdev
[0]['bssid']
866 params
= hs20_ap_params()
867 params
['hessid'] = bssid
868 hostapd
.add_ap(apdev
[0]['ifname'], params
)
870 bssid2
= apdev
[1]['bssid']
871 params
= hs20_ap_params()
872 params
['hessid'] = bssid2
873 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
874 hostapd
.add_ap(apdev
[1]['ifname'], params
)
877 dev
[0].request("SET pmf 2")
878 id = dev
[0].add_cred_values({ 'realm': "example.com",
879 'username': "hs20-test",
880 'password': "password",
881 'domain': "example.com" })
882 interworking_select(dev
[0], bssid
, "home", freq
="2412")
883 interworking_connect(dev
[0], bssid
, "TTLS")
885 logger
.info("Verifying GAS query while associated")
886 dev
[0].request("FETCH_ANQP")
887 for i
in range(0, 2 * 6):
888 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
890 raise Exception("Operation timed out")
892 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
893 """Hotspot 2.0 connection with fragmented GAS query while associated"""
894 bssid
= apdev
[0]['bssid']
895 params
= hs20_ap_params()
896 params
['hessid'] = bssid
897 hostapd
.add_ap(apdev
[0]['ifname'], params
)
898 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
899 hapd
.set("gas_frag_limit", "50")
902 id = dev
[0].add_cred_values({ 'realm': "example.com",
903 'username': "hs20-test",
904 'password': "password",
905 'domain': "example.com" })
906 interworking_select(dev
[0], bssid
, "home", freq
="2412")
907 interworking_connect(dev
[0], bssid
, "TTLS")
909 logger
.info("Verifying GAS query while associated")
910 dev
[0].request("FETCH_ANQP")
911 for i
in range(0, 6):
912 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
914 raise Exception("Operation timed out")
916 def test_ap_hs20_multiple_connects(dev
, apdev
):
917 """Hotspot 2.0 connection through multiple network selections"""
918 bssid
= apdev
[0]['bssid']
919 params
= hs20_ap_params()
920 params
['hessid'] = bssid
921 hostapd
.add_ap(apdev
[0]['ifname'], params
)
924 values
= { 'realm': "example.com",
925 'username': "hs20-test",
926 'password': "password",
927 'domain': "example.com" }
928 id = dev
[0].add_cred_values(values
)
930 dev
[0].scan_for_bss(bssid
, freq
="2412")
932 for i
in range(0, 3):
933 logger
.info("Starting Interworking network selection")
934 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
936 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
937 "INTERWORKING-ALREADY-CONNECTED",
938 "CTRL-EVENT-CONNECTED"], timeout
=15)
940 raise Exception("Connection timed out")
941 if "INTERWORKING-NO-MATCH" in ev
:
942 raise Exception("Matching AP not found")
943 if "CTRL-EVENT-CONNECTED" in ev
:
945 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
948 dev
[0].request("DISCONNECT")
949 dev
[0].dump_monitor()
951 networks
= dev
[0].list_networks()
952 if len(networks
) > 1:
953 raise Exception("Duplicated network block detected")
955 def test_ap_hs20_disallow_aps(dev
, apdev
):
956 """Hotspot 2.0 connection and disallow_aps"""
957 bssid
= apdev
[0]['bssid']
958 params
= hs20_ap_params()
959 params
['hessid'] = bssid
960 hostapd
.add_ap(apdev
[0]['ifname'], params
)
963 values
= { 'realm': "example.com",
964 'username': "hs20-test",
965 'password': "password",
966 'domain': "example.com" }
967 id = dev
[0].add_cred_values(values
)
969 dev
[0].scan_for_bss(bssid
, freq
="2412")
971 logger
.info("Verify disallow_aps bssid")
972 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
973 dev
[0].request("INTERWORKING_SELECT auto")
974 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
976 raise Exception("Network selection timed out")
977 dev
[0].dump_monitor()
979 logger
.info("Verify disallow_aps ssid")
980 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
981 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
982 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
984 raise Exception("Network selection timed out")
985 dev
[0].dump_monitor()
987 logger
.info("Verify disallow_aps clear")
988 dev
[0].request("SET disallow_aps ")
989 interworking_select(dev
[0], bssid
, "home", freq
="2412")
991 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
992 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
993 if "FAIL" not in ret
:
994 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
996 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
997 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
998 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
999 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1001 def policy_test(dev
, ap
, values
, only_one
=True):
1004 logger
.info("Verify network selection to AP " + ap
['ifname'])
1006 dev
.scan_for_bss(bssid
, freq
="2412")
1008 logger
.info("Verify network selection")
1011 id = dev
.add_cred_values(values
)
1012 dev
.request("INTERWORKING_SELECT auto freq=2412")
1015 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1016 "INTERWORKING-BLACKLISTED",
1017 "INTERWORKING-SELECTED"], timeout
=15)
1019 raise Exception("Network selection timed out")
1021 if "INTERWORKING-NO-MATCH" in ev
:
1022 raise Exception("Matching AP not found")
1023 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1024 raise Exception("Unexpected AP claimed acceptable")
1025 if "INTERWORKING-SELECTED" in ev
:
1026 if bssid
and bssid
not in ev
:
1027 raise Exception("Selected incorrect BSS")
1030 ev
= dev
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1032 raise Exception("Connection timed out")
1033 if bssid
and bssid
not in ev
:
1034 raise Exception("Connected to incorrect BSS")
1036 conn_bssid
= dev
.get_status_field("bssid")
1037 if bssid
and conn_bssid
!= bssid
:
1038 raise Exception("bssid information points to incorrect BSS")
1044 def default_cred(domain
=None):
1045 cred
= { 'realm': "example.com",
1046 'username': "hs20-test",
1047 'password': "password" }
1049 cred
['domain'] = domain
1052 def test_ap_hs20_prefer_home(dev
, apdev
):
1053 """Hotspot 2.0 required roaming consortium"""
1054 params
= hs20_ap_params()
1055 params
['domain_name'] = "example.org"
1056 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1058 params
= hs20_ap_params()
1059 params
['ssid'] = "test-hs20-other"
1060 params
['domain_name'] = "example.com"
1061 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1063 values
= default_cred()
1064 values
['domain'] = "example.com"
1065 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1066 values
['domain'] = "example.org"
1067 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1069 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1070 """Hotspot 2.0 required roaming consortium"""
1071 params
= hs20_ap_params()
1072 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1074 params
= hs20_ap_params()
1075 params
['ssid'] = "test-hs20-other"
1076 params
['roaming_consortium'] = [ "223344" ]
1077 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1079 values
= default_cred()
1080 values
['required_roaming_consortium'] = "223344"
1081 policy_test(dev
[0], apdev
[1], values
)
1082 values
['required_roaming_consortium'] = "112233"
1083 policy_test(dev
[0], apdev
[0], values
)
1085 id = dev
[0].add_cred()
1086 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1087 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1089 for val
in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1090 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1091 raise Exception("Invalid roaming consortium value accepted: " + val
)
1093 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1094 """Hotspot 2.0 exclusion based on SSID"""
1095 params
= hs20_ap_params()
1096 params
['roaming_consortium'] = [ "223344" ]
1097 params
['anqp_3gpp_cell_net'] = "555,444"
1098 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1100 params
= hs20_ap_params()
1101 params
['ssid'] = "test-hs20-other"
1102 params
['roaming_consortium'] = [ "223344" ]
1103 params
['anqp_3gpp_cell_net'] = "555,444"
1104 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1106 values
= default_cred()
1107 values
['excluded_ssid'] = "test-hs20"
1108 events
= policy_test(dev
[0], apdev
[1], values
)
1109 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1111 raise Exception("Excluded network not reported")
1112 values
['excluded_ssid'] = "test-hs20-other"
1113 events
= policy_test(dev
[0], apdev
[0], values
)
1114 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1116 raise Exception("Excluded network not reported")
1118 values
= default_cred()
1119 values
['roaming_consortium'] = "223344"
1120 values
['eap'] = "TTLS"
1121 values
['phase2'] = "auth=MSCHAPV2"
1122 values
['excluded_ssid'] = "test-hs20"
1123 events
= policy_test(dev
[0], apdev
[1], values
)
1124 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1126 raise Exception("Excluded network not reported")
1128 values
= { 'imsi': "555444-333222111", 'eap': "SIM",
1129 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1130 'excluded_ssid': "test-hs20" }
1131 events
= policy_test(dev
[0], apdev
[1], values
)
1132 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1134 raise Exception("Excluded network not reported")
1136 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1137 """Hotspot 2.0 and roaming from current to higher priority network"""
1138 bssid
= apdev
[0]['bssid']
1139 params
= hs20_ap_params(ssid
="test-hs20-visited")
1140 params
['domain_name'] = "visited.example.org"
1141 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1143 dev
[0].hs20_enable()
1144 id = dev
[0].add_cred_values({ 'realm': "example.com",
1145 'username': "hs20-test",
1146 'password': "password",
1147 'domain': "example.com" })
1148 logger
.info("Connect to the only network option")
1149 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1150 dev
[0].dump_monitor()
1151 interworking_connect(dev
[0], bssid
, "TTLS")
1153 logger
.info("Start another AP (home operator) and reconnect")
1154 bssid2
= apdev
[1]['bssid']
1155 params
= hs20_ap_params(ssid
="test-hs20-home")
1156 params
['domain_name'] = "example.com"
1157 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1159 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1160 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1161 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1162 "INTERWORKING-ALREADY-CONNECTED",
1163 "CTRL-EVENT-CONNECTED"], timeout
=15)
1165 raise Exception("Connection timed out")
1166 if "INTERWORKING-NO-MATCH" in ev
:
1167 raise Exception("Matching AP not found")
1168 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1169 raise Exception("Unexpected AP selected")
1170 if bssid2
not in ev
:
1171 raise Exception("Unexpected BSSID after reconnection")
1173 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1174 """Hotspot 2.0 and domain_suffix_match"""
1175 bssid
= apdev
[0]['bssid']
1176 params
= hs20_ap_params()
1177 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1179 dev
[0].hs20_enable()
1180 id = dev
[0].add_cred_values({ 'realm': "example.com",
1181 'username': "hs20-test",
1182 'password': "password",
1183 'domain': "example.com",
1184 'domain_suffix_match': "w1.fi" })
1185 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1186 dev
[0].dump_monitor()
1187 interworking_connect(dev
[0], bssid
, "TTLS")
1188 dev
[0].request("REMOVE_NETWORK all")
1189 dev
[0].dump_monitor()
1191 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1192 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1193 dev
[0].dump_monitor()
1194 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1195 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1197 raise Exception("TLS certificate error not reported")
1198 if "Domain suffix mismatch" not in ev
:
1199 raise Exception("Domain suffix mismatch not reported")
1201 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1202 """Hotspot 2.0 and roaming partner preference"""
1203 params
= hs20_ap_params()
1204 params
['domain_name'] = "roaming.example.org"
1205 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1207 params
= hs20_ap_params()
1208 params
['ssid'] = "test-hs20-other"
1209 params
['domain_name'] = "roaming.example.net"
1210 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1212 logger
.info("Verify default vs. specified preference")
1213 values
= default_cred()
1214 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1215 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1216 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1217 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1219 logger
.info("Verify partial FQDN match")
1220 values
['roaming_partner'] = "example.net,0,0,*"
1221 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1222 values
['roaming_partner'] = "example.net,0,255,*"
1223 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1225 def test_ap_hs20_max_bss_load(dev
, apdev
):
1226 """Hotspot 2.0 and maximum BSS load"""
1227 params
= hs20_ap_params()
1228 params
['bss_load_test'] = "12:200:20000"
1229 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1231 params
= hs20_ap_params()
1232 params
['ssid'] = "test-hs20-other"
1233 params
['bss_load_test'] = "5:20:10000"
1234 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1236 logger
.info("Verify maximum BSS load constraint")
1237 values
= default_cred()
1238 values
['domain'] = "example.com"
1239 values
['max_bss_load'] = "100"
1240 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1242 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1243 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1244 raise Exception("Maximum BSS Load case not noticed")
1245 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1246 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1247 raise Exception("Maximum BSS Load case reported incorrectly")
1249 logger
.info("Verify maximum BSS load does not prevent connection")
1250 values
['max_bss_load'] = "1"
1251 events
= policy_test(dev
[0], None, values
)
1253 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1254 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1255 raise Exception("Maximum BSS Load case not noticed")
1256 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1257 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1258 raise Exception("Maximum BSS Load case not noticed")
1260 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1261 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1262 params
= hs20_ap_params()
1263 params
['bss_load_test'] = "12:200:20000"
1264 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1266 params
= hs20_ap_params()
1267 params
['ssid'] = "test-hs20-other"
1268 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1270 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1271 values
= default_cred()
1272 values
['domain'] = "example.com"
1273 values
['max_bss_load'] = "100"
1274 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1276 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1277 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1278 raise Exception("Maximum BSS Load case not noticed")
1279 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1280 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1281 raise Exception("Maximum BSS Load case reported incorrectly")
1283 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1284 """Hotspot 2.0 multi-cred sp_priority"""
1286 return _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1288 dev
[0].request("SET external_sim 0")
1290 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1291 if not hlr_auc_gw_available():
1293 bssid
= apdev
[0]['bssid']
1294 params
= hs20_ap_params()
1295 params
['hessid'] = bssid
1296 del params
['domain_name']
1297 params
['anqp_3gpp_cell_net'] = "232,01"
1298 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1300 dev
[0].hs20_enable()
1301 dev
[0].scan_for_bss(bssid
, freq
="2412")
1302 dev
[0].request("SET external_sim 1")
1303 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1304 'provisioning_sp': "example.com",
1305 'sp_priority' :"1" })
1306 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1307 'username': "hs20-test",
1308 'password': "password",
1309 'domain': "example.com",
1310 'provisioning_sp': "example.com",
1311 'sp_priority': "2" })
1312 dev
[0].dump_monitor()
1313 dev
[0].scan_for_bss(bssid
, freq
="2412")
1314 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1315 interworking_ext_sim_auth(dev
[0], "SIM")
1316 check_sp_type(dev
[0], "unknown")
1317 dev
[0].request("REMOVE_NETWORK all")
1319 dev
[0].set_cred(id1
, "sp_priority", "2")
1320 dev
[0].set_cred(id2
, "sp_priority", "1")
1321 dev
[0].dump_monitor()
1322 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1323 interworking_auth(dev
[0], "TTLS")
1324 check_sp_type(dev
[0], "unknown")
1326 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1327 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1329 return _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
1331 dev
[0].request("SET external_sim 0")
1333 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1334 if not hlr_auc_gw_available():
1336 bssid
= apdev
[0]['bssid']
1337 params
= hs20_ap_params()
1338 params
['hessid'] = bssid
1339 del params
['nai_realm']
1340 del params
['domain_name']
1341 params
['anqp_3gpp_cell_net'] = "232,01"
1342 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1344 bssid2
= apdev
[1]['bssid']
1345 params
= hs20_ap_params()
1346 params
['ssid'] = "test-hs20-other"
1347 params
['hessid'] = bssid2
1348 del params
['domain_name']
1349 del params
['anqp_3gpp_cell_net']
1350 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1352 dev
[0].hs20_enable()
1353 dev
[0].request("SET external_sim 1")
1354 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1355 'provisioning_sp': "example.com",
1356 'sp_priority': "1" })
1357 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1358 'username': "hs20-test",
1359 'password': "password",
1360 'domain': "example.com",
1361 'provisioning_sp': "example.com",
1362 'sp_priority': "2" })
1363 dev
[0].dump_monitor()
1364 dev
[0].scan_for_bss(bssid
, freq
="2412")
1365 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1366 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1367 interworking_ext_sim_auth(dev
[0], "SIM")
1368 check_sp_type(dev
[0], "unknown")
1369 conn_bssid
= dev
[0].get_status_field("bssid")
1370 if conn_bssid
!= bssid
:
1371 raise Exception("Connected to incorrect BSS")
1372 dev
[0].request("REMOVE_NETWORK all")
1374 dev
[0].set_cred(id1
, "sp_priority", "2")
1375 dev
[0].set_cred(id2
, "sp_priority", "1")
1376 dev
[0].dump_monitor()
1377 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1378 interworking_auth(dev
[0], "TTLS")
1379 check_sp_type(dev
[0], "unknown")
1380 conn_bssid
= dev
[0].get_status_field("bssid")
1381 if conn_bssid
!= bssid2
:
1382 raise Exception("Connected to incorrect BSS")
1384 def check_conn_capab_selection(dev
, type, missing
):
1385 dev
.request("INTERWORKING_SELECT freq=2412")
1386 ev
= dev
.wait_event(["INTERWORKING-AP"])
1388 raise Exception("Network selection timed out");
1389 if "type=" + type not in ev
:
1390 raise Exception("Unexpected network type")
1391 if missing
and "conn_capab_missing=1" not in ev
:
1392 raise Exception("conn_capab_missing not reported")
1393 if not missing
and "conn_capab_missing=1" in ev
:
1394 raise Exception("conn_capab_missing reported unexpectedly")
1396 def conn_capab_cred(domain
=None, req_conn_capab
=None):
1397 cred
= default_cred(domain
=domain
)
1399 cred
['req_conn_capab'] = req_conn_capab
1402 def test_ap_hs20_req_conn_capab(dev
, apdev
):
1403 """Hotspot 2.0 network selection with req_conn_capab"""
1404 bssid
= apdev
[0]['bssid']
1405 params
= hs20_ap_params()
1406 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1408 dev
[0].hs20_enable()
1409 dev
[0].scan_for_bss(bssid
, freq
="2412")
1410 logger
.info("Not used in home network")
1411 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
1412 id = dev
[0].add_cred_values(values
)
1413 check_conn_capab_selection(dev
[0], "home", False)
1415 logger
.info("Used in roaming network")
1416 dev
[0].remove_cred(id)
1417 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
1418 id = dev
[0].add_cred_values(values
)
1419 check_conn_capab_selection(dev
[0], "roaming", True)
1421 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1422 check_auto_select(dev
[0], bssid
)
1424 logger
.info("Additional req_conn_capab checks")
1426 dev
[0].remove_cred(id)
1427 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
1428 id = dev
[0].add_cred_values(values
)
1429 check_conn_capab_selection(dev
[0], "roaming", True)
1431 dev
[0].remove_cred(id)
1432 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
1433 id = dev
[0].add_cred_values(values
)
1434 check_conn_capab_selection(dev
[0], "roaming", True)
1436 bssid2
= apdev
[1]['bssid']
1437 params
= hs20_ap_params(ssid
="test-hs20b")
1438 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1439 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1441 dev
[0].remove_cred(id)
1442 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
1443 id = dev
[0].add_cred_values(values
)
1444 dev
[0].set_cred(id, "req_conn_capab", "6:22")
1445 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1446 dev
[0].request("INTERWORKING_SELECT freq=2412")
1447 for i
in range(0, 2):
1448 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
1450 raise Exception("Network selection timed out");
1451 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
1452 raise Exception("Missing protocol connection capability not reported")
1453 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
1454 raise Exception("Protocol connection capability not reported correctly")
1456 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
1457 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1458 bssid
= apdev
[0]['bssid']
1459 params
= hs20_ap_params()
1460 params
['domain_name'] = "roaming.example.org"
1461 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1462 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1464 bssid2
= apdev
[1]['bssid']
1465 params
= hs20_ap_params(ssid
="test-hs20-b")
1466 params
['domain_name'] = "roaming.example.net"
1467 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1469 values
= default_cred()
1470 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1471 id = dev
[0].add_cred_values(values
)
1472 check_auto_select(dev
[0], bssid2
)
1474 dev
[0].set_cred(id, "req_conn_capab", "50")
1475 check_auto_select(dev
[0], bssid
)
1477 dev
[0].remove_cred(id)
1478 id = dev
[0].add_cred_values(values
)
1479 dev
[0].set_cred(id, "req_conn_capab", "51")
1480 check_auto_select(dev
[0], bssid2
)
1482 def check_bandwidth_selection(dev
, type, below
):
1483 dev
.request("INTERWORKING_SELECT freq=2412")
1484 ev
= dev
.wait_event(["INTERWORKING-AP"])
1486 raise Exception("Network selection timed out");
1487 if "type=" + type not in ev
:
1488 raise Exception("Unexpected network type")
1489 if below
and "below_min_backhaul=1" not in ev
:
1490 raise Exception("below_min_backhaul not reported")
1491 if not below
and "below_min_backhaul=1" in ev
:
1492 raise Exception("below_min_backhaul reported unexpectedly")
1494 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
1495 cred
= default_cred(domain
=domain
)
1497 cred
['min_dl_bandwidth_home'] = str(dl_home
)
1499 cred
['min_ul_bandwidth_home'] = str(ul_home
)
1501 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
1503 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
1506 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
1507 """Hotspot 2.0 network selection with min bandwidth (home)"""
1508 bssid
= apdev
[0]['bssid']
1509 params
= hs20_ap_params()
1510 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1512 dev
[0].hs20_enable()
1513 dev
[0].scan_for_bss(bssid
, freq
="2412")
1514 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1515 id = dev
[0].add_cred_values(values
)
1516 check_bandwidth_selection(dev
[0], "home", False)
1517 dev
[0].remove_cred(id)
1519 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1520 id = dev
[0].add_cred_values(values
)
1521 check_bandwidth_selection(dev
[0], "home", True)
1522 dev
[0].remove_cred(id)
1524 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1525 id = dev
[0].add_cred_values(values
)
1526 check_bandwidth_selection(dev
[0], "home", True)
1527 dev
[0].remove_cred(id)
1529 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1530 id = dev
[0].add_cred_values(values
)
1531 check_bandwidth_selection(dev
[0], "home", True)
1532 check_auto_select(dev
[0], bssid
)
1534 bssid2
= apdev
[1]['bssid']
1535 params
= hs20_ap_params(ssid
="test-hs20-b")
1536 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1537 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1539 check_auto_select(dev
[0], bssid2
)
1541 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
1542 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1543 bssid
= apdev
[0]['bssid']
1544 params
= hs20_ap_params()
1545 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1547 dev
[0].hs20_enable()
1548 dev
[0].scan_for_bss(bssid
, freq
="2412")
1549 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
1550 id = dev
[0].add_cred_values(values
)
1551 check_bandwidth_selection(dev
[0], "roaming", False)
1552 dev
[0].remove_cred(id)
1554 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
1555 id = dev
[0].add_cred_values(values
)
1556 check_bandwidth_selection(dev
[0], "roaming", True)
1557 dev
[0].remove_cred(id)
1559 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
1560 id = dev
[0].add_cred_values(values
)
1561 check_bandwidth_selection(dev
[0], "roaming", True)
1562 dev
[0].remove_cred(id)
1564 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
1565 id = dev
[0].add_cred_values(values
)
1566 check_bandwidth_selection(dev
[0], "roaming", True)
1567 check_auto_select(dev
[0], bssid
)
1569 bssid2
= apdev
[1]['bssid']
1570 params
= hs20_ap_params(ssid
="test-hs20-b")
1571 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1572 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1574 check_auto_select(dev
[0], bssid2
)
1576 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
1577 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1578 bssid
= apdev
[0]['bssid']
1579 params
= hs20_ap_params()
1580 params
['domain_name'] = "roaming.example.org"
1581 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1582 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1584 bssid2
= apdev
[1]['bssid']
1585 params
= hs20_ap_params(ssid
="test-hs20-b")
1586 params
['domain_name'] = "roaming.example.net"
1587 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1589 values
= default_cred()
1590 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1591 id = dev
[0].add_cred_values(values
)
1592 check_auto_select(dev
[0], bssid2
)
1594 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1595 check_auto_select(dev
[0], bssid
)
1597 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1598 check_auto_select(dev
[0], bssid2
)
1600 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
1601 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1602 bssid
= apdev
[0]['bssid']
1603 params
= hs20_ap_params()
1604 del params
['hs20_wan_metrics']
1605 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1607 dev
[0].hs20_enable()
1608 dev
[0].scan_for_bss(bssid
, freq
="2412")
1609 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
1610 dl_roaming
=10000, ul_roaming
=10000)
1611 dev
[0].add_cred_values(values
)
1612 check_bandwidth_selection(dev
[0], "home", False)
1614 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
1615 """Hotspot 2.0 connection and deauthentication request for ESS"""
1617 _test_ap_hs20_deauth_req_ess(dev
, apdev
)
1619 dev
[0].request("SET pmf 0")
1621 def _test_ap_hs20_deauth_req_ess(dev
, apdev
):
1622 dev
[0].request("SET pmf 2")
1623 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1624 dev
[0].dump_monitor()
1625 addr
= dev
[0].p2p_interface_addr()
1626 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1627 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
1628 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1630 raise Exception("Timeout on deauth imminent notice")
1631 if "1 120 http://example.com/" not in ev
:
1632 raise Exception("Unexpected deauth imminent notice: " + ev
)
1633 hapd
.request("DEAUTHENTICATE " + addr
)
1634 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1636 raise Exception("Timeout on disconnection")
1637 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1638 raise Exception("Network not marked temporarily disabled")
1639 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1640 "Trying to associate",
1641 "CTRL-EVENT-CONNECTED"], timeout
=5)
1643 raise Exception("Unexpected connection attempt")
1645 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
1646 """Hotspot 2.0 connection and deauthentication request for BSS"""
1648 _test_ap_hs20_deauth_req_bss(dev
, apdev
)
1650 dev
[0].request("SET pmf 0")
1652 def _test_ap_hs20_deauth_req_bss(dev
, apdev
):
1653 dev
[0].request("SET pmf 2")
1654 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1655 dev
[0].dump_monitor()
1656 addr
= dev
[0].p2p_interface_addr()
1657 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1658 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
1659 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1661 raise Exception("Timeout on deauth imminent notice")
1662 if "0 120 http://example.com/" not in ev
:
1663 raise Exception("Unexpected deauth imminent notice: " + ev
)
1664 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
1665 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1667 raise Exception("Timeout on disconnection")
1668 if "reason=4" not in ev
:
1669 raise Exception("Unexpected disconnection reason")
1670 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1671 raise Exception("Network not marked temporarily disabled")
1672 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1673 "Trying to associate",
1674 "CTRL-EVENT-CONNECTED"], timeout
=5)
1676 raise Exception("Unexpected connection attempt")
1678 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1679 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1681 _test_ap_hs20_deauth_req_from_radius(dev
, apdev
)
1683 dev
[0].request("SET pmf 0")
1685 def _test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1686 bssid
= apdev
[0]['bssid']
1687 params
= hs20_ap_params()
1688 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1689 params
['hs20_deauth_req_timeout'] = "2"
1690 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1692 dev
[0].request("SET pmf 2")
1693 dev
[0].hs20_enable()
1694 dev
[0].add_cred_values({ 'realm': "example.com",
1695 'username': "hs20-deauth-test",
1696 'password': "password" })
1697 interworking_select(dev
[0], bssid
, freq
="2412")
1698 interworking_connect(dev
[0], bssid
, "TTLS")
1699 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
1701 raise Exception("Timeout on deauth imminent notice")
1702 if " 1 100" not in ev
:
1703 raise Exception("Unexpected deauth imminent contents")
1704 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=3)
1706 raise Exception("Timeout on disconnection")
1708 def test_ap_hs20_remediation_required(dev
, apdev
):
1709 """Hotspot 2.0 connection and remediation required from RADIUS"""
1711 _test_ap_hs20_remediation_required(dev
, apdev
)
1713 dev
[0].request("SET pmf 0")
1715 def _test_ap_hs20_remediation_required(dev
, apdev
):
1716 bssid
= apdev
[0]['bssid']
1717 params
= hs20_ap_params()
1718 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1719 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1721 dev
[0].request("SET pmf 1")
1722 dev
[0].hs20_enable()
1723 dev
[0].add_cred_values({ 'realm': "example.com",
1724 'username': "hs20-subrem-test",
1725 'password': "password" })
1726 interworking_select(dev
[0], bssid
, freq
="2412")
1727 interworking_connect(dev
[0], bssid
, "TTLS")
1728 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1730 raise Exception("Timeout on subscription remediation notice")
1731 if " 1 https://example.com/" not in ev
:
1732 raise Exception("Unexpected subscription remediation event contents")
1734 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1735 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1737 _test_ap_hs20_remediation_required_ctrl(dev
, apdev
)
1739 dev
[0].request("SET pmf 0")
1741 def _test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1742 bssid
= apdev
[0]['bssid']
1743 addr
= dev
[0].p2p_dev_addr()
1744 params
= hs20_ap_params()
1745 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1746 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
1748 dev
[0].request("SET pmf 1")
1749 dev
[0].hs20_enable()
1750 dev
[0].add_cred_values(default_cred())
1751 interworking_select(dev
[0], bssid
, freq
="2412")
1752 interworking_connect(dev
[0], bssid
, "TTLS")
1754 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
1755 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1757 raise Exception("Timeout on subscription remediation notice")
1758 if " 1 https://example.com/" not in ev
:
1759 raise Exception("Unexpected subscription remediation event contents")
1761 hapd
.request("HS20_WNM_NOTIF " + addr
)
1762 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1764 raise Exception("Timeout on subscription remediation notice")
1765 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1766 raise Exception("Unexpected subscription remediation event contents: " + ev
)
1768 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
1769 raise Exception("Unexpected HS20_WNM_NOTIF success")
1770 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
1771 raise Exception("Unexpected HS20_WNM_NOTIF success")
1772 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1773 raise Exception("Unexpected HS20_WNM_NOTIF success")
1775 def test_ap_hs20_session_info(dev
, apdev
):
1776 """Hotspot 2.0 connection and session information from RADIUS"""
1778 _test_ap_hs20_session_info(dev
, apdev
)
1780 dev
[0].request("SET pmf 0")
1782 def _test_ap_hs20_session_info(dev
, apdev
):
1783 bssid
= apdev
[0]['bssid']
1784 params
= hs20_ap_params()
1785 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1786 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1788 dev
[0].request("SET pmf 1")
1789 dev
[0].hs20_enable()
1790 dev
[0].add_cred_values({ 'realm': "example.com",
1791 'username': "hs20-session-info-test",
1792 'password': "password" })
1793 interworking_select(dev
[0], bssid
, freq
="2412")
1794 interworking_connect(dev
[0], bssid
, "TTLS")
1795 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
1797 raise Exception("Timeout on ESS disassociation imminent notice")
1798 if " 1 59904 https://example.com/" not in ev
:
1799 raise Exception("Unexpected ESS disassociation imminent event contents")
1800 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1802 raise Exception("Scan not started")
1803 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
1805 raise Exception("Scan not completed")
1807 def test_ap_hs20_osen(dev
, apdev
):
1808 """Hotspot 2.0 OSEN connection"""
1809 params
= { 'ssid': "osen",
1811 'auth_server_addr': "127.0.0.1",
1812 'auth_server_port': "1812",
1813 'auth_server_shared_secret': "radius" }
1814 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1816 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
1818 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
1819 scan_freq
="2412", wait_connect
=False)
1820 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1821 group
="GTK_NOT_USED",
1822 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1823 ca_cert
="auth_serv/ca.pem",
1826 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
1827 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
1828 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1829 group
="GTK_NOT_USED",
1830 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1831 ca_cert
="auth_serv/ca.pem",
1833 wpas
.request("DISCONNECT")
1835 def test_ap_hs20_network_preference(dev
, apdev
):
1836 """Hotspot 2.0 network selection with preferred home network"""
1837 bssid
= apdev
[0]['bssid']
1838 params
= hs20_ap_params()
1839 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1841 dev
[0].hs20_enable()
1842 values
= { 'realm': "example.com",
1843 'username': "hs20-test",
1844 'password': "password",
1845 'domain': "example.com" }
1846 dev
[0].add_cred_values(values
)
1848 id = dev
[0].add_network()
1849 dev
[0].set_network_quoted(id, "ssid", "home")
1850 dev
[0].set_network_quoted(id, "psk", "12345678")
1851 dev
[0].set_network(id, "priority", "1")
1852 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1854 dev
[0].scan_for_bss(bssid
, freq
="2412")
1855 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1856 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1858 raise Exception("Connection timed out")
1860 raise Exception("Unexpected network selected")
1862 bssid2
= apdev
[1]['bssid']
1863 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1864 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1866 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1867 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1868 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1869 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1871 raise Exception("Connection timed out")
1872 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1873 raise Exception("No roam to higher priority network")
1874 if bssid2
not in ev
:
1875 raise Exception("Unexpected network selected")
1877 def test_ap_hs20_network_preference2(dev
, apdev
):
1878 """Hotspot 2.0 network selection with preferred credential"""
1879 bssid2
= apdev
[1]['bssid']
1880 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1881 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1883 dev
[0].hs20_enable()
1884 values
= { 'realm': "example.com",
1885 'username': "hs20-test",
1886 'password': "password",
1887 'domain': "example.com",
1889 dev
[0].add_cred_values(values
)
1891 id = dev
[0].add_network()
1892 dev
[0].set_network_quoted(id, "ssid", "home")
1893 dev
[0].set_network_quoted(id, "psk", "12345678")
1894 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1896 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1897 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1898 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1900 raise Exception("Connection timed out")
1901 if bssid2
not in ev
:
1902 raise Exception("Unexpected network selected")
1904 bssid
= apdev
[0]['bssid']
1905 params
= hs20_ap_params()
1906 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1908 dev
[0].scan_for_bss(bssid
, freq
="2412")
1909 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1910 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1911 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1913 raise Exception("Connection timed out")
1914 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1915 raise Exception("No roam to higher priority network")
1917 raise Exception("Unexpected network selected")
1919 def test_ap_hs20_network_preference3(dev
, apdev
):
1920 """Hotspot 2.0 network selection with two credential (one preferred)"""
1921 bssid
= apdev
[0]['bssid']
1922 params
= hs20_ap_params()
1923 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1925 bssid2
= apdev
[1]['bssid']
1926 params
= hs20_ap_params(ssid
="test-hs20b")
1927 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
1928 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1930 dev
[0].hs20_enable()
1931 values
= { 'realm': "example.com",
1932 'username': "hs20-test",
1933 'password': "password",
1935 dev
[0].add_cred_values(values
)
1936 values
= { 'realm': "example.org",
1937 'username': "hs20-test",
1938 'password': "password" }
1939 id = dev
[0].add_cred_values(values
)
1941 dev
[0].scan_for_bss(bssid
, freq
="2412")
1942 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1943 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1944 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1946 raise Exception("Connection timed out")
1948 raise Exception("Unexpected network selected")
1950 dev
[0].set_cred(id, "priority", "2")
1951 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1952 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1953 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1955 raise Exception("Connection timed out")
1956 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1957 raise Exception("No roam to higher priority network")
1958 if bssid2
not in ev
:
1959 raise Exception("Unexpected network selected")
1961 def test_ap_hs20_network_preference4(dev
, apdev
):
1962 """Hotspot 2.0 network selection with username vs. SIM credential"""
1963 bssid
= apdev
[0]['bssid']
1964 params
= hs20_ap_params()
1965 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1967 bssid2
= apdev
[1]['bssid']
1968 params
= hs20_ap_params(ssid
="test-hs20b")
1969 params
['hessid'] = bssid2
1970 params
['anqp_3gpp_cell_net'] = "555,444"
1971 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1972 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1974 dev
[0].hs20_enable()
1975 values
= { 'realm': "example.com",
1976 'username': "hs20-test",
1977 'password': "password",
1979 dev
[0].add_cred_values(values
)
1980 values
= { 'imsi': "555444-333222111",
1982 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1983 id = dev
[0].add_cred_values(values
)
1985 dev
[0].scan_for_bss(bssid
, freq
="2412")
1986 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1987 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1988 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1990 raise Exception("Connection timed out")
1992 raise Exception("Unexpected network selected")
1994 dev
[0].set_cred(id, "priority", "2")
1995 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1996 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1997 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1999 raise Exception("Connection timed out")
2000 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2001 raise Exception("No roam to higher priority network")
2002 if bssid2
not in ev
:
2003 raise Exception("Unexpected network selected")
2005 def test_ap_hs20_fetch_osu(dev
, apdev
):
2006 """Hotspot 2.0 OSU provider and icon fetch"""
2007 bssid
= apdev
[0]['bssid']
2008 params
= hs20_ap_params()
2009 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2010 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2011 params
['osu_method_list'] = "1"
2012 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2013 params
['osu_icon'] = "w1fi_logo"
2014 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2015 params
['osu_server_uri'] = "https://example.com/osu/"
2016 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2018 bssid2
= apdev
[1]['bssid']
2019 params
= hs20_ap_params(ssid
="test-hs20b")
2020 params
['hessid'] = bssid2
2021 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2022 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2023 params
['osu_method_list'] = "0"
2024 params
['osu_nai'] = "osen@example.com"
2025 params
['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
2026 params
['osu_icon'] = "w1fi_logo"
2027 params
['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
2028 params
['osu_server_uri'] = "https://example.org/osu/"
2029 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2031 with
open("w1fi_logo.png", "r") as f
:
2032 orig_logo
= f
.read()
2033 dev
[0].hs20_enable()
2034 dir = "/tmp/osu-fetch"
2035 if os
.path
.isdir(dir):
2036 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2038 os
.remove(dir + "/" + f
)
2045 dev
[1].scan_for_bss(bssid
, freq
="2412")
2046 dev
[0].request("SET osu_dir " + dir)
2047 dev
[0].request("FETCH_OSU")
2048 if "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2049 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2050 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2051 raise Exception("HS20_ICON_REQUEST failed")
2054 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2055 "RX-HS20-ANQP-ICON"], timeout
=15)
2057 raise Exception("Timeout on OSU fetch")
2058 if "OSU provider fetch completed" in ev
:
2060 if "RX-HS20-ANQP-ICON" in ev
:
2061 with
open(ev
.split(' ')[1], "r") as f
:
2063 if logo
== orig_logo
:
2066 with
open(dir + "/osu-providers.txt", "r") as f
:
2068 if "OSU-PROVIDER " + bssid
not in prov
:
2069 raise Exception("Missing OSU_PROVIDER")
2070 if "OSU-PROVIDER " + bssid2
not in prov
:
2071 raise Exception("Missing OSU_PROVIDER")
2073 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2075 os
.remove(dir + "/" + f
)
2079 raise Exception("Unexpected number of icons fetched")
2081 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2083 raise Exception("Timeout on GAS-QUERY-DONE")
2084 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2086 raise Exception("Timeout on GAS-QUERY-DONE")
2087 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2088 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2089 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2091 raise Exception("Timeout on icon fetch")
2092 if "Icon Binary File" not in ev
:
2093 raise Exception("Unexpected ANQP element")
2095 def test_ap_hs20_fetch_osu_stop(dev
, apdev
):
2096 """Hotspot 2.0 OSU provider fetch stopped"""
2097 bssid
= apdev
[0]['bssid']
2098 params
= hs20_ap_params()
2099 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2100 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2101 params
['osu_method_list'] = "1"
2102 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2103 params
['osu_icon'] = "w1fi_logo"
2104 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2105 params
['osu_server_uri'] = "https://example.com/osu/"
2106 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2108 dev
[0].hs20_enable()
2109 dir = "/tmp/osu-fetch"
2110 if os
.path
.isdir(dir):
2111 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2113 os
.remove(dir + "/" + f
)
2120 dev
[0].request("SET osu_dir " + dir)
2121 dev
[0].request("SCAN freq=2412-2462")
2122 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=10)
2124 raise Exception("Scan did not start")
2125 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2126 raise Exception("FETCH_OSU accepted while scanning")
2127 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
2129 raise Exception("Scan timed out")
2130 hapd
.set("ext_mgmt_frame_handling", "1")
2131 dev
[0].request("FETCH_ANQP")
2132 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2133 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
2134 dev
[0].request("STOP_FETCH_ANQP")
2135 dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2136 dev
[0].dump_monitor()
2138 dev
[0].request("INTERWORKING_SELECT freq=2412")
2140 msg
= hapd
.mgmt_rx()
2141 if msg
['subtype'] == 13:
2143 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2144 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
2145 ev
= dev
[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
2148 raise Exception("Network selection timed out");
2150 dev
[0].dump_monitor()
2151 if "OK" not in dev
[0].request("FETCH_OSU"):
2152 raise Exception("FETCH_OSU failed")
2153 dev
[0].request("CANCEL_FETCH_OSU")
2157 if dev
[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
2160 dev
[0].dump_monitor()
2161 if "OK" not in dev
[0].request("FETCH_OSU"):
2162 raise Exception("FETCH_OSU failed")
2163 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2164 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2165 ev
= dev
[0].wait_event(["GAS-QUERY-START"], 10)
2167 raise Exception("GAS timed out")
2168 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2169 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2170 dev
[0].request("CANCEL_FETCH_OSU")
2171 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], 10)
2173 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
2175 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2177 os
.remove(dir + "/" + f
)
2180 def test_ap_hs20_ft(dev
, apdev
):
2181 """Hotspot 2.0 connection with FT"""
2182 bssid
= apdev
[0]['bssid']
2183 params
= hs20_ap_params()
2184 params
['wpa_key_mgmt'] = "FT-EAP"
2185 params
['nas_identifier'] = "nas1.w1.fi"
2186 params
['r1_key_holder'] = "000102030405"
2187 params
["mobility_domain"] = "a1b2"
2188 params
["reassociation_deadline"] = "1000"
2189 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2191 dev
[0].hs20_enable()
2192 id = dev
[0].add_cred_values({ 'realm': "example.com",
2193 'username': "hs20-test",
2194 'password': "password",
2195 'ca_cert': "auth_serv/ca.pem",
2196 'domain': "example.com",
2197 'update_identifier': "1234" })
2198 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2199 interworking_connect(dev
[0], bssid
, "TTLS")
2201 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
2202 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2207 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
2212 con
= sqlite3
.connect(dbfile
)
2215 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2216 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2217 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2218 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2219 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2222 params
= { "ssid": "as", "beacon_int": "2000",
2223 "radius_server_clients": "auth_serv/radius_clients.conf",
2224 "radius_server_auth_port": '18128',
2226 "eap_user_file": "sqlite:" + dbfile
,
2227 "ca_cert": "auth_serv/ca.pem",
2228 "server_cert": "auth_serv/server.pem",
2229 "private_key": "auth_serv/server.key",
2230 "subscr_remediation_url": "https://example.org/",
2231 "subscr_remediation_method": "1" }
2232 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2234 bssid
= apdev
[0]['bssid']
2235 params
= hs20_ap_params()
2236 params
['auth_server_port'] = "18128"
2237 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2239 dev
[0].request("SET pmf 1")
2240 dev
[0].hs20_enable()
2241 id = dev
[0].add_cred_values({ 'realm': "example.com",
2242 'username': "user-mschapv2",
2243 'password': "password",
2244 'ca_cert': "auth_serv/ca.pem" })
2245 interworking_select(dev
[0], bssid
, freq
="2412")
2246 interworking_connect(dev
[0], bssid
, "TTLS")
2247 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2249 raise Exception("Timeout on subscription remediation notice")
2250 if " 1 https://example.org/" not in ev
:
2251 raise Exception("Unexpected subscription remediation event contents")
2255 cur
.execute("SELECT * from authlog")
2256 rows
= cur
.fetchall()
2258 raise Exception("No authlog entries")
2262 dev
[0].request("SET pmf 0")
2264 def test_ap_hs20_external_selection(dev
, apdev
):
2265 """Hotspot 2.0 connection using external network selection and creation"""
2266 bssid
= apdev
[0]['bssid']
2267 params
= hs20_ap_params()
2268 params
['hessid'] = bssid
2269 params
['disable_dgaf'] = '1'
2270 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2272 dev
[0].hs20_enable()
2273 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
2274 identity
="hs20-test", password
="password",
2275 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2276 scan_freq
="2412", update_identifier
="54321")
2277 if dev
[0].get_status_field("hs20") != "2":
2278 raise Exception("Unexpected hs20 indication")
2280 def test_ap_hs20_random_mac_addr(dev
, apdev
):
2281 """Hotspot 2.0 connection with random MAC address"""
2282 bssid
= apdev
[0]['bssid']
2283 params
= hs20_ap_params()
2284 params
['hessid'] = bssid
2285 params
['disable_dgaf'] = '1'
2286 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2288 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2289 wpas
.interface_add("wlan5")
2290 addr
= wpas
.p2p_interface_addr()
2291 wpas
.request("SET mac_addr 1")
2292 wpas
.request("SET preassoc_mac_addr 1")
2293 wpas
.request("SET rand_addr_lifetime 60")
2295 wpas
.flush_scan_cache()
2296 id = wpas
.add_cred_values({ 'realm': "example.com",
2297 'username': "hs20-test",
2298 'password': "password",
2299 'ca_cert': "auth_serv/ca.pem",
2300 'domain': "example.com",
2301 'update_identifier': "1234" })
2302 interworking_select(wpas
, bssid
, "home", freq
="2412")
2303 interworking_connect(wpas
, bssid
, "TTLS")
2304 addr1
= wpas
.get_driver_status_field("addr")
2306 raise Exception("Did not use random MAC address")
2308 sta
= hapd
.get_sta(addr
)
2309 if sta
['addr'] != "FAIL":
2310 raise Exception("Unexpected STA association with permanent address")
2311 sta
= hapd
.get_sta(addr1
)
2312 if sta
['addr'] != addr1
:
2313 raise Exception("STA association with random address not found")
2315 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
2316 """Multiple networks and cred removal"""
2317 bssid
= apdev
[0]['bssid']
2318 params
= hs20_ap_params()
2319 params
['nai_realm'] = [ "0,example.com,25[3:26]"]
2320 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2322 dev
[0].add_network()
2323 dev
[0].hs20_enable()
2324 id = dev
[0].add_cred_values({ 'realm': "example.com",
2326 'password': "password" })
2327 interworking_select(dev
[0], bssid
, freq
="2412")
2328 interworking_connect(dev
[0], bssid
, "PEAP")
2329 dev
[0].add_network()
2331 dev
[0].request("DISCONNECT")
2332 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
2334 raise Exception("Timeout on disconnection")
2337 hapd
.set("ssid", "another ssid")
2340 interworking_select(dev
[0], bssid
, freq
="2412")
2341 interworking_connect(dev
[0], bssid
, "PEAP")
2342 dev
[0].add_network()
2343 if len(dev
[0].list_networks()) != 5:
2344 raise Exception("Unexpected number of networks prior to remove_crec")
2346 dev
[0].dump_monitor()
2347 dev
[0].remove_cred(id)
2348 if len(dev
[0].list_networks()) != 3:
2349 raise Exception("Unexpected number of networks after to remove_crec")
2350 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
2352 raise Exception("Timeout on disconnection")
2354 def _test_ap_hs20_proxyarp(dev
, apdev
):
2355 bssid
= apdev
[0]['bssid']
2356 params
= hs20_ap_params()
2357 params
['hessid'] = bssid
2358 params
['disable_dgaf'] = '0'
2359 params
['proxy_arp'] = '1'
2360 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2361 if "OK" in hapd
.request("ENABLE"):
2362 raise Exception("Incomplete hostapd configuration was accepted")
2363 hapd
.set("ap_isolate", "1")
2364 if "OK" in hapd
.request("ENABLE"):
2365 raise Exception("Incomplete hostapd configuration was accepted")
2366 hapd
.set('bridge', 'ap-br0')
2371 # For now, do not report failures due to missing kernel support
2372 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2374 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2376 raise Exception("AP startup timed out")
2377 if "AP-ENABLED" not in ev
:
2378 raise Exception("AP startup failed")
2380 dev
[0].hs20_enable()
2381 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2382 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2384 id = dev
[0].add_cred_values({ 'realm': "example.com",
2385 'username': "hs20-test",
2386 'password': "password",
2387 'ca_cert': "auth_serv/ca.pem",
2388 'domain': "example.com",
2389 'update_identifier': "1234" })
2390 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2391 interworking_connect(dev
[0], bssid
, "TTLS")
2393 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2394 identity
="hs20-test", password
="password",
2395 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2399 addr0
= dev
[0].p2p_interface_addr()
2400 addr1
= dev
[1].p2p_interface_addr()
2402 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2403 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2405 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2406 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2408 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2409 raise Exception("DATA_TEST_FRAME failed")
2411 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2412 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2414 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2415 raise Exception("DATA_TEST_FRAME failed")
2417 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2418 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2420 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2421 raise Exception("DATA_TEST_FRAME failed")
2423 matches
= get_permanent_neighbors("ap-br0")
2424 logger
.info("After connect: " + str(matches
))
2425 if len(matches
) != 3:
2426 raise Exception("Unexpected number of neighbor entries after connect")
2427 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2428 raise Exception("dev0 addr missing")
2429 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2430 raise Exception("dev1 addr(1) missing")
2431 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2432 raise Exception("dev1 addr(2) missing")
2433 dev
[0].request("DISCONNECT")
2434 dev
[1].request("DISCONNECT")
2436 matches
= get_permanent_neighbors("ap-br0")
2437 logger
.info("After disconnect: " + str(matches
))
2438 if len(matches
) > 0:
2439 raise Exception("Unexpected neighbor entries after disconnect")
2441 def test_ap_hs20_proxyarp(dev
, apdev
):
2442 """Hotspot 2.0 and ProxyARP"""
2445 res
= _test_ap_hs20_proxyarp(dev
, apdev
)
2447 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2448 stderr
=open('/dev/null', 'w'))
2449 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2450 stderr
=open('/dev/null', 'w'))
2454 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
2455 bssid
= apdev
[0]['bssid']
2456 params
= hs20_ap_params()
2457 params
['hessid'] = bssid
2458 params
['disable_dgaf'] = '1' if disabled
else '0'
2459 params
['proxy_arp'] = '1'
2460 params
['ap_isolate'] = '1'
2461 params
['bridge'] = 'ap-br0'
2462 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2466 # For now, do not report failures due to missing kernel support
2467 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2469 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
2471 raise Exception("AP startup timed out")
2473 dev
[0].hs20_enable()
2474 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2475 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2477 id = dev
[0].add_cred_values({ 'realm': "example.com",
2478 'username': "hs20-test",
2479 'password': "password",
2480 'ca_cert': "auth_serv/ca.pem",
2481 'domain': "example.com",
2482 'update_identifier': "1234" })
2483 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2484 interworking_connect(dev
[0], bssid
, "TTLS")
2486 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2487 identity
="hs20-test", password
="password",
2488 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2492 addr0
= dev
[0].p2p_interface_addr()
2494 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2496 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2497 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2499 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2500 raise Exception("DATA_TEST_FRAME failed")
2502 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
2504 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2505 raise Exception("DATA_TEST_FRAME failed")
2507 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
2508 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
2509 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2510 raise Exception("DATA_TEST_FRAME failed")
2512 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2513 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2514 yiaddr
="192.168.1.123", chaddr
=addr0
)
2515 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2516 raise Exception("DATA_TEST_FRAME failed")
2517 # another copy for additional code coverage
2518 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2519 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2520 yiaddr
="192.168.1.123", chaddr
=addr0
)
2521 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2522 raise Exception("DATA_TEST_FRAME failed")
2524 matches
= get_permanent_neighbors("ap-br0")
2525 logger
.info("After connect: " + str(matches
))
2526 if len(matches
) != 2:
2527 raise Exception("Unexpected number of neighbor entries after connect")
2528 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2529 raise Exception("dev0 addr missing")
2530 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2531 raise Exception("dev0 IPv4 addr missing")
2532 dev
[0].request("DISCONNECT")
2533 dev
[1].request("DISCONNECT")
2535 matches
= get_permanent_neighbors("ap-br0")
2536 logger
.info("After disconnect: " + str(matches
))
2537 if len(matches
) > 0:
2538 raise Exception("Unexpected neighbor entries after disconnect")
2540 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
2541 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
2544 res
= _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
2546 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2547 stderr
=open('/dev/null', 'w'))
2548 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2549 stderr
=open('/dev/null', 'w'))
2553 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
2554 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
2557 res
= _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
2559 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2560 stderr
=open('/dev/null', 'w'))
2561 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2562 stderr
=open('/dev/null', 'w'))
2566 def ip_checksum(buf
):
2570 for i
in range(0, len(buf
), 2):
2571 val
, = struct
.unpack('H', buf
[i
:i
+2])
2574 sum = (sum & 0xffff) + (sum >> 16)
2575 return struct
.pack('H', ~
sum & 0xffff)
2577 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
2578 start
= struct
.pack("BB", type, code
)
2580 icmp
= start
+ '\x00\x00' + end
2581 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
2582 csum
= ip_checksum(pseudo
+ icmp
)
2583 return start
+ csum
+ end
2585 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
2586 reachable_time
=0, retrans_timer
=0, opt
=None):
2587 link_mc
= binascii
.unhexlify("3333ff000002")
2588 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2590 ehdr
= link_mc
+ _src_ll
+ proto
2591 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2592 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2594 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
2595 reachable_time
, retrans_timer
)
2600 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
2602 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2603 ipv6
+= _ip_src
+ _ip_dst
2605 return ehdr
+ ipv6
+ icmp
2607 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2608 link_mc
= binascii
.unhexlify("3333ff000002")
2609 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2611 ehdr
= link_mc
+ _src_ll
+ proto
2612 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2613 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2615 reserved
= '\x00\x00\x00\x00'
2616 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2618 payload
= reserved
+ _target
+ opt
2620 payload
= reserved
+ _target
2621 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
2623 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2624 ipv6
+= _ip_src
+ _ip_dst
2626 return ehdr
+ ipv6
+ icmp
2628 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2629 link_mc
= binascii
.unhexlify("3333ff000002")
2630 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2632 ehdr
= link_mc
+ _src_ll
+ proto
2633 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2634 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2636 reserved
= '\x00\x00\x00\x00'
2637 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2639 payload
= reserved
+ _target
+ opt
2641 payload
= reserved
+ _target
2642 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
2644 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2645 ipv6
+= _ip_src
+ _ip_dst
2647 return ehdr
+ ipv6
+ icmp
2649 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
2650 subnet_mask
="255.255.255.0", truncated_opt
=False,
2651 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False):
2652 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2653 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2655 ehdr
= _dst_ll
+ _src_ll
+ proto
2656 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
2657 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
2658 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
2660 _ciaddr
= '\x00\x00\x00\x00'
2661 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
2662 _siaddr
= '\x00\x00\x00\x00'
2663 _giaddr
= '\x00\x00\x00\x00'
2664 _chaddr
= binascii
.unhexlify(chaddr
.replace(':','') + "00000000000000000000")
2665 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2666 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2669 payload
+= '\x63\x82\x53\x00'
2671 payload
+= '\x63\x82\x53\x63'
2673 payload
+= '\x22\xff\x00'
2674 # Option: DHCP Message Type = ACK
2675 payload
+= '\x35\x01\x05'
2678 # Option: Subnet Mask
2679 payload
+= '\x01\x04' + _subnet_mask
2680 # Option: Time Offset
2681 payload
+= struct
.pack('>BBL', 2, 4, 0)
2685 payload
+= '\x00\x00\x00\x00'
2688 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2689 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2691 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0) + payload
2694 tot_len
= force_tot_len
2696 tot_len
= 20 + len(udp
)
2697 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
2698 ipv4
= start
+ '\x00\x00' + _ip_src
+ _ip_dst
2699 csum
= ip_checksum(ipv4
)
2700 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
2702 return ehdr
+ ipv4
+ udp
2704 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
2705 target_mac
, target_ip
):
2706 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2707 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2709 ehdr
= _dst_ll
+ _src_ll
+ proto
2711 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':',''))
2712 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
2713 _target_mac
= binascii
.unhexlify(target_mac
.replace(':',''))
2714 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
2716 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
2717 arp
+= _sender_mac
+ _sender_ip
2718 arp
+= _target_mac
+ _target_ip
2722 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
2723 sender_mac
=None, sender_ip
="0.0.0.0",
2724 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
2729 if sender_mac
is None:
2730 sender_mac
= hapd_bssid
2731 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2734 src_ll
= dev
.p2p_interface_addr()
2735 if sender_mac
is None:
2736 sender_mac
= dev
.p2p_interface_addr()
2737 cmd
= "DATA_TEST_FRAME "
2739 pkt
= build_arp(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=src_ll
, opcode
=opcode
,
2740 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
2741 target_mac
=target_mac
, target_ip
=target_ip
)
2742 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2743 raise Exception("DATA_TEST_FRAME failed")
2745 def get_permanent_neighbors(ifname
):
2746 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
2747 res
= cmd
.stdout
.read()
2749 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
2751 def _test_proxyarp_open(dev
, apdev
, params
):
2752 cap_br
= os
.path
.join(params
['logdir'], "proxyarp_open.ap-br0.pcap")
2753 cap_dev0
= os
.path
.join(params
['logdir'], "proxyarp_open.%s.pcap" % dev
[0].ifname
)
2754 cap_dev1
= os
.path
.join(params
['logdir'], "proxyarp_open.%s.pcap" % dev
[1].ifname
)
2756 bssid
= apdev
[0]['bssid']
2757 params
= { 'ssid': 'open' }
2758 params
['proxy_arp'] = '1'
2759 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2760 hapd
.set("ap_isolate", "1")
2761 hapd
.set('bridge', 'ap-br0')
2766 # For now, do not report failures due to missing kernel support
2767 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2769 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2771 raise Exception("AP startup timed out")
2772 if "AP-ENABLED" not in ev
:
2773 raise Exception("AP startup failed")
2775 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2776 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2779 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
2780 '-w', cap_br
, '-s', '2000'],
2781 stderr
=open('/dev/null', 'w'))
2782 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
2783 '-w', cap_dev0
, '-s', '2000'],
2784 stderr
=open('/dev/null', 'w'))
2785 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
2786 '-w', cap_dev1
, '-s', '2000'],
2787 stderr
=open('/dev/null', 'w'))
2789 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2790 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2793 addr0
= dev
[0].p2p_interface_addr()
2794 addr1
= dev
[1].p2p_interface_addr()
2796 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2797 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2800 pkt
= build_ns(src_ll
=addr0
, ip_src
="::", ip_dst
="ff02::1:ff00:2",
2801 target
="aaaa:bbbb:cccc::2", opt
=src_ll_opt0
)
2802 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2803 raise Exception("DATA_TEST_FRAME failed")
2805 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2806 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2808 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2809 raise Exception("DATA_TEST_FRAME failed")
2810 # test frame without source link-layer address option
2811 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2812 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2")
2813 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2814 raise Exception("DATA_TEST_FRAME failed")
2815 # test frame with bogus option
2816 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2817 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2818 opt
="\x70\x01\x01\x02\x03\x04\x05\x05")
2819 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2820 raise Exception("DATA_TEST_FRAME failed")
2821 # test frame with truncated source link-layer address option
2822 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2823 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2824 opt
="\x01\x01\x01\x02\x03\x04")
2825 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2826 raise Exception("DATA_TEST_FRAME failed")
2827 # test frame with foreign source link-layer address option
2828 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2829 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2830 opt
="\x01\x01\x01\x02\x03\x04\x05\x06")
2831 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2832 raise Exception("DATA_TEST_FRAME failed")
2834 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2835 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2837 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2838 raise Exception("DATA_TEST_FRAME failed")
2840 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2841 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2843 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2844 raise Exception("DATA_TEST_FRAME failed")
2845 # another copy for additional code coverage
2846 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2847 raise Exception("DATA_TEST_FRAME failed")
2849 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2850 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2851 yiaddr
="192.168.1.124", chaddr
=addr0
)
2852 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2853 raise Exception("DATA_TEST_FRAME failed")
2854 # Change address and verify unicast
2855 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2856 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2857 yiaddr
="192.168.1.123", chaddr
=addr0
)
2858 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2859 raise Exception("DATA_TEST_FRAME failed")
2861 # Not-associated client MAC address
2862 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2863 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2864 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
2865 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2866 raise Exception("DATA_TEST_FRAME failed")
2869 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2870 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2871 yiaddr
="0.0.0.0", chaddr
=addr1
)
2872 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2873 raise Exception("DATA_TEST_FRAME failed")
2876 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2877 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2878 yiaddr
="192.168.1.126", chaddr
=addr1
,
2879 subnet_mask
="0.0.0.0")
2880 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2881 raise Exception("DATA_TEST_FRAME failed")
2884 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2885 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2886 yiaddr
="192.168.1.127", chaddr
=addr1
,
2888 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2889 raise Exception("DATA_TEST_FRAME failed")
2892 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2893 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2894 yiaddr
="192.168.1.128", chaddr
=addr1
,
2896 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2897 raise Exception("DATA_TEST_FRAME failed")
2899 # Wrong IPv4 total length
2900 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2901 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2902 yiaddr
="192.168.1.129", chaddr
=addr1
,
2904 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2905 raise Exception("DATA_TEST_FRAME failed")
2908 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2909 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2910 yiaddr
="192.168.1.129", chaddr
=addr1
,
2912 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2913 raise Exception("DATA_TEST_FRAME failed")
2915 matches
= get_permanent_neighbors("ap-br0")
2916 logger
.info("After connect: " + str(matches
))
2917 if len(matches
) != 4:
2918 raise Exception("Unexpected number of neighbor entries after connect")
2919 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2920 raise Exception("dev0 addr missing")
2921 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2922 raise Exception("dev1 addr(1) missing")
2923 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2924 raise Exception("dev1 addr(2) missing")
2925 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2926 raise Exception("dev0 IPv4 addr missing")
2928 targets
= [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
2930 for target
in targets
:
2931 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
2933 for target
in targets
:
2934 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
2937 # ARP Probe from wireless STA
2938 send_arp(dev
[1], target_ip
="192.168.1.127")
2939 # ARP Announcement from wireless STA
2940 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
2941 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
2944 matches
= get_permanent_neighbors("ap-br0")
2945 logger
.info("After ARP Probe + Announcement: " + str(matches
))
2947 # ARP Request for the newly introduced IP address from wireless STA
2948 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
2950 # ARP Request for the newly introduced IP address from bridge
2951 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
2952 target_ip
="192.168.1.127")
2954 # ARP Probe from bridge
2955 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.128")
2956 # ARP Announcement from bridge
2957 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="129.168.1.128",
2958 target_ip
="192.168.1.128")
2959 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="129.168.1.128",
2960 target_ip
="192.168.1.128", opcode
=2)
2962 matches
= get_permanent_neighbors("ap-br0")
2963 logger
.info("After ARP Probe + Announcement: " + str(matches
))
2965 # ARP Request for the newly introduced IP address from wireless STA
2966 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.128")
2968 # ARP Request for the newly introduced IP address from bridge
2969 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
2970 target_ip
="192.168.1.128")
2972 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
2973 send_arp(dev
[1], target_ip
="192.168.1.123")
2974 # ARP Probe from wireless STA (duplicate address; learned through ARP)
2975 send_arp(dev
[0], target_ip
="192.168.1.127")
2977 # Gratuitous ARP Reply for another STA's IP address
2978 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
2979 target_mac
=addr1
, target_ip
="192.168.1.127")
2980 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
2981 target_mac
=addr0
, target_ip
="192.168.1.123")
2982 # ARP Request to verify previous mapping
2983 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
2984 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
2988 dev
[0].request("DISCONNECT")
2989 dev
[1].request("DISCONNECT")
2993 matches
= get_permanent_neighbors("ap-br0")
2994 logger
.info("After disconnect: " + str(matches
))
2995 if len(matches
) > 0:
2996 raise Exception("Unexpected neighbor entries after disconnect")
2998 def test_proxyarp_open(dev
, apdev
, params
):
2999 """ProxyARP with open network"""
3002 res
= _test_proxyarp_open(dev
, apdev
, params
)
3004 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3005 stderr
=open('/dev/null', 'w'))
3006 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3007 stderr
=open('/dev/null', 'w'))