]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_ap_hs20.py
tests: Verify HS 2.0 AP connection with non-HS 2.0 station
[thirdparty/hostap.git] / tests / hwsim / test_ap_hs20.py
CommitLineData
93a06242 1# Hotspot 2.0 tests
2f37a66d 2# Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
93a06242
JM
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7import time
8import subprocess
9import logging
c9aa4308 10logger = logging.getLogger()
efd43d85
JM
11import os.path
12import subprocess
93a06242
JM
13
14import hostapd
715bf904 15from wlantest import Wlantest
93a06242 16
d4058934
JM
17def hs20_ap_params(ssid="test-hs20"):
18 params = hostapd.wpa2_params(ssid=ssid)
93a06242
JM
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
2f37a66d 46def interworking_select(dev, bssid, type=None, no_match=False, freq=None):
bbe86767 47 dev.dump_monitor()
2f37a66d
JM
48 freq_extra = " freq=" + freq if freq else ""
49 dev.request("INTERWORKING_SELECT" + freq_extra)
bbe86767
JM
50 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
51 timeout=15)
93a06242
JM
52 if ev is None:
53 raise Exception("Network selection timed out");
bbe86767
JM
54 if no_match:
55 if "INTERWORKING-NO-MATCH" not in ev:
56 raise Exception("Unexpected network match")
57 return
93a06242
JM
58 if "INTERWORKING-NO-MATCH" in ev:
59 raise Exception("Matching network not found")
2cdd91d8 60 if bssid and bssid not in ev:
93a06242 61 raise Exception("Unexpected BSSID in match")
bbe86767
JM
62 if type and "type=" + type not in ev:
63 raise Exception("Network type not recognized correctly")
93a06242 64
bbe86767
JM
65def 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")
efd43d85 71
bbe86767 72def hlr_auc_gw_available():
efd43d85
JM
73 if not os.path.exists("/tmp/hlr_auc_gw.sock"):
74 logger.info("No hlr_auc_gw available");
bbe86767 75 return False
efd43d85
JM
76 if not os.path.exists("../../hostapd/hlr_auc_gw"):
77 logger.info("No hlr_auc_gw available");
bbe86767
JM
78 return False
79 return True
efd43d85 80
bbe86767
JM
81def interworking_ext_sim_connect(dev, bssid, method):
82 dev.request("INTERWORKING_CONNECT " + bssid)
078683ac 83 interworking_ext_sim_auth(dev, method)
efd43d85 84
078683ac 85def interworking_ext_sim_auth(dev, method):
bbe86767 86 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
efd43d85
JM
87 if ev is None:
88 raise Exception("Network connected timed out")
bbe86767 89 if "(" + method + ")" not in ev:
efd43d85
JM
90 raise Exception("Unexpected EAP method selection")
91
bbe86767 92 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
efd43d85
JM
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
bbe86767
JM
109 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
110 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
efd43d85
JM
111 if ev is None:
112 raise Exception("Connection timed out")
f4defd91 113
8fba2e5d
JM
114def interworking_connect(dev, bssid, method):
115 dev.request("INTERWORKING_CONNECT " + bssid)
078683ac 116 interworking_auth(dev, method)
8fba2e5d 117
078683ac 118def interworking_auth(dev, method):
8fba2e5d
JM
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
715bf904
JM
129def 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
2cdd91d8
JM
140def 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
2cdd91d8
JM
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")
2f37a66d 158 interworking_select(dev[0], None, "home", freq="2412")
2cdd91d8
JM
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
cddc19e5
JM
182def 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
715bf904
JM
215def 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"
8175854e
JM
230 del params['venue_group']
231 del params['venue_type']
715bf904
JM
232 hostapd.add_ap(apdev[1]['ifname'], params)
233
715bf904
JM
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)
0589f401 242 dev[0].scan(freq="2412")
94a2dd0b 243 time.sleep(0.03)
715bf904
JM
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")
0589f401 252 dev[0].scan(freq="2412")
94a2dd0b 253 time.sleep(0.03)
715bf904
JM
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")
0589f401 260 dev[0].scan(freq="2412")
94a2dd0b 261 time.sleep(0.03)
715bf904
JM
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")
0589f401 270 dev[0].scan(freq="2412")
94a2dd0b 271 time.sleep(0.03)
715bf904
JM
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")
0589f401 278 dev[0].scan(freq="2412")
94a2dd0b 279 time.sleep(0.03)
715bf904
JM
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")
0589f401 287 dev[0].scan(freq="2412")
94a2dd0b 288 time.sleep(0.03)
715bf904
JM
289 check_probe_resp(wt, bssid, None)
290 check_probe_resp(wt, bssid2, None)
291
bbe86767
JM
292def 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()
2232edf8
JM
300 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
301 'password': "secret",
302 'domain': "example.com" })
bbe86767
JM
303 interworking_select(dev[0], bssid, "home")
304
305 dev[0].remove_cred(id)
2232edf8
JM
306 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
307 'password': "secret",
308 'domain': "no.match.example.com" })
2f37a66d 309 interworking_select(dev[0], bssid, "roaming", freq="2412")
bbe86767
JM
310
311 dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
2f37a66d 312 interworking_select(dev[0], bssid, no_match=True, freq="2412")
bbe86767 313
4b572e3a
JM
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
459e96cd
JM
326def 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
459e96cd
JM
334 dev.hs20_enable()
335 dev.add_cred_values({ 'imsi': "555444-333222111", 'eap': method,
336 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
2f37a66d 337 interworking_select(dev, "home", freq="2412")
459e96cd
JM
338 interworking_connect(dev, bssid, method)
339 check_sp_type(dev, "home")
340
341def 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
347def 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
353def 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
bbe86767
JM
359def 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")
2232edf8 372 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
2f37a66d 373 interworking_select(dev[0], "home", freq="2412")
bbe86767
JM
374 interworking_ext_sim_connect(dev[0], bssid, "SIM")
375 check_sp_type(dev[0], "home")
59f8a3c6
JM
376
377def 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")
2232edf8 390 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
2f37a66d 391 interworking_select(dev[0], "roaming", freq="2412")
59f8a3c6
JM
392 interworking_ext_sim_connect(dev[0], bssid, "SIM")
393 check_sp_type(dev[0], "roaming")
8fba2e5d
JM
394
395def test_ap_hs20_username(dev, apdev):
396 """Hotspot 2.0 connection in username/password credential"""
8fba2e5d
JM
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()
2232edf8
JM
403 id = dev[0].add_cred_values({ 'realm': "example.com",
404 'username': "hs20-test",
405 'password': "password",
a1281b9f 406 'ca_cert': "auth_serv/ca.pem",
5f1e31cf
JM
407 'domain': "example.com",
408 'update_identifier': "1234" })
2f37a66d 409 interworking_select(dev[0], bssid, "home", freq="2412")
8fba2e5d
JM
410 interworking_connect(dev[0], bssid, "TTLS")
411 check_sp_type(dev[0], "home")
412
a1281b9f
JM
413 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS",
414 identity="hs20-test", password="password",
415 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
416 scan_freq="2412")
417
dcd68168
JM
418def eap_test(dev, ap, eap_params, method, user):
419 bssid = ap['bssid']
420 params = hs20_ap_params()
421 params['nai_realm'] = [ "0,example.com," + eap_params ]
422 hostapd.add_ap(ap['ifname'], params)
423
dcd68168
JM
424 dev.hs20_enable()
425 dev.add_cred_values({ 'realm': "example.com",
426 'username': user,
427 'password': "password" })
2f37a66d 428 interworking_select(dev, bssid, freq="2412")
dcd68168
JM
429 interworking_connect(dev, bssid, method)
430
431def test_ap_hs20_eap_peap_mschapv2(dev, apdev):
432 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
433 eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user")
434
435def test_ap_hs20_eap_peap_gtc(dev, apdev):
436 """Hotspot 2.0 connection with PEAP/GTC"""
437 eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user")
438
439def test_ap_hs20_eap_ttls_chap(dev, apdev):
440 """Hotspot 2.0 connection with TTLS/CHAP"""
441 eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user")
442
443def test_ap_hs20_eap_ttls_mschap(dev, apdev):
444 """Hotspot 2.0 connection with TTLS/MSCHAP"""
445 eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user")
446
447def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev):
448 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
449 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
450
451def test_ap_hs20_eap_fast_mschapv2(dev, apdev):
452 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
453 eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user")
454
455def test_ap_hs20_eap_fast_gtc(dev, apdev):
456 """Hotspot 2.0 connection with FAST/EAP-GTC"""
457 eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user")
458
459def test_ap_hs20_eap_tls(dev, apdev):
460 """Hotspot 2.0 connection with EAP-TLS"""
461 bssid = apdev[0]['bssid']
462 params = hs20_ap_params()
463 params['nai_realm'] = [ "0,example.com,13[5:6]" ]
464 hostapd.add_ap(apdev[0]['ifname'], params)
465
dcd68168
JM
466 dev[0].hs20_enable()
467 dev[0].add_cred_values({ 'realm': "example.com",
468 'username': "certificate-user",
469 'ca_cert': "auth_serv/ca.pem",
470 'client_cert': "auth_serv/user.pem",
471 'private_key': "auth_serv/user.key"})
2f37a66d 472 interworking_select(dev[0], bssid, freq="2412")
dcd68168
JM
473 interworking_connect(dev[0], bssid, "TLS")
474
0aca5d13
JM
475def test_ap_hs20_nai_realms(dev, apdev):
476 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
477 bssid = apdev[0]['bssid']
478 params = hs20_ap_params()
479 params['hessid'] = bssid
480 params['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
481 hostapd.add_ap(apdev[0]['ifname'], params)
482
0aca5d13
JM
483 dev[0].hs20_enable()
484 id = dev[0].add_cred_values({ 'realm': "example.com",
485 'username': "pap user",
486 'password': "password",
487 'domain': "example.com" })
2f37a66d 488 interworking_select(dev[0], bssid, "home", freq="2412")
0aca5d13
JM
489 interworking_connect(dev[0], bssid, "TTLS")
490 check_sp_type(dev[0], "home")
491
e209eb98
JM
492def test_ap_hs20_roaming_consortium(dev, apdev):
493 """Hotspot 2.0 connection based on roaming consortium match"""
494 bssid = apdev[0]['bssid']
495 params = hs20_ap_params()
496 params['hessid'] = bssid
497 hostapd.add_ap(apdev[0]['ifname'], params)
498
e209eb98
JM
499 dev[0].hs20_enable()
500 id = dev[0].add_cred_values({ 'realm': "example.com",
501 'username': "user",
502 'password': "password",
503 'domain': "example.com",
504 'roaming_consortium': "fedcba",
505 'eap': "PEAP" })
2f37a66d 506 interworking_select(dev[0], bssid, "home", freq="2412")
e209eb98
JM
507 interworking_connect(dev[0], bssid, "PEAP")
508 check_sp_type(dev[0], "home")
509
8fba2e5d
JM
510def test_ap_hs20_username_roaming(dev, apdev):
511 """Hotspot 2.0 connection in username/password credential (roaming)"""
8fba2e5d
JM
512 bssid = apdev[0]['bssid']
513 params = hs20_ap_params()
514 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
515 "0,roaming.example.com,21[2:4][5:7]",
516 "0,another.example.com" ]
517 params['domain_name'] = "another.example.com"
518 params['hessid'] = bssid
519 hostapd.add_ap(apdev[0]['ifname'], params)
520
521 dev[0].hs20_enable()
2232edf8
JM
522 id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
523 'username': "hs20-test",
524 'password': "password",
525 'domain': "example.com" })
2f37a66d 526 interworking_select(dev[0], bssid, "roaming", freq="2412")
8fba2e5d
JM
527 interworking_connect(dev[0], bssid, "TTLS")
528 check_sp_type(dev[0], "roaming")
529
530def test_ap_hs20_username_unknown(dev, apdev):
531 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
8fba2e5d
JM
532 bssid = apdev[0]['bssid']
533 params = hs20_ap_params()
534 params['hessid'] = bssid
535 hostapd.add_ap(apdev[0]['ifname'], params)
536
537 dev[0].hs20_enable()
2232edf8
JM
538 id = dev[0].add_cred_values({ 'realm': "example.com",
539 'username': "hs20-test",
540 'password': "password" })
2f37a66d 541 interworking_select(dev[0], bssid, "unknown", freq="2412")
8fba2e5d
JM
542 interworking_connect(dev[0], bssid, "TTLS")
543 check_sp_type(dev[0], "unknown")
544
545def test_ap_hs20_username_unknown2(dev, apdev):
546 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
8fba2e5d
JM
547 bssid = apdev[0]['bssid']
548 params = hs20_ap_params()
549 params['hessid'] = bssid
550 del params['domain_name']
551 hostapd.add_ap(apdev[0]['ifname'], params)
552
553 dev[0].hs20_enable()
2232edf8
JM
554 id = dev[0].add_cred_values({ 'realm': "example.com",
555 'username': "hs20-test",
556 'password': "password",
557 'domain': "example.com" })
2f37a66d 558 interworking_select(dev[0], bssid, "unknown", freq="2412")
8fba2e5d
JM
559 interworking_connect(dev[0], bssid, "TTLS")
560 check_sp_type(dev[0], "unknown")
d1ba402f 561
483691bd
JM
562def test_ap_hs20_gas_while_associated(dev, apdev):
563 """Hotspot 2.0 connection with GAS query while associated"""
564 bssid = apdev[0]['bssid']
565 params = hs20_ap_params()
566 params['hessid'] = bssid
567 hostapd.add_ap(apdev[0]['ifname'], params)
568
483691bd
JM
569 dev[0].hs20_enable()
570 id = dev[0].add_cred_values({ 'realm': "example.com",
571 'username': "hs20-test",
572 'password': "password",
573 'domain': "example.com" })
2f37a66d 574 interworking_select(dev[0], bssid, "home", freq="2412")
483691bd
JM
575 interworking_connect(dev[0], bssid, "TTLS")
576
577 logger.info("Verifying GAS query while associated")
578 dev[0].request("FETCH_ANQP")
579 for i in range(0, 6):
580 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
581 if ev is None:
582 raise Exception("Operation timed out")
583
ee2caef3
JM
584def test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
585 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
586 bssid = apdev[0]['bssid']
587 params = hs20_ap_params()
588 params['hessid'] = bssid
589 hostapd.add_ap(apdev[0]['ifname'], params)
590
591 bssid2 = apdev[1]['bssid']
592 params = hs20_ap_params()
593 params['hessid'] = bssid2
594 params['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
595 hostapd.add_ap(apdev[1]['ifname'], params)
596
597 dev[0].hs20_enable()
598 dev[0].request("SET pmf 2")
599 id = dev[0].add_cred_values({ 'realm': "example.com",
600 'username': "hs20-test",
601 'password': "password",
602 'domain': "example.com" })
603 interworking_select(dev[0], bssid, "home", freq="2412")
604 interworking_connect(dev[0], bssid, "TTLS")
605
606 logger.info("Verifying GAS query while associated")
607 dev[0].request("FETCH_ANQP")
608 for i in range(0, 2 * 6):
609 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
610 if ev is None:
611 raise Exception("Operation timed out")
612
483691bd
JM
613def test_ap_hs20_gas_frag_while_associated(dev, apdev):
614 """Hotspot 2.0 connection with fragmented GAS query while associated"""
615 bssid = apdev[0]['bssid']
616 params = hs20_ap_params()
617 params['hessid'] = bssid
618 hostapd.add_ap(apdev[0]['ifname'], params)
619 hapd = hostapd.Hostapd(apdev[0]['ifname'])
620 hapd.set("gas_frag_limit", "50")
621
483691bd
JM
622 dev[0].hs20_enable()
623 id = dev[0].add_cred_values({ 'realm': "example.com",
624 'username': "hs20-test",
625 'password': "password",
626 'domain': "example.com" })
2f37a66d 627 interworking_select(dev[0], bssid, "home", freq="2412")
483691bd
JM
628 interworking_connect(dev[0], bssid, "TTLS")
629
630 logger.info("Verifying GAS query while associated")
631 dev[0].request("FETCH_ANQP")
632 for i in range(0, 6):
633 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
634 if ev is None:
635 raise Exception("Operation timed out")
636
6a0b4002
JM
637def test_ap_hs20_multiple_connects(dev, apdev):
638 """Hotspot 2.0 connection through multiple network selections"""
639 bssid = apdev[0]['bssid']
640 params = hs20_ap_params()
641 params['hessid'] = bssid
642 hostapd.add_ap(apdev[0]['ifname'], params)
643
644 dev[0].hs20_enable()
645 values = { 'realm': "example.com",
646 'username': "hs20-test",
647 'password': "password",
648 'domain': "example.com" }
649 id = dev[0].add_cred_values(values)
650
651 for i in range(0, 3):
652 logger.info("Starting Interworking network selection")
2f37a66d 653 dev[0].request("INTERWORKING_SELECT auto freq=2412")
6a0b4002
JM
654 while True:
655 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
656 "INTERWORKING-ALREADY-CONNECTED",
657 "CTRL-EVENT-CONNECTED"], timeout=15)
658 if ev is None:
659 raise Exception("Connection timed out")
660 if "INTERWORKING-NO-MATCH" in ev:
661 raise Exception("Matching AP not found")
662 if "CTRL-EVENT-CONNECTED" in ev:
663 break
664 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
665 break
666 if i == 0:
667 dev[0].request("DISCONNECT")
668 dev[0].dump_monitor()
669
670 networks = dev[0].list_networks()
671 if len(networks) > 1:
672 raise Exception("Duplicated network block detected")
673
b4264f8f
JM
674def test_ap_hs20_disallow_aps(dev, apdev):
675 """Hotspot 2.0 connection and disallow_aps"""
676 bssid = apdev[0]['bssid']
677 params = hs20_ap_params()
678 params['hessid'] = bssid
679 hostapd.add_ap(apdev[0]['ifname'], params)
680
681 dev[0].hs20_enable()
682 values = { 'realm': "example.com",
683 'username': "hs20-test",
684 'password': "password",
685 'domain': "example.com" }
686 id = dev[0].add_cred_values(values)
687
688 logger.info("Verify disallow_aps bssid")
689 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
690 dev[0].request("INTERWORKING_SELECT auto")
691 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
692 if ev is None:
693 raise Exception("Network selection timed out")
694 dev[0].dump_monitor()
695
696 logger.info("Verify disallow_aps ssid")
697 dev[0].request("SET disallow_aps ssid 746573742d68733230")
2f37a66d 698 dev[0].request("INTERWORKING_SELECT auto freq=2412")
b4264f8f
JM
699 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
700 if ev is None:
701 raise Exception("Network selection timed out")
702 dev[0].dump_monitor()
703
704 logger.info("Verify disallow_aps clear")
705 dev[0].request("SET disallow_aps ")
2f37a66d 706 interworking_select(dev[0], bssid, "home", freq="2412")
b4264f8f
JM
707
708 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
709 ret = dev[0].request("INTERWORKING_CONNECT " + bssid)
710 if "FAIL" not in ret:
711 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
712
d1ba402f
JM
713def policy_test(dev, ap, values, only_one=True):
714 dev.dump_monitor()
19839f8e
JM
715 if ap:
716 logger.info("Verify network selection to AP " + ap['ifname'])
717 bssid = ap['bssid']
718 else:
719 logger.info("Verify network selection")
720 bssid = None
d1ba402f
JM
721 dev.hs20_enable()
722 id = dev.add_cred_values(values)
2f37a66d 723 dev.request("INTERWORKING_SELECT auto freq=2412")
19839f8e 724 events = []
d1ba402f
JM
725 while True:
726 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1965cc3a 727 "INTERWORKING-BLACKLISTED",
953a574d 728 "INTERWORKING-SELECTED"], timeout=15)
d1ba402f 729 if ev is None:
953a574d 730 raise Exception("Network selection timed out")
19839f8e 731 events.append(ev)
d1ba402f
JM
732 if "INTERWORKING-NO-MATCH" in ev:
733 raise Exception("Matching AP not found")
19839f8e 734 if bssid and only_one and "INTERWORKING-AP" in ev and bssid not in ev:
d1ba402f 735 raise Exception("Unexpected AP claimed acceptable")
953a574d 736 if "INTERWORKING-SELECTED" in ev:
19839f8e 737 if bssid and bssid not in ev:
953a574d 738 raise Exception("Selected incorrect BSS")
d1ba402f
JM
739 break
740
953a574d
JM
741 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
742 if ev is None:
743 raise Exception("Connection timed out")
19839f8e 744 if bssid and bssid not in ev:
953a574d
JM
745 raise Exception("Connected to incorrect BSS")
746
d1ba402f 747 conn_bssid = dev.get_status_field("bssid")
19839f8e 748 if bssid and conn_bssid != bssid:
d1ba402f
JM
749 raise Exception("bssid information points to incorrect BSS")
750
751 dev.remove_cred(id)
752 dev.dump_monitor()
19839f8e 753 return events
d1ba402f 754
d355372c
JM
755def default_cred():
756 return { 'realm': "example.com",
757 'username': "hs20-test",
758 'password': "password" }
759
d1ba402f
JM
760def test_ap_hs20_req_roaming_consortium(dev, apdev):
761 """Hotspot 2.0 required roaming consortium"""
762 params = hs20_ap_params()
763 hostapd.add_ap(apdev[0]['ifname'], params)
764
765 params = hs20_ap_params()
766 params['ssid'] = "test-hs20-other"
767 params['roaming_consortium'] = [ "223344" ]
768 hostapd.add_ap(apdev[1]['ifname'], params)
769
d355372c
JM
770 values = default_cred()
771 values['required_roaming_consortium'] = "223344"
d1ba402f
JM
772 policy_test(dev[0], apdev[1], values)
773 values['required_roaming_consortium'] = "112233"
774 policy_test(dev[0], apdev[0], values)
d355372c 775
af70a093
JM
776 id = dev[0].add_cred()
777 dev[0].set_cred(id, "required_roaming_consortium", "112233")
778 dev[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
779
780 for val in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
781 if "FAIL" not in dev[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val)):
782 raise Exception("Invalid roaming consortium value accepted: " + val)
783
d355372c
JM
784def test_ap_hs20_excluded_ssid(dev, apdev):
785 """Hotspot 2.0 exclusion based on SSID"""
786 params = hs20_ap_params()
787 hostapd.add_ap(apdev[0]['ifname'], params)
788
789 params = hs20_ap_params()
790 params['ssid'] = "test-hs20-other"
791 params['roaming_consortium'] = [ "223344" ]
792 hostapd.add_ap(apdev[1]['ifname'], params)
793
794 values = default_cred()
795 values['excluded_ssid'] = "test-hs20"
1965cc3a
JM
796 events = policy_test(dev[0], apdev[1], values)
797 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
798 if len(ev) != 1:
799 raise Exception("Excluded network not reported")
d355372c 800 values['excluded_ssid'] = "test-hs20-other"
1965cc3a
JM
801 events = policy_test(dev[0], apdev[0], values)
802 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[1]['bssid'] in e]
803 if len(ev) != 1:
804 raise Exception("Excluded network not reported")
d4058934
JM
805
806def test_ap_hs20_roam_to_higher_prio(dev, apdev):
807 """Hotspot 2.0 and roaming from current to higher priority network"""
808 bssid = apdev[0]['bssid']
809 params = hs20_ap_params(ssid="test-hs20-visited")
810 params['domain_name'] = "visited.example.org"
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 logger.info("Connect to the only network option")
819 interworking_select(dev[0], bssid, "roaming", freq="2412")
820 dev[0].dump_monitor()
821 interworking_connect(dev[0], bssid, "TTLS")
822
823 logger.info("Start another AP (home operator) and reconnect")
824 bssid2 = apdev[1]['bssid']
825 params = hs20_ap_params(ssid="test-hs20-home")
826 params['domain_name'] = "example.com"
827 hostapd.add_ap(apdev[1]['ifname'], params)
828
829 dev[0].request("INTERWORKING_SELECT auto freq=2412")
830 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
831 "INTERWORKING-ALREADY-CONNECTED",
832 "CTRL-EVENT-CONNECTED"], timeout=15)
833 if ev is None:
834 raise Exception("Connection timed out")
835 if "INTERWORKING-NO-MATCH" in ev:
836 raise Exception("Matching AP not found")
837 if "INTERWORKING-ALREADY-CONNECTED" in ev:
838 raise Exception("Unexpected AP selected")
839 if bssid2 not in ev:
840 raise Exception("Unexpected BSSID after reconnection")
12c587a5
JM
841
842def test_ap_hs20_domain_suffix_match(dev, apdev):
843 """Hotspot 2.0 and domain_suffix_match"""
844 bssid = apdev[0]['bssid']
845 params = hs20_ap_params()
846 hostapd.add_ap(apdev[0]['ifname'], params)
847
848 dev[0].hs20_enable()
849 id = dev[0].add_cred_values({ 'realm': "example.com",
850 'username': "hs20-test",
851 'password': "password",
852 'domain': "example.com",
853 'domain_suffix_match': "w1.fi" })
854 interworking_select(dev[0], bssid, "home", freq="2412")
855 dev[0].dump_monitor()
856 interworking_connect(dev[0], bssid, "TTLS")
857 dev[0].request("REMOVE_NETWORK all")
858 dev[0].dump_monitor()
859
860 dev[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
861 interworking_select(dev[0], bssid, "home", freq="2412")
862 dev[0].dump_monitor()
863 dev[0].request("INTERWORKING_CONNECT " + bssid)
864 ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
865 if ev is None:
866 raise Exception("TLS certificate error not reported")
867 if "Domain suffix mismatch" not in ev:
868 raise Exception("Domain suffix mismatch not reported")
078683ac 869
2253ea44
JM
870def test_ap_hs20_roaming_partner_preference(dev, apdev):
871 """Hotspot 2.0 and roaming partner preference"""
872 params = hs20_ap_params()
873 params['domain_name'] = "roaming.example.org"
874 hostapd.add_ap(apdev[0]['ifname'], params)
875
876 params = hs20_ap_params()
877 params['ssid'] = "test-hs20-other"
878 params['domain_name'] = "roaming.example.net"
879 hostapd.add_ap(apdev[1]['ifname'], params)
880
881 logger.info("Verify default vs. specified preference")
882 values = default_cred()
883 values['roaming_partner'] = "roaming.example.net,1,127,*"
884 policy_test(dev[0], apdev[1], values, only_one=False)
885 values['roaming_partner'] = "roaming.example.net,1,129,*"
886 policy_test(dev[0], apdev[0], values, only_one=False)
887
888 logger.info("Verify partial FQDN match")
889 values['roaming_partner'] = "example.net,0,0,*"
890 policy_test(dev[0], apdev[1], values, only_one=False)
891 values['roaming_partner'] = "example.net,0,255,*"
892 policy_test(dev[0], apdev[0], values, only_one=False)
893
19839f8e
JM
894def test_ap_hs20_max_bss_load(dev, apdev):
895 """Hotspot 2.0 and maximum BSS load"""
896 params = hs20_ap_params()
897 params['bss_load_test'] = "12:200:20000"
898 hostapd.add_ap(apdev[0]['ifname'], params)
899
900 params = hs20_ap_params()
901 params['ssid'] = "test-hs20-other"
902 params['bss_load_test'] = "5:20:10000"
903 hostapd.add_ap(apdev[1]['ifname'], params)
904
905 logger.info("Verify maximum BSS load constraint")
906 values = default_cred()
907 values['domain'] = "example.com"
908 values['max_bss_load'] = "100"
909 events = policy_test(dev[0], apdev[1], values, only_one=False)
910
911 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
912 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
913 raise Exception("Maximum BSS Load case not noticed")
914 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
915 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
916 raise Exception("Maximum BSS Load case reported incorrectly")
917
918 logger.info("Verify maximum BSS load does not prevent connection")
919 values['max_bss_load'] = "1"
920 events = policy_test(dev[0], None, values)
921
922 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
923 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
924 raise Exception("Maximum BSS Load case not noticed")
925 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
926 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
927 raise Exception("Maximum BSS Load case not noticed")
928
929def test_ap_hs20_max_bss_load2(dev, apdev):
930 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
931 params = hs20_ap_params()
932 params['bss_load_test'] = "12:200:20000"
933 hostapd.add_ap(apdev[0]['ifname'], params)
934
935 params = hs20_ap_params()
936 params['ssid'] = "test-hs20-other"
937 hostapd.add_ap(apdev[1]['ifname'], params)
938
939 logger.info("Verify maximum BSS load constraint with AP advertisement")
940 values = default_cred()
941 values['domain'] = "example.com"
942 values['max_bss_load'] = "100"
943 events = policy_test(dev[0], apdev[1], values, only_one=False)
944
945 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
946 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
947 raise Exception("Maximum BSS Load case not noticed")
948 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
949 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
950 raise Exception("Maximum BSS Load case reported incorrectly")
951
078683ac
JM
952def test_ap_hs20_multi_cred_sp_prio(dev, apdev):
953 """Hotspot 2.0 multi-cred sp_priority"""
954 if not hlr_auc_gw_available():
955 return "skip"
956 bssid = apdev[0]['bssid']
957 params = hs20_ap_params()
958 params['hessid'] = bssid
959 del params['domain_name']
960 params['anqp_3gpp_cell_net'] = "232,01"
961 hostapd.add_ap(apdev[0]['ifname'], params)
962
963 dev[0].hs20_enable()
964 dev[0].request("SET external_sim 1")
965 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
966 'provisioning_sp': "example.com",
967 'sp_priority' :"1" })
968 id2 = dev[0].add_cred_values({ 'realm': "example.com",
969 'username': "hs20-test",
970 'password': "password",
971 'domain': "example.com",
972 'provisioning_sp': "example.com",
973 'sp_priority': "2" })
974 dev[0].dump_monitor()
975 dev[0].request("INTERWORKING_SELECT auto")
976 interworking_ext_sim_auth(dev[0], "SIM")
977 check_sp_type(dev[0], "unknown")
978 dev[0].request("REMOVE_NETWORK all")
979
980 dev[0].set_cred(id1, "sp_priority", "2")
981 dev[0].set_cred(id2, "sp_priority", "1")
982 dev[0].dump_monitor()
983 dev[0].request("INTERWORKING_SELECT auto")
984 interworking_auth(dev[0], "TTLS")
985 check_sp_type(dev[0], "unknown")
986
987def test_ap_hs20_multi_cred_sp_prio2(dev, apdev):
988 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
989 if not hlr_auc_gw_available():
990 return "skip"
991 bssid = apdev[0]['bssid']
992 params = hs20_ap_params()
993 params['hessid'] = bssid
994 del params['nai_realm']
995 del params['domain_name']
996 params['anqp_3gpp_cell_net'] = "232,01"
997 hostapd.add_ap(apdev[0]['ifname'], params)
998
999 bssid2 = apdev[1]['bssid']
1000 params = hs20_ap_params()
1001 params['ssid'] = "test-hs20-other"
1002 params['hessid'] = bssid2
1003 del params['domain_name']
1004 del params['anqp_3gpp_cell_net']
1005 hostapd.add_ap(apdev[1]['ifname'], params)
1006
1007 dev[0].hs20_enable()
1008 dev[0].request("SET external_sim 1")
1009 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1010 'provisioning_sp': "example.com",
1011 'sp_priority': "1" })
1012 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1013 'username': "hs20-test",
1014 'password': "password",
1015 'domain': "example.com",
1016 'provisioning_sp': "example.com",
1017 'sp_priority': "2" })
1018 dev[0].dump_monitor()
1019 dev[0].request("INTERWORKING_SELECT auto")
1020 interworking_ext_sim_auth(dev[0], "SIM")
1021 check_sp_type(dev[0], "unknown")
1022 conn_bssid = dev[0].get_status_field("bssid")
1023 if conn_bssid != bssid:
1024 raise Exception("Connected to incorrect BSS")
1025 dev[0].request("REMOVE_NETWORK all")
1026
1027 dev[0].set_cred(id1, "sp_priority", "2")
1028 dev[0].set_cred(id2, "sp_priority", "1")
1029 dev[0].dump_monitor()
1030 dev[0].request("INTERWORKING_SELECT auto")
1031 interworking_auth(dev[0], "TTLS")
1032 check_sp_type(dev[0], "unknown")
1033 conn_bssid = dev[0].get_status_field("bssid")
1034 if conn_bssid != bssid2:
1035 raise Exception("Connected to incorrect BSS")
5e32f825 1036
18153179
JM
1037def test_ap_hs20_req_conn_capab(dev, apdev):
1038 """Hotspot 2.0 network selection with req_conn_capab"""
1039 bssid = apdev[0]['bssid']
1040 params = hs20_ap_params()
1041 hostapd.add_ap(apdev[0]['ifname'], params)
1042
1043 dev[0].hs20_enable()
1044 logger.info("Not used in home network")
1045 id = dev[0].add_cred_values({ 'realm': "example.com",
1046 'username': "hs20-test",
1047 'password': "password",
1048 'domain': "example.com",
1049 'req_conn_capab': "6:1234" })
1050 dev[0].request("INTERWORKING_SELECT freq=2412")
1051 ev = dev[0].wait_event(["INTERWORKING-AP"])
1052 if ev is None:
1053 raise Exception("Network selection timed out");
1054 if "type=home" not in ev:
1055 raise Exception("Unexpected network type")
1056 if "conn_capab_missing=1" in ev:
1057 raise Exception("req_conn_capab used in home network")
1058
1059 logger.info("Used in roaming network")
1060 dev[0].remove_cred(id)
1061 id = dev[0].add_cred_values({ 'realm': "example.com",
1062 'username': "hs20-test",
1063 'password': "password",
1064 'domain': "example.org",
1065 'req_conn_capab': "6:1234" })
1066 dev[0].request("INTERWORKING_SELECT freq=2412")
1067 ev = dev[0].wait_event(["INTERWORKING-AP"])
1068 if ev is None:
1069 raise Exception("Network selection timed out");
1070 if "type=roaming" not in ev:
1071 raise Exception("Unexpected network type")
1072 if "conn_capab_missing=1" not in ev:
1073 raise Exception("Missing conn_capab not reported")
1074
1075 logger.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1076 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1077 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1078 if ev is None:
1079 raise Exception("Connection timed out")
1080
5e32f825
JM
1081def test_ap_hs20_deauth_req_ess(dev, apdev):
1082 """Hotspot 2.0 connection and deauthentication request for ESS"""
1083 dev[0].request("SET pmf 2")
1084 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1085 dev[0].dump_monitor()
1086 addr = dev[0].p2p_interface_addr()
1087 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1088 hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/")
1089 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1090 if ev is None:
1091 raise Exception("Timeout on deauth imminent notice")
1092 if "1 120 http://example.com/" not in ev:
1093 raise Exception("Unexpected deauth imminent notice: " + ev)
1094 hapd.request("DEAUTHENTICATE " + addr)
1095 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1096 if ev is None:
1097 raise Exception("Timeout on disconnection")
1098 ev = dev[0].wait_event(["SME: Trying to authenticate",
1099 "Trying to associate",
1100 "CTRL-EVENT-CONNECTED"], timeout=5)
1101 if ev is not None:
1102 raise Exception("Unexpected connection attempt")
1103
1104def test_ap_hs20_deauth_req_bss(dev, apdev):
1105 """Hotspot 2.0 connection and deauthentication request for BSS"""
1106 dev[0].request("SET pmf 2")
1107 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1108 dev[0].dump_monitor()
1109 addr = dev[0].p2p_interface_addr()
1110 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1111 hapd.request("HS20_DEAUTH_REQ " + addr + " 0 120 http://example.com/")
1112 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1113 if ev is None:
1114 raise Exception("Timeout on deauth imminent notice")
1115 if "0 120 http://example.com/" not in ev:
1116 raise Exception("Unexpected deauth imminent notice: " + ev)
1117 hapd.request("DEAUTHENTICATE " + addr + " reason=4")
1118 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1119 if ev is None:
1120 raise Exception("Timeout on disconnection")
1121 if "reason=4" not in ev:
1122 raise Exception("Unexpected disconnection reason")
1123 ev = dev[0].wait_event(["SME: Trying to authenticate",
1124 "Trying to associate",
1125 "CTRL-EVENT-CONNECTED"], timeout=5)
1126 if ev is not None:
1127 raise Exception("Unexpected connection attempt")
9e709315
JM
1128
1129def test_ap_hs20_osen(dev, apdev):
1130 """Hotspot 2.0 OSEN connection"""
1131 params = { 'ssid': "osen",
1132 'osen': "1",
1133 'auth_server_addr': "127.0.0.1",
1134 'auth_server_port': "1812",
1135 'auth_server_shared_secret': "radius" }
1136 hostapd.add_ap(apdev[0]['ifname'], params)
1137
1138 dev[0].connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1139 group="GTK_NOT_USED",
1140 eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1141 ca_cert="auth_serv/ca.pem",
1142 scan_freq="2412")
a96066a5
JM
1143
1144def test_ap_hs20_network_preference(dev, apdev):
1145 """Hotspot 2.0 network selection with preferred home network"""
1146 bssid = apdev[0]['bssid']
1147 params = hs20_ap_params()
1148 hostapd.add_ap(apdev[0]['ifname'], params)
1149
1150 dev[0].hs20_enable()
1151 values = { 'realm': "example.com",
1152 'username': "hs20-test",
1153 'password': "password",
1154 'domain': "example.com" }
1155 dev[0].add_cred_values(values)
1156
1157 id = dev[0].add_network()
1158 dev[0].set_network_quoted(id, "ssid", "home")
1159 dev[0].set_network_quoted(id, "psk", "12345678")
1160 dev[0].set_network(id, "priority", "1")
1161 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1162
1163 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1164 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1165 if ev is None:
1166 raise Exception("Connection timed out")
1167 if bssid not in ev:
1168 raise Exception("Unexpected network selected")
1169
1170 bssid2 = apdev[1]['bssid']
1171 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1172 hostapd.add_ap(apdev[1]['ifname'], params)
1173
1174 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1175 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1176 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1177 if ev is None:
1178 raise Exception("Connection timed out")
1179 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1180 raise Exception("No roam to higher priority network")
1181 if bssid2 not in ev:
1182 raise Exception("Unexpected network selected")
1183
1184def test_ap_hs20_network_preference2(dev, apdev):
1185 """Hotspot 2.0 network selection with preferred credential"""
1186 bssid2 = apdev[1]['bssid']
1187 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1188 hostapd.add_ap(apdev[1]['ifname'], params)
1189
1190 dev[0].hs20_enable()
1191 values = { 'realm': "example.com",
1192 'username': "hs20-test",
1193 'password': "password",
1194 'domain': "example.com",
1195 'priority': "1" }
1196 dev[0].add_cred_values(values)
1197
1198 id = dev[0].add_network()
1199 dev[0].set_network_quoted(id, "ssid", "home")
1200 dev[0].set_network_quoted(id, "psk", "12345678")
1201 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1202
1203 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1204 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1205 if ev is None:
1206 raise Exception("Connection timed out")
1207 if bssid2 not in ev:
1208 raise Exception("Unexpected network selected")
1209
1210 bssid = apdev[0]['bssid']
1211 params = hs20_ap_params()
1212 hostapd.add_ap(apdev[0]['ifname'], params)
1213
1214 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1215 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1216 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1217 if ev is None:
1218 raise Exception("Connection timed out")
1219 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1220 raise Exception("No roam to higher priority network")
1221 if bssid not in ev:
1222 raise Exception("Unexpected network selected")