1# Hotspot 2.0 tests 2# Copyright (c) 2013-2019, 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 7from remotehost import remote_compatible 8import base64 9import binascii 10import struct 11import time 12import logging 13logger = logging.getLogger() 14import os 15import os.path 16import socket 17import subprocess 18 19import hostapd 20from utils import * 21import hwsim_utils 22from tshark import run_tshark 23from wlantest import Wlantest 24from wpasupplicant import WpaSupplicant 25from wlantest import WlantestCapture 26from test_ap_eap import check_eap_capa, check_domain_match_full 27from test_gas import gas_rx, parse_gas, action_response, anqp_initial_resp, send_gas_resp, ACTION_CATEG_PUBLIC, GAS_INITIAL_RESPONSE 28 29def hs20_ap_params(ssid="test-hs20"): 30 params = hostapd.wpa2_params(ssid=ssid) 31 params['wpa_key_mgmt'] = "WPA-EAP" 32 params['ieee80211w'] = "1" 33 params['ieee8021x'] = "1" 34 params['auth_server_addr'] = "127.0.0.1" 35 params['auth_server_port'] = "1812" 36 params['auth_server_shared_secret'] = "radius" 37 params['interworking'] = "1" 38 params['access_network_type'] = "14" 39 params['internet'] = "1" 40 params['asra'] = "0" 41 params['esr'] = "0" 42 params['uesa'] = "0" 43 params['venue_group'] = "7" 44 params['venue_type'] = "1" 45 params['venue_name'] = ["eng:Example venue", "fin:Esimerkkipaikka"] 46 params['roaming_consortium'] = ["112233", "1020304050", "010203040506", 47 "fedcba"] 48 params['domain_name'] = "example.com,another.example.com" 49 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]", 50 "0,another.example.com"] 51 params['hs20'] = "1" 52 params['hs20_wan_metrics'] = "01:8000:1000:80:240:3000" 53 params['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0"] 54 params['hs20_operating_class'] = "5173" 55 params['anqp_3gpp_cell_net'] = "244,91" 56 return params 57 58def check_auto_select(dev, bssid, hapd=None): 59 dev.scan_for_bss(bssid, freq="2412") 60 dev.request("INTERWORKING_SELECT auto freq=2412") 61 ev = dev.wait_connected(timeout=15) 62 if bssid not in ev: 63 raise Exception("Connected to incorrect network") 64 if hapd: 65 hapd.wait_sta() 66 dev.request("REMOVE_NETWORK all") 67 dev.wait_disconnected() 68 dev.dump_monitor() 69 if hapd: 70 hapd.wait_sta_disconnect() 71 72def interworking_select(dev, bssid, type=None, no_match=False, freq=None): 73 dev.dump_monitor() 74 if bssid and freq and not no_match: 75 dev.scan_for_bss(bssid, freq=freq) 76 freq_extra = " freq=" + str(freq) if freq else "" 77 dev.request("INTERWORKING_SELECT" + freq_extra) 78 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"], 79 timeout=15) 80 if ev is None: 81 raise Exception("Network selection timed out") 82 if no_match: 83 if "INTERWORKING-NO-MATCH" not in ev: 84 raise Exception("Unexpected network match") 85 return 86 if "INTERWORKING-NO-MATCH" in ev: 87 logger.info("Matching network not found - try again") 88 dev.dump_monitor() 89 dev.request("INTERWORKING_SELECT" + freq_extra) 90 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"], 91 timeout=15) 92 if ev is None: 93 raise Exception("Network selection timed out") 94 if "INTERWORKING-NO-MATCH" in ev: 95 raise Exception("Matching network not found") 96 if bssid and bssid not in ev: 97 raise Exception("Unexpected BSSID in match") 98 if type and "type=" + type not in ev: 99 raise Exception("Network type not recognized correctly") 100 101def check_sp_type(dev, sp_type): 102 type = dev.get_status_field("sp_type") 103 if type is None: 104 raise Exception("sp_type not available") 105 if type != sp_type: 106 raise Exception("sp_type did not indicate %s network" % sp_type) 107 108def hlr_auc_gw_available(): 109 if not os.path.exists("/tmp/hlr_auc_gw.sock"): 110 raise HwsimSkip("No hlr_auc_gw socket available") 111 if not os.path.exists("../../hostapd/hlr_auc_gw"): 112 raise HwsimSkip("No hlr_auc_gw available") 113 114def interworking_ext_sim_connect(dev, bssid, method): 115 dev.request("INTERWORKING_CONNECT " + bssid) 116 interworking_ext_sim_auth(dev, method) 117 118def interworking_ext_sim_auth(dev, method): 119 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15) 120 if ev is None: 121 raise Exception("Network connected timed out") 122 if "(" + method + ")" not in ev: 123 raise Exception("Unexpected EAP method selection") 124 125 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15) 126 if ev is None: 127 raise Exception("Wait for external SIM processing request timed out") 128 p = ev.split(':', 2) 129 if p[1] != "GSM-AUTH": 130 raise Exception("Unexpected CTRL-REQ-SIM type") 131 id = p[0].split('-')[3] 132 rand = p[2].split(' ')[0] 133 134 res = subprocess.check_output(["../../hostapd/hlr_auc_gw", 135 "-m", 136 "auth_serv/hlr_auc_gw.milenage_db", 137 "GSM-AUTH-REQ 232010000000000 " + rand]).decode() 138 if "GSM-AUTH-RESP" not in res: 139 raise Exception("Unexpected hlr_auc_gw response") 140 resp = res.split(' ')[2].rstrip() 141 142 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp) 143 dev.wait_connected(timeout=15) 144 145def interworking_connect(dev, bssid, method): 146 dev.request("INTERWORKING_CONNECT " + bssid) 147 interworking_auth(dev, method) 148 149def interworking_auth(dev, method): 150 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15) 151 if ev is None: 152 raise Exception("Network connected timed out") 153 if "(" + method + ")" not in ev: 154 raise Exception("Unexpected EAP method selection") 155 156 dev.wait_connected(timeout=15) 157 158def check_probe_resp(wt, bssid_unexpected, bssid_expected): 159 if bssid_unexpected: 160 count = wt.get_bss_counter("probe_response", bssid_unexpected) 161 if count > 0: 162 raise Exception("Unexpected Probe Response frame from AP") 163 164 if bssid_expected: 165 count = wt.get_bss_counter("probe_response", bssid_expected) 166 if count == 0: 167 raise Exception("No Probe Response frame from AP") 168 169def test_ap_anqp_sharing(dev, apdev): 170 """ANQP sharing within ESS and explicit unshare""" 171 check_eap_capa(dev[0], "MSCHAPV2") 172 dev[0].flush_scan_cache() 173 174 bssid = apdev[0]['bssid'] 175 params = hs20_ap_params() 176 params['hessid'] = bssid 177 hostapd.add_ap(apdev[0], params) 178 179 bssid2 = apdev[1]['bssid'] 180 params = hs20_ap_params() 181 params['hessid'] = bssid 182 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"] 183 hostapd.add_ap(apdev[1], params) 184 185 dev[0].hs20_enable() 186 id = dev[0].add_cred_values({'realm': "example.com", 'username': "test", 187 'password': "secret", 188 'domain': "example.com"}) 189 logger.info("Normal network selection with shared ANQP results") 190 dev[0].scan_for_bss(bssid, freq="2412") 191 dev[0].scan_for_bss(bssid2, freq="2412") 192 interworking_select(dev[0], None, "home", freq="2412") 193 dev[0].dump_monitor() 194 state = dev[0].get_status_field('wpa_state') 195 if state != "DISCONNECTED": 196 raise Exception("Unexpected wpa_state after INTERWORKING_SELECT: " + state) 197 198 logger.debug("BSS entries:\n" + dev[0].request("BSS RANGE=ALL")) 199 res1 = dev[0].get_bss(bssid) 200 res2 = dev[0].get_bss(bssid2) 201 if 'anqp_nai_realm' not in res1: 202 raise Exception("anqp_nai_realm not found for AP1") 203 if 'anqp_nai_realm' not in res2: 204 raise Exception("anqp_nai_realm not found for AP2") 205 if res1['anqp_nai_realm'] != res2['anqp_nai_realm']: 206 raise Exception("ANQP results were not shared between BSSes") 207 208 logger.info("Explicit ANQP request to unshare ANQP results") 209 dev[0].request("ANQP_GET " + bssid + " 263") 210 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 211 if ev is None: 212 raise Exception("ANQP operation timed out") 213 214 dev[0].request("ANQP_GET " + bssid2 + " 263") 215 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 216 if ev is None: 217 raise Exception("ANQP operation timed out") 218 219 res1 = dev[0].get_bss(bssid) 220 res2 = dev[0].get_bss(bssid2) 221 if res1['anqp_nai_realm'] == res2['anqp_nai_realm']: 222 raise Exception("ANQP results were not unshared") 223 224def test_ap_anqp_domain_id(dev, apdev): 225 """ANQP Domain ID""" 226 check_eap_capa(dev[0], "MSCHAPV2") 227 dev[0].flush_scan_cache() 228 229 bssid = apdev[0]['bssid'] 230 params = hs20_ap_params() 231 params['hessid'] = bssid 232 params['anqp_domain_id'] = '1234' 233 hostapd.add_ap(apdev[0], params) 234 235 bssid2 = apdev[1]['bssid'] 236 params = hs20_ap_params() 237 params['hessid'] = bssid 238 params['anqp_domain_id'] = '1234' 239 hostapd.add_ap(apdev[1], params) 240 241 dev[0].hs20_enable() 242 id = dev[0].add_cred_values({'realm': "example.com", 'username': "test", 243 'password': "secret", 244 'domain': "example.com"}) 245 dev[0].scan_for_bss(bssid, freq="2412") 246 dev[0].scan_for_bss(bssid2, freq="2412") 247 interworking_select(dev[0], None, "home", freq="2412") 248 249def test_ap_anqp_no_sharing_diff_ess(dev, apdev): 250 """ANQP no sharing between ESSs""" 251 check_eap_capa(dev[0], "MSCHAPV2") 252 dev[0].flush_scan_cache() 253 254 bssid = apdev[0]['bssid'] 255 params = hs20_ap_params() 256 params['hessid'] = bssid 257 hostapd.add_ap(apdev[0], params) 258 259 bssid2 = apdev[1]['bssid'] 260 params = hs20_ap_params(ssid="test-hs20-another") 261 params['hessid'] = bssid 262 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"] 263 hostapd.add_ap(apdev[1], params) 264 265 dev[0].hs20_enable() 266 id = dev[0].add_cred_values({'realm': "example.com", 'username': "test", 267 'password': "secret", 268 'domain': "example.com"}) 269 logger.info("Normal network selection with shared ANQP results") 270 dev[0].scan_for_bss(bssid, freq="2412") 271 dev[0].scan_for_bss(bssid2, freq="2412") 272 interworking_select(dev[0], None, "home", freq="2412") 273 274def test_ap_anqp_no_sharing_missing_info(dev, apdev): 275 """ANQP no sharing due to missing information""" 276 check_eap_capa(dev[0], "MSCHAPV2") 277 dev[0].flush_scan_cache() 278 279 bssid = apdev[0]['bssid'] 280 params = hs20_ap_params() 281 params['hessid'] = bssid 282 del params['roaming_consortium'] 283 del params['domain_name'] 284 del params['anqp_3gpp_cell_net'] 285 del params['nai_realm'] 286 hostapd.add_ap(apdev[0], params) 287 288 bssid2 = apdev[1]['bssid'] 289 params = hs20_ap_params() 290 params['hessid'] = bssid 291 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"] 292 hostapd.add_ap(apdev[1], params) 293 294 dev[0].hs20_enable() 295 id = dev[0].add_cred_values({'realm': "example.com", 'username': "test", 296 'password': "secret", 297 'domain': "example.com"}) 298 logger.info("Normal network selection with shared ANQP results") 299 dev[0].scan_for_bss(bssid, freq="2412") 300 dev[0].scan_for_bss(bssid2, freq="2412") 301 interworking_select(dev[0], None, "home", freq="2412") 302 303def test_ap_anqp_sharing_oom(dev, apdev): 304 """ANQP sharing within ESS and explicit unshare OOM""" 305 check_eap_capa(dev[0], "MSCHAPV2") 306 dev[0].flush_scan_cache() 307 308 bssid = apdev[0]['bssid'] 309 params = hs20_ap_params() 310 params['hessid'] = bssid 311 hostapd.add_ap(apdev[0], params) 312 313 bssid2 = apdev[1]['bssid'] 314 params = hs20_ap_params() 315 params['hessid'] = bssid 316 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"] 317 hostapd.add_ap(apdev[1], params) 318 319 dev[0].hs20_enable() 320 id = dev[0].add_cred_values({'realm': "example.com", 'username': "test", 321 'password': "secret", 322 'domain': "example.com"}) 323 dev[0].scan_for_bss(bssid, freq="2412") 324 dev[0].scan_for_bss(bssid2, freq="2412") 325 interworking_select(dev[0], None, "home", freq="2412") 326 dev[0].dump_monitor() 327 328 with alloc_fail(dev[0], 1, "wpa_bss_anqp_clone"): 329 dev[0].request("ANQP_GET " + bssid + " 263") 330 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 331 if ev is None: 332 raise Exception("ANQP operation timed out") 333 334def test_ap_nai_home_realm_query(dev, apdev): 335 """NAI Home Realm Query""" 336 check_eap_capa(dev[0], "MSCHAPV2") 337 bssid = apdev[0]['bssid'] 338 params = hs20_ap_params() 339 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]", 340 "0,another.example.org"] 341 hostapd.add_ap(apdev[0], params) 342 343 dev[0].scan(freq="2412") 344 dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " realm=example.com") 345 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 346 if ev is None: 347 raise Exception("ANQP operation timed out") 348 nai1 = dev[0].get_bss(bssid)['anqp_nai_realm'] 349 dev[0].dump_monitor() 350 351 dev[0].request("ANQP_GET " + bssid + " 263") 352 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 353 if ev is None: 354 raise Exception("ANQP operation timed out") 355 nai2 = dev[0].get_bss(bssid)['anqp_nai_realm'] 356 357 if len(nai1) >= len(nai2): 358 raise Exception("Unexpected NAI Realm list response lengths") 359 if binascii.hexlify(b"example.com").decode() not in nai1: 360 raise Exception("Home realm not reported") 361 if binascii.hexlify(b"example.org").decode() in nai1: 362 raise Exception("Non-home realm reported") 363 if binascii.hexlify(b"example.com").decode() not in nai2: 364 raise Exception("Home realm not reported in wildcard query") 365 if binascii.hexlify(b"example.org").decode() not in nai2: 366 raise Exception("Non-home realm not reported in wildcard query ") 367 368 cmds = ["foo", 369 "00:11:22:33:44:55 123", 370 "00:11:22:33:44:55 qq"] 371 for cmd in cmds: 372 if "FAIL" not in dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd): 373 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd) 374 375 dev[0].dump_monitor() 376 if "OK" not in dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid): 377 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed") 378 ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10) 379 if ev is None: 380 raise Exception("ANQP operation timed out") 381 ev = dev[0].wait_event(["RX-ANQP"], timeout=0.1) 382 if ev is not None: 383 raise Exception("Unexpected ANQP response: " + ev) 384 385 dev[0].dump_monitor() 386 if "OK" not in dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " 01000b6578616d706c652e636f6d"): 387 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed") 388 ev = dev[0].wait_event(["RX-ANQP"], timeout=10) 389 if ev is None: 390 raise Exception("No ANQP response") 391 if "NAI Realm list" not in ev: 392 raise Exception("Missing NAI Realm list: " + ev) 393 394 dev[0].add_cred_values({'realm': "example.com", 'username': "test", 395 'password': "secret", 396 'domain': "example.com"}) 397 dev[0].dump_monitor() 398 if "OK" not in dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid): 399 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed") 400 ev = dev[0].wait_event(["RX-ANQP"], timeout=10) 401 if ev is None: 402 raise Exception("No ANQP response") 403 if "NAI Realm list" not in ev: 404 raise Exception("Missing NAI Realm list: " + ev) 405 406@remote_compatible 407def test_ap_interworking_scan_filtering(dev, apdev): 408 """Interworking scan filtering with HESSID and access network type""" 409 try: 410 _test_ap_interworking_scan_filtering(dev, apdev) 411 finally: 412 dev[0].request("SET hessid 00:00:00:00:00:00") 413 dev[0].request("SET access_network_type 15") 414 415def _test_ap_interworking_scan_filtering(dev, apdev): 416 bssid = apdev[0]['bssid'] 417 params = hs20_ap_params() 418 ssid = "test-hs20-ap1" 419 params['ssid'] = ssid 420 params['hessid'] = bssid 421 hapd0 = hostapd.add_ap(apdev[0], params) 422 423 bssid2 = apdev[1]['bssid'] 424 params = hs20_ap_params() 425 ssid2 = "test-hs20-ap2" 426 params['ssid'] = ssid2 427 params['hessid'] = bssid2 428 params['access_network_type'] = "1" 429 del params['venue_group'] 430 del params['venue_type'] 431 hostapd.add_ap(apdev[1], params) 432 433 dev[0].hs20_enable() 434 435 Wlantest.setup(hapd0) 436 wt = Wlantest() 437 wt.flush() 438 439 # Make sure wlantest has seen both BSSs to avoid issues in trying to clear 440 # counters for non-existing BSS. 441 dev[0].scan_for_bss(bssid, freq="2412") 442 dev[0].scan_for_bss(bssid2, freq="2412") 443 wt.clear_bss_counters(bssid) 444 wt.clear_bss_counters(bssid2) 445 446 logger.info("Check probe request filtering based on HESSID") 447 448 dev[0].request("SET hessid " + bssid2) 449 dev[0].scan(freq="2412") 450 time.sleep(0.03) 451 check_probe_resp(wt, bssid, bssid2) 452 453 logger.info("Check probe request filtering based on access network type") 454 455 wt.clear_bss_counters(bssid) 456 wt.clear_bss_counters(bssid2) 457 dev[0].request("SET hessid 00:00:00:00:00:00") 458 dev[0].request("SET access_network_type 14") 459 dev[0].scan(freq="2412") 460 time.sleep(0.03) 461 check_probe_resp(wt, bssid2, bssid) 462 463 wt.clear_bss_counters(bssid) 464 wt.clear_bss_counters(bssid2) 465 dev[0].request("SET hessid 00:00:00:00:00:00") 466 dev[0].request("SET access_network_type 1") 467 dev[0].scan(freq="2412") 468 time.sleep(0.03) 469 check_probe_resp(wt, bssid, bssid2) 470 471 logger.info("Check probe request filtering based on HESSID and ANT") 472 473 wt.clear_bss_counters(bssid) 474 wt.clear_bss_counters(bssid2) 475 dev[0].request("SET hessid " + bssid) 476 dev[0].request("SET access_network_type 14") 477 dev[0].scan(freq="2412") 478 time.sleep(0.03) 479 check_probe_resp(wt, bssid2, bssid) 480 481 wt.clear_bss_counters(bssid) 482 wt.clear_bss_counters(bssid2) 483 dev[0].request("SET hessid " + bssid2) 484 dev[0].request("SET access_network_type 14") 485 dev[0].scan(freq="2412") 486 time.sleep(0.03) 487 check_probe_resp(wt, bssid, None) 488 check_probe_resp(wt, bssid2, None) 489 490 wt.clear_bss_counters(bssid) 491 wt.clear_bss_counters(bssid2) 492 dev[0].request("SET hessid " + bssid) 493 dev[0].request("SET access_network_type 1") 494 dev[0].scan(freq="2412") 495 time.sleep(0.03) 496 check_probe_resp(wt, bssid, None) 497 check_probe_resp(wt, bssid2, None) 498 499def test_ap_hs20_select(dev, apdev): 500 """Hotspot 2.0 network selection""" 501 bssid = apdev[0]['bssid'] 502 params = hs20_ap_params() 503 params['hessid'] = bssid 504 hostapd.add_ap(apdev[0], params) 505 dev[0].flush_scan_cache() 506 507 dev[0].hs20_enable() 508 id = dev[0].add_cred_values({'realm': "example.com", 'username': "test", 509 'password': "secret", 510 'domain': "example.com"}) 511 interworking_select(dev[0], bssid, "home") 512 513 dev[0].remove_cred(id) 514 id = dev[0].add_cred_values({'realm': "example.com", 'username': "test", 515 'password': "secret", 516 'domain': "no.match.example.com"}) 517 interworking_select(dev[0], bssid, "roaming", freq="2412") 518 519 dev[0].set_cred_quoted(id, "realm", "no.match.example.com") 520 interworking_select(dev[0], bssid, no_match=True, freq="2412") 521 522 res = dev[0].request("SCAN_RESULTS") 523 if "[HS20]" not in res: 524 raise Exception("HS20 flag missing from scan results: " + res) 525 526 bssid2 = apdev[1]['bssid'] 527 params = hs20_ap_params() 528 params['nai_realm'] = ["0,example.org,21"] 529 params['hessid'] = bssid2 530 params['domain_name'] = "example.org" 531 hostapd.add_ap(apdev[1], params) 532 dev[0].remove_cred(id) 533 id = dev[0].add_cred_values({'realm': "example.org", 'username': "test", 534 'password': "secret", 535 'domain': "example.org"}) 536 interworking_select(dev[0], bssid2, "home", freq="2412") 537 538def hs20_simulated_sim(dev, ap, method, imsi_privacy=False, 539 imsi_privacy_attr=False): 540 bssid = ap['bssid'] 541 params = hs20_ap_params() 542 params['hessid'] = bssid 543 params['anqp_3gpp_cell_net'] = "555,444" 544 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org" 545 hostapd.add_ap(ap, params) 546 547 dev.hs20_enable() 548 params = {'imsi': "555444-333222111", 'eap': method, 549 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"} 550 if imsi_privacy: 551 check_imsi_privacy_support(dev) 552 params['imsi_privacy_cert'] = "auth_serv/imsi-privacy-cert.pem" 553 if imsi_privacy_attr: 554 params['imsi_privacy_attr'] = "Identifier=1234567" 555 dev.add_cred_values(params) 556 interworking_select(dev, bssid, "home", freq="2412") 557 interworking_connect(dev, bssid, method) 558 check_sp_type(dev, "home") 559 560def test_ap_hs20_sim(dev, apdev): 561 """Hotspot 2.0 with simulated SIM and EAP-SIM""" 562 hlr_auc_gw_available() 563 hs20_simulated_sim(dev[0], apdev[0], "SIM") 564 dev[0].request("INTERWORKING_SELECT auto freq=2412") 565 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15) 566 if ev is None: 567 raise Exception("Timeout on already-connected event") 568 569def test_ap_hs20_sim_imsi_privacy(dev, apdev): 570 """Hotspot 2.0 with simulated SIM and EAP-SIM with IMSI privacy""" 571 hlr_auc_gw_available() 572 hs20_simulated_sim(dev[0], apdev[0], "SIM", imsi_privacy=True) 573 574def test_ap_hs20_sim_invalid(dev, apdev): 575 """Hotspot 2.0 with simulated SIM and EAP-SIM - invalid IMSI""" 576 hlr_auc_gw_available() 577 bssid = apdev[0]['bssid'] 578 params = hs20_ap_params() 579 params['hessid'] = bssid 580 params['anqp_3gpp_cell_net'] = "555,444" 581 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org" 582 hostapd.add_ap(apdev[0], params) 583 584 dev[0].hs20_enable() 585 dev[0].add_cred_values({'imsi': "555444-3332221110", 'eap': "SIM", 586 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"}) 587 # This hits "No valid IMSI available" in build_root_nai() 588 interworking_select(dev[0], bssid, freq="2412") 589 590def test_ap_hs20_sim_oom(dev, apdev): 591 """Hotspot 2.0 with simulated SIM and EAP-SIM - OOM""" 592 hlr_auc_gw_available() 593 bssid = apdev[0]['bssid'] 594 params = hs20_ap_params() 595 params['hessid'] = bssid 596 params['anqp_3gpp_cell_net'] = "555,444" 597 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org" 598 hostapd.add_ap(apdev[0], params) 599 600 dev[0].hs20_enable() 601 dev[0].add_cred_values({'imsi': "555444-333222111", 'eap': "SIM", 602 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"}) 603 dev[0].scan_for_bss(bssid, freq=2412) 604 interworking_select(dev[0], bssid, freq="2412") 605 606 with alloc_fail(dev[0], 1, "wpa_config_add_network;interworking_connect_3gpp"): 607 dev[0].request("INTERWORKING_CONNECT " + bssid) 608 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 609 610 with alloc_fail(dev[0], 1, "=interworking_connect_3gpp"): 611 dev[0].request("INTERWORKING_CONNECT " + bssid) 612 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 613 614def test_ap_hs20_aka(dev, apdev): 615 """Hotspot 2.0 with simulated USIM and EAP-AKA""" 616 hlr_auc_gw_available() 617 hs20_simulated_sim(dev[0], apdev[0], "AKA") 618 619def test_ap_hs20_aka_imsi_privacy(dev, apdev): 620 """Hotspot 2.0 with simulated USIM and EAP-AKA with IMSI privacy""" 621 hlr_auc_gw_available() 622 hs20_simulated_sim(dev[0], apdev[0], "AKA", imsi_privacy=True) 623 624def test_ap_hs20_aka_imsi_privacy_attr(dev, apdev): 625 """Hotspot 2.0 with simulated USIM and EAP-AKA with IMSI privacy/attr""" 626 hlr_auc_gw_available() 627 hs20_simulated_sim(dev[0], apdev[0], "AKA", imsi_privacy=True, 628 imsi_privacy_attr=True) 629 630def test_ap_hs20_aka_prime(dev, apdev): 631 """Hotspot 2.0 with simulated USIM and EAP-AKA'""" 632 hlr_auc_gw_available() 633 hs20_simulated_sim(dev[0], apdev[0], "AKA'") 634 635def test_ap_hs20_aka_prime_imsi_privacy(dev, apdev): 636 """Hotspot 2.0 with simulated USIM and EAP-AKA with IMSI privacy'""" 637 hlr_auc_gw_available() 638 hs20_simulated_sim(dev[0], apdev[0], "AKA'", imsi_privacy=True) 639 640def test_ap_hs20_ext_sim(dev, apdev): 641 """Hotspot 2.0 with external SIM processing""" 642 hlr_auc_gw_available() 643 bssid = apdev[0]['bssid'] 644 params = hs20_ap_params() 645 params['hessid'] = bssid 646 params['anqp_3gpp_cell_net'] = "232,01" 647 params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org" 648 hostapd.add_ap(apdev[0], params) 649 650 dev[0].hs20_enable() 651 try: 652 dev[0].request("SET external_sim 1") 653 dev[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM"}) 654 interworking_select(dev[0], bssid, "home", freq="2412") 655 interworking_ext_sim_connect(dev[0], bssid, "SIM") 656 check_sp_type(dev[0], "home") 657 finally: 658 dev[0].request("SET external_sim 0") 659 660def test_ap_hs20_ext_sim_roaming(dev, apdev): 661 """Hotspot 2.0 with external SIM processing in roaming network""" 662 hlr_auc_gw_available() 663 bssid = apdev[0]['bssid'] 664 params = hs20_ap_params() 665 params['hessid'] = bssid 666 params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56" 667 params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org" 668 hostapd.add_ap(apdev[0], params) 669 670 dev[0].hs20_enable() 671 try: 672 dev[0].request("SET external_sim 1") 673 dev[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM"}) 674 interworking_select(dev[0], bssid, "roaming", freq="2412") 675 interworking_ext_sim_connect(dev[0], bssid, "SIM") 676 check_sp_type(dev[0], "roaming") 677 finally: 678 dev[0].request("SET external_sim 0") 679 680def test_ap_hs20_username(dev, apdev): 681 """Hotspot 2.0 connection in username/password credential""" 682 check_eap_capa(dev[0], "MSCHAPV2") 683 bssid = apdev[0]['bssid'] 684 params = hs20_ap_params() 685 params['hessid'] = bssid 686 params['disable_dgaf'] = '1' 687 hapd = hostapd.add_ap(apdev[0], params) 688 689 dev[0].hs20_enable() 690 id = dev[0].add_cred_values({'realm': "example.com", 691 'username': "hs20-test", 692 'password': "password", 693 'ca_cert': "auth_serv/ca.pem", 694 'domain': "example.com", 695 'update_identifier': "1234"}) 696 interworking_select(dev[0], bssid, "home", freq="2412") 697 interworking_connect(dev[0], bssid, "TTLS") 698 check_sp_type(dev[0], "home") 699 status = dev[0].get_status() 700 if status['pairwise_cipher'] != "CCMP": 701 raise Exception("Unexpected pairwise cipher") 702 if status['hs20'] != "3": 703 raise Exception("Unexpected HS 2.0 support indication") 704 hapd.wait_sta() 705 sta = hapd.get_sta(dev[0].own_addr()) 706 if sta['dot1xAuthSessionUserName'] != "anonymous@example.com": 707 raise Exception("Unexpected anonymous identity: " + sta['dot1xAuthSessionUserName']) 708 709 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS", 710 identity="hs20-test", password="password", 711 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 712 scan_freq="2412") 713 714def test_ap_hs20_username_with_realm(dev, apdev): 715 """Hotspot 2.0 connection in username-with-realm/password credential""" 716 check_eap_capa(dev[0], "MSCHAPV2") 717 bssid = apdev[0]['bssid'] 718 params = hs20_ap_params() 719 params['hessid'] = bssid 720 params['disable_dgaf'] = '1' 721 hapd = hostapd.add_ap(apdev[0], params) 722 723 dev[0].hs20_enable() 724 id = dev[0].add_cred_values({'realm': "example.com", 725 'username': "hs20-test@inner.com", 726 'password': "password2", 727 'ca_cert': "auth_serv/ca.pem", 728 'domain': "example.com"}) 729 interworking_select(dev[0], bssid, "home", freq="2412") 730 interworking_connect(dev[0], bssid, "TTLS") 731 check_sp_type(dev[0], "home") 732 hapd.wait_sta() 733 sta = hapd.get_sta(dev[0].own_addr()) 734 if sta['dot1xAuthSessionUserName'] != "anonymous@example.com": 735 raise Exception("Unexpected anonymous identity: " + sta['dot1xAuthSessionUserName']) 736 737def test_ap_hs20_connect_api(dev, apdev): 738 """Hotspot 2.0 connection with connect API""" 739 check_eap_capa(dev[0], "MSCHAPV2") 740 bssid = apdev[0]['bssid'] 741 params = hs20_ap_params() 742 params['hessid'] = bssid 743 params['disable_dgaf'] = '1' 744 hostapd.add_ap(apdev[0], params) 745 746 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 747 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 748 wpas.hs20_enable() 749 wpas.flush_scan_cache() 750 id = wpas.add_cred_values({'realm': "example.com", 751 'username': "hs20-test", 752 'password': "password", 753 'ca_cert': "auth_serv/ca.pem", 754 'domain': "example.com", 755 'update_identifier': "1234"}) 756 interworking_select(wpas, bssid, "home", freq="2412") 757 interworking_connect(wpas, bssid, "TTLS") 758 check_sp_type(wpas, "home") 759 status = wpas.get_status() 760 if status['pairwise_cipher'] != "CCMP": 761 raise Exception("Unexpected pairwise cipher") 762 if status['hs20'] != "3": 763 raise Exception("Unexpected HS 2.0 support indication") 764 765def test_ap_hs20_auto_interworking(dev, apdev): 766 """Hotspot 2.0 connection with auto_interworking=1""" 767 check_eap_capa(dev[0], "MSCHAPV2") 768 bssid = apdev[0]['bssid'] 769 params = hs20_ap_params() 770 params['hessid'] = bssid 771 params['disable_dgaf'] = '1' 772 hostapd.add_ap(apdev[0], params) 773 774 dev[0].hs20_enable(auto_interworking=True) 775 id = dev[0].add_cred_values({'realm': "example.com", 776 'username': "hs20-test", 777 'password': "password", 778 'ca_cert': "auth_serv/ca.pem", 779 'domain': "example.com", 780 'update_identifier': "1234"}) 781 dev[0].request("REASSOCIATE") 782 dev[0].wait_connected(timeout=15) 783 check_sp_type(dev[0], "home") 784 status = dev[0].get_status() 785 if status['pairwise_cipher'] != "CCMP": 786 raise Exception("Unexpected pairwise cipher") 787 if status['hs20'] != "3": 788 raise Exception("Unexpected HS 2.0 support indication") 789 790def test_ap_hs20_auto_interworking_global_pmf(dev, apdev): 791 """Hotspot 2.0 connection with auto_interworking=1 and pmf=2""" 792 check_eap_capa(dev[0], "MSCHAPV2") 793 bssid = apdev[0]['bssid'] 794 params = hs20_ap_params() 795 params['hessid'] = bssid 796 hostapd.add_ap(apdev[0], params) 797 798 dev[0].hs20_enable(auto_interworking=True) 799 id = dev[0].add_cred_values({'realm': "example.com", 800 'username': "hs20-test", 801 'password': "password", 802 'ca_cert': "auth_serv/ca.pem", 803 'domain': "example.com", 804 'update_identifier': "1234"}) 805 try: 806 dev[0].set("pmf", "2") 807 dev[0].request("REASSOCIATE") 808 dev[0].wait_connected(timeout=15) 809 pmf = dev[0].get_status_field("pmf") 810 if pmf != "1": 811 raise Exception("Unexpected PMF state: " + str(pmf)) 812 finally: 813 dev[0].set("pmf", "0") 814 815def test_ap_hs20_auto_interworking_global_pmf_fail(dev, apdev): 816 """Hotspot 2.0 connection with auto_interworking=1 and pmf=2 failure""" 817 check_eap_capa(dev[0], "MSCHAPV2") 818 bssid = apdev[0]['bssid'] 819 params = hs20_ap_params() 820 params['ieee80211w'] = "0" 821 params['hessid'] = bssid 822 hostapd.add_ap(apdev[0], params) 823 824 dev[0].hs20_enable(auto_interworking=True) 825 id = dev[0].add_cred_values({'realm': "example.com", 826 'username': "hs20-test", 827 'password': "password", 828 'ca_cert': "auth_serv/ca.pem", 829 'domain': "example.com", 830 'update_identifier': "1234"}) 831 try: 832 dev[0].set("pmf", "2") 833 dev[0].request("REASSOCIATE") 834 for i in range(2): 835 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 836 "INTERWORKING-SELECTED"], timeout=15) 837 if ev is None: 838 raise Exception("Connection result not reported") 839 if "CTRL-EVENT-CONNECTED" in ev: 840 raise Exception("Unexpected connection") 841 dev[0].request("DISCONNECT") 842 finally: 843 dev[0].set("pmf", "0") 844 845@remote_compatible 846def test_ap_hs20_auto_interworking_no_match(dev, apdev): 847 """Hotspot 2.0 connection with auto_interworking=1 and no matching network""" 848 hapd = hostapd.add_ap(apdev[0], {"ssid": "mismatch"}) 849 850 dev[0].hs20_enable(auto_interworking=True) 851 id = dev[0].connect("mismatch", psk="12345678", scan_freq="2412", 852 only_add_network=True) 853 dev[0].request("ENABLE_NETWORK " + str(id) + " no-connect") 854 855 id = dev[0].add_cred_values({'realm': "example.com", 856 'username': "hs20-test", 857 'password': "password", 858 'ca_cert': "auth_serv/ca.pem", 859 'domain': "example.com", 860 'update_identifier': "1234"}) 861 dev[0].request("INTERWORKING_SELECT auto freq=2412") 862 time.sleep(0.1) 863 dev[0].dump_monitor() 864 for i in range(5): 865 logger.info("start ping") 866 if "PONG" not in dev[0].ctrl.request("PING", timeout=2): 867 raise Exception("PING failed") 868 logger.info("ping done") 869 fetch = 0 870 scan = 0 871 for j in range(15): 872 ev = dev[0].wait_event(["ANQP fetch completed", 873 "CTRL-EVENT-SCAN-RESULTS"], timeout=0.05) 874 if ev is None: 875 break 876 if "ANQP fetch completed" in ev: 877 fetch += 1 878 else: 879 scan += 1 880 if fetch > 2 * scan + 3: 881 raise Exception("Too many ANQP fetch iterations") 882 dev[0].dump_monitor() 883 dev[0].request("DISCONNECT") 884 885@remote_compatible 886def test_ap_hs20_auto_interworking_no_cred_match(dev, apdev): 887 """Hotspot 2.0 connection with auto_interworking=1 but no cred match""" 888 bssid = apdev[0]['bssid'] 889 params = {"ssid": "test"} 890 hostapd.add_ap(apdev[0], params) 891 892 dev[0].hs20_enable(auto_interworking=True) 893 dev[0].add_cred_values({'realm': "example.com", 894 'username': "hs20-test", 895 'password': "password", 896 'ca_cert': "auth_serv/ca.pem", 897 'domain': "example.com"}) 898 899 id = dev[0].connect("test", psk="12345678", only_add_network=True) 900 dev[0].request("ENABLE_NETWORK %s" % id) 901 logger.info("Verify that scanning continues when there is partial network block match") 902 for i in range(0, 2): 903 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10) 904 if ev is None: 905 raise Exception("Scan timed out") 906 logger.info("Scan completed") 907 908def eap_test(dev, ap, eap_params, method, user, release=0): 909 bssid = ap['bssid'] 910 params = hs20_ap_params() 911 params['nai_realm'] = ["0,example.com," + eap_params] 912 if release > 0: 913 params['hs20_release'] = str(release) 914 hapd = hostapd.add_ap(ap, params) 915 916 dev.flush_scan_cache() 917 dev.hs20_enable() 918 dev.add_cred_values({'realm': "example.com", 919 'ca_cert': "auth_serv/ca.pem", 920 'username': user, 921 'password': "password"}) 922 interworking_select(dev, bssid, freq="2412") 923 interworking_connect(dev, bssid, method) 924 return hapd 925 926@remote_compatible 927def test_ap_hs20_eap_unknown(dev, apdev): 928 """Hotspot 2.0 connection with unknown EAP method""" 929 bssid = apdev[0]['bssid'] 930 params = hs20_ap_params() 931 params['nai_realm'] = "0,example.com,99" 932 hostapd.add_ap(apdev[0], params) 933 934 dev[0].hs20_enable() 935 dev[0].add_cred_values(default_cred()) 936 interworking_select(dev[0], None, no_match=True, freq="2412") 937 938def test_ap_hs20_eap_peap_mschapv2(dev, apdev): 939 """Hotspot 2.0 connection with PEAP/MSCHAPV2""" 940 check_eap_capa(dev[0], "MSCHAPV2") 941 eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user") 942 943def test_ap_hs20_eap_peap_default(dev, apdev): 944 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)""" 945 check_eap_capa(dev[0], "MSCHAPV2") 946 eap_test(dev[0], apdev[0], "25", "PEAP", "user") 947 948def test_ap_hs20_eap_peap_gtc(dev, apdev): 949 """Hotspot 2.0 connection with PEAP/GTC""" 950 eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user") 951 952@remote_compatible 953def test_ap_hs20_eap_peap_unknown(dev, apdev): 954 """Hotspot 2.0 connection with PEAP/unknown""" 955 bssid = apdev[0]['bssid'] 956 params = hs20_ap_params() 957 params['nai_realm'] = "0,example.com,25[3:99]" 958 hostapd.add_ap(apdev[0], params) 959 960 dev[0].hs20_enable() 961 dev[0].add_cred_values(default_cred()) 962 interworking_select(dev[0], None, no_match=True, freq="2412") 963 964def test_ap_hs20_eap_ttls_chap(dev, apdev): 965 """Hotspot 2.0 connection with TTLS/CHAP""" 966 skip_with_fips(dev[0]) 967 eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user") 968 969def test_ap_hs20_eap_ttls_mschap(dev, apdev): 970 """Hotspot 2.0 connection with TTLS/MSCHAP""" 971 skip_with_fips(dev[0]) 972 eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user") 973 974def test_ap_hs20_eap_ttls_default(dev, apdev): 975 """Hotspot 2.0 connection with TTLS/default""" 976 skip_with_fips(dev[0]) 977 eap_test(dev[0], apdev[0], "21", "TTLS", "hs20-test") 978 979def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev): 980 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2""" 981 check_eap_capa(dev[0], "MSCHAPV2") 982 eap_test(dev[0], apdev[0], "21[3:26][6:7][99:99]", "TTLS", "user") 983 984@remote_compatible 985def test_ap_hs20_eap_ttls_eap_unknown(dev, apdev): 986 """Hotspot 2.0 connection with TTLS/EAP-unknown""" 987 bssid = apdev[0]['bssid'] 988 params = hs20_ap_params() 989 params['nai_realm'] = "0,example.com,21[3:99]" 990 hostapd.add_ap(apdev[0], params) 991 992 dev[0].hs20_enable() 993 dev[0].add_cred_values(default_cred()) 994 interworking_select(dev[0], None, no_match=True, freq="2412") 995 996@remote_compatible 997def test_ap_hs20_eap_ttls_eap_unsupported(dev, apdev): 998 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)""" 999 bssid = apdev[0]['bssid'] 1000 params = hs20_ap_params() 1001 params['nai_realm'] = "0,example.com,21[3:5]" 1002 hostapd.add_ap(apdev[0], params) 1003 1004 dev[0].hs20_enable() 1005 dev[0].add_cred_values(default_cred()) 1006 interworking_select(dev[0], None, no_match=True, freq="2412") 1007 1008@remote_compatible 1009def test_ap_hs20_eap_ttls_unknown(dev, apdev): 1010 """Hotspot 2.0 connection with TTLS/unknown""" 1011 bssid = apdev[0]['bssid'] 1012 params = hs20_ap_params() 1013 params['nai_realm'] = "0,example.com,21[2:5]" 1014 hostapd.add_ap(apdev[0], params) 1015 1016 dev[0].hs20_enable() 1017 dev[0].add_cred_values(default_cred()) 1018 interworking_select(dev[0], None, no_match=True, freq="2412") 1019 1020def test_ap_hs20_eap_fast_mschapv2(dev, apdev): 1021 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2""" 1022 check_eap_capa(dev[0], "FAST") 1023 eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user") 1024 1025def test_ap_hs20_eap_fast_gtc(dev, apdev): 1026 """Hotspot 2.0 connection with FAST/EAP-GTC""" 1027 check_eap_capa(dev[0], "FAST") 1028 eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user") 1029 1030def test_ap_hs20_eap_tls(dev, apdev): 1031 """Hotspot 2.0 connection with EAP-TLS""" 1032 bssid = apdev[0]['bssid'] 1033 params = hs20_ap_params() 1034 params['nai_realm'] = ["0,example.com,13[5:6]"] 1035 hostapd.add_ap(apdev[0], params) 1036 1037 dev[0].flush_scan_cache() 1038 dev[0].hs20_enable() 1039 dev[0].add_cred_values({'realm': "example.com", 1040 'username': "certificate-user", 1041 'ca_cert': "auth_serv/ca.pem", 1042 'client_cert': "auth_serv/user.pem", 1043 'private_key': "auth_serv/user.key"}) 1044 interworking_select(dev[0], bssid, freq="2412") 1045 interworking_connect(dev[0], bssid, "TLS") 1046 1047@remote_compatible 1048def test_ap_hs20_eap_cert_unknown(dev, apdev): 1049 """Hotspot 2.0 connection with certificate, but unknown EAP method""" 1050 bssid = apdev[0]['bssid'] 1051 params = hs20_ap_params() 1052 params['nai_realm'] = ["0,example.com,99[5:6]"] 1053 hostapd.add_ap(apdev[0], params) 1054 1055 dev[0].hs20_enable() 1056 dev[0].add_cred_values({'realm': "example.com", 1057 'username': "certificate-user", 1058 'ca_cert': "auth_serv/ca.pem", 1059 'client_cert': "auth_serv/user.pem", 1060 'private_key': "auth_serv/user.key"}) 1061 interworking_select(dev[0], None, no_match=True, freq="2412") 1062 1063@remote_compatible 1064def test_ap_hs20_eap_cert_unsupported(dev, apdev): 1065 """Hotspot 2.0 connection with certificate, but unsupported TTLS""" 1066 bssid = apdev[0]['bssid'] 1067 params = hs20_ap_params() 1068 params['nai_realm'] = ["0,example.com,21[5:6]"] 1069 hostapd.add_ap(apdev[0], params) 1070 1071 dev[0].hs20_enable() 1072 dev[0].add_cred_values({'realm': "example.com", 1073 'username': "certificate-user", 1074 'ca_cert': "auth_serv/ca.pem", 1075 'client_cert': "auth_serv/user.pem", 1076 'private_key': "auth_serv/user.key"}) 1077 interworking_select(dev[0], None, no_match=True, freq="2412") 1078 1079@remote_compatible 1080def test_ap_hs20_eap_invalid_cred(dev, apdev): 1081 """Hotspot 2.0 connection with invalid cred configuration""" 1082 bssid = apdev[0]['bssid'] 1083 params = hs20_ap_params() 1084 hostapd.add_ap(apdev[0], params) 1085 1086 dev[0].hs20_enable() 1087 dev[0].add_cred_values({'realm': "example.com", 1088 'username': "certificate-user", 1089 'client_cert': "auth_serv/user.pem"}) 1090 interworking_select(dev[0], None, no_match=True, freq="2412") 1091 1092def test_ap_hs20_nai_realms(dev, apdev): 1093 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP""" 1094 bssid = apdev[0]['bssid'] 1095 params = hs20_ap_params() 1096 params['hessid'] = bssid 1097 params['nai_realm'] = ["0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]"] 1098 hostapd.add_ap(apdev[0], params) 1099 1100 dev[0].flush_scan_cache() 1101 dev[0].hs20_enable() 1102 id = dev[0].add_cred_values({'realm': "example.com", 1103 'ca_cert': "auth_serv/ca.pem", 1104 'username': "pap user", 1105 'password': "password", 1106 'domain': "example.com"}) 1107 interworking_select(dev[0], bssid, "home", freq="2412") 1108 interworking_connect(dev[0], bssid, "TTLS") 1109 check_sp_type(dev[0], "home") 1110 1111def test_ap_hs20_roaming_consortium(dev, apdev): 1112 """Hotspot 2.0 connection based on roaming consortium match""" 1113 bssid = apdev[0]['bssid'] 1114 params = hs20_ap_params() 1115 params['hessid'] = bssid 1116 hostapd.add_ap(apdev[0], params) 1117 1118 dev[0].flush_scan_cache() 1119 dev[0].hs20_enable() 1120 for consortium in ["112233", "1020304050", "010203040506", "fedcba"]: 1121 id = dev[0].add_cred_values({'username': "user", 1122 'password': "password", 1123 'domain': "example.com", 1124 'ca_cert': "auth_serv/ca.pem", 1125 'roaming_consortium': consortium, 1126 'eap': "PEAP"}) 1127 interworking_select(dev[0], bssid, "home", freq="2412") 1128 interworking_connect(dev[0], bssid, "PEAP") 1129 check_sp_type(dev[0], "home") 1130 dev[0].request("INTERWORKING_SELECT auto freq=2412") 1131 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15) 1132 if ev is None: 1133 raise Exception("Timeout on already-connected event") 1134 dev[0].remove_cred(id) 1135 1136def test_ap_hs20_home_ois(dev, apdev): 1137 """Hotspot 2.0 connection based on roaming consortium match""" 1138 bssid = apdev[0]['bssid'] 1139 params = hs20_ap_params() 1140 params['hessid'] = bssid 1141 hostapd.add_ap(apdev[0], params) 1142 1143 dev[0].flush_scan_cache() 1144 dev[0].hs20_enable() 1145 for consortium in [["112233"], ["1020304050"], ["010203040506"], ["fedcba"], 1146 ["f12233", "f020304050", "f10203040506", "fedcba"]]: 1147 id = dev[0].add_cred_values({'username': "user", 1148 'password': "password", 1149 'domain': "example.com", 1150 'ca_cert': "auth_serv/ca.pem", 1151 'home_ois': consortium, 1152 'eap': "PEAP"}) 1153 interworking_select(dev[0], bssid, "home", freq="2412") 1154 interworking_connect(dev[0], bssid, "PEAP") 1155 check_sp_type(dev[0], "home") 1156 dev[0].request("INTERWORKING_SELECT auto freq=2412") 1157 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15) 1158 if ev is None: 1159 raise Exception("Timeout on already-connected event") 1160 dev[0].remove_cred(id) 1161 1162def test_ap_hs20_roaming_consortiums_match(dev, apdev): 1163 """Hotspot 2.0 connection based on roaming_consortiums match""" 1164 bssid = apdev[0]['bssid'] 1165 params = hs20_ap_params() 1166 params['hessid'] = bssid 1167 hostapd.add_ap(apdev[0], params) 1168 1169 dev[0].flush_scan_cache() 1170 dev[0].hs20_enable() 1171 tests = [("112233", "112233"), 1172 ("ffffff,1020304050,eeeeee", "1020304050")] 1173 for consortium, selected in tests: 1174 id = dev[0].add_cred_values({'username': "user", 1175 'password': "password", 1176 'domain': "my.home.example.com", 1177 'ca_cert': "auth_serv/ca.pem", 1178 'roaming_consortiums': consortium, 1179 'eap': "PEAP"}) 1180 interworking_select(dev[0], bssid, "roaming", freq="2412") 1181 interworking_connect(dev[0], bssid, "PEAP") 1182 check_sp_type(dev[0], "roaming") 1183 network_id = dev[0].get_status_field("id") 1184 sel = dev[0].get_network(network_id, "roaming_consortium_selection") 1185 if sel != selected: 1186 raise Exception("Unexpected roaming_consortium_selection value: " + 1187 sel) 1188 dev[0].request("INTERWORKING_SELECT auto freq=2412") 1189 ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15) 1190 if ev is None: 1191 raise Exception("Timeout on already-connected event") 1192 dev[0].remove_cred(id) 1193 1194def test_ap_hs20_max_roaming_consortiums(dev, apdev): 1195 """Maximum number of cred roaming_consortiums""" 1196 id = dev[0].add_cred() 1197 consortium = (36*",ffffff")[1:] 1198 if "OK" not in dev[0].request('SET_CRED %d roaming_consortiums "%s"' % (id, consortium)): 1199 raise Exception("Maximum number of consortium OIs rejected") 1200 consortium = (37*",ffffff")[1:] 1201 if "FAIL" not in dev[0].request('SET_CRED %d roaming_consortiums "%s"' % (id, consortium)): 1202 raise Exception("Over maximum number of consortium OIs accepted") 1203 dev[0].remove_cred(id) 1204 1205def test_ap_hs20_roaming_consortium_invalid(dev, apdev): 1206 """Hotspot 2.0 connection and invalid roaming consortium ANQP-element""" 1207 bssid = apdev[0]['bssid'] 1208 params = hs20_ap_params() 1209 params['hessid'] = bssid 1210 # Override Roaming Consortium ANQP-element with an incorrectly encoded 1211 # value. 1212 params['anqp_elem'] = "261:04fedcba" 1213 hostapd.add_ap(apdev[0], params) 1214 1215 dev[0].hs20_enable() 1216 id = dev[0].add_cred_values({'username': "user", 1217 'password': "password", 1218 'domain': "example.com", 1219 'ca_cert': "auth_serv/ca.pem", 1220 'home_ois': ["fedcba"], 1221 'eap': "PEAP"}) 1222 interworking_select(dev[0], bssid, "home", freq="2412", no_match=True) 1223 1224def test_ap_hs20_roaming_consortium_element(dev, apdev): 1225 """Hotspot 2.0 connection and invalid roaming consortium element""" 1226 bssid = apdev[0]['bssid'] 1227 params = hs20_ap_params() 1228 params['hessid'] = bssid 1229 del params['roaming_consortium'] 1230 params['vendor_elements'] = '6f00' 1231 hapd = hostapd.add_ap(apdev[0], params) 1232 1233 dev[0].hs20_enable() 1234 dev[0].scan_for_bss(bssid, freq="2412") 1235 id = dev[0].add_cred_values({'username': "user", 1236 'password': "password", 1237 'domain': "example.com", 1238 'ca_cert': "auth_serv/ca.pem", 1239 'home_ois': ["112233"], 1240 'eap': "PEAP"}) 1241 interworking_select(dev[0], bssid, freq="2412", no_match=True) 1242 1243 hapd.set('vendor_elements', '6f020001') 1244 if "OK" not in hapd.request("UPDATE_BEACON"): 1245 raise Exception("UPDATE_BEACON failed") 1246 dev[0].request("BSS_FLUSH 0") 1247 dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) 1248 interworking_select(dev[0], bssid, freq="2412", no_match=True) 1249 1250def test_ap_hs20_roaming_consortium_constraints(dev, apdev): 1251 """Hotspot 2.0 connection and roaming consortium constraints""" 1252 bssid = apdev[0]['bssid'] 1253 params = hs20_ap_params() 1254 params['hessid'] = bssid 1255 params['bss_load_test'] = "12:200:20000" 1256 hostapd.add_ap(apdev[0], params) 1257 1258 dev[0].hs20_enable() 1259 1260 vals = {'username': "user", 1261 'password': "password", 1262 'domain': "example.com", 1263 'ca_cert': "auth_serv/ca.pem", 1264 'home_ois': ["fedcba"], 1265 'eap': "TTLS"} 1266 vals2 = vals.copy() 1267 vals2['required_home_ois'] = ["223344"] 1268 id = dev[0].add_cred_values(vals2) 1269 interworking_select(dev[0], bssid, "home", freq="2412", no_match=True) 1270 dev[0].remove_cred(id) 1271 1272 vals2 = vals.copy() 1273 vals2['min_dl_bandwidth_home'] = "65500" 1274 id = dev[0].add_cred_values(vals2) 1275 dev[0].request("INTERWORKING_SELECT freq=2412") 1276 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1277 if ev is None: 1278 raise Exception("No AP found") 1279 if "below_min_backhaul=1" not in ev: 1280 raise Exception("below_min_backhaul not reported") 1281 dev[0].remove_cred(id) 1282 1283 vals2 = vals.copy() 1284 vals2['max_bss_load'] = "100" 1285 id = dev[0].add_cred_values(vals2) 1286 dev[0].request("INTERWORKING_SELECT freq=2412") 1287 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1288 if ev is None: 1289 raise Exception("No AP found") 1290 if "over_max_bss_load=1" not in ev: 1291 raise Exception("over_max_bss_load not reported") 1292 dev[0].remove_cred(id) 1293 1294 vals2 = vals.copy() 1295 vals2['req_conn_capab'] = "6:1234" 1296 vals2['domain'] = 'example.org' 1297 id = dev[0].add_cred_values(vals2) 1298 1299 dev[0].request("INTERWORKING_SELECT freq=2412") 1300 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1301 if ev is None: 1302 raise Exception("No AP found") 1303 if "conn_capab_missing=1" not in ev: 1304 raise Exception("conn_capab_missing not reported") 1305 dev[0].remove_cred(id) 1306 1307 values = default_cred() 1308 values['home_ois'] = ["fedcba"] 1309 id3 = dev[0].add_cred_values(values) 1310 1311 vals2 = vals.copy() 1312 vals2['home_ois'] = ["fedcba"] 1313 vals2['priority'] = "2" 1314 id = dev[0].add_cred_values(vals2) 1315 1316 values = default_cred() 1317 values['home_ois'] = ["fedcba"] 1318 id2 = dev[0].add_cred_values(values) 1319 1320 dev[0].request("INTERWORKING_SELECT freq=2412") 1321 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1322 if ev is None: 1323 raise Exception("No AP found") 1324 dev[0].remove_cred(id) 1325 dev[0].remove_cred(id2) 1326 dev[0].remove_cred(id3) 1327 1328def test_ap_hs20_3gpp_constraints(dev, apdev): 1329 """Hotspot 2.0 connection and 3GPP credential constraints""" 1330 bssid = apdev[0]['bssid'] 1331 params = hs20_ap_params() 1332 params['hessid'] = bssid 1333 params['anqp_3gpp_cell_net'] = "555,444" 1334 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org" 1335 params['bss_load_test'] = "12:200:20000" 1336 hapd = hostapd.add_ap(apdev[0], params) 1337 1338 dev[0].hs20_enable() 1339 1340 vals = {'imsi': "555444-333222111", 1341 'eap': "SIM", 1342 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"} 1343 vals2 = vals.copy() 1344 vals2['required_home_ois'] = ["223344"] 1345 id = dev[0].add_cred_values(vals2) 1346 interworking_select(dev[0], bssid, "home", freq="2412", no_match=True) 1347 dev[0].remove_cred(id) 1348 1349 vals2 = vals.copy() 1350 vals2['min_dl_bandwidth_home'] = "65500" 1351 id = dev[0].add_cred_values(vals2) 1352 dev[0].request("INTERWORKING_SELECT freq=2412") 1353 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1354 if ev is None: 1355 raise Exception("No AP found") 1356 if "below_min_backhaul=1" not in ev: 1357 raise Exception("below_min_backhaul not reported") 1358 dev[0].remove_cred(id) 1359 1360 vals2 = vals.copy() 1361 vals2['max_bss_load'] = "100" 1362 id = dev[0].add_cred_values(vals2) 1363 dev[0].request("INTERWORKING_SELECT freq=2412") 1364 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1365 if ev is None: 1366 raise Exception("No AP found") 1367 if "over_max_bss_load=1" not in ev: 1368 raise Exception("over_max_bss_load not reported") 1369 dev[0].remove_cred(id) 1370 1371 values = default_cred() 1372 values['home_ois'] = ["fedcba"] 1373 id3 = dev[0].add_cred_values(values) 1374 1375 vals2 = vals.copy() 1376 vals2['home_ois'] = ["fedcba"] 1377 vals2['priority'] = "2" 1378 id = dev[0].add_cred_values(vals2) 1379 1380 values = default_cred() 1381 values['home_ois'] = ["fedcba"] 1382 id2 = dev[0].add_cred_values(values) 1383 1384 dev[0].request("INTERWORKING_SELECT freq=2412") 1385 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1386 if ev is None: 1387 raise Exception("No AP found") 1388 dev[0].remove_cred(id) 1389 dev[0].remove_cred(id2) 1390 dev[0].remove_cred(id3) 1391 1392 hapd.disable() 1393 params = hs20_ap_params() 1394 params['hessid'] = bssid 1395 params['anqp_3gpp_cell_net'] = "555,444" 1396 params['bss_load_test'] = "12:200:20000" 1397 hapd = hostapd.add_ap(apdev[0], params) 1398 vals2 = vals.copy() 1399 vals2['req_conn_capab'] = "6:1234" 1400 id = dev[0].add_cred_values(vals2) 1401 dev[0].request("INTERWORKING_SELECT freq=2412") 1402 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1403 if ev is None: 1404 raise Exception("No AP found") 1405 if "conn_capab_missing=1" not in ev: 1406 raise Exception("conn_capab_missing not reported") 1407 dev[0].remove_cred(id) 1408 1409def test_ap_hs20_connect_no_full_match(dev, apdev): 1410 """Hotspot 2.0 connection and no full match""" 1411 bssid = apdev[0]['bssid'] 1412 params = hs20_ap_params() 1413 params['hessid'] = bssid 1414 params['anqp_3gpp_cell_net'] = "555,444" 1415 hapd = hostapd.add_ap(apdev[0], params) 1416 1417 dev[0].flush_scan_cache() 1418 dev[0].hs20_enable() 1419 1420 vals = {'username': "user", 1421 'password': "password", 1422 'domain': "example.com", 1423 'ca_cert': "auth_serv/ca.pem", 1424 'home_ois': ["fedcba"], 1425 'eap': "TTLS", 1426 'min_dl_bandwidth_home': "65500"} 1427 id = dev[0].add_cred_values(vals) 1428 dev[0].request("INTERWORKING_SELECT freq=2412") 1429 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1430 if ev is None: 1431 raise Exception("No AP found") 1432 if "below_min_backhaul=1" not in ev: 1433 raise Exception("below_min_backhaul not reported") 1434 interworking_connect(dev[0], bssid, "TTLS") 1435 # wait for sta to connect so it can actually disconnect later 1436 hapd.wait_sta() 1437 dev[0].remove_cred(id) 1438 dev[0].wait_disconnected() 1439 # wait for sta to disconnect so it can send GAS query 1440 hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=1) 1441 1442 vals = {'imsi': "555444-333222111", 'eap': "SIM", 1443 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", 1444 'min_dl_bandwidth_roaming': "65500"} 1445 id = dev[0].add_cred_values(vals) 1446 dev[0].request("INTERWORKING_SELECT freq=2412") 1447 ev = dev[0].wait_event(["INTERWORKING-AP"], timeout=15) 1448 if ev is None: 1449 raise Exception("No AP found") 1450 if "below_min_backhaul=1" not in ev: 1451 raise Exception("below_min_backhaul not reported") 1452 interworking_connect(dev[0], bssid, "SIM") 1453 dev[0].remove_cred(id) 1454 dev[0].wait_disconnected() 1455 1456def test_ap_hs20_username_roaming(dev, apdev): 1457 """Hotspot 2.0 connection in username/password credential (roaming)""" 1458 check_eap_capa(dev[0], "MSCHAPV2") 1459 bssid = apdev[0]['bssid'] 1460 params = hs20_ap_params() 1461 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]", 1462 "0,roaming.example.com,21[2:4][5:7]", 1463 "0,another.example.com"] 1464 params['domain_name'] = "another.example.com" 1465 params['hessid'] = bssid 1466 hostapd.add_ap(apdev[0], params) 1467 1468 dev[0].hs20_enable() 1469 id = dev[0].add_cred_values({'realm': "roaming.example.com", 1470 'username': "hs20-test", 1471 'password': "password", 1472 'ca_cert': "auth_serv/ca.pem", 1473 'domain': "example.com"}) 1474 interworking_select(dev[0], bssid, "roaming", freq="2412") 1475 interworking_connect(dev[0], bssid, "TTLS") 1476 check_sp_type(dev[0], "roaming") 1477 1478def test_ap_hs20_username_unknown(dev, apdev): 1479 """Hotspot 2.0 connection in username/password credential (no domain in cred)""" 1480 check_eap_capa(dev[0], "MSCHAPV2") 1481 bssid = apdev[0]['bssid'] 1482 params = hs20_ap_params() 1483 params['hessid'] = bssid 1484 hostapd.add_ap(apdev[0], params) 1485 1486 dev[0].hs20_enable() 1487 id = dev[0].add_cred_values({'realm': "example.com", 1488 'ca_cert': "auth_serv/ca.pem", 1489 'username': "hs20-test", 1490 'password': "password"}) 1491 interworking_select(dev[0], bssid, "unknown", freq="2412") 1492 interworking_connect(dev[0], bssid, "TTLS") 1493 check_sp_type(dev[0], "unknown") 1494 1495def test_ap_hs20_username_unknown2(dev, apdev): 1496 """Hotspot 2.0 connection in username/password credential (no domain advertized)""" 1497 check_eap_capa(dev[0], "MSCHAPV2") 1498 bssid = apdev[0]['bssid'] 1499 params = hs20_ap_params() 1500 params['hessid'] = bssid 1501 del params['domain_name'] 1502 hostapd.add_ap(apdev[0], params) 1503 1504 dev[0].hs20_enable() 1505 id = dev[0].add_cred_values({'realm': "example.com", 1506 'ca_cert': "auth_serv/ca.pem", 1507 'username': "hs20-test", 1508 'password': "password", 1509 'domain': "example.com"}) 1510 interworking_select(dev[0], bssid, "unknown", freq="2412") 1511 interworking_connect(dev[0], bssid, "TTLS") 1512 check_sp_type(dev[0], "unknown") 1513 1514def test_ap_hs20_gas_while_associated(dev, apdev): 1515 """Hotspot 2.0 connection with GAS query while associated""" 1516 check_eap_capa(dev[0], "MSCHAPV2") 1517 bssid = apdev[0]['bssid'] 1518 params = hs20_ap_params() 1519 params['hessid'] = bssid 1520 hapd = hostapd.add_ap(apdev[0], params) 1521 1522 dev[0].hs20_enable() 1523 id = dev[0].add_cred_values({'realm': "example.com", 1524 'ca_cert': "auth_serv/ca.pem", 1525 'username': "hs20-test", 1526 'password': "password", 1527 'domain': "example.com"}) 1528 interworking_select(dev[0], bssid, "home", freq="2412") 1529 interworking_connect(dev[0], bssid, "TTLS") 1530 hapd.wait_sta() 1531 1532 logger.info("Verifying GAS query while associated") 1533 dev[0].request("FETCH_ANQP") 1534 for i in range(0, 6): 1535 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 1536 if ev is None: 1537 raise Exception("Operation timed out") 1538 1539def test_ap_hs20_gas_with_another_ap_while_associated(dev, apdev): 1540 """GAS query with another AP while associated""" 1541 check_eap_capa(dev[0], "MSCHAPV2") 1542 bssid = apdev[0]['bssid'] 1543 params = hs20_ap_params() 1544 params['hessid'] = bssid 1545 hapd = hostapd.add_ap(apdev[0], params) 1546 1547 bssid2 = apdev[1]['bssid'] 1548 params = hs20_ap_params() 1549 params['hessid'] = bssid2 1550 params['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"] 1551 hostapd.add_ap(apdev[1], params) 1552 1553 dev[0].hs20_enable() 1554 id = dev[0].add_cred_values({'realm': "example.com", 1555 'ca_cert': "auth_serv/ca.pem", 1556 'username': "hs20-test", 1557 'password': "password", 1558 'domain': "example.com"}) 1559 interworking_select(dev[0], bssid, "home", freq="2412") 1560 interworking_connect(dev[0], bssid, "TTLS") 1561 hapd.wait_sta() 1562 dev[0].dump_monitor() 1563 1564 logger.info("Verifying GAS query with same AP while associated") 1565 dev[0].request("ANQP_GET " + bssid + " 263") 1566 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 1567 if ev is None: 1568 raise Exception("ANQP operation timed out") 1569 dev[0].dump_monitor() 1570 1571 logger.info("Verifying GAS query with another AP while associated") 1572 dev[0].scan_for_bss(bssid2, 2412) 1573 dev[0].request("ANQP_GET " + bssid2 + " 263") 1574 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 1575 if ev is None: 1576 raise Exception("ANQP operation timed out") 1577 1578def test_ap_hs20_gas_while_associated_with_pmf(dev, apdev): 1579 """Hotspot 2.0 connection with GAS query while associated and using PMF""" 1580 check_eap_capa(dev[0], "MSCHAPV2") 1581 try: 1582 _test_ap_hs20_gas_while_associated_with_pmf(dev, apdev) 1583 finally: 1584 dev[0].request("SET pmf 0") 1585 1586def _test_ap_hs20_gas_while_associated_with_pmf(dev, apdev): 1587 bssid = apdev[0]['bssid'] 1588 params = hs20_ap_params() 1589 params['hessid'] = bssid 1590 hapd = hostapd.add_ap(apdev[0], params) 1591 1592 bssid2 = apdev[1]['bssid'] 1593 params = hs20_ap_params() 1594 params['hessid'] = bssid2 1595 params['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"] 1596 hostapd.add_ap(apdev[1], params) 1597 1598 dev[0].flush_scan_cache() 1599 dev[0].hs20_enable() 1600 dev[0].request("SET pmf 2") 1601 id = dev[0].add_cred_values({'realm': "example.com", 1602 'ca_cert': "auth_serv/ca.pem", 1603 'username': "hs20-test", 1604 'password': "password", 1605 'domain': "example.com"}) 1606 interworking_select(dev[0], bssid, "home", freq="2412") 1607 interworking_connect(dev[0], bssid, "TTLS") 1608 hapd.wait_sta() 1609 1610 logger.info("Verifying GAS query while associated") 1611 dev[0].request("FETCH_ANQP") 1612 for i in range(0, 2 * 6): 1613 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 1614 if ev is None: 1615 raise Exception("Operation timed out") 1616 1617def test_ap_hs20_gas_with_another_ap_while_using_pmf(dev, apdev): 1618 """GAS query with another AP while associated and using PMF""" 1619 check_eap_capa(dev[0], "MSCHAPV2") 1620 try: 1621 _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev, apdev) 1622 finally: 1623 dev[0].request("SET pmf 0") 1624 1625def _test_ap_hs20_gas_with_another_ap_while_using_pmf(dev, apdev): 1626 bssid = apdev[0]['bssid'] 1627 params = hs20_ap_params() 1628 params['hessid'] = bssid 1629 hapd = hostapd.add_ap(apdev[0], params) 1630 1631 bssid2 = apdev[1]['bssid'] 1632 params = hs20_ap_params() 1633 params['hessid'] = bssid2 1634 params['nai_realm'] = ["0,no-match.example.org,13[5:6],21[2:4][5:7]"] 1635 hostapd.add_ap(apdev[1], params) 1636 1637 dev[0].hs20_enable() 1638 dev[0].request("SET pmf 2") 1639 id = dev[0].add_cred_values({'realm': "example.com", 1640 'ca_cert': "auth_serv/ca.pem", 1641 'username': "hs20-test", 1642 'password': "password", 1643 'domain': "example.com"}) 1644 interworking_select(dev[0], bssid, "home", freq="2412") 1645 interworking_connect(dev[0], bssid, "TTLS") 1646 dev[0].dump_monitor() 1647 hapd.wait_sta() 1648 1649 logger.info("Verifying GAS query with same AP while associated") 1650 dev[0].request("ANQP_GET " + bssid + " 263") 1651 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 1652 if ev is None: 1653 raise Exception("ANQP operation timed out") 1654 dev[0].dump_monitor() 1655 1656 logger.info("Verifying GAS query with another AP while associated") 1657 dev[0].scan_for_bss(bssid2, 2412) 1658 dev[0].request("ANQP_GET " + bssid2 + " 263") 1659 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 1660 if ev is None: 1661 raise Exception("ANQP operation timed out") 1662 1663def test_ap_hs20_gas_frag_while_associated(dev, apdev): 1664 """Hotspot 2.0 connection with fragmented GAS query while associated""" 1665 check_eap_capa(dev[0], "MSCHAPV2") 1666 bssid = apdev[0]['bssid'] 1667 params = hs20_ap_params() 1668 params['hessid'] = bssid 1669 hapd = hostapd.add_ap(apdev[0], params) 1670 hapd.set("gas_frag_limit", "50") 1671 1672 dev[0].hs20_enable() 1673 id = dev[0].add_cred_values({'realm': "example.com", 1674 'ca_cert': "auth_serv/ca.pem", 1675 'username': "hs20-test", 1676 'password': "password", 1677 'domain': "example.com"}) 1678 interworking_select(dev[0], bssid, "home", freq="2412") 1679 interworking_connect(dev[0], bssid, "TTLS") 1680 hapd.wait_sta() 1681 1682 logger.info("Verifying GAS query while associated") 1683 dev[0].request("FETCH_ANQP") 1684 for i in range(0, 6): 1685 ev = dev[0].wait_event(["RX-ANQP"], timeout=5) 1686 if ev is None: 1687 raise Exception("Operation timed out") 1688 1689def test_ap_hs20_multiple_connects(dev, apdev): 1690 """Hotspot 2.0 connection through multiple network selections""" 1691 check_eap_capa(dev[0], "MSCHAPV2") 1692 bssid = apdev[0]['bssid'] 1693 params = hs20_ap_params() 1694 params['hessid'] = bssid 1695 hostapd.add_ap(apdev[0], params) 1696 1697 dev[0].hs20_enable() 1698 values = {'realm': "example.com", 1699 'ca_cert': "auth_serv/ca.pem", 1700 'username': "hs20-test", 1701 'password': "password", 1702 'domain': "example.com"} 1703 id = dev[0].add_cred_values(values) 1704 1705 dev[0].scan_for_bss(bssid, freq="2412") 1706 1707 for i in range(0, 3): 1708 logger.info("Starting Interworking network selection") 1709 dev[0].request("INTERWORKING_SELECT auto freq=2412") 1710 while True: 1711 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH", 1712 "INTERWORKING-ALREADY-CONNECTED", 1713 "CTRL-EVENT-CONNECTED"], timeout=15) 1714 if ev is None: 1715 raise Exception("Connection timed out") 1716 if "INTERWORKING-NO-MATCH" in ev: 1717 raise Exception("Matching AP not found") 1718 if "CTRL-EVENT-CONNECTED" in ev: 1719 break 1720 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev: 1721 break 1722 if i == 0: 1723 dev[0].request("DISCONNECT") 1724 dev[0].dump_monitor() 1725 1726 networks = dev[0].list_networks() 1727 if len(networks) > 1: 1728 raise Exception("Duplicated network block detected") 1729 1730def test_ap_hs20_disallow_aps(dev, apdev): 1731 """Hotspot 2.0 connection and disallow_aps""" 1732 bssid = apdev[0]['bssid'] 1733 params = hs20_ap_params() 1734 params['hessid'] = bssid 1735 hostapd.add_ap(apdev[0], params) 1736 1737 dev[0].hs20_enable() 1738 values = {'realm': "example.com", 1739 'ca_cert': "auth_serv/ca.pem", 1740 'username': "hs20-test", 1741 'password': "password", 1742 'domain': "example.com"} 1743 id = dev[0].add_cred_values(values) 1744 1745 dev[0].scan_for_bss(bssid, freq="2412") 1746 1747 logger.info("Verify disallow_aps bssid") 1748 dev[0].request("SET disallow_aps bssid " + bssid.replace(':', '')) 1749 dev[0].request("INTERWORKING_SELECT auto") 1750 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15) 1751 if ev is None: 1752 raise Exception("Network selection timed out") 1753 dev[0].dump_monitor() 1754 1755 logger.info("Verify disallow_aps ssid") 1756 dev[0].request("SET disallow_aps ssid 746573742d68733230") 1757 dev[0].request("INTERWORKING_SELECT auto freq=2412") 1758 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15) 1759 if ev is None: 1760 raise Exception("Network selection timed out") 1761 dev[0].dump_monitor() 1762 1763 logger.info("Verify disallow_aps clear") 1764 dev[0].request("SET disallow_aps ") 1765 interworking_select(dev[0], bssid, "home", freq="2412") 1766 1767 dev[0].request("SET disallow_aps bssid " + bssid.replace(':', '')) 1768 ret = dev[0].request("INTERWORKING_CONNECT " + bssid) 1769 if "FAIL" not in ret: 1770 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected") 1771 1772 if "FAIL" not in dev[0].request("INTERWORKING_CONNECT foo"): 1773 raise Exception("Invalid INTERWORKING_CONNECT not rejected") 1774 if "FAIL" not in dev[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"): 1775 raise Exception("Invalid INTERWORKING_CONNECT not rejected") 1776 1777def policy_test(dev, ap, hapd, values, only_one=True): 1778 dev.dump_monitor() 1779 if hapd is not None: 1780 hapd.dump_monitor() 1781 if ap: 1782 logger.info("Verify network selection to AP " + ap['ifname']) 1783 bssid = ap['bssid'] 1784 dev.scan_for_bss(bssid, freq="2412") 1785 else: 1786 logger.info("Verify network selection") 1787 bssid = None 1788 dev.hs20_enable() 1789 id = dev.add_cred_values(values) 1790 dev.request("INTERWORKING_SELECT auto freq=2412") 1791 events = [] 1792 while True: 1793 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH", 1794 "INTERWORKING-BLACKLISTED", 1795 "INTERWORKING-SELECTED"], timeout=15) 1796 if ev is None: 1797 raise Exception("Network selection timed out") 1798 events.append(ev) 1799 if "INTERWORKING-NO-MATCH" in ev: 1800 raise Exception("Matching AP not found") 1801 if bssid and only_one and "INTERWORKING-AP" in ev and bssid not in ev: 1802 raise Exception("Unexpected AP claimed acceptable") 1803 if "INTERWORKING-SELECTED" in ev: 1804 if bssid and bssid not in ev: 1805 raise Exception("Selected incorrect BSS") 1806 break 1807 1808 ev = dev.wait_connected(timeout=15) 1809 if bssid and bssid not in ev: 1810 raise Exception("Connected to incorrect BSS") 1811 1812 conn_bssid = dev.get_status_field("bssid") 1813 if bssid and conn_bssid != bssid: 1814 raise Exception("bssid information points to incorrect BSS") 1815 1816 if hapd is not None: 1817 hapd.wait_sta() 1818 1819 dev.remove_cred(id) 1820 dev.dump_monitor() 1821 return events 1822 1823def default_cred(domain=None, user="hs20-test"): 1824 cred = {'realm': "example.com", 1825 'ca_cert': "auth_serv/ca.pem", 1826 'username': user, 1827 'password': "password"} 1828 if domain: 1829 cred['domain'] = domain 1830 return cred 1831 1832def test_ap_hs20_prefer_home(dev, apdev): 1833 """Hotspot 2.0 required roaming consortium""" 1834 check_eap_capa(dev[0], "MSCHAPV2") 1835 params = hs20_ap_params() 1836 params['domain_name'] = "example.org" 1837 hapd0 = hostapd.add_ap(apdev[0], params) 1838 1839 params = hs20_ap_params() 1840 params['ssid'] = "test-hs20-other" 1841 params['domain_name'] = "example.com" 1842 hapd1 = hostapd.add_ap(apdev[1], params) 1843 1844 values = default_cred() 1845 values['domain'] = "example.com" 1846 policy_test(dev[0], apdev[1], hapd1, values, only_one=False) 1847 values['domain'] = "example.org" 1848 policy_test(dev[0], apdev[0], hapd0, values, only_one=False) 1849 1850def test_ap_hs20_req_home_ois(dev, apdev): 1851 """Hotspot 2.0 required roaming consortium""" 1852 check_eap_capa(dev[0], "MSCHAPV2") 1853 params = hs20_ap_params() 1854 hapd0 = hostapd.add_ap(apdev[0], params) 1855 1856 params = hs20_ap_params() 1857 params['ssid'] = "test-hs20-other" 1858 params['roaming_consortium'] = ["223344"] 1859 hapd1 = hostapd.add_ap(apdev[1], params) 1860 1861 values = default_cred() 1862 values['required_home_ois'] = ["223344"] 1863 policy_test(dev[0], apdev[1], hapd1, values) 1864 values['required_home_ois'] = ["112233"] 1865 policy_test(dev[0], apdev[0], hapd0, values) 1866 1867 id = dev[0].add_cred() 1868 dev[0].set_cred_quoted(id, "required_home_ois", "112233") 1869 dev[0].set_cred_quoted(id, "required_home_ois", 1870 "112233445566778899aabbccddeeff") 1871 1872 for val in ["", "1", "11", "1122", "1122334", 1873 "112233445566778899aabbccddeeff00", "1122334455,12345"]: 1874 if "FAIL" not in dev[0].request('SET_CRED {} required_home_ois "{}"'.format(id, val)): 1875 raise Exception("Invalid roaming consortium value accepted: " + val) 1876 1877def test_ap_hs20_req_roaming_consortium_no_match(dev, apdev): 1878 """Hotspot 2.0 required roaming consortium and no match""" 1879 check_eap_capa(dev[0], "MSCHAPV2") 1880 params = hs20_ap_params() 1881 del params['roaming_consortium'] 1882 hostapd.add_ap(apdev[0], params) 1883 1884 params = hs20_ap_params() 1885 params['ssid'] = "test-hs20-other" 1886 params['roaming_consortium'] = ["223345"] 1887 hostapd.add_ap(apdev[1], params) 1888 1889 values = default_cred() 1890 values['required_home_ois'] = ["223344"] 1891 dev[0].hs20_enable() 1892 id = dev[0].add_cred_values(values) 1893 dev[0].request("INTERWORKING_SELECT auto freq=2412") 1894 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=10) 1895 if ev is None: 1896 raise Exception("INTERWORKING-NO-MATCH not reported") 1897 1898def test_ap_hs20_excluded_ssid(dev, apdev): 1899 """Hotspot 2.0 exclusion based on SSID""" 1900 check_eap_capa(dev[0], "MSCHAPV2") 1901 params = hs20_ap_params() 1902 params['roaming_consortium'] = ["223344"] 1903 params['anqp_3gpp_cell_net'] = "555,444" 1904 hapd0 = hostapd.add_ap(apdev[0], params) 1905 1906 params = hs20_ap_params() 1907 params['ssid'] = "test-hs20-other" 1908 params['roaming_consortium'] = ["223344"] 1909 params['anqp_3gpp_cell_net'] = "555,444" 1910 hapd1 = hostapd.add_ap(apdev[1], params) 1911 1912 values = default_cred() 1913 values['excluded_ssid'] = "test-hs20" 1914 events = policy_test(dev[0], apdev[1], hapd1, values) 1915 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e] 1916 if len(ev) != 1: 1917 raise Exception("Excluded network not reported") 1918 values['excluded_ssid'] = "test-hs20-other" 1919 events = policy_test(dev[0], apdev[0], hapd0, values) 1920 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[1]['bssid'] in e] 1921 if len(ev) != 1: 1922 raise Exception("Excluded network not reported") 1923 1924 values = default_cred() 1925 values['home_ois'] = ["223344"] 1926 values['eap'] = "TTLS" 1927 values['phase2'] = "auth=MSCHAPV2" 1928 values['excluded_ssid'] = "test-hs20" 1929 events = policy_test(dev[0], apdev[1], hapd1, values) 1930 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e] 1931 if len(ev) != 1: 1932 raise Exception("Excluded network not reported") 1933 1934 values = {'imsi': "555444-333222111", 'eap': "SIM", 1935 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123", 1936 'excluded_ssid': "test-hs20"} 1937 events = policy_test(dev[0], apdev[1], hapd1, values) 1938 ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e] 1939 if len(ev) != 1: 1940 raise Exception("Excluded network not reported") 1941 1942def test_ap_hs20_roam_to_higher_prio(dev, apdev): 1943 """Hotspot 2.0 and roaming from current to higher priority network""" 1944 check_eap_capa(dev[0], "MSCHAPV2") 1945 bssid = apdev[0]['bssid'] 1946 params = hs20_ap_params(ssid="test-hs20-visited") 1947 params['domain_name'] = "visited.example.org" 1948 hostapd.add_ap(apdev[0], params) 1949 1950 dev[0].hs20_enable() 1951 id = dev[0].add_cred_values({'realm': "example.com", 1952 'ca_cert': "auth_serv/ca.pem", 1953 'username': "hs20-test", 1954 'password': "password", 1955 'domain': "example.com"}) 1956 logger.info("Connect to the only network option") 1957 interworking_select(dev[0], bssid, "roaming", freq="2412") 1958 dev[0].dump_monitor() 1959 interworking_connect(dev[0], bssid, "TTLS") 1960 1961 logger.info("Start another AP (home operator) and reconnect") 1962 bssid2 = apdev[1]['bssid'] 1963 params = hs20_ap_params(ssid="test-hs20-home") 1964 params['domain_name'] = "example.com" 1965 hostapd.add_ap(apdev[1], params) 1966 1967 dev[0].scan_for_bss(bssid2, freq="2412", force_scan=True) 1968 dev[0].request("INTERWORKING_SELECT auto freq=2412") 1969 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH", 1970 "INTERWORKING-ALREADY-CONNECTED", 1971 "CTRL-EVENT-CONNECTED"], timeout=15) 1972 if ev is None: 1973 raise Exception("Connection timed out") 1974 if "INTERWORKING-NO-MATCH" in ev: 1975 raise Exception("Matching AP not found") 1976 if "INTERWORKING-ALREADY-CONNECTED" in ev: 1977 raise Exception("Unexpected AP selected") 1978 if bssid2 not in ev: 1979 raise Exception("Unexpected BSSID after reconnection") 1980 1981def test_ap_hs20_domain_suffix_match_full(dev, apdev): 1982 """Hotspot 2.0 and domain_suffix_match""" 1983 check_domain_match_full(dev[0]) 1984 check_eap_capa(dev[0], "MSCHAPV2") 1985 bssid = apdev[0]['bssid'] 1986 params = hs20_ap_params() 1987 hostapd.add_ap(apdev[0], params) 1988 1989 dev[0].hs20_enable() 1990 id = dev[0].add_cred_values({'realm': "example.com", 1991 'username': "hs20-test", 1992 'password': "password", 1993 'ca_cert': "auth_serv/ca.pem", 1994 'domain': "example.com", 1995 'domain_suffix_match': "server.w1.fi"}) 1996 interworking_select(dev[0], bssid, "home", freq="2412") 1997 dev[0].dump_monitor() 1998 interworking_connect(dev[0], bssid, "TTLS") 1999 dev[0].request("REMOVE_NETWORK all") 2000 dev[0].dump_monitor() 2001 2002 dev[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com") 2003 interworking_select(dev[0], bssid, "home", freq="2412") 2004 dev[0].dump_monitor() 2005 dev[0].request("INTERWORKING_CONNECT " + bssid) 2006 ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"]) 2007 if ev is None: 2008 raise Exception("TLS certificate error not reported") 2009 if "Domain suffix mismatch" not in ev: 2010 raise Exception("Domain suffix mismatch not reported") 2011 2012def test_ap_hs20_domain_suffix_match(dev, apdev): 2013 """Hotspot 2.0 and domain_suffix_match""" 2014 check_eap_capa(dev[0], "MSCHAPV2") 2015 check_domain_match_full(dev[0]) 2016 bssid = apdev[0]['bssid'] 2017 params = hs20_ap_params() 2018 hostapd.add_ap(apdev[0], params) 2019 2020 dev[0].hs20_enable() 2021 id = dev[0].add_cred_values({'realm': "example.com", 2022 'username': "hs20-test", 2023 'password': "password", 2024 'ca_cert': "auth_serv/ca.pem", 2025 'domain': "example.com", 2026 'domain_suffix_match': "w1.fi"}) 2027 interworking_select(dev[0], bssid, "home", freq="2412") 2028 dev[0].dump_monitor() 2029 interworking_connect(dev[0], bssid, "TTLS") 2030 2031def test_ap_hs20_roaming_partner_preference(dev, apdev): 2032 """Hotspot 2.0 and roaming partner preference""" 2033 check_eap_capa(dev[0], "MSCHAPV2") 2034 params = hs20_ap_params() 2035 params['domain_name'] = "roaming.example.org" 2036 hapd0 = hostapd.add_ap(apdev[0], params) 2037 2038 params = hs20_ap_params() 2039 params['ssid'] = "test-hs20-other" 2040 params['domain_name'] = "roaming.example.net" 2041 hapd1 = hostapd.add_ap(apdev[1], params) 2042 2043 logger.info("Verify default vs. specified preference") 2044 values = default_cred() 2045 values['roaming_partner'] = "roaming.example.net,1,127,*" 2046 policy_test(dev[0], apdev[1], hapd1, values, only_one=False) 2047 values['roaming_partner'] = "roaming.example.net,1,129,*" 2048 policy_test(dev[0], apdev[0], hapd0, values, only_one=False) 2049 2050 logger.info("Verify partial FQDN match") 2051 values['roaming_partner'] = "example.net,0,0,*" 2052 policy_test(dev[0], apdev[1], hapd1, values, only_one=False) 2053 values['roaming_partner'] = "example.net,0,255,*" 2054 policy_test(dev[0], apdev[0], hapd0, values, only_one=False) 2055 2056def test_ap_hs20_max_bss_load(dev, apdev): 2057 """Hotspot 2.0 and maximum BSS load""" 2058 check_eap_capa(dev[0], "MSCHAPV2") 2059 params = hs20_ap_params() 2060 params['bss_load_test'] = "12:200:20000" 2061 hapd0 = hostapd.add_ap(apdev[0], params) 2062 2063 params = hs20_ap_params() 2064 params['ssid'] = "test-hs20-other" 2065 params['bss_load_test'] = "5:20:10000" 2066 hapd1 = hostapd.add_ap(apdev[1], params) 2067 2068 logger.info("Verify maximum BSS load constraint") 2069 values = default_cred() 2070 values['domain'] = "example.com" 2071 values['max_bss_load'] = "100" 2072 events = policy_test(dev[0], apdev[1], hapd1, values, only_one=False) 2073 2074 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e] 2075 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]: 2076 raise Exception("Maximum BSS Load case not noticed") 2077 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e] 2078 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]: 2079 raise Exception("Maximum BSS Load case reported incorrectly") 2080 2081 logger.info("Verify maximum BSS load does not prevent connection") 2082 values['max_bss_load'] = "1" 2083 events = policy_test(dev[0], None, None, values) 2084 2085 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e] 2086 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]: 2087 raise Exception("Maximum BSS Load case not noticed") 2088 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e] 2089 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]: 2090 raise Exception("Maximum BSS Load case not noticed") 2091 2092def test_ap_hs20_max_bss_load2(dev, apdev): 2093 """Hotspot 2.0 and maximum BSS load with one AP not advertising""" 2094 check_eap_capa(dev[0], "MSCHAPV2") 2095 params = hs20_ap_params() 2096 params['bss_load_test'] = "12:200:20000" 2097 hostapd.add_ap(apdev[0], params) 2098 2099 params = hs20_ap_params() 2100 params['ssid'] = "test-hs20-other" 2101 hapd1 = hostapd.add_ap(apdev[1], params) 2102 2103 logger.info("Verify maximum BSS load constraint with AP advertisement") 2104 values = default_cred() 2105 values['domain'] = "example.com" 2106 values['max_bss_load'] = "100" 2107 events = policy_test(dev[0], apdev[1], hapd1, values, only_one=False) 2108 2109 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e] 2110 if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]: 2111 raise Exception("Maximum BSS Load case not noticed") 2112 ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e] 2113 if len(ev) != 1 or "over_max_bss_load=1" in ev[0]: 2114 raise Exception("Maximum BSS Load case reported incorrectly") 2115 2116def test_ap_hs20_max_bss_load_roaming(dev, apdev): 2117 """Hotspot 2.0 and maximum BSS load (roaming)""" 2118 check_eap_capa(dev[0], "MSCHAPV2") 2119 params = hs20_ap_params() 2120 params['bss_load_test'] = "12:200:20000" 2121 hapd0 = hostapd.add_ap(apdev[0], params) 2122 2123 values = default_cred() 2124 values['domain'] = "roaming.example.com" 2125 values['max_bss_load'] = "100" 2126 events = policy_test(dev[0], apdev[0], hapd0, values, only_one=True) 2127 ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e] 2128 if len(ev) != 1: 2129 raise Exception("No INTERWORKING-AP event") 2130 if "over_max_bss_load=1" in ev[0]: 2131 raise Exception("Maximum BSS Load reported for roaming") 2132 2133def test_ap_hs20_multi_cred_sp_prio(dev, apdev): 2134 """Hotspot 2.0 multi-cred sp_priority""" 2135 check_eap_capa(dev[0], "MSCHAPV2") 2136 try: 2137 _test_ap_hs20_multi_cred_sp_prio(dev, apdev) 2138 finally: 2139 dev[0].request("SET external_sim 0") 2140 2141def _test_ap_hs20_multi_cred_sp_prio(dev, apdev): 2142 hlr_auc_gw_available() 2143 bssid = apdev[0]['bssid'] 2144 params = hs20_ap_params() 2145 params['hessid'] = bssid 2146 del params['domain_name'] 2147 params['anqp_3gpp_cell_net'] = "232,01" 2148 hostapd.add_ap(apdev[0], params) 2149 2150 dev[0].hs20_enable() 2151 dev[0].scan_for_bss(bssid, freq="2412") 2152 dev[0].request("SET external_sim 1") 2153 id1 = dev[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM", 2154 'provisioning_sp': "example.com", 2155 'sp_priority' :"1"}) 2156 id2 = dev[0].add_cred_values({'realm': "example.com", 2157 'ca_cert': "auth_serv/ca.pem", 2158 'username': "hs20-test", 2159 'password': "password", 2160 'domain': "example.com", 2161 'provisioning_sp': "example.com", 2162 'sp_priority': "2"}) 2163 dev[0].dump_monitor() 2164 dev[0].scan_for_bss(bssid, freq="2412") 2165 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2166 interworking_ext_sim_auth(dev[0], "SIM") 2167 check_sp_type(dev[0], "unknown") 2168 dev[0].request("REMOVE_NETWORK all") 2169 2170 dev[0].set_cred(id1, "sp_priority", "2") 2171 dev[0].set_cred(id2, "sp_priority", "1") 2172 dev[0].dump_monitor() 2173 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2174 interworking_auth(dev[0], "TTLS") 2175 check_sp_type(dev[0], "unknown") 2176 2177def test_ap_hs20_multi_cred_sp_prio2(dev, apdev): 2178 """Hotspot 2.0 multi-cred sp_priority with two BSSes""" 2179 check_eap_capa(dev[0], "MSCHAPV2") 2180 try: 2181 _test_ap_hs20_multi_cred_sp_prio2(dev, apdev) 2182 finally: 2183 dev[0].request("SET external_sim 0") 2184 2185def _test_ap_hs20_multi_cred_sp_prio2(dev, apdev): 2186 hlr_auc_gw_available() 2187 bssid = apdev[0]['bssid'] 2188 params = hs20_ap_params() 2189 params['hessid'] = bssid 2190 del params['nai_realm'] 2191 del params['domain_name'] 2192 params['anqp_3gpp_cell_net'] = "232,01" 2193 hostapd.add_ap(apdev[0], params) 2194 2195 bssid2 = apdev[1]['bssid'] 2196 params = hs20_ap_params() 2197 params['ssid'] = "test-hs20-other" 2198 params['hessid'] = bssid2 2199 del params['domain_name'] 2200 del params['anqp_3gpp_cell_net'] 2201 hostapd.add_ap(apdev[1], params) 2202 2203 dev[0].hs20_enable() 2204 dev[0].request("SET external_sim 1") 2205 id1 = dev[0].add_cred_values({'imsi': "23201-0000000000", 'eap': "SIM", 2206 'provisioning_sp': "example.com", 2207 'sp_priority': "1"}) 2208 id2 = dev[0].add_cred_values({'realm': "example.com", 2209 'ca_cert': "auth_serv/ca.pem", 2210 'username': "hs20-test", 2211 'password': "password", 2212 'domain': "example.com", 2213 'provisioning_sp': "example.com", 2214 'sp_priority': "2"}) 2215 dev[0].dump_monitor() 2216 dev[0].scan_for_bss(bssid, freq="2412") 2217 dev[0].scan_for_bss(bssid2, freq="2412") 2218 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2219 interworking_ext_sim_auth(dev[0], "SIM") 2220 check_sp_type(dev[0], "unknown") 2221 conn_bssid = dev[0].get_status_field("bssid") 2222 if conn_bssid != bssid: 2223 raise Exception("Connected to incorrect BSS") 2224 dev[0].request("REMOVE_NETWORK all") 2225 2226 dev[0].set_cred(id1, "sp_priority", "2") 2227 dev[0].set_cred(id2, "sp_priority", "1") 2228 dev[0].dump_monitor() 2229 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2230 interworking_auth(dev[0], "TTLS") 2231 check_sp_type(dev[0], "unknown") 2232 conn_bssid = dev[0].get_status_field("bssid") 2233 if conn_bssid != bssid2: 2234 raise Exception("Connected to incorrect BSS") 2235 2236def test_ap_hs20_multi_cred_sp_prio_same(dev, apdev): 2237 """Hotspot 2.0 multi-cred and same sp_priority""" 2238 check_eap_capa(dev[0], "MSCHAPV2") 2239 hlr_auc_gw_available() 2240 bssid = apdev[0]['bssid'] 2241 params = hs20_ap_params() 2242 params['hessid'] = bssid 2243 del params['domain_name'] 2244 params['anqp_3gpp_cell_net'] = "232,01" 2245 hostapd.add_ap(apdev[0], params) 2246 2247 dev[0].hs20_enable() 2248 dev[0].scan_for_bss(bssid, freq="2412") 2249 id1 = dev[0].add_cred_values({'realm': "example.com", 2250 'ca_cert': "auth_serv/ca.pem", 2251 'username': "hs20-test", 2252 'password': "password", 2253 'domain': "domain1.example.com", 2254 'provisioning_sp': "example.com", 2255 'sp_priority': "1"}) 2256 id2 = dev[0].add_cred_values({'realm': "example.com", 2257 'ca_cert': "auth_serv/ca.pem", 2258 'username': "hs20-test", 2259 'password': "password", 2260 'domain': "domain2.example.com", 2261 'provisioning_sp': "example.com", 2262 'sp_priority': "1"}) 2263 dev[0].dump_monitor() 2264 dev[0].scan_for_bss(bssid, freq="2412") 2265 check_auto_select(dev[0], bssid) 2266 2267def check_conn_capab_selection(dev, type, missing): 2268 dev.request("INTERWORKING_SELECT freq=2412") 2269 ev = dev.wait_event(["INTERWORKING-AP"]) 2270 if ev is None: 2271 raise Exception("Network selection timed out") 2272 if "type=" + type not in ev: 2273 raise Exception("Unexpected network type") 2274 if missing and "conn_capab_missing=1" not in ev: 2275 raise Exception("conn_capab_missing not reported") 2276 if not missing and "conn_capab_missing=1" in ev: 2277 raise Exception("conn_capab_missing reported unexpectedly") 2278 2279def conn_capab_cred(domain=None, req_conn_capab=None): 2280 cred = default_cred(domain=domain) 2281 if req_conn_capab: 2282 cred['req_conn_capab'] = req_conn_capab 2283 return cred 2284 2285def test_ap_hs20_req_conn_capab(dev, apdev): 2286 """Hotspot 2.0 network selection with req_conn_capab""" 2287 check_eap_capa(dev[0], "MSCHAPV2") 2288 bssid = apdev[0]['bssid'] 2289 params = hs20_ap_params() 2290 hapd = hostapd.add_ap(apdev[0], params) 2291 2292 dev[0].hs20_enable() 2293 dev[0].scan_for_bss(bssid, freq="2412") 2294 logger.info("Not used in home network") 2295 values = conn_capab_cred(domain="example.com", req_conn_capab="6:1234") 2296 id = dev[0].add_cred_values(values) 2297 check_conn_capab_selection(dev[0], "home", False) 2298 2299 logger.info("Used in roaming network") 2300 dev[0].remove_cred(id) 2301 values = conn_capab_cred(domain="example.org", req_conn_capab="6:1234") 2302 id = dev[0].add_cred_values(values) 2303 check_conn_capab_selection(dev[0], "roaming", True) 2304 2305 logger.info("Verify that req_conn_capab does not prevent connection if no other network is available") 2306 check_auto_select(dev[0], bssid, hapd=hapd) 2307 2308 logger.info("Additional req_conn_capab checks") 2309 2310 dev[0].remove_cred(id) 2311 values = conn_capab_cred(domain="example.org", req_conn_capab="1:0") 2312 id = dev[0].add_cred_values(values) 2313 check_conn_capab_selection(dev[0], "roaming", True) 2314 2315 dev[0].remove_cred(id) 2316 values = conn_capab_cred(domain="example.org", req_conn_capab="17:5060") 2317 id = dev[0].add_cred_values(values) 2318 check_conn_capab_selection(dev[0], "roaming", True) 2319 2320 bssid2 = apdev[1]['bssid'] 2321 params = hs20_ap_params(ssid="test-hs20b") 2322 params['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0", "50:0:1"] 2323 hostapd.add_ap(apdev[1], params) 2324 2325 dev[0].remove_cred(id) 2326 values = conn_capab_cred(domain="example.org", req_conn_capab="50") 2327 id = dev[0].add_cred_values(values) 2328 dev[0].set_cred(id, "req_conn_capab", "6:22") 2329 dev[0].scan_for_bss(bssid2, freq="2412") 2330 dev[0].request("INTERWORKING_SELECT freq=2412") 2331 for i in range(0, 2): 2332 ev = dev[0].wait_event(["INTERWORKING-AP"]) 2333 if ev is None: 2334 raise Exception("Network selection timed out") 2335 if bssid in ev and "conn_capab_missing=1" not in ev: 2336 raise Exception("Missing protocol connection capability not reported") 2337 if bssid2 in ev and "conn_capab_missing=1" in ev: 2338 raise Exception("Protocol connection capability not reported correctly") 2339 2340def test_ap_hs20_req_conn_capab2(dev, apdev): 2341 """Hotspot 2.0 network selection with req_conn_capab (not present)""" 2342 check_eap_capa(dev[0], "MSCHAPV2") 2343 bssid = apdev[0]['bssid'] 2344 params = hs20_ap_params() 2345 del params['hs20_conn_capab'] 2346 hostapd.add_ap(apdev[0], params) 2347 2348 dev[0].hs20_enable() 2349 dev[0].scan_for_bss(bssid, freq="2412") 2350 values = conn_capab_cred(domain="example.org", req_conn_capab="6:1234") 2351 id = dev[0].add_cred_values(values) 2352 check_conn_capab_selection(dev[0], "roaming", False) 2353 2354def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev, apdev): 2355 """Hotspot 2.0 and req_conn_capab with roaming partner preference""" 2356 check_eap_capa(dev[0], "MSCHAPV2") 2357 bssid = apdev[0]['bssid'] 2358 params = hs20_ap_params() 2359 params['domain_name'] = "roaming.example.org" 2360 params['hs20_conn_capab'] = ["1:0:2", "6:22:1", "17:5060:0", "50:0:1"] 2361 hapd = hostapd.add_ap(apdev[0], params) 2362 2363 bssid2 = apdev[1]['bssid'] 2364 params = hs20_ap_params(ssid="test-hs20-b") 2365 params['domain_name'] = "roaming.example.net" 2366 hapd2 = hostapd.add_ap(apdev[1], params) 2367 2368 values = default_cred() 2369 values['roaming_partner'] = "roaming.example.net,1,127,*" 2370 id = dev[0].add_cred_values(values) 2371 check_auto_select(dev[0], bssid2, hapd=hapd2) 2372 2373 dev[0].set_cred(id, "req_conn_capab", "50") 2374 check_auto_select(dev[0], bssid, hapd=hapd) 2375 2376 dev[0].remove_cred(id) 2377 id = dev[0].add_cred_values(values) 2378 dev[0].set_cred(id, "req_conn_capab", "51") 2379 check_auto_select(dev[0], bssid2, hapd=hapd2) 2380 2381def check_bandwidth_selection(dev, type, below): 2382 dev.request("INTERWORKING_SELECT freq=2412") 2383 ev = dev.wait_event(["INTERWORKING-AP"]) 2384 if ev is None: 2385 raise Exception("Network selection timed out") 2386 logger.debug("BSS entries:\n" + dev.request("BSS RANGE=ALL")) 2387 if "type=" + type not in ev: 2388 raise Exception("Unexpected network type") 2389 if below and "below_min_backhaul=1" not in ev: 2390 raise Exception("below_min_backhaul not reported") 2391 if not below and "below_min_backhaul=1" in ev: 2392 raise Exception("below_min_backhaul reported unexpectedly") 2393 2394def bw_cred(domain=None, dl_home=None, ul_home=None, dl_roaming=None, ul_roaming=None): 2395 cred = default_cred(domain=domain) 2396 if dl_home: 2397 cred['min_dl_bandwidth_home'] = str(dl_home) 2398 if ul_home: 2399 cred['min_ul_bandwidth_home'] = str(ul_home) 2400 if dl_roaming: 2401 cred['min_dl_bandwidth_roaming'] = str(dl_roaming) 2402 if ul_roaming: 2403 cred['min_ul_bandwidth_roaming'] = str(ul_roaming) 2404 return cred 2405 2406def test_ap_hs20_min_bandwidth_home(dev, apdev): 2407 """Hotspot 2.0 network selection with min bandwidth (home)""" 2408 check_eap_capa(dev[0], "MSCHAPV2") 2409 bssid = apdev[0]['bssid'] 2410 params = hs20_ap_params() 2411 hapd = hostapd.add_ap(apdev[0], params) 2412 2413 dev[0].hs20_enable() 2414 dev[0].scan_for_bss(bssid, freq="2412") 2415 values = bw_cred(domain="example.com", dl_home=5490, ul_home=58) 2416 id = dev[0].add_cred_values(values) 2417 check_bandwidth_selection(dev[0], "home", False) 2418 dev[0].remove_cred(id) 2419 2420 values = bw_cred(domain="example.com", dl_home=5491, ul_home=58) 2421 id = dev[0].add_cred_values(values) 2422 check_bandwidth_selection(dev[0], "home", True) 2423 dev[0].remove_cred(id) 2424 2425 values = bw_cred(domain="example.com", dl_home=5490, ul_home=59) 2426 id = dev[0].add_cred_values(values) 2427 check_bandwidth_selection(dev[0], "home", True) 2428 dev[0].remove_cred(id) 2429 2430 values = bw_cred(domain="example.com", dl_home=5491, ul_home=59) 2431 id = dev[0].add_cred_values(values) 2432 check_bandwidth_selection(dev[0], "home", True) 2433 check_auto_select(dev[0], bssid, hapd=hapd) 2434 2435 bssid2 = apdev[1]['bssid'] 2436 params = hs20_ap_params(ssid="test-hs20-b") 2437 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000" 2438 hapd2 = hostapd.add_ap(apdev[1], params) 2439 2440 check_auto_select(dev[0], bssid2, hapd=hapd2) 2441 2442def test_ap_hs20_min_bandwidth_home2(dev, apdev): 2443 """Hotspot 2.0 network selection with min bandwidth - special cases""" 2444 check_eap_capa(dev[0], "MSCHAPV2") 2445 bssid = apdev[0]['bssid'] 2446 params = hs20_ap_params() 2447 hapd = hostapd.add_ap(apdev[0], params) 2448 2449 dev[0].hs20_enable() 2450 dev[0].scan_for_bss(bssid, freq="2412") 2451 values = bw_cred(domain="example.com", dl_home=5490, ul_home=58) 2452 id = dev[0].add_cred_values(values) 2453 check_bandwidth_selection(dev[0], "home", False) 2454 2455 logger.info("WAN link at capacity") 2456 hapd.set('hs20_wan_metrics', "09:8000:1000:80:240:3000") 2457 check_bandwidth_selection(dev[0], "home", True) 2458 2459 logger.info("Downlink/Uplink Load was not measured") 2460 hapd.set('hs20_wan_metrics', "01:8000:1000:80:240:0") 2461 check_bandwidth_selection(dev[0], "home", False) 2462 2463 logger.info("Uplink and Downlink max values") 2464 hapd.set('hs20_wan_metrics', "01:4294967295:4294967295:80:240:3000") 2465 check_bandwidth_selection(dev[0], "home", False) 2466 2467 dev[0].remove_cred(id) 2468 2469def test_ap_hs20_min_bandwidth_home_hidden_ssid_in_scan_res(dev, apdev): 2470 """Hotspot 2.0 network selection with min bandwidth (home) while hidden SSID is included in scan results""" 2471 check_eap_capa(dev[0], "MSCHAPV2") 2472 bssid = apdev[0]['bssid'] 2473 2474 hapd = hostapd.add_ap(apdev[0], {"ssid": 'secret', 2475 "ignore_broadcast_ssid": "1"}) 2476 dev[0].scan_for_bss(bssid, freq=2412) 2477 hapd.disable() 2478 hapd_global = hostapd.HostapdGlobal(apdev[0]) 2479 hapd_global.flush() 2480 hapd_global.remove(apdev[0]['ifname']) 2481 2482 params = hs20_ap_params() 2483 hapd = hostapd.add_ap(apdev[0], params) 2484 2485 dev[0].hs20_enable() 2486 dev[0].scan_for_bss(bssid, freq="2412") 2487 values = bw_cred(domain="example.com", dl_home=5490, ul_home=58) 2488 id = dev[0].add_cred_values(values) 2489 check_bandwidth_selection(dev[0], "home", False) 2490 dev[0].remove_cred(id) 2491 2492 values = bw_cred(domain="example.com", dl_home=5491, ul_home=58) 2493 id = dev[0].add_cred_values(values) 2494 check_bandwidth_selection(dev[0], "home", True) 2495 dev[0].remove_cred(id) 2496 2497 values = bw_cred(domain="example.com", dl_home=5490, ul_home=59) 2498 id = dev[0].add_cred_values(values) 2499 check_bandwidth_selection(dev[0], "home", True) 2500 dev[0].remove_cred(id) 2501 2502 values = bw_cred(domain="example.com", dl_home=5491, ul_home=59) 2503 id = dev[0].add_cred_values(values) 2504 check_bandwidth_selection(dev[0], "home", True) 2505 check_auto_select(dev[0], bssid, hapd=hapd) 2506 2507 bssid2 = apdev[1]['bssid'] 2508 params = hs20_ap_params(ssid="test-hs20-b") 2509 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000" 2510 hapd2 = hostapd.add_ap(apdev[1], params) 2511 2512 check_auto_select(dev[0], bssid2, hapd=hapd2) 2513 2514 dev[0].flush_scan_cache() 2515 2516def test_ap_hs20_min_bandwidth_roaming(dev, apdev): 2517 """Hotspot 2.0 network selection with min bandwidth (roaming)""" 2518 check_eap_capa(dev[0], "MSCHAPV2") 2519 bssid = apdev[0]['bssid'] 2520 params = hs20_ap_params() 2521 hapd = hostapd.add_ap(apdev[0], params) 2522 2523 dev[0].hs20_enable() 2524 dev[0].scan_for_bss(bssid, freq="2412") 2525 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=58) 2526 id = dev[0].add_cred_values(values) 2527 check_bandwidth_selection(dev[0], "roaming", False) 2528 dev[0].remove_cred(id) 2529 2530 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=58) 2531 id = dev[0].add_cred_values(values) 2532 check_bandwidth_selection(dev[0], "roaming", True) 2533 dev[0].remove_cred(id) 2534 2535 values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=59) 2536 id = dev[0].add_cred_values(values) 2537 check_bandwidth_selection(dev[0], "roaming", True) 2538 dev[0].remove_cred(id) 2539 2540 values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=59) 2541 id = dev[0].add_cred_values(values) 2542 check_bandwidth_selection(dev[0], "roaming", True) 2543 check_auto_select(dev[0], bssid, hapd=hapd) 2544 2545 bssid2 = apdev[1]['bssid'] 2546 params = hs20_ap_params(ssid="test-hs20-b") 2547 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000" 2548 hapd2 = hostapd.add_ap(apdev[1], params) 2549 2550 check_auto_select(dev[0], bssid2, hapd=hapd2) 2551 2552def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev, apdev): 2553 """Hotspot 2.0 and minimum bandwidth with roaming partner preference""" 2554 check_eap_capa(dev[0], "MSCHAPV2") 2555 bssid = apdev[0]['bssid'] 2556 params = hs20_ap_params() 2557 params['domain_name'] = "roaming.example.org" 2558 params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000" 2559 hapd = hostapd.add_ap(apdev[0], params) 2560 2561 bssid2 = apdev[1]['bssid'] 2562 params = hs20_ap_params(ssid="test-hs20-b") 2563 params['domain_name'] = "roaming.example.net" 2564 hapd2 = hostapd.add_ap(apdev[1], params) 2565 2566 values = default_cred() 2567 values['roaming_partner'] = "roaming.example.net,1,127,*" 2568 id = dev[0].add_cred_values(values) 2569 check_auto_select(dev[0], bssid2, hapd=hapd2) 2570 2571 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "6000") 2572 check_auto_select(dev[0], bssid, hapd=hapd) 2573 2574 dev[0].set_cred(id, "min_dl_bandwidth_roaming", "10000") 2575 check_auto_select(dev[0], bssid2, hapd=hapd2) 2576 2577def test_ap_hs20_min_bandwidth_no_wan_metrics(dev, apdev): 2578 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics""" 2579 bssid = apdev[0]['bssid'] 2580 params = hs20_ap_params() 2581 del params['hs20_wan_metrics'] 2582 hostapd.add_ap(apdev[0], params) 2583 2584 dev[0].hs20_enable() 2585 dev[0].scan_for_bss(bssid, freq="2412") 2586 values = bw_cred(domain="example.com", dl_home=10000, ul_home=10000, 2587 dl_roaming=10000, ul_roaming=10000) 2588 dev[0].add_cred_values(values) 2589 check_bandwidth_selection(dev[0], "home", False) 2590 2591def test_ap_hs20_deauth_req_ess(dev, apdev): 2592 """Hotspot 2.0 connection and deauthentication request for ESS""" 2593 check_eap_capa(dev[0], "MSCHAPV2") 2594 try: 2595 _test_ap_hs20_deauth_req_ess(dev, apdev) 2596 finally: 2597 dev[0].request("SET pmf 0") 2598 2599def _test_ap_hs20_deauth_req_ess(dev, apdev): 2600 dev[0].request("SET pmf 2") 2601 hapd = eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user") 2602 dev[0].dump_monitor() 2603 addr = dev[0].p2p_interface_addr() 2604 hapd.wait_sta() 2605 hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/") 2606 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"]) 2607 if ev is None: 2608 raise Exception("Timeout on deauth imminent notice") 2609 if "1 120 http://example.com/" not in ev: 2610 raise Exception("Unexpected deauth imminent notice: " + ev) 2611 hapd.request("DEAUTHENTICATE " + addr) 2612 dev[0].wait_disconnected(timeout=10) 2613 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']: 2614 raise Exception("Network not marked temporarily disabled") 2615 ev = dev[0].wait_event(["SME: Trying to authenticate", 2616 "Trying to associate", 2617 "CTRL-EVENT-CONNECTED"], timeout=5) 2618 if ev is not None: 2619 raise Exception("Unexpected connection attempt") 2620 2621def test_ap_hs20_deauth_req_bss(dev, apdev): 2622 """Hotspot 2.0 connection and deauthentication request for BSS""" 2623 check_eap_capa(dev[0], "MSCHAPV2") 2624 try: 2625 _test_ap_hs20_deauth_req_bss(dev, apdev) 2626 finally: 2627 dev[0].request("SET pmf 0") 2628 2629def _test_ap_hs20_deauth_req_bss(dev, apdev): 2630 dev[0].request("SET pmf 2") 2631 hapd = eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user") 2632 dev[0].dump_monitor() 2633 addr = dev[0].p2p_interface_addr() 2634 hapd.wait_sta() 2635 hapd.request("HS20_DEAUTH_REQ " + addr + " 0 120 http://example.com/") 2636 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"]) 2637 if ev is None: 2638 raise Exception("Timeout on deauth imminent notice") 2639 if "0 120 http://example.com/" not in ev: 2640 raise Exception("Unexpected deauth imminent notice: " + ev) 2641 hapd.request("DEAUTHENTICATE " + addr + " reason=4") 2642 ev = dev[0].wait_disconnected(timeout=10) 2643 if "reason=4" not in ev: 2644 raise Exception("Unexpected disconnection reason") 2645 if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']: 2646 raise Exception("Network not marked temporarily disabled") 2647 ev = dev[0].wait_event(["SME: Trying to authenticate", 2648 "Trying to associate", 2649 "CTRL-EVENT-CONNECTED"], timeout=5) 2650 if ev is not None: 2651 raise Exception("Unexpected connection attempt") 2652 2653def test_ap_hs20_deauth_req_from_radius(dev, apdev): 2654 """Hotspot 2.0 connection and deauthentication request from RADIUS""" 2655 check_eap_capa(dev[0], "MSCHAPV2") 2656 try: 2657 _test_ap_hs20_deauth_req_from_radius(dev, apdev) 2658 finally: 2659 dev[0].request("SET pmf 0") 2660 2661def test_ap_hs20_deauth_req_from_radius_url(dev, apdev): 2662 """Hotspot 2.0 connection and deauthentication request from RADIUS with URL""" 2663 check_eap_capa(dev[0], "MSCHAPV2") 2664 try: 2665 _test_ap_hs20_deauth_req_from_radius(dev, apdev, url=True) 2666 finally: 2667 dev[0].set("pmf", "0") 2668 2669def _test_ap_hs20_deauth_req_from_radius(dev, apdev, url=False): 2670 bssid = apdev[0]['bssid'] 2671 params = hs20_ap_params() 2672 params['nai_realm'] = ["0,example.com,21[2:4]"] 2673 params['hs20_deauth_req_timeout'] = "2" 2674 hostapd.add_ap(apdev[0], params) 2675 2676 dev[0].request("SET pmf 2") 2677 dev[0].hs20_enable() 2678 user = "hs20-deauth-test-url" if url else "hs20-deauth-test" 2679 dev[0].add_cred_values({'realm': "example.com", 2680 'username': user, 2681 'password': "password"}) 2682 interworking_select(dev[0], bssid, freq="2412") 2683 interworking_connect(dev[0], bssid, "TTLS") 2684 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout=5) 2685 if ev is None: 2686 raise Exception("Timeout on deauth imminent notice") 2687 if not url and ev.split(' ', 1)[1] != "1 100 ": 2688 raise Exception("Unexpected deauth imminent contents: " + ev) 2689 if url and ev.split(' ', 1)[1] != "0 0 https://example.com/deauth/": 2690 raise Exception("Unexpected deauth imminent contents: " + ev) 2691 dev[0].wait_disconnected(timeout=3 if url else 1) 2692 2693def test_ap_hs20_deauth_req_without_pmf(dev, apdev): 2694 """Hotspot 2.0 connection and deauthentication request without PMF""" 2695 check_eap_capa(dev[0], "MSCHAPV2") 2696 dev[0].request("SET pmf 0") 2697 hapd = eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user", release=1) 2698 dev[0].dump_monitor() 2699 id = int(dev[0].get_status_field("id")) 2700 dev[0].set_network(id, "ieee80211w", "0") 2701 dev[0].request("DISCONNECT") 2702 dev[0].wait_disconnected() 2703 dev[0].select_network(id, freq=2412) 2704 dev[0].wait_connected() 2705 addr = dev[0].own_addr() 2706 hapd.wait_sta() 2707 hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/") 2708 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout=0.2) 2709 if ev is not None: 2710 raise Exception("Deauth imminent notice without PMF accepted") 2711 with alloc_fail(hapd, 1, "wpabuf_alloc;hostapd_ctrl_iface_hs20_deauth_req"): 2712 if "FAIL" not in hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/"): 2713 raise Exception("HS20_DEAUTH_REQ accepted during OOM") 2714 2715def test_ap_hs20_deauth_req_pmf_htc(dev, apdev): 2716 """Hotspot 2.0 connection and deauthentication request PMF misbehavior (+HTC)""" 2717 try: 2718 run_ap_hs20_deauth_req_pmf_htc(dev, apdev) 2719 finally: 2720 stop_monitor(apdev[1]["ifname"]) 2721 2722def run_ap_hs20_deauth_req_pmf_htc(dev, apdev): 2723 check_eap_capa(dev[0], "MSCHAPV2") 2724 dev[0].request("SET pmf 0") 2725 hapd = eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user", release=1) 2726 dev[0].dump_monitor() 2727 addr = dev[0].own_addr() 2728 hapd.wait_sta() 2729 2730 sock = start_monitor(apdev[1]["ifname"]) 2731 radiotap = radiotap_build() 2732 bssid = hapd.own_addr().replace(':', '') 2733 addr = dev[0].own_addr().replace(':', '') 2734 payload = "0a1a0101dd1b506f9a0101780013687474703a2f2f6578616d706c652e636f6d2f" 2735 # Claim there is a HT Control field, but then start the frame body from 2736 # there and do not encrypt the Robust Action frame. 2737 frame = binascii.unhexlify("d0803a01" + addr + 2 * bssid + "0000" + payload) 2738 # Claim there is a HT Control field and start the frame body in the correct 2739 # location, but do not encrypt the Robust Action frame. Make the first octet 2740 # of HT Control field use a non-robust Action Category value. 2741 frame2 = binascii.unhexlify("d0803a01" + addr + 2 * bssid + "0000" + "04000000" + payload) 2742 2743 sock.send(radiotap + frame) 2744 sock.send(radiotap + frame2) 2745 2746 ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout=1) 2747 if ev is not None: 2748 raise Exception("Deauth imminent notice without PMF accepted") 2749 2750def test_ap_hs20_session_info(dev, apdev): 2751 """Hotspot 2.0 connection and session information from RADIUS""" 2752 check_eap_capa(dev[0], "MSCHAPV2") 2753 try: 2754 _test_ap_hs20_session_info(dev, apdev) 2755 finally: 2756 dev[0].request("SET pmf 0") 2757 2758def _test_ap_hs20_session_info(dev, apdev): 2759 bssid = apdev[0]['bssid'] 2760 params = hs20_ap_params() 2761 params['nai_realm'] = ["0,example.com,21[2:4]"] 2762 hostapd.add_ap(apdev[0], params) 2763 2764 dev[0].request("SET pmf 1") 2765 dev[0].hs20_enable() 2766 dev[0].add_cred_values({'realm': "example.com", 2767 'username': "hs20-session-info-test", 2768 'password': "password"}) 2769 interworking_select(dev[0], bssid, freq="2412") 2770 interworking_connect(dev[0], bssid, "TTLS") 2771 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout=10) 2772 if ev is None: 2773 raise Exception("Timeout on ESS disassociation imminent notice") 2774 if " 1 59904 https://example.com/" not in ev: 2775 raise Exception("Unexpected ESS disassociation imminent event contents") 2776 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"]) 2777 if ev is None: 2778 raise Exception("Scan not started") 2779 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=30) 2780 if ev is None: 2781 raise Exception("Scan not completed") 2782 2783def test_ap_hs20_network_preference(dev, apdev): 2784 """Hotspot 2.0 network selection with preferred home network""" 2785 check_eap_capa(dev[0], "MSCHAPV2") 2786 dev[0].flush_scan_cache() 2787 bssid = apdev[0]['bssid'] 2788 params = hs20_ap_params() 2789 hostapd.add_ap(apdev[0], params) 2790 2791 dev[0].hs20_enable() 2792 values = {'realm': "example.com", 2793 'username': "hs20-test", 2794 'password': "password", 2795 'domain': "example.com"} 2796 dev[0].add_cred_values(values) 2797 2798 id = dev[0].add_network() 2799 dev[0].set_network_quoted(id, "ssid", "home") 2800 dev[0].set_network_quoted(id, "psk", "12345678") 2801 dev[0].set_network(id, "priority", "1") 2802 dev[0].request("ENABLE_NETWORK %s no-connect" % id) 2803 2804 dev[0].scan_for_bss(bssid, freq="2412") 2805 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2806 ev = dev[0].wait_connected(timeout=15) 2807 if bssid not in ev: 2808 raise Exception("Unexpected network selected") 2809 2810 bssid2 = apdev[1]['bssid'] 2811 params = hostapd.wpa2_params(ssid="home", passphrase="12345678") 2812 hostapd.add_ap(apdev[1], params) 2813 2814 dev[0].scan_for_bss(bssid2, freq="2412") 2815 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2816 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2817 "INTERWORKING-ALREADY-CONNECTED"], timeout=15) 2818 if ev is None: 2819 raise Exception("Connection timed out") 2820 if "INTERWORKING-ALREADY-CONNECTED" in ev: 2821 raise Exception("No roam to higher priority network") 2822 if bssid2 not in ev: 2823 raise Exception("Unexpected network selected") 2824 2825def test_ap_hs20_network_preference2(dev, apdev): 2826 """Hotspot 2.0 network selection with preferred credential""" 2827 check_eap_capa(dev[0], "MSCHAPV2") 2828 dev[0].flush_scan_cache() 2829 bssid2 = apdev[1]['bssid'] 2830 params = hostapd.wpa2_params(ssid="home", passphrase="12345678") 2831 hostapd.add_ap(apdev[1], params) 2832 2833 dev[0].hs20_enable() 2834 values = {'realm': "example.com", 2835 'username': "hs20-test", 2836 'password': "password", 2837 'domain': "example.com", 2838 'priority': "1"} 2839 dev[0].add_cred_values(values) 2840 2841 id = dev[0].add_network() 2842 dev[0].set_network_quoted(id, "ssid", "home") 2843 dev[0].set_network_quoted(id, "psk", "12345678") 2844 dev[0].request("ENABLE_NETWORK %s no-connect" % id) 2845 2846 dev[0].scan_for_bss(bssid2, freq="2412") 2847 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2848 ev = dev[0].wait_connected(timeout=15) 2849 if bssid2 not in ev: 2850 raise Exception("Unexpected network selected") 2851 2852 bssid = apdev[0]['bssid'] 2853 params = hs20_ap_params() 2854 hostapd.add_ap(apdev[0], params) 2855 2856 dev[0].scan_for_bss(bssid, freq="2412") 2857 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2858 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2859 "INTERWORKING-ALREADY-CONNECTED"], timeout=15) 2860 if ev is None: 2861 raise Exception("Connection timed out") 2862 if "INTERWORKING-ALREADY-CONNECTED" in ev: 2863 raise Exception("No roam to higher priority network") 2864 if bssid not in ev: 2865 raise Exception("Unexpected network selected") 2866 2867def test_ap_hs20_network_preference3(dev, apdev): 2868 """Hotspot 2.0 network selection with two credential (one preferred)""" 2869 check_eap_capa(dev[0], "MSCHAPV2") 2870 dev[0].flush_scan_cache() 2871 bssid = apdev[0]['bssid'] 2872 params = hs20_ap_params() 2873 hostapd.add_ap(apdev[0], params) 2874 2875 bssid2 = apdev[1]['bssid'] 2876 params = hs20_ap_params(ssid="test-hs20b") 2877 params['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]" 2878 hostapd.add_ap(apdev[1], params) 2879 2880 dev[0].hs20_enable() 2881 values = {'realm': "example.com", 2882 'username': "hs20-test", 2883 'password': "password", 2884 'priority': "1"} 2885 dev[0].add_cred_values(values) 2886 values = {'realm': "example.org", 2887 'username': "hs20-test", 2888 'password': "password"} 2889 id = dev[0].add_cred_values(values) 2890 2891 dev[0].scan_for_bss(bssid, freq="2412") 2892 dev[0].scan_for_bss(bssid2, freq="2412") 2893 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2894 ev = dev[0].wait_connected(timeout=15) 2895 if bssid not in ev: 2896 raise Exception("Unexpected network selected") 2897 2898 dev[0].set_cred(id, "priority", "2") 2899 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2900 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2901 "INTERWORKING-ALREADY-CONNECTED"], timeout=15) 2902 if ev is None: 2903 raise Exception("Connection timed out") 2904 if "INTERWORKING-ALREADY-CONNECTED" in ev: 2905 raise Exception("No roam to higher priority network") 2906 if bssid2 not in ev: 2907 raise Exception("Unexpected network selected") 2908 2909def test_ap_hs20_network_preference4(dev, apdev): 2910 """Hotspot 2.0 network selection with username vs. SIM credential""" 2911 check_eap_capa(dev[0], "MSCHAPV2") 2912 dev[0].flush_scan_cache() 2913 bssid = apdev[0]['bssid'] 2914 params = hs20_ap_params() 2915 hostapd.add_ap(apdev[0], params) 2916 2917 bssid2 = apdev[1]['bssid'] 2918 params = hs20_ap_params(ssid="test-hs20b") 2919 params['hessid'] = bssid2 2920 params['anqp_3gpp_cell_net'] = "555,444" 2921 params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org" 2922 hostapd.add_ap(apdev[1], params) 2923 2924 dev[0].hs20_enable() 2925 values = {'realm': "example.com", 2926 'username': "hs20-test", 2927 'password': "password", 2928 'priority': "1"} 2929 dev[0].add_cred_values(values) 2930 values = {'imsi': "555444-333222111", 2931 'eap': "SIM", 2932 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"} 2933 id = dev[0].add_cred_values(values) 2934 2935 dev[0].scan_for_bss(bssid, freq="2412") 2936 dev[0].scan_for_bss(bssid2, freq="2412") 2937 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2938 ev = dev[0].wait_connected(timeout=15) 2939 if bssid not in ev: 2940 raise Exception("Unexpected network selected") 2941 2942 dev[0].set_cred(id, "priority", "2") 2943 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2944 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED", 2945 "INTERWORKING-ALREADY-CONNECTED"], timeout=15) 2946 if ev is None: 2947 raise Exception("Connection timed out") 2948 if "INTERWORKING-ALREADY-CONNECTED" in ev: 2949 raise Exception("No roam to higher priority network") 2950 if bssid2 not in ev: 2951 raise Exception("Unexpected network selected") 2952 2953def test_ap_hs20_interworking_select_blocking_scan(dev, apdev): 2954 """Ongoing INTERWORKING_SELECT blocking SCAN""" 2955 check_eap_capa(dev[0], "MSCHAPV2") 2956 bssid = apdev[0]['bssid'] 2957 params = hs20_ap_params() 2958 hostapd.add_ap(apdev[0], params) 2959 2960 dev[0].hs20_enable() 2961 values = {'realm': "example.com", 2962 'username': "hs20-test", 2963 'password': "password", 2964 'domain': "example.com"} 2965 dev[0].add_cred_values(values) 2966 2967 dev[0].scan_for_bss(bssid, freq="2412") 2968 dev[0].request("INTERWORKING_SELECT auto freq=2412") 2969 if "FAIL-BUSY" not in dev[0].request("SCAN"): 2970 raise Exception("Unexpected SCAN command result") 2971 dev[0].wait_connected(timeout=15) 2972 2973def test_ap_hs20_ft(dev, apdev): 2974 """Hotspot 2.0 connection with FT""" 2975 check_eap_capa(dev[0], "MSCHAPV2") 2976 bssid = apdev[0]['bssid'] 2977 params = hs20_ap_params() 2978 params['wpa_key_mgmt'] = "FT-EAP" 2979 params['nas_identifier'] = "nas1.w1.fi" 2980 params['r1_key_holder'] = "000102030405" 2981 params["mobility_domain"] = "a1b2" 2982 params["reassociation_deadline"] = "1000" 2983 hapd = hostapd.add_ap(apdev[0], params) 2984 2985 dev[0].hs20_enable() 2986 id = dev[0].add_cred_values({'realm': "example.com", 2987 'username': "hs20-test", 2988 'password': "password", 2989 'ca_cert': "auth_serv/ca.pem", 2990 'domain': "example.com", 2991 'update_identifier': "1234"}) 2992 interworking_select(dev[0], bssid, "home", freq="2412") 2993 interworking_connect(dev[0], bssid, "TTLS") 2994 dev[0].dump_monitor() 2995 key_mgmt = dev[0].get_status_field("key_mgmt") 2996 if key_mgmt != "FT-EAP": 2997 raise Exception("Unexpected key_mgmt: " + key_mgmt) 2998 # speed up testing by avoiding unnecessary scanning of other channels 2999 nid = dev[0].get_status_field("id") 3000 dev[0].set_network(nid, "scan_freq", "2412") 3001 3002 params = hs20_ap_params() 3003 hapd2 = hostapd.add_ap(apdev[1], params) 3004 3005 hapd.disable() 3006 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=10) 3007 if ev is None: 3008 raise Exception("Disconnection not reported") 3009 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5) 3010 if ev is None: 3011 raise Exception("Connection to AP2 not reported") 3012 key_mgmt = dev[0].get_status_field("key_mgmt") 3013 if key_mgmt != "WPA2/IEEE 802.1X/EAP": 3014 raise Exception("Unexpected key_mgmt: " + key_mgmt) 3015 3016def test_ap_hs20_external_selection(dev, apdev): 3017 """Hotspot 2.0 connection using external network selection and creation""" 3018 check_eap_capa(dev[0], "MSCHAPV2") 3019 bssid = apdev[0]['bssid'] 3020 params = hs20_ap_params() 3021 params['hessid'] = bssid 3022 params['disable_dgaf'] = '1' 3023 hostapd.add_ap(apdev[0], params) 3024 3025 dev[0].hs20_enable() 3026 dev[0].connect("test-hs20", proto="RSN", key_mgmt="WPA-EAP", eap="TTLS", 3027 ieee80211w="1", 3028 identity="hs20-test", password="password", 3029 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 3030 scan_freq="2412", update_identifier="54321", 3031 roaming_consortium_selection="1020304050") 3032 if dev[0].get_status_field("hs20") != "3": 3033 raise Exception("Unexpected hs20 indication") 3034 network_id = dev[0].get_status_field("id") 3035 sel = dev[0].get_network(network_id, "roaming_consortium_selection") 3036 if sel != "1020304050": 3037 raise Exception("Unexpected roaming_consortium_selection value: " + sel) 3038 3039def test_ap_hs20_random_mac_addr(dev, apdev): 3040 """Hotspot 2.0 connection with random MAC address""" 3041 check_eap_capa(dev[0], "MSCHAPV2") 3042 bssid = apdev[0]['bssid'] 3043 params = hs20_ap_params() 3044 params['hessid'] = bssid 3045 params['disable_dgaf'] = '1' 3046 hapd = hostapd.add_ap(apdev[0], params) 3047 3048 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 3049 wpas.interface_add("wlan5") 3050 addr = wpas.p2p_interface_addr() 3051 wpas.request("SET mac_addr 1") 3052 wpas.request("SET preassoc_mac_addr 1") 3053 wpas.request("SET rand_addr_lifetime 60") 3054 wpas.hs20_enable() 3055 wpas.flush_scan_cache() 3056 id = wpas.add_cred_values({'realm': "example.com", 3057 'username': "hs20-test", 3058 'password': "password", 3059 'ca_cert': "auth_serv/ca.pem", 3060 'domain': "example.com", 3061 'update_identifier': "1234"}) 3062 interworking_select(wpas, bssid, "home", freq="2412") 3063 interworking_connect(wpas, bssid, "TTLS") 3064 addr1 = wpas.get_driver_status_field("addr") 3065 if addr == addr1: 3066 raise Exception("Did not use random MAC address") 3067 3068 sta = hapd.get_sta(addr) 3069 if sta['addr'] != "FAIL": 3070 raise Exception("Unexpected STA association with permanent address") 3071 sta = hapd.get_sta(addr1) 3072 if sta['addr'] != addr1: 3073 raise Exception("STA association with random address not found") 3074 3075def test_ap_hs20_multi_network_and_cred_removal(dev, apdev): 3076 """Multiple networks and cred removal""" 3077 check_eap_capa(dev[0], "MSCHAPV2") 3078 bssid = apdev[0]['bssid'] 3079 params = hs20_ap_params() 3080 params['nai_realm'] = ["0,example.com,25[3:26]"] 3081 hapd = hostapd.add_ap(apdev[0], params) 3082 3083 dev[0].add_network() 3084 dev[0].hs20_enable() 3085 id = dev[0].add_cred_values({'realm': "example.com", 3086 'username': "user", 3087 'password': "password"}) 3088 interworking_select(dev[0], bssid, freq="2412") 3089 interworking_connect(dev[0], bssid, "PEAP") 3090 dev[0].add_network() 3091 3092 dev[0].request("DISCONNECT") 3093 dev[0].wait_disconnected(timeout=10) 3094 3095 hapd.disable() 3096 hapd.set("ssid", "another ssid") 3097 hapd.enable() 3098 3099 interworking_select(dev[0], bssid, freq="2412") 3100 interworking_connect(dev[0], bssid, "PEAP") 3101 dev[0].add_network() 3102 if len(dev[0].list_networks()) != 5: 3103 raise Exception("Unexpected number of networks prior to remove_cred") 3104 3105 dev[0].dump_monitor() 3106 dev[0].remove_cred(id) 3107 if len(dev[0].list_networks()) != 3: 3108 raise Exception("Unexpected number of networks after to remove_cred") 3109 dev[0].wait_disconnected(timeout=10) 3110 3111def test_ap_hs20_interworking_add_network(dev, apdev): 3112 """Hotspot 2.0 connection using INTERWORKING_ADD_NETWORK""" 3113 check_eap_capa(dev[0], "MSCHAPV2") 3114 bssid = apdev[0]['bssid'] 3115 params = hs20_ap_params() 3116 params['nai_realm'] = ["0,example.com,21[3:26][6:7][99:99]"] 3117 hostapd.add_ap(apdev[0], params) 3118 3119 dev[0].hs20_enable() 3120 dev[0].add_cred_values(default_cred(user="user")) 3121 interworking_select(dev[0], bssid, freq=2412) 3122 id = dev[0].interworking_add_network(bssid) 3123 dev[0].select_network(id, freq=2412) 3124 dev[0].wait_connected() 3125 3126def _test_ap_hs20_proxyarp(dev, apdev): 3127 bssid = apdev[0]['bssid'] 3128 params = hs20_ap_params() 3129 params['hessid'] = bssid 3130 params['disable_dgaf'] = '0' 3131 params['proxy_arp'] = '1' 3132 hapd = hostapd.add_ap(apdev[0], params, no_enable=True) 3133 if "OK" in hapd.request("ENABLE"): 3134 raise Exception("Incomplete hostapd configuration was accepted") 3135 hapd.set("ap_isolate", "1") 3136 if "OK" in hapd.request("ENABLE"): 3137 raise Exception("Incomplete hostapd configuration was accepted") 3138 hapd.set('bridge', 'ap-br0') 3139 hapd.dump_monitor() 3140 try: 3141 hapd.enable() 3142 except: 3143 # For now, do not report failures due to missing kernel support 3144 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version") 3145 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10) 3146 if ev is None: 3147 raise Exception("AP startup timed out") 3148 if "AP-ENABLED" not in ev: 3149 raise Exception("AP startup failed") 3150 3151 dev[0].hs20_enable() 3152 subprocess.call(['brctl', 'setfd', 'ap-br0', '0']) 3153 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up']) 3154 3155 id = dev[0].add_cred_values({'realm': "example.com", 3156 'username': "hs20-test", 3157 'password': "password", 3158 'ca_cert': "auth_serv/ca.pem", 3159 'domain': "example.com", 3160 'update_identifier': "1234"}) 3161 interworking_select(dev[0], bssid, "home", freq="2412") 3162 interworking_connect(dev[0], bssid, "TTLS") 3163 3164 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS", 3165 identity="hs20-test", password="password", 3166 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 3167 scan_freq="2412") 3168 time.sleep(0.1) 3169 3170 addr0 = dev[0].p2p_interface_addr() 3171 addr1 = dev[1].p2p_interface_addr() 3172 3173 src_ll_opt0 = b"\x01\x01" + binascii.unhexlify(addr0.replace(':', '')) 3174 src_ll_opt1 = b"\x01\x01" + binascii.unhexlify(addr1.replace(':', '')) 3175 3176 pkt = build_ns(src_ll=addr0, ip_src="aaaa:bbbb:cccc::2", 3177 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:cccc::2", 3178 opt=src_ll_opt0) 3179 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()): 3180 raise Exception("DATA_TEST_FRAME failed") 3181 3182 pkt = build_ns(src_ll=addr1, ip_src="aaaa:bbbb:dddd::2", 3183 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:dddd::2", 3184 opt=src_ll_opt1) 3185 if "OK" not in dev[1].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()): 3186 raise Exception("DATA_TEST_FRAME failed") 3187 3188 pkt = build_ns(src_ll=addr1, ip_src="aaaa:bbbb:eeee::2", 3189 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:eeee::2", 3190 opt=src_ll_opt1) 3191 if "OK" not in dev[1].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()): 3192 raise Exception("DATA_TEST_FRAME failed") 3193 3194 # Wait for frames to be processed 3195 time.sleep(0.1) 3196 3197 matches = get_permanent_neighbors("ap-br0") 3198 logger.info("After connect: " + str(matches)) 3199 if len(matches) != 3: 3200 raise Exception("Unexpected number of neighbor entries after connect") 3201 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches: 3202 raise Exception("dev0 addr missing") 3203 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches: 3204 raise Exception("dev1 addr(1) missing") 3205 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches: 3206 raise Exception("dev1 addr(2) missing") 3207 dev[0].request("DISCONNECT") 3208 dev[1].request("DISCONNECT") 3209 time.sleep(0.5) 3210 matches = get_permanent_neighbors("ap-br0") 3211 logger.info("After disconnect: " + str(matches)) 3212 if len(matches) > 0: 3213 raise Exception("Unexpected neighbor entries after disconnect") 3214 3215def test_ap_hs20_hidden_ssid_in_scan_res(dev, apdev): 3216 """Hotspot 2.0 connection with hidden SSId in scan results""" 3217 check_eap_capa(dev[0], "MSCHAPV2") 3218 bssid = apdev[0]['bssid'] 3219 3220 hapd = hostapd.add_ap(apdev[0], {"ssid": 'secret', 3221 "ignore_broadcast_ssid": "1"}) 3222 dev[0].scan_for_bss(bssid, freq=2412) 3223 hapd.disable() 3224 hapd_global = hostapd.HostapdGlobal(apdev[0]) 3225 hapd_global.flush() 3226 hapd_global.remove(apdev[0]['ifname']) 3227 3228 params = hs20_ap_params() 3229 params['hessid'] = bssid 3230 hapd = hostapd.add_ap(apdev[0], params) 3231 3232 dev[0].hs20_enable() 3233 id = dev[0].add_cred_values({'realm': "example.com", 3234 'username': "hs20-test", 3235 'password': "password", 3236 'ca_cert': "auth_serv/ca.pem", 3237 'domain': "example.com"}) 3238 interworking_select(dev[0], bssid, "home", freq="2412") 3239 interworking_connect(dev[0], bssid, "TTLS") 3240 3241 # clear BSS table to avoid issues in following test cases 3242 dev[0].request("DISCONNECT") 3243 dev[0].wait_disconnected() 3244 hapd.disable() 3245 dev[0].flush_scan_cache() 3246 dev[0].flush_scan_cache() 3247 3248def test_ap_hs20_proxyarp(dev, apdev): 3249 """Hotspot 2.0 and ProxyARP""" 3250 check_eap_capa(dev[0], "MSCHAPV2") 3251 try: 3252 _test_ap_hs20_proxyarp(dev, apdev) 3253 finally: 3254 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'], 3255 stderr=open('/dev/null', 'w')) 3256 subprocess.call(['brctl', 'delbr', 'ap-br0'], 3257 stderr=open('/dev/null', 'w')) 3258 3259def _test_ap_hs20_proxyarp_dgaf(dev, apdev, disabled): 3260 bssid = apdev[0]['bssid'] 3261 params = hs20_ap_params() 3262 params['hessid'] = bssid 3263 params['disable_dgaf'] = '1' if disabled else '0' 3264 params['proxy_arp'] = '1' 3265 params['na_mcast_to_ucast'] = '1' 3266 params['ap_isolate'] = '1' 3267 params['bridge'] = 'ap-br0' 3268 hapd = hostapd.add_ap(apdev[0], params, no_enable=True) 3269 try: 3270 hapd.enable() 3271 except: 3272 # For now, do not report failures due to missing kernel support 3273 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version") 3274 ev = hapd.wait_event(["AP-ENABLED"], timeout=10) 3275 if ev is None: 3276 raise Exception("AP startup timed out") 3277 3278 dev[0].hs20_enable() 3279 subprocess.call(['brctl', 'setfd', 'ap-br0', '0']) 3280 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up']) 3281 3282 id = dev[0].add_cred_values({'realm': "example.com", 3283 'username': "hs20-test", 3284 'password': "password", 3285 'ca_cert': "auth_serv/ca.pem", 3286 'domain': "example.com", 3287 'update_identifier': "1234"}) 3288 interworking_select(dev[0], bssid, "home", freq="2412") 3289 interworking_connect(dev[0], bssid, "TTLS") 3290 3291 dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS", 3292 identity="hs20-test", password="password", 3293 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 3294 scan_freq="2412") 3295 time.sleep(0.1) 3296 3297 addr0 = dev[0].p2p_interface_addr() 3298 3299 src_ll_opt0 = b"\x01\x01" + binascii.unhexlify(addr0.replace(':', '')) 3300 3301 pkt = build_ns(src_ll=addr0, ip_src="aaaa:bbbb:cccc::2", 3302 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:cccc::2", 3303 opt=src_ll_opt0) 3304 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()): 3305 raise Exception("DATA_TEST_FRAME failed") 3306 3307 pkt = build_ra(src_ll=apdev[0]['bssid'], ip_src="aaaa:bbbb:cccc::33", 3308 ip_dst="ff01::1") 3309 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3310 raise Exception("DATA_TEST_FRAME failed") 3311 3312 pkt = build_na(src_ll=apdev[0]['bssid'], ip_src="aaaa:bbbb:cccc::44", 3313 ip_dst="ff01::1", target="aaaa:bbbb:cccc::55") 3314 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3315 raise Exception("DATA_TEST_FRAME failed") 3316 3317 pkt = build_dhcp_ack(dst_ll="ff:ff:ff:ff:ff:ff", src_ll=bssid, 3318 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3319 yiaddr="192.168.1.123", chaddr=addr0) 3320 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3321 raise Exception("DATA_TEST_FRAME failed") 3322 # another copy for additional code coverage 3323 pkt = build_dhcp_ack(dst_ll=addr0, src_ll=bssid, 3324 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3325 yiaddr="192.168.1.123", chaddr=addr0) 3326 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3327 raise Exception("DATA_TEST_FRAME failed") 3328 3329 # Wait for frames to be processed 3330 time.sleep(0.1) 3331 3332 matches = get_permanent_neighbors("ap-br0") 3333 logger.info("After connect: " + str(matches)) 3334 if len(matches) != 2: 3335 raise Exception("Unexpected number of neighbor entries after connect") 3336 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches: 3337 raise Exception("dev0 addr missing") 3338 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches: 3339 raise Exception("dev0 IPv4 addr missing") 3340 dev[0].request("DISCONNECT") 3341 dev[1].request("DISCONNECT") 3342 time.sleep(0.5) 3343 matches = get_permanent_neighbors("ap-br0") 3344 logger.info("After disconnect: " + str(matches)) 3345 if len(matches) > 0: 3346 raise Exception("Unexpected neighbor entries after disconnect") 3347 3348def test_ap_hs20_proxyarp_disable_dgaf(dev, apdev): 3349 """Hotspot 2.0 and ProxyARP with DGAF disabled""" 3350 check_eap_capa(dev[0], "MSCHAPV2") 3351 try: 3352 _test_ap_hs20_proxyarp_dgaf(dev, apdev, True) 3353 finally: 3354 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'], 3355 stderr=open('/dev/null', 'w')) 3356 subprocess.call(['brctl', 'delbr', 'ap-br0'], 3357 stderr=open('/dev/null', 'w')) 3358 3359def test_ap_hs20_proxyarp_enable_dgaf(dev, apdev): 3360 """Hotspot 2.0 and ProxyARP with DGAF enabled""" 3361 check_eap_capa(dev[0], "MSCHAPV2") 3362 try: 3363 _test_ap_hs20_proxyarp_dgaf(dev, apdev, False) 3364 finally: 3365 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'], 3366 stderr=open('/dev/null', 'w')) 3367 subprocess.call(['brctl', 'delbr', 'ap-br0'], 3368 stderr=open('/dev/null', 'w')) 3369 3370def ip_checksum(buf): 3371 sum = 0 3372 if len(buf) & 0x01: 3373 buf += b'\x00' 3374 for i in range(0, len(buf), 2): 3375 val, = struct.unpack('H', buf[i:i+2]) 3376 sum += val 3377 while (sum >> 16): 3378 sum = (sum & 0xffff) + (sum >> 16) 3379 return struct.pack('H', ~sum & 0xffff) 3380 3381def ipv6_solicited_node_mcaddr(target): 3382 prefix = socket.inet_pton(socket.AF_INET6, "ff02::1:ff00:0") 3383 mask = socket.inet_pton(socket.AF_INET6, "::ff:ffff") 3384 _target = socket.inet_pton(socket.AF_INET6, target) 3385 p = struct.unpack('4I', prefix) 3386 m = struct.unpack('4I', mask) 3387 t = struct.unpack('4I', _target) 3388 res = (p[0] | (t[0] & m[0]), 3389 p[1] | (t[1] & m[1]), 3390 p[2] | (t[2] & m[2]), 3391 p[3] | (t[3] & m[3])) 3392 return socket.inet_ntop(socket.AF_INET6, struct.pack('4I', *res)) 3393 3394def build_icmpv6(ipv6_addrs, type, code, payload): 3395 start = struct.pack("BB", type, code) 3396 end = payload 3397 icmp = start + b'\x00\x00' + end 3398 pseudo = ipv6_addrs + struct.pack(">LBBBB", len(icmp), 0, 0, 0, 58) 3399 csum = ip_checksum(pseudo + icmp) 3400 return start + csum + end 3401 3402def build_ra(src_ll, ip_src, ip_dst, cur_hop_limit=0, router_lifetime=0, 3403 reachable_time=0, retrans_timer=0, opt=None): 3404 link_mc = binascii.unhexlify("3333ff000002") 3405 _src_ll = binascii.unhexlify(src_ll.replace(':', '')) 3406 proto = b'\x86\xdd' 3407 ehdr = link_mc + _src_ll + proto 3408 _ip_src = socket.inet_pton(socket.AF_INET6, ip_src) 3409 _ip_dst = socket.inet_pton(socket.AF_INET6, ip_dst) 3410 3411 adv = struct.pack('>BBHLL', cur_hop_limit, 0, router_lifetime, 3412 reachable_time, retrans_timer) 3413 if opt: 3414 payload = adv + opt 3415 else: 3416 payload = adv 3417 icmp = build_icmpv6(_ip_src + _ip_dst, 134, 0, payload) 3418 3419 ipv6 = struct.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp), 58, 255) 3420 ipv6 += _ip_src + _ip_dst 3421 3422 return ehdr + ipv6 + icmp 3423 3424def build_ns(src_ll, ip_src, ip_dst, target, opt=None): 3425 link_mc = binascii.unhexlify("3333ff000002") 3426 _src_ll = binascii.unhexlify(src_ll.replace(':', '')) 3427 proto = b'\x86\xdd' 3428 ehdr = link_mc + _src_ll + proto 3429 _ip_src = socket.inet_pton(socket.AF_INET6, ip_src) 3430 if ip_dst is None: 3431 ip_dst = ipv6_solicited_node_mcaddr(target) 3432 _ip_dst = socket.inet_pton(socket.AF_INET6, ip_dst) 3433 3434 reserved = b'\x00\x00\x00\x00' 3435 _target = socket.inet_pton(socket.AF_INET6, target) 3436 if opt: 3437 payload = reserved + _target + opt 3438 else: 3439 payload = reserved + _target 3440 icmp = build_icmpv6(_ip_src + _ip_dst, 135, 0, payload) 3441 3442 ipv6 = struct.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp), 58, 255) 3443 ipv6 += _ip_src + _ip_dst 3444 3445 return ehdr + ipv6 + icmp 3446 3447def send_ns(dev, src_ll=None, target=None, ip_src=None, ip_dst=None, opt=None, 3448 hapd_bssid=None): 3449 if hapd_bssid: 3450 if src_ll is None: 3451 src_ll = hapd_bssid 3452 cmd = "DATA_TEST_FRAME ifname=ap-br0 " 3453 else: 3454 if src_ll is None: 3455 src_ll = dev.p2p_interface_addr() 3456 cmd = "DATA_TEST_FRAME " 3457 3458 if opt is None: 3459 opt = b"\x01\x01" + binascii.unhexlify(src_ll.replace(':', '')) 3460 3461 pkt = build_ns(src_ll=src_ll, ip_src=ip_src, ip_dst=ip_dst, target=target, 3462 opt=opt) 3463 if "OK" not in dev.request(cmd + binascii.hexlify(pkt).decode()): 3464 raise Exception("DATA_TEST_FRAME failed") 3465 3466def build_na(src_ll, ip_src, ip_dst, target, opt=None, flags=0): 3467 link_mc = binascii.unhexlify("3333ff000002") 3468 _src_ll = binascii.unhexlify(src_ll.replace(':', '')) 3469 proto = b'\x86\xdd' 3470 ehdr = link_mc + _src_ll + proto 3471 _ip_src = socket.inet_pton(socket.AF_INET6, ip_src) 3472 _ip_dst = socket.inet_pton(socket.AF_INET6, ip_dst) 3473 3474 _target = socket.inet_pton(socket.AF_INET6, target) 3475 if opt: 3476 payload = struct.pack('>Bxxx', flags) + _target + opt 3477 else: 3478 payload = struct.pack('>Bxxx', flags) + _target 3479 icmp = build_icmpv6(_ip_src + _ip_dst, 136, 0, payload) 3480 3481 ipv6 = struct.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp), 58, 255) 3482 ipv6 += _ip_src + _ip_dst 3483 3484 return ehdr + ipv6 + icmp 3485 3486def send_na(dev, src_ll=None, target=None, ip_src=None, ip_dst=None, opt=None, 3487 hapd_bssid=None): 3488 if hapd_bssid: 3489 if src_ll is None: 3490 src_ll = hapd_bssid 3491 cmd = "DATA_TEST_FRAME ifname=ap-br0 " 3492 else: 3493 if src_ll is None: 3494 src_ll = dev.p2p_interface_addr() 3495 cmd = "DATA_TEST_FRAME " 3496 3497 pkt = build_na(src_ll=src_ll, ip_src=ip_src, ip_dst=ip_dst, target=target, 3498 opt=opt) 3499 if "OK" not in dev.request(cmd + binascii.hexlify(pkt).decode()): 3500 raise Exception("DATA_TEST_FRAME failed") 3501 3502def build_dhcp_ack(dst_ll, src_ll, ip_src, ip_dst, yiaddr, chaddr, 3503 subnet_mask="255.255.255.0", truncated_opt=False, 3504 wrong_magic=False, force_tot_len=None, no_dhcp=False, 3505 udp_checksum=True): 3506 _dst_ll = binascii.unhexlify(dst_ll.replace(':', '')) 3507 _src_ll = binascii.unhexlify(src_ll.replace(':', '')) 3508 proto = b'\x08\x00' 3509 ehdr = _dst_ll + _src_ll + proto 3510 _ip_src = socket.inet_pton(socket.AF_INET, ip_src) 3511 _ip_dst = socket.inet_pton(socket.AF_INET, ip_dst) 3512 _subnet_mask = socket.inet_pton(socket.AF_INET, subnet_mask) 3513 3514 _ciaddr = b'\x00\x00\x00\x00' 3515 _yiaddr = socket.inet_pton(socket.AF_INET, yiaddr) 3516 _siaddr = b'\x00\x00\x00\x00' 3517 _giaddr = b'\x00\x00\x00\x00' 3518 _chaddr = binascii.unhexlify(chaddr.replace(':', '') + "00000000000000000000") 3519 payload = struct.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0) 3520 payload += _ciaddr + _yiaddr + _siaddr + _giaddr + _chaddr + 192*b'\x00' 3521 # magic 3522 if wrong_magic: 3523 payload += b'\x63\x82\x53\x00' 3524 else: 3525 payload += b'\x63\x82\x53\x63' 3526 if truncated_opt: 3527 payload += b'\x22\xff\x00' 3528 # Option: DHCP Message Type = ACK 3529 payload += b'\x35\x01\x05' 3530 # Pad Option 3531 payload += b'\x00' 3532 # Option: Subnet Mask 3533 payload += b'\x01\x04' + _subnet_mask 3534 # Option: Time Offset 3535 payload += struct.pack('>BBL', 2, 4, 0) 3536 # End Option 3537 payload += b'\xff' 3538 # Pad Option 3539 payload += b'\x00\x00\x00\x00' 3540 3541 if no_dhcp: 3542 payload = struct.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0) 3543 payload += _ciaddr + _yiaddr + _siaddr + _giaddr + _chaddr + 192*b'\x00' 3544 3545 if udp_checksum: 3546 pseudohdr = _ip_src + _ip_dst + struct.pack('>BBH', 0, 17, 3547 8 + len(payload)) 3548 udphdr = struct.pack('>HHHH', 67, 68, 8 + len(payload), 0) 3549 checksum, = struct.unpack('>H', ip_checksum(pseudohdr + udphdr + payload)) 3550 else: 3551 checksum = 0 3552 udp = struct.pack('>HHHH', 67, 68, 8 + len(payload), checksum) + payload 3553 3554 if force_tot_len: 3555 tot_len = force_tot_len 3556 else: 3557 tot_len = 20 + len(udp) 3558 start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17) 3559 ipv4 = start + b'\x00\x00' + _ip_src + _ip_dst 3560 csum = ip_checksum(ipv4) 3561 ipv4 = start + csum + _ip_src + _ip_dst 3562 3563 return ehdr + ipv4 + udp 3564 3565def build_arp(dst_ll, src_ll, opcode, sender_mac, sender_ip, 3566 target_mac, target_ip): 3567 _dst_ll = binascii.unhexlify(dst_ll.replace(':', '')) 3568 _src_ll = binascii.unhexlify(src_ll.replace(':', '')) 3569 proto = b'\x08\x06' 3570 ehdr = _dst_ll + _src_ll + proto 3571 3572 _sender_mac = binascii.unhexlify(sender_mac.replace(':', '')) 3573 _sender_ip = socket.inet_pton(socket.AF_INET, sender_ip) 3574 _target_mac = binascii.unhexlify(target_mac.replace(':', '')) 3575 _target_ip = socket.inet_pton(socket.AF_INET, target_ip) 3576 3577 arp = struct.pack('>HHBBH', 1, 0x0800, 6, 4, opcode) 3578 arp += _sender_mac + _sender_ip 3579 arp += _target_mac + _target_ip 3580 3581 return ehdr + arp 3582 3583def send_arp(dev, dst_ll="ff:ff:ff:ff:ff:ff", src_ll=None, opcode=1, 3584 sender_mac=None, sender_ip="0.0.0.0", 3585 target_mac="00:00:00:00:00:00", target_ip="0.0.0.0", 3586 hapd_bssid=None): 3587 if hapd_bssid: 3588 if src_ll is None: 3589 src_ll = hapd_bssid 3590 if sender_mac is None: 3591 sender_mac = hapd_bssid 3592 cmd = "DATA_TEST_FRAME ifname=ap-br0 " 3593 else: 3594 if src_ll is None: 3595 src_ll = dev.p2p_interface_addr() 3596 if sender_mac is None: 3597 sender_mac = dev.p2p_interface_addr() 3598 cmd = "DATA_TEST_FRAME " 3599 3600 pkt = build_arp(dst_ll=dst_ll, src_ll=src_ll, opcode=opcode, 3601 sender_mac=sender_mac, sender_ip=sender_ip, 3602 target_mac=target_mac, target_ip=target_ip) 3603 if "OK" not in dev.request(cmd + binascii.hexlify(pkt).decode()): 3604 raise Exception("DATA_TEST_FRAME failed") 3605 3606def get_permanent_neighbors(ifname): 3607 cmd = subprocess.Popen(['ip', 'nei'], stdout=subprocess.PIPE) 3608 out, err = cmd.communicate() 3609 res = out.decode() 3610 return [line.strip() for line in res.splitlines() if "PERMANENT" in line and ifname in line] 3611 3612def get_bridge_macs(ifname): 3613 cmd = subprocess.Popen(['brctl', 'showmacs', ifname], 3614 stdout=subprocess.PIPE) 3615 out, err = cmd.communicate() 3616 return out.decode() 3617 3618def tshark_get_arp(cap, filter): 3619 res = run_tshark(cap, filter, 3620 ["eth.dst", "eth.src", 3621 "arp.src.hw_mac", "arp.src.proto_ipv4", 3622 "arp.dst.hw_mac", "arp.dst.proto_ipv4"], 3623 wait=False) 3624 frames = [] 3625 for l in res.splitlines(): 3626 frames.append(l.split('\t')) 3627 return frames 3628 3629def tshark_get_ns(cap): 3630 res = run_tshark(cap, "icmpv6.type == 135", 3631 ["eth.dst", "eth.src", 3632 "ipv6.src", "ipv6.dst", 3633 "icmpv6.nd.ns.target_address", 3634 "icmpv6.opt.linkaddr"], 3635 wait=False) 3636 frames = [] 3637 for l in res.splitlines(): 3638 frames.append(l.split('\t')) 3639 return frames 3640 3641def tshark_get_na(cap): 3642 res = run_tshark(cap, "icmpv6.type == 136", 3643 ["eth.dst", "eth.src", 3644 "ipv6.src", "ipv6.dst", 3645 "icmpv6.nd.na.target_address", 3646 "icmpv6.opt.linkaddr"], 3647 wait=False) 3648 frames = [] 3649 for l in res.splitlines(): 3650 frames.append(l.split('\t')) 3651 return frames 3652 3653def _test_proxyarp_open(dev, apdev, params, ebtables=False): 3654 cap_br = params['prefix'] + ".ap-br0.pcap" 3655 cap_dev0 = params['prefix'] + ".%s.pcap" % dev[0].ifname 3656 cap_dev1 = params['prefix'] + ".%s.pcap" % dev[1].ifname 3657 cap_dev2 = params['prefix'] + ".%s.pcap" % dev[2].ifname 3658 3659 bssid = apdev[0]['bssid'] 3660 params = {'ssid': 'open'} 3661 params['proxy_arp'] = '1' 3662 hapd = hostapd.add_ap(apdev[0], params, no_enable=True) 3663 hapd.set("ap_isolate", "1") 3664 hapd.set('bridge', 'ap-br0') 3665 hapd.dump_monitor() 3666 try: 3667 hapd.enable() 3668 except: 3669 # For now, do not report failures due to missing kernel support 3670 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version") 3671 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10) 3672 if ev is None: 3673 raise Exception("AP startup timed out") 3674 if "AP-ENABLED" not in ev: 3675 raise Exception("AP startup failed") 3676 3677 params2 = {'ssid': 'another'} 3678 hapd2 = hostapd.add_ap(apdev[1], params2, no_enable=True) 3679 hapd2.set('bridge', 'ap-br0') 3680 hapd2.enable() 3681 3682 subprocess.call(['brctl', 'setfd', 'ap-br0', '0']) 3683 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up']) 3684 3685 if ebtables: 3686 for chain in ['FORWARD', 'OUTPUT']: 3687 try: 3688 err = subprocess.call(['ebtables', '-A', chain, '-p', 'ARP', 3689 '-d', 'Broadcast', 3690 '-o', apdev[0]['ifname'], 3691 '-j', 'DROP']) 3692 if err != 0: 3693 raise 3694 except: 3695 raise HwsimSkip("No ebtables available") 3696 3697 time.sleep(0.5) 3698 cmd = {} 3699 cmd[0] = WlantestCapture('ap-br0', cap_br) 3700 cmd[1] = WlantestCapture(dev[0].ifname, cap_dev0) 3701 cmd[2] = WlantestCapture(dev[1].ifname, cap_dev1) 3702 cmd[3] = WlantestCapture(dev[2].ifname, cap_dev2) 3703 3704 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412") 3705 dev[1].connect("open", key_mgmt="NONE", scan_freq="2412") 3706 dev[2].connect("another", key_mgmt="NONE", scan_freq="2412") 3707 time.sleep(1.1) 3708 3709 brcmd = subprocess.Popen(['brctl', 'show'], stdout=subprocess.PIPE) 3710 out, err = brcmd.communicate() 3711 logger.info("Bridge setup: " + out.decode()) 3712 3713 brcmd = subprocess.Popen(['brctl', 'showstp', 'ap-br0'], 3714 stdout=subprocess.PIPE) 3715 out, err = brcmd.communicate() 3716 logger.info("Bridge showstp: " + out.decode()) 3717 3718 addr0 = dev[0].p2p_interface_addr() 3719 addr1 = dev[1].p2p_interface_addr() 3720 addr2 = dev[2].p2p_interface_addr() 3721 3722 pkt = build_dhcp_ack(dst_ll="ff:ff:ff:ff:ff:ff", src_ll=bssid, 3723 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3724 yiaddr="192.168.1.124", chaddr=addr0) 3725 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3726 raise Exception("DATA_TEST_FRAME failed") 3727 # Change address and verify unicast 3728 pkt = build_dhcp_ack(dst_ll=addr0, src_ll=bssid, 3729 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3730 yiaddr="192.168.1.123", chaddr=addr0, 3731 udp_checksum=False) 3732 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3733 raise Exception("DATA_TEST_FRAME failed") 3734 3735 # Not-associated client MAC address 3736 pkt = build_dhcp_ack(dst_ll="ff:ff:ff:ff:ff:ff", src_ll=bssid, 3737 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3738 yiaddr="192.168.1.125", chaddr="22:33:44:55:66:77") 3739 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3740 raise Exception("DATA_TEST_FRAME failed") 3741 3742 # No IP address 3743 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid, 3744 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3745 yiaddr="0.0.0.0", chaddr=addr1) 3746 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3747 raise Exception("DATA_TEST_FRAME failed") 3748 3749 # Zero subnet mask 3750 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid, 3751 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3752 yiaddr="192.168.1.126", chaddr=addr1, 3753 subnet_mask="0.0.0.0") 3754 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3755 raise Exception("DATA_TEST_FRAME failed") 3756 3757 # Truncated option 3758 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid, 3759 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3760 yiaddr="192.168.1.127", chaddr=addr1, 3761 truncated_opt=True) 3762 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3763 raise Exception("DATA_TEST_FRAME failed") 3764 3765 # Wrong magic 3766 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid, 3767 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3768 yiaddr="192.168.1.128", chaddr=addr1, 3769 wrong_magic=True) 3770 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3771 raise Exception("DATA_TEST_FRAME failed") 3772 3773 # Wrong IPv4 total length 3774 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid, 3775 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3776 yiaddr="192.168.1.129", chaddr=addr1, 3777 force_tot_len=1000) 3778 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3779 raise Exception("DATA_TEST_FRAME failed") 3780 3781 # BOOTP 3782 pkt = build_dhcp_ack(dst_ll=addr1, src_ll=bssid, 3783 ip_src="192.168.1.1", ip_dst="255.255.255.255", 3784 yiaddr="192.168.1.129", chaddr=addr1, 3785 no_dhcp=True) 3786 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 3787 raise Exception("DATA_TEST_FRAME failed") 3788 3789 # Wait for frames to be processed 3790 time.sleep(0.1) 3791 3792 macs = get_bridge_macs("ap-br0") 3793 logger.info("After connect (showmacs): " + str(macs)) 3794 3795 matches = get_permanent_neighbors("ap-br0") 3796 logger.info("After connect: " + str(matches)) 3797 if len(matches) != 1: 3798 raise Exception("Unexpected number of neighbor entries after connect") 3799 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches: 3800 raise Exception("dev0 IPv4 addr missing") 3801 3802 targets = ["192.168.1.123", "192.168.1.124", "192.168.1.125", 3803 "192.168.1.126"] 3804 for target in targets: 3805 send_arp(dev[1], sender_ip="192.168.1.100", target_ip=target) 3806 3807 for target in targets: 3808 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.101", 3809 target_ip=target) 3810 3811 for target in targets: 3812 send_arp(dev[2], sender_ip="192.168.1.103", target_ip=target) 3813 3814 # ARP Probe from wireless STA 3815 send_arp(dev[1], target_ip="192.168.1.127") 3816 # ARP Announcement from wireless STA 3817 send_arp(dev[1], sender_ip="192.168.1.127", target_ip="192.168.1.127") 3818 send_arp(dev[1], sender_ip="192.168.1.127", target_ip="192.168.1.127", 3819 opcode=2) 3820 3821 macs = get_bridge_macs("ap-br0") 3822 logger.info("After ARP Probe + Announcement (showmacs): " + str(macs)) 3823 3824 matches = get_permanent_neighbors("ap-br0") 3825 logger.info("After ARP Probe + Announcement: " + str(matches)) 3826 3827 # ARP Request for the newly introduced IP address from wireless STA 3828 send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.127") 3829 3830 # ARP Request for the newly introduced IP address from bridge 3831 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.102", 3832 target_ip="192.168.1.127") 3833 send_arp(dev[2], sender_ip="192.168.1.103", target_ip="192.168.1.127") 3834 3835 # ARP Probe from bridge 3836 send_arp(hapd, hapd_bssid=bssid, target_ip="192.168.1.130") 3837 send_arp(dev[2], target_ip="192.168.1.131") 3838 # ARP Announcement from bridge (not to be learned by AP for proxyarp) 3839 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.130", 3840 target_ip="192.168.1.130") 3841 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.130", 3842 target_ip="192.168.1.130", opcode=2) 3843 send_arp(dev[2], sender_ip="192.168.1.131", target_ip="192.168.1.131") 3844 send_arp(dev[2], sender_ip="192.168.1.131", target_ip="192.168.1.131", 3845 opcode=2) 3846 3847 macs = get_bridge_macs("ap-br0") 3848 logger.info("After ARP Probe + Announcement (showmacs): " + str(macs)) 3849 3850 matches = get_permanent_neighbors("ap-br0") 3851 logger.info("After ARP Probe + Announcement: " + str(matches)) 3852 3853 # ARP Request for the newly introduced IP address from wireless STA 3854 send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.130") 3855 # ARP Response from bridge (AP does not proxy for non-wireless devices) 3856 send_arp(hapd, hapd_bssid=bssid, dst_ll=addr0, sender_ip="192.168.1.130", 3857 target_ip="192.168.1.123", opcode=2) 3858 3859 # ARP Request for the newly introduced IP address from wireless STA 3860 send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.131") 3861 # ARP Response from bridge (AP does not proxy for non-wireless devices) 3862 send_arp(dev[2], dst_ll=addr0, sender_ip="192.168.1.131", 3863 target_ip="192.168.1.123", opcode=2) 3864 3865 # ARP Request for the newly introduced IP address from bridge 3866 send_arp(hapd, hapd_bssid=bssid, sender_ip="192.168.1.102", 3867 target_ip="192.168.1.130") 3868 send_arp(dev[2], sender_ip="192.168.1.104", target_ip="192.168.1.131") 3869 3870 # ARP Probe from wireless STA (duplicate address; learned through DHCP) 3871 send_arp(dev[1], target_ip="192.168.1.123") 3872 # ARP Probe from wireless STA (duplicate address; learned through ARP) 3873 send_arp(dev[0], target_ip="192.168.1.127") 3874 3875 # Gratuitous ARP Reply for another STA's IP address 3876 send_arp(dev[0], opcode=2, sender_mac=addr0, sender_ip="192.168.1.127", 3877 target_mac=addr1, target_ip="192.168.1.127") 3878 send_arp(dev[1], opcode=2, sender_mac=addr1, sender_ip="192.168.1.123", 3879 target_mac=addr0, target_ip="192.168.1.123") 3880 # ARP Request to verify previous mapping 3881 send_arp(dev[1], sender_ip="192.168.1.127", target_ip="192.168.1.123") 3882 send_arp(dev[0], sender_ip="192.168.1.123", target_ip="192.168.1.127") 3883 3884 try: 3885 hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0") 3886 except Exception as e: 3887 logger.info("test_connectibity_iface failed: " + str(e)) 3888 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp") 3889 hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0") 3890 hwsim_utils.test_connectivity(dev[0], dev[1]) 3891 3892 dev[0].request("DISCONNECT") 3893 dev[1].request("DISCONNECT") 3894 time.sleep(1.5) 3895 for i in range(len(cmd)): 3896 cmd[i].close() 3897 time.sleep(0.1) 3898 macs = get_bridge_macs("ap-br0") 3899 logger.info("After disconnect (showmacs): " + str(macs)) 3900 matches = get_permanent_neighbors("ap-br0") 3901 logger.info("After disconnect: " + str(matches)) 3902 if len(matches) > 0: 3903 raise Exception("Unexpected neighbor entries after disconnect") 3904 if ebtables: 3905 cmd = subprocess.Popen(['ebtables', '-L', '--Lc'], 3906 stdout=subprocess.PIPE) 3907 out, err = cmd.communicate() 3908 logger.info("ebtables results:\n" + out.decode()) 3909 3910 # Verify that expected ARP messages were seen and no unexpected 3911 # ARP messages were seen. 3912 3913 arp_req = tshark_get_arp(cap_dev0, "arp.opcode == 1") 3914 arp_reply = tshark_get_arp(cap_dev0, "arp.opcode == 2") 3915 logger.info("dev0 seen ARP requests:\n" + str(arp_req)) 3916 logger.info("dev0 seen ARP replies:\n" + str(arp_reply)) 3917 3918 if ['ff:ff:ff:ff:ff:ff', addr1, 3919 addr1, '192.168.1.100', 3920 '00:00:00:00:00:00', '192.168.1.123'] in arp_req: 3921 raise Exception("dev0 saw ARP request from dev1") 3922 if ['ff:ff:ff:ff:ff:ff', addr2, 3923 addr2, '192.168.1.103', 3924 '00:00:00:00:00:00', '192.168.1.123'] in arp_req: 3925 raise Exception("dev0 saw ARP request from dev2") 3926 # TODO: Uncomment once fixed in kernel 3927 #if ['ff:ff:ff:ff:ff:ff', bssid, 3928 # bssid, '192.168.1.101', 3929 # '00:00:00:00:00:00', '192.168.1.123'] in arp_req: 3930 # raise Exception("dev0 saw ARP request from br") 3931 3932 if ebtables: 3933 for req in arp_req: 3934 if req[1] != addr0: 3935 raise Exception("Unexpected foreign ARP request on dev0") 3936 3937 arp_req = tshark_get_arp(cap_dev1, "arp.opcode == 1") 3938 arp_reply = tshark_get_arp(cap_dev1, "arp.opcode == 2") 3939 logger.info("dev1 seen ARP requests:\n" + str(arp_req)) 3940 logger.info("dev1 seen ARP replies:\n" + str(arp_reply)) 3941 3942 if ['ff:ff:ff:ff:ff:ff', addr2, 3943 addr2, '192.168.1.103', 3944 '00:00:00:00:00:00', '192.168.1.123'] in arp_req: 3945 raise Exception("dev1 saw ARP request from dev2") 3946 if [addr1, addr0, addr0, '192.168.1.123', addr1, '192.168.1.100'] not in arp_reply: 3947 raise Exception("dev1 did not get ARP response for 192.168.1.123") 3948 3949 if ebtables: 3950 for req in arp_req: 3951 if req[1] != addr1: 3952 raise Exception("Unexpected foreign ARP request on dev1") 3953 3954 arp_req = tshark_get_arp(cap_dev2, "arp.opcode == 1") 3955 arp_reply = tshark_get_arp(cap_dev2, "arp.opcode == 2") 3956 logger.info("dev2 seen ARP requests:\n" + str(arp_req)) 3957 logger.info("dev2 seen ARP replies:\n" + str(arp_reply)) 3958 3959 if [addr2, addr0, 3960 addr0, '192.168.1.123', 3961 addr2, '192.168.1.103'] not in arp_reply: 3962 raise Exception("dev2 did not get ARP response for 192.168.1.123") 3963 3964 arp_req = tshark_get_arp(cap_br, "arp.opcode == 1") 3965 arp_reply = tshark_get_arp(cap_br, "arp.opcode == 2") 3966 logger.info("br seen ARP requests:\n" + str(arp_req)) 3967 logger.info("br seen ARP replies:\n" + str(arp_reply)) 3968 3969 # TODO: Uncomment once fixed in kernel 3970 #if [bssid, addr0, 3971 # addr0, '192.168.1.123', 3972 # bssid, '192.168.1.101'] not in arp_reply: 3973 # raise Exception("br did not get ARP response for 192.168.1.123") 3974 3975def _test_proxyarp_open_ipv6(dev, apdev, params, ebtables=False): 3976 cap_br = params['prefix'] + ".ap-br0.pcap" 3977 cap_dev0 = params['prefix'] + ".%s.pcap" % dev[0].ifname 3978 cap_dev1 = params['prefix'] + ".%s.pcap" % dev[1].ifname 3979 cap_dev2 = params['prefix'] + ".%s.pcap" % dev[2].ifname 3980 3981 bssid = apdev[0]['bssid'] 3982 params = {'ssid': 'open'} 3983 params['proxy_arp'] = '1' 3984 hapd = hostapd.add_ap(apdev[0], params, no_enable=True) 3985 hapd.set("ap_isolate", "1") 3986 hapd.set('bridge', 'ap-br0') 3987 hapd.dump_monitor() 3988 try: 3989 hapd.enable() 3990 except: 3991 # For now, do not report failures due to missing kernel support 3992 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version") 3993 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10) 3994 if ev is None: 3995 raise Exception("AP startup timed out") 3996 if "AP-ENABLED" not in ev: 3997 raise Exception("AP startup failed") 3998 3999 params2 = {'ssid': 'another'} 4000 hapd2 = hostapd.add_ap(apdev[1], params2, no_enable=True) 4001 hapd2.set('bridge', 'ap-br0') 4002 hapd2.enable() 4003 4004 subprocess.call(['brctl', 'setfd', 'ap-br0', '0']) 4005 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up']) 4006 4007 if ebtables: 4008 for chain in ['FORWARD', 'OUTPUT']: 4009 try: 4010 err = subprocess.call(['ebtables', '-A', chain, 4011 '-d', 'Multicast', 4012 '-p', 'IPv6', 4013 '--ip6-protocol', 'ipv6-icmp', 4014 '--ip6-icmp-type', 4015 'neighbor-solicitation', 4016 '-o', apdev[0]['ifname'], '-j', 'DROP']) 4017 if err != 0: 4018 raise 4019 subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast', 4020 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp', 4021 '--ip6-icmp-type', 'neighbor-advertisement', 4022 '-o', apdev[0]['ifname'], '-j', 'DROP']) 4023 subprocess.call(['ebtables', '-A', chain, 4024 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp', 4025 '--ip6-icmp-type', 'router-solicitation', 4026 '-o', apdev[0]['ifname'], '-j', 'DROP']) 4027 # Multicast Listener Report Message 4028 subprocess.call(['ebtables', '-A', chain, '-d', 'Multicast', 4029 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp', 4030 '--ip6-icmp-type', '143', 4031 '-o', apdev[0]['ifname'], '-j', 'DROP']) 4032 except: 4033 raise HwsimSkip("No ebtables available") 4034 4035 time.sleep(0.5) 4036 cmd = {} 4037 cmd[0] = WlantestCapture('ap-br0', cap_br) 4038 cmd[1] = WlantestCapture(dev[0].ifname, cap_dev0) 4039 cmd[2] = WlantestCapture(dev[1].ifname, cap_dev1) 4040 cmd[3] = WlantestCapture(dev[2].ifname, cap_dev2) 4041 4042 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412") 4043 dev[1].connect("open", key_mgmt="NONE", scan_freq="2412") 4044 dev[2].connect("another", key_mgmt="NONE", scan_freq="2412") 4045 time.sleep(0.1) 4046 4047 brcmd = subprocess.Popen(['brctl', 'show'], stdout=subprocess.PIPE) 4048 out, err = brcmd.communicate() 4049 logger.info("Bridge setup: " + out.decode()) 4050 4051 brcmd = subprocess.Popen(['brctl', 'showstp', 'ap-br0'], 4052 stdout=subprocess.PIPE) 4053 out, err = brcmd.communicate() 4054 logger.info("Bridge showstp: " + out.decode()) 4055 4056 addr0 = dev[0].p2p_interface_addr() 4057 addr1 = dev[1].p2p_interface_addr() 4058 addr2 = dev[2].p2p_interface_addr() 4059 4060 src_ll_opt0 = b"\x01\x01" + binascii.unhexlify(addr0.replace(':', '')) 4061 src_ll_opt1 = b"\x01\x01" + binascii.unhexlify(addr1.replace(':', '')) 4062 4063 # DAD NS 4064 send_ns(dev[0], ip_src="::", target="aaaa:bbbb:cccc::2") 4065 4066 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2") 4067 # test frame without source link-layer address option 4068 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2", 4069 opt='') 4070 # test frame with bogus option 4071 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2", 4072 opt=b"\x70\x01\x01\x02\x03\x04\x05\x05") 4073 # test frame with truncated source link-layer address option 4074 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2", 4075 opt=b"\x01\x01\x01\x02\x03\x04") 4076 # test frame with foreign source link-layer address option 4077 send_ns(dev[0], ip_src="aaaa:bbbb:cccc::2", target="aaaa:bbbb:cccc::2", 4078 opt=b"\x01\x01\x01\x02\x03\x04\x05\x06") 4079 4080 send_ns(dev[1], ip_src="aaaa:bbbb:dddd::2", target="aaaa:bbbb:dddd::2") 4081 4082 send_ns(dev[1], ip_src="aaaa:bbbb:eeee::2", target="aaaa:bbbb:eeee::2") 4083 # another copy for additional code coverage 4084 send_ns(dev[1], ip_src="aaaa:bbbb:eeee::2", target="aaaa:bbbb:eeee::2") 4085 4086 macs = get_bridge_macs("ap-br0") 4087 logger.info("After connect (showmacs): " + str(macs)) 4088 4089 matches = get_permanent_neighbors("ap-br0") 4090 logger.info("After connect: " + str(matches)) 4091 if len(matches) != 3: 4092 raise Exception("Unexpected number of neighbor entries after connect") 4093 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches: 4094 raise Exception("dev0 addr missing") 4095 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches: 4096 raise Exception("dev1 addr(1) missing") 4097 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches: 4098 raise Exception("dev1 addr(2) missing") 4099 4100 send_ns(dev[0], target="aaaa:bbbb:dddd::2", ip_src="aaaa:bbbb:cccc::2") 4101 time.sleep(0.1) 4102 send_ns(dev[1], target="aaaa:bbbb:cccc::2", ip_src="aaaa:bbbb:dddd::2") 4103 time.sleep(0.1) 4104 send_ns(hapd, hapd_bssid=bssid, target="aaaa:bbbb:dddd::2", 4105 ip_src="aaaa:bbbb:ffff::2") 4106 time.sleep(0.1) 4107 send_ns(dev[2], target="aaaa:bbbb:cccc::2", ip_src="aaaa:bbbb:ff00::2") 4108 time.sleep(0.1) 4109 send_ns(dev[2], target="aaaa:bbbb:dddd::2", ip_src="aaaa:bbbb:ff00::2") 4110 time.sleep(0.1) 4111 send_ns(dev[2], target="aaaa:bbbb:eeee::2", ip_src="aaaa:bbbb:ff00::2") 4112 time.sleep(0.1) 4113 4114 # Try to probe for an already assigned address 4115 send_ns(dev[1], target="aaaa:bbbb:cccc::2", ip_src="::") 4116 time.sleep(0.1) 4117 send_ns(hapd, hapd_bssid=bssid, target="aaaa:bbbb:cccc::2", ip_src="::") 4118 time.sleep(0.1) 4119 send_ns(dev[2], target="aaaa:bbbb:cccc::2", ip_src="::") 4120 time.sleep(0.1) 4121 4122 # Unsolicited NA 4123 send_na(dev[1], target="aaaa:bbbb:cccc:aeae::3", 4124 ip_src="aaaa:bbbb:cccc:aeae::3", ip_dst="ff02::1") 4125 send_na(hapd, hapd_bssid=bssid, target="aaaa:bbbb:cccc:aeae::4", 4126 ip_src="aaaa:bbbb:cccc:aeae::4", ip_dst="ff02::1") 4127 send_na(dev[2], target="aaaa:bbbb:cccc:aeae::5", 4128 ip_src="aaaa:bbbb:cccc:aeae::5", ip_dst="ff02::1") 4129 4130 try: 4131 hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0") 4132 except Exception as e: 4133 logger.info("test_connectibity_iface failed: " + str(e)) 4134 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp") 4135 hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0") 4136 hwsim_utils.test_connectivity(dev[0], dev[1]) 4137 4138 dev[0].request("DISCONNECT") 4139 dev[1].request("DISCONNECT") 4140 time.sleep(0.5) 4141 for i in range(len(cmd)): 4142 cmd[i].close() 4143 macs = get_bridge_macs("ap-br0") 4144 logger.info("After disconnect (showmacs): " + str(macs)) 4145 matches = get_permanent_neighbors("ap-br0") 4146 logger.info("After disconnect: " + str(matches)) 4147 if len(matches) > 0: 4148 raise Exception("Unexpected neighbor entries after disconnect") 4149 if ebtables: 4150 cmd = subprocess.Popen(['ebtables', '-L', '--Lc'], 4151 stdout=subprocess.PIPE) 4152 out, err = cmd.communicate() 4153 logger.info("ebtables results:\n" + out.decode()) 4154 4155 ns = tshark_get_ns(cap_dev0) 4156 logger.info("dev0 seen NS: " + str(ns)) 4157 na = tshark_get_na(cap_dev0) 4158 logger.info("dev0 seen NA: " + str(na)) 4159 4160 if [addr0, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2', 4161 'aaaa:bbbb:dddd::2', addr1] not in na: 4162 # For now, skip the test instead of reporting the error since the IPv6 4163 # proxyarp support is not yet in the upstream kernel tree. 4164 #raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2") 4165 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp (IPv6)") 4166 4167 if ebtables: 4168 for req in ns: 4169 if req[1] == bssid and req[0] == "33:33:ff:" + bssid[9:] and \ 4170 req[3] == 'ff02::1:ff00:300' and req[4] == 'fe80::ff:fe00:300': 4171 # At least for now, ignore this special case until the kernel 4172 # can be prevented from sending it out. 4173 logger.info("dev0: Ignore NS from AP to own local addr: " + str(req)) 4174 elif req[1] != addr0: 4175 raise Exception("Unexpected foreign NS on dev0: " + str(req)) 4176 4177 ns = tshark_get_ns(cap_dev1) 4178 logger.info("dev1 seen NS: " + str(ns)) 4179 na = tshark_get_na(cap_dev1) 4180 logger.info("dev1 seen NA: " + str(na)) 4181 4182 if [addr1, addr0, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:dddd::2', 4183 'aaaa:bbbb:cccc::2', addr0] not in na: 4184 raise Exception("dev1 did not get NA for aaaa:bbbb:cccc::2") 4185 4186 if ebtables: 4187 for req in ns: 4188 if req[1] == bssid and req[0] == "33:33:ff:" + bssid[9:] and \ 4189 req[3] == 'ff02::1:ff00:300' and req[4] == 'fe80::ff:fe00:300': 4190 # At least for now, ignore this special case until the kernel 4191 # can be prevented from sending it out. 4192 logger.info("dev1: Ignore NS from AP to own local addr: " + str(req)) 4193 elif req[1] != addr1: 4194 raise Exception("Unexpected foreign NS on dev1: " + str(req)) 4195 4196 ns = tshark_get_ns(cap_dev2) 4197 logger.info("dev2 seen NS: " + str(ns)) 4198 na = tshark_get_na(cap_dev2) 4199 logger.info("dev2 seen NA: " + str(na)) 4200 4201 # FIX: enable once kernel implementation for proxyarp IPv6 is fixed 4202 #if [addr2, addr0, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:ff00::2', 4203 # 'aaaa:bbbb:cccc::2', addr0] not in na: 4204 # raise Exception("dev2 did not get NA for aaaa:bbbb:cccc::2") 4205 #if [addr2, addr1, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:ff00::2', 4206 # 'aaaa:bbbb:dddd::2', addr1] not in na: 4207 # raise Exception("dev2 did not get NA for aaaa:bbbb:dddd::2") 4208 #if [addr2, addr1, 'aaaa:bbbb:eeee::2', 'aaaa:bbbb:ff00::2', 4209 # 'aaaa:bbbb:eeee::2', addr1] not in na: 4210 # raise Exception("dev2 did not get NA for aaaa:bbbb:eeee::2") 4211 4212def test_proxyarp_open(dev, apdev, params): 4213 """ProxyARP with open network""" 4214 try: 4215 _test_proxyarp_open(dev, apdev, params) 4216 finally: 4217 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'], 4218 stderr=open('/dev/null', 'w')) 4219 subprocess.call(['brctl', 'delbr', 'ap-br0'], 4220 stderr=open('/dev/null', 'w')) 4221 4222def test_proxyarp_open_ipv6(dev, apdev, params): 4223 """ProxyARP with open network (IPv6)""" 4224 try: 4225 _test_proxyarp_open_ipv6(dev, apdev, params) 4226 finally: 4227 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'], 4228 stderr=open('/dev/null', 'w')) 4229 subprocess.call(['brctl', 'delbr', 'ap-br0'], 4230 stderr=open('/dev/null', 'w')) 4231 4232def test_proxyarp_open_ebtables(dev, apdev, params): 4233 """ProxyARP with open network""" 4234 try: 4235 _test_proxyarp_open(dev, apdev, params, ebtables=True) 4236 finally: 4237 try: 4238 subprocess.call(['ebtables', '-F', 'FORWARD']) 4239 subprocess.call(['ebtables', '-F', 'OUTPUT']) 4240 except: 4241 pass 4242 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'], 4243 stderr=open('/dev/null', 'w')) 4244 subprocess.call(['brctl', 'delbr', 'ap-br0'], 4245 stderr=open('/dev/null', 'w')) 4246 4247def test_proxyarp_open_ebtables_ipv6(dev, apdev, params): 4248 """ProxyARP with open network (IPv6)""" 4249 try: 4250 _test_proxyarp_open_ipv6(dev, apdev, params, ebtables=True) 4251 finally: 4252 try: 4253 subprocess.call(['ebtables', '-F', 'FORWARD']) 4254 subprocess.call(['ebtables', '-F', 'OUTPUT']) 4255 except: 4256 pass 4257 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'], 4258 stderr=open('/dev/null', 'w')) 4259 subprocess.call(['brctl', 'delbr', 'ap-br0'], 4260 stderr=open('/dev/null', 'w')) 4261 4262def test_proxyarp_errors(dev, apdev, params): 4263 """ProxyARP error cases""" 4264 try: 4265 run_proxyarp_errors(dev, apdev, params) 4266 finally: 4267 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'], 4268 stderr=open('/dev/null', 'w')) 4269 subprocess.call(['brctl', 'delbr', 'ap-br0'], 4270 stderr=open('/dev/null', 'w')) 4271 4272def run_proxyarp_errors(dev, apdev, params): 4273 params = {'ssid': 'open', 4274 'proxy_arp': '1', 4275 'ap_isolate': '1', 4276 'bridge': 'ap-br0', 4277 'disable_dgaf': '1'} 4278 hapd = hostapd.add_ap(apdev[0], params, no_enable=True) 4279 try: 4280 hapd.enable() 4281 except: 4282 # For now, do not report failures due to missing kernel support 4283 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version") 4284 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=10) 4285 if ev is None: 4286 raise Exception("AP startup timed out") 4287 if "AP-ENABLED" not in ev: 4288 raise Exception("AP startup failed") 4289 4290 hapd.disable() 4291 with alloc_fail(hapd, 1, "l2_packet_init;x_snoop_get_l2_packet;dhcp_snoop_init"): 4292 if "FAIL" not in hapd.request("ENABLE"): 4293 raise Exception("ENABLE accepted unexpectedly") 4294 with alloc_fail(hapd, 1, "l2_packet_init;x_snoop_get_l2_packet;ndisc_snoop_init"): 4295 if "FAIL" not in hapd.request("ENABLE"): 4296 raise Exception("ENABLE accepted unexpectedly") 4297 with fail_test(hapd, 1, "l2_packet_set_packet_filter;x_snoop_get_l2_packet;ndisc_snoop_init"): 4298 if "FAIL" not in hapd.request("ENABLE"): 4299 raise Exception("ENABLE accepted unexpectedly") 4300 with fail_test(hapd, 1, "l2_packet_set_packet_filter;x_snoop_get_l2_packet;dhcp_snoop_init"): 4301 if "FAIL" not in hapd.request("ENABLE"): 4302 raise Exception("ENABLE accepted unexpectedly") 4303 hapd.enable() 4304 4305 subprocess.call(['brctl', 'setfd', 'ap-br0', '0']) 4306 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up']) 4307 4308 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412") 4309 addr0 = dev[0].own_addr() 4310 4311 pkt = build_ra(src_ll=apdev[0]['bssid'], ip_src="aaaa:bbbb:cccc::33", 4312 ip_dst="ff01::1") 4313 with fail_test(hapd, 1, "x_snoop_mcast_to_ucast_convert_send"): 4314 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt).decode()): 4315 raise Exception("DATA_TEST_FRAME failed") 4316 wait_fail_trigger(hapd, "GET_FAIL") 4317 4318 with alloc_fail(hapd, 1, "sta_ip6addr_add"): 4319 src_ll_opt0 = b"\x01\x01" + binascii.unhexlify(addr0.replace(':', '')) 4320 pkt = build_ns(src_ll=addr0, ip_src="aaaa:bbbb:cccc::2", 4321 ip_dst="ff02::1:ff00:2", target="aaaa:bbbb:cccc::2", 4322 opt=src_ll_opt0) 4323 hwsim_utils.sync_carrier(dev[0]) 4324 if "OK" not in dev[0].request("DATA_TEST_FRAME " + binascii.hexlify(pkt).decode()): 4325 raise Exception("DATA_TEST_FRAME failed") 4326 wait_fail_trigger(hapd, "GET_ALLOC_FAIL") 4327 4328def test_ap_hs20_connect_deinit(dev, apdev): 4329 """Hotspot 2.0 connection interrupted with deinit""" 4330 check_eap_capa(dev[0], "MSCHAPV2") 4331 bssid = apdev[0]['bssid'] 4332 params = hs20_ap_params() 4333 params['hessid'] = bssid 4334 hapd = hostapd.add_ap(apdev[0], params) 4335 4336 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 4337 wpas.interface_add("wlan5", drv_params="") 4338 wpas.hs20_enable() 4339 wpas.flush_scan_cache() 4340 wpas.add_cred_values({'realm': "example.com", 4341 'username': "hs20-test", 4342 'password': "password", 4343 'ca_cert': "auth_serv/ca.pem", 4344 'domain': "example.com"}) 4345 4346 wpas.scan_for_bss(bssid, freq=2412) 4347 hapd.disable() 4348 4349 wpas.request("INTERWORKING_SELECT freq=2412") 4350 4351 id = wpas.request("RADIO_WORK add block-work") 4352 ev = wpas.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout=5) 4353 if ev is None: 4354 raise Exception("Timeout while waiting radio work to start") 4355 ev = wpas.wait_event(["GAS-QUERY-START", "EXT-RADIO-WORK-START"], timeout=5) 4356 if ev is None: 4357 raise Exception("Timeout while waiting radio work to start (2)") 4358 4359 # Remove the interface while the gas-query radio work is still pending and 4360 # GAS query has not yet been started. 4361 wpas.interface_remove("wlan5") 4362 4363def test_ap_hs20_anqp_format_errors(dev, apdev): 4364 """Interworking network selection and ANQP format errors""" 4365 bssid = apdev[0]['bssid'] 4366 params = hs20_ap_params() 4367 params['hessid'] = bssid 4368 hapd = hostapd.add_ap(apdev[0], params) 4369 4370 dev[0].hs20_enable() 4371 values = {'realm': "example.com", 4372 'ca_cert': "auth_serv/ca.pem", 4373 'username': "hs20-test", 4374 'password': "password", 4375 'domain': "example.com"} 4376 id = dev[0].add_cred_values(values) 4377 4378 dev[0].scan_for_bss(bssid, freq="2412") 4379 4380 tests = ["00", "ffff", "010011223344", "020008000005112233445500", 4381 "01000400000000", "01000000000000", 4382 "01000300000200", "0100040000ff0000", "01000300000100", 4383 "01000300000001", 4384 "01000600000056112233", 4385 "01000900000002050001000111", 4386 "01000600000001000000", "01000600000001ff0000", 4387 "01000600000001020001", 4388 "010008000000010400010001", "0100080000000104000100ff", 4389 "010011000000010d00050200020100030005000600", 4390 "0000"] 4391 for t in tests: 4392 hapd.set("anqp_elem", "263:" + t) 4393 dev[0].request("INTERWORKING_SELECT freq=2412") 4394 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=5) 4395 if ev is None: 4396 raise Exception("Network selection timed out") 4397 dev[0].dump_monitor() 4398 4399 dev[0].remove_cred(id) 4400 id = dev[0].add_cred_values({'imsi': "555444-333222111", 'eap': "AKA", 4401 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"}) 4402 4403 tests = ["00", "0100", "0001", "00ff", "000200ff", "0003000101", 4404 "00020100"] 4405 for t in tests: 4406 hapd.set("anqp_elem", "264:" + t) 4407 dev[0].request("INTERWORKING_SELECT freq=2412") 4408 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=5) 4409 if ev is None: 4410 raise Exception("Network selection timed out") 4411 dev[0].dump_monitor() 4412 4413def test_ap_hs20_cred_with_nai_realm(dev, apdev): 4414 """Hotspot 2.0 network selection and cred_with_nai_realm cred->realm""" 4415 bssid = apdev[0]['bssid'] 4416 params = hs20_ap_params() 4417 params['hessid'] = bssid 4418 hostapd.add_ap(apdev[0], params) 4419 4420 dev[0].hs20_enable() 4421 4422 id = dev[0].add_cred_values({'realm': "example.com", 4423 'username': "test", 4424 'password': "secret", 4425 'domain': "example.com", 4426 'eap': 'TTLS'}) 4427 interworking_select(dev[0], bssid, "home", freq=2412) 4428 dev[0].remove_cred(id) 4429 4430 id = dev[0].add_cred_values({'realm': "foo.com", 4431 'username': "test", 4432 'password': "secret", 4433 'domain': "example.com", 4434 'home_ois': ["112234"], 4435 'eap': 'TTLS'}) 4436 interworking_select(dev[0], bssid, "home", freq=2412, no_match=True) 4437 dev[0].remove_cred(id) 4438 4439def test_ap_hs20_cred_and_no_roaming_consortium(dev, apdev): 4440 """Hotspot 2.0 network selection and no roaming consortium""" 4441 bssid = apdev[0]['bssid'] 4442 params = hs20_ap_params() 4443 params['hessid'] = bssid 4444 del params['roaming_consortium'] 4445 hostapd.add_ap(apdev[0], params) 4446 4447 dev[0].hs20_enable() 4448 4449 id = dev[0].add_cred_values({'realm': "example.com", 4450 'username': "test", 4451 'password': "secret", 4452 'domain': "example.com", 4453 'home_ois': ["112234"], 4454 'eap': 'TTLS'}) 4455 interworking_select(dev[0], bssid, "home", freq=2412) 4456 4457def test_ap_hs20_interworking_oom(dev, apdev): 4458 """Hotspot 2.0 network selection and OOM""" 4459 bssid = apdev[0]['bssid'] 4460 params = hs20_ap_params() 4461 params['hessid'] = bssid 4462 params['nai_realm'] = ["0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]", 4463 "0,example.com,13[5:6],21[2:4][5:7]", 4464 "0,another.example.com"] 4465 hostapd.add_ap(apdev[0], params) 4466 4467 dev[0].hs20_enable() 4468 4469 id = dev[0].add_cred_values({'realm': "example.com", 4470 'username': "test", 4471 'password': "secret", 4472 'domain': "example.com", 4473 'eap': 'TTLS'}) 4474 4475 dev[0].scan_for_bss(bssid, freq="2412") 4476 4477 funcs = ["wpabuf_alloc;interworking_anqp_send_req", 4478 "anqp_build_req;interworking_anqp_send_req", 4479 "gas_query_req;interworking_anqp_send_req", 4480 "dup_binstr;nai_realm_parse_realm", 4481 "=nai_realm_parse_realm", 4482 "=nai_realm_parse", 4483 "=nai_realm_match"] 4484 for func in funcs: 4485 with alloc_fail(dev[0], 1, func): 4486 dev[0].request("INTERWORKING_SELECT auto freq=2412") 4487 ev = dev[0].wait_event(["Starting ANQP"], timeout=5) 4488 if ev is None: 4489 raise Exception("ANQP did not start") 4490 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4491 dev[0].dump_monitor() 4492 4493def test_ap_hs20_no_cred_connect(dev, apdev): 4494 """Hotspot 2.0 and connect attempt without credential""" 4495 bssid = apdev[0]['bssid'] 4496 params = hs20_ap_params() 4497 params['hessid'] = bssid 4498 hapd = hostapd.add_ap(apdev[0], params) 4499 4500 dev[0].hs20_enable() 4501 dev[0].scan_for_bss(bssid, freq="2412") 4502 if "FAIL" not in dev[0].request("INTERWORKING_CONNECT " + bssid): 4503 raise Exception("Unexpected INTERWORKING_CONNECT success") 4504 4505def test_ap_hs20_no_rsn_connect(dev, apdev): 4506 """Hotspot 2.0 and connect attempt without RSN""" 4507 bssid = apdev[0]['bssid'] 4508 params = hostapd.wpa_params(ssid="test-hs20") 4509 params['wpa_key_mgmt'] = "WPA-EAP" 4510 params['ieee80211w'] = "1" 4511 params['ieee8021x'] = "1" 4512 params['auth_server_addr'] = "127.0.0.1" 4513 params['auth_server_port'] = "1812" 4514 params['auth_server_shared_secret'] = "radius" 4515 params['interworking'] = "1" 4516 params['roaming_consortium'] = ["112233", "1020304050", "010203040506", 4517 "fedcba"] 4518 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]", 4519 "0,another.example.com"] 4520 hapd = hostapd.add_ap(apdev[0], params) 4521 4522 dev[0].hs20_enable() 4523 dev[0].scan_for_bss(bssid, freq="2412") 4524 4525 id = dev[0].add_cred_values({'realm': "example.com", 4526 'username': "test", 4527 'password': "secret", 4528 'domain': "example.com", 4529 'home_ois': ["112233"], 4530 'eap': 'TTLS'}) 4531 4532 interworking_select(dev[0], bssid, freq=2412, no_match=True) 4533 if "FAIL" not in dev[0].request("INTERWORKING_CONNECT " + bssid): 4534 raise Exception("Unexpected INTERWORKING_CONNECT success") 4535 4536def test_ap_hs20_no_match_connect(dev, apdev): 4537 """Hotspot 2.0 and connect attempt without matching cred""" 4538 bssid = apdev[0]['bssid'] 4539 params = hs20_ap_params() 4540 hapd = hostapd.add_ap(apdev[0], params) 4541 4542 dev[0].hs20_enable() 4543 dev[0].scan_for_bss(bssid, freq="2412") 4544 4545 id = dev[0].add_cred_values({'realm': "example.org", 4546 'username': "test", 4547 'password': "secret", 4548 'domain': "example.org", 4549 'home_ois': ["112234"], 4550 'eap': 'TTLS'}) 4551 4552 interworking_select(dev[0], bssid, freq=2412, no_match=True) 4553 if "FAIL" not in dev[0].request("INTERWORKING_CONNECT " + bssid): 4554 raise Exception("Unexpected INTERWORKING_CONNECT success") 4555 4556def test_ap_hs20_multiple_home_cred(dev, apdev): 4557 """Hotspot 2.0 and select with multiple matching home credentials""" 4558 bssid = apdev[0]['bssid'] 4559 params = hs20_ap_params() 4560 params['hessid'] = bssid 4561 params['nai_realm'] = ["0,example.com,13[5:6],21[2:4][5:7]"] 4562 params['domain_name'] = "example.com" 4563 hapd = hostapd.add_ap(apdev[0], params) 4564 4565 bssid2 = apdev[1]['bssid'] 4566 params = hs20_ap_params(ssid="test-hs20-other") 4567 params['hessid'] = bssid2 4568 params['nai_realm'] = ["0,example.org,13[5:6],21[2:4][5:7]"] 4569 params['domain_name'] = "example.org" 4570 hapd2 = hostapd.add_ap(apdev[1], params) 4571 4572 dev[0].hs20_enable() 4573 dev[0].scan_for_bss(bssid2, freq="2412") 4574 dev[0].scan_for_bss(bssid, freq="2412") 4575 id = dev[0].add_cred_values({'realm': "example.com", 4576 'priority': '2', 4577 'username': "hs20-test", 4578 'password': "password", 4579 'domain': "example.com"}) 4580 id2 = dev[0].add_cred_values({'realm': "example.org", 4581 'priority': '3', 4582 'username': "hs20-test", 4583 'password': "password", 4584 'domain': "example.org"}) 4585 dev[0].request("INTERWORKING_SELECT auto freq=2412") 4586 ev = dev[0].wait_connected(timeout=15) 4587 if bssid2 not in ev: 4588 raise Exception("Connected to incorrect network") 4589 4590def test_ap_hs20_anqp_invalid_gas_response(dev, apdev): 4591 """Hotspot 2.0 network selection and invalid GAS response""" 4592 bssid = apdev[0]['bssid'] 4593 params = hs20_ap_params() 4594 params['hessid'] = bssid 4595 hapd = hostapd.add_ap(apdev[0], params) 4596 4597 dev[0].flush_scan_cache() 4598 dev[0].scan_for_bss(bssid, freq="2412") 4599 hapd.set("ext_mgmt_frame_handling", "1") 4600 4601 dev[0].hs20_enable() 4602 4603 id = dev[0].add_cred_values({'realm': "example.com", 4604 'username': "test", 4605 'password': "secret", 4606 'domain': "example.com", 4607 'home_ois': ["112234"], 4608 'eap': 'TTLS'}) 4609 dev[0].request("INTERWORKING_SELECT freq=2412") 4610 4611 query = gas_rx(hapd) 4612 gas = parse_gas(query['payload']) 4613 4614 logger.info("ANQP: Unexpected Advertisement Protocol in response") 4615 resp = action_response(query) 4616 adv_proto = struct.pack('8B', 108, 6, 127, 0xdd, 0x00, 0x11, 0x22, 0x33) 4617 data = struct.pack('<H', 0) 4618 resp['payload'] = struct.pack('<BBBHH', ACTION_CATEG_PUBLIC, 4619 GAS_INITIAL_RESPONSE, 4620 gas['dialog_token'], 0, 0) + adv_proto + data 4621 send_gas_resp(hapd, resp) 4622 4623 ev = dev[0].wait_event(["ANQP-QUERY-DONE"], timeout=5) 4624 if ev is None: 4625 raise Exception("No ANQP-QUERY-DONE seen") 4626 if "result=INVALID_FRAME" not in ev: 4627 raise Exception("Unexpected result: " + ev) 4628 4629 dev[0].request("INTERWORKING_SELECT freq=2412") 4630 4631 query = gas_rx(hapd) 4632 gas = parse_gas(query['payload']) 4633 4634 logger.info("ANQP: Invalid element length for Info ID 1234") 4635 resp = action_response(query) 4636 adv_proto = struct.pack('BBBB', 108, 2, 127, 0) 4637 elements = struct.pack('<HH', 1234, 1) 4638 data = struct.pack('<H', len(elements)) + elements 4639 resp['payload'] = struct.pack('<BBBHH', ACTION_CATEG_PUBLIC, 4640 GAS_INITIAL_RESPONSE, 4641 gas['dialog_token'], 0, 0) + adv_proto + data 4642 send_gas_resp(hapd, resp) 4643 4644 ev = dev[0].wait_event(["ANQP-QUERY-DONE"], timeout=5) 4645 if ev is None: 4646 raise Exception("No ANQP-QUERY-DONE seen") 4647 if "result=INVALID_FRAME" not in ev: 4648 raise Exception("Unexpected result: " + ev) 4649 4650 with alloc_fail(dev[0], 1, "=anqp_add_extra"): 4651 dev[0].request("INTERWORKING_SELECT freq=2412") 4652 4653 query = gas_rx(hapd) 4654 gas = parse_gas(query['payload']) 4655 4656 resp = action_response(query) 4657 elements = struct.pack('<HHHH', 1, 0, 1, 0) 4658 data = struct.pack('<H', len(elements)) + elements 4659 resp['payload'] = struct.pack('<BBBHH', ACTION_CATEG_PUBLIC, 4660 GAS_INITIAL_RESPONSE, 4661 gas['dialog_token'], 0, 0) + adv_proto + data 4662 send_gas_resp(hapd, resp) 4663 4664 ev = dev[0].wait_event(["ANQP-QUERY-DONE"], timeout=5) 4665 if ev is None: 4666 raise Exception("No ANQP-QUERY-DONE seen") 4667 if "result=SUCCESS" not in ev: 4668 raise Exception("Unexpected result: " + ev) 4669 4670 with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;anqp_add_extra"): 4671 dev[0].request("INTERWORKING_SELECT freq=2412") 4672 4673 query = gas_rx(hapd) 4674 gas = parse_gas(query['payload']) 4675 4676 resp = action_response(query) 4677 elements = struct.pack('<HHHH', 1, 0, 1, 0) 4678 data = struct.pack('<H', len(elements)) + elements 4679 resp['payload'] = struct.pack('<BBBHH', ACTION_CATEG_PUBLIC, 4680 GAS_INITIAL_RESPONSE, 4681 gas['dialog_token'], 0, 0) + adv_proto + data 4682 send_gas_resp(hapd, resp) 4683 4684 ev = dev[0].wait_event(["ANQP-QUERY-DONE"], timeout=5) 4685 if ev is None: 4686 raise Exception("No ANQP-QUERY-DONE seen") 4687 if "result=SUCCESS" not in ev: 4688 raise Exception("Unexpected result: " + ev) 4689 4690 tests = [struct.pack('<HH', 0xdddd, 0), 4691 struct.pack('<HH3B', 0xdddd, 3, 0x50, 0x6f, 0x9a), 4692 struct.pack('<HH4B', 0xdddd, 4, 0x50, 0x6f, 0x9a, 0), 4693 struct.pack('<HH4B', 0xdddd, 4, 0x11, 0x22, 0x33, 0), 4694 struct.pack('<HHHH', 1, 0, 1, 0)] 4695 for elements in tests: 4696 dev[0].request("INTERWORKING_SELECT freq=2412") 4697 4698 query = gas_rx(hapd) 4699 gas = parse_gas(query['payload']) 4700 4701 resp = action_response(query) 4702 data = struct.pack('<H', len(elements)) + elements 4703 resp['payload'] = struct.pack('<BBBHH', ACTION_CATEG_PUBLIC, 4704 GAS_INITIAL_RESPONSE, 4705 gas['dialog_token'], 0, 0) + adv_proto + data 4706 send_gas_resp(hapd, resp) 4707 4708 ev = dev[0].wait_event(["ANQP-QUERY-DONE"], timeout=5) 4709 if ev is None: 4710 raise Exception("No ANQP-QUERY-DONE seen") 4711 if "result=SUCCESS" not in ev: 4712 raise Exception("Unexpected result: " + ev) 4713 4714def test_ap_hs20_set_profile_failures(dev, apdev): 4715 """Hotspot 2.0 and failures during profile configuration""" 4716 bssid = apdev[0]['bssid'] 4717 params = hs20_ap_params() 4718 params['hessid'] = bssid 4719 params['anqp_3gpp_cell_net'] = "555,444" 4720 hapd = hostapd.add_ap(apdev[0], params) 4721 4722 dev[0].hs20_enable() 4723 dev[0].scan_for_bss(bssid, freq="2412") 4724 4725 id = dev[0].add_cred_values({'realm': "example.com", 4726 'domain': "example.com", 4727 'username': "test", 4728 'password': "secret", 4729 'eap': 'TTLS'}) 4730 interworking_select(dev[0], bssid, "home", freq=2412) 4731 dev[0].dump_monitor() 4732 dev[0].request("NOTE ssid->eap.eap_methods = os_malloc()") 4733 with alloc_fail(dev[0], 1, "interworking_set_eap_params"): 4734 dev[0].request("INTERWORKING_CONNECT " + bssid) 4735 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4736 dev[0].remove_cred(id) 4737 4738 id = dev[0].add_cred_values({'realm': "example.com", 4739 'domain': "example.com", 4740 'username': "hs20-test-with-domain@example.com", 4741 'password': "password"}) 4742 interworking_select(dev[0], bssid, "home", freq=2412) 4743 dev[0].dump_monitor() 4744 dev[0].request("NOTE anon = os_malloc()") 4745 with alloc_fail(dev[0], 1, "interworking_set_eap_params"): 4746 dev[0].request("INTERWORKING_CONNECT " + bssid) 4747 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4748 dev[0].request("NOTE Successful connection with cred->username including realm") 4749 dev[0].request("INTERWORKING_CONNECT " + bssid) 4750 dev[0].wait_connected() 4751 hapd.wait_sta() 4752 dev[0].remove_cred(id) 4753 dev[0].wait_disconnected() 4754 hapd.wait_sta_disconnect() 4755 4756 id = dev[0].add_cred_values({'realm': "example.com", 4757 'domain': "example.com", 4758 'username': "hs20-test", 4759 'password': "password"}) 4760 interworking_select(dev[0], bssid, "home", freq=2412) 4761 dev[0].dump_monitor() 4762 dev[0].request("NOTE anon = os_malloc() (second)") 4763 with alloc_fail(dev[0], 1, "interworking_set_eap_params"): 4764 dev[0].request("INTERWORKING_CONNECT " + bssid) 4765 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4766 with alloc_fail(dev[0], 1, "wpa_config_add_network;interworking_connect"): 4767 dev[0].request("INTERWORKING_CONNECT " + bssid) 4768 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4769 with alloc_fail(dev[0], 1, "=interworking_connect"): 4770 dev[0].request("INTERWORKING_CONNECT " + bssid) 4771 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4772 dev[0].request("NOTE wpa_config_set(eap)") 4773 with alloc_fail(dev[0], 1, "wpa_config_parse_eap;wpa_config_set;interworking_connect"): 4774 dev[0].request("INTERWORKING_CONNECT " + bssid) 4775 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4776 dev[0].request("NOTE wpa_config_set(TTLS-NON_EAP_MSCHAPV2-phase2)") 4777 with alloc_fail(dev[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 4778 dev[0].request("INTERWORKING_CONNECT " + bssid) 4779 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4780 dev[0].remove_cred(id) 4781 4782 id = dev[0].add_cred_values({'home_ois': ["112233"], 4783 'domain': "example.com", 4784 'username': "hs20-test", 4785 'password': "password", 4786 'eap': 'TTLS', 4787 'phase2': "auth=MSCHAPV2"}) 4788 interworking_select(dev[0], bssid, "home", freq=2412) 4789 dev[0].dump_monitor() 4790 dev[0].request("NOTE anon = os_strdup()") 4791 with alloc_fail(dev[0], 2, "interworking_set_eap_params"): 4792 dev[0].request("INTERWORKING_CONNECT " + bssid) 4793 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4794 dev[0].request("NOTE wpa_config_set_quoted(anonymous_identity)") 4795 with alloc_fail(dev[0], 1, "=wpa_config_set_quoted;interworking_set_eap_params"): 4796 dev[0].request("INTERWORKING_CONNECT " + bssid) 4797 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4798 dev[0].request("NOTE Successful connection with cred->realm not included") 4799 dev[0].request("INTERWORKING_CONNECT " + bssid) 4800 dev[0].wait_connected() 4801 hapd.wait_sta() 4802 dev[0].remove_cred(id) 4803 dev[0].wait_disconnected() 4804 hapd.wait_sta_disconnect() 4805 4806 id = dev[0].add_cred_values({'home_ois': ["112233"], 4807 'domain': "example.com", 4808 'realm': "example.com", 4809 'username': "user", 4810 'password': "password", 4811 'eap': 'PEAP'}) 4812 interworking_select(dev[0], bssid, "home", freq=2412) 4813 dev[0].dump_monitor() 4814 dev[0].request("NOTE id = os_strdup()") 4815 with alloc_fail(dev[0], 2, "interworking_set_eap_params"): 4816 dev[0].request("INTERWORKING_CONNECT " + bssid) 4817 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4818 dev[0].request("NOTE wpa_config_set_quoted(identity)") 4819 with alloc_fail(dev[0], 1, "=wpa_config_set_quoted;interworking_set_eap_params"): 4820 dev[0].request("INTERWORKING_CONNECT " + bssid) 4821 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4822 dev[0].remove_cred(id) 4823 4824 id = dev[0].add_cred_values({'home_ois': ["112233"], 4825 'domain': "example.com", 4826 'realm': "example.com", 4827 'username': "user", 4828 'password': "password", 4829 'eap': "TTLS"}) 4830 interworking_select(dev[0], bssid, "home", freq=2412) 4831 dev[0].dump_monitor() 4832 dev[0].request("NOTE wpa_config_set_quoted(identity) (second)") 4833 with alloc_fail(dev[0], 2, "=wpa_config_set_quoted;interworking_set_eap_params"): 4834 dev[0].request("INTERWORKING_CONNECT " + bssid) 4835 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4836 dev[0].request("NOTE wpa_config_set_quoted(password)") 4837 with alloc_fail(dev[0], 3, "=wpa_config_set_quoted;interworking_set_eap_params"): 4838 dev[0].request("INTERWORKING_CONNECT " + bssid) 4839 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4840 with alloc_fail(dev[0], 1, "wpa_config_add_network;interworking_connect_roaming_consortium"): 4841 dev[0].request("INTERWORKING_CONNECT " + bssid) 4842 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4843 with alloc_fail(dev[0], 1, "=interworking_connect_roaming_consortium"): 4844 dev[0].request("INTERWORKING_CONNECT " + bssid) 4845 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4846 dev[0].remove_cred(id) 4847 4848 id = dev[0].add_cred_values({'home_ois': ["112233"], 4849 'domain': "example.com", 4850 'realm': "example.com", 4851 'username': "user", 4852 'eap': "PEAP"}) 4853 dev[0].set_cred(id, "password", "ext:password") 4854 interworking_select(dev[0], bssid, "home", freq=2412) 4855 dev[0].dump_monitor() 4856 dev[0].request("NOTE wpa_config_set(password)") 4857 with alloc_fail(dev[0], 1, "wpa_config_parse_password;interworking_set_eap_params"): 4858 dev[0].request("INTERWORKING_CONNECT " + bssid) 4859 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4860 with alloc_fail(dev[0], 1, "interworking_set_hs20_params"): 4861 dev[0].request("INTERWORKING_CONNECT " + bssid) 4862 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4863 dev[0].remove_cred(id) 4864 4865 id = dev[0].add_cred_values({'realm': "example.com", 4866 'domain': "example.com", 4867 'username': "certificate-user", 4868 'phase1': "include_tls_length=0", 4869 'domain_suffix_match': "example.com", 4870 'ca_cert': "auth_serv/ca.pem", 4871 'client_cert': "auth_serv/user.pem", 4872 'private_key': "auth_serv/user.key", 4873 'private_key_passwd': "secret"}) 4874 interworking_select(dev[0], bssid, "home", freq=2412) 4875 dev[0].dump_monitor() 4876 dev[0].request("NOTE wpa_config_set_quoted(client_cert)") 4877 with alloc_fail(dev[0], 2, "=wpa_config_set_quoted;interworking_set_eap_params"): 4878 dev[0].request("INTERWORKING_CONNECT " + bssid) 4879 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4880 dev[0].request("NOTE wpa_config_set_quoted(private_key)") 4881 with alloc_fail(dev[0], 3, "=wpa_config_set_quoted;interworking_set_eap_params"): 4882 dev[0].request("INTERWORKING_CONNECT " + bssid) 4883 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4884 dev[0].request("NOTE wpa_config_set_quoted(private_key_passwd)") 4885 with alloc_fail(dev[0], 4, "=wpa_config_set_quoted;interworking_set_eap_params"): 4886 dev[0].request("INTERWORKING_CONNECT " + bssid) 4887 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4888 dev[0].request("NOTE wpa_config_set_quoted(ca_cert)") 4889 with alloc_fail(dev[0], 5, "=wpa_config_set_quoted;interworking_set_eap_params"): 4890 dev[0].request("INTERWORKING_CONNECT " + bssid) 4891 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4892 dev[0].request("NOTE wpa_config_set_quoted(domain_suffix_match)") 4893 with alloc_fail(dev[0], 6, "=wpa_config_set_quoted;interworking_set_eap_params"): 4894 dev[0].request("INTERWORKING_CONNECT " + bssid) 4895 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4896 with alloc_fail(dev[0], 1, "interworking_set_hs20_params"): 4897 dev[0].request("INTERWORKING_CONNECT " + bssid) 4898 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4899 dev[0].remove_cred(id) 4900 4901 id = dev[0].add_cred_values({'imsi': "555444-333222111", 'eap': "SIM", 4902 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"}) 4903 interworking_select(dev[0], bssid, freq=2412) 4904 dev[0].dump_monitor() 4905 with alloc_fail(dev[0], 1, "interworking_set_hs20_params"): 4906 dev[0].request("INTERWORKING_CONNECT " + bssid) 4907 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4908 dev[0].request("NOTE wpa_config_set_quoted(password;milenage)") 4909 with alloc_fail(dev[0], 2, "=wpa_config_set_quoted;interworking_connect_3gpp"): 4910 dev[0].request("INTERWORKING_CONNECT " + bssid) 4911 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4912 dev[0].request("NOTE wpa_config_set(eap)") 4913 with alloc_fail(dev[0], 1, "wpa_config_parse_eap;wpa_config_set;interworking_connect_3gpp"): 4914 dev[0].request("INTERWORKING_CONNECT " + bssid) 4915 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4916 dev[0].request("NOTE set_root_nai:wpa_config_set(identity)") 4917 with alloc_fail(dev[0], 1, "wpa_config_parse_str;interworking_connect_3gpp"): 4918 dev[0].request("INTERWORKING_CONNECT " + bssid) 4919 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4920 dev[0].remove_cred(id) 4921 4922 id = dev[0].add_cred_values({'home_ois': ["112233"], 4923 'eap': 'TTLS', 4924 'username': "user@example.com", 4925 'password': "password"}) 4926 interworking_select(dev[0], bssid, freq=2412) 4927 dev[0].dump_monitor() 4928 dev[0].request("NOTE Interworking: No EAP method set for credential using roaming consortium") 4929 dev[0].request("INTERWORKING_CONNECT " + bssid) 4930 dev[0].remove_cred(id) 4931 4932 hapd.disable() 4933 params = hs20_ap_params() 4934 params['nai_realm'] = "0,example.com,25[3:26]" 4935 hapd = hostapd.add_ap(apdev[0], params) 4936 id = dev[0].add_cred_values({'realm': "example.com", 4937 'domain': "example.com", 4938 'username': "hs20-test", 4939 'password': "password"}) 4940 interworking_select(dev[0], bssid, freq=2412) 4941 dev[0].dump_monitor() 4942 dev[0].request("NOTE wpa_config_set(PEAP/FAST-phase1)") 4943 with alloc_fail(dev[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 4944 dev[0].request("INTERWORKING_CONNECT " + bssid) 4945 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4946 dev[0].request("NOTE wpa_config_set(PEAP/FAST-pac_interworking)") 4947 with alloc_fail(dev[0], 2, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 4948 dev[0].request("INTERWORKING_CONNECT " + bssid) 4949 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4950 dev[0].request("NOTE wpa_config_set(PEAP/FAST-phase2)") 4951 with alloc_fail(dev[0], 3, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 4952 dev[0].request("INTERWORKING_CONNECT " + bssid) 4953 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4954 4955 hapd.disable() 4956 params = hs20_ap_params() 4957 params['nai_realm'] = "0,example.com,21" 4958 hapd = hostapd.add_ap(apdev[0], params) 4959 interworking_select(dev[0], bssid, freq=2412) 4960 dev[0].request("NOTE wpa_config_set(TTLS-defaults-phase2)") 4961 with alloc_fail(dev[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 4962 dev[0].request("INTERWORKING_CONNECT " + bssid) 4963 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4964 4965 hapd.disable() 4966 params = hs20_ap_params() 4967 params['nai_realm'] = "0,example.com,21[2:3]" 4968 hapd = hostapd.add_ap(apdev[0], params) 4969 interworking_select(dev[0], bssid, freq=2412) 4970 dev[0].request("NOTE wpa_config_set(TTLS-NON_EAP_MSCHAP-phase2)") 4971 with alloc_fail(dev[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 4972 dev[0].request("INTERWORKING_CONNECT " + bssid) 4973 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4974 4975 hapd.disable() 4976 params = hs20_ap_params() 4977 params['nai_realm'] = "0,example.com,21[2:2]" 4978 hapd = hostapd.add_ap(apdev[0], params) 4979 interworking_select(dev[0], bssid, freq=2412) 4980 dev[0].request("NOTE wpa_config_set(TTLS-NON_EAP_CHAP-phase2)") 4981 with alloc_fail(dev[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 4982 dev[0].request("INTERWORKING_CONNECT " + bssid) 4983 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4984 4985 hapd.disable() 4986 params = hs20_ap_params() 4987 params['nai_realm'] = "0,example.com,21[2:1]" 4988 hapd = hostapd.add_ap(apdev[0], params) 4989 interworking_select(dev[0], bssid, freq=2412) 4990 dev[0].request("NOTE wpa_config_set(TTLS-NON_EAP_PAP-phase2)") 4991 with alloc_fail(dev[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 4992 dev[0].request("INTERWORKING_CONNECT " + bssid) 4993 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 4994 4995 hapd.disable() 4996 params = hs20_ap_params() 4997 params['nai_realm'] = "0,example.com,21[3:26]" 4998 hapd = hostapd.add_ap(apdev[0], params) 4999 interworking_select(dev[0], bssid, freq=2412) 5000 dev[0].request("NOTE wpa_config_set(TTLS-EAP-MSCHAPV2-phase2)") 5001 with alloc_fail(dev[0], 1, "wpa_config_parse_str;wpa_config_set;interworking_connect"): 5002 dev[0].request("INTERWORKING_CONNECT " + bssid) 5003 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 5004 5005 dev[0].remove_cred(id) 5006 5007def test_ap_hs20_unexpected(dev, apdev): 5008 """Unexpected Hotspot 2.0 AP configuration""" 5009 skip_without_tkip(dev[0]) 5010 skip_without_tkip(dev[1]) 5011 skip_without_tkip(dev[2]) 5012 check_eap_capa(dev[0], "MSCHAPV2") 5013 bssid = apdev[0]['bssid'] 5014 params = hostapd.wpa_eap_params(ssid="test-hs20-fake") 5015 params['wpa'] = "3" 5016 params['wpa_pairwise'] = "TKIP CCMP" 5017 params['rsn_pairwise'] = "CCMP" 5018 params['ieee80211w'] = "1" 5019 #params['vendor_elements'] = 'dd07506f9a10140000' 5020 params['vendor_elements'] = 'dd04506f9a10' 5021 hostapd.add_ap(apdev[0], params) 5022 5023 dev[0].hs20_enable() 5024 dev[0].scan_for_bss(bssid, freq="2412") 5025 dev[0].connect("test-hs20-fake", key_mgmt="WPA-EAP", eap="TTLS", 5026 pairwise="TKIP", 5027 identity="hs20-test", password="password", 5028 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 5029 scan_freq="2412") 5030 5031 dev[1].hs20_enable() 5032 dev[1].scan_for_bss(bssid, freq="2412") 5033 dev[1].connect("test-hs20-fake", key_mgmt="WPA-EAP", eap="TTLS", 5034 proto="WPA", 5035 identity="hs20-test", password="password", 5036 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 5037 scan_freq="2412") 5038 5039 dev[2].hs20_enable() 5040 dev[2].scan_for_bss(bssid, freq="2412") 5041 dev[2].connect("test-hs20-fake", key_mgmt="WPA-EAP", eap="TTLS", 5042 ieee80211w="1", 5043 proto="RSN", pairwise="CCMP", 5044 identity="hs20-test", password="password", 5045 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 5046 scan_freq="2412") 5047 5048def test_ap_interworking_element_update(dev, apdev): 5049 """Dynamic Interworking element update""" 5050 bssid = apdev[0]['bssid'] 5051 params = hs20_ap_params() 5052 params['hessid'] = bssid 5053 hapd = hostapd.add_ap(apdev[0], params) 5054 5055 dev[0].hs20_enable() 5056 dev[0].scan_for_bss(bssid, freq="2412") 5057 bss = dev[0].get_bss(bssid) 5058 logger.info("Before update: " + str(bss)) 5059 if '6b091e0701020000000300' not in bss['ie']: 5060 raise Exception("Expected Interworking element not seen before update") 5061 5062 # Update configuration parameters related to Interworking element 5063 hapd.set('access_network_type', '2') 5064 hapd.set('asra', '1') 5065 hapd.set('esr', '1') 5066 hapd.set('uesa', '1') 5067 hapd.set('venue_group', '2') 5068 hapd.set('venue_type', '8') 5069 if "OK" not in hapd.request("UPDATE_BEACON"): 5070 raise Exception("UPDATE_BEACON failed") 5071 dev[0].request("BSS_FLUSH 0") 5072 dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) 5073 bss = dev[0].get_bss(bssid) 5074 logger.info("After update: " + str(bss)) 5075 if '6b09f20208020000000300' not in bss['ie']: 5076 raise Exception("Expected Interworking element not seen after update") 5077 5078def test_ap_hs20_terms_and_conditions(dev, apdev): 5079 """Hotspot 2.0 Terms and Conditions signaling""" 5080 check_eap_capa(dev[0], "MSCHAPV2") 5081 bssid = apdev[0]['bssid'] 5082 params = hs20_ap_params() 5083 params['hessid'] = bssid 5084 params['hs20_t_c_filename'] = 'terms-and-conditions' 5085 params['hs20_t_c_timestamp'] = '123456789' 5086 5087 hostapd.add_ap(apdev[0], params) 5088 5089 dev[0].hs20_enable() 5090 dev[0].connect("test-hs20", proto="RSN", key_mgmt="WPA-EAP", eap="TTLS", 5091 identity="hs20-t-c-test", password="password", 5092 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 5093 ieee80211w='2', scan_freq="2412") 5094 ev = dev[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout=5) 5095 if ev is None: 5096 raise Exception("Terms and Conditions Acceptance notification not received") 5097 url = "https://example.com/t_and_c?addr=%s&ap=123" % dev[0].own_addr() 5098 if url not in ev: 5099 raise Exception("Unexpected URL: " + ev) 5100 5101def test_ap_hs20_terms_and_conditions_coa(dev, apdev): 5102 """Hotspot 2.0 Terms and Conditions signaling - CoA""" 5103 try: 5104 import pyrad.client 5105 import pyrad.packet 5106 import pyrad.dictionary 5107 import radius_das 5108 except ImportError: 5109 raise HwsimSkip("No pyrad modules available") 5110 5111 check_eap_capa(dev[0], "MSCHAPV2") 5112 bssid = apdev[0]['bssid'] 5113 params = hs20_ap_params() 5114 params['hessid'] = bssid 5115 params['hs20_t_c_filename'] = 'terms-and-conditions' 5116 params['hs20_t_c_timestamp'] = '123456789' 5117 params['own_ip_addr'] = "127.0.0.1" 5118 params['radius_das_port'] = "3799" 5119 params['radius_das_client'] = "127.0.0.1 secret" 5120 params['radius_das_require_event_timestamp'] = "1" 5121 hapd = hostapd.add_ap(apdev[0], params) 5122 5123 dev[0].hs20_enable() 5124 dev[0].connect("test-hs20", proto="RSN", key_mgmt="WPA-EAP", eap="TTLS", 5125 identity="hs20-t-c-test", password="password", 5126 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 5127 ieee80211w='2', scan_freq="2412") 5128 5129 ev = hapd.wait_event(["HS20-T-C-FILTERING-ADD"], timeout=5) 5130 if ev is None: 5131 raise Exception("Terms and Conditions filtering not enabled") 5132 if ev.split(' ')[1] != dev[0].own_addr(): 5133 raise Exception("Unexpected STA address for filtering: " + ev) 5134 5135 ev = dev[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout=5) 5136 if ev is None: 5137 raise Exception("Terms and Conditions Acceptance notification not received") 5138 url = "https://example.com/t_and_c?addr=%s&ap=123" % dev[0].own_addr() 5139 if url not in ev: 5140 raise Exception("Unexpected URL: " + ev) 5141 5142 dict = pyrad.dictionary.Dictionary("dictionary.radius") 5143 5144 srv = pyrad.client.Client(server="127.0.0.1", acctport=3799, 5145 secret=b"secret", dict=dict) 5146 srv.retries = 1 5147 srv.timeout = 1 5148 5149 sta = hapd.get_sta(dev[0].own_addr()) 5150 multi_sess_id = sta['authMultiSessionId'] 5151 5152 logger.info("CoA-Request with matching Acct-Session-Id") 5153 vsa = binascii.unhexlify('00009f68090600000000') 5154 req = radius_das.CoAPacket(dict=dict, secret=b"secret", 5155 NAS_IP_Address="127.0.0.1", 5156 Acct_Multi_Session_Id=multi_sess_id, 5157 Chargeable_User_Identity="hs20-cui", 5158 Event_Timestamp=int(time.time()), 5159 Vendor_Specific=vsa) 5160 reply = srv.SendPacket(req) 5161 logger.debug("RADIUS response from hostapd") 5162 for i in list(reply.keys()): 5163 logger.debug("%s: %s" % (i, reply[i])) 5164 if reply.code != pyrad.packet.CoAACK: 5165 raise Exception("CoA-Request failed") 5166 5167 ev = hapd.wait_event(["HS20-T-C-FILTERING-REMOVE"], timeout=5) 5168 if ev is None: 5169 raise Exception("Terms and Conditions filtering not disabled") 5170 if ev.split(' ')[1] != dev[0].own_addr(): 5171 raise Exception("Unexpected STA address for filtering: " + ev) 5172 5173def test_ap_hs20_terms_and_conditions_sql(dev, apdev, params): 5174 """Hotspot 2.0 Terms and Conditions using SQLite for user DB""" 5175 addr = dev[0].own_addr() 5176 run_ap_hs20_terms_and_conditions_sql(dev, apdev, params, 5177 "https://example.com/t_and_c?addr=@1@&ap=123", 5178 "https://example.com/t_and_c?addr=" + addr + "&ap=123") 5179 5180def test_ap_hs20_terms_and_conditions_sql2(dev, apdev, params): 5181 """Hotspot 2.0 Terms and Conditions using SQLite for user DB""" 5182 addr = dev[0].own_addr() 5183 run_ap_hs20_terms_and_conditions_sql(dev, apdev, params, 5184 "https://example.com/t_and_c?addr=@1@", 5185 "https://example.com/t_and_c?addr=" + addr) 5186 5187def run_ap_hs20_terms_and_conditions_sql(dev, apdev, params, url_template, 5188 url_expected): 5189 check_eap_capa(dev[0], "MSCHAPV2") 5190 try: 5191 import sqlite3 5192 except ImportError: 5193 raise HwsimSkip("No sqlite3 module available") 5194 dbfile = params['prefix'] + ".eap-user.db" 5195 try: 5196 os.remove(dbfile) 5197 except: 5198 pass 5199 con = sqlite3.connect(dbfile) 5200 with con: 5201 cur = con.cursor() 5202 cur.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, phase2 INTEGER, t_c_timestamp INTEGER)") 5203 cur.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)") 5204 cur.execute("INSERT INTO users(identity,methods,password,phase2) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1)") 5205 cur.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')") 5206 cur.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)") 5207 cur.execute("CREATE TABLE pending_tc(mac_addr TEXT PRIMARY KEY, identity TEXT)") 5208 cur.execute("CREATE TABLE current_sessions(mac_addr TEXT PRIMARY KEY, identity TEXT, start_time TEXT, nas TEXT, hs20_t_c_filtering BOOLEAN, waiting_coa_ack BOOLEAN, coa_ack_received BOOLEAN)") 5209 5210 5211 try: 5212 params = {"ssid": "as", "beacon_int": "2000", 5213 "radius_server_clients": "auth_serv/radius_clients.conf", 5214 "radius_server_auth_port": '18128', 5215 "eap_server": "1", 5216 "eap_user_file": "sqlite:" + dbfile, 5217 "ca_cert": "auth_serv/ca.pem", 5218 "server_cert": "auth_serv/server.pem", 5219 "private_key": "auth_serv/server.key"} 5220 params['hs20_t_c_server_url'] = url_template 5221 authsrv = hostapd.add_ap(apdev[1], params) 5222 5223 bssid = apdev[0]['bssid'] 5224 params = hs20_ap_params() 5225 params['auth_server_port'] = "18128" 5226 params['hs20_t_c_filename'] = 'terms-and-conditions' 5227 params['hs20_t_c_timestamp'] = '123456789' 5228 params['own_ip_addr'] = "127.0.0.1" 5229 params['radius_das_port'] = "3799" 5230 params['radius_das_client'] = "127.0.0.1 radius" 5231 params['radius_das_require_event_timestamp'] = "1" 5232 params['disable_pmksa_caching'] = '1' 5233 hapd = hostapd.add_ap(apdev[0], params) 5234 5235 dev[0].request("SET pmf 1") 5236 dev[0].hs20_enable() 5237 id = dev[0].add_cred_values({'realm': "example.com", 5238 'username': "user-mschapv2", 5239 'password': "password", 5240 'ca_cert': "auth_serv/ca.pem"}) 5241 interworking_select(dev[0], bssid, freq="2412") 5242 interworking_connect(dev[0], bssid, "TTLS") 5243 5244 ev = hapd.wait_event(["HS20-T-C-FILTERING-ADD"], timeout=5) 5245 if ev is None: 5246 raise Exception("Terms and Conditions filtering not enabled") 5247 hapd.dump_monitor() 5248 5249 ev = dev[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout=5) 5250 if ev is None: 5251 raise Exception("Terms and Conditions Acceptance notification not received") 5252 url = ev.split(' ')[1] 5253 if url != url_expected: 5254 raise Exception("Unexpected URL delivered to the client: %s (expected %s)" % (url, url_expected)) 5255 dev[0].dump_monitor() 5256 5257 with con: 5258 cur = con.cursor() 5259 cur.execute("SELECT * from current_sessions") 5260 rows = cur.fetchall() 5261 if len(rows) != 1: 5262 raise Exeception("Unexpected number of rows in current_sessions (%d; expected %d)" % (len(rows), 1)) 5263 logger.info("current_sessions: " + str(rows)) 5264 5265 tests = ["foo", "disconnect q", "coa %s" % dev[0].own_addr()] 5266 for t in tests: 5267 if "FAIL" not in authsrv.request("DAC_REQUEST " + t): 5268 raise Exception("Invalid DAC_REQUEST accepted: " + t) 5269 if "OK" not in authsrv.request("DAC_REQUEST coa %s t_c_clear" % dev[0].own_addr()): 5270 raise Exception("DAC_REQUEST failed") 5271 5272 ev = hapd.wait_event(["HS20-T-C-FILTERING-REMOVE"], timeout=5) 5273 if ev is None: 5274 raise Exception("Terms and Conditions filtering not disabled") 5275 if ev.split(' ')[1] != dev[0].own_addr(): 5276 raise Exception("Unexpected STA address for filtering: " + ev) 5277 5278 time.sleep(0.2) 5279 with con: 5280 cur = con.cursor() 5281 cur.execute("SELECT * from current_sessions") 5282 rows = cur.fetchall() 5283 if len(rows) != 1: 5284 raise Exeception("Unexpected number of rows in current_sessions (%d; expected %d)" % (len(rows), 1)) 5285 logger.info("current_sessions: " + str(rows)) 5286 if rows[0][4] != 0 or rows[0][5] != 0 or rows[0][6] != 1: 5287 raise Exception("Unexpected current_sessions information after CoA-ACK") 5288 5289 dev[0].request("DISCONNECT") 5290 dev[0].wait_disconnected() 5291 dev[0].dump_monitor() 5292 5293 # Simulate T&C server operation on user reading the updated version 5294 with con: 5295 cur = con.cursor() 5296 cur.execute("SELECT identity FROM pending_tc WHERE mac_addr='" + 5297 dev[0].own_addr() + "'") 5298 rows = cur.fetchall() 5299 if len(rows) != 1: 5300 raise Exception("No pending_tc entry found") 5301 if rows[0][0] != 'user-mschapv2': 5302 raise Exception("Unexpected pending_tc identity value") 5303 5304 cur.execute("UPDATE users SET t_c_timestamp=123456789 WHERE identity='user-mschapv2'") 5305 5306 dev[0].request("RECONNECT") 5307 dev[0].wait_connected() 5308 5309 ev = hapd.wait_event(["HS20-T-C-FILTERING-ADD"], timeout=0.1) 5310 if ev is not None: 5311 raise Exception("Terms and Conditions filtering enabled unexpectedly") 5312 hapd.dump_monitor() 5313 5314 ev = dev[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout=0.1) 5315 if ev is not None: 5316 raise Exception("Unexpected Terms and Conditions Acceptance notification") 5317 dev[0].dump_monitor() 5318 5319 dev[0].request("DISCONNECT") 5320 dev[0].wait_disconnected() 5321 dev[0].dump_monitor() 5322 5323 # New T&C available 5324 hapd.set('hs20_t_c_timestamp', '123456790') 5325 5326 dev[0].request("RECONNECT") 5327 dev[0].wait_connected() 5328 5329 ev = hapd.wait_event(["HS20-T-C-FILTERING-ADD"], timeout=5) 5330 if ev is None: 5331 raise Exception("Terms and Conditions filtering not enabled") 5332 hapd.dump_monitor() 5333 5334 ev = dev[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout=5) 5335 if ev is None: 5336 raise Exception("Terms and Conditions Acceptance notification not received (2)") 5337 dev[0].dump_monitor() 5338 5339 dev[0].request("DISCONNECT") 5340 dev[0].wait_disconnected() 5341 dev[0].dump_monitor() 5342 5343 # Simulate T&C server operation on user reading the updated version 5344 with con: 5345 cur = con.cursor() 5346 cur.execute("UPDATE users SET t_c_timestamp=123456790 WHERE identity='user-mschapv2'") 5347 5348 dev[0].request("RECONNECT") 5349 dev[0].wait_connected() 5350 5351 ev = hapd.wait_event(["HS20-T-C-FILTERING-ADD"], timeout=0.1) 5352 if ev is not None: 5353 raise Exception("Terms and Conditions filtering enabled unexpectedly") 5354 hapd.dump_monitor() 5355 5356 ev = dev[0].wait_event(["HS20-T-C-ACCEPTANCE"], timeout=0.1) 5357 if ev is not None: 5358 raise Exception("Unexpected Terms and Conditions Acceptance notification (2)") 5359 dev[0].dump_monitor() 5360 finally: 5361 os.remove(dbfile) 5362 dev[0].request("SET pmf 0") 5363 5364def test_ap_hs20_release_number_1(dev, apdev): 5365 """Hotspot 2.0 with AP claiming support for Release 1""" 5366 run_ap_hs20_release_number(dev, apdev, 1) 5367 5368def test_ap_hs20_release_number_2(dev, apdev): 5369 """Hotspot 2.0 with AP claiming support for Release 2""" 5370 run_ap_hs20_release_number(dev, apdev, 2) 5371 5372def test_ap_hs20_release_number_3(dev, apdev): 5373 """Hotspot 2.0 with AP claiming support for Release 3""" 5374 run_ap_hs20_release_number(dev, apdev, 3) 5375 5376def run_ap_hs20_release_number(dev, apdev, release): 5377 check_eap_capa(dev[0], "MSCHAPV2") 5378 eap_test(dev[0], apdev[0], "21[3:26][6:7][99:99]", "TTLS", "user", 5379 release=release) 5380 rel = dev[0].get_status_field('hs20') 5381 if rel != str(release): 5382 raise Exception("Unexpected release number indicated: " + rel) 5383 5384def test_ap_hs20_missing_pmf(dev, apdev): 5385 """Hotspot 2.0 connection attempt without PMF""" 5386 check_eap_capa(dev[0], "MSCHAPV2") 5387 bssid = apdev[0]['bssid'] 5388 params = hs20_ap_params() 5389 params['hessid'] = bssid 5390 params['disable_dgaf'] = '1' 5391 hostapd.add_ap(apdev[0], params) 5392 5393 dev[0].hs20_enable() 5394 dev[0].connect("test-hs20", proto="RSN", key_mgmt="WPA-EAP", eap="TTLS", 5395 ieee80211w="0", 5396 identity="hs20-test", password="password", 5397 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 5398 scan_freq="2412", update_identifier="54321", 5399 roaming_consortium_selection="1020304050", 5400 wait_connect=False) 5401 ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=10) 5402 dev[0].request("DISCONNECT") 5403 if ev is None: 5404 raise Exception("Association rejection not reported") 5405 if "status_code=31" not in ev: 5406 raise Exception("Unexpected rejection reason: " + ev) 5407 5408def test_ap_hs20_open_osu_association(dev, apdev): 5409 """Hotspot 2.0 open OSU association""" 5410 try: 5411 run_ap_hs20_open_osu_association(dev, apdev) 5412 finally: 5413 dev[0].request("VENDOR_ELEM_REMOVE 13 *") 5414 5415def run_ap_hs20_open_osu_association(dev, apdev): 5416 params = {"ssid": "HS 2.0 OSU open"} 5417 hostapd.add_ap(apdev[0], params) 5418 dev[0].connect("HS 2.0 OSU open", key_mgmt="NONE", scan_freq="2412") 5419 dev[0].request("REMOVE_NETWORK all") 5420 dev[0].wait_disconnected() 5421 dev[0].dump_monitor() 5422 # Test with unexpected Hotspot 2.0 Indication element in Assoc Req 5423 dev[0].request("VENDOR_ELEM_ADD 13 dd07506f9a10220000") 5424 dev[0].connect("HS 2.0 OSU open", key_mgmt="NONE", scan_freq="2412") 5425