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