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