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