]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_ap_hs20.py
GAS client: Use Protected Dual of Public Action frames with PMF
[thirdparty/hostap.git] / tests / hwsim / test_ap_hs20.py
CommitLineData
93a06242
JM
1#!/usr/bin/python
2#
3# Hotspot 2.0 tests
2f37a66d 4# Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
93a06242
JM
5#
6# This software may be distributed under the terms of the BSD license.
7# See README for more details.
8
9import time
10import subprocess
11import logging
c9aa4308 12logger = logging.getLogger()
efd43d85
JM
13import os.path
14import subprocess
93a06242
JM
15
16import hostapd
715bf904 17from wlantest import Wlantest
93a06242
JM
18
19def hs20_ap_params():
20 params = hostapd.wpa2_params(ssid="test-hs20")
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
2f37a66d 48def interworking_select(dev, bssid, type=None, no_match=False, freq=None):
bbe86767 49 dev.dump_monitor()
2f37a66d
JM
50 freq_extra = " freq=" + freq if freq else ""
51 dev.request("INTERWORKING_SELECT" + freq_extra)
bbe86767
JM
52 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
53 timeout=15)
93a06242
JM
54 if ev is None:
55 raise Exception("Network selection timed out");
bbe86767
JM
56 if no_match:
57 if "INTERWORKING-NO-MATCH" not in ev:
58 raise Exception("Unexpected network match")
59 return
93a06242
JM
60 if "INTERWORKING-NO-MATCH" in ev:
61 raise Exception("Matching network not found")
2cdd91d8 62 if bssid and bssid not in ev:
93a06242 63 raise Exception("Unexpected BSSID in match")
bbe86767
JM
64 if type and "type=" + type not in ev:
65 raise Exception("Network type not recognized correctly")
93a06242 66
bbe86767
JM
67def check_sp_type(dev, sp_type):
68 type = dev.get_status_field("sp_type")
69 if type is None:
70 raise Exception("sp_type not available")
71 if type != sp_type:
72 raise Exception("sp_type did not indicate home network")
efd43d85 73
bbe86767 74def hlr_auc_gw_available():
efd43d85
JM
75 if not os.path.exists("/tmp/hlr_auc_gw.sock"):
76 logger.info("No hlr_auc_gw available");
bbe86767 77 return False
efd43d85
JM
78 if not os.path.exists("../../hostapd/hlr_auc_gw"):
79 logger.info("No hlr_auc_gw available");
bbe86767
JM
80 return False
81 return True
efd43d85 82
bbe86767
JM
83def interworking_ext_sim_connect(dev, bssid, method):
84 dev.request("INTERWORKING_CONNECT " + bssid)
efd43d85 85
bbe86767 86 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
efd43d85
JM
87 if ev is None:
88 raise Exception("Network connected timed out")
bbe86767 89 if "(" + method + ")" not in ev:
efd43d85
JM
90 raise Exception("Unexpected EAP method selection")
91
bbe86767 92 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
efd43d85
JM
93 if ev is None:
94 raise Exception("Wait for external SIM processing request timed out")
95 p = ev.split(':', 2)
96 if p[1] != "GSM-AUTH":
97 raise Exception("Unexpected CTRL-REQ-SIM type")
98 id = p[0].split('-')[3]
99 rand = p[2].split(' ')[0]
100
101 res = subprocess.check_output(["../../hostapd/hlr_auc_gw",
102 "-m",
103 "auth_serv/hlr_auc_gw.milenage_db",
104 "GSM-AUTH-REQ 232010000000000 " + rand])
105 if "GSM-AUTH-RESP" not in res:
106 raise Exception("Unexpected hlr_auc_gw response")
107 resp = res.split(' ')[2].rstrip()
108
bbe86767
JM
109 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
110 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
efd43d85
JM
111 if ev is None:
112 raise Exception("Connection timed out")
f4defd91 113
8fba2e5d
JM
114def interworking_connect(dev, bssid, method):
115 dev.request("INTERWORKING_CONNECT " + bssid)
116
117 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
118 if ev is None:
119 raise Exception("Network connected timed out")
120 if "(" + method + ")" not in ev:
121 raise Exception("Unexpected EAP method selection")
122
123 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
124 if ev is None:
125 raise Exception("Connection timed out")
126
715bf904
JM
127def check_probe_resp(wt, bssid_unexpected, bssid_expected):
128 if bssid_unexpected:
129 count = wt.get_bss_counter("probe_response", bssid_unexpected)
130 if count > 0:
131 raise Exception("Unexpected Probe Response frame from AP")
132
133 if bssid_expected:
134 count = wt.get_bss_counter("probe_response", bssid_expected)
135 if count == 0:
136 raise Exception("No Probe Response frame from AP")
137
2cdd91d8
JM
138def test_ap_anqp_sharing(dev, apdev):
139 """ANQP sharing within ESS and explicit unshare"""
140 bssid = apdev[0]['bssid']
141 params = hs20_ap_params()
142 params['hessid'] = bssid
143 hostapd.add_ap(apdev[0]['ifname'], params)
144
145 bssid2 = apdev[1]['bssid']
146 params = hs20_ap_params()
147 params['hessid'] = bssid
148 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
149 hostapd.add_ap(apdev[1]['ifname'], params)
150
2cdd91d8
JM
151 dev[0].hs20_enable()
152 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
153 'password': "secret",
154 'domain': "example.com" })
155 logger.info("Normal network selection with shared ANQP results")
2f37a66d 156 interworking_select(dev[0], None, "home", freq="2412")
2cdd91d8
JM
157 dev[0].dump_monitor()
158
159 res1 = dev[0].get_bss(bssid)
160 res2 = dev[0].get_bss(bssid2)
161 if res1['anqp_nai_realm'] != res2['anqp_nai_realm']:
162 raise Exception("ANQP results were not shared between BSSes")
163
164 logger.info("Explicit ANQP request to unshare ANQP results")
165 dev[0].request("ANQP_GET " + bssid + " 263")
166 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
167 if ev is None:
168 raise Exception("ANQP operation timed out")
169
170 dev[0].request("ANQP_GET " + bssid2 + " 263")
171 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
172 if ev is None:
173 raise Exception("ANQP operation timed out")
174
175 res1 = dev[0].get_bss(bssid)
176 res2 = dev[0].get_bss(bssid2)
177 if res1['anqp_nai_realm'] == res2['anqp_nai_realm']:
178 raise Exception("ANQP results were not unshared")
179
715bf904
JM
180def test_ap_interworking_scan_filtering(dev, apdev):
181 """Interworking scan filtering with HESSID and access network type"""
182 bssid = apdev[0]['bssid']
183 params = hs20_ap_params()
184 ssid = "test-hs20-ap1"
185 params['ssid'] = ssid
186 params['hessid'] = bssid
187 hostapd.add_ap(apdev[0]['ifname'], params)
188
189 bssid2 = apdev[1]['bssid']
190 params = hs20_ap_params()
191 ssid2 = "test-hs20-ap2"
192 params['ssid'] = ssid2
193 params['hessid'] = bssid2
194 params['access_network_type'] = "1"
8175854e
JM
195 del params['venue_group']
196 del params['venue_type']
715bf904
JM
197 hostapd.add_ap(apdev[1]['ifname'], params)
198
715bf904
JM
199 dev[0].hs20_enable()
200
201 wt = Wlantest()
202 wt.flush()
203
204 logger.info("Check probe request filtering based on HESSID")
205
206 dev[0].request("SET hessid " + bssid2)
0589f401 207 dev[0].scan(freq="2412")
94a2dd0b 208 time.sleep(0.03)
715bf904
JM
209 check_probe_resp(wt, bssid, bssid2)
210
211 logger.info("Check probe request filtering based on access network type")
212
213 wt.clear_bss_counters(bssid)
214 wt.clear_bss_counters(bssid2)
215 dev[0].request("SET hessid 00:00:00:00:00:00")
216 dev[0].request("SET access_network_type 14")
0589f401 217 dev[0].scan(freq="2412")
94a2dd0b 218 time.sleep(0.03)
715bf904
JM
219 check_probe_resp(wt, bssid2, bssid)
220
221 wt.clear_bss_counters(bssid)
222 wt.clear_bss_counters(bssid2)
223 dev[0].request("SET hessid 00:00:00:00:00:00")
224 dev[0].request("SET access_network_type 1")
0589f401 225 dev[0].scan(freq="2412")
94a2dd0b 226 time.sleep(0.03)
715bf904
JM
227 check_probe_resp(wt, bssid, bssid2)
228
229 logger.info("Check probe request filtering based on HESSID and ANT")
230
231 wt.clear_bss_counters(bssid)
232 wt.clear_bss_counters(bssid2)
233 dev[0].request("SET hessid " + bssid)
234 dev[0].request("SET access_network_type 14")
0589f401 235 dev[0].scan(freq="2412")
94a2dd0b 236 time.sleep(0.03)
715bf904
JM
237 check_probe_resp(wt, bssid2, bssid)
238
239 wt.clear_bss_counters(bssid)
240 wt.clear_bss_counters(bssid2)
241 dev[0].request("SET hessid " + bssid2)
242 dev[0].request("SET access_network_type 14")
0589f401 243 dev[0].scan(freq="2412")
94a2dd0b 244 time.sleep(0.03)
715bf904
JM
245 check_probe_resp(wt, bssid, None)
246 check_probe_resp(wt, bssid2, None)
247
248 wt.clear_bss_counters(bssid)
249 wt.clear_bss_counters(bssid2)
250 dev[0].request("SET hessid " + bssid)
251 dev[0].request("SET access_network_type 1")
0589f401 252 dev[0].scan(freq="2412")
94a2dd0b 253 time.sleep(0.03)
715bf904
JM
254 check_probe_resp(wt, bssid, None)
255 check_probe_resp(wt, bssid2, None)
256
bbe86767
JM
257def test_ap_hs20_select(dev, apdev):
258 """Hotspot 2.0 network selection"""
259 bssid = apdev[0]['bssid']
260 params = hs20_ap_params()
261 params['hessid'] = bssid
262 hostapd.add_ap(apdev[0]['ifname'], params)
263
264 dev[0].hs20_enable()
2232edf8
JM
265 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
266 'password': "secret",
267 'domain': "example.com" })
bbe86767
JM
268 interworking_select(dev[0], bssid, "home")
269
270 dev[0].remove_cred(id)
2232edf8
JM
271 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
272 'password': "secret",
273 'domain': "no.match.example.com" })
2f37a66d 274 interworking_select(dev[0], bssid, "roaming", freq="2412")
bbe86767
JM
275
276 dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
2f37a66d 277 interworking_select(dev[0], bssid, no_match=True, freq="2412")
bbe86767 278
459e96cd
JM
279def hs20_simulated_sim(dev, ap, method):
280 bssid = ap['bssid']
281 params = hs20_ap_params()
282 params['hessid'] = bssid
283 params['anqp_3gpp_cell_net'] = "555,444"
284 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
285 hostapd.add_ap(ap['ifname'], params)
286
459e96cd
JM
287 dev.hs20_enable()
288 dev.add_cred_values({ 'imsi': "555444-333222111", 'eap': method,
289 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
2f37a66d 290 interworking_select(dev, "home", freq="2412")
459e96cd
JM
291 interworking_connect(dev, bssid, method)
292 check_sp_type(dev, "home")
293
294def test_ap_hs20_sim(dev, apdev):
295 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
296 if not hlr_auc_gw_available():
297 return "skip"
298 hs20_simulated_sim(dev[0], apdev[0], "SIM")
299
300def test_ap_hs20_aka(dev, apdev):
301 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
302 if not hlr_auc_gw_available():
303 return "skip"
304 hs20_simulated_sim(dev[0], apdev[0], "AKA")
305
306def test_ap_hs20_aka_prime(dev, apdev):
307 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
308 if not hlr_auc_gw_available():
309 return "skip"
310 hs20_simulated_sim(dev[0], apdev[0], "AKA'")
311
bbe86767
JM
312def test_ap_hs20_ext_sim(dev, apdev):
313 """Hotspot 2.0 with external SIM processing"""
314 if not hlr_auc_gw_available():
315 return "skip"
316 bssid = apdev[0]['bssid']
317 params = hs20_ap_params()
318 params['hessid'] = bssid
319 params['anqp_3gpp_cell_net'] = "232,01"
320 params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
321 hostapd.add_ap(apdev[0]['ifname'], params)
322
323 dev[0].hs20_enable()
324 dev[0].request("SET external_sim 1")
2232edf8 325 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
2f37a66d 326 interworking_select(dev[0], "home", freq="2412")
bbe86767
JM
327 interworking_ext_sim_connect(dev[0], bssid, "SIM")
328 check_sp_type(dev[0], "home")
59f8a3c6
JM
329
330def test_ap_hs20_ext_sim_roaming(dev, apdev):
331 """Hotspot 2.0 with external SIM processing in roaming network"""
332 if not hlr_auc_gw_available():
333 return "skip"
334 bssid = apdev[0]['bssid']
335 params = hs20_ap_params()
336 params['hessid'] = bssid
337 params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
338 params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
339 hostapd.add_ap(apdev[0]['ifname'], params)
340
341 dev[0].hs20_enable()
342 dev[0].request("SET external_sim 1")
2232edf8 343 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
2f37a66d 344 interworking_select(dev[0], "roaming", freq="2412")
59f8a3c6
JM
345 interworking_ext_sim_connect(dev[0], bssid, "SIM")
346 check_sp_type(dev[0], "roaming")
8fba2e5d
JM
347
348def test_ap_hs20_username(dev, apdev):
349 """Hotspot 2.0 connection in username/password credential"""
8fba2e5d
JM
350 bssid = apdev[0]['bssid']
351 params = hs20_ap_params()
352 params['hessid'] = bssid
353 hostapd.add_ap(apdev[0]['ifname'], params)
354
355 dev[0].hs20_enable()
2232edf8
JM
356 id = dev[0].add_cred_values({ 'realm': "example.com",
357 'username': "hs20-test",
358 'password': "password",
359 'domain': "example.com" })
2f37a66d 360 interworking_select(dev[0], bssid, "home", freq="2412")
8fba2e5d
JM
361 interworking_connect(dev[0], bssid, "TTLS")
362 check_sp_type(dev[0], "home")
363
dcd68168
JM
364def eap_test(dev, ap, eap_params, method, user):
365 bssid = ap['bssid']
366 params = hs20_ap_params()
367 params['nai_realm'] = [ "0,example.com," + eap_params ]
368 hostapd.add_ap(ap['ifname'], params)
369
dcd68168
JM
370 dev.hs20_enable()
371 dev.add_cred_values({ 'realm': "example.com",
372 'username': user,
373 'password': "password" })
2f37a66d 374 interworking_select(dev, bssid, freq="2412")
dcd68168
JM
375 interworking_connect(dev, bssid, method)
376
377def test_ap_hs20_eap_peap_mschapv2(dev, apdev):
378 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
379 eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user")
380
381def test_ap_hs20_eap_peap_gtc(dev, apdev):
382 """Hotspot 2.0 connection with PEAP/GTC"""
383 eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user")
384
385def test_ap_hs20_eap_ttls_chap(dev, apdev):
386 """Hotspot 2.0 connection with TTLS/CHAP"""
387 eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user")
388
389def test_ap_hs20_eap_ttls_mschap(dev, apdev):
390 """Hotspot 2.0 connection with TTLS/MSCHAP"""
391 eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user")
392
393def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev):
394 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
395 eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
396
397def test_ap_hs20_eap_fast_mschapv2(dev, apdev):
398 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
399 eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user")
400
401def test_ap_hs20_eap_fast_gtc(dev, apdev):
402 """Hotspot 2.0 connection with FAST/EAP-GTC"""
403 eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user")
404
405def test_ap_hs20_eap_tls(dev, apdev):
406 """Hotspot 2.0 connection with EAP-TLS"""
407 bssid = apdev[0]['bssid']
408 params = hs20_ap_params()
409 params['nai_realm'] = [ "0,example.com,13[5:6]" ]
410 hostapd.add_ap(apdev[0]['ifname'], params)
411
dcd68168
JM
412 dev[0].hs20_enable()
413 dev[0].add_cred_values({ 'realm': "example.com",
414 'username': "certificate-user",
415 'ca_cert': "auth_serv/ca.pem",
416 'client_cert': "auth_serv/user.pem",
417 'private_key': "auth_serv/user.key"})
2f37a66d 418 interworking_select(dev[0], bssid, freq="2412")
dcd68168
JM
419 interworking_connect(dev[0], bssid, "TLS")
420
0aca5d13
JM
421def test_ap_hs20_nai_realms(dev, apdev):
422 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
423 bssid = apdev[0]['bssid']
424 params = hs20_ap_params()
425 params['hessid'] = bssid
426 params['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
427 hostapd.add_ap(apdev[0]['ifname'], params)
428
0aca5d13
JM
429 dev[0].hs20_enable()
430 id = dev[0].add_cred_values({ 'realm': "example.com",
431 'username': "pap user",
432 'password': "password",
433 'domain': "example.com" })
2f37a66d 434 interworking_select(dev[0], bssid, "home", freq="2412")
0aca5d13
JM
435 interworking_connect(dev[0], bssid, "TTLS")
436 check_sp_type(dev[0], "home")
437
e209eb98
JM
438def test_ap_hs20_roaming_consortium(dev, apdev):
439 """Hotspot 2.0 connection based on roaming consortium match"""
440 bssid = apdev[0]['bssid']
441 params = hs20_ap_params()
442 params['hessid'] = bssid
443 hostapd.add_ap(apdev[0]['ifname'], params)
444
e209eb98
JM
445 dev[0].hs20_enable()
446 id = dev[0].add_cred_values({ 'realm': "example.com",
447 'username': "user",
448 'password': "password",
449 'domain': "example.com",
450 'roaming_consortium': "fedcba",
451 'eap': "PEAP" })
2f37a66d 452 interworking_select(dev[0], bssid, "home", freq="2412")
e209eb98
JM
453 interworking_connect(dev[0], bssid, "PEAP")
454 check_sp_type(dev[0], "home")
455
8fba2e5d
JM
456def test_ap_hs20_username_roaming(dev, apdev):
457 """Hotspot 2.0 connection in username/password credential (roaming)"""
8fba2e5d
JM
458 bssid = apdev[0]['bssid']
459 params = hs20_ap_params()
460 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
461 "0,roaming.example.com,21[2:4][5:7]",
462 "0,another.example.com" ]
463 params['domain_name'] = "another.example.com"
464 params['hessid'] = bssid
465 hostapd.add_ap(apdev[0]['ifname'], params)
466
467 dev[0].hs20_enable()
2232edf8
JM
468 id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
469 'username': "hs20-test",
470 'password': "password",
471 'domain': "example.com" })
2f37a66d 472 interworking_select(dev[0], bssid, "roaming", freq="2412")
8fba2e5d
JM
473 interworking_connect(dev[0], bssid, "TTLS")
474 check_sp_type(dev[0], "roaming")
475
476def test_ap_hs20_username_unknown(dev, apdev):
477 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
8fba2e5d
JM
478 bssid = apdev[0]['bssid']
479 params = hs20_ap_params()
480 params['hessid'] = bssid
481 hostapd.add_ap(apdev[0]['ifname'], params)
482
483 dev[0].hs20_enable()
2232edf8
JM
484 id = dev[0].add_cred_values({ 'realm': "example.com",
485 'username': "hs20-test",
486 'password': "password" })
2f37a66d 487 interworking_select(dev[0], bssid, "unknown", freq="2412")
8fba2e5d
JM
488 interworking_connect(dev[0], bssid, "TTLS")
489 check_sp_type(dev[0], "unknown")
490
491def test_ap_hs20_username_unknown2(dev, apdev):
492 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
8fba2e5d
JM
493 bssid = apdev[0]['bssid']
494 params = hs20_ap_params()
495 params['hessid'] = bssid
496 del params['domain_name']
497 hostapd.add_ap(apdev[0]['ifname'], params)
498
499 dev[0].hs20_enable()
2232edf8
JM
500 id = dev[0].add_cred_values({ 'realm': "example.com",
501 'username': "hs20-test",
502 'password': "password",
503 'domain': "example.com" })
2f37a66d 504 interworking_select(dev[0], bssid, "unknown", freq="2412")
8fba2e5d
JM
505 interworking_connect(dev[0], bssid, "TTLS")
506 check_sp_type(dev[0], "unknown")
d1ba402f 507
483691bd
JM
508def test_ap_hs20_gas_while_associated(dev, apdev):
509 """Hotspot 2.0 connection with GAS query while associated"""
510 bssid = apdev[0]['bssid']
511 params = hs20_ap_params()
512 params['hessid'] = bssid
513 hostapd.add_ap(apdev[0]['ifname'], params)
514
483691bd
JM
515 dev[0].hs20_enable()
516 id = dev[0].add_cred_values({ 'realm': "example.com",
517 'username': "hs20-test",
518 'password': "password",
519 'domain': "example.com" })
2f37a66d 520 interworking_select(dev[0], bssid, "home", freq="2412")
483691bd
JM
521 interworking_connect(dev[0], bssid, "TTLS")
522
523 logger.info("Verifying GAS query while associated")
524 dev[0].request("FETCH_ANQP")
525 for i in range(0, 6):
526 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
527 if ev is None:
528 raise Exception("Operation timed out")
529
530def test_ap_hs20_gas_frag_while_associated(dev, apdev):
531 """Hotspot 2.0 connection with fragmented GAS query while associated"""
532 bssid = apdev[0]['bssid']
533 params = hs20_ap_params()
534 params['hessid'] = bssid
535 hostapd.add_ap(apdev[0]['ifname'], params)
536 hapd = hostapd.Hostapd(apdev[0]['ifname'])
537 hapd.set("gas_frag_limit", "50")
538
483691bd
JM
539 dev[0].hs20_enable()
540 id = dev[0].add_cred_values({ 'realm': "example.com",
541 'username': "hs20-test",
542 'password': "password",
543 'domain': "example.com" })
2f37a66d 544 interworking_select(dev[0], bssid, "home", freq="2412")
483691bd
JM
545 interworking_connect(dev[0], bssid, "TTLS")
546
547 logger.info("Verifying GAS query while associated")
548 dev[0].request("FETCH_ANQP")
549 for i in range(0, 6):
550 ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
551 if ev is None:
552 raise Exception("Operation timed out")
553
6a0b4002
JM
554def test_ap_hs20_multiple_connects(dev, apdev):
555 """Hotspot 2.0 connection through multiple network selections"""
556 bssid = apdev[0]['bssid']
557 params = hs20_ap_params()
558 params['hessid'] = bssid
559 hostapd.add_ap(apdev[0]['ifname'], params)
560
561 dev[0].hs20_enable()
562 values = { 'realm': "example.com",
563 'username': "hs20-test",
564 'password': "password",
565 'domain': "example.com" }
566 id = dev[0].add_cred_values(values)
567
568 for i in range(0, 3):
569 logger.info("Starting Interworking network selection")
2f37a66d 570 dev[0].request("INTERWORKING_SELECT auto freq=2412")
6a0b4002
JM
571 while True:
572 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
573 "INTERWORKING-ALREADY-CONNECTED",
574 "CTRL-EVENT-CONNECTED"], timeout=15)
575 if ev is None:
576 raise Exception("Connection timed out")
577 if "INTERWORKING-NO-MATCH" in ev:
578 raise Exception("Matching AP not found")
579 if "CTRL-EVENT-CONNECTED" in ev:
580 break
581 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
582 break
583 if i == 0:
584 dev[0].request("DISCONNECT")
585 dev[0].dump_monitor()
586
587 networks = dev[0].list_networks()
588 if len(networks) > 1:
589 raise Exception("Duplicated network block detected")
590
b4264f8f
JM
591def test_ap_hs20_disallow_aps(dev, apdev):
592 """Hotspot 2.0 connection and disallow_aps"""
593 bssid = apdev[0]['bssid']
594 params = hs20_ap_params()
595 params['hessid'] = bssid
596 hostapd.add_ap(apdev[0]['ifname'], params)
597
598 dev[0].hs20_enable()
599 values = { 'realm': "example.com",
600 'username': "hs20-test",
601 'password': "password",
602 'domain': "example.com" }
603 id = dev[0].add_cred_values(values)
604
605 logger.info("Verify disallow_aps bssid")
606 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
607 dev[0].request("INTERWORKING_SELECT auto")
608 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
609 if ev is None:
610 raise Exception("Network selection timed out")
611 dev[0].dump_monitor()
612
613 logger.info("Verify disallow_aps ssid")
614 dev[0].request("SET disallow_aps ssid 746573742d68733230")
2f37a66d 615 dev[0].request("INTERWORKING_SELECT auto freq=2412")
b4264f8f
JM
616 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
617 if ev is None:
618 raise Exception("Network selection timed out")
619 dev[0].dump_monitor()
620
621 logger.info("Verify disallow_aps clear")
622 dev[0].request("SET disallow_aps ")
2f37a66d 623 interworking_select(dev[0], bssid, "home", freq="2412")
b4264f8f
JM
624
625 dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
626 ret = dev[0].request("INTERWORKING_CONNECT " + bssid)
627 if "FAIL" not in ret:
628 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
629
d1ba402f
JM
630def policy_test(dev, ap, values, only_one=True):
631 dev.dump_monitor()
632 logger.info("Verify network selection to AP " + ap['ifname'])
633 bssid = ap['bssid']
634 dev.hs20_enable()
635 id = dev.add_cred_values(values)
2f37a66d 636 dev.request("INTERWORKING_SELECT auto freq=2412")
d1ba402f
JM
637 while True:
638 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
639 "CTRL-EVENT-CONNECTED"], timeout=15)
640 if ev is None:
641 raise Exception("Connection timed out")
642 if "INTERWORKING-NO-MATCH" in ev:
643 raise Exception("Matching AP not found")
644 if only_one and "INTERWORKING-AP" in ev and bssid not in ev:
645 raise Exception("Unexpected AP claimed acceptable")
646 if "CTRL-EVENT-CONNECTED" in ev:
647 if bssid not in ev:
648 raise Exception("Connected to incorrect BSS")
649 break
650
651 conn_bssid = dev.get_status_field("bssid")
652 if conn_bssid != bssid:
653 raise Exception("bssid information points to incorrect BSS")
654
655 dev.remove_cred(id)
656 dev.dump_monitor()
657
d355372c
JM
658def default_cred():
659 return { 'realm': "example.com",
660 'username': "hs20-test",
661 'password': "password" }
662
d1ba402f
JM
663def test_ap_hs20_req_roaming_consortium(dev, apdev):
664 """Hotspot 2.0 required roaming consortium"""
665 params = hs20_ap_params()
666 hostapd.add_ap(apdev[0]['ifname'], params)
667
668 params = hs20_ap_params()
669 params['ssid'] = "test-hs20-other"
670 params['roaming_consortium'] = [ "223344" ]
671 hostapd.add_ap(apdev[1]['ifname'], params)
672
d355372c
JM
673 values = default_cred()
674 values['required_roaming_consortium'] = "223344"
d1ba402f
JM
675 policy_test(dev[0], apdev[1], values)
676 values['required_roaming_consortium'] = "112233"
677 policy_test(dev[0], apdev[0], values)
d355372c
JM
678
679def test_ap_hs20_excluded_ssid(dev, apdev):
680 """Hotspot 2.0 exclusion based on SSID"""
681 params = hs20_ap_params()
682 hostapd.add_ap(apdev[0]['ifname'], params)
683
684 params = hs20_ap_params()
685 params['ssid'] = "test-hs20-other"
686 params['roaming_consortium'] = [ "223344" ]
687 hostapd.add_ap(apdev[1]['ifname'], params)
688
689 values = default_cred()
690 values['excluded_ssid'] = "test-hs20"
691 policy_test(dev[0], apdev[1], values)
692 values['excluded_ssid'] = "test-hs20-other"
693 policy_test(dev[0], apdev[0], values)