]>
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 "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2007 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2008 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2009 raise Exception("HS20_ICON_REQUEST failed")
2012 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2013 "RX-HS20-ANQP-ICON"], timeout
=15)
2015 raise Exception("Timeout on OSU fetch")
2016 if "OSU provider fetch completed" in ev
:
2018 if "RX-HS20-ANQP-ICON" in ev
:
2019 with
open(ev
.split(' ')[1], "r") as f
:
2021 if logo
== orig_logo
:
2024 with
open(dir + "/osu-providers.txt", "r") as f
:
2026 if "OSU-PROVIDER " + bssid
not in prov
:
2027 raise Exception("Missing OSU_PROVIDER")
2028 if "OSU-PROVIDER " + bssid2
not in prov
:
2029 raise Exception("Missing OSU_PROVIDER")
2031 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2033 os
.remove(dir + "/" + f
)
2037 raise Exception("Unexpected number of icons fetched")
2039 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2041 raise Exception("Timeout on GAS-QUERY-DONE")
2042 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2044 raise Exception("Timeout on GAS-QUERY-DONE")
2045 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2046 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2047 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2049 raise Exception("Timeout on icon fetch")
2050 if "Icon Binary File" not in ev
:
2051 raise Exception("Unexpected ANQP element")
2053 def test_ap_hs20_ft(dev
, apdev
):
2054 """Hotspot 2.0 connection with FT"""
2055 bssid
= apdev
[0]['bssid']
2056 params
= hs20_ap_params()
2057 params
['wpa_key_mgmt'] = "FT-EAP"
2058 params
['nas_identifier'] = "nas1.w1.fi"
2059 params
['r1_key_holder'] = "000102030405"
2060 params
["mobility_domain"] = "a1b2"
2061 params
["reassociation_deadline"] = "1000"
2062 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2064 dev
[0].hs20_enable()
2065 id = dev
[0].add_cred_values({ 'realm': "example.com",
2066 'username': "hs20-test",
2067 'password': "password",
2068 'ca_cert': "auth_serv/ca.pem",
2069 'domain': "example.com",
2070 'update_identifier': "1234" })
2071 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2072 interworking_connect(dev
[0], bssid
, "TTLS")
2074 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
2075 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2080 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
2085 con
= sqlite3
.connect(dbfile
)
2088 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2089 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2090 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2091 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2092 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2095 params
= { "ssid": "as", "beacon_int": "2000",
2096 "radius_server_clients": "auth_serv/radius_clients.conf",
2097 "radius_server_auth_port": '18128',
2099 "eap_user_file": "sqlite:" + dbfile
,
2100 "ca_cert": "auth_serv/ca.pem",
2101 "server_cert": "auth_serv/server.pem",
2102 "private_key": "auth_serv/server.key",
2103 "subscr_remediation_url": "https://example.org/",
2104 "subscr_remediation_method": "1" }
2105 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2107 bssid
= apdev
[0]['bssid']
2108 params
= hs20_ap_params()
2109 params
['auth_server_port'] = "18128"
2110 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2112 dev
[0].request("SET pmf 1")
2113 dev
[0].hs20_enable()
2114 id = dev
[0].add_cred_values({ 'realm': "example.com",
2115 'username': "user-mschapv2",
2116 'password': "password",
2117 'ca_cert': "auth_serv/ca.pem" })
2118 interworking_select(dev
[0], bssid
, freq
="2412")
2119 interworking_connect(dev
[0], bssid
, "TTLS")
2120 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2122 raise Exception("Timeout on subscription remediation notice")
2123 if " 1 https://example.org/" not in ev
:
2124 raise Exception("Unexpected subscription remediation event contents")
2128 cur
.execute("SELECT * from authlog")
2129 rows
= cur
.fetchall()
2131 raise Exception("No authlog entries")
2136 def test_ap_hs20_external_selection(dev
, apdev
):
2137 """Hotspot 2.0 connection using external network selection and creation"""
2138 bssid
= apdev
[0]['bssid']
2139 params
= hs20_ap_params()
2140 params
['hessid'] = bssid
2141 params
['disable_dgaf'] = '1'
2142 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2144 dev
[0].hs20_enable()
2145 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
2146 identity
="hs20-test", password
="password",
2147 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2148 scan_freq
="2412", update_identifier
="54321")
2149 if dev
[0].get_status_field("hs20") != "2":
2150 raise Exception("Unexpected hs20 indication")
2152 def test_ap_hs20_random_mac_addr(dev
, apdev
):
2153 """Hotspot 2.0 connection with random MAC address"""
2154 bssid
= apdev
[0]['bssid']
2155 params
= hs20_ap_params()
2156 params
['hessid'] = bssid
2157 params
['disable_dgaf'] = '1'
2158 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2160 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2161 wpas
.interface_add("wlan5")
2162 addr
= wpas
.p2p_interface_addr()
2163 wpas
.request("SET mac_addr 1")
2164 wpas
.request("SET preassoc_mac_addr 1")
2165 wpas
.request("SET rand_addr_lifetime 60")
2167 wpas
.flush_scan_cache()
2168 id = wpas
.add_cred_values({ 'realm': "example.com",
2169 'username': "hs20-test",
2170 'password': "password",
2171 'ca_cert': "auth_serv/ca.pem",
2172 'domain': "example.com",
2173 'update_identifier': "1234" })
2174 interworking_select(wpas
, bssid
, "home", freq
="2412")
2175 interworking_connect(wpas
, bssid
, "TTLS")
2176 addr1
= wpas
.get_driver_status_field("addr")
2178 raise Exception("Did not use random MAC address")
2180 sta
= hapd
.get_sta(addr
)
2181 if sta
['addr'] != "FAIL":
2182 raise Exception("Unexpected STA association with permanent address")
2183 sta
= hapd
.get_sta(addr1
)
2184 if sta
['addr'] != addr1
:
2185 raise Exception("STA association with random address not found")
2187 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
2188 """Multiple networks and cred removal"""
2189 bssid
= apdev
[0]['bssid']
2190 params
= hs20_ap_params()
2191 params
['nai_realm'] = [ "0,example.com,25[3:26]"]
2192 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2194 dev
[0].add_network()
2195 dev
[0].hs20_enable()
2196 id = dev
[0].add_cred_values({ 'realm': "example.com",
2198 'password': "password" })
2199 interworking_select(dev
[0], bssid
, freq
="2412")
2200 interworking_connect(dev
[0], bssid
, "PEAP")
2201 dev
[0].add_network()
2203 dev
[0].request("DISCONNECT")
2204 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
2206 raise Exception("Timeout on disconnection")
2209 hapd
.set("ssid", "another ssid")
2212 interworking_select(dev
[0], bssid
, freq
="2412")
2213 interworking_connect(dev
[0], bssid
, "PEAP")
2214 dev
[0].add_network()
2215 if len(dev
[0].list_networks()) != 5:
2216 raise Exception("Unexpected number of networks prior to remove_crec")
2218 dev
[0].dump_monitor()
2219 dev
[0].remove_cred(id)
2220 if len(dev
[0].list_networks()) != 3:
2221 raise Exception("Unexpected number of networks after to remove_crec")
2222 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
2224 raise Exception("Timeout on disconnection")
2226 def _test_ap_hs20_proxyarp(dev
, apdev
):
2227 bssid
= apdev
[0]['bssid']
2228 params
= hs20_ap_params()
2229 params
['hessid'] = bssid
2230 params
['disable_dgaf'] = '0'
2231 params
['proxy_arp'] = '1'
2232 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2233 if "OK" in hapd
.request("ENABLE"):
2234 raise Exception("Incomplete hostapd configuration was accepted")
2235 hapd
.set("ap_isolate", "1")
2236 if "OK" in hapd
.request("ENABLE"):
2237 raise Exception("Incomplete hostapd configuration was accepted")
2238 hapd
.set('bridge', 'ap-br0')
2243 # For now, do not report failures due to missing kernel support
2244 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2246 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2248 raise Exception("AP startup timed out")
2249 if "AP-ENABLED" not in ev
:
2250 raise Exception("AP startup failed")
2252 dev
[0].hs20_enable()
2253 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2254 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2256 id = dev
[0].add_cred_values({ 'realm': "example.com",
2257 'username': "hs20-test",
2258 'password': "password",
2259 'ca_cert': "auth_serv/ca.pem",
2260 'domain': "example.com",
2261 'update_identifier': "1234" })
2262 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2263 interworking_connect(dev
[0], bssid
, "TTLS")
2265 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2266 identity
="hs20-test", password
="password",
2267 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2271 addr0
= dev
[0].p2p_interface_addr()
2272 addr1
= dev
[1].p2p_interface_addr()
2274 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2275 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2277 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2278 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2280 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2281 raise Exception("DATA_TEST_FRAME failed")
2283 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2284 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2286 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2287 raise Exception("DATA_TEST_FRAME failed")
2289 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2290 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2292 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2293 raise Exception("DATA_TEST_FRAME failed")
2295 matches
= get_permanent_neighbors("ap-br0")
2296 logger
.info("After connect: " + str(matches
))
2297 if len(matches
) != 3:
2298 raise Exception("Unexpected number of neighbor entries after connect")
2299 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2300 raise Exception("dev0 addr missing")
2301 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2302 raise Exception("dev1 addr(1) missing")
2303 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2304 raise Exception("dev1 addr(2) missing")
2305 dev
[0].request("DISCONNECT")
2306 dev
[1].request("DISCONNECT")
2308 matches
= get_permanent_neighbors("ap-br0")
2309 logger
.info("After disconnect: " + str(matches
))
2310 if len(matches
) > 0:
2311 raise Exception("Unexpected neighbor entries after disconnect")
2313 def test_ap_hs20_proxyarp(dev
, apdev
):
2314 """Hotspot 2.0 and ProxyARP"""
2317 res
= _test_ap_hs20_proxyarp(dev
, apdev
)
2319 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2320 stderr
=open('/dev/null', 'w'))
2321 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2322 stderr
=open('/dev/null', 'w'))
2326 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
2327 bssid
= apdev
[0]['bssid']
2328 params
= hs20_ap_params()
2329 params
['hessid'] = bssid
2330 params
['disable_dgaf'] = '1' if disabled
else '0'
2331 params
['proxy_arp'] = '1'
2332 params
['ap_isolate'] = '1'
2333 params
['bridge'] = 'ap-br0'
2334 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2338 # For now, do not report failures due to missing kernel support
2339 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2341 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
2343 raise Exception("AP startup timed out")
2345 dev
[0].hs20_enable()
2346 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2347 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2349 id = dev
[0].add_cred_values({ 'realm': "example.com",
2350 'username': "hs20-test",
2351 'password': "password",
2352 'ca_cert': "auth_serv/ca.pem",
2353 'domain': "example.com",
2354 'update_identifier': "1234" })
2355 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2356 interworking_connect(dev
[0], bssid
, "TTLS")
2358 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2359 identity
="hs20-test", password
="password",
2360 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2364 addr0
= dev
[0].p2p_interface_addr()
2366 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2368 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2369 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2371 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2372 raise Exception("DATA_TEST_FRAME failed")
2374 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
2376 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2377 raise Exception("DATA_TEST_FRAME failed")
2379 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
2380 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
2381 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2382 raise Exception("DATA_TEST_FRAME failed")
2384 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2385 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2386 yiaddr
="192.168.1.123", chaddr
=addr0
)
2387 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2388 raise Exception("DATA_TEST_FRAME failed")
2389 # another copy for additional code coverage
2390 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2391 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2392 yiaddr
="192.168.1.123", chaddr
=addr0
)
2393 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2394 raise Exception("DATA_TEST_FRAME failed")
2396 matches
= get_permanent_neighbors("ap-br0")
2397 logger
.info("After connect: " + str(matches
))
2398 if len(matches
) != 2:
2399 raise Exception("Unexpected number of neighbor entries after connect")
2400 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2401 raise Exception("dev0 addr missing")
2402 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2403 raise Exception("dev0 IPv4 addr missing")
2404 dev
[0].request("DISCONNECT")
2405 dev
[1].request("DISCONNECT")
2407 matches
= get_permanent_neighbors("ap-br0")
2408 logger
.info("After disconnect: " + str(matches
))
2409 if len(matches
) > 0:
2410 raise Exception("Unexpected neighbor entries after disconnect")
2412 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
2413 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
2416 res
= _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
2418 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2419 stderr
=open('/dev/null', 'w'))
2420 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2421 stderr
=open('/dev/null', 'w'))
2425 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
2426 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
2429 res
= _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
2431 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2432 stderr
=open('/dev/null', 'w'))
2433 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2434 stderr
=open('/dev/null', 'w'))
2438 def ip_checksum(buf
):
2442 for i
in range(0, len(buf
), 2):
2443 val
, = struct
.unpack('H', buf
[i
:i
+2])
2446 sum = (sum & 0xffff) + (sum >> 16)
2447 return struct
.pack('H', ~
sum & 0xffff)
2449 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
2450 start
= struct
.pack("BB", type, code
)
2452 icmp
= start
+ '\x00\x00' + end
2453 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
2454 csum
= ip_checksum(pseudo
+ icmp
)
2455 return start
+ csum
+ end
2457 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
2458 reachable_time
=0, retrans_timer
=0, opt
=None):
2459 link_mc
= binascii
.unhexlify("3333ff000002")
2460 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2462 ehdr
= link_mc
+ _src_ll
+ proto
2463 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2464 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2466 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
2467 reachable_time
, retrans_timer
)
2472 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
2474 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2475 ipv6
+= _ip_src
+ _ip_dst
2477 return ehdr
+ ipv6
+ icmp
2479 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2480 link_mc
= binascii
.unhexlify("3333ff000002")
2481 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2483 ehdr
= link_mc
+ _src_ll
+ proto
2484 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2485 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2487 reserved
= '\x00\x00\x00\x00'
2488 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2490 payload
= reserved
+ _target
+ opt
2492 payload
= reserved
+ _target
2493 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
2495 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2496 ipv6
+= _ip_src
+ _ip_dst
2498 return ehdr
+ ipv6
+ icmp
2500 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2501 link_mc
= binascii
.unhexlify("3333ff000002")
2502 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2504 ehdr
= link_mc
+ _src_ll
+ proto
2505 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2506 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2508 reserved
= '\x00\x00\x00\x00'
2509 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2511 payload
= reserved
+ _target
+ opt
2513 payload
= reserved
+ _target
2514 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
2516 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2517 ipv6
+= _ip_src
+ _ip_dst
2519 return ehdr
+ ipv6
+ icmp
2521 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
2522 subnet_mask
="255.255.255.0", truncated_opt
=False,
2523 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False):
2524 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2525 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2527 ehdr
= _dst_ll
+ _src_ll
+ proto
2528 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
2529 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
2530 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
2532 _ciaddr
= '\x00\x00\x00\x00'
2533 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
2534 _siaddr
= '\x00\x00\x00\x00'
2535 _giaddr
= '\x00\x00\x00\x00'
2536 _chaddr
= binascii
.unhexlify(chaddr
.replace(':','') + "00000000000000000000")
2537 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2538 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2541 payload
+= '\x63\x82\x53\x00'
2543 payload
+= '\x63\x82\x53\x63'
2545 payload
+= '\x22\xff\x00'
2546 # Option: DHCP Message Type = ACK
2547 payload
+= '\x35\x01\x05'
2550 # Option: Subnet Mask
2551 payload
+= '\x01\x04' + _subnet_mask
2552 # Option: Time Offset
2553 payload
+= struct
.pack('>BBL', 2, 4, 0)
2557 payload
+= '\x00\x00\x00\x00'
2560 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2561 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2563 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0) + payload
2566 tot_len
= force_tot_len
2568 tot_len
= 20 + len(udp
)
2569 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
2570 ipv4
= start
+ '\x00\x00' + _ip_src
+ _ip_dst
2571 csum
= ip_checksum(ipv4
)
2572 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
2574 return ehdr
+ ipv4
+ udp
2576 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
2577 target_mac
, target_ip
):
2578 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2579 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2581 ehdr
= _dst_ll
+ _src_ll
+ proto
2583 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':',''))
2584 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
2585 _target_mac
= binascii
.unhexlify(target_mac
.replace(':',''))
2586 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
2588 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
2589 arp
+= _sender_mac
+ _sender_ip
2590 arp
+= _target_mac
+ _target_ip
2594 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
2595 sender_mac
=None, sender_ip
="0.0.0.0",
2596 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
2601 if sender_mac
is None:
2602 sender_mac
= hapd_bssid
2603 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2606 src_ll
= dev
.p2p_interface_addr()
2607 if sender_mac
is None:
2608 sender_mac
= dev
.p2p_interface_addr()
2609 cmd
= "DATA_TEST_FRAME "
2611 pkt
= build_arp(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=src_ll
, opcode
=opcode
,
2612 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
2613 target_mac
=target_mac
, target_ip
=target_ip
)
2614 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2615 raise Exception("DATA_TEST_FRAME failed")
2617 def get_permanent_neighbors(ifname
):
2618 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
2619 res
= cmd
.stdout
.read()
2621 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
2623 def _test_proxyarp_open(dev
, apdev
, params
):
2624 cap_br
= os
.path
.join(params
['logdir'], "proxyarp_open.ap-br0.pcap")
2625 cap_dev0
= os
.path
.join(params
['logdir'], "proxyarp_open.%s.pcap" % dev
[0].ifname
)
2626 cap_dev1
= os
.path
.join(params
['logdir'], "proxyarp_open.%s.pcap" % dev
[1].ifname
)
2628 bssid
= apdev
[0]['bssid']
2629 params
= { 'ssid': 'open' }
2630 params
['proxy_arp'] = '1'
2631 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2632 hapd
.set("ap_isolate", "1")
2633 hapd
.set('bridge', 'ap-br0')
2638 # For now, do not report failures due to missing kernel support
2639 logger
.info("Could not start hostapd - assume proxyarp not supported in kernel version")
2641 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2643 raise Exception("AP startup timed out")
2644 if "AP-ENABLED" not in ev
:
2645 raise Exception("AP startup failed")
2647 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2648 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2651 cmd
[0] = subprocess
.Popen(['tcpdump', '-i', 'ap-br0', '-w', cap_br
,
2652 '-s', '2000'], stderr
=open('/dev/null', 'w'))
2653 cmd
[1] = subprocess
.Popen(['tcpdump', '-i', dev
[0].ifname
, '-w', cap_dev0
,
2654 '-s', '2000'], stderr
=open('/dev/null', 'w'))
2655 cmd
[2] = subprocess
.Popen(['tcpdump', '-i', dev
[1].ifname
, '-w', cap_dev1
,
2656 '-s', '2000'], stderr
=open('/dev/null', 'w'))
2658 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2659 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2662 addr0
= dev
[0].p2p_interface_addr()
2663 addr1
= dev
[1].p2p_interface_addr()
2665 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2666 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2669 pkt
= build_ns(src_ll
=addr0
, ip_src
="::", ip_dst
="ff02::1:ff00:2",
2670 target
="aaaa:bbbb:cccc::2", opt
=src_ll_opt0
)
2671 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2672 raise Exception("DATA_TEST_FRAME failed")
2674 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2675 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2677 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2678 raise Exception("DATA_TEST_FRAME failed")
2679 # test frame without source link-layer address option
2680 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2681 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2")
2682 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2683 raise Exception("DATA_TEST_FRAME failed")
2684 # test frame with bogus option
2685 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2686 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2687 opt
="\x70\x01\x01\x02\x03\x04\x05\x05")
2688 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2689 raise Exception("DATA_TEST_FRAME failed")
2690 # test frame with truncated source link-layer address option
2691 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2692 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2693 opt
="\x01\x01\x01\x02\x03\x04")
2694 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2695 raise Exception("DATA_TEST_FRAME failed")
2696 # test frame with foreign source link-layer address option
2697 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2698 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2699 opt
="\x01\x01\x01\x02\x03\x04\x05\x06")
2700 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2701 raise Exception("DATA_TEST_FRAME failed")
2703 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2704 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2706 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2707 raise Exception("DATA_TEST_FRAME failed")
2709 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2710 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2712 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2713 raise Exception("DATA_TEST_FRAME failed")
2714 # another copy for additional code coverage
2715 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2716 raise Exception("DATA_TEST_FRAME failed")
2718 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2719 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2720 yiaddr
="192.168.1.124", chaddr
=addr0
)
2721 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2722 raise Exception("DATA_TEST_FRAME failed")
2723 # Change address and verify unicast
2724 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2725 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2726 yiaddr
="192.168.1.123", chaddr
=addr0
)
2727 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2728 raise Exception("DATA_TEST_FRAME failed")
2730 # Not-associated client MAC address
2731 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2732 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2733 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
2734 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2735 raise Exception("DATA_TEST_FRAME failed")
2738 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2739 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2740 yiaddr
="0.0.0.0", chaddr
=addr1
)
2741 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2742 raise Exception("DATA_TEST_FRAME failed")
2745 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2746 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2747 yiaddr
="192.168.1.126", chaddr
=addr1
,
2748 subnet_mask
="0.0.0.0")
2749 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2750 raise Exception("DATA_TEST_FRAME failed")
2753 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2754 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2755 yiaddr
="192.168.1.127", chaddr
=addr1
,
2757 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2758 raise Exception("DATA_TEST_FRAME failed")
2761 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2762 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2763 yiaddr
="192.168.1.128", chaddr
=addr1
,
2765 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2766 raise Exception("DATA_TEST_FRAME failed")
2768 # Wrong IPv4 total length
2769 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2770 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2771 yiaddr
="192.168.1.129", chaddr
=addr1
,
2773 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2774 raise Exception("DATA_TEST_FRAME failed")
2777 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2778 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2779 yiaddr
="192.168.1.129", chaddr
=addr1
,
2781 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2782 raise Exception("DATA_TEST_FRAME failed")
2784 matches
= get_permanent_neighbors("ap-br0")
2785 logger
.info("After connect: " + str(matches
))
2786 if len(matches
) != 4:
2787 raise Exception("Unexpected number of neighbor entries after connect")
2788 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2789 raise Exception("dev0 addr missing")
2790 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2791 raise Exception("dev1 addr(1) missing")
2792 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2793 raise Exception("dev1 addr(2) missing")
2794 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2795 raise Exception("dev0 IPv4 addr missing")
2797 targets
= [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
2799 for target
in targets
:
2800 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
2802 for target
in targets
:
2803 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
2806 # ARP Probe from wireless STA
2807 send_arp(dev
[1], target_ip
="192.168.1.127")
2808 # ARP Announcement from wireless STA
2809 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
2810 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
2813 matches
= get_permanent_neighbors("ap-br0")
2814 logger
.info("After ARP Probe + Announcement: " + str(matches
))
2816 # ARP Request for the newly introduced IP address from wireless STA
2817 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
2819 # ARP Request for the newly introduced IP address from bridge
2820 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
2821 target_ip
="192.168.1.127")
2823 # ARP Probe from bridge
2824 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.128")
2825 # ARP Announcement from bridge
2826 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="129.168.1.128",
2827 target_ip
="192.168.1.128")
2828 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="129.168.1.128",
2829 target_ip
="192.168.1.128", opcode
=2)
2831 matches
= get_permanent_neighbors("ap-br0")
2832 logger
.info("After ARP Probe + Announcement: " + str(matches
))
2834 # ARP Request for the newly introduced IP address from wireless STA
2835 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.128")
2837 # ARP Request for the newly introduced IP address from bridge
2838 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
2839 target_ip
="192.168.1.128")
2841 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
2842 send_arp(dev
[1], target_ip
="192.168.1.123")
2843 # ARP Probe from wireless STA (duplicate address; learned through ARP)
2844 send_arp(dev
[0], target_ip
="192.168.1.127")
2846 # Gratuitous ARP Reply for another STA's IP address
2847 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
2848 target_mac
=addr1
, target_ip
="192.168.1.127")
2849 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
2850 target_mac
=addr0
, target_ip
="192.168.1.123")
2851 # ARP Request to verify previous mapping
2852 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
2853 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
2857 dev
[0].request("DISCONNECT")
2858 dev
[1].request("DISCONNECT")
2862 matches
= get_permanent_neighbors("ap-br0")
2863 logger
.info("After disconnect: " + str(matches
))
2864 if len(matches
) > 0:
2865 raise Exception("Unexpected neighbor entries after disconnect")
2867 def test_proxyarp_open(dev
, apdev
, params
):
2868 """ProxyARP with open network"""
2871 res
= _test_proxyarp_open(dev
, apdev
, params
)
2873 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2874 stderr
=open('/dev/null', 'w'))
2875 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2876 stderr
=open('/dev/null', 'w'))