]>
git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_hs20.py
4 # Copyright (c) 2013, Jouni Malinen <j@w1.fi>
6 # This software may be distributed under the terms of the BSD license.
7 # See README for more details.
12 logger
= logging
.getLogger()
17 from wlantest
import Wlantest
20 params
= hostapd
.wpa2_params(ssid
="test-hs20")
21 params
['wpa_key_mgmt'] = "WPA-EAP"
22 params
['ieee80211w'] = "1"
23 params
['ieee8021x'] = "1"
24 params
['auth_server_addr'] = "127.0.0.1"
25 params
['auth_server_port'] = "1812"
26 params
['auth_server_shared_secret'] = "radius"
27 params
['interworking'] = "1"
28 params
['access_network_type'] = "14"
29 params
['internet'] = "1"
33 params
['venue_group'] = "7"
34 params
['venue_type'] = "1"
35 params
['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
36 params
['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
38 params
['domain_name'] = "example.com,another.example.com"
39 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
40 "0,another.example.com" ]
42 params
['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
43 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
44 params
['hs20_operating_class'] = "5173"
45 params
['anqp_3gpp_cell_net'] = "244,91"
48 def interworking_select(dev
, bssid
, type=None, no_match
=False):
50 dev
.request("INTERWORKING_SELECT")
51 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
54 raise Exception("Network selection timed out");
56 if "INTERWORKING-NO-MATCH" not in ev
:
57 raise Exception("Unexpected network match")
59 if "INTERWORKING-NO-MATCH" in ev
:
60 raise Exception("Matching network not found")
61 if bssid
and bssid
not in ev
:
62 raise Exception("Unexpected BSSID in match")
63 if type and "type=" + type not in ev
:
64 raise Exception("Network type not recognized correctly")
66 def check_sp_type(dev
, sp_type
):
67 type = dev
.get_status_field("sp_type")
69 raise Exception("sp_type not available")
71 raise Exception("sp_type did not indicate home network")
73 def hlr_auc_gw_available():
74 if not os
.path
.exists("/tmp/hlr_auc_gw.sock"):
75 logger
.info("No hlr_auc_gw available");
77 if not os
.path
.exists("../../hostapd/hlr_auc_gw"):
78 logger
.info("No hlr_auc_gw available");
82 def interworking_ext_sim_connect(dev
, bssid
, method
):
83 dev
.request("INTERWORKING_CONNECT " + bssid
)
85 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
87 raise Exception("Network connected timed out")
88 if "(" + method
+ ")" not in ev
:
89 raise Exception("Unexpected EAP method selection")
91 ev
= dev
.wait_event(["CTRL-REQ-SIM"], timeout
=15)
93 raise Exception("Wait for external SIM processing request timed out")
95 if p
[1] != "GSM-AUTH":
96 raise Exception("Unexpected CTRL-REQ-SIM type")
97 id = p
[0].split('-')[3]
98 rand
= p
[2].split(' ')[0]
100 res
= subprocess
.check_output(["../../hostapd/hlr_auc_gw",
102 "auth_serv/hlr_auc_gw.milenage_db",
103 "GSM-AUTH-REQ 232010000000000 " + rand
])
104 if "GSM-AUTH-RESP" not in res
:
105 raise Exception("Unexpected hlr_auc_gw response")
106 resp
= res
.split(' ')[2].rstrip()
108 dev
.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp
)
109 ev
= dev
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
111 raise Exception("Connection timed out")
113 def interworking_connect(dev
, bssid
, method
):
114 dev
.request("INTERWORKING_CONNECT " + bssid
)
116 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
118 raise Exception("Network connected timed out")
119 if "(" + method
+ ")" not in ev
:
120 raise Exception("Unexpected EAP method selection")
122 ev
= dev
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=15)
124 raise Exception("Connection timed out")
126 def check_probe_resp(wt
, bssid_unexpected
, bssid_expected
):
128 count
= wt
.get_bss_counter("probe_response", bssid_unexpected
)
130 raise Exception("Unexpected Probe Response frame from AP")
133 count
= wt
.get_bss_counter("probe_response", bssid_expected
)
135 raise Exception("No Probe Response frame from AP")
137 def test_ap_anqp_sharing(dev
, apdev
):
138 """ANQP sharing within ESS and explicit unshare"""
139 bssid
= apdev
[0]['bssid']
140 params
= hs20_ap_params()
141 params
['hessid'] = bssid
142 hostapd
.add_ap(apdev
[0]['ifname'], params
)
144 bssid2
= apdev
[1]['bssid']
145 params
= hs20_ap_params()
146 params
['hessid'] = bssid
147 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
148 hostapd
.add_ap(apdev
[1]['ifname'], params
)
150 dev
[0].request("SET ignore_old_scan_res 1")
152 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
153 'password': "secret",
154 'domain': "example.com" })
155 logger
.info("Normal network selection with shared ANQP results")
156 interworking_select(dev
[0], None, "home")
157 dev
[0].dump_monitor()
159 res1
= dev
[0].get_bss(bssid
)
160 res2
= dev
[0].get_bss(bssid2
)
161 if res1
['anqp_nai_realm'] != res2
['anqp_nai_realm']:
162 raise Exception("ANQP results were not shared between BSSes")
164 logger
.info("Explicit ANQP request to unshare ANQP results")
165 dev
[0].request("ANQP_GET " + bssid
+ " 263")
166 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
168 raise Exception("ANQP operation timed out")
170 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
171 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
173 raise Exception("ANQP operation timed out")
175 res1
= dev
[0].get_bss(bssid
)
176 res2
= dev
[0].get_bss(bssid2
)
177 if res1
['anqp_nai_realm'] == res2
['anqp_nai_realm']:
178 raise Exception("ANQP results were not unshared")
180 def test_ap_interworking_scan_filtering(dev
, apdev
):
181 """Interworking scan filtering with HESSID and access network type"""
182 bssid
= apdev
[0]['bssid']
183 params
= hs20_ap_params()
184 ssid
= "test-hs20-ap1"
185 params
['ssid'] = ssid
186 params
['hessid'] = bssid
187 hostapd
.add_ap(apdev
[0]['ifname'], params
)
189 bssid2
= apdev
[1]['bssid']
190 params
= hs20_ap_params()
191 ssid2
= "test-hs20-ap2"
192 params
['ssid'] = ssid2
193 params
['hessid'] = bssid2
194 params
['access_network_type'] = "1"
195 del params
['venue_group']
196 del params
['venue_type']
197 hostapd
.add_ap(apdev
[1]['ifname'], params
)
199 dev
[0].request("SET ignore_old_scan_res 1")
205 logger
.info("Check probe request filtering based on HESSID")
207 dev
[0].request("SET hessid " + bssid2
)
208 dev
[0].scan(freq
="2412")
209 check_probe_resp(wt
, bssid
, bssid2
)
211 logger
.info("Check probe request filtering based on access network type")
213 wt
.clear_bss_counters(bssid
)
214 wt
.clear_bss_counters(bssid2
)
215 dev
[0].request("SET hessid 00:00:00:00:00:00")
216 dev
[0].request("SET access_network_type 14")
217 dev
[0].scan(freq
="2412")
218 check_probe_resp(wt
, bssid2
, bssid
)
220 wt
.clear_bss_counters(bssid
)
221 wt
.clear_bss_counters(bssid2
)
222 dev
[0].request("SET hessid 00:00:00:00:00:00")
223 dev
[0].request("SET access_network_type 1")
224 dev
[0].scan(freq
="2412")
225 check_probe_resp(wt
, bssid
, bssid2
)
227 logger
.info("Check probe request filtering based on HESSID and ANT")
229 wt
.clear_bss_counters(bssid
)
230 wt
.clear_bss_counters(bssid2
)
231 dev
[0].request("SET hessid " + bssid
)
232 dev
[0].request("SET access_network_type 14")
233 dev
[0].scan(freq
="2412")
234 check_probe_resp(wt
, bssid2
, bssid
)
236 wt
.clear_bss_counters(bssid
)
237 wt
.clear_bss_counters(bssid2
)
238 dev
[0].request("SET hessid " + bssid2
)
239 dev
[0].request("SET access_network_type 14")
240 dev
[0].scan(freq
="2412")
241 check_probe_resp(wt
, bssid
, None)
242 check_probe_resp(wt
, bssid2
, None)
244 wt
.clear_bss_counters(bssid
)
245 wt
.clear_bss_counters(bssid2
)
246 dev
[0].request("SET hessid " + bssid
)
247 dev
[0].request("SET access_network_type 1")
248 dev
[0].scan(freq
="2412")
249 check_probe_resp(wt
, bssid
, None)
250 check_probe_resp(wt
, bssid2
, None)
252 def test_ap_hs20_select(dev
, apdev
):
253 """Hotspot 2.0 network selection"""
254 bssid
= apdev
[0]['bssid']
255 params
= hs20_ap_params()
256 params
['hessid'] = bssid
257 hostapd
.add_ap(apdev
[0]['ifname'], params
)
259 dev
[0].request("SET ignore_old_scan_res 1")
261 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
262 'password': "secret",
263 'domain': "example.com" })
264 interworking_select(dev
[0], bssid
, "home")
266 dev
[0].remove_cred(id)
267 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
268 'password': "secret",
269 'domain': "no.match.example.com" })
270 interworking_select(dev
[0], bssid
, "roaming")
272 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com");
273 interworking_select(dev
[0], bssid
, no_match
=True)
275 def test_ap_hs20_ext_sim(dev
, apdev
):
276 """Hotspot 2.0 with external SIM processing"""
277 if not hlr_auc_gw_available():
279 bssid
= apdev
[0]['bssid']
280 params
= hs20_ap_params()
281 params
['hessid'] = bssid
282 params
['anqp_3gpp_cell_net'] = "232,01"
283 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
284 hostapd
.add_ap(apdev
[0]['ifname'], params
)
286 dev
[0].request("SET ignore_old_scan_res 1")
288 dev
[0].request("SET external_sim 1")
289 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
290 interworking_select(dev
[0], "home")
291 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
292 check_sp_type(dev
[0], "home")
294 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
295 """Hotspot 2.0 with external SIM processing in roaming network"""
296 if not hlr_auc_gw_available():
298 bssid
= apdev
[0]['bssid']
299 params
= hs20_ap_params()
300 params
['hessid'] = bssid
301 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
302 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
303 hostapd
.add_ap(apdev
[0]['ifname'], params
)
305 dev
[0].request("SET ignore_old_scan_res 1")
307 dev
[0].request("SET external_sim 1")
308 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
309 interworking_select(dev
[0], "roaming")
310 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
311 check_sp_type(dev
[0], "roaming")
313 def test_ap_hs20_username(dev
, apdev
):
314 """Hotspot 2.0 connection in username/password credential"""
315 bssid
= apdev
[0]['bssid']
316 params
= hs20_ap_params()
317 params
['hessid'] = bssid
318 hostapd
.add_ap(apdev
[0]['ifname'], params
)
320 dev
[0].request("SET ignore_old_scan_res 1")
322 id = dev
[0].add_cred_values({ 'realm': "example.com",
323 'username': "hs20-test",
324 'password': "password",
325 'domain': "example.com" })
326 interworking_select(dev
[0], bssid
, "home")
327 interworking_connect(dev
[0], bssid
, "TTLS")
328 check_sp_type(dev
[0], "home")
330 def test_ap_hs20_username_roaming(dev
, apdev
):
331 """Hotspot 2.0 connection in username/password credential (roaming)"""
332 bssid
= apdev
[0]['bssid']
333 params
= hs20_ap_params()
334 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
335 "0,roaming.example.com,21[2:4][5:7]",
336 "0,another.example.com" ]
337 params
['domain_name'] = "another.example.com"
338 params
['hessid'] = bssid
339 hostapd
.add_ap(apdev
[0]['ifname'], params
)
341 dev
[0].request("SET ignore_old_scan_res 1")
343 id = dev
[0].add_cred_values({ 'realm': "roaming.example.com",
344 'username': "hs20-test",
345 'password': "password",
346 'domain': "example.com" })
347 interworking_select(dev
[0], bssid
, "roaming")
348 interworking_connect(dev
[0], bssid
, "TTLS")
349 check_sp_type(dev
[0], "roaming")
351 def test_ap_hs20_username_unknown(dev
, apdev
):
352 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
353 bssid
= apdev
[0]['bssid']
354 params
= hs20_ap_params()
355 params
['hessid'] = bssid
356 hostapd
.add_ap(apdev
[0]['ifname'], params
)
358 dev
[0].request("SET ignore_old_scan_res 1")
360 id = dev
[0].add_cred_values({ 'realm': "example.com",
361 'username': "hs20-test",
362 'password': "password" })
363 interworking_select(dev
[0], bssid
, "unknown")
364 interworking_connect(dev
[0], bssid
, "TTLS")
365 check_sp_type(dev
[0], "unknown")
367 def test_ap_hs20_username_unknown2(dev
, apdev
):
368 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
369 bssid
= apdev
[0]['bssid']
370 params
= hs20_ap_params()
371 params
['hessid'] = bssid
372 del params
['domain_name']
373 hostapd
.add_ap(apdev
[0]['ifname'], params
)
375 dev
[0].request("SET ignore_old_scan_res 1")
377 id = dev
[0].add_cred_values({ 'realm': "example.com",
378 'username': "hs20-test",
379 'password': "password",
380 'domain': "example.com" })
381 interworking_select(dev
[0], bssid
, "unknown")
382 interworking_connect(dev
[0], bssid
, "TTLS")
383 check_sp_type(dev
[0], "unknown")
385 def test_ap_hs20_gas_while_associated(dev
, apdev
):
386 """Hotspot 2.0 connection with GAS query while associated"""
387 bssid
= apdev
[0]['bssid']
388 params
= hs20_ap_params()
389 params
['hessid'] = bssid
390 hostapd
.add_ap(apdev
[0]['ifname'], params
)
392 dev
[0].request("SET ignore_old_scan_res 1")
394 id = dev
[0].add_cred_values({ 'realm': "example.com",
395 'username': "hs20-test",
396 'password': "password",
397 'domain': "example.com" })
398 interworking_select(dev
[0], bssid
, "home")
399 interworking_connect(dev
[0], bssid
, "TTLS")
401 logger
.info("Verifying GAS query while associated")
402 dev
[0].request("FETCH_ANQP")
403 for i
in range(0, 6):
404 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
406 raise Exception("Operation timed out")
408 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
409 """Hotspot 2.0 connection with fragmented GAS query while associated"""
410 bssid
= apdev
[0]['bssid']
411 params
= hs20_ap_params()
412 params
['hessid'] = bssid
413 hostapd
.add_ap(apdev
[0]['ifname'], params
)
414 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
415 hapd
.set("gas_frag_limit", "50")
417 dev
[0].request("SET ignore_old_scan_res 1")
419 id = dev
[0].add_cred_values({ 'realm': "example.com",
420 'username': "hs20-test",
421 'password': "password",
422 'domain': "example.com" })
423 interworking_select(dev
[0], bssid
, "home")
424 interworking_connect(dev
[0], bssid
, "TTLS")
426 logger
.info("Verifying GAS query while associated")
427 dev
[0].request("FETCH_ANQP")
428 for i
in range(0, 6):
429 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
431 raise Exception("Operation timed out")
433 def test_ap_hs20_multiple_connects(dev
, apdev
):
434 """Hotspot 2.0 connection through multiple network selections"""
435 bssid
= apdev
[0]['bssid']
436 params
= hs20_ap_params()
437 params
['hessid'] = bssid
438 hostapd
.add_ap(apdev
[0]['ifname'], params
)
440 dev
[0].request("SET ignore_old_scan_res 1")
442 values
= { 'realm': "example.com",
443 'username': "hs20-test",
444 'password': "password",
445 'domain': "example.com" }
446 id = dev
[0].add_cred_values(values
)
448 for i
in range(0, 3):
449 logger
.info("Starting Interworking network selection")
450 dev
[0].request("INTERWORKING_SELECT auto")
452 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
453 "INTERWORKING-ALREADY-CONNECTED",
454 "CTRL-EVENT-CONNECTED"], timeout
=15)
456 raise Exception("Connection timed out")
457 if "INTERWORKING-NO-MATCH" in ev
:
458 raise Exception("Matching AP not found")
459 if "CTRL-EVENT-CONNECTED" in ev
:
461 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
464 dev
[0].request("DISCONNECT")
465 dev
[0].dump_monitor()
467 networks
= dev
[0].list_networks()
468 if len(networks
) > 1:
469 raise Exception("Duplicated network block detected")
471 def test_ap_hs20_disallow_aps(dev
, apdev
):
472 """Hotspot 2.0 connection and disallow_aps"""
473 bssid
= apdev
[0]['bssid']
474 params
= hs20_ap_params()
475 params
['hessid'] = bssid
476 hostapd
.add_ap(apdev
[0]['ifname'], params
)
478 dev
[0].request("SET ignore_old_scan_res 1")
480 values
= { 'realm': "example.com",
481 'username': "hs20-test",
482 'password': "password",
483 'domain': "example.com" }
484 id = dev
[0].add_cred_values(values
)
486 logger
.info("Verify disallow_aps bssid")
487 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
488 dev
[0].request("INTERWORKING_SELECT auto")
489 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
491 raise Exception("Network selection timed out")
492 dev
[0].dump_monitor()
494 logger
.info("Verify disallow_aps ssid")
495 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
496 dev
[0].request("INTERWORKING_SELECT auto")
497 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
499 raise Exception("Network selection timed out")
500 dev
[0].dump_monitor()
502 logger
.info("Verify disallow_aps clear")
503 dev
[0].request("SET disallow_aps ")
504 interworking_select(dev
[0], bssid
, "home")
506 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
507 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
508 if "FAIL" not in ret
:
509 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
511 def policy_test(dev
, ap
, values
, only_one
=True):
513 logger
.info("Verify network selection to AP " + ap
['ifname'])
515 dev
.request("SET ignore_old_scan_res 1")
517 id = dev
.add_cred_values(values
)
518 dev
.request("INTERWORKING_SELECT auto")
520 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
521 "CTRL-EVENT-CONNECTED"], timeout
=15)
523 raise Exception("Connection timed out")
524 if "INTERWORKING-NO-MATCH" in ev
:
525 raise Exception("Matching AP not found")
526 if only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
527 raise Exception("Unexpected AP claimed acceptable")
528 if "CTRL-EVENT-CONNECTED" in ev
:
530 raise Exception("Connected to incorrect BSS")
533 conn_bssid
= dev
.get_status_field("bssid")
534 if conn_bssid
!= bssid
:
535 raise Exception("bssid information points to incorrect BSS")
541 return { 'realm': "example.com",
542 'username': "hs20-test",
543 'password': "password" }
545 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
546 """Hotspot 2.0 required roaming consortium"""
547 params
= hs20_ap_params()
548 hostapd
.add_ap(apdev
[0]['ifname'], params
)
550 params
= hs20_ap_params()
551 params
['ssid'] = "test-hs20-other"
552 params
['roaming_consortium'] = [ "223344" ]
553 hostapd
.add_ap(apdev
[1]['ifname'], params
)
555 values
= default_cred()
556 values
['required_roaming_consortium'] = "223344"
557 policy_test(dev
[0], apdev
[1], values
)
558 values
['required_roaming_consortium'] = "112233"
559 policy_test(dev
[0], apdev
[0], values
)
561 def test_ap_hs20_excluded_ssid(dev
, apdev
):
562 """Hotspot 2.0 exclusion based on SSID"""
563 params
= hs20_ap_params()
564 hostapd
.add_ap(apdev
[0]['ifname'], params
)
566 params
= hs20_ap_params()
567 params
['ssid'] = "test-hs20-other"
568 params
['roaming_consortium'] = [ "223344" ]
569 hostapd
.add_ap(apdev
[1]['ifname'], params
)
571 values
= default_cred()
572 values
['excluded_ssid'] = "test-hs20"
573 policy_test(dev
[0], apdev
[1], values
)
574 values
['excluded_ssid'] = "test-hs20-other"
575 policy_test(dev
[0], apdev
[0], values
)