]>
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"""
859 bssid
= apdev
[0]['bssid']
860 params
= hs20_ap_params()
861 params
['hessid'] = bssid
862 hostapd
.add_ap(apdev
[0]['ifname'], params
)
864 bssid2
= apdev
[1]['bssid']
865 params
= hs20_ap_params()
866 params
['hessid'] = bssid2
867 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
868 hostapd
.add_ap(apdev
[1]['ifname'], params
)
871 dev
[0].request("SET pmf 2")
872 id = dev
[0].add_cred_values({ 'realm': "example.com",
873 'username': "hs20-test",
874 'password': "password",
875 'domain': "example.com" })
876 interworking_select(dev
[0], bssid
, "home", freq
="2412")
877 interworking_connect(dev
[0], bssid
, "TTLS")
879 logger
.info("Verifying GAS query while associated")
880 dev
[0].request("FETCH_ANQP")
881 for i
in range(0, 2 * 6):
882 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
884 raise Exception("Operation timed out")
886 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
887 """Hotspot 2.0 connection with fragmented GAS query while associated"""
888 bssid
= apdev
[0]['bssid']
889 params
= hs20_ap_params()
890 params
['hessid'] = bssid
891 hostapd
.add_ap(apdev
[0]['ifname'], params
)
892 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
893 hapd
.set("gas_frag_limit", "50")
896 id = dev
[0].add_cred_values({ 'realm': "example.com",
897 'username': "hs20-test",
898 'password': "password",
899 'domain': "example.com" })
900 interworking_select(dev
[0], bssid
, "home", freq
="2412")
901 interworking_connect(dev
[0], bssid
, "TTLS")
903 logger
.info("Verifying GAS query while associated")
904 dev
[0].request("FETCH_ANQP")
905 for i
in range(0, 6):
906 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
908 raise Exception("Operation timed out")
910 def test_ap_hs20_multiple_connects(dev
, apdev
):
911 """Hotspot 2.0 connection through multiple network selections"""
912 bssid
= apdev
[0]['bssid']
913 params
= hs20_ap_params()
914 params
['hessid'] = bssid
915 hostapd
.add_ap(apdev
[0]['ifname'], params
)
918 values
= { 'realm': "example.com",
919 'username': "hs20-test",
920 'password': "password",
921 'domain': "example.com" }
922 id = dev
[0].add_cred_values(values
)
924 dev
[0].scan_for_bss(bssid
, freq
="2412")
926 for i
in range(0, 3):
927 logger
.info("Starting Interworking network selection")
928 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
930 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
931 "INTERWORKING-ALREADY-CONNECTED",
932 "CTRL-EVENT-CONNECTED"], timeout
=15)
934 raise Exception("Connection timed out")
935 if "INTERWORKING-NO-MATCH" in ev
:
936 raise Exception("Matching AP not found")
937 if "CTRL-EVENT-CONNECTED" in ev
:
939 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
942 dev
[0].request("DISCONNECT")
943 dev
[0].dump_monitor()
945 networks
= dev
[0].list_networks()
946 if len(networks
) > 1:
947 raise Exception("Duplicated network block detected")
949 def test_ap_hs20_disallow_aps(dev
, apdev
):
950 """Hotspot 2.0 connection and disallow_aps"""
951 bssid
= apdev
[0]['bssid']
952 params
= hs20_ap_params()
953 params
['hessid'] = bssid
954 hostapd
.add_ap(apdev
[0]['ifname'], params
)
957 values
= { 'realm': "example.com",
958 'username': "hs20-test",
959 'password': "password",
960 'domain': "example.com" }
961 id = dev
[0].add_cred_values(values
)
963 dev
[0].scan_for_bss(bssid
, freq
="2412")
965 logger
.info("Verify disallow_aps bssid")
966 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
967 dev
[0].request("INTERWORKING_SELECT auto")
968 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
970 raise Exception("Network selection timed out")
971 dev
[0].dump_monitor()
973 logger
.info("Verify disallow_aps ssid")
974 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
975 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
976 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
978 raise Exception("Network selection timed out")
979 dev
[0].dump_monitor()
981 logger
.info("Verify disallow_aps clear")
982 dev
[0].request("SET disallow_aps ")
983 interworking_select(dev
[0], bssid
, "home", freq
="2412")
985 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
986 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
987 if "FAIL" not in ret
:
988 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
990 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
991 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
992 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
993 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
995 def policy_test(dev
, ap
, values
, only_one
=True):
998 logger
.info("Verify network selection to AP " + ap
['ifname'])
1000 dev
.scan_for_bss(bssid
, freq
="2412")
1002 logger
.info("Verify network selection")
1005 id = dev
.add_cred_values(values
)
1006 dev
.request("INTERWORKING_SELECT auto freq=2412")
1009 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1010 "INTERWORKING-BLACKLISTED",
1011 "INTERWORKING-SELECTED"], timeout
=15)
1013 raise Exception("Network selection timed out")
1015 if "INTERWORKING-NO-MATCH" in ev
:
1016 raise Exception("Matching AP not found")
1017 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1018 raise Exception("Unexpected AP claimed acceptable")
1019 if "INTERWORKING-SELECTED" in ev
:
1020 if bssid
and bssid
not in ev
:
1021 raise Exception("Selected incorrect BSS")
1024 ev
= dev
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1026 raise Exception("Connection timed out")
1027 if bssid
and bssid
not in ev
:
1028 raise Exception("Connected to incorrect BSS")
1030 conn_bssid
= dev
.get_status_field("bssid")
1031 if bssid
and conn_bssid
!= bssid
:
1032 raise Exception("bssid information points to incorrect BSS")
1038 def default_cred(domain
=None):
1039 cred
= { 'realm': "example.com",
1040 'username': "hs20-test",
1041 'password': "password" }
1043 cred
['domain'] = domain
1046 def test_ap_hs20_prefer_home(dev
, apdev
):
1047 """Hotspot 2.0 required roaming consortium"""
1048 params
= hs20_ap_params()
1049 params
['domain_name'] = "example.org"
1050 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1052 params
= hs20_ap_params()
1053 params
['ssid'] = "test-hs20-other"
1054 params
['domain_name'] = "example.com"
1055 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1057 values
= default_cred()
1058 values
['domain'] = "example.com"
1059 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1060 values
['domain'] = "example.org"
1061 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1063 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1064 """Hotspot 2.0 required roaming consortium"""
1065 params
= hs20_ap_params()
1066 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1068 params
= hs20_ap_params()
1069 params
['ssid'] = "test-hs20-other"
1070 params
['roaming_consortium'] = [ "223344" ]
1071 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1073 values
= default_cred()
1074 values
['required_roaming_consortium'] = "223344"
1075 policy_test(dev
[0], apdev
[1], values
)
1076 values
['required_roaming_consortium'] = "112233"
1077 policy_test(dev
[0], apdev
[0], values
)
1079 id = dev
[0].add_cred()
1080 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1081 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1083 for val
in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1084 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1085 raise Exception("Invalid roaming consortium value accepted: " + val
)
1087 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1088 """Hotspot 2.0 exclusion based on SSID"""
1089 params
= hs20_ap_params()
1090 params
['roaming_consortium'] = [ "223344" ]
1091 params
['anqp_3gpp_cell_net'] = "555,444"
1092 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1094 params
= hs20_ap_params()
1095 params
['ssid'] = "test-hs20-other"
1096 params
['roaming_consortium'] = [ "223344" ]
1097 params
['anqp_3gpp_cell_net'] = "555,444"
1098 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1100 values
= default_cred()
1101 values
['excluded_ssid'] = "test-hs20"
1102 events
= policy_test(dev
[0], apdev
[1], values
)
1103 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1105 raise Exception("Excluded network not reported")
1106 values
['excluded_ssid'] = "test-hs20-other"
1107 events
= policy_test(dev
[0], apdev
[0], values
)
1108 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1110 raise Exception("Excluded network not reported")
1112 values
= default_cred()
1113 values
['roaming_consortium'] = "223344"
1114 values
['eap'] = "TTLS"
1115 values
['phase2'] = "auth=MSCHAPV2"
1116 values
['excluded_ssid'] = "test-hs20"
1117 events
= policy_test(dev
[0], apdev
[1], values
)
1118 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1120 raise Exception("Excluded network not reported")
1122 values
= { 'imsi': "555444-333222111", 'eap': "SIM",
1123 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1124 'excluded_ssid': "test-hs20" }
1125 events
= policy_test(dev
[0], apdev
[1], values
)
1126 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1128 raise Exception("Excluded network not reported")
1130 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1131 """Hotspot 2.0 and roaming from current to higher priority network"""
1132 bssid
= apdev
[0]['bssid']
1133 params
= hs20_ap_params(ssid
="test-hs20-visited")
1134 params
['domain_name'] = "visited.example.org"
1135 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1137 dev
[0].hs20_enable()
1138 id = dev
[0].add_cred_values({ 'realm': "example.com",
1139 'username': "hs20-test",
1140 'password': "password",
1141 'domain': "example.com" })
1142 logger
.info("Connect to the only network option")
1143 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1144 dev
[0].dump_monitor()
1145 interworking_connect(dev
[0], bssid
, "TTLS")
1147 logger
.info("Start another AP (home operator) and reconnect")
1148 bssid2
= apdev
[1]['bssid']
1149 params
= hs20_ap_params(ssid
="test-hs20-home")
1150 params
['domain_name'] = "example.com"
1151 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1153 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1154 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1155 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1156 "INTERWORKING-ALREADY-CONNECTED",
1157 "CTRL-EVENT-CONNECTED"], timeout
=15)
1159 raise Exception("Connection timed out")
1160 if "INTERWORKING-NO-MATCH" in ev
:
1161 raise Exception("Matching AP not found")
1162 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1163 raise Exception("Unexpected AP selected")
1164 if bssid2
not in ev
:
1165 raise Exception("Unexpected BSSID after reconnection")
1167 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1168 """Hotspot 2.0 and domain_suffix_match"""
1169 bssid
= apdev
[0]['bssid']
1170 params
= hs20_ap_params()
1171 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1173 dev
[0].hs20_enable()
1174 id = dev
[0].add_cred_values({ 'realm': "example.com",
1175 'username': "hs20-test",
1176 'password': "password",
1177 'domain': "example.com",
1178 'domain_suffix_match': "w1.fi" })
1179 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1180 dev
[0].dump_monitor()
1181 interworking_connect(dev
[0], bssid
, "TTLS")
1182 dev
[0].request("REMOVE_NETWORK all")
1183 dev
[0].dump_monitor()
1185 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1186 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1187 dev
[0].dump_monitor()
1188 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1189 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1191 raise Exception("TLS certificate error not reported")
1192 if "Domain suffix mismatch" not in ev
:
1193 raise Exception("Domain suffix mismatch not reported")
1195 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1196 """Hotspot 2.0 and roaming partner preference"""
1197 params
= hs20_ap_params()
1198 params
['domain_name'] = "roaming.example.org"
1199 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1201 params
= hs20_ap_params()
1202 params
['ssid'] = "test-hs20-other"
1203 params
['domain_name'] = "roaming.example.net"
1204 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1206 logger
.info("Verify default vs. specified preference")
1207 values
= default_cred()
1208 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1209 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1210 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1211 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1213 logger
.info("Verify partial FQDN match")
1214 values
['roaming_partner'] = "example.net,0,0,*"
1215 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1216 values
['roaming_partner'] = "example.net,0,255,*"
1217 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1219 def test_ap_hs20_max_bss_load(dev
, apdev
):
1220 """Hotspot 2.0 and maximum BSS load"""
1221 params
= hs20_ap_params()
1222 params
['bss_load_test'] = "12:200:20000"
1223 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1225 params
= hs20_ap_params()
1226 params
['ssid'] = "test-hs20-other"
1227 params
['bss_load_test'] = "5:20:10000"
1228 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1230 logger
.info("Verify maximum BSS load constraint")
1231 values
= default_cred()
1232 values
['domain'] = "example.com"
1233 values
['max_bss_load'] = "100"
1234 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1236 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1237 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1238 raise Exception("Maximum BSS Load case not noticed")
1239 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1240 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1241 raise Exception("Maximum BSS Load case reported incorrectly")
1243 logger
.info("Verify maximum BSS load does not prevent connection")
1244 values
['max_bss_load'] = "1"
1245 events
= policy_test(dev
[0], None, values
)
1247 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1248 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1249 raise Exception("Maximum BSS Load case not noticed")
1250 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1251 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1252 raise Exception("Maximum BSS Load case not noticed")
1254 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1255 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1256 params
= hs20_ap_params()
1257 params
['bss_load_test'] = "12:200:20000"
1258 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1260 params
= hs20_ap_params()
1261 params
['ssid'] = "test-hs20-other"
1262 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1264 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1265 values
= default_cred()
1266 values
['domain'] = "example.com"
1267 values
['max_bss_load'] = "100"
1268 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1270 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1271 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1272 raise Exception("Maximum BSS Load case not noticed")
1273 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1274 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1275 raise Exception("Maximum BSS Load case reported incorrectly")
1277 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1278 """Hotspot 2.0 multi-cred sp_priority"""
1280 return _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1282 dev
[0].request("SET external_sim 0")
1284 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1285 if not hlr_auc_gw_available():
1287 bssid
= apdev
[0]['bssid']
1288 params
= hs20_ap_params()
1289 params
['hessid'] = bssid
1290 del params
['domain_name']
1291 params
['anqp_3gpp_cell_net'] = "232,01"
1292 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1294 dev
[0].hs20_enable()
1295 dev
[0].scan_for_bss(bssid
, freq
="2412")
1296 dev
[0].request("SET external_sim 1")
1297 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1298 'provisioning_sp': "example.com",
1299 'sp_priority' :"1" })
1300 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1301 'username': "hs20-test",
1302 'password': "password",
1303 'domain': "example.com",
1304 'provisioning_sp': "example.com",
1305 'sp_priority': "2" })
1306 dev
[0].dump_monitor()
1307 dev
[0].scan_for_bss(bssid
, freq
="2412")
1308 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1309 interworking_ext_sim_auth(dev
[0], "SIM")
1310 check_sp_type(dev
[0], "unknown")
1311 dev
[0].request("REMOVE_NETWORK all")
1313 dev
[0].set_cred(id1
, "sp_priority", "2")
1314 dev
[0].set_cred(id2
, "sp_priority", "1")
1315 dev
[0].dump_monitor()
1316 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1317 interworking_auth(dev
[0], "TTLS")
1318 check_sp_type(dev
[0], "unknown")
1320 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1321 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1323 return _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
1325 dev
[0].request("SET external_sim 0")
1327 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1328 if not hlr_auc_gw_available():
1330 bssid
= apdev
[0]['bssid']
1331 params
= hs20_ap_params()
1332 params
['hessid'] = bssid
1333 del params
['nai_realm']
1334 del params
['domain_name']
1335 params
['anqp_3gpp_cell_net'] = "232,01"
1336 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1338 bssid2
= apdev
[1]['bssid']
1339 params
= hs20_ap_params()
1340 params
['ssid'] = "test-hs20-other"
1341 params
['hessid'] = bssid2
1342 del params
['domain_name']
1343 del params
['anqp_3gpp_cell_net']
1344 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1346 dev
[0].hs20_enable()
1347 dev
[0].request("SET external_sim 1")
1348 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1349 'provisioning_sp': "example.com",
1350 'sp_priority': "1" })
1351 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1352 'username': "hs20-test",
1353 'password': "password",
1354 'domain': "example.com",
1355 'provisioning_sp': "example.com",
1356 'sp_priority': "2" })
1357 dev
[0].dump_monitor()
1358 dev
[0].scan_for_bss(bssid
, freq
="2412")
1359 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1360 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1361 interworking_ext_sim_auth(dev
[0], "SIM")
1362 check_sp_type(dev
[0], "unknown")
1363 conn_bssid
= dev
[0].get_status_field("bssid")
1364 if conn_bssid
!= bssid
:
1365 raise Exception("Connected to incorrect BSS")
1366 dev
[0].request("REMOVE_NETWORK all")
1368 dev
[0].set_cred(id1
, "sp_priority", "2")
1369 dev
[0].set_cred(id2
, "sp_priority", "1")
1370 dev
[0].dump_monitor()
1371 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1372 interworking_auth(dev
[0], "TTLS")
1373 check_sp_type(dev
[0], "unknown")
1374 conn_bssid
= dev
[0].get_status_field("bssid")
1375 if conn_bssid
!= bssid2
:
1376 raise Exception("Connected to incorrect BSS")
1378 def check_conn_capab_selection(dev
, type, missing
):
1379 dev
.request("INTERWORKING_SELECT freq=2412")
1380 ev
= dev
.wait_event(["INTERWORKING-AP"])
1382 raise Exception("Network selection timed out");
1383 if "type=" + type not in ev
:
1384 raise Exception("Unexpected network type")
1385 if missing
and "conn_capab_missing=1" not in ev
:
1386 raise Exception("conn_capab_missing not reported")
1387 if not missing
and "conn_capab_missing=1" in ev
:
1388 raise Exception("conn_capab_missing reported unexpectedly")
1390 def conn_capab_cred(domain
=None, req_conn_capab
=None):
1391 cred
= default_cred(domain
=domain
)
1393 cred
['req_conn_capab'] = req_conn_capab
1396 def test_ap_hs20_req_conn_capab(dev
, apdev
):
1397 """Hotspot 2.0 network selection with req_conn_capab"""
1398 bssid
= apdev
[0]['bssid']
1399 params
= hs20_ap_params()
1400 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1402 dev
[0].hs20_enable()
1403 dev
[0].scan_for_bss(bssid
, freq
="2412")
1404 logger
.info("Not used in home network")
1405 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
1406 id = dev
[0].add_cred_values(values
)
1407 check_conn_capab_selection(dev
[0], "home", False)
1409 logger
.info("Used in roaming network")
1410 dev
[0].remove_cred(id)
1411 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
1412 id = dev
[0].add_cred_values(values
)
1413 check_conn_capab_selection(dev
[0], "roaming", True)
1415 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1416 check_auto_select(dev
[0], bssid
)
1418 logger
.info("Additional req_conn_capab checks")
1420 dev
[0].remove_cred(id)
1421 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
1422 id = dev
[0].add_cred_values(values
)
1423 check_conn_capab_selection(dev
[0], "roaming", True)
1425 dev
[0].remove_cred(id)
1426 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
1427 id = dev
[0].add_cred_values(values
)
1428 check_conn_capab_selection(dev
[0], "roaming", True)
1430 bssid2
= apdev
[1]['bssid']
1431 params
= hs20_ap_params(ssid
="test-hs20b")
1432 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1433 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1435 dev
[0].remove_cred(id)
1436 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
1437 id = dev
[0].add_cred_values(values
)
1438 dev
[0].set_cred(id, "req_conn_capab", "6:22")
1439 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1440 dev
[0].request("INTERWORKING_SELECT freq=2412")
1441 for i
in range(0, 2):
1442 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
1444 raise Exception("Network selection timed out");
1445 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
1446 raise Exception("Missing protocol connection capability not reported")
1447 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
1448 raise Exception("Protocol connection capability not reported correctly")
1450 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
1451 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1452 bssid
= apdev
[0]['bssid']
1453 params
= hs20_ap_params()
1454 params
['domain_name'] = "roaming.example.org"
1455 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1456 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1458 bssid2
= apdev
[1]['bssid']
1459 params
= hs20_ap_params(ssid
="test-hs20-b")
1460 params
['domain_name'] = "roaming.example.net"
1461 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1463 values
= default_cred()
1464 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1465 id = dev
[0].add_cred_values(values
)
1466 check_auto_select(dev
[0], bssid2
)
1468 dev
[0].set_cred(id, "req_conn_capab", "50")
1469 check_auto_select(dev
[0], bssid
)
1471 dev
[0].remove_cred(id)
1472 id = dev
[0].add_cred_values(values
)
1473 dev
[0].set_cred(id, "req_conn_capab", "51")
1474 check_auto_select(dev
[0], bssid2
)
1476 def check_bandwidth_selection(dev
, type, below
):
1477 dev
.request("INTERWORKING_SELECT freq=2412")
1478 ev
= dev
.wait_event(["INTERWORKING-AP"])
1480 raise Exception("Network selection timed out");
1481 if "type=" + type not in ev
:
1482 raise Exception("Unexpected network type")
1483 if below
and "below_min_backhaul=1" not in ev
:
1484 raise Exception("below_min_backhaul not reported")
1485 if not below
and "below_min_backhaul=1" in ev
:
1486 raise Exception("below_min_backhaul reported unexpectedly")
1488 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
1489 cred
= default_cred(domain
=domain
)
1491 cred
['min_dl_bandwidth_home'] = str(dl_home
)
1493 cred
['min_ul_bandwidth_home'] = str(ul_home
)
1495 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
1497 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
1500 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
1501 """Hotspot 2.0 network selection with min bandwidth (home)"""
1502 bssid
= apdev
[0]['bssid']
1503 params
= hs20_ap_params()
1504 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1506 dev
[0].hs20_enable()
1507 dev
[0].scan_for_bss(bssid
, freq
="2412")
1508 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1509 id = dev
[0].add_cred_values(values
)
1510 check_bandwidth_selection(dev
[0], "home", False)
1511 dev
[0].remove_cred(id)
1513 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1514 id = dev
[0].add_cred_values(values
)
1515 check_bandwidth_selection(dev
[0], "home", True)
1516 dev
[0].remove_cred(id)
1518 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1519 id = dev
[0].add_cred_values(values
)
1520 check_bandwidth_selection(dev
[0], "home", True)
1521 dev
[0].remove_cred(id)
1523 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1524 id = dev
[0].add_cred_values(values
)
1525 check_bandwidth_selection(dev
[0], "home", True)
1526 check_auto_select(dev
[0], bssid
)
1528 bssid2
= apdev
[1]['bssid']
1529 params
= hs20_ap_params(ssid
="test-hs20-b")
1530 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1531 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1533 check_auto_select(dev
[0], bssid2
)
1535 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
1536 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1537 bssid
= apdev
[0]['bssid']
1538 params
= hs20_ap_params()
1539 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1541 dev
[0].hs20_enable()
1542 dev
[0].scan_for_bss(bssid
, freq
="2412")
1543 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
1544 id = dev
[0].add_cred_values(values
)
1545 check_bandwidth_selection(dev
[0], "roaming", False)
1546 dev
[0].remove_cred(id)
1548 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
1549 id = dev
[0].add_cred_values(values
)
1550 check_bandwidth_selection(dev
[0], "roaming", True)
1551 dev
[0].remove_cred(id)
1553 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
1554 id = dev
[0].add_cred_values(values
)
1555 check_bandwidth_selection(dev
[0], "roaming", True)
1556 dev
[0].remove_cred(id)
1558 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
1559 id = dev
[0].add_cred_values(values
)
1560 check_bandwidth_selection(dev
[0], "roaming", True)
1561 check_auto_select(dev
[0], bssid
)
1563 bssid2
= apdev
[1]['bssid']
1564 params
= hs20_ap_params(ssid
="test-hs20-b")
1565 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1566 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1568 check_auto_select(dev
[0], bssid2
)
1570 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
1571 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1572 bssid
= apdev
[0]['bssid']
1573 params
= hs20_ap_params()
1574 params
['domain_name'] = "roaming.example.org"
1575 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1576 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1578 bssid2
= apdev
[1]['bssid']
1579 params
= hs20_ap_params(ssid
="test-hs20-b")
1580 params
['domain_name'] = "roaming.example.net"
1581 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1583 values
= default_cred()
1584 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1585 id = dev
[0].add_cred_values(values
)
1586 check_auto_select(dev
[0], bssid2
)
1588 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1589 check_auto_select(dev
[0], bssid
)
1591 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1592 check_auto_select(dev
[0], bssid2
)
1594 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
1595 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1596 bssid
= apdev
[0]['bssid']
1597 params
= hs20_ap_params()
1598 del params
['hs20_wan_metrics']
1599 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1601 dev
[0].hs20_enable()
1602 dev
[0].scan_for_bss(bssid
, freq
="2412")
1603 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
1604 dl_roaming
=10000, ul_roaming
=10000)
1605 dev
[0].add_cred_values(values
)
1606 check_bandwidth_selection(dev
[0], "home", False)
1608 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
1609 """Hotspot 2.0 connection and deauthentication request for ESS"""
1610 dev
[0].request("SET pmf 2")
1611 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1612 dev
[0].dump_monitor()
1613 addr
= dev
[0].p2p_interface_addr()
1614 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1615 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
1616 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1618 raise Exception("Timeout on deauth imminent notice")
1619 if "1 120 http://example.com/" not in ev
:
1620 raise Exception("Unexpected deauth imminent notice: " + ev
)
1621 hapd
.request("DEAUTHENTICATE " + addr
)
1622 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1624 raise Exception("Timeout on disconnection")
1625 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1626 raise Exception("Network not marked temporarily disabled")
1627 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1628 "Trying to associate",
1629 "CTRL-EVENT-CONNECTED"], timeout
=5)
1631 raise Exception("Unexpected connection attempt")
1633 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
1634 """Hotspot 2.0 connection and deauthentication request for BSS"""
1635 dev
[0].request("SET pmf 2")
1636 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1637 dev
[0].dump_monitor()
1638 addr
= dev
[0].p2p_interface_addr()
1639 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1640 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
1641 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1643 raise Exception("Timeout on deauth imminent notice")
1644 if "0 120 http://example.com/" not in ev
:
1645 raise Exception("Unexpected deauth imminent notice: " + ev
)
1646 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
1647 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1649 raise Exception("Timeout on disconnection")
1650 if "reason=4" not in ev
:
1651 raise Exception("Unexpected disconnection reason")
1652 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1653 raise Exception("Network not marked temporarily disabled")
1654 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1655 "Trying to associate",
1656 "CTRL-EVENT-CONNECTED"], timeout
=5)
1658 raise Exception("Unexpected connection attempt")
1660 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1661 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1662 bssid
= apdev
[0]['bssid']
1663 params
= hs20_ap_params()
1664 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1665 params
['hs20_deauth_req_timeout'] = "2"
1666 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1668 dev
[0].request("SET pmf 2")
1669 dev
[0].hs20_enable()
1670 dev
[0].add_cred_values({ 'realm': "example.com",
1671 'username': "hs20-deauth-test",
1672 'password': "password" })
1673 interworking_select(dev
[0], bssid
, freq
="2412")
1674 interworking_connect(dev
[0], bssid
, "TTLS")
1675 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
1677 raise Exception("Timeout on deauth imminent notice")
1678 if " 1 100" not in ev
:
1679 raise Exception("Unexpected deauth imminent contents")
1680 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=3)
1682 raise Exception("Timeout on disconnection")
1684 def test_ap_hs20_remediation_required(dev
, apdev
):
1685 """Hotspot 2.0 connection and remediation required from RADIUS"""
1686 bssid
= apdev
[0]['bssid']
1687 params
= hs20_ap_params()
1688 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1689 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1691 dev
[0].request("SET pmf 1")
1692 dev
[0].hs20_enable()
1693 dev
[0].add_cred_values({ 'realm': "example.com",
1694 'username': "hs20-subrem-test",
1695 'password': "password" })
1696 interworking_select(dev
[0], bssid
, freq
="2412")
1697 interworking_connect(dev
[0], bssid
, "TTLS")
1698 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1700 raise Exception("Timeout on subscription remediation notice")
1701 if " 1 https://example.com/" not in ev
:
1702 raise Exception("Unexpected subscription remediation event contents")
1704 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1705 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1706 bssid
= apdev
[0]['bssid']
1707 addr
= dev
[0].p2p_dev_addr()
1708 params
= hs20_ap_params()
1709 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1710 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
1712 dev
[0].request("SET pmf 1")
1713 dev
[0].hs20_enable()
1714 dev
[0].add_cred_values(default_cred())
1715 interworking_select(dev
[0], bssid
, freq
="2412")
1716 interworking_connect(dev
[0], bssid
, "TTLS")
1718 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
1719 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1721 raise Exception("Timeout on subscription remediation notice")
1722 if " 1 https://example.com/" not in ev
:
1723 raise Exception("Unexpected subscription remediation event contents")
1725 hapd
.request("HS20_WNM_NOTIF " + addr
)
1726 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1728 raise Exception("Timeout on subscription remediation notice")
1729 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1730 raise Exception("Unexpected subscription remediation event contents: " + ev
)
1732 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
1733 raise Exception("Unexpected HS20_WNM_NOTIF success")
1734 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
1735 raise Exception("Unexpected HS20_WNM_NOTIF success")
1736 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1737 raise Exception("Unexpected HS20_WNM_NOTIF success")
1739 def test_ap_hs20_session_info(dev
, apdev
):
1740 """Hotspot 2.0 connection and session information from RADIUS"""
1741 bssid
= apdev
[0]['bssid']
1742 params
= hs20_ap_params()
1743 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1744 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1746 dev
[0].request("SET pmf 1")
1747 dev
[0].hs20_enable()
1748 dev
[0].add_cred_values({ 'realm': "example.com",
1749 'username': "hs20-session-info-test",
1750 'password': "password" })
1751 interworking_select(dev
[0], bssid
, freq
="2412")
1752 interworking_connect(dev
[0], bssid
, "TTLS")
1753 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
1755 raise Exception("Timeout on ESS disassociation imminent notice")
1756 if " 1 59904 https://example.com/" not in ev
:
1757 raise Exception("Unexpected ESS disassociation imminent event contents")
1758 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1760 raise Exception("Scan not started")
1761 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
1763 raise Exception("Scan not completed")
1765 def test_ap_hs20_osen(dev
, apdev
):
1766 """Hotspot 2.0 OSEN connection"""
1767 params
= { 'ssid': "osen",
1769 'auth_server_addr': "127.0.0.1",
1770 'auth_server_port': "1812",
1771 'auth_server_shared_secret': "radius" }
1772 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1774 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
1776 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
1777 scan_freq
="2412", wait_connect
=False)
1778 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1779 group
="GTK_NOT_USED",
1780 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1781 ca_cert
="auth_serv/ca.pem",
1784 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
1785 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
1786 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1787 group
="GTK_NOT_USED",
1788 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1789 ca_cert
="auth_serv/ca.pem",
1791 wpas
.request("DISCONNECT")
1793 def test_ap_hs20_network_preference(dev
, apdev
):
1794 """Hotspot 2.0 network selection with preferred home network"""
1795 bssid
= apdev
[0]['bssid']
1796 params
= hs20_ap_params()
1797 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1799 dev
[0].hs20_enable()
1800 values
= { 'realm': "example.com",
1801 'username': "hs20-test",
1802 'password': "password",
1803 'domain': "example.com" }
1804 dev
[0].add_cred_values(values
)
1806 id = dev
[0].add_network()
1807 dev
[0].set_network_quoted(id, "ssid", "home")
1808 dev
[0].set_network_quoted(id, "psk", "12345678")
1809 dev
[0].set_network(id, "priority", "1")
1810 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1812 dev
[0].scan_for_bss(bssid
, freq
="2412")
1813 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1814 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1816 raise Exception("Connection timed out")
1818 raise Exception("Unexpected network selected")
1820 bssid2
= apdev
[1]['bssid']
1821 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1822 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1824 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1825 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1826 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1827 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1829 raise Exception("Connection timed out")
1830 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1831 raise Exception("No roam to higher priority network")
1832 if bssid2
not in ev
:
1833 raise Exception("Unexpected network selected")
1835 def test_ap_hs20_network_preference2(dev
, apdev
):
1836 """Hotspot 2.0 network selection with preferred credential"""
1837 bssid2
= apdev
[1]['bssid']
1838 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1839 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1841 dev
[0].hs20_enable()
1842 values
= { 'realm': "example.com",
1843 'username': "hs20-test",
1844 'password': "password",
1845 'domain': "example.com",
1847 dev
[0].add_cred_values(values
)
1849 id = dev
[0].add_network()
1850 dev
[0].set_network_quoted(id, "ssid", "home")
1851 dev
[0].set_network_quoted(id, "psk", "12345678")
1852 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1854 dev
[0].scan_for_bss(bssid2
, 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")
1859 if bssid2
not in ev
:
1860 raise Exception("Unexpected network selected")
1862 bssid
= apdev
[0]['bssid']
1863 params
= hs20_ap_params()
1864 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1866 dev
[0].scan_for_bss(bssid
, 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")
1875 raise Exception("Unexpected network selected")
1877 def test_ap_hs20_network_preference3(dev
, apdev
):
1878 """Hotspot 2.0 network selection with two credential (one preferred)"""
1879 bssid
= apdev
[0]['bssid']
1880 params
= hs20_ap_params()
1881 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1883 bssid2
= apdev
[1]['bssid']
1884 params
= hs20_ap_params(ssid
="test-hs20b")
1885 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
1886 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1888 dev
[0].hs20_enable()
1889 values
= { 'realm': "example.com",
1890 'username': "hs20-test",
1891 'password': "password",
1893 dev
[0].add_cred_values(values
)
1894 values
= { 'realm': "example.org",
1895 'username': "hs20-test",
1896 'password': "password" }
1897 id = dev
[0].add_cred_values(values
)
1899 dev
[0].scan_for_bss(bssid
, freq
="2412")
1900 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1901 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1902 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1904 raise Exception("Connection timed out")
1906 raise Exception("Unexpected network selected")
1908 dev
[0].set_cred(id, "priority", "2")
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")
1916 if bssid2
not in ev
:
1917 raise Exception("Unexpected network selected")
1919 def test_ap_hs20_network_preference4(dev
, apdev
):
1920 """Hotspot 2.0 network selection with username vs. SIM credential"""
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
['hessid'] = bssid2
1928 params
['anqp_3gpp_cell_net'] = "555,444"
1929 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1930 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1932 dev
[0].hs20_enable()
1933 values
= { 'realm': "example.com",
1934 'username': "hs20-test",
1935 'password': "password",
1937 dev
[0].add_cred_values(values
)
1938 values
= { 'imsi': "555444-333222111",
1940 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1941 id = dev
[0].add_cred_values(values
)
1943 dev
[0].scan_for_bss(bssid
, freq
="2412")
1944 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1945 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1946 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
1948 raise Exception("Connection timed out")
1950 raise Exception("Unexpected network selected")
1952 dev
[0].set_cred(id, "priority", "2")
1953 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1954 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1955 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1957 raise Exception("Connection timed out")
1958 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1959 raise Exception("No roam to higher priority network")
1960 if bssid2
not in ev
:
1961 raise Exception("Unexpected network selected")
1963 def test_ap_hs20_fetch_osu(dev
, apdev
):
1964 """Hotspot 2.0 OSU provider and icon fetch"""
1965 bssid
= apdev
[0]['bssid']
1966 params
= hs20_ap_params()
1967 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1968 params
['osu_ssid'] = '"HS 2.0 OSU open"'
1969 params
['osu_method_list'] = "1"
1970 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
1971 params
['osu_icon'] = "w1fi_logo"
1972 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
1973 params
['osu_server_uri'] = "https://example.com/osu/"
1974 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1976 bssid2
= apdev
[1]['bssid']
1977 params
= hs20_ap_params(ssid
="test-hs20b")
1978 params
['hessid'] = bssid2
1979 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1980 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
1981 params
['osu_method_list'] = "0"
1982 params
['osu_nai'] = "osen@example.com"
1983 params
['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
1984 params
['osu_icon'] = "w1fi_logo"
1985 params
['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
1986 params
['osu_server_uri'] = "https://example.org/osu/"
1987 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1989 with
open("w1fi_logo.png", "r") as f
:
1990 orig_logo
= f
.read()
1991 dev
[0].hs20_enable()
1992 dir = "/tmp/osu-fetch"
1993 if os
.path
.isdir(dir):
1994 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
1996 os
.remove(dir + "/" + f
)
2003 dev
[1].scan_for_bss(bssid
, freq
="2412")
2004 dev
[0].request("SET osu_dir " + dir)
2005 dev
[0].request("FETCH_OSU")
2006 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2007 raise Exception("HS20_ICON_REQUEST failed")
2010 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2011 "RX-HS20-ANQP-ICON"], timeout
=15)
2013 raise Exception("Timeout on OSU fetch")
2014 if "OSU provider fetch completed" in ev
:
2016 if "RX-HS20-ANQP-ICON" in ev
:
2017 with
open(ev
.split(' ')[1], "r") as f
:
2019 if logo
== orig_logo
:
2022 with
open(dir + "/osu-providers.txt", "r") as f
:
2024 if "OSU-PROVIDER " + bssid
not in prov
:
2025 raise Exception("Missing OSU_PROVIDER")
2026 if "OSU-PROVIDER " + bssid2
not in prov
:
2027 raise Exception("Missing OSU_PROVIDER")
2029 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2031 os
.remove(dir + "/" + f
)
2035 raise Exception("Unexpected number of icons fetched")
2037 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2039 raise Exception("Timeout on GAS-QUERY-DONE")
2040 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2042 raise Exception("Timeout on GAS-QUERY-DONE")
2043 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2044 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2045 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2047 raise Exception("Timeout on icon fetch")
2048 if "Icon Binary File" not in ev
:
2049 raise Exception("Unexpected ANQP element")
2051 def test_ap_hs20_ft(dev
, apdev
):
2052 """Hotspot 2.0 connection with FT"""
2053 bssid
= apdev
[0]['bssid']
2054 params
= hs20_ap_params()
2055 params
['wpa_key_mgmt'] = "FT-EAP"
2056 params
['nas_identifier'] = "nas1.w1.fi"
2057 params
['r1_key_holder'] = "000102030405"
2058 params
["mobility_domain"] = "a1b2"
2059 params
["reassociation_deadline"] = "1000"
2060 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2062 dev
[0].hs20_enable()
2063 id = dev
[0].add_cred_values({ 'realm': "example.com",
2064 'username': "hs20-test",
2065 'password': "password",
2066 'ca_cert': "auth_serv/ca.pem",
2067 'domain': "example.com",
2068 'update_identifier': "1234" })
2069 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2070 interworking_connect(dev
[0], bssid
, "TTLS")
2072 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
2073 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2078 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
2083 con
= sqlite3
.connect(dbfile
)
2086 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2087 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2088 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2089 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2090 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2093 params
= { "ssid": "as", "beacon_int": "2000",
2094 "radius_server_clients": "auth_serv/radius_clients.conf",
2095 "radius_server_auth_port": '18128',
2097 "eap_user_file": "sqlite:" + dbfile
,
2098 "ca_cert": "auth_serv/ca.pem",
2099 "server_cert": "auth_serv/server.pem",
2100 "private_key": "auth_serv/server.key",
2101 "subscr_remediation_url": "https://example.org/",
2102 "subscr_remediation_method": "1" }
2103 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2105 bssid
= apdev
[0]['bssid']
2106 params
= hs20_ap_params()
2107 params
['auth_server_port'] = "18128"
2108 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2110 dev
[0].request("SET pmf 1")
2111 dev
[0].hs20_enable()
2112 id = dev
[0].add_cred_values({ 'realm': "example.com",
2113 'username': "user-mschapv2",
2114 'password': "password",
2115 'ca_cert': "auth_serv/ca.pem" })
2116 interworking_select(dev
[0], bssid
, freq
="2412")
2117 interworking_connect(dev
[0], bssid
, "TTLS")
2118 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2120 raise Exception("Timeout on subscription remediation notice")
2121 if " 1 https://example.org/" not in ev
:
2122 raise Exception("Unexpected subscription remediation event contents")
2126 cur
.execute("SELECT * from authlog")
2127 rows
= cur
.fetchall()
2129 raise Exception("No authlog entries")
2134 def test_ap_hs20_external_selection(dev
, apdev
):
2135 """Hotspot 2.0 connection using external network selection and creation"""
2136 bssid
= apdev
[0]['bssid']
2137 params
= hs20_ap_params()
2138 params
['hessid'] = bssid
2139 params
['disable_dgaf'] = '1'
2140 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2142 dev
[0].hs20_enable()
2143 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
2144 identity
="hs20-test", password
="password",
2145 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2146 scan_freq
="2412", update_identifier
="54321")
2147 if dev
[0].get_status_field("hs20") != "2":
2148 raise Exception("Unexpected hs20 indication")
2150 def test_ap_hs20_random_mac_addr(dev
, apdev
):
2151 """Hotspot 2.0 connection with random MAC address"""
2152 bssid
= apdev
[0]['bssid']
2153 params
= hs20_ap_params()
2154 params
['hessid'] = bssid
2155 params
['disable_dgaf'] = '1'
2156 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2158 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2159 wpas
.interface_add("wlan5")
2160 addr
= wpas
.p2p_interface_addr()
2161 wpas
.request("SET mac_addr 1")
2162 wpas
.request("SET preassoc_mac_addr 1")
2163 wpas
.request("SET rand_addr_lifetime 60")
2165 wpas
.flush_scan_cache()
2166 id = wpas
.add_cred_values({ 'realm': "example.com",
2167 'username': "hs20-test",
2168 'password': "password",
2169 'ca_cert': "auth_serv/ca.pem",
2170 'domain': "example.com",
2171 'update_identifier': "1234" })
2172 interworking_select(wpas
, bssid
, "home", freq
="2412")
2173 interworking_connect(wpas
, bssid
, "TTLS")
2174 addr1
= wpas
.get_driver_status_field("addr")
2176 raise Exception("Did not use random MAC address")
2178 sta
= hapd
.get_sta(addr
)
2179 if sta
['addr'] != "FAIL":
2180 raise Exception("Unexpected STA association with permanent address")
2181 sta
= hapd
.get_sta(addr1
)
2182 if sta
['addr'] != addr1
:
2183 raise Exception("STA association with random address not found")
2185 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
2186 """Multiple networks and cred removal"""
2187 bssid
= apdev
[0]['bssid']
2188 params
= hs20_ap_params()
2189 params
['nai_realm'] = [ "0,example.com,25[3:26]"]
2190 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2192 dev
[0].add_network()
2193 dev
[0].hs20_enable()
2194 id = dev
[0].add_cred_values({ 'realm': "example.com",
2196 'password': "password" })
2197 interworking_select(dev
[0], bssid
, freq
="2412")
2198 interworking_connect(dev
[0], bssid
, "PEAP")
2199 dev
[0].add_network()
2201 dev
[0].request("DISCONNECT")
2202 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
2204 raise Exception("Timeout on disconnection")
2207 hapd
.set("ssid", "another ssid")
2210 interworking_select(dev
[0], bssid
, freq
="2412")
2211 interworking_connect(dev
[0], bssid
, "PEAP")
2212 dev
[0].add_network()
2213 if len(dev
[0].list_networks()) != 5:
2214 raise Exception("Unexpected number of networks prior to remove_crec")
2216 dev
[0].dump_monitor()
2217 dev
[0].remove_cred(id)
2218 if len(dev
[0].list_networks()) != 3:
2219 raise Exception("Unexpected number of networks after to remove_crec")
2220 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
2222 raise Exception("Timeout on disconnection")
2224 def _test_ap_hs20_proxyarp(dev
, apdev
):
2225 bssid
= apdev
[0]['bssid']
2226 params
= hs20_ap_params()
2227 params
['hessid'] = bssid
2228 params
['disable_dgaf'] = '0'
2229 params
['proxy_arp'] = '1'
2230 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2231 if "OK" in hapd
.request("ENABLE"):
2232 raise Exception("Incomplete hostapd configuration was accepted")
2233 hapd
.set("ap_isolate", "1")
2234 if "OK" in hapd
.request("ENABLE"):
2235 raise Exception("Incomplete hostapd configuration was accepted")
2236 hapd
.set('bridge', 'ap-br0')
2241 # For now, do not report failures due to missing kernel support
2242 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2244 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2246 raise Exception("AP startup timed out")
2247 if "AP-ENABLED" not in ev
:
2248 raise Exception("AP startup failed")
2250 dev
[0].hs20_enable()
2251 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2252 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2254 id = dev
[0].add_cred_values({ 'realm': "example.com",
2255 'username': "hs20-test",
2256 'password': "password",
2257 'ca_cert': "auth_serv/ca.pem",
2258 'domain': "example.com",
2259 'update_identifier': "1234" })
2260 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2261 interworking_connect(dev
[0], bssid
, "TTLS")
2263 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2264 identity
="hs20-test", password
="password",
2265 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2269 addr0
= dev
[0].p2p_interface_addr()
2270 addr1
= dev
[1].p2p_interface_addr()
2272 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2273 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2275 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2276 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2278 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2279 raise Exception("DATA_TEST_FRAME failed")
2281 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2282 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2284 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2285 raise Exception("DATA_TEST_FRAME failed")
2287 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2288 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2290 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2291 raise Exception("DATA_TEST_FRAME failed")
2293 matches
= get_permanent_neighbors("ap-br0")
2294 logger
.info("After connect: " + str(matches
))
2295 if len(matches
) != 3:
2296 raise Exception("Unexpected number of neighbor entries after connect")
2297 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2298 raise Exception("dev0 addr missing")
2299 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2300 raise Exception("dev1 addr(1) missing")
2301 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2302 raise Exception("dev1 addr(2) missing")
2303 dev
[0].request("DISCONNECT")
2304 dev
[1].request("DISCONNECT")
2306 matches
= get_permanent_neighbors("ap-br0")
2307 logger
.info("After disconnect: " + str(matches
))
2308 if len(matches
) > 0:
2309 raise Exception("Unexpected neighbor entries after disconnect")
2311 def test_ap_hs20_proxyarp(dev
, apdev
):
2312 """Hotspot 2.0 and ProxyARP"""
2315 res
= _test_ap_hs20_proxyarp(dev
, apdev
)
2317 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2318 stderr
=open('/dev/null', 'w'))
2319 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2320 stderr
=open('/dev/null', 'w'))
2324 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
2325 bssid
= apdev
[0]['bssid']
2326 params
= hs20_ap_params()
2327 params
['hessid'] = bssid
2328 params
['disable_dgaf'] = '1' if disabled
else '0'
2329 params
['proxy_arp'] = '1'
2330 params
['ap_isolate'] = '1'
2331 params
['bridge'] = 'ap-br0'
2332 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2336 # For now, do not report failures due to missing kernel support
2337 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2339 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
2341 raise Exception("AP startup timed out")
2343 dev
[0].hs20_enable()
2344 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2345 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2347 id = dev
[0].add_cred_values({ 'realm': "example.com",
2348 'username': "hs20-test",
2349 'password': "password",
2350 'ca_cert': "auth_serv/ca.pem",
2351 'domain': "example.com",
2352 'update_identifier': "1234" })
2353 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2354 interworking_connect(dev
[0], bssid
, "TTLS")
2356 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2357 identity
="hs20-test", password
="password",
2358 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2362 addr0
= dev
[0].p2p_interface_addr()
2364 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2366 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2367 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2369 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2370 raise Exception("DATA_TEST_FRAME failed")
2372 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
2374 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2375 raise Exception("DATA_TEST_FRAME failed")
2377 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
2378 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
2379 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2380 raise Exception("DATA_TEST_FRAME failed")
2382 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2383 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2384 yiaddr
="192.168.1.123", chaddr
=addr0
)
2385 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2386 raise Exception("DATA_TEST_FRAME failed")
2387 # another copy for additional code coverage
2388 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2389 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2390 yiaddr
="192.168.1.123", chaddr
=addr0
)
2391 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2392 raise Exception("DATA_TEST_FRAME failed")
2394 matches
= get_permanent_neighbors("ap-br0")
2395 logger
.info("After connect: " + str(matches
))
2396 if len(matches
) != 2:
2397 raise Exception("Unexpected number of neighbor entries after connect")
2398 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2399 raise Exception("dev0 addr missing")
2400 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2401 raise Exception("dev0 IPv4 addr missing")
2402 dev
[0].request("DISCONNECT")
2403 dev
[1].request("DISCONNECT")
2405 matches
= get_permanent_neighbors("ap-br0")
2406 logger
.info("After disconnect: " + str(matches
))
2407 if len(matches
) > 0:
2408 raise Exception("Unexpected neighbor entries after disconnect")
2410 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
2411 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
2414 res
= _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
2416 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2417 stderr
=open('/dev/null', 'w'))
2418 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2419 stderr
=open('/dev/null', 'w'))
2423 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
2424 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
2427 res
= _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
2429 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2430 stderr
=open('/dev/null', 'w'))
2431 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2432 stderr
=open('/dev/null', 'w'))
2436 def ip_checksum(buf
):
2440 for i
in range(0, len(buf
), 2):
2441 val
, = struct
.unpack('H', buf
[i
:i
+2])
2444 sum = (sum & 0xffff) + (sum >> 16)
2445 return struct
.pack('H', ~
sum & 0xffff)
2447 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
2448 start
= struct
.pack("BB", type, code
)
2450 icmp
= start
+ '\x00\x00' + end
2451 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
2452 csum
= ip_checksum(pseudo
+ icmp
)
2453 return start
+ csum
+ end
2455 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
2456 reachable_time
=0, retrans_timer
=0, opt
=None):
2457 link_mc
= binascii
.unhexlify("3333ff000002")
2458 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2460 ehdr
= link_mc
+ _src_ll
+ proto
2461 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2462 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2464 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
2465 reachable_time
, retrans_timer
)
2470 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
2472 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2473 ipv6
+= _ip_src
+ _ip_dst
2475 return ehdr
+ ipv6
+ icmp
2477 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2478 link_mc
= binascii
.unhexlify("3333ff000002")
2479 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2481 ehdr
= link_mc
+ _src_ll
+ proto
2482 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2483 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2485 reserved
= '\x00\x00\x00\x00'
2486 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2488 payload
= reserved
+ _target
+ opt
2490 payload
= reserved
+ _target
2491 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
2493 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2494 ipv6
+= _ip_src
+ _ip_dst
2496 return ehdr
+ ipv6
+ icmp
2498 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2499 link_mc
= binascii
.unhexlify("3333ff000002")
2500 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2502 ehdr
= link_mc
+ _src_ll
+ proto
2503 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2504 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2506 reserved
= '\x00\x00\x00\x00'
2507 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2509 payload
= reserved
+ _target
+ opt
2511 payload
= reserved
+ _target
2512 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
2514 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2515 ipv6
+= _ip_src
+ _ip_dst
2517 return ehdr
+ ipv6
+ icmp
2519 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
2520 subnet_mask
="255.255.255.0", truncated_opt
=False,
2521 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False):
2522 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2523 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2525 ehdr
= _dst_ll
+ _src_ll
+ proto
2526 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
2527 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
2528 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
2530 _ciaddr
= '\x00\x00\x00\x00'
2531 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
2532 _siaddr
= '\x00\x00\x00\x00'
2533 _giaddr
= '\x00\x00\x00\x00'
2534 _chaddr
= binascii
.unhexlify(chaddr
.replace(':','') + "00000000000000000000")
2535 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2536 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2539 payload
+= '\x63\x82\x53\x00'
2541 payload
+= '\x63\x82\x53\x63'
2543 payload
+= '\x22\xff\x00'
2544 # Option: DHCP Message Type = ACK
2545 payload
+= '\x35\x01\x05'
2548 # Option: Subnet Mask
2549 payload
+= '\x01\x04' + _subnet_mask
2550 # Option: Time Offset
2551 payload
+= struct
.pack('>BBL', 2, 4, 0)
2555 payload
+= '\x00\x00\x00\x00'
2558 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2559 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2561 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0) + payload
2564 tot_len
= force_tot_len
2566 tot_len
= 20 + len(udp
)
2567 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
2568 ipv4
= start
+ '\x00\x00' + _ip_src
+ _ip_dst
2569 csum
= ip_checksum(ipv4
)
2570 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
2572 return ehdr
+ ipv4
+ udp
2574 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
2575 target_mac
, target_ip
):
2576 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2577 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2579 ehdr
= _dst_ll
+ _src_ll
+ proto
2581 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':',''))
2582 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
2583 _target_mac
= binascii
.unhexlify(target_mac
.replace(':',''))
2584 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
2586 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
2587 arp
+= _sender_mac
+ _sender_ip
2588 arp
+= _target_mac
+ _target_ip
2592 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
2593 sender_mac
=None, sender_ip
="0.0.0.0",
2594 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
2599 if sender_mac
is None:
2600 sender_mac
= hapd_bssid
2601 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2604 src_ll
= dev
.p2p_interface_addr()
2605 if sender_mac
is None:
2606 sender_mac
= dev
.p2p_interface_addr()
2607 cmd
= "DATA_TEST_FRAME "
2609 pkt
= build_arp(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=src_ll
, opcode
=opcode
,
2610 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
2611 target_mac
=target_mac
, target_ip
=target_ip
)
2612 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2613 raise Exception("DATA_TEST_FRAME failed")
2615 def get_permanent_neighbors(ifname
):
2616 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
2617 res
= cmd
.stdout
.read()
2619 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
2621 def _test_proxyarp_open(dev
, apdev
, params
):
2622 cap_br
= os
.path
.join(params
['logdir'], "proxyarp_open.ap-br0.pcap")
2623 cap_dev0
= os
.path
.join(params
['logdir'], "proxyarp_open.%s.pcap" % dev
[0].ifname
)
2624 cap_dev1
= os
.path
.join(params
['logdir'], "proxyarp_open.%s.pcap" % dev
[1].ifname
)
2626 bssid
= apdev
[0]['bssid']
2627 params
= { 'ssid': 'open' }
2628 params
['proxy_arp'] = '1'
2629 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2630 hapd
.set("ap_isolate", "1")
2631 hapd
.set('bridge', 'ap-br0')
2636 # For now, do not report failures due to missing kernel support
2637 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2639 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2641 raise Exception("AP startup timed out")
2642 if "AP-ENABLED" not in ev
:
2643 raise Exception("AP startup failed")
2645 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2646 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2649 cmd
[0] = subprocess
.Popen(['tcpdump', '-i', 'ap-br0', '-w', cap_br
,
2650 '-s', '2000'], stderr
=open('/dev/null', 'w'))
2651 cmd
[1] = subprocess
.Popen(['tcpdump', '-i', dev
[0].ifname
, '-w', cap_dev0
,
2652 '-s', '2000'], stderr
=open('/dev/null', 'w'))
2653 cmd
[2] = subprocess
.Popen(['tcpdump', '-i', dev
[1].ifname
, '-w', cap_dev1
,
2654 '-s', '2000'], stderr
=open('/dev/null', 'w'))
2656 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2657 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2660 addr0
= dev
[0].p2p_interface_addr()
2661 addr1
= dev
[1].p2p_interface_addr()
2663 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2664 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2667 pkt
= build_ns(src_ll
=addr0
, ip_src
="::", ip_dst
="ff02::1:ff00:2",
2668 target
="aaaa:bbbb:cccc::2", opt
=src_ll_opt0
)
2669 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2670 raise Exception("DATA_TEST_FRAME failed")
2672 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2673 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2675 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2676 raise Exception("DATA_TEST_FRAME failed")
2677 # test frame without source link-layer address option
2678 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2679 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2")
2680 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2681 raise Exception("DATA_TEST_FRAME failed")
2682 # test frame with bogus option
2683 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2684 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2685 opt
="\x70\x01\x01\x02\x03\x04\x05\x05")
2686 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2687 raise Exception("DATA_TEST_FRAME failed")
2688 # test frame with truncated source link-layer address option
2689 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2690 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2691 opt
="\x01\x01\x01\x02\x03\x04")
2692 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2693 raise Exception("DATA_TEST_FRAME failed")
2694 # test frame with foreign source link-layer address option
2695 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2696 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2697 opt
="\x01\x01\x01\x02\x03\x04\x05\x06")
2698 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2699 raise Exception("DATA_TEST_FRAME failed")
2701 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2702 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2704 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2705 raise Exception("DATA_TEST_FRAME failed")
2707 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2708 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2710 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2711 raise Exception("DATA_TEST_FRAME failed")
2712 # another copy for additional code coverage
2713 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2714 raise Exception("DATA_TEST_FRAME failed")
2716 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2717 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2718 yiaddr
="192.168.1.124", chaddr
=addr0
)
2719 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2720 raise Exception("DATA_TEST_FRAME failed")
2721 # Change address and verify unicast
2722 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2723 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2724 yiaddr
="192.168.1.123", chaddr
=addr0
)
2725 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2726 raise Exception("DATA_TEST_FRAME failed")
2728 # Not-associated client MAC address
2729 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2730 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2731 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
2732 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2733 raise Exception("DATA_TEST_FRAME failed")
2736 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2737 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2738 yiaddr
="0.0.0.0", chaddr
=addr1
)
2739 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2740 raise Exception("DATA_TEST_FRAME failed")
2743 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2744 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2745 yiaddr
="192.168.1.126", chaddr
=addr1
,
2746 subnet_mask
="0.0.0.0")
2747 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2748 raise Exception("DATA_TEST_FRAME failed")
2751 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2752 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2753 yiaddr
="192.168.1.127", chaddr
=addr1
,
2755 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2756 raise Exception("DATA_TEST_FRAME failed")
2759 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2760 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2761 yiaddr
="192.168.1.128", chaddr
=addr1
,
2763 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2764 raise Exception("DATA_TEST_FRAME failed")
2766 # Wrong IPv4 total length
2767 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2768 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2769 yiaddr
="192.168.1.129", chaddr
=addr1
,
2771 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2772 raise Exception("DATA_TEST_FRAME failed")
2775 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2776 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2777 yiaddr
="192.168.1.129", chaddr
=addr1
,
2779 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2780 raise Exception("DATA_TEST_FRAME failed")
2782 matches
= get_permanent_neighbors("ap-br0")
2783 logger
.info("After connect: " + str(matches
))
2784 if len(matches
) != 4:
2785 raise Exception("Unexpected number of neighbor entries after connect")
2786 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2787 raise Exception("dev0 addr missing")
2788 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2789 raise Exception("dev1 addr(1) missing")
2790 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2791 raise Exception("dev1 addr(2) missing")
2792 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2793 raise Exception("dev0 IPv4 addr missing")
2795 targets
= [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
2797 for target
in targets
:
2798 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
2800 for target
in targets
:
2801 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
2804 # ARP Probe from wireless STA
2805 send_arp(dev
[1], target_ip
="192.168.1.127")
2806 # ARP Announcement from wireless STA
2807 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
2808 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
2811 matches
= get_permanent_neighbors("ap-br0")
2812 logger
.info("After ARP Probe + Announcement: " + str(matches
))
2814 # ARP Request for the newly introduced IP address from wireless STA
2815 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
2817 # ARP Request for the newly introduced IP address from bridge
2818 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
2819 target_ip
="192.168.1.127")
2821 # ARP Probe from bridge
2822 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.128")
2823 # ARP Announcement from bridge
2824 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="129.168.1.128",
2825 target_ip
="192.168.1.128")
2826 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="129.168.1.128",
2827 target_ip
="192.168.1.128", opcode
=2)
2829 matches
= get_permanent_neighbors("ap-br0")
2830 logger
.info("After ARP Probe + Announcement: " + str(matches
))
2832 # ARP Request for the newly introduced IP address from wireless STA
2833 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.128")
2835 # ARP Request for the newly introduced IP address from bridge
2836 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
2837 target_ip
="192.168.1.128")
2839 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
2840 send_arp(dev
[1], target_ip
="192.168.1.123")
2841 # ARP Probe from wireless STA (duplicate address; learned through ARP)
2842 send_arp(dev
[0], target_ip
="192.168.1.127")
2844 # Gratuitous ARP Reply for another STA's IP address
2845 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
2846 target_mac
=addr1
, target_ip
="192.168.1.127")
2847 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
2848 target_mac
=addr0
, target_ip
="192.168.1.123")
2849 # ARP Request to verify previous mapping
2850 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
2851 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
2855 dev
[0].request("DISCONNECT")
2856 dev
[1].request("DISCONNECT")
2860 matches
= get_permanent_neighbors("ap-br0")
2861 logger
.info("After disconnect: " + str(matches
))
2862 if len(matches
) > 0:
2863 raise Exception("Unexpected neighbor entries after disconnect")
2865 def test_proxyarp_open(dev
, apdev
, params
):
2866 """ProxyARP with open network"""
2869 res
= _test_proxyarp_open(dev
, apdev
, params
)
2871 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2872 stderr
=open('/dev/null', 'w'))
2873 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2874 stderr
=open('/dev/null', 'w'))