]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_hs20.py
tests: Verify multi-cred sp_priority use
[thirdparty/hostap.git] / tests / hwsim / test_ap_hs20.py
1 # Hotspot 2.0 tests
2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import time
8 import subprocess
9 import logging
10 logger = logging.getLogger()
11 import os.path
12 import subprocess
13
14 import hostapd
15 from wlantest import Wlantest
16
17 def hs20_ap_params(ssid="test-hs20"):
18 params = hostapd.wpa2_params(ssid=ssid)
19 params['wpa_key_mgmt'] = "WPA-EAP"
20 params['ieee80211w'] = "1"
21 params['ieee8021x'] = "1"
22 params['auth_server_addr'] = "127.0.0.1"
23 params['auth_server_port'] = "1812"
24 params['auth_server_shared_secret'] = "radius"
25 params['interworking'] = "1"
26 params['access_network_type'] = "14"
27 params['internet'] = "1"
28 params['asra'] = "0"
29 params['esr'] = "0"
30 params['uesa'] = "0"
31 params['venue_group'] = "7"
32 params['venue_type'] = "1"
33 params['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
34 params['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
35 "fedcba" ]
36 params['domain_name'] = "example.com,another.example.com"
37 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
38 "0,another.example.com" ]
39 params['hs20'] = "1"
40 params['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
41 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
42 params['hs20_operating_class'] = "5173"
43 params['anqp_3gpp_cell_net'] = "244,91"
44 return params
45
46 def interworking_select(dev, bssid, type=None, no_match=False, freq=None):
47 dev.dump_monitor()
48 freq_extra = " freq=" + freq if freq else ""
49 dev.request("INTERWORKING_SELECT" + freq_extra)
50 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
51 timeout=15)
52 if ev is None:
53 raise Exception("Network selection timed out");
54 if no_match:
55 if "INTERWORKING-NO-MATCH" not in ev:
56 raise Exception("Unexpected network match")
57 return
58 if "INTERWORKING-NO-MATCH" in ev:
59 raise Exception("Matching network not found")
60 if bssid and bssid not in ev:
61 raise Exception("Unexpected BSSID in match")
62 if type and "type=" + type not in ev:
63 raise Exception("Network type not recognized correctly")
64
65 def check_sp_type(dev, sp_type):
66 type = dev.get_status_field("sp_type")
67 if type is None:
68 raise Exception("sp_type not available")
69 if type != sp_type:
70 raise Exception("sp_type did not indicate home network")
71
72 def hlr_auc_gw_available():
73 if not os.path.exists("/tmp/hlr_auc_gw.sock"):
74 logger.info("No hlr_auc_gw available");
75 return False
76 if not os.path.exists("../../hostapd/hlr_auc_gw"):
77 logger.info("No hlr_auc_gw available");
78 return False
79 return True
80
81 def interworking_ext_sim_connect(dev, bssid, method):
82 dev.request("INTERWORKING_CONNECT " + bssid)
83 interworking_ext_sim_auth(dev, method)
84
85 def interworking_ext_sim_auth(dev, method):
86 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
87 if ev is None:
88 raise Exception("Network connected timed out")
89 if "(" + method + ")" not in ev:
90 raise Exception("Unexpected EAP method selection")
91
92 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
93 if ev is None:
94 raise Exception("Wait for external SIM processing request timed out")
95 p = ev.split(':', 2)
96 if p[1] != "GSM-AUTH":
97 raise Exception("Unexpected CTRL-REQ-SIM type")
98 id = p[0].split('-')[3]
99 rand = p[2].split(' ')[0]
100
101 res = subprocess.check_output(["../../hostapd/hlr_auc_gw",
102 "-m",
103 "auth_serv/hlr_auc_gw.milenage_db",
104 "GSM-AUTH-REQ 232010000000000 " + rand])
105 if "GSM-AUTH-RESP" not in res:
106 raise Exception("Unexpected hlr_auc_gw response")
107 resp = res.split(' ')[2].rstrip()
108
109 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
110 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
111 if ev is None:
112 raise Exception("Connection timed out")
113
114 def interworking_connect(dev, bssid, method):
115 dev.request("INTERWORKING_CONNECT " + bssid)
116 interworking_auth(dev, method)
117
118 def interworking_auth(dev, method):
119 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
120 if ev is None:
121 raise Exception("Network connected timed out")
122 if "(" + method + ")" not in ev:
123 raise Exception("Unexpected EAP method selection")
124
125 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
126 if ev is None:
127 raise Exception("Connection timed out")
128
129 def check_probe_resp(wt, bssid_unexpected, bssid_expected):
130 if bssid_unexpected:
131 count = wt.get_bss_counter("probe_response", bssid_unexpected)
132 if count > 0:
133 raise Exception("Unexpected Probe Response frame from AP")
134
135 if bssid_expected:
136 count = wt.get_bss_counter("probe_response", bssid_expected)
137 if count == 0:
138 raise Exception("No Probe Response frame from AP")
139
140 def test_ap_anqp_sharing(dev, apdev):
141 """ANQP sharing within ESS and explicit unshare"""
142 bssid = apdev[0]['bssid']
143 params = hs20_ap_params()
144 params['hessid'] = bssid
145 hostapd.add_ap(apdev[0]['ifname'], params)
146
147 bssid2 = apdev[1]['bssid']
148 params = hs20_ap_params()
149 params['hessid'] = bssid
150 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
151 hostapd.add_ap(apdev[1]['ifname'], params)
152
153 dev[0].hs20_enable()
154 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
155 'password': "secret",
156 'domain': "example.com" })
157 logger.info("Normal network selection with shared ANQP results")
158 interworking_select(dev[0], None, "home", freq="2412")
159 dev[0].dump_monitor()
160
161 res1 = dev[0].get_bss(bssid)
162 res2 = dev[0].get_bss(bssid2)
163 if res1['anqp_nai_realm'] != res2['anqp_nai_realm']:
164 raise Exception("ANQP results were not shared between BSSes")
165
166 logger.info("Explicit ANQP request to unshare ANQP results")
167 dev[0].request("ANQP_GET " + bssid + " 263")
168 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
169 if ev is None:
170 raise Exception("ANQP operation timed out")
171
172 dev[0].request("ANQP_GET " + bssid2 + " 263")
173 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
174 if ev is None:
175 raise Exception("ANQP operation timed out")
176
177 res1 = dev[0].get_bss(bssid)
178 res2 = dev[0].get_bss(bssid2)
179 if res1['anqp_nai_realm'] == res2['anqp_nai_realm']:
180 raise Exception("ANQP results were not unshared")
181
182 def test_ap_nai_home_realm_query(dev, apdev):
183 """NAI Home Realm Query"""
184 bssid = apdev[0]['bssid']
185 params = hs20_ap_params()
186 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
187 "0,another.example.org" ]
188 hostapd.add_ap(apdev[0]['ifname'], params)
189
190 dev[0].scan(freq="2412")
191 dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " realm=example.com")
192 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
193 if ev is None:
194 raise Exception("ANQP operation timed out")
195 nai1 = dev[0].get_bss(bssid)['anqp_nai_realm']
196 dev[0].dump_monitor()
197
198 dev[0].request("ANQP_GET " + bssid + " 263")
199 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
200 if ev is None:
201 raise Exception("ANQP operation timed out")
202 nai2 = dev[0].get_bss(bssid)['anqp_nai_realm']
203
204 if len(nai1) >= len(nai2):
205 raise Exception("Unexpected NAI Realm list response lengths")
206 if "example.com".encode('hex') not in nai1:
207 raise Exception("Home realm not reported")
208 if "example.org".encode('hex') in nai1:
209 raise Exception("Non-home realm reported")
210 if "example.com".encode('hex') not in nai2:
211 raise Exception("Home realm not reported in wildcard query")
212 if "example.org".encode('hex') not in nai2:
213 raise Exception("Non-home realm not reported in wildcard query ")
214
215 def test_ap_interworking_scan_filtering(dev, apdev):
216 """Interworking scan filtering with HESSID and access network type"""
217 bssid = apdev[0]['bssid']
218 params = hs20_ap_params()
219 ssid = "test-hs20-ap1"
220 params['ssid'] = ssid
221 params['hessid'] = bssid
222 hostapd.add_ap(apdev[0]['ifname'], params)
223
224 bssid2 = apdev[1]['bssid']
225 params = hs20_ap_params()
226 ssid2 = "test-hs20-ap2"
227 params['ssid'] = ssid2
228 params['hessid'] = bssid2
229 params['access_network_type'] = "1"
230 del params['venue_group']
231 del params['venue_type']
232 hostapd.add_ap(apdev[1]['ifname'], params)
233
234 dev[0].hs20_enable()
235
236 wt = Wlantest()
237 wt.flush()
238
239 logger.info("Check probe request filtering based on HESSID")
240
241 dev[0].request("SET hessid " + bssid2)
242 dev[0].scan(freq="2412")
243 time.sleep(0.03)
244 check_probe_resp(wt, bssid, bssid2)
245
246 logger.info("Check probe request filtering based on access network type")
247
248 wt.clear_bss_counters(bssid)
249 wt.clear_bss_counters(bssid2)
250 dev[0].request("SET hessid 00:00:00:00:00:00")
251 dev[0].request("SET access_network_type 14")
252 dev[0].scan(freq="2412")
253 time.sleep(0.03)
254 check_probe_resp(wt, bssid2, bssid)
255
256 wt.clear_bss_counters(bssid)
257 wt.clear_bss_counters(bssid2)
258 dev[0].request("SET hessid 00:00:00:00:00:00")
259 dev[0].request("SET access_network_type 1")
260 dev[0].scan(freq="2412")
261 time.sleep(0.03)
262 check_probe_resp(wt, bssid, bssid2)
263
264 logger.info("Check probe request filtering based on HESSID and ANT")
265
266 wt.clear_bss_counters(bssid)
267 wt.clear_bss_counters(bssid2)
268 dev[0].request("SET hessid " + bssid)
269 dev[0].request("SET access_network_type 14")
270 dev[0].scan(freq="2412")
271 time.sleep(0.03)
272 check_probe_resp(wt, bssid2, bssid)
273
274 wt.clear_bss_counters(bssid)
275 wt.clear_bss_counters(bssid2)
276 dev[0].request("SET hessid " + bssid2)
277 dev[0].request("SET access_network_type 14")
278 dev[0].scan(freq="2412")
279 time.sleep(0.03)
280 check_probe_resp(wt, bssid, None)
281 check_probe_resp(wt, bssid2, None)
282
283 wt.clear_bss_counters(bssid)
284 wt.clear_bss_counters(bssid2)
285 dev[0].request("SET hessid " + bssid)
286 dev[0].request("SET access_network_type 1")
287 dev[0].scan(freq="2412")
288 time.sleep(0.03)
289 check_probe_resp(wt, bssid, None)
290 check_probe_resp(wt, bssid2, None)
291
292 def test_ap_hs20_select(dev, apdev):
293 """Hotspot 2.0 network selection"""
294 bssid = apdev[0]['bssid']
295 params = hs20_ap_params()
296 params['hessid'] = bssid
297 hostapd.add_ap(apdev[0]['ifname'], params)
298
299 dev[0].hs20_enable()
300 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
301 'password': "secret",
302 'domain': "example.com" })
303 interworking_select(dev[0], bssid, "home")
304
305 dev[0].remove_cred(id)
306 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
307 'password': "secret",
308 'domain': "no.match.example.com" })
309 interworking_select(dev[0], bssid, "roaming", freq="2412")
310
311 dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
312 interworking_select(dev[0], bssid, no_match=True, freq="2412")
313
314 bssid2 = apdev[1]['bssid']
315 params = hs20_ap_params()
316 params['nai_realm'] = [ "0,example.org,21" ]
317 params['hessid'] = bssid2
318 params['domain_name'] = "example.org"
319 hostapd.add_ap(apdev[1]['ifname'], params)
320 dev[0].remove_cred(id)
321 id = dev[0].add_cred_values({ 'realm': "example.org", 'username': "test",
322 'password': "secret",
323 'domain': "example.org" })
324 interworking_select(dev[0], bssid2, "home", freq="2412")
325
326 def hs20_simulated_sim(dev, ap, method):
327 bssid = ap['bssid']
328 params = hs20_ap_params()
329 params['hessid'] = bssid
330 params['anqp_3gpp_cell_net'] = "555,444"
331 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
332 hostapd.add_ap(ap['ifname'], params)
333
334 dev.hs20_enable()
335 dev.add_cred_values({ 'imsi': "555444-333222111", 'eap': method,
336 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
337 interworking_select(dev, "home", freq="2412")
338 interworking_connect(dev, bssid, method)
339 check_sp_type(dev, "home")
340
341 def test_ap_hs20_sim(dev, apdev):
342 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
343 if not hlr_auc_gw_available():
344 return "skip"
345 hs20_simulated_sim(dev[0], apdev[0], "SIM")
346
347 def test_ap_hs20_aka(dev, apdev):
348 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
349 if not hlr_auc_gw_available():
350 return "skip"
351 hs20_simulated_sim(dev[0], apdev[0], "AKA")
352
353 def test_ap_hs20_aka_prime(dev, apdev):
354 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
355 if not hlr_auc_gw_available():
356 return "skip"
357 hs20_simulated_sim(dev[0], apdev[0], "AKA'")
358
359 def test_ap_hs20_ext_sim(dev, apdev):
360 """Hotspot 2.0 with external SIM processing"""
361 if not hlr_auc_gw_available():
362 return "skip"
363 bssid = apdev[0]['bssid']
364 params = hs20_ap_params()
365 params['hessid'] = bssid
366 params['anqp_3gpp_cell_net'] = "232,01"
367 params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
368 hostapd.add_ap(apdev[0]['ifname'], params)
369
370 dev[0].hs20_enable()
371 dev[0].request("SET external_sim 1")
372 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
373 interworking_select(dev[0], "home", freq="2412")
374 interworking_ext_sim_connect(dev[0], bssid, "SIM")
375 check_sp_type(dev[0], "home")
376
377 def test_ap_hs20_ext_sim_roaming(dev, apdev):
378 """Hotspot 2.0 with external SIM processing in roaming network"""
379 if not hlr_auc_gw_available():
380 return "skip"
381 bssid = apdev[0]['bssid']
382 params = hs20_ap_params()
383 params['hessid'] = bssid
384 params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
385 params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
386 hostapd.add_ap(apdev[0]['ifname'], params)
387
388 dev[0].hs20_enable()
389 dev[0].request("SET external_sim 1")
390 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
391 interworking_select(dev[0], "roaming", freq="2412")
392 interworking_ext_sim_connect(dev[0], bssid, "SIM")
393 check_sp_type(dev[0], "roaming")
394
395 def test_ap_hs20_username(dev, apdev):
396 """Hotspot 2.0 connection in username/password credential"""
397 bssid = apdev[0]['bssid']
398 params = hs20_ap_params()
399 params['hessid'] = bssid
400 hostapd.add_ap(apdev[0]['ifname'], params)
401
402 dev[0].hs20_enable()
403 id = dev[0].add_cred_values({ 'realm': "example.com",
404 'username': "hs20-test",
405 'password': "password",
406 'domain': "example.com" })
407 interworking_select(dev[0], bssid, "home", freq="2412")
408 interworking_connect(dev[0], bssid, "TTLS")
409 check_sp_type(dev[0], "home")
410
411 def eap_test(dev, ap, eap_params, method, user):
412 bssid = ap['bssid']
413 params = hs20_ap_params()
414 params['nai_realm'] = [ "0,example.com," + eap_params ]
415 hostapd.add_ap(ap['ifname'], params)
416
417 dev.hs20_enable()
418 dev.add_cred_values({ 'realm': "example.com",
419 'username': user,
420 'password': "password" })
421 interworking_select(dev, bssid, freq="2412")
422 interworking_connect(dev, bssid, method)
423
424 def test_ap_hs20_eap_peap_mschapv2(dev, apdev):
425 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
426 eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user")
427
428 def test_ap_hs20_eap_peap_gtc(dev, apdev):
429 """Hotspot 2.0 connection with PEAP/GTC"""
430 eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user")
431
432 def test_ap_hs20_eap_ttls_chap(dev, apdev):
433 """Hotspot 2.0 connection with TTLS/CHAP"""
434 eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user")
435
436 def test_ap_hs20_eap_ttls_mschap(dev, apdev):
437 """Hotspot 2.0 connection with TTLS/MSCHAP"""
438 eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user")
439
440 def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev):
441 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
442 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
443
444 def test_ap_hs20_eap_fast_mschapv2(dev, apdev):
445 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
446 eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user")
447
448 def test_ap_hs20_eap_fast_gtc(dev, apdev):
449 """Hotspot 2.0 connection with FAST/EAP-GTC"""
450 eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user")
451
452 def test_ap_hs20_eap_tls(dev, apdev):
453 """Hotspot 2.0 connection with EAP-TLS"""
454 bssid = apdev[0]['bssid']
455 params = hs20_ap_params()
456 params['nai_realm'] = [ "0,example.com,13[5:6]" ]
457 hostapd.add_ap(apdev[0]['ifname'], params)
458
459 dev[0].hs20_enable()
460 dev[0].add_cred_values({ 'realm': "example.com",
461 'username': "certificate-user",
462 'ca_cert': "auth_serv/ca.pem",
463 'client_cert': "auth_serv/user.pem",
464 'private_key': "auth_serv/user.key"})
465 interworking_select(dev[0], bssid, freq="2412")
466 interworking_connect(dev[0], bssid, "TLS")
467
468 def test_ap_hs20_nai_realms(dev, apdev):
469 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
470 bssid = apdev[0]['bssid']
471 params = hs20_ap_params()
472 params['hessid'] = bssid
473 params['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
474 hostapd.add_ap(apdev[0]['ifname'], params)
475
476 dev[0].hs20_enable()
477 id = dev[0].add_cred_values({ 'realm': "example.com",
478 'username': "pap user",
479 'password': "password",
480 'domain': "example.com" })
481 interworking_select(dev[0], bssid, "home", freq="2412")
482 interworking_connect(dev[0], bssid, "TTLS")
483 check_sp_type(dev[0], "home")
484
485 def test_ap_hs20_roaming_consortium(dev, apdev):
486 """Hotspot 2.0 connection based on roaming consortium match"""
487 bssid = apdev[0]['bssid']
488 params = hs20_ap_params()
489 params['hessid'] = bssid
490 hostapd.add_ap(apdev[0]['ifname'], params)
491
492 dev[0].hs20_enable()
493 id = dev[0].add_cred_values({ 'realm': "example.com",
494 'username': "user",
495 'password': "password",
496 'domain': "example.com",
497 'roaming_consortium': "fedcba",
498 'eap': "PEAP" })
499 interworking_select(dev[0], bssid, "home", freq="2412")
500 interworking_connect(dev[0], bssid, "PEAP")
501 check_sp_type(dev[0], "home")
502
503 def test_ap_hs20_username_roaming(dev, apdev):
504 """Hotspot 2.0 connection in username/password credential (roaming)"""
505 bssid = apdev[0]['bssid']
506 params = hs20_ap_params()
507 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
508 "0,roaming.example.com,21[2:4][5:7]",
509 "0,another.example.com" ]
510 params['domain_name'] = "another.example.com"
511 params['hessid'] = bssid
512 hostapd.add_ap(apdev[0]['ifname'], params)
513
514 dev[0].hs20_enable()
515 id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
516 'username': "hs20-test",
517 'password': "password",
518 'domain': "example.com" })
519 interworking_select(dev[0], bssid, "roaming", freq="2412")
520 interworking_connect(dev[0], bssid, "TTLS")
521 check_sp_type(dev[0], "roaming")
522
523 def test_ap_hs20_username_unknown(dev, apdev):
524 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
525 bssid = apdev[0]['bssid']
526 params = hs20_ap_params()
527 params['hessid'] = bssid
528 hostapd.add_ap(apdev[0]['ifname'], params)
529
530 dev[0].hs20_enable()
531 id = dev[0].add_cred_values({ 'realm': "example.com",
532 'username': "hs20-test",
533 'password': "password" })
534 interworking_select(dev[0], bssid, "unknown", freq="2412")
535 interworking_connect(dev[0], bssid, "TTLS")
536 check_sp_type(dev[0], "unknown")
537
538 def test_ap_hs20_username_unknown2(dev, apdev):
539 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
540 bssid = apdev[0]['bssid']
541 params = hs20_ap_params()
542 params['hessid'] = bssid
543 del params['domain_name']
544 hostapd.add_ap(apdev[0]['ifname'], params)
545
546 dev[0].hs20_enable()
547 id = dev[0].add_cred_values({ 'realm': "example.com",
548 'username': "hs20-test",
549 'password': "password",
550 'domain': "example.com" })
551 interworking_select(dev[0], bssid, "unknown", freq="2412")
552 interworking_connect(dev[0], bssid, "TTLS")
553 check_sp_type(dev[0], "unknown")
554
555 def test_ap_hs20_gas_while_associated(dev, apdev):
556 """Hotspot 2.0 connection with GAS query while associated"""
557 bssid = apdev[0]['bssid']
558 params = hs20_ap_params()
559 params['hessid'] = bssid
560 hostapd.add_ap(apdev[0]['ifname'], params)
561
562 dev[0].hs20_enable()
563 id = dev[0].add_cred_values({ 'realm': "example.com",
564 'username': "hs20-test",
565 'password': "password",
566 'domain': "example.com" })
567 interworking_select(dev[0], bssid, "home", freq="2412")
568 interworking_connect(dev[0], bssid, "TTLS")
569
570 logger.info("Verifying GAS query while associated")
571 dev[0].request("FETCH_ANQP")
572 for i in range(0, 6):
573 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
574 if ev is None:
575 raise Exception("Operation timed out")
576
577 def test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
578 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
579 bssid = apdev[0]['bssid']
580 params = hs20_ap_params()
581 params['hessid'] = bssid
582 hostapd.add_ap(apdev[0]['ifname'], params)
583
584 bssid2 = apdev[1]['bssid']
585 params = hs20_ap_params()
586 params['hessid'] = bssid2
587 params['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
588 hostapd.add_ap(apdev[1]['ifname'], params)
589
590 dev[0].hs20_enable()
591 dev[0].request("SET pmf 2")
592 id = dev[0].add_cred_values({ 'realm': "example.com",
593 'username': "hs20-test",
594 'password': "password",
595 'domain': "example.com" })
596 interworking_select(dev[0], bssid, "home", freq="2412")
597 interworking_connect(dev[0], bssid, "TTLS")
598
599 logger.info("Verifying GAS query while associated")
600 dev[0].request("FETCH_ANQP")
601 for i in range(0, 2 * 6):
602 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
603 if ev is None:
604 raise Exception("Operation timed out")
605
606 def test_ap_hs20_gas_frag_while_associated(dev, apdev):
607 """Hotspot 2.0 connection with fragmented GAS query while associated"""
608 bssid = apdev[0]['bssid']
609 params = hs20_ap_params()
610 params['hessid'] = bssid
611 hostapd.add_ap(apdev[0]['ifname'], params)
612 hapd = hostapd.Hostapd(apdev[0]['ifname'])
613 hapd.set("gas_frag_limit", "50")
614
615 dev[0].hs20_enable()
616 id = dev[0].add_cred_values({ 'realm': "example.com",
617 'username': "hs20-test",
618 'password': "password",
619 'domain': "example.com" })
620 interworking_select(dev[0], bssid, "home", freq="2412")
621 interworking_connect(dev[0], bssid, "TTLS")
622
623 logger.info("Verifying GAS query while associated")
624 dev[0].request("FETCH_ANQP")
625 for i in range(0, 6):
626 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
627 if ev is None:
628 raise Exception("Operation timed out")
629
630 def test_ap_hs20_multiple_connects(dev, apdev):
631 """Hotspot 2.0 connection through multiple network selections"""
632 bssid = apdev[0]['bssid']
633 params = hs20_ap_params()
634 params['hessid'] = bssid
635 hostapd.add_ap(apdev[0]['ifname'], params)
636
637 dev[0].hs20_enable()
638 values = { 'realm': "example.com",
639 'username': "hs20-test",
640 'password': "password",
641 'domain': "example.com" }
642 id = dev[0].add_cred_values(values)
643
644 for i in range(0, 3):
645 logger.info("Starting Interworking network selection")
646 dev[0].request("INTERWORKING_SELECT auto freq=2412")
647 while True:
648 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
649 "INTERWORKING-ALREADY-CONNECTED",
650 "CTRL-EVENT-CONNECTED"], timeout=15)
651 if ev is None:
652 raise Exception("Connection timed out")
653 if "INTERWORKING-NO-MATCH" in ev:
654 raise Exception("Matching AP not found")
655 if "CTRL-EVENT-CONNECTED" in ev:
656 break
657 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
658 break
659 if i == 0:
660 dev[0].request("DISCONNECT")
661 dev[0].dump_monitor()
662
663 networks = dev[0].list_networks()
664 if len(networks) > 1:
665 raise Exception("Duplicated network block detected")
666
667 def test_ap_hs20_disallow_aps(dev, apdev):
668 """Hotspot 2.0 connection and disallow_aps"""
669 bssid = apdev[0]['bssid']
670 params = hs20_ap_params()
671 params['hessid'] = bssid
672 hostapd.add_ap(apdev[0]['ifname'], params)
673
674 dev[0].hs20_enable()
675 values = { 'realm': "example.com",
676 'username': "hs20-test",
677 'password': "password",
678 'domain': "example.com" }
679 id = dev[0].add_cred_values(values)
680
681 logger.info("Verify disallow_aps bssid")
682 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
683 dev[0].request("INTERWORKING_SELECT auto")
684 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
685 if ev is None:
686 raise Exception("Network selection timed out")
687 dev[0].dump_monitor()
688
689 logger.info("Verify disallow_aps ssid")
690 dev[0].request("SET disallow_aps ssid 746573742d68733230")
691 dev[0].request("INTERWORKING_SELECT auto freq=2412")
692 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
693 if ev is None:
694 raise Exception("Network selection timed out")
695 dev[0].dump_monitor()
696
697 logger.info("Verify disallow_aps clear")
698 dev[0].request("SET disallow_aps ")
699 interworking_select(dev[0], bssid, "home", freq="2412")
700
701 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
702 ret = dev[0].request("INTERWORKING_CONNECT " + bssid)
703 if "FAIL" not in ret:
704 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
705
706 def policy_test(dev, ap, values, only_one=True):
707 dev.dump_monitor()
708 logger.info("Verify network selection to AP " + ap['ifname'])
709 bssid = ap['bssid']
710 dev.hs20_enable()
711 id = dev.add_cred_values(values)
712 dev.request("INTERWORKING_SELECT auto freq=2412")
713 while True:
714 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
715 "CTRL-EVENT-CONNECTED"], timeout=15)
716 if ev is None:
717 raise Exception("Connection timed out")
718 if "INTERWORKING-NO-MATCH" in ev:
719 raise Exception("Matching AP not found")
720 if only_one and "INTERWORKING-AP" in ev and bssid not in ev:
721 raise Exception("Unexpected AP claimed acceptable")
722 if "CTRL-EVENT-CONNECTED" in ev:
723 if bssid not in ev:
724 raise Exception("Connected to incorrect BSS")
725 break
726
727 conn_bssid = dev.get_status_field("bssid")
728 if conn_bssid != bssid:
729 raise Exception("bssid information points to incorrect BSS")
730
731 dev.remove_cred(id)
732 dev.dump_monitor()
733
734 def default_cred():
735 return { 'realm': "example.com",
736 'username': "hs20-test",
737 'password': "password" }
738
739 def test_ap_hs20_req_roaming_consortium(dev, apdev):
740 """Hotspot 2.0 required roaming consortium"""
741 params = hs20_ap_params()
742 hostapd.add_ap(apdev[0]['ifname'], params)
743
744 params = hs20_ap_params()
745 params['ssid'] = "test-hs20-other"
746 params['roaming_consortium'] = [ "223344" ]
747 hostapd.add_ap(apdev[1]['ifname'], params)
748
749 values = default_cred()
750 values['required_roaming_consortium'] = "223344"
751 policy_test(dev[0], apdev[1], values)
752 values['required_roaming_consortium'] = "112233"
753 policy_test(dev[0], apdev[0], values)
754
755 def test_ap_hs20_excluded_ssid(dev, apdev):
756 """Hotspot 2.0 exclusion based on SSID"""
757 params = hs20_ap_params()
758 hostapd.add_ap(apdev[0]['ifname'], params)
759
760 params = hs20_ap_params()
761 params['ssid'] = "test-hs20-other"
762 params['roaming_consortium'] = [ "223344" ]
763 hostapd.add_ap(apdev[1]['ifname'], params)
764
765 values = default_cred()
766 values['excluded_ssid'] = "test-hs20"
767 policy_test(dev[0], apdev[1], values)
768 values['excluded_ssid'] = "test-hs20-other"
769 policy_test(dev[0], apdev[0], values)
770
771 def test_ap_hs20_roam_to_higher_prio(dev, apdev):
772 """Hotspot 2.0 and roaming from current to higher priority network"""
773 bssid = apdev[0]['bssid']
774 params = hs20_ap_params(ssid="test-hs20-visited")
775 params['domain_name'] = "visited.example.org"
776 hostapd.add_ap(apdev[0]['ifname'], params)
777
778 dev[0].hs20_enable()
779 id = dev[0].add_cred_values({ 'realm': "example.com",
780 'username': "hs20-test",
781 'password': "password",
782 'domain': "example.com" })
783 logger.info("Connect to the only network option")
784 interworking_select(dev[0], bssid, "roaming", freq="2412")
785 dev[0].dump_monitor()
786 interworking_connect(dev[0], bssid, "TTLS")
787
788 logger.info("Start another AP (home operator) and reconnect")
789 bssid2 = apdev[1]['bssid']
790 params = hs20_ap_params(ssid="test-hs20-home")
791 params['domain_name'] = "example.com"
792 hostapd.add_ap(apdev[1]['ifname'], params)
793
794 dev[0].request("INTERWORKING_SELECT auto freq=2412")
795 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
796 "INTERWORKING-ALREADY-CONNECTED",
797 "CTRL-EVENT-CONNECTED"], timeout=15)
798 if ev is None:
799 raise Exception("Connection timed out")
800 if "INTERWORKING-NO-MATCH" in ev:
801 raise Exception("Matching AP not found")
802 if "INTERWORKING-ALREADY-CONNECTED" in ev:
803 raise Exception("Unexpected AP selected")
804 if bssid2 not in ev:
805 raise Exception("Unexpected BSSID after reconnection")
806
807 def test_ap_hs20_domain_suffix_match(dev, apdev):
808 """Hotspot 2.0 and domain_suffix_match"""
809 bssid = apdev[0]['bssid']
810 params = hs20_ap_params()
811 hostapd.add_ap(apdev[0]['ifname'], params)
812
813 dev[0].hs20_enable()
814 id = dev[0].add_cred_values({ 'realm': "example.com",
815 'username': "hs20-test",
816 'password': "password",
817 'domain': "example.com",
818 'domain_suffix_match': "w1.fi" })
819 interworking_select(dev[0], bssid, "home", freq="2412")
820 dev[0].dump_monitor()
821 interworking_connect(dev[0], bssid, "TTLS")
822 dev[0].request("REMOVE_NETWORK all")
823 dev[0].dump_monitor()
824
825 dev[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
826 interworking_select(dev[0], bssid, "home", freq="2412")
827 dev[0].dump_monitor()
828 dev[0].request("INTERWORKING_CONNECT " + bssid)
829 ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
830 if ev is None:
831 raise Exception("TLS certificate error not reported")
832 if "Domain suffix mismatch" not in ev:
833 raise Exception("Domain suffix mismatch not reported")
834
835 def test_ap_hs20_multi_cred_sp_prio(dev, apdev):
836 """Hotspot 2.0 multi-cred sp_priority"""
837 if not hlr_auc_gw_available():
838 return "skip"
839 bssid = apdev[0]['bssid']
840 params = hs20_ap_params()
841 params['hessid'] = bssid
842 del params['domain_name']
843 params['anqp_3gpp_cell_net'] = "232,01"
844 hostapd.add_ap(apdev[0]['ifname'], params)
845
846 dev[0].hs20_enable()
847 dev[0].request("SET external_sim 1")
848 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
849 'provisioning_sp': "example.com",
850 'sp_priority' :"1" })
851 id2 = dev[0].add_cred_values({ 'realm': "example.com",
852 'username': "hs20-test",
853 'password': "password",
854 'domain': "example.com",
855 'provisioning_sp': "example.com",
856 'sp_priority': "2" })
857 dev[0].dump_monitor()
858 dev[0].request("INTERWORKING_SELECT auto")
859 interworking_ext_sim_auth(dev[0], "SIM")
860 check_sp_type(dev[0], "unknown")
861 dev[0].request("REMOVE_NETWORK all")
862
863 dev[0].set_cred(id1, "sp_priority", "2")
864 dev[0].set_cred(id2, "sp_priority", "1")
865 dev[0].dump_monitor()
866 dev[0].request("INTERWORKING_SELECT auto")
867 interworking_auth(dev[0], "TTLS")
868 check_sp_type(dev[0], "unknown")
869
870 def test_ap_hs20_multi_cred_sp_prio2(dev, apdev):
871 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
872 if not hlr_auc_gw_available():
873 return "skip"
874 bssid = apdev[0]['bssid']
875 params = hs20_ap_params()
876 params['hessid'] = bssid
877 del params['nai_realm']
878 del params['domain_name']
879 params['anqp_3gpp_cell_net'] = "232,01"
880 hostapd.add_ap(apdev[0]['ifname'], params)
881
882 bssid2 = apdev[1]['bssid']
883 params = hs20_ap_params()
884 params['ssid'] = "test-hs20-other"
885 params['hessid'] = bssid2
886 del params['domain_name']
887 del params['anqp_3gpp_cell_net']
888 hostapd.add_ap(apdev[1]['ifname'], params)
889
890 dev[0].hs20_enable()
891 dev[0].request("SET external_sim 1")
892 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
893 'provisioning_sp': "example.com",
894 'sp_priority': "1" })
895 id2 = dev[0].add_cred_values({ 'realm': "example.com",
896 'username': "hs20-test",
897 'password': "password",
898 'domain': "example.com",
899 'provisioning_sp': "example.com",
900 'sp_priority': "2" })
901 dev[0].dump_monitor()
902 dev[0].request("INTERWORKING_SELECT auto")
903 interworking_ext_sim_auth(dev[0], "SIM")
904 check_sp_type(dev[0], "unknown")
905 conn_bssid = dev[0].get_status_field("bssid")
906 if conn_bssid != bssid:
907 raise Exception("Connected to incorrect BSS")
908 dev[0].request("REMOVE_NETWORK all")
909
910 dev[0].set_cred(id1, "sp_priority", "2")
911 dev[0].set_cred(id2, "sp_priority", "1")
912 dev[0].dump_monitor()
913 dev[0].request("INTERWORKING_SELECT auto")
914 interworking_auth(dev[0], "TTLS")
915 check_sp_type(dev[0], "unknown")
916 conn_bssid = dev[0].get_status_field("bssid")
917 if conn_bssid != bssid2:
918 raise Exception("Connected to incorrect BSS")