]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_ap_hs20.py
tests: Connection during large packet loss
[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()
97de642a 11import os
efd43d85
JM
12import os.path
13import subprocess
93a06242
JM
14
15import hostapd
715bf904 16from wlantest import Wlantest
9d1e1172 17from wpasupplicant import WpaSupplicant
93a06242 18
d4058934
JM
19def hs20_ap_params(ssid="test-hs20"):
20 params = hostapd.wpa2_params(ssid=ssid)
93a06242
JM
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"
30 params['asra'] = "0"
31 params['esr'] = "0"
32 params['uesa'] = "0"
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",
37 "fedcba" ]
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" ]
41 params['hs20'] = "1"
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"
46 return params
47
9714fbcd
JM
48def check_auto_select(dev, bssid):
49 dev.request("INTERWORKING_SELECT auto freq=2412")
50 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
51 if ev is None:
52 raise Exception("Connection timed out")
53 if bssid not in ev:
54 raise Exception("Connected to incorrect network")
55 dev.request("REMOVE_NETWORK all")
56
2f37a66d 57def interworking_select(dev, bssid, type=None, no_match=False, freq=None):
bbe86767 58 dev.dump_monitor()
2f37a66d
JM
59 freq_extra = " freq=" + freq if freq else ""
60 dev.request("INTERWORKING_SELECT" + freq_extra)
bbe86767
JM
61 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
62 timeout=15)
93a06242
JM
63 if ev is None:
64 raise Exception("Network selection timed out");
bbe86767
JM
65 if no_match:
66 if "INTERWORKING-NO-MATCH" not in ev:
67 raise Exception("Unexpected network match")
68 return
93a06242
JM
69 if "INTERWORKING-NO-MATCH" in ev:
70 raise Exception("Matching network not found")
2cdd91d8 71 if bssid and bssid not in ev:
93a06242 72 raise Exception("Unexpected BSSID in match")
bbe86767
JM
73 if type and "type=" + type not in ev:
74 raise Exception("Network type not recognized correctly")
93a06242 75
bbe86767
JM
76def check_sp_type(dev, sp_type):
77 type = dev.get_status_field("sp_type")
78 if type is None:
79 raise Exception("sp_type not available")
80 if type != sp_type:
81 raise Exception("sp_type did not indicate home network")
efd43d85 82
bbe86767 83def hlr_auc_gw_available():
efd43d85
JM
84 if not os.path.exists("/tmp/hlr_auc_gw.sock"):
85 logger.info("No hlr_auc_gw available");
bbe86767 86 return False
efd43d85
JM
87 if not os.path.exists("../../hostapd/hlr_auc_gw"):
88 logger.info("No hlr_auc_gw available");
bbe86767
JM
89 return False
90 return True
efd43d85 91
bbe86767
JM
92def interworking_ext_sim_connect(dev, bssid, method):
93 dev.request("INTERWORKING_CONNECT " + bssid)
078683ac 94 interworking_ext_sim_auth(dev, method)
efd43d85 95
078683ac 96def interworking_ext_sim_auth(dev, method):
bbe86767 97 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
efd43d85
JM
98 if ev is None:
99 raise Exception("Network connected timed out")
bbe86767 100 if "(" + method + ")" not in ev:
efd43d85
JM
101 raise Exception("Unexpected EAP method selection")
102
bbe86767 103 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
efd43d85
JM
104 if ev is None:
105 raise Exception("Wait for external SIM processing request timed out")
106 p = ev.split(':', 2)
107 if p[1] != "GSM-AUTH":
108 raise Exception("Unexpected CTRL-REQ-SIM type")
109 id = p[0].split('-')[3]
110 rand = p[2].split(' ')[0]
111
112 res = subprocess.check_output(["../../hostapd/hlr_auc_gw",
113 "-m",
114 "auth_serv/hlr_auc_gw.milenage_db",
115 "GSM-AUTH-REQ 232010000000000 " + rand])
116 if "GSM-AUTH-RESP" not in res:
117 raise Exception("Unexpected hlr_auc_gw response")
118 resp = res.split(' ')[2].rstrip()
119
bbe86767
JM
120 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
121 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
efd43d85
JM
122 if ev is None:
123 raise Exception("Connection timed out")
f4defd91 124
8fba2e5d
JM
125def interworking_connect(dev, bssid, method):
126 dev.request("INTERWORKING_CONNECT " + bssid)
078683ac 127 interworking_auth(dev, method)
8fba2e5d 128
078683ac 129def interworking_auth(dev, method):
8fba2e5d
JM
130 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
131 if ev is None:
132 raise Exception("Network connected timed out")
133 if "(" + method + ")" not in ev:
134 raise Exception("Unexpected EAP method selection")
135
136 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
137 if ev is None:
138 raise Exception("Connection timed out")
139
715bf904
JM
140def check_probe_resp(wt, bssid_unexpected, bssid_expected):
141 if bssid_unexpected:
142 count = wt.get_bss_counter("probe_response", bssid_unexpected)
143 if count > 0:
144 raise Exception("Unexpected Probe Response frame from AP")
145
146 if bssid_expected:
147 count = wt.get_bss_counter("probe_response", bssid_expected)
148 if count == 0:
149 raise Exception("No Probe Response frame from AP")
150
2cdd91d8
JM
151def test_ap_anqp_sharing(dev, apdev):
152 """ANQP sharing within ESS and explicit unshare"""
153 bssid = apdev[0]['bssid']
154 params = hs20_ap_params()
155 params['hessid'] = bssid
156 hostapd.add_ap(apdev[0]['ifname'], params)
157
158 bssid2 = apdev[1]['bssid']
159 params = hs20_ap_params()
160 params['hessid'] = bssid
161 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
162 hostapd.add_ap(apdev[1]['ifname'], params)
163
2cdd91d8
JM
164 dev[0].hs20_enable()
165 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
166 'password': "secret",
167 'domain': "example.com" })
168 logger.info("Normal network selection with shared ANQP results")
2f37a66d 169 interworking_select(dev[0], None, "home", freq="2412")
2cdd91d8
JM
170 dev[0].dump_monitor()
171
172 res1 = dev[0].get_bss(bssid)
173 res2 = dev[0].get_bss(bssid2)
174 if res1['anqp_nai_realm'] != res2['anqp_nai_realm']:
175 raise Exception("ANQP results were not shared between BSSes")
176
177 logger.info("Explicit ANQP request to unshare ANQP results")
178 dev[0].request("ANQP_GET " + bssid + " 263")
179 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
180 if ev is None:
181 raise Exception("ANQP operation timed out")
182
183 dev[0].request("ANQP_GET " + bssid2 + " 263")
184 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
185 if ev is None:
186 raise Exception("ANQP operation timed out")
187
188 res1 = dev[0].get_bss(bssid)
189 res2 = dev[0].get_bss(bssid2)
190 if res1['anqp_nai_realm'] == res2['anqp_nai_realm']:
191 raise Exception("ANQP results were not unshared")
192
cddc19e5
JM
193def test_ap_nai_home_realm_query(dev, apdev):
194 """NAI Home Realm Query"""
195 bssid = apdev[0]['bssid']
196 params = hs20_ap_params()
197 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
198 "0,another.example.org" ]
199 hostapd.add_ap(apdev[0]['ifname'], params)
200
201 dev[0].scan(freq="2412")
202 dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " realm=example.com")
203 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
204 if ev is None:
205 raise Exception("ANQP operation timed out")
206 nai1 = dev[0].get_bss(bssid)['anqp_nai_realm']
207 dev[0].dump_monitor()
208
209 dev[0].request("ANQP_GET " + bssid + " 263")
210 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
211 if ev is None:
212 raise Exception("ANQP operation timed out")
213 nai2 = dev[0].get_bss(bssid)['anqp_nai_realm']
214
215 if len(nai1) >= len(nai2):
216 raise Exception("Unexpected NAI Realm list response lengths")
217 if "example.com".encode('hex') not in nai1:
218 raise Exception("Home realm not reported")
219 if "example.org".encode('hex') in nai1:
220 raise Exception("Non-home realm reported")
221 if "example.com".encode('hex') not in nai2:
222 raise Exception("Home realm not reported in wildcard query")
223 if "example.org".encode('hex') not in nai2:
224 raise Exception("Non-home realm not reported in wildcard query ")
225
715bf904
JM
226def test_ap_interworking_scan_filtering(dev, apdev):
227 """Interworking scan filtering with HESSID and access network type"""
228 bssid = apdev[0]['bssid']
229 params = hs20_ap_params()
230 ssid = "test-hs20-ap1"
231 params['ssid'] = ssid
232 params['hessid'] = bssid
233 hostapd.add_ap(apdev[0]['ifname'], params)
234
235 bssid2 = apdev[1]['bssid']
236 params = hs20_ap_params()
237 ssid2 = "test-hs20-ap2"
238 params['ssid'] = ssid2
239 params['hessid'] = bssid2
240 params['access_network_type'] = "1"
8175854e
JM
241 del params['venue_group']
242 del params['venue_type']
715bf904
JM
243 hostapd.add_ap(apdev[1]['ifname'], params)
244
715bf904
JM
245 dev[0].hs20_enable()
246
247 wt = Wlantest()
248 wt.flush()
249
250 logger.info("Check probe request filtering based on HESSID")
251
252 dev[0].request("SET hessid " + bssid2)
0589f401 253 dev[0].scan(freq="2412")
94a2dd0b 254 time.sleep(0.03)
715bf904
JM
255 check_probe_resp(wt, bssid, bssid2)
256
257 logger.info("Check probe request filtering based on access network type")
258
259 wt.clear_bss_counters(bssid)
260 wt.clear_bss_counters(bssid2)
261 dev[0].request("SET hessid 00:00:00:00:00:00")
262 dev[0].request("SET access_network_type 14")
0589f401 263 dev[0].scan(freq="2412")
94a2dd0b 264 time.sleep(0.03)
715bf904
JM
265 check_probe_resp(wt, bssid2, bssid)
266
267 wt.clear_bss_counters(bssid)
268 wt.clear_bss_counters(bssid2)
269 dev[0].request("SET hessid 00:00:00:00:00:00")
270 dev[0].request("SET access_network_type 1")
0589f401 271 dev[0].scan(freq="2412")
94a2dd0b 272 time.sleep(0.03)
715bf904
JM
273 check_probe_resp(wt, bssid, bssid2)
274
275 logger.info("Check probe request filtering based on HESSID and ANT")
276
277 wt.clear_bss_counters(bssid)
278 wt.clear_bss_counters(bssid2)
279 dev[0].request("SET hessid " + bssid)
280 dev[0].request("SET access_network_type 14")
0589f401 281 dev[0].scan(freq="2412")
94a2dd0b 282 time.sleep(0.03)
715bf904
JM
283 check_probe_resp(wt, bssid2, bssid)
284
285 wt.clear_bss_counters(bssid)
286 wt.clear_bss_counters(bssid2)
287 dev[0].request("SET hessid " + bssid2)
288 dev[0].request("SET access_network_type 14")
0589f401 289 dev[0].scan(freq="2412")
94a2dd0b 290 time.sleep(0.03)
715bf904
JM
291 check_probe_resp(wt, bssid, None)
292 check_probe_resp(wt, bssid2, None)
293
294 wt.clear_bss_counters(bssid)
295 wt.clear_bss_counters(bssid2)
296 dev[0].request("SET hessid " + bssid)
297 dev[0].request("SET access_network_type 1")
0589f401 298 dev[0].scan(freq="2412")
94a2dd0b 299 time.sleep(0.03)
715bf904
JM
300 check_probe_resp(wt, bssid, None)
301 check_probe_resp(wt, bssid2, None)
302
bbe86767
JM
303def test_ap_hs20_select(dev, apdev):
304 """Hotspot 2.0 network selection"""
305 bssid = apdev[0]['bssid']
306 params = hs20_ap_params()
307 params['hessid'] = bssid
308 hostapd.add_ap(apdev[0]['ifname'], params)
309
310 dev[0].hs20_enable()
2232edf8
JM
311 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
312 'password': "secret",
313 'domain': "example.com" })
bbe86767
JM
314 interworking_select(dev[0], bssid, "home")
315
316 dev[0].remove_cred(id)
2232edf8
JM
317 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
318 'password': "secret",
319 'domain': "no.match.example.com" })
2f37a66d 320 interworking_select(dev[0], bssid, "roaming", freq="2412")
bbe86767
JM
321
322 dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
2f37a66d 323 interworking_select(dev[0], bssid, no_match=True, freq="2412")
bbe86767 324
4b572e3a
JM
325 bssid2 = apdev[1]['bssid']
326 params = hs20_ap_params()
327 params['nai_realm'] = [ "0,example.org,21" ]
328 params['hessid'] = bssid2
329 params['domain_name'] = "example.org"
330 hostapd.add_ap(apdev[1]['ifname'], params)
331 dev[0].remove_cred(id)
332 id = dev[0].add_cred_values({ 'realm': "example.org", 'username': "test",
333 'password': "secret",
334 'domain': "example.org" })
335 interworking_select(dev[0], bssid2, "home", freq="2412")
336
459e96cd
JM
337def hs20_simulated_sim(dev, ap, method):
338 bssid = ap['bssid']
339 params = hs20_ap_params()
340 params['hessid'] = bssid
341 params['anqp_3gpp_cell_net'] = "555,444"
342 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
343 hostapd.add_ap(ap['ifname'], params)
344
459e96cd
JM
345 dev.hs20_enable()
346 dev.add_cred_values({ 'imsi': "555444-333222111", 'eap': method,
347 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
2f37a66d 348 interworking_select(dev, "home", freq="2412")
459e96cd
JM
349 interworking_connect(dev, bssid, method)
350 check_sp_type(dev, "home")
351
352def test_ap_hs20_sim(dev, apdev):
353 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
354 if not hlr_auc_gw_available():
355 return "skip"
356 hs20_simulated_sim(dev[0], apdev[0], "SIM")
16ab63f4
JM
357 dev[0].request("INTERWORKING_SELECT auto freq=2412")
358 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
359 if ev is None:
360 raise Exception("Timeout on already-connected event")
459e96cd
JM
361
362def test_ap_hs20_aka(dev, apdev):
363 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
364 if not hlr_auc_gw_available():
365 return "skip"
366 hs20_simulated_sim(dev[0], apdev[0], "AKA")
367
368def test_ap_hs20_aka_prime(dev, apdev):
369 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
370 if not hlr_auc_gw_available():
371 return "skip"
372 hs20_simulated_sim(dev[0], apdev[0], "AKA'")
373
bbe86767
JM
374def test_ap_hs20_ext_sim(dev, apdev):
375 """Hotspot 2.0 with external SIM processing"""
376 if not hlr_auc_gw_available():
377 return "skip"
378 bssid = apdev[0]['bssid']
379 params = hs20_ap_params()
380 params['hessid'] = bssid
381 params['anqp_3gpp_cell_net'] = "232,01"
382 params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
383 hostapd.add_ap(apdev[0]['ifname'], params)
384
385 dev[0].hs20_enable()
386 dev[0].request("SET external_sim 1")
2232edf8 387 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
2f37a66d 388 interworking_select(dev[0], "home", freq="2412")
bbe86767
JM
389 interworking_ext_sim_connect(dev[0], bssid, "SIM")
390 check_sp_type(dev[0], "home")
59f8a3c6
JM
391
392def test_ap_hs20_ext_sim_roaming(dev, apdev):
393 """Hotspot 2.0 with external SIM processing in roaming network"""
394 if not hlr_auc_gw_available():
395 return "skip"
396 bssid = apdev[0]['bssid']
397 params = hs20_ap_params()
398 params['hessid'] = bssid
399 params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
400 params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
401 hostapd.add_ap(apdev[0]['ifname'], params)
402
403 dev[0].hs20_enable()
404 dev[0].request("SET external_sim 1")
2232edf8 405 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
2f37a66d 406 interworking_select(dev[0], "roaming", freq="2412")
59f8a3c6
JM
407 interworking_ext_sim_connect(dev[0], bssid, "SIM")
408 check_sp_type(dev[0], "roaming")
8fba2e5d
JM
409
410def test_ap_hs20_username(dev, apdev):
411 """Hotspot 2.0 connection in username/password credential"""
8fba2e5d
JM
412 bssid = apdev[0]['bssid']
413 params = hs20_ap_params()
414 params['hessid'] = bssid
d627e131 415 params['disable_dgaf'] = '1'
8fba2e5d
JM
416 hostapd.add_ap(apdev[0]['ifname'], params)
417
418 dev[0].hs20_enable()
2232edf8
JM
419 id = dev[0].add_cred_values({ 'realm': "example.com",
420 'username': "hs20-test",
421 'password': "password",
a1281b9f 422 'ca_cert': "auth_serv/ca.pem",
5f1e31cf
JM
423 'domain': "example.com",
424 'update_identifier': "1234" })
2f37a66d 425 interworking_select(dev[0], bssid, "home", freq="2412")
8fba2e5d
JM
426 interworking_connect(dev[0], bssid, "TTLS")
427 check_sp_type(dev[0], "home")
10b3cc67
JM
428 status = dev[0].get_status()
429 if status['pairwise_cipher'] != "CCMP":
430 raise Exception("Unexpected pairwise cipher")
431 if status['hs20'] != "2":
432 raise Exception("Unexpected HS 2.0 support indication")
8fba2e5d 433
a1281b9f
JM
434 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS",
435 identity="hs20-test", password="password",
436 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
437 scan_freq="2412")
438
dcd68168
JM
439def eap_test(dev, ap, eap_params, method, user):
440 bssid = ap['bssid']
441 params = hs20_ap_params()
442 params['nai_realm'] = [ "0,example.com," + eap_params ]
443 hostapd.add_ap(ap['ifname'], params)
444
dcd68168
JM
445 dev.hs20_enable()
446 dev.add_cred_values({ 'realm': "example.com",
447 'username': user,
448 'password': "password" })
2f37a66d 449 interworking_select(dev, bssid, freq="2412")
dcd68168
JM
450 interworking_connect(dev, bssid, method)
451
932be82c
JM
452def test_ap_hs20_eap_unknown(dev, apdev):
453 """Hotspot 2.0 connection with unknown EAP method"""
454 bssid = apdev[0]['bssid']
455 params = hs20_ap_params()
456 params['nai_realm'] = "0,example.com,99"
457 hostapd.add_ap(apdev[0]['ifname'], params)
458
459 dev[0].hs20_enable()
460 dev[0].add_cred_values(default_cred())
461 interworking_select(dev[0], None, no_match=True, freq="2412")
462
dcd68168
JM
463def test_ap_hs20_eap_peap_mschapv2(dev, apdev):
464 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
465 eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user")
466
932be82c
JM
467def test_ap_hs20_eap_peap_default(dev, apdev):
468 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
469 eap_test(dev[0], apdev[0], "25", "PEAP", "user")
470
dcd68168
JM
471def test_ap_hs20_eap_peap_gtc(dev, apdev):
472 """Hotspot 2.0 connection with PEAP/GTC"""
473 eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user")
474
932be82c
JM
475def test_ap_hs20_eap_peap_unknown(dev, apdev):
476 """Hotspot 2.0 connection with PEAP/unknown"""
477 bssid = apdev[0]['bssid']
478 params = hs20_ap_params()
479 params['nai_realm'] = "0,example.com,25[3:99]"
480 hostapd.add_ap(apdev[0]['ifname'], params)
481
482 dev[0].hs20_enable()
483 dev[0].add_cred_values(default_cred())
484 interworking_select(dev[0], None, no_match=True, freq="2412")
485
dcd68168
JM
486def test_ap_hs20_eap_ttls_chap(dev, apdev):
487 """Hotspot 2.0 connection with TTLS/CHAP"""
488 eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user")
489
490def test_ap_hs20_eap_ttls_mschap(dev, apdev):
491 """Hotspot 2.0 connection with TTLS/MSCHAP"""
492 eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user")
493
494def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev):
495 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
932be82c
JM
496 eap_test(dev[0], apdev[0], "21[3:26][6:7][99:99]", "TTLS", "user")
497
498def test_ap_hs20_eap_ttls_eap_unknown(dev, apdev):
499 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
500 bssid = apdev[0]['bssid']
501 params = hs20_ap_params()
502 params['nai_realm'] = "0,example.com,21[3:99]"
503 hostapd.add_ap(apdev[0]['ifname'], params)
504
505 dev[0].hs20_enable()
506 dev[0].add_cred_values(default_cred())
507 interworking_select(dev[0], None, no_match=True, freq="2412")
508
509def test_ap_hs20_eap_ttls_eap_unsupported(dev, apdev):
510 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
511 bssid = apdev[0]['bssid']
512 params = hs20_ap_params()
513 params['nai_realm'] = "0,example.com,21[3:5]"
514 hostapd.add_ap(apdev[0]['ifname'], params)
515
516 dev[0].hs20_enable()
517 dev[0].add_cred_values(default_cred())
518 interworking_select(dev[0], None, no_match=True, freq="2412")
519
520def test_ap_hs20_eap_ttls_unknown(dev, apdev):
521 """Hotspot 2.0 connection with TTLS/unknown"""
522 bssid = apdev[0]['bssid']
523 params = hs20_ap_params()
524 params['nai_realm'] = "0,example.com,21[2:5]"
525 hostapd.add_ap(apdev[0]['ifname'], params)
526
527 dev[0].hs20_enable()
528 dev[0].add_cred_values(default_cred())
529 interworking_select(dev[0], None, no_match=True, freq="2412")
dcd68168
JM
530
531def test_ap_hs20_eap_fast_mschapv2(dev, apdev):
532 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
533 eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user")
534
535def test_ap_hs20_eap_fast_gtc(dev, apdev):
536 """Hotspot 2.0 connection with FAST/EAP-GTC"""
537 eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user")
538
539def test_ap_hs20_eap_tls(dev, apdev):
540 """Hotspot 2.0 connection with EAP-TLS"""
541 bssid = apdev[0]['bssid']
542 params = hs20_ap_params()
543 params['nai_realm'] = [ "0,example.com,13[5:6]" ]
544 hostapd.add_ap(apdev[0]['ifname'], params)
545
dcd68168
JM
546 dev[0].hs20_enable()
547 dev[0].add_cred_values({ 'realm': "example.com",
548 'username': "certificate-user",
549 'ca_cert': "auth_serv/ca.pem",
550 'client_cert': "auth_serv/user.pem",
551 'private_key': "auth_serv/user.key"})
2f37a66d 552 interworking_select(dev[0], bssid, freq="2412")
dcd68168
JM
553 interworking_connect(dev[0], bssid, "TLS")
554
932be82c
JM
555def test_ap_hs20_eap_cert_unknown(dev, apdev):
556 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
557 bssid = apdev[0]['bssid']
558 params = hs20_ap_params()
559 params['nai_realm'] = [ "0,example.com,99[5:6]" ]
560 hostapd.add_ap(apdev[0]['ifname'], params)
561
562 dev[0].hs20_enable()
563 dev[0].add_cred_values({ 'realm': "example.com",
564 'username': "certificate-user",
565 'ca_cert': "auth_serv/ca.pem",
566 'client_cert': "auth_serv/user.pem",
567 'private_key': "auth_serv/user.key"})
568 interworking_select(dev[0], None, no_match=True, freq="2412")
569
570def test_ap_hs20_eap_cert_unsupported(dev, apdev):
571 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
572 bssid = apdev[0]['bssid']
573 params = hs20_ap_params()
574 params['nai_realm'] = [ "0,example.com,21[5:6]" ]
575 hostapd.add_ap(apdev[0]['ifname'], params)
576
577 dev[0].hs20_enable()
578 dev[0].add_cred_values({ 'realm': "example.com",
579 'username': "certificate-user",
580 'ca_cert': "auth_serv/ca.pem",
581 'client_cert': "auth_serv/user.pem",
582 'private_key': "auth_serv/user.key"})
583 interworking_select(dev[0], None, no_match=True, freq="2412")
584
585def test_ap_hs20_eap_invalid_cred(dev, apdev):
586 """Hotspot 2.0 connection with invalid cred configuration"""
587 bssid = apdev[0]['bssid']
588 params = hs20_ap_params()
589 hostapd.add_ap(apdev[0]['ifname'], params)
590
591 dev[0].hs20_enable()
592 dev[0].add_cred_values({ 'realm': "example.com",
593 'username': "certificate-user",
594 'client_cert': "auth_serv/user.pem" })
595 interworking_select(dev[0], None, no_match=True, freq="2412")
596
0aca5d13
JM
597def test_ap_hs20_nai_realms(dev, apdev):
598 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
599 bssid = apdev[0]['bssid']
600 params = hs20_ap_params()
601 params['hessid'] = bssid
602 params['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
603 hostapd.add_ap(apdev[0]['ifname'], params)
604
0aca5d13
JM
605 dev[0].hs20_enable()
606 id = dev[0].add_cred_values({ 'realm': "example.com",
607 'username': "pap user",
608 'password': "password",
609 'domain': "example.com" })
2f37a66d 610 interworking_select(dev[0], bssid, "home", freq="2412")
0aca5d13
JM
611 interworking_connect(dev[0], bssid, "TTLS")
612 check_sp_type(dev[0], "home")
613
e209eb98
JM
614def test_ap_hs20_roaming_consortium(dev, apdev):
615 """Hotspot 2.0 connection based on roaming consortium match"""
616 bssid = apdev[0]['bssid']
617 params = hs20_ap_params()
618 params['hessid'] = bssid
619 hostapd.add_ap(apdev[0]['ifname'], params)
620
e209eb98 621 dev[0].hs20_enable()
80584122
JM
622 for consortium in [ "112233", "1020304050", "010203040506", "fedcba" ]:
623 id = dev[0].add_cred_values({ 'username': "user",
624 'password': "password",
625 'domain': "example.com",
626 'roaming_consortium': consortium,
627 'eap': "PEAP" })
628 interworking_select(dev[0], bssid, "home", freq="2412")
629 interworking_connect(dev[0], bssid, "PEAP")
630 check_sp_type(dev[0], "home")
631 dev[0].request("INTERWORKING_SELECT auto freq=2412")
632 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
633 if ev is None:
634 raise Exception("Timeout on already-connected event")
635 dev[0].remove_cred(id)
e209eb98 636
8fba2e5d
JM
637def test_ap_hs20_username_roaming(dev, apdev):
638 """Hotspot 2.0 connection in username/password credential (roaming)"""
8fba2e5d
JM
639 bssid = apdev[0]['bssid']
640 params = hs20_ap_params()
641 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
642 "0,roaming.example.com,21[2:4][5:7]",
643 "0,another.example.com" ]
644 params['domain_name'] = "another.example.com"
645 params['hessid'] = bssid
646 hostapd.add_ap(apdev[0]['ifname'], params)
647
648 dev[0].hs20_enable()
2232edf8
JM
649 id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
650 'username': "hs20-test",
651 'password': "password",
652 'domain': "example.com" })
2f37a66d 653 interworking_select(dev[0], bssid, "roaming", freq="2412")
8fba2e5d
JM
654 interworking_connect(dev[0], bssid, "TTLS")
655 check_sp_type(dev[0], "roaming")
656
657def test_ap_hs20_username_unknown(dev, apdev):
658 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
8fba2e5d
JM
659 bssid = apdev[0]['bssid']
660 params = hs20_ap_params()
661 params['hessid'] = bssid
662 hostapd.add_ap(apdev[0]['ifname'], params)
663
664 dev[0].hs20_enable()
2232edf8
JM
665 id = dev[0].add_cred_values({ 'realm': "example.com",
666 'username': "hs20-test",
667 'password': "password" })
2f37a66d 668 interworking_select(dev[0], bssid, "unknown", freq="2412")
8fba2e5d
JM
669 interworking_connect(dev[0], bssid, "TTLS")
670 check_sp_type(dev[0], "unknown")
671
672def test_ap_hs20_username_unknown2(dev, apdev):
673 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
8fba2e5d
JM
674 bssid = apdev[0]['bssid']
675 params = hs20_ap_params()
676 params['hessid'] = bssid
677 del params['domain_name']
678 hostapd.add_ap(apdev[0]['ifname'], params)
679
680 dev[0].hs20_enable()
2232edf8
JM
681 id = dev[0].add_cred_values({ 'realm': "example.com",
682 'username': "hs20-test",
683 'password': "password",
684 'domain': "example.com" })
2f37a66d 685 interworking_select(dev[0], bssid, "unknown", freq="2412")
8fba2e5d
JM
686 interworking_connect(dev[0], bssid, "TTLS")
687 check_sp_type(dev[0], "unknown")
d1ba402f 688
483691bd
JM
689def test_ap_hs20_gas_while_associated(dev, apdev):
690 """Hotspot 2.0 connection with GAS query while associated"""
691 bssid = apdev[0]['bssid']
692 params = hs20_ap_params()
693 params['hessid'] = bssid
694 hostapd.add_ap(apdev[0]['ifname'], params)
695
483691bd
JM
696 dev[0].hs20_enable()
697 id = dev[0].add_cred_values({ 'realm': "example.com",
698 'username': "hs20-test",
699 'password': "password",
700 'domain': "example.com" })
2f37a66d 701 interworking_select(dev[0], bssid, "home", freq="2412")
483691bd
JM
702 interworking_connect(dev[0], bssid, "TTLS")
703
704 logger.info("Verifying GAS query while associated")
705 dev[0].request("FETCH_ANQP")
706 for i in range(0, 6):
707 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
708 if ev is None:
709 raise Exception("Operation timed out")
710
ee2caef3
JM
711def test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
712 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
713 bssid = apdev[0]['bssid']
714 params = hs20_ap_params()
715 params['hessid'] = bssid
716 hostapd.add_ap(apdev[0]['ifname'], params)
717
718 bssid2 = apdev[1]['bssid']
719 params = hs20_ap_params()
720 params['hessid'] = bssid2
721 params['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
722 hostapd.add_ap(apdev[1]['ifname'], params)
723
724 dev[0].hs20_enable()
725 dev[0].request("SET pmf 2")
726 id = dev[0].add_cred_values({ 'realm': "example.com",
727 'username': "hs20-test",
728 'password': "password",
729 'domain': "example.com" })
730 interworking_select(dev[0], bssid, "home", freq="2412")
731 interworking_connect(dev[0], bssid, "TTLS")
732
733 logger.info("Verifying GAS query while associated")
734 dev[0].request("FETCH_ANQP")
735 for i in range(0, 2 * 6):
736 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
737 if ev is None:
738 raise Exception("Operation timed out")
739
483691bd
JM
740def test_ap_hs20_gas_frag_while_associated(dev, apdev):
741 """Hotspot 2.0 connection with fragmented GAS query while associated"""
742 bssid = apdev[0]['bssid']
743 params = hs20_ap_params()
744 params['hessid'] = bssid
745 hostapd.add_ap(apdev[0]['ifname'], params)
746 hapd = hostapd.Hostapd(apdev[0]['ifname'])
747 hapd.set("gas_frag_limit", "50")
748
483691bd
JM
749 dev[0].hs20_enable()
750 id = dev[0].add_cred_values({ 'realm': "example.com",
751 'username': "hs20-test",
752 'password': "password",
753 'domain': "example.com" })
2f37a66d 754 interworking_select(dev[0], bssid, "home", freq="2412")
483691bd
JM
755 interworking_connect(dev[0], bssid, "TTLS")
756
757 logger.info("Verifying GAS query while associated")
758 dev[0].request("FETCH_ANQP")
759 for i in range(0, 6):
760 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
761 if ev is None:
762 raise Exception("Operation timed out")
763
6a0b4002
JM
764def test_ap_hs20_multiple_connects(dev, apdev):
765 """Hotspot 2.0 connection through multiple network selections"""
766 bssid = apdev[0]['bssid']
767 params = hs20_ap_params()
768 params['hessid'] = bssid
769 hostapd.add_ap(apdev[0]['ifname'], params)
770
771 dev[0].hs20_enable()
772 values = { 'realm': "example.com",
773 'username': "hs20-test",
774 'password': "password",
775 'domain': "example.com" }
776 id = dev[0].add_cred_values(values)
777
778 for i in range(0, 3):
779 logger.info("Starting Interworking network selection")
2f37a66d 780 dev[0].request("INTERWORKING_SELECT auto freq=2412")
6a0b4002
JM
781 while True:
782 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
783 "INTERWORKING-ALREADY-CONNECTED",
784 "CTRL-EVENT-CONNECTED"], timeout=15)
785 if ev is None:
786 raise Exception("Connection timed out")
787 if "INTERWORKING-NO-MATCH" in ev:
788 raise Exception("Matching AP not found")
789 if "CTRL-EVENT-CONNECTED" in ev:
790 break
791 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
792 break
793 if i == 0:
794 dev[0].request("DISCONNECT")
795 dev[0].dump_monitor()
796
797 networks = dev[0].list_networks()
798 if len(networks) > 1:
799 raise Exception("Duplicated network block detected")
800
b4264f8f
JM
801def test_ap_hs20_disallow_aps(dev, apdev):
802 """Hotspot 2.0 connection and disallow_aps"""
803 bssid = apdev[0]['bssid']
804 params = hs20_ap_params()
805 params['hessid'] = bssid
806 hostapd.add_ap(apdev[0]['ifname'], params)
807
808 dev[0].hs20_enable()
809 values = { 'realm': "example.com",
810 'username': "hs20-test",
811 'password': "password",
812 'domain': "example.com" }
813 id = dev[0].add_cred_values(values)
814
815 logger.info("Verify disallow_aps bssid")
816 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
817 dev[0].request("INTERWORKING_SELECT auto")
818 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
819 if ev is None:
820 raise Exception("Network selection timed out")
821 dev[0].dump_monitor()
822
823 logger.info("Verify disallow_aps ssid")
824 dev[0].request("SET disallow_aps ssid 746573742d68733230")
2f37a66d 825 dev[0].request("INTERWORKING_SELECT auto freq=2412")
b4264f8f
JM
826 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
827 if ev is None:
828 raise Exception("Network selection timed out")
829 dev[0].dump_monitor()
830
831 logger.info("Verify disallow_aps clear")
832 dev[0].request("SET disallow_aps ")
2f37a66d 833 interworking_select(dev[0], bssid, "home", freq="2412")
b4264f8f
JM
834
835 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
836 ret = dev[0].request("INTERWORKING_CONNECT " + bssid)
837 if "FAIL" not in ret:
838 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
839
d1ba402f
JM
840def policy_test(dev, ap, values, only_one=True):
841 dev.dump_monitor()
19839f8e
JM
842 if ap:
843 logger.info("Verify network selection to AP " + ap['ifname'])
844 bssid = ap['bssid']
845 else:
846 logger.info("Verify network selection")
847 bssid = None
d1ba402f
JM
848 dev.hs20_enable()
849 id = dev.add_cred_values(values)
2f37a66d 850 dev.request("INTERWORKING_SELECT auto freq=2412")
19839f8e 851 events = []
d1ba402f
JM
852 while True:
853 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1965cc3a 854 "INTERWORKING-BLACKLISTED",
953a574d 855 "INTERWORKING-SELECTED"], timeout=15)
d1ba402f 856 if ev is None:
953a574d 857 raise Exception("Network selection timed out")
19839f8e 858 events.append(ev)
d1ba402f
JM
859 if "INTERWORKING-NO-MATCH" in ev:
860 raise Exception("Matching AP not found")
19839f8e 861 if bssid and only_one and "INTERWORKING-AP" in ev and bssid not in ev:
d1ba402f 862 raise Exception("Unexpected AP claimed acceptable")
953a574d 863 if "INTERWORKING-SELECTED" in ev:
19839f8e 864 if bssid and bssid not in ev:
953a574d 865 raise Exception("Selected incorrect BSS")
d1ba402f
JM
866 break
867
953a574d
JM
868 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
869 if ev is None:
870 raise Exception("Connection timed out")
19839f8e 871 if bssid and bssid not in ev:
953a574d
JM
872 raise Exception("Connected to incorrect BSS")
873
d1ba402f 874 conn_bssid = dev.get_status_field("bssid")
19839f8e 875 if bssid and conn_bssid != bssid:
d1ba402f
JM
876 raise Exception("bssid information points to incorrect BSS")
877
878 dev.remove_cred(id)
879 dev.dump_monitor()
19839f8e 880 return events
d1ba402f 881
9714fbcd
JM
882def default_cred(domain=None):
883 cred = { 'realm': "example.com",
d355372c
JM
884 'username': "hs20-test",
885 'password': "password" }
9714fbcd
JM
886 if domain:
887 cred['domain'] = domain
888 return cred
d355372c 889
cfa57df6
JM
890def test_ap_hs20_prefer_home(dev, apdev):
891 """Hotspot 2.0 required roaming consortium"""
892 params = hs20_ap_params()
893 params['domain_name'] = "example.org"
894 hostapd.add_ap(apdev[0]['ifname'], params)
895
896 params = hs20_ap_params()
897 params['ssid'] = "test-hs20-other"
898 params['domain_name'] = "example.com"
899 hostapd.add_ap(apdev[1]['ifname'], params)
900
901 values = default_cred()
902 values['domain'] = "example.com"
903 policy_test(dev[0], apdev[1], values, only_one=False)
904 values['domain'] = "example.org"
905 policy_test(dev[0], apdev[0], values, only_one=False)
906
d1ba402f
JM
907def test_ap_hs20_req_roaming_consortium(dev, apdev):
908 """Hotspot 2.0 required roaming consortium"""
909 params = hs20_ap_params()
910 hostapd.add_ap(apdev[0]['ifname'], params)
911
912 params = hs20_ap_params()
913 params['ssid'] = "test-hs20-other"
914 params['roaming_consortium'] = [ "223344" ]
915 hostapd.add_ap(apdev[1]['ifname'], params)
916
d355372c
JM
917 values = default_cred()
918 values['required_roaming_consortium'] = "223344"
d1ba402f
JM
919 policy_test(dev[0], apdev[1], values)
920 values['required_roaming_consortium'] = "112233"
921 policy_test(dev[0], apdev[0], values)
d355372c 922
af70a093
JM
923 id = dev[0].add_cred()
924 dev[0].set_cred(id, "required_roaming_consortium", "112233")
925 dev[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
926
927 for val in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
928 if "FAIL" not in dev[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val)):
929 raise Exception("Invalid roaming consortium value accepted: " + val)
930
d355372c
JM
931def test_ap_hs20_excluded_ssid(dev, apdev):
932 """Hotspot 2.0 exclusion based on SSID"""
933 params = hs20_ap_params()
e2afdef2
JM
934 params['roaming_consortium'] = [ "223344" ]
935 params['anqp_3gpp_cell_net'] = "555,444"
d355372c
JM
936 hostapd.add_ap(apdev[0]['ifname'], params)
937
938 params = hs20_ap_params()
939 params['ssid'] = "test-hs20-other"
940 params['roaming_consortium'] = [ "223344" ]
e2afdef2 941 params['anqp_3gpp_cell_net'] = "555,444"
d355372c
JM
942 hostapd.add_ap(apdev[1]['ifname'], params)
943
944 values = default_cred()
945 values['excluded_ssid'] = "test-hs20"
1965cc3a
JM
946 events = policy_test(dev[0], apdev[1], values)
947 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
948 if len(ev) != 1:
949 raise Exception("Excluded network not reported")
d355372c 950 values['excluded_ssid'] = "test-hs20-other"
1965cc3a
JM
951 events = policy_test(dev[0], apdev[0], values)
952 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[1]['bssid'] in e]
953 if len(ev) != 1:
954 raise Exception("Excluded network not reported")
d4058934 955
e2afdef2
JM
956 values = default_cred()
957 values['roaming_consortium'] = "223344"
958 values['eap'] = "TTLS"
959 values['phase2'] = "auth=MSCHAPV2"
960 values['excluded_ssid'] = "test-hs20"
961 events = policy_test(dev[0], apdev[1], values)
962 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
963 if len(ev) != 1:
964 raise Exception("Excluded network not reported")
965
966 values = { 'imsi': "555444-333222111", 'eap': "SIM",
967 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
968 'excluded_ssid': "test-hs20" }
969 events = policy_test(dev[0], apdev[1], values)
970 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
971 if len(ev) != 1:
972 raise Exception("Excluded network not reported")
973
d4058934
JM
974def test_ap_hs20_roam_to_higher_prio(dev, apdev):
975 """Hotspot 2.0 and roaming from current to higher priority network"""
976 bssid = apdev[0]['bssid']
977 params = hs20_ap_params(ssid="test-hs20-visited")
978 params['domain_name'] = "visited.example.org"
979 hostapd.add_ap(apdev[0]['ifname'], params)
980
981 dev[0].hs20_enable()
982 id = dev[0].add_cred_values({ 'realm': "example.com",
983 'username': "hs20-test",
984 'password': "password",
985 'domain': "example.com" })
986 logger.info("Connect to the only network option")
987 interworking_select(dev[0], bssid, "roaming", freq="2412")
988 dev[0].dump_monitor()
989 interworking_connect(dev[0], bssid, "TTLS")
990
991 logger.info("Start another AP (home operator) and reconnect")
992 bssid2 = apdev[1]['bssid']
993 params = hs20_ap_params(ssid="test-hs20-home")
994 params['domain_name'] = "example.com"
995 hostapd.add_ap(apdev[1]['ifname'], params)
996
997 dev[0].request("INTERWORKING_SELECT auto freq=2412")
998 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
999 "INTERWORKING-ALREADY-CONNECTED",
1000 "CTRL-EVENT-CONNECTED"], timeout=15)
1001 if ev is None:
1002 raise Exception("Connection timed out")
1003 if "INTERWORKING-NO-MATCH" in ev:
1004 raise Exception("Matching AP not found")
1005 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1006 raise Exception("Unexpected AP selected")
1007 if bssid2 not in ev:
1008 raise Exception("Unexpected BSSID after reconnection")
12c587a5
JM
1009
1010def test_ap_hs20_domain_suffix_match(dev, apdev):
1011 """Hotspot 2.0 and domain_suffix_match"""
1012 bssid = apdev[0]['bssid']
1013 params = hs20_ap_params()
1014 hostapd.add_ap(apdev[0]['ifname'], params)
1015
1016 dev[0].hs20_enable()
1017 id = dev[0].add_cred_values({ 'realm': "example.com",
1018 'username': "hs20-test",
1019 'password': "password",
1020 'domain': "example.com",
1021 'domain_suffix_match': "w1.fi" })
1022 interworking_select(dev[0], bssid, "home", freq="2412")
1023 dev[0].dump_monitor()
1024 interworking_connect(dev[0], bssid, "TTLS")
1025 dev[0].request("REMOVE_NETWORK all")
1026 dev[0].dump_monitor()
1027
1028 dev[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1029 interworking_select(dev[0], bssid, "home", freq="2412")
1030 dev[0].dump_monitor()
1031 dev[0].request("INTERWORKING_CONNECT " + bssid)
1032 ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1033 if ev is None:
1034 raise Exception("TLS certificate error not reported")
1035 if "Domain suffix mismatch" not in ev:
1036 raise Exception("Domain suffix mismatch not reported")
078683ac 1037
2253ea44
JM
1038def test_ap_hs20_roaming_partner_preference(dev, apdev):
1039 """Hotspot 2.0 and roaming partner preference"""
1040 params = hs20_ap_params()
1041 params['domain_name'] = "roaming.example.org"
1042 hostapd.add_ap(apdev[0]['ifname'], params)
1043
1044 params = hs20_ap_params()
1045 params['ssid'] = "test-hs20-other"
1046 params['domain_name'] = "roaming.example.net"
1047 hostapd.add_ap(apdev[1]['ifname'], params)
1048
1049 logger.info("Verify default vs. specified preference")
1050 values = default_cred()
1051 values['roaming_partner'] = "roaming.example.net,1,127,*"
1052 policy_test(dev[0], apdev[1], values, only_one=False)
1053 values['roaming_partner'] = "roaming.example.net,1,129,*"
1054 policy_test(dev[0], apdev[0], values, only_one=False)
1055
1056 logger.info("Verify partial FQDN match")
1057 values['roaming_partner'] = "example.net,0,0,*"
1058 policy_test(dev[0], apdev[1], values, only_one=False)
1059 values['roaming_partner'] = "example.net,0,255,*"
1060 policy_test(dev[0], apdev[0], values, only_one=False)
1061
19839f8e
JM
1062def test_ap_hs20_max_bss_load(dev, apdev):
1063 """Hotspot 2.0 and maximum BSS load"""
1064 params = hs20_ap_params()
1065 params['bss_load_test'] = "12:200:20000"
1066 hostapd.add_ap(apdev[0]['ifname'], params)
1067
1068 params = hs20_ap_params()
1069 params['ssid'] = "test-hs20-other"
1070 params['bss_load_test'] = "5:20:10000"
1071 hostapd.add_ap(apdev[1]['ifname'], params)
1072
1073 logger.info("Verify maximum BSS load constraint")
1074 values = default_cred()
1075 values['domain'] = "example.com"
1076 values['max_bss_load'] = "100"
1077 events = policy_test(dev[0], apdev[1], values, only_one=False)
1078
1079 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1080 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1081 raise Exception("Maximum BSS Load case not noticed")
1082 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1083 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1084 raise Exception("Maximum BSS Load case reported incorrectly")
1085
1086 logger.info("Verify maximum BSS load does not prevent connection")
1087 values['max_bss_load'] = "1"
1088 events = policy_test(dev[0], None, values)
1089
1090 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1091 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1092 raise Exception("Maximum BSS Load case not noticed")
1093 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1094 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1095 raise Exception("Maximum BSS Load case not noticed")
1096
1097def test_ap_hs20_max_bss_load2(dev, apdev):
1098 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1099 params = hs20_ap_params()
1100 params['bss_load_test'] = "12:200:20000"
1101 hostapd.add_ap(apdev[0]['ifname'], params)
1102
1103 params = hs20_ap_params()
1104 params['ssid'] = "test-hs20-other"
1105 hostapd.add_ap(apdev[1]['ifname'], params)
1106
1107 logger.info("Verify maximum BSS load constraint with AP advertisement")
1108 values = default_cred()
1109 values['domain'] = "example.com"
1110 values['max_bss_load'] = "100"
1111 events = policy_test(dev[0], apdev[1], values, only_one=False)
1112
1113 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1114 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1115 raise Exception("Maximum BSS Load case not noticed")
1116 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1117 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1118 raise Exception("Maximum BSS Load case reported incorrectly")
1119
078683ac
JM
1120def test_ap_hs20_multi_cred_sp_prio(dev, apdev):
1121 """Hotspot 2.0 multi-cred sp_priority"""
1122 if not hlr_auc_gw_available():
1123 return "skip"
1124 bssid = apdev[0]['bssid']
1125 params = hs20_ap_params()
1126 params['hessid'] = bssid
1127 del params['domain_name']
1128 params['anqp_3gpp_cell_net'] = "232,01"
1129 hostapd.add_ap(apdev[0]['ifname'], params)
1130
1131 dev[0].hs20_enable()
1132 dev[0].request("SET external_sim 1")
1133 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1134 'provisioning_sp': "example.com",
1135 'sp_priority' :"1" })
1136 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1137 'username': "hs20-test",
1138 'password': "password",
1139 'domain': "example.com",
1140 'provisioning_sp': "example.com",
1141 'sp_priority': "2" })
1142 dev[0].dump_monitor()
0b651713 1143 dev[0].request("INTERWORKING_SELECT auto freq=2412")
078683ac
JM
1144 interworking_ext_sim_auth(dev[0], "SIM")
1145 check_sp_type(dev[0], "unknown")
1146 dev[0].request("REMOVE_NETWORK all")
1147
1148 dev[0].set_cred(id1, "sp_priority", "2")
1149 dev[0].set_cred(id2, "sp_priority", "1")
1150 dev[0].dump_monitor()
0b651713 1151 dev[0].request("INTERWORKING_SELECT auto freq=2412")
078683ac
JM
1152 interworking_auth(dev[0], "TTLS")
1153 check_sp_type(dev[0], "unknown")
1154
1155def test_ap_hs20_multi_cred_sp_prio2(dev, apdev):
1156 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1157 if not hlr_auc_gw_available():
1158 return "skip"
1159 bssid = apdev[0]['bssid']
1160 params = hs20_ap_params()
1161 params['hessid'] = bssid
1162 del params['nai_realm']
1163 del params['domain_name']
1164 params['anqp_3gpp_cell_net'] = "232,01"
1165 hostapd.add_ap(apdev[0]['ifname'], params)
1166
1167 bssid2 = apdev[1]['bssid']
1168 params = hs20_ap_params()
1169 params['ssid'] = "test-hs20-other"
1170 params['hessid'] = bssid2
1171 del params['domain_name']
1172 del params['anqp_3gpp_cell_net']
1173 hostapd.add_ap(apdev[1]['ifname'], params)
1174
1175 dev[0].hs20_enable()
1176 dev[0].request("SET external_sim 1")
1177 id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1178 'provisioning_sp': "example.com",
1179 'sp_priority': "1" })
1180 id2 = dev[0].add_cred_values({ 'realm': "example.com",
1181 'username': "hs20-test",
1182 'password': "password",
1183 'domain': "example.com",
1184 'provisioning_sp': "example.com",
1185 'sp_priority': "2" })
1186 dev[0].dump_monitor()
0b651713 1187 dev[0].request("INTERWORKING_SELECT auto freq=2412")
078683ac
JM
1188 interworking_ext_sim_auth(dev[0], "SIM")
1189 check_sp_type(dev[0], "unknown")
1190 conn_bssid = dev[0].get_status_field("bssid")
1191 if conn_bssid != bssid:
1192 raise Exception("Connected to incorrect BSS")
1193 dev[0].request("REMOVE_NETWORK all")
1194
1195 dev[0].set_cred(id1, "sp_priority", "2")
1196 dev[0].set_cred(id2, "sp_priority", "1")
1197 dev[0].dump_monitor()
0b651713 1198 dev[0].request("INTERWORKING_SELECT auto freq=2412")
078683ac
JM
1199 interworking_auth(dev[0], "TTLS")
1200 check_sp_type(dev[0], "unknown")
1201 conn_bssid = dev[0].get_status_field("bssid")
1202 if conn_bssid != bssid2:
1203 raise Exception("Connected to incorrect BSS")
5e32f825 1204
a3dd0478
JM
1205def check_conn_capab_selection(dev, type, missing):
1206 dev.request("INTERWORKING_SELECT freq=2412")
1207 ev = dev.wait_event(["INTERWORKING-AP"])
1208 if ev is None:
1209 raise Exception("Network selection timed out");
1210 if "type=" + type not in ev:
1211 raise Exception("Unexpected network type")
1212 if missing and "conn_capab_missing=1" not in ev:
1213 raise Exception("conn_capab_missing not reported")
1214 if not missing and "conn_capab_missing=1" in ev:
1215 raise Exception("conn_capab_missing reported unexpectedly")
1216
1217def conn_capab_cred(domain=None, req_conn_capab=None):
1218 cred = default_cred(domain=domain)
1219 if req_conn_capab:
1220 cred['req_conn_capab'] = req_conn_capab
1221 return cred
1222
18153179
JM
1223def test_ap_hs20_req_conn_capab(dev, apdev):
1224 """Hotspot 2.0 network selection with req_conn_capab"""
1225 bssid = apdev[0]['bssid']
1226 params = hs20_ap_params()
1227 hostapd.add_ap(apdev[0]['ifname'], params)
1228
1229 dev[0].hs20_enable()
1230 logger.info("Not used in home network")
a3dd0478
JM
1231 values = conn_capab_cred(domain="example.com", req_conn_capab="6:1234")
1232 id = dev[0].add_cred_values(values)
1233 check_conn_capab_selection(dev[0], "home", False)
18153179
JM
1234
1235 logger.info("Used in roaming network")
1236 dev[0].remove_cred(id)
a3dd0478
JM
1237 values = conn_capab_cred(domain="example.org", req_conn_capab="6:1234")
1238 id = dev[0].add_cred_values(values)
1239 check_conn_capab_selection(dev[0], "roaming", True)
18153179
JM
1240
1241 logger.info("Verify that req_conn_capab does not prevent connection if no other network is available")
a3dd0478
JM
1242 check_auto_select(dev[0], bssid)
1243
1244 logger.info("Additional req_conn_capab checks")
1245
1246 dev[0].remove_cred(id)
1247 values = conn_capab_cred(domain="example.org", req_conn_capab="1:0")
1248 id = dev[0].add_cred_values(values)
1249 check_conn_capab_selection(dev[0], "roaming", True)
1250
1251 dev[0].remove_cred(id)
1252 values = conn_capab_cred(domain="example.org", req_conn_capab="17:5060")
1253 id = dev[0].add_cred_values(values)
1254 check_conn_capab_selection(dev[0], "roaming", True)
1255
1256 bssid2 = apdev[1]['bssid']
1257 params = hs20_ap_params(ssid="test-hs20b")
1258 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1259 hostapd.add_ap(apdev[1]['ifname'], params)
1260
1261 dev[0].remove_cred(id)
1262 values = conn_capab_cred(domain="example.org", req_conn_capab="50")
1263 id = dev[0].add_cred_values(values)
1264 dev[0].set_cred(id, "req_conn_capab", "6:22")
1265 dev[0].request("INTERWORKING_SELECT freq=2412")
1266 for i in range(0, 2):
1267 ev = dev[0].wait_event(["INTERWORKING-AP"])
1268 if ev is None:
1269 raise Exception("Network selection timed out");
1270 if bssid in ev and "conn_capab_missing=1" not in ev:
1271 raise Exception("Missing protocol connection capability not reported")
1272 if bssid2 in ev and "conn_capab_missing=1" in ev:
1273 raise Exception("Protocol connection capability not reported correctly")
1274
1275def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev, apdev):
1276 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1277 bssid = apdev[0]['bssid']
1278 params = hs20_ap_params()
1279 params['domain_name'] = "roaming.example.org"
1280 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1281 hostapd.add_ap(apdev[0]['ifname'], params)
1282
1283 bssid2 = apdev[1]['bssid']
1284 params = hs20_ap_params(ssid="test-hs20-b")
1285 params['domain_name'] = "roaming.example.net"
1286 hostapd.add_ap(apdev[1]['ifname'], params)
1287
1288 values = default_cred()
1289 values['roaming_partner'] = "roaming.example.net,1,127,*"
1290 id = dev[0].add_cred_values(values)
1291 check_auto_select(dev[0], bssid2)
1292
1293 dev[0].set_cred(id, "req_conn_capab", "50")
1294 check_auto_select(dev[0], bssid)
1295
1296 dev[0].remove_cred(id)
1297 id = dev[0].add_cred_values(values)
1298 dev[0].set_cred(id, "req_conn_capab", "51")
1299 check_auto_select(dev[0], bssid2)
18153179 1300
9714fbcd
JM
1301def check_bandwidth_selection(dev, type, below):
1302 dev.request("INTERWORKING_SELECT freq=2412")
1303 ev = dev.wait_event(["INTERWORKING-AP"])
1304 if ev is None:
1305 raise Exception("Network selection timed out");
1306 if "type=" + type not in ev:
1307 raise Exception("Unexpected network type")
1308 if below and "below_min_backhaul=1" not in ev:
1309 raise Exception("below_min_backhaul not reported")
1310 if not below and "below_min_backhaul=1" in ev:
1311 raise Exception("below_min_backhaul reported unexpectedly")
1312
1313def bw_cred(domain=None, dl_home=None, ul_home=None, dl_roaming=None, ul_roaming=None):
1314 cred = default_cred(domain=domain)
1315 if dl_home:
1316 cred['min_dl_bandwidth_home'] = str(dl_home)
1317 if ul_home:
1318 cred['min_ul_bandwidth_home'] = str(ul_home)
1319 if dl_roaming:
1320 cred['min_dl_bandwidth_roaming'] = str(dl_roaming)
1321 if ul_roaming:
1322 cred['min_ul_bandwidth_roaming'] = str(ul_roaming)
1323 return cred
1324
1325def test_ap_hs20_min_bandwidth_home(dev, apdev):
1326 """Hotspot 2.0 network selection with min bandwidth (home)"""
1327 bssid = apdev[0]['bssid']
1328 params = hs20_ap_params()
1329 hostapd.add_ap(apdev[0]['ifname'], params)
1330
1331 dev[0].hs20_enable()
1332 values = bw_cred(domain="example.com", dl_home=5490, ul_home=58)
1333 id = dev[0].add_cred_values(values)
1334 check_bandwidth_selection(dev[0], "home", False)
1335 dev[0].remove_cred(id)
1336
1337 values = bw_cred(domain="example.com", dl_home=5491, ul_home=58)
1338 id = dev[0].add_cred_values(values)
1339 check_bandwidth_selection(dev[0], "home", True)
1340 dev[0].remove_cred(id)
1341
1342 values = bw_cred(domain="example.com", dl_home=5490, ul_home=59)
1343 id = dev[0].add_cred_values(values)
1344 check_bandwidth_selection(dev[0], "home", True)
1345 dev[0].remove_cred(id)
1346
1347 values = bw_cred(domain="example.com", dl_home=5491, ul_home=59)
1348 id = dev[0].add_cred_values(values)
1349 check_bandwidth_selection(dev[0], "home", True)
1350 check_auto_select(dev[0], bssid)
1351
1352 bssid2 = apdev[1]['bssid']
1353 params = hs20_ap_params(ssid="test-hs20-b")
1354 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1355 hostapd.add_ap(apdev[1]['ifname'], params)
1356
1357 check_auto_select(dev[0], bssid2)
1358
1359def test_ap_hs20_min_bandwidth_roaming(dev, apdev):
1360 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1361 bssid = apdev[0]['bssid']
1362 params = hs20_ap_params()
1363 hostapd.add_ap(apdev[0]['ifname'], params)
1364
1365 dev[0].hs20_enable()
1366 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=58)
1367 id = dev[0].add_cred_values(values)
1368 check_bandwidth_selection(dev[0], "roaming", False)
1369 dev[0].remove_cred(id)
1370
1371 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=58)
1372 id = dev[0].add_cred_values(values)
1373 check_bandwidth_selection(dev[0], "roaming", True)
1374 dev[0].remove_cred(id)
1375
1376 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=59)
1377 id = dev[0].add_cred_values(values)
1378 check_bandwidth_selection(dev[0], "roaming", True)
1379 dev[0].remove_cred(id)
1380
1381 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=59)
1382 id = dev[0].add_cred_values(values)
1383 check_bandwidth_selection(dev[0], "roaming", True)
1384 check_auto_select(dev[0], bssid)
1385
1386 bssid2 = apdev[1]['bssid']
1387 params = hs20_ap_params(ssid="test-hs20-b")
1388 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1389 hostapd.add_ap(apdev[1]['ifname'], params)
1390
1391 check_auto_select(dev[0], bssid2)
1392
1393def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev, apdev):
1394 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1395 bssid = apdev[0]['bssid']
1396 params = hs20_ap_params()
1397 params['domain_name'] = "roaming.example.org"
1398 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1399 hostapd.add_ap(apdev[0]['ifname'], params)
1400
1401 bssid2 = apdev[1]['bssid']
1402 params = hs20_ap_params(ssid="test-hs20-b")
1403 params['domain_name'] = "roaming.example.net"
1404 hostapd.add_ap(apdev[1]['ifname'], params)
1405
1406 values = default_cred()
1407 values['roaming_partner'] = "roaming.example.net,1,127,*"
1408 id = dev[0].add_cred_values(values)
1409 check_auto_select(dev[0], bssid2)
1410
1411 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1412 check_auto_select(dev[0], bssid)
1413
1414 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1415 check_auto_select(dev[0], bssid2)
1416
1417def test_ap_hs20_min_bandwidth_no_wan_metrics(dev, apdev):
1418 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1419 bssid = apdev[0]['bssid']
1420 params = hs20_ap_params()
1421 del params['hs20_wan_metrics']
1422 hostapd.add_ap(apdev[0]['ifname'], params)
1423
1424 dev[0].hs20_enable()
1425 values = bw_cred(domain="example.com", dl_home=10000, ul_home=10000,
1426 dl_roaming=10000, ul_roaming=10000)
1427 dev[0].add_cred_values(values)
1428 check_bandwidth_selection(dev[0], "home", False)
1429
5e32f825
JM
1430def test_ap_hs20_deauth_req_ess(dev, apdev):
1431 """Hotspot 2.0 connection and deauthentication request for ESS"""
1432 dev[0].request("SET pmf 2")
1433 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1434 dev[0].dump_monitor()
1435 addr = dev[0].p2p_interface_addr()
1436 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1437 hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/")
1438 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1439 if ev is None:
1440 raise Exception("Timeout on deauth imminent notice")
1441 if "1 120 http://example.com/" not in ev:
1442 raise Exception("Unexpected deauth imminent notice: " + ev)
1443 hapd.request("DEAUTHENTICATE " + addr)
1444 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1445 if ev is None:
1446 raise Exception("Timeout on disconnection")
c61e5a82
JM
1447 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1448 raise Exception("Network not marked temporarily disabled")
5e32f825
JM
1449 ev = dev[0].wait_event(["SME: Trying to authenticate",
1450 "Trying to associate",
1451 "CTRL-EVENT-CONNECTED"], timeout=5)
1452 if ev is not None:
1453 raise Exception("Unexpected connection attempt")
1454
1455def test_ap_hs20_deauth_req_bss(dev, apdev):
1456 """Hotspot 2.0 connection and deauthentication request for BSS"""
1457 dev[0].request("SET pmf 2")
1458 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1459 dev[0].dump_monitor()
1460 addr = dev[0].p2p_interface_addr()
1461 hapd = hostapd.Hostapd(apdev[0]['ifname'])
1462 hapd.request("HS20_DEAUTH_REQ " + addr + " 0 120 http://example.com/")
1463 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1464 if ev is None:
1465 raise Exception("Timeout on deauth imminent notice")
1466 if "0 120 http://example.com/" not in ev:
1467 raise Exception("Unexpected deauth imminent notice: " + ev)
1468 hapd.request("DEAUTHENTICATE " + addr + " reason=4")
1469 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1470 if ev is None:
1471 raise Exception("Timeout on disconnection")
1472 if "reason=4" not in ev:
1473 raise Exception("Unexpected disconnection reason")
c61e5a82
JM
1474 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1475 raise Exception("Network not marked temporarily disabled")
5e32f825
JM
1476 ev = dev[0].wait_event(["SME: Trying to authenticate",
1477 "Trying to associate",
1478 "CTRL-EVENT-CONNECTED"], timeout=5)
1479 if ev is not None:
1480 raise Exception("Unexpected connection attempt")
9e709315 1481
48ef12e7
JM
1482def test_ap_hs20_deauth_req_from_radius(dev, apdev):
1483 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1484 bssid = apdev[0]['bssid']
1485 params = hs20_ap_params()
1486 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1487 params['hs20_deauth_req_timeout'] = "2"
1488 hostapd.add_ap(apdev[0]['ifname'], params)
1489
1490 dev[0].request("SET pmf 2")
1491 dev[0].hs20_enable()
1492 dev[0].add_cred_values({ 'realm': "example.com",
1493 'username': "hs20-deauth-test",
1494 'password': "password" })
1495 interworking_select(dev[0], bssid, freq="2412")
1496 interworking_connect(dev[0], bssid, "TTLS")
1497 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout=5)
1498 if ev is None:
1499 raise Exception("Timeout on deauth imminent notice")
1500 if " 1 100" not in ev:
1501 raise Exception("Unexpected deauth imminent contents")
1502 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=3)
1503 if ev is None:
1504 raise Exception("Timeout on disconnection")
1505
5cf88011
JM
1506def test_ap_hs20_remediation_required(dev, apdev):
1507 """Hotspot 2.0 connection and remediation required from RADIUS"""
1508 bssid = apdev[0]['bssid']
1509 params = hs20_ap_params()
1510 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1511 hostapd.add_ap(apdev[0]['ifname'], params)
1512
1513 dev[0].request("SET pmf 1")
1514 dev[0].hs20_enable()
1515 dev[0].add_cred_values({ 'realm': "example.com",
1516 'username': "hs20-subrem-test",
1517 'password': "password" })
1518 interworking_select(dev[0], bssid, freq="2412")
1519 interworking_connect(dev[0], bssid, "TTLS")
1520 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1521 if ev is None:
1522 raise Exception("Timeout on subscription remediation notice")
1523 if " 1 https://example.com/" not in ev:
1524 raise Exception("Unexpected subscription remediation event contents")
1525
32b450fc
JM
1526def test_ap_hs20_remediation_required_ctrl(dev, apdev):
1527 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1528 bssid = apdev[0]['bssid']
1529 addr = dev[0].p2p_dev_addr()
1530 params = hs20_ap_params()
1531 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1532 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1533
1534 dev[0].request("SET pmf 1")
1535 dev[0].hs20_enable()
1536 dev[0].add_cred_values(default_cred())
1537 interworking_select(dev[0], bssid, freq="2412")
1538 interworking_connect(dev[0], bssid, "TTLS")
1539
1540 hapd.request("HS20_WNM_NOTIF " + addr + " https://example.com/")
1541 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1542 if ev is None:
1543 raise Exception("Timeout on subscription remediation notice")
1544 if " 1 https://example.com/" not in ev:
1545 raise Exception("Unexpected subscription remediation event contents")
1546
1547 hapd.request("HS20_WNM_NOTIF " + addr)
1548 ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1549 if ev is None:
1550 raise Exception("Timeout on subscription remediation notice")
1551 if not ev.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1552 raise Exception("Unexpected subscription remediation event contents: " + ev)
1553
1554 if "FAIL" not in hapd.request("HS20_WNM_NOTIF "):
1555 raise Exception("Unexpected HS20_WNM_NOTIF success")
1556 if "FAIL" not in hapd.request("HS20_WNM_NOTIF foo"):
1557 raise Exception("Unexpected HS20_WNM_NOTIF success")
1558 if "FAIL" not in hapd.request("HS20_WNM_NOTIF " + addr + " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1559 raise Exception("Unexpected HS20_WNM_NOTIF success")
1560
8fc1f204
JM
1561def test_ap_hs20_session_info(dev, apdev):
1562 """Hotspot 2.0 connection and session information from RADIUS"""
1563 bssid = apdev[0]['bssid']
1564 params = hs20_ap_params()
1565 params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1566 hostapd.add_ap(apdev[0]['ifname'], params)
1567
1568 dev[0].request("SET pmf 1")
1569 dev[0].hs20_enable()
1570 dev[0].add_cred_values({ 'realm': "example.com",
1571 'username': "hs20-session-info-test",
1572 'password': "password" })
1573 interworking_select(dev[0], bssid, freq="2412")
1574 interworking_connect(dev[0], bssid, "TTLS")
1575 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout=10)
1576 if ev is None:
1577 raise Exception("Timeout on ESS disassociation imminent notice")
1578 if " 1 59904 https://example.com/" not in ev:
1579 raise Exception("Unexpected ESS disassociation imminent event contents")
1580 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1581 if ev is None:
1582 raise Exception("Scan not started")
1583 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
1584 if ev is None:
1585 raise Exception("Scan not completed")
1586
9e709315
JM
1587def test_ap_hs20_osen(dev, apdev):
1588 """Hotspot 2.0 OSEN connection"""
1589 params = { 'ssid': "osen",
1590 'osen': "1",
1591 'auth_server_addr': "127.0.0.1",
1592 'auth_server_port': "1812",
1593 'auth_server_shared_secret': "radius" }
1594 hostapd.add_ap(apdev[0]['ifname'], params)
1595
1596 dev[0].connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1597 group="GTK_NOT_USED",
1598 eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1599 ca_cert="auth_serv/ca.pem",
1600 scan_freq="2412")
a96066a5 1601
9d1e1172
JM
1602 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1603 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1604 wpas.connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1605 group="GTK_NOT_USED",
1606 eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1607 ca_cert="auth_serv/ca.pem",
1608 scan_freq="2412")
1609 wpas.request("DISCONNECT")
1610
a96066a5
JM
1611def test_ap_hs20_network_preference(dev, apdev):
1612 """Hotspot 2.0 network selection with preferred home network"""
1613 bssid = apdev[0]['bssid']
1614 params = hs20_ap_params()
1615 hostapd.add_ap(apdev[0]['ifname'], params)
1616
1617 dev[0].hs20_enable()
1618 values = { 'realm': "example.com",
1619 'username': "hs20-test",
1620 'password': "password",
1621 'domain': "example.com" }
1622 dev[0].add_cred_values(values)
1623
1624 id = dev[0].add_network()
1625 dev[0].set_network_quoted(id, "ssid", "home")
1626 dev[0].set_network_quoted(id, "psk", "12345678")
1627 dev[0].set_network(id, "priority", "1")
1628 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1629
1630 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1631 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1632 if ev is None:
1633 raise Exception("Connection timed out")
1634 if bssid not in ev:
1635 raise Exception("Unexpected network selected")
1636
1637 bssid2 = apdev[1]['bssid']
1638 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1639 hostapd.add_ap(apdev[1]['ifname'], params)
1640
1641 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1642 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1643 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1644 if ev is None:
1645 raise Exception("Connection timed out")
1646 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1647 raise Exception("No roam to higher priority network")
1648 if bssid2 not in ev:
1649 raise Exception("Unexpected network selected")
1650
1651def test_ap_hs20_network_preference2(dev, apdev):
1652 """Hotspot 2.0 network selection with preferred credential"""
1653 bssid2 = apdev[1]['bssid']
1654 params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1655 hostapd.add_ap(apdev[1]['ifname'], params)
1656
1657 dev[0].hs20_enable()
1658 values = { 'realm': "example.com",
1659 'username': "hs20-test",
1660 'password': "password",
1661 'domain': "example.com",
1662 'priority': "1" }
1663 dev[0].add_cred_values(values)
1664
1665 id = dev[0].add_network()
1666 dev[0].set_network_quoted(id, "ssid", "home")
1667 dev[0].set_network_quoted(id, "psk", "12345678")
1668 dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1669
1670 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1671 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1672 if ev is None:
1673 raise Exception("Connection timed out")
1674 if bssid2 not in ev:
1675 raise Exception("Unexpected network selected")
1676
1677 bssid = apdev[0]['bssid']
1678 params = hs20_ap_params()
1679 hostapd.add_ap(apdev[0]['ifname'], params)
1680
1681 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1682 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1683 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1684 if ev is None:
1685 raise Exception("Connection timed out")
1686 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1687 raise Exception("No roam to higher priority network")
1688 if bssid not in ev:
1689 raise Exception("Unexpected network selected")
eaff3458
JM
1690
1691def test_ap_hs20_network_preference3(dev, apdev):
1692 """Hotspot 2.0 network selection with two credential (one preferred)"""
1693 bssid = apdev[0]['bssid']
1694 params = hs20_ap_params()
1695 hostapd.add_ap(apdev[0]['ifname'], params)
1696
1697 bssid2 = apdev[1]['bssid']
1698 params = hs20_ap_params(ssid="test-hs20b")
1699 params['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
1700 hostapd.add_ap(apdev[1]['ifname'], params)
1701
1702 dev[0].hs20_enable()
1703 values = { 'realm': "example.com",
1704 'username': "hs20-test",
1705 'password': "password",
1706 'priority': "1" }
1707 dev[0].add_cred_values(values)
1708 values = { 'realm': "example.org",
1709 'username': "hs20-test",
1710 'password': "password" }
1711 id = dev[0].add_cred_values(values)
1712
1713 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1714 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1715 if ev is None:
1716 raise Exception("Connection timed out")
1717 if bssid not in ev:
1718 raise Exception("Unexpected network selected")
1719
1720 dev[0].set_cred(id, "priority", "2")
1721 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1722 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1723 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1724 if ev is None:
1725 raise Exception("Connection timed out")
1726 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1727 raise Exception("No roam to higher priority network")
1728 if bssid2 not in ev:
1729 raise Exception("Unexpected network selected")
1221639d
JM
1730
1731def test_ap_hs20_network_preference4(dev, apdev):
1732 """Hotspot 2.0 network selection with username vs. SIM credential"""
1733 bssid = apdev[0]['bssid']
1734 params = hs20_ap_params()
1735 hostapd.add_ap(apdev[0]['ifname'], params)
1736
1737 bssid2 = apdev[1]['bssid']
1738 params = hs20_ap_params(ssid="test-hs20b")
1739 params['hessid'] = bssid2
1740 params['anqp_3gpp_cell_net'] = "555,444"
1741 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1742 hostapd.add_ap(apdev[1]['ifname'], params)
1743
1744 dev[0].hs20_enable()
1745 values = { 'realm': "example.com",
1746 'username': "hs20-test",
1747 'password': "password",
1748 'priority': "1" }
1749 dev[0].add_cred_values(values)
1750 values = { 'imsi': "555444-333222111",
1751 'eap': "SIM",
1752 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1753 id = dev[0].add_cred_values(values)
1754
1755 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1756 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1757 if ev is None:
1758 raise Exception("Connection timed out")
1759 if bssid not in ev:
1760 raise Exception("Unexpected network selected")
1761
1762 dev[0].set_cred(id, "priority", "2")
1763 dev[0].request("INTERWORKING_SELECT auto freq=2412")
1764 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1765 "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1766 if ev is None:
1767 raise Exception("Connection timed out")
1768 if "INTERWORKING-ALREADY-CONNECTED" in ev:
1769 raise Exception("No roam to higher priority network")
1770 if bssid2 not in ev:
1771 raise Exception("Unexpected network selected")
97de642a
JM
1772
1773def test_ap_hs20_fetch_osu(dev, apdev):
1774 """Hotspot 2.0 OSU provider and icon fetch"""
1775 bssid = apdev[0]['bssid']
1776 params = hs20_ap_params()
1777 params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1778 params['osu_ssid'] = '"HS 2.0 OSU open"'
1779 params['osu_method_list'] = "1"
1780 params['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
1781 params['osu_icon'] = "w1fi_logo"
1782 params['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
1783 params['osu_server_uri'] = "https://example.com/osu/"
1784 hostapd.add_ap(apdev[0]['ifname'], params)
1785
1786 bssid2 = apdev[1]['bssid']
1787 params = hs20_ap_params(ssid="test-hs20b")
1788 params['hessid'] = bssid2
1789 params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1790 params['osu_ssid'] = '"HS 2.0 OSU OSEN"'
1791 params['osu_method_list'] = "0"
1792 params['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
1793 params['osu_icon'] = "w1fi_logo"
1794 params['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
1795 params['osu_server_uri'] = "https://example.org/osu/"
1796 hostapd.add_ap(apdev[1]['ifname'], params)
1797
1798 with open("w1fi_logo.png", "r") as f:
1799 orig_logo = f.read()
1800 dev[0].hs20_enable()
1801 dir = "/tmp/osu-fetch"
1802 if os.path.isdir(dir):
1803 files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
1804 for f in files:
1805 os.remove(dir + "/" + f)
1806 else:
1807 try:
1808 os.makedirs(dir)
1809 except:
1810 pass
1811 try:
1812 dev[0].request("SET osu_dir " + dir)
1813 dev[0].request("FETCH_OSU")
1814 icons = 0
1815 while True:
1816 ev = dev[0].wait_event(["OSU provider fetch completed",
1817 "RX-HS20-ANQP-ICON"], timeout=15)
1818 if ev is None:
1819 raise Exception("Timeout on OSU fetch")
1820 if "OSU provider fetch completed" in ev:
1821 break
1822 if "RX-HS20-ANQP-ICON" in ev:
1823 with open(ev.split(' ')[1], "r") as f:
1824 logo = f.read()
1825 if logo == orig_logo:
1826 icons += 1
1827
1828 with open(dir + "/osu-providers.txt", "r") as f:
1829 prov = f.read()
1830 if "OSU-PROVIDER " + bssid not in prov:
1831 raise Exception("Missing OSU_PROVIDER")
1832 if "OSU-PROVIDER " + bssid2 not in prov:
1833 raise Exception("Missing OSU_PROVIDER")
1834 finally:
1835 files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
1836 for f in files:
1837 os.remove(dir + "/" + f)
1838 os.rmdir(dir)
1839
1840 if icons != 2:
1841 raise Exception("Unexpected number of icons fetched")