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