1# wpa_supplicant D-Bus interface tests 2# Copyright (c) 2014-2015, 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 7import binascii 8import logging 9logger = logging.getLogger() 10import subprocess 11import time 12import shutil 13import struct 14import sys 15from test_ap_hs20 import hs20_ap_params 16from test_nan_usd import check_nan_usd_capab, split_nan_event 17 18try: 19 if sys.version_info[0] > 2: 20 from gi.repository import GObject as gobject 21 else: 22 import gobject 23 import dbus 24 dbus_imported = True 25except ImportError: 26 dbus_imported = False 27 28import hostapd 29from wpasupplicant import WpaSupplicant 30from utils import * 31from p2p_utils import * 32from test_ap_tdls import connect_2sta_open 33from test_ap_eap import check_altsubject_match_support, check_eap_capa 34from test_nfc_p2p import set_ip_addr_info 35from test_wpas_mesh import check_mesh_support, add_open_mesh_network 36 37WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1" 38WPAS_DBUS_PATH = "/fi/w1/wpa_supplicant1" 39WPAS_DBUS_IFACE = "fi.w1.wpa_supplicant1.Interface" 40WPAS_DBUS_IFACE_WPS = WPAS_DBUS_IFACE + ".WPS" 41WPAS_DBUS_NETWORK = "fi.w1.wpa_supplicant1.Network" 42WPAS_DBUS_BSS = "fi.w1.wpa_supplicant1.BSS" 43WPAS_DBUS_IFACE_P2PDEVICE = WPAS_DBUS_IFACE + ".P2PDevice" 44WPAS_DBUS_P2P_PEER = "fi.w1.wpa_supplicant1.Peer" 45WPAS_DBUS_GROUP = "fi.w1.wpa_supplicant1.Group" 46WPAS_DBUS_PERSISTENT_GROUP = "fi.w1.wpa_supplicant1.PersistentGroup" 47WPAS_DBUS_IFACE_MESH = WPAS_DBUS_IFACE + ".Mesh" 48 49def prepare_dbus(dev): 50 if not dbus_imported: 51 logger.info("No dbus module available") 52 raise HwsimSkip("No dbus module available") 53 try: 54 from dbus.mainloop.glib import DBusGMainLoop 55 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 56 bus = dbus.SystemBus() 57 wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH) 58 wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE) 59 path = wpas.GetInterface(dev.ifname) 60 if_obj = bus.get_object(WPAS_DBUS_SERVICE, path) 61 return (bus, wpas_obj, path, if_obj) 62 except Exception as e: 63 raise HwsimSkip("Could not connect to D-Bus: %s" % e) 64 65class TestDbus(object): 66 def __init__(self, bus): 67 self.loop = gobject.MainLoop() 68 self.signals = [] 69 self.bus = bus 70 71 def __exit__(self, type, value, traceback): 72 for s in self.signals: 73 s.remove() 74 75 def add_signal(self, handler, interface, name, byte_arrays=False): 76 s = self.bus.add_signal_receiver(handler, dbus_interface=interface, 77 signal_name=name, 78 byte_arrays=byte_arrays) 79 self.signals.append(s) 80 81 def timeout(self, *args): 82 logger.debug("timeout") 83 self.loop.quit() 84 return False 85 86class alloc_fail_dbus(object): 87 def __init__(self, dev, count, funcs, operation="Operation", 88 expected="NoMemory"): 89 self._dev = dev 90 self._count = count 91 self._funcs = funcs 92 self._operation = operation 93 self._expected = expected 94 def __enter__(self): 95 cmd = "TEST_ALLOC_FAIL %d:%s" % (self._count, self._funcs) 96 if "OK" not in self._dev.request(cmd): 97 raise HwsimSkip("TEST_ALLOC_FAIL not supported") 98 def __exit__(self, type, value, traceback): 99 if type is None: 100 raise Exception("%s succeeded during out-of-memory" % self._operation) 101 if type == dbus.exceptions.DBusException and self._expected in str(value): 102 return True 103 if self._dev.request("GET_ALLOC_FAIL") != "0:%s" % self._funcs: 104 raise Exception("%s did not trigger allocation failure" % self._operation) 105 return False 106 107def start_ap(ap, ssid="test-wps", 108 ap_uuid="27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"): 109 params = {"ssid": ssid, "eap_server": "1", "wps_state": "2", 110 "wpa_passphrase": "12345678", "wpa": "2", 111 "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP", 112 "ap_pin": "12345670", "uuid": ap_uuid} 113 return hostapd.add_ap(ap, params) 114 115def test_dbus_getall(dev, apdev): 116 """D-Bus GetAll""" 117 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 118 119 dev[0].flush_scan_cache() 120 121 props = wpas_obj.GetAll(WPAS_DBUS_SERVICE, 122 dbus_interface=dbus.PROPERTIES_IFACE) 123 logger.debug("GetAll(fi.w1.wpa.supplicant1, /fi/w1/wpa_supplicant1) ==> " + str(props)) 124 125 props = if_obj.GetAll(WPAS_DBUS_IFACE, 126 dbus_interface=dbus.PROPERTIES_IFACE) 127 logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_IFACE, path, str(props))) 128 129 props = if_obj.GetAll(WPAS_DBUS_IFACE_WPS, 130 dbus_interface=dbus.PROPERTIES_IFACE) 131 logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_IFACE_WPS, path, str(props))) 132 133 res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs', 134 dbus_interface=dbus.PROPERTIES_IFACE) 135 if len(res) != 0: 136 raise Exception("Unexpected BSSs entry: " + str(res)) 137 138 res = if_obj.Get(WPAS_DBUS_IFACE, 'Networks', 139 dbus_interface=dbus.PROPERTIES_IFACE) 140 if len(res) != 0: 141 raise Exception("Unexpected Networks entry: " + str(res)) 142 143 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 144 bssid = apdev[0]['bssid'] 145 dev[0].scan_for_bss(bssid, freq=2412) 146 id = dev[0].add_network() 147 dev[0].set_network(id, "disabled", "0") 148 dev[0].set_network_quoted(id, "ssid", "test") 149 150 res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs', 151 dbus_interface=dbus.PROPERTIES_IFACE) 152 if len(res) < 1: 153 raise Exception("Missing BSSs entry: " + str(res)) 154 if len(res) > 1: 155 raise Exception("Too manu BSSs entries: " + str(res)) 156 bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0]) 157 props = bss_obj.GetAll(WPAS_DBUS_BSS, dbus_interface=dbus.PROPERTIES_IFACE) 158 logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_BSS, res[0], str(props))) 159 bssid_str = '' 160 for item in props['BSSID']: 161 if len(bssid_str) > 0: 162 bssid_str += ':' 163 bssid_str += '%02x' % item 164 if bssid_str != bssid: 165 raise Exception("Unexpected BSSID in BSSs entry") 166 167 res = if_obj.Get(WPAS_DBUS_IFACE, 'Networks', 168 dbus_interface=dbus.PROPERTIES_IFACE) 169 if len(res) != 1: 170 raise Exception("Missing Networks entry: " + str(res)) 171 net_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0]) 172 props = net_obj.GetAll(WPAS_DBUS_NETWORK, 173 dbus_interface=dbus.PROPERTIES_IFACE) 174 logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_NETWORK, res[0], str(props))) 175 ssid = props['Properties']['ssid'] 176 if ssid != '"test"': 177 raise Exception("Unexpected SSID in network entry") 178 179def test_dbus_getall_oom(dev, apdev): 180 """D-Bus GetAll wpa_config_get_all() OOM""" 181 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 182 183 id = dev[0].add_network() 184 dev[0].set_network(id, "disabled", "0") 185 dev[0].set_network_quoted(id, "ssid", "test") 186 187 res = if_obj.Get(WPAS_DBUS_IFACE, 'Networks', 188 dbus_interface=dbus.PROPERTIES_IFACE) 189 if len(res) != 1: 190 raise Exception("Missing Networks entry: " + str(res)) 191 net_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0]) 192 for i in range(1, 50): 193 with alloc_fail(dev[0], i, "wpa_config_get_all"): 194 try: 195 props = net_obj.GetAll(WPAS_DBUS_NETWORK, 196 dbus_interface=dbus.PROPERTIES_IFACE) 197 except dbus.exceptions.DBusException as e: 198 pass 199 200def dbus_get(dbus, wpas_obj, prop, expect=None, byte_arrays=False): 201 val = wpas_obj.Get(WPAS_DBUS_SERVICE, prop, 202 dbus_interface=dbus.PROPERTIES_IFACE, 203 byte_arrays=byte_arrays) 204 if expect is not None and val != expect: 205 raise Exception("Unexpected %s: %s (expected: %s)" % 206 (prop, str(val), str(expect))) 207 return val 208 209def dbus_set(dbus, wpas_obj, prop, val): 210 wpas_obj.Set(WPAS_DBUS_SERVICE, prop, val, 211 dbus_interface=dbus.PROPERTIES_IFACE) 212 213def test_dbus_properties(dev, apdev): 214 """D-Bus Get/Set fi.w1.wpa_supplicant1 properties""" 215 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 216 217 dbus_get(dbus, wpas_obj, "DebugLevel", expect="msgdump") 218 dbus_set(dbus, wpas_obj, "DebugLevel", "debug") 219 dbus_get(dbus, wpas_obj, "DebugLevel", expect="debug") 220 for (val, err) in [(3, "Error.Failed: wrong property type"), 221 ("foo", "Error.Failed: wrong debug level value")]: 222 try: 223 dbus_set(dbus, wpas_obj, "DebugLevel", val) 224 raise Exception("Invalid DebugLevel value accepted: " + str(val)) 225 except dbus.exceptions.DBusException as e: 226 if err not in str(e): 227 raise Exception("Unexpected error message: " + str(e)) 228 dbus_set(dbus, wpas_obj, "DebugLevel", "msgdump") 229 dbus_get(dbus, wpas_obj, "DebugLevel", expect="msgdump") 230 231 dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=True) 232 dbus_set(dbus, wpas_obj, "DebugTimestamp", False) 233 dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=False) 234 try: 235 dbus_set(dbus, wpas_obj, "DebugTimestamp", "foo") 236 raise Exception("Invalid DebugTimestamp value accepted") 237 except dbus.exceptions.DBusException as e: 238 if "Error.Failed: wrong property type" not in str(e): 239 raise Exception("Unexpected error message: " + str(e)) 240 dbus_set(dbus, wpas_obj, "DebugTimestamp", True) 241 dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=True) 242 243 dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=True) 244 dbus_set(dbus, wpas_obj, "DebugShowKeys", False) 245 dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=False) 246 try: 247 dbus_set(dbus, wpas_obj, "DebugShowKeys", "foo") 248 raise Exception("Invalid DebugShowKeys value accepted") 249 except dbus.exceptions.DBusException as e: 250 if "Error.Failed: wrong property type" not in str(e): 251 raise Exception("Unexpected error message: " + str(e)) 252 dbus_set(dbus, wpas_obj, "DebugShowKeys", True) 253 dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=True) 254 255 res = dbus_get(dbus, wpas_obj, "Interfaces") 256 if len(res) != 1: 257 raise Exception("Unexpected Interfaces value: " + str(res)) 258 259 res = dbus_get(dbus, wpas_obj, "EapMethods") 260 if len(res) < 5 or "TTLS" not in res: 261 raise Exception("Unexpected EapMethods value: " + str(res)) 262 263 res = dbus_get(dbus, wpas_obj, "Capabilities") 264 if len(res) < 2 or "p2p" not in res: 265 raise Exception("Unexpected Capabilities value: " + str(res)) 266 267 dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True) 268 val = binascii.unhexlify("010006020304050608") 269 dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(val)) 270 res = dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True) 271 if val != res: 272 raise Exception("WFDIEs value changed") 273 try: 274 dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(b'\x00')) 275 raise Exception("Invalid WFDIEs value accepted") 276 except dbus.exceptions.DBusException as e: 277 if "InvalidArgs" not in str(e): 278 raise Exception("Unexpected error message: " + str(e)) 279 dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(b'')) 280 dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(val)) 281 dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(b'')) 282 res = dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True) 283 if len(res) != 0: 284 raise Exception("WFDIEs not cleared properly") 285 286 res = dbus_get(dbus, wpas_obj, "EapMethods") 287 try: 288 dbus_set(dbus, wpas_obj, "EapMethods", res) 289 raise Exception("Invalid Set accepted") 290 except dbus.exceptions.DBusException as e: 291 if "InvalidArgs: Property is read-only" not in str(e): 292 raise Exception("Unexpected error message: " + str(e)) 293 294 try: 295 wpas_obj.SetFoo(WPAS_DBUS_SERVICE, "DebugShowKeys", True, 296 dbus_interface=dbus.PROPERTIES_IFACE) 297 raise Exception("Unknown method accepted") 298 except dbus.exceptions.DBusException as e: 299 if "UnknownMethod" not in str(e): 300 raise Exception("Unexpected error message: " + str(e)) 301 302 try: 303 wpas_obj.Get("foo", "DebugShowKeys", 304 dbus_interface=dbus.PROPERTIES_IFACE) 305 raise Exception("Invalid Get accepted") 306 except dbus.exceptions.DBusException as e: 307 if "InvalidArgs: No such property" not in str(e): 308 raise Exception("Unexpected error message: " + str(e)) 309 310 test_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH, 311 introspect=False) 312 try: 313 test_obj.Get(123, "DebugShowKeys", 314 dbus_interface=dbus.PROPERTIES_IFACE) 315 raise Exception("Invalid Get accepted") 316 except dbus.exceptions.DBusException as e: 317 if "InvalidArgs: Invalid arguments" not in str(e): 318 raise Exception("Unexpected error message: " + str(e)) 319 try: 320 test_obj.Get(WPAS_DBUS_SERVICE, 123, 321 dbus_interface=dbus.PROPERTIES_IFACE) 322 raise Exception("Invalid Get accepted") 323 except dbus.exceptions.DBusException as e: 324 if "InvalidArgs: Invalid arguments" not in str(e): 325 raise Exception("Unexpected error message: " + str(e)) 326 327 try: 328 wpas_obj.Set(WPAS_DBUS_SERVICE, "WFDIEs", 329 dbus.ByteArray(b'', variant_level=2), 330 dbus_interface=dbus.PROPERTIES_IFACE) 331 raise Exception("Invalid Set accepted") 332 except dbus.exceptions.DBusException as e: 333 if "InvalidArgs: invalid message format" not in str(e): 334 raise Exception("Unexpected error message: " + str(e)) 335 336def test_dbus_set_global_properties(dev, apdev): 337 """D-Bus Get/Set fi.w1.wpa_supplicant1 interface global properties""" 338 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 339 340 dev[0].set("model_name", "") 341 props = [('Okc', '0', '1'), ('ModelName', '', 'blahblahblah')] 342 343 for p in props: 344 res = if_obj.Get(WPAS_DBUS_IFACE, p[0], 345 dbus_interface=dbus.PROPERTIES_IFACE) 346 if res != p[1]: 347 raise Exception("Unexpected " + p[0] + " value: " + str(res)) 348 349 if_obj.Set(WPAS_DBUS_IFACE, p[0], p[2], 350 dbus_interface=dbus.PROPERTIES_IFACE) 351 352 res = if_obj.Get(WPAS_DBUS_IFACE, p[0], 353 dbus_interface=dbus.PROPERTIES_IFACE) 354 if res != p[2]: 355 raise Exception("Unexpected " + p[0] + " value after set: " + str(res)) 356 dev[0].set("model_name", "") 357 358def test_dbus_invalid_method(dev, apdev): 359 """D-Bus invalid method""" 360 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 361 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 362 363 try: 364 wps.Foo() 365 raise Exception("Unknown method accepted") 366 except dbus.exceptions.DBusException as e: 367 if "UnknownMethod" not in str(e): 368 raise Exception("Unexpected error message: " + str(e)) 369 370 test_obj = bus.get_object(WPAS_DBUS_SERVICE, path, introspect=False) 371 test_wps = dbus.Interface(test_obj, WPAS_DBUS_IFACE_WPS) 372 try: 373 test_wps.Start(123) 374 raise Exception("WPS.Start with incorrect signature accepted") 375 except dbus.exceptions.DBusException as e: 376 if "InvalidArgs: Invalid arg" not in str(e): 377 raise Exception("Unexpected error message: " + str(e)) 378 379def test_dbus_get_set_wps(dev, apdev): 380 """D-Bus Get/Set for WPS properties""" 381 try: 382 _test_dbus_get_set_wps(dev, apdev) 383 finally: 384 dev[0].request("SET wps_cred_processing 0") 385 dev[0].request("SET config_methods display keypad virtual_display nfc_interface p2ps") 386 dev[0].set("device_name", "Device A") 387 dev[0].set("manufacturer", "") 388 dev[0].set("model_name", "") 389 dev[0].set("model_number", "") 390 dev[0].set("serial_number", "") 391 dev[0].set("device_type", "0-00000000-0") 392 393def _test_dbus_get_set_wps(dev, apdev): 394 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 395 396 if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods", 397 dbus_interface=dbus.PROPERTIES_IFACE) 398 399 val = "display keypad virtual_display nfc_interface" 400 dev[0].request("SET config_methods " + val) 401 402 config = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods", 403 dbus_interface=dbus.PROPERTIES_IFACE) 404 if config != val: 405 raise Exception("Unexpected Get(ConfigMethods) result: " + config) 406 407 val2 = "push_button display" 408 if_obj.Set(WPAS_DBUS_IFACE_WPS, "ConfigMethods", val2, 409 dbus_interface=dbus.PROPERTIES_IFACE) 410 config = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods", 411 dbus_interface=dbus.PROPERTIES_IFACE) 412 if config != val2: 413 raise Exception("Unexpected Get(ConfigMethods) result after Set: " + config) 414 415 dev[0].request("SET config_methods " + val) 416 417 for i in range(3): 418 dev[0].request("SET wps_cred_processing " + str(i)) 419 val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials", 420 dbus_interface=dbus.PROPERTIES_IFACE) 421 expected_val = False if i == 1 else True 422 if val != expected_val: 423 raise Exception("Unexpected Get(ProcessCredentials) result({}): {}".format(i, val)) 424 425 tests = [("device_name", "DeviceName"), 426 ("manufacturer", "Manufacturer"), 427 ("model_name", "ModelName"), 428 ("model_number", "ModelNumber"), 429 ("serial_number", "SerialNumber")] 430 431 for f1, f2 in tests: 432 val2 = "test-value-test" 433 dev[0].set(f1, val2) 434 val = if_obj.Get(WPAS_DBUS_IFACE_WPS, f2, 435 dbus_interface=dbus.PROPERTIES_IFACE) 436 if val != val2: 437 raise Exception("Get(%s) returned unexpected value" % f2) 438 val2 = "TEST-value" 439 if_obj.Set(WPAS_DBUS_IFACE_WPS, f2, val2, 440 dbus_interface=dbus.PROPERTIES_IFACE) 441 val = if_obj.Get(WPAS_DBUS_IFACE_WPS, f2, 442 dbus_interface=dbus.PROPERTIES_IFACE) 443 if val != val2: 444 raise Exception("Get(%s) returned unexpected value after Set" % f2) 445 446 dev[0].set("device_type", "5-0050F204-1") 447 val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "DeviceType", 448 dbus_interface=dbus.PROPERTIES_IFACE) 449 if val[0] != 0x00 or val[1] != 0x05 != val[2] != 0x00 or val[3] != 0x50 or val[4] != 0xf2 or val[5] != 0x04 or val[6] != 0x00 or val[7] != 0x01: 450 raise Exception("DeviceType mismatch") 451 if_obj.Set(WPAS_DBUS_IFACE_WPS, "DeviceType", val, 452 dbus_interface=dbus.PROPERTIES_IFACE) 453 val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "DeviceType", 454 dbus_interface=dbus.PROPERTIES_IFACE) 455 if val[0] != 0x00 or val[1] != 0x05 != val[2] != 0x00 or val[3] != 0x50 or val[4] != 0xf2 or val[5] != 0x04 or val[6] != 0x00 or val[7] != 0x01: 456 raise Exception("DeviceType mismatch after Set") 457 458 val2 = b'\x01\x02\x03\x04\x05\x06\x07\x08' 459 if_obj.Set(WPAS_DBUS_IFACE_WPS, "DeviceType", dbus.ByteArray(val2), 460 dbus_interface=dbus.PROPERTIES_IFACE) 461 val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "DeviceType", 462 dbus_interface=dbus.PROPERTIES_IFACE, 463 byte_arrays=True) 464 if val != val2: 465 raise Exception("DeviceType mismatch after Set (2)") 466 467 class TestDbusGetSet(TestDbus): 468 def __init__(self, bus): 469 TestDbus.__init__(self, bus) 470 self.signal_received = False 471 self.signal_received_deprecated = False 472 self.sets_done = False 473 474 def __enter__(self): 475 gobject.timeout_add(1, self.run_sets) 476 gobject.timeout_add(1000, self.timeout) 477 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE_WPS, 478 "PropertiesChanged") 479 self.add_signal(self.propertiesChanged2, dbus.PROPERTIES_IFACE, 480 "PropertiesChanged") 481 self.loop.run() 482 return self 483 484 def propertiesChanged(self, properties): 485 logger.debug("PropertiesChanged: " + str(properties)) 486 if "ProcessCredentials" in properties: 487 self.signal_received_deprecated = True 488 if self.sets_done and self.signal_received: 489 self.loop.quit() 490 491 def propertiesChanged2(self, interface_name, changed_properties, 492 invalidated_properties): 493 logger.debug("propertiesChanged2: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties))) 494 if interface_name != WPAS_DBUS_IFACE_WPS: 495 return 496 if "ProcessCredentials" in changed_properties: 497 self.signal_received = True 498 if self.sets_done and self.signal_received_deprecated: 499 self.loop.quit() 500 501 def run_sets(self, *args): 502 logger.debug("run_sets") 503 if_obj.Set(WPAS_DBUS_IFACE_WPS, "ProcessCredentials", 504 dbus.Boolean(1), 505 dbus_interface=dbus.PROPERTIES_IFACE) 506 if if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials", 507 dbus_interface=dbus.PROPERTIES_IFACE) != True: 508 raise Exception("Unexpected Get(ProcessCredentials) result after Set") 509 if_obj.Set(WPAS_DBUS_IFACE_WPS, "ProcessCredentials", 510 dbus.Boolean(0), 511 dbus_interface=dbus.PROPERTIES_IFACE) 512 if if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials", 513 dbus_interface=dbus.PROPERTIES_IFACE) != False: 514 raise Exception("Unexpected Get(ProcessCredentials) result after Set") 515 516 self.dbus_sets_done = True 517 return False 518 519 def success(self): 520 return self.signal_received and self.signal_received_deprecated 521 522 with TestDbusGetSet(bus) as t: 523 if not t.success(): 524 raise Exception("No signal received for ProcessCredentials change") 525 526def test_dbus_wps_invalid(dev, apdev): 527 """D-Bus invaldi WPS operation""" 528 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 529 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 530 531 failures = [{'Role': 'foo', 'Type': 'pbc'}, 532 {'Role': 123, 'Type': 'pbc'}, 533 {'Type': 'pbc'}, 534 {'Role': 'enrollee'}, 535 {'Role': 'registrar'}, 536 {'Role': 'enrollee', 'Type': 123}, 537 {'Role': 'enrollee', 'Type': 'foo'}, 538 {'Role': 'enrollee', 'Type': 'pbc', 539 'Bssid': '02:33:44:55:66:77'}, 540 {'Role': 'enrollee', 'Type': 'pin', 'Pin': 123}, 541 {'Role': 'enrollee', 'Type': 'pbc', 542 'Bssid': dbus.ByteArray(b'12345')}, 543 {'Role': 'enrollee', 'Type': 'pbc', 544 'P2PDeviceAddress': 12345}, 545 {'Role': 'enrollee', 'Type': 'pbc', 546 'P2PDeviceAddress': dbus.ByteArray(b'12345')}, 547 {'Role': 'enrollee', 'Type': 'pbc', 'Foo': 'bar'}] 548 for args in failures: 549 try: 550 wps.Start(args) 551 raise Exception("Invalid WPS.Start() arguments accepted: " + str(args)) 552 except dbus.exceptions.DBusException as e: 553 if not str(e).startswith("fi.w1.wpa_supplicant1.InvalidArgs"): 554 raise Exception("Unexpected error message: " + str(e)) 555 556def test_dbus_wps_oom(dev, apdev): 557 """D-Bus WPS operation (OOM)""" 558 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 559 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 560 561 with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_getter_state", "Get"): 562 if_obj.Get(WPAS_DBUS_IFACE, "State", 563 dbus_interface=dbus.PROPERTIES_IFACE) 564 565 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 566 bssid = apdev[0]['bssid'] 567 dev[0].scan_for_bss(bssid, freq=2412) 568 569 time.sleep(0.05) 570 for i in range(1, 3): 571 with alloc_fail_dbus(dev[0], i, "=wpas_dbus_getter_bsss", "Get"): 572 if_obj.Get(WPAS_DBUS_IFACE, "BSSs", 573 dbus_interface=dbus.PROPERTIES_IFACE) 574 575 res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs', 576 dbus_interface=dbus.PROPERTIES_IFACE) 577 bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0]) 578 with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_getter_bss_rates", "Get"): 579 bss_obj.Get(WPAS_DBUS_BSS, "Rates", 580 dbus_interface=dbus.PROPERTIES_IFACE) 581 with alloc_fail(dev[0], 1, 582 "wpa_bss_get_bit_rates;wpas_dbus_getter_bss_rates"): 583 try: 584 bss_obj.Get(WPAS_DBUS_BSS, "Rates", 585 dbus_interface=dbus.PROPERTIES_IFACE) 586 except dbus.exceptions.DBusException as e: 587 pass 588 589 id = dev[0].add_network() 590 dev[0].set_network(id, "disabled", "0") 591 dev[0].set_network_quoted(id, "ssid", "test") 592 593 for i in range(1, 3): 594 with alloc_fail_dbus(dev[0], i, "=wpas_dbus_getter_networks", "Get"): 595 if_obj.Get(WPAS_DBUS_IFACE, "Networks", 596 dbus_interface=dbus.PROPERTIES_IFACE) 597 598 with alloc_fail_dbus(dev[0], 1, "wpas_dbus_getter_interfaces", "Get"): 599 dbus_get(dbus, wpas_obj, "Interfaces") 600 601 for i in range(1, 6): 602 with alloc_fail_dbus(dev[0], i, "=eap_get_names_as_string_array;wpas_dbus_getter_eap_methods", "Get"): 603 dbus_get(dbus, wpas_obj, "EapMethods") 604 605 with alloc_fail_dbus(dev[0], 1, "wpas_dbus_setter_config_methods", "Set", 606 expected="Error.Failed: Failed to set property"): 607 val2 = "push_button display" 608 if_obj.Set(WPAS_DBUS_IFACE_WPS, "ConfigMethods", val2, 609 dbus_interface=dbus.PROPERTIES_IFACE) 610 611 with alloc_fail_dbus(dev[0], 1, "=wpa_config_add_network;wpas_dbus_handler_wps_start", 612 "WPS.Start", 613 expected="UnknownError: WPS start failed"): 614 wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670'}) 615 616def test_dbus_wps_pbc(dev, apdev): 617 """D-Bus WPS/PBC operation and signals""" 618 try: 619 _test_dbus_wps_pbc(dev, apdev) 620 finally: 621 dev[0].request("SET wps_cred_processing 0") 622 623def _test_dbus_wps_pbc(dev, apdev): 624 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 625 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 626 627 hapd = start_ap(apdev[0]) 628 hapd.request("WPS_PBC") 629 bssid = apdev[0]['bssid'] 630 dev[0].flush_scan_cache() 631 dev[0].scan_for_bss(bssid, freq="2412") 632 dev[0].request("SET wps_cred_processing 2") 633 634 res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs', 635 dbus_interface=dbus.PROPERTIES_IFACE) 636 if len(res) != 1: 637 raise Exception("Missing BSSs entry: " + str(res)) 638 bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0]) 639 props = bss_obj.GetAll(WPAS_DBUS_BSS, dbus_interface=dbus.PROPERTIES_IFACE) 640 logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_BSS, res[0], str(props))) 641 if 'WPS' not in props: 642 raise Exception("No WPS information in the BSS entry") 643 if 'Type' not in props['WPS']: 644 raise Exception("No Type field in the WPS dictionary") 645 if props['WPS']['Type'] != 'pbc': 646 raise Exception("Unexpected WPS Type: " + props['WPS']['Type']) 647 648 class TestDbusWps(TestDbus): 649 def __init__(self, bus, wps): 650 TestDbus.__init__(self, bus) 651 self.success_seen = False 652 self.credentials_received = False 653 self.wps = wps 654 655 def __enter__(self): 656 gobject.timeout_add(1, self.start_pbc) 657 gobject.timeout_add(15000, self.timeout) 658 self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event") 659 self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS, 660 "Credentials") 661 self.loop.run() 662 return self 663 664 def wpsEvent(self, name, args): 665 logger.debug("wpsEvent: %s args='%s'" % (name, str(args))) 666 if name == "success": 667 self.success_seen = True 668 if self.credentials_received: 669 self.loop.quit() 670 671 def credentials(self, args): 672 logger.debug("credentials: " + str(args)) 673 self.credentials_received = True 674 if self.success_seen: 675 self.loop.quit() 676 677 def start_pbc(self, *args): 678 logger.debug("start_pbc") 679 self.wps.Start({'Role': 'enrollee', 'Type': 'pbc'}) 680 return False 681 682 def success(self): 683 return self.success_seen and self.credentials_received 684 685 with TestDbusWps(bus, wps) as t: 686 if not t.success(): 687 raise Exception("Failure in D-Bus operations") 688 689 dev[0].wait_connected(timeout=10) 690 dev[0].request("DISCONNECT") 691 hapd.disable() 692 dev[0].flush_scan_cache() 693 694def test_dbus_wps_pbc_overlap(dev, apdev): 695 """D-Bus WPS/PBC operation and signal for PBC overlap""" 696 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 697 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 698 699 hapd = start_ap(apdev[0]) 700 hapd2 = start_ap(apdev[1], ssid="test-wps2", 701 ap_uuid="27ea801a-9e5c-4e73-bd82-f89cbcd10d7f") 702 hapd.request("WPS_PBC") 703 hapd2.request("WPS_PBC") 704 bssid = apdev[0]['bssid'] 705 dev[0].scan_for_bss(bssid, freq="2412") 706 bssid2 = apdev[1]['bssid'] 707 dev[0].scan_for_bss(bssid2, freq="2412") 708 709 class TestDbusWps(TestDbus): 710 def __init__(self, bus, wps): 711 TestDbus.__init__(self, bus) 712 self.overlap_seen = False 713 self.wps = wps 714 715 def __enter__(self): 716 gobject.timeout_add(1, self.start_pbc) 717 gobject.timeout_add(15000, self.timeout) 718 self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event") 719 self.loop.run() 720 return self 721 722 def wpsEvent(self, name, args): 723 logger.debug("wpsEvent: %s args='%s'" % (name, str(args))) 724 if name == "pbc-overlap": 725 self.overlap_seen = True 726 self.loop.quit() 727 728 def start_pbc(self, *args): 729 logger.debug("start_pbc") 730 self.wps.Start({'Role': 'enrollee', 'Type': 'pbc'}) 731 return False 732 733 def success(self): 734 return self.overlap_seen 735 736 with TestDbusWps(bus, wps) as t: 737 if not t.success(): 738 raise Exception("Failure in D-Bus operations") 739 740 dev[0].request("WPS_CANCEL") 741 dev[0].request("DISCONNECT") 742 hapd.disable() 743 hapd2.disable() 744 dev[0].flush_scan_cache() 745 746def test_dbus_wps_pin(dev, apdev): 747 """D-Bus WPS/PIN operation and signals""" 748 try: 749 _test_dbus_wps_pin(dev, apdev) 750 finally: 751 dev[0].request("SET wps_cred_processing 0") 752 753def _test_dbus_wps_pin(dev, apdev): 754 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 755 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 756 757 hapd = start_ap(apdev[0]) 758 hapd.request("WPS_PIN any 12345670") 759 bssid = apdev[0]['bssid'] 760 dev[0].scan_for_bss(bssid, freq="2412") 761 dev[0].request("SET wps_cred_processing 2") 762 763 class TestDbusWps(TestDbus): 764 def __init__(self, bus): 765 TestDbus.__init__(self, bus) 766 self.success_seen = False 767 self.credentials_received = False 768 769 def __enter__(self): 770 gobject.timeout_add(1, self.start_pin) 771 gobject.timeout_add(15000, self.timeout) 772 self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event") 773 self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS, 774 "Credentials") 775 self.loop.run() 776 return self 777 778 def wpsEvent(self, name, args): 779 logger.debug("wpsEvent: %s args='%s'" % (name, str(args))) 780 if name == "success": 781 self.success_seen = True 782 if self.credentials_received: 783 self.loop.quit() 784 785 def credentials(self, args): 786 logger.debug("credentials: " + str(args)) 787 self.credentials_received = True 788 if self.success_seen: 789 self.loop.quit() 790 791 def start_pin(self, *args): 792 logger.debug("start_pin") 793 bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode())) 794 wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670', 795 'Bssid': bssid_ay}) 796 return False 797 798 def success(self): 799 return self.success_seen and self.credentials_received 800 801 with TestDbusWps(bus) as t: 802 if not t.success(): 803 raise Exception("Failure in D-Bus operations") 804 805 dev[0].wait_connected(timeout=10) 806 807def test_dbus_wps_pin2(dev, apdev): 808 """D-Bus WPS/PIN operation and signals (PIN from wpa_supplicant)""" 809 try: 810 _test_dbus_wps_pin2(dev, apdev) 811 finally: 812 dev[0].request("SET wps_cred_processing 0") 813 814def _test_dbus_wps_pin2(dev, apdev): 815 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 816 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 817 818 hapd = start_ap(apdev[0]) 819 bssid = apdev[0]['bssid'] 820 dev[0].scan_for_bss(bssid, freq="2412") 821 dev[0].request("SET wps_cred_processing 2") 822 823 class TestDbusWps(TestDbus): 824 def __init__(self, bus): 825 TestDbus.__init__(self, bus) 826 self.success_seen = False 827 self.failed = False 828 829 def __enter__(self): 830 gobject.timeout_add(1, self.start_pin) 831 gobject.timeout_add(15000, self.timeout) 832 self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event") 833 self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS, 834 "Credentials") 835 self.loop.run() 836 return self 837 838 def wpsEvent(self, name, args): 839 logger.debug("wpsEvent: %s args='%s'" % (name, str(args))) 840 if name == "success": 841 self.success_seen = True 842 if self.credentials_received: 843 self.loop.quit() 844 845 def credentials(self, args): 846 logger.debug("credentials: " + str(args)) 847 self.credentials_received = True 848 if self.success_seen: 849 self.loop.quit() 850 851 def start_pin(self, *args): 852 logger.debug("start_pin") 853 bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode())) 854 res = wps.Start({'Role': 'enrollee', 'Type': 'pin', 855 'Bssid': bssid_ay}) 856 pin = res['Pin'] 857 h = hostapd.Hostapd(apdev[0]['ifname']) 858 h.request("WPS_PIN any " + pin) 859 return False 860 861 def success(self): 862 return self.success_seen and self.credentials_received 863 864 with TestDbusWps(bus) as t: 865 if not t.success(): 866 raise Exception("Failure in D-Bus operations") 867 868 dev[0].wait_connected(timeout=10) 869 870def test_dbus_wps_pin_m2d(dev, apdev): 871 """D-Bus WPS/PIN operation and signals with M2D""" 872 try: 873 _test_dbus_wps_pin_m2d(dev, apdev) 874 finally: 875 dev[0].request("SET wps_cred_processing 0") 876 877def _test_dbus_wps_pin_m2d(dev, apdev): 878 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 879 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 880 881 hapd = start_ap(apdev[0]) 882 bssid = apdev[0]['bssid'] 883 dev[0].scan_for_bss(bssid, freq="2412") 884 dev[0].request("SET wps_cred_processing 2") 885 886 class TestDbusWps(TestDbus): 887 def __init__(self, bus): 888 TestDbus.__init__(self, bus) 889 self.success_seen = False 890 self.credentials_received = False 891 892 def __enter__(self): 893 gobject.timeout_add(1, self.start_pin) 894 gobject.timeout_add(15000, self.timeout) 895 self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event") 896 self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS, 897 "Credentials") 898 self.loop.run() 899 return self 900 901 def wpsEvent(self, name, args): 902 logger.debug("wpsEvent: %s args='%s'" % (name, str(args))) 903 if name == "success": 904 self.success_seen = True 905 if self.credentials_received: 906 self.loop.quit() 907 elif name == "m2d": 908 h = hostapd.Hostapd(apdev[0]['ifname']) 909 h.request("WPS_PIN any 12345670") 910 911 def credentials(self, args): 912 logger.debug("credentials: " + str(args)) 913 self.credentials_received = True 914 if self.success_seen: 915 self.loop.quit() 916 917 def start_pin(self, *args): 918 logger.debug("start_pin") 919 bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode())) 920 wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670', 921 'Bssid': bssid_ay}) 922 return False 923 924 def success(self): 925 return self.success_seen and self.credentials_received 926 927 with TestDbusWps(bus) as t: 928 if not t.success(): 929 raise Exception("Failure in D-Bus operations") 930 931 dev[0].wait_connected(timeout=10) 932 933def test_dbus_wps_reg(dev, apdev): 934 """D-Bus WPS/Registrar operation and signals""" 935 try: 936 _test_dbus_wps_reg(dev, apdev) 937 finally: 938 dev[0].request("SET wps_cred_processing 0") 939 940def _test_dbus_wps_reg(dev, apdev): 941 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 942 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 943 944 hapd = start_ap(apdev[0]) 945 hapd.request("WPS_PIN any 12345670") 946 bssid = apdev[0]['bssid'] 947 dev[0].scan_for_bss(bssid, freq="2412") 948 dev[0].request("SET wps_cred_processing 2") 949 950 class TestDbusWps(TestDbus): 951 def __init__(self, bus): 952 TestDbus.__init__(self, bus) 953 self.credentials_received = False 954 955 def __enter__(self): 956 gobject.timeout_add(100, self.start_reg) 957 gobject.timeout_add(15000, self.timeout) 958 self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event") 959 self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS, 960 "Credentials") 961 self.loop.run() 962 return self 963 964 def wpsEvent(self, name, args): 965 logger.debug("wpsEvent: %s args='%s'" % (name, str(args))) 966 967 def credentials(self, args): 968 logger.debug("credentials: " + str(args)) 969 self.credentials_received = True 970 self.loop.quit() 971 972 def start_reg(self, *args): 973 logger.debug("start_reg") 974 bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode())) 975 wps.Start({'Role': 'registrar', 'Type': 'pin', 976 'Pin': '12345670', 'Bssid': bssid_ay}) 977 return False 978 979 def success(self): 980 return self.credentials_received 981 982 with TestDbusWps(bus) as t: 983 if not t.success(): 984 raise Exception("Failure in D-Bus operations") 985 986 dev[0].wait_connected(timeout=10) 987 988def test_dbus_wps_cancel(dev, apdev): 989 """D-Bus WPS Cancel operation""" 990 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 991 wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS) 992 993 hapd = start_ap(apdev[0]) 994 bssid = apdev[0]['bssid'] 995 996 wps.Cancel() 997 dev[0].scan_for_bss(bssid, freq="2412") 998 bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode())) 999 wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670', 1000 'Bssid': bssid_ay}) 1001 wps.Cancel() 1002 dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 1) 1003 1004def test_dbus_scan_invalid(dev, apdev): 1005 """D-Bus invalid scan method""" 1006 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1007 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1008 1009 tests = [({}, "InvalidArgs"), 1010 ({'Type': 123}, "InvalidArgs"), 1011 ({'Type': 'foo'}, "InvalidArgs"), 1012 ({'Type': 'active', 'Foo': 'bar'}, "InvalidArgs"), 1013 ({'Type': 'active', 'SSIDs': 'foo'}, "InvalidArgs"), 1014 ({'Type': 'active', 'SSIDs': ['foo']}, "InvalidArgs"), 1015 ({'Type': 'active', 1016 'SSIDs': [dbus.ByteArray(b"1"), dbus.ByteArray(b"2"), 1017 dbus.ByteArray(b"3"), dbus.ByteArray(b"4"), 1018 dbus.ByteArray(b"5"), dbus.ByteArray(b"6"), 1019 dbus.ByteArray(b"7"), dbus.ByteArray(b"8"), 1020 dbus.ByteArray(b"9"), dbus.ByteArray(b"10"), 1021 dbus.ByteArray(b"11"), dbus.ByteArray(b"12"), 1022 dbus.ByteArray(b"13"), dbus.ByteArray(b"14"), 1023 dbus.ByteArray(b"15"), dbus.ByteArray(b"16"), 1024 dbus.ByteArray(b"17")]}, 1025 "InvalidArgs"), 1026 ({'Type': 'active', 1027 'SSIDs': [dbus.ByteArray(b"1234567890abcdef1234567890abcdef1")]}, 1028 "InvalidArgs"), 1029 ({'Type': 'active', 'IEs': 'foo'}, "InvalidArgs"), 1030 ({'Type': 'active', 'IEs': ['foo']}, "InvalidArgs"), 1031 ({'Type': 'active', 'Channels': 2412}, "InvalidArgs"), 1032 ({'Type': 'active', 'Channels': [2412]}, "InvalidArgs"), 1033 ({'Type': 'active', 1034 'Channels': [(dbus.Int32(2412), dbus.UInt32(20))]}, 1035 "InvalidArgs"), 1036 ({'Type': 'active', 1037 'Channels': [(dbus.UInt32(2412), dbus.Int32(20))]}, 1038 "InvalidArgs"), 1039 ({'Type': 'active', 'AllowRoam': "yes"}, "InvalidArgs"), 1040 ({'Type': 'passive', 'IEs': [dbus.ByteArray(b"\xdd\x00")]}, 1041 "InvalidArgs"), 1042 ({'Type': 'passive', 'SSIDs': [dbus.ByteArray(b"foo")]}, 1043 "InvalidArgs")] 1044 for (t, err) in tests: 1045 try: 1046 iface.Scan(t) 1047 raise Exception("Invalid Scan() arguments accepted: " + str(t)) 1048 except dbus.exceptions.DBusException as e: 1049 if err not in str(e): 1050 raise Exception("Unexpected error message for invalid Scan(%s): %s" % (str(t), str(e))) 1051 1052def test_dbus_scan_oom(dev, apdev): 1053 """D-Bus scan method and OOM""" 1054 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1055 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1056 1057 with alloc_fail_dbus(dev[0], 1, 1058 "wpa_scan_clone_params;wpas_dbus_handler_scan", 1059 "Scan", expected="ScanError: Scan request rejected"): 1060 iface.Scan({'Type': 'passive', 1061 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]}) 1062 1063 with alloc_fail_dbus(dev[0], 1, 1064 "=wpas_dbus_get_scan_channels;wpas_dbus_handler_scan", 1065 "Scan"): 1066 iface.Scan({'Type': 'passive', 1067 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]}) 1068 1069 with alloc_fail_dbus(dev[0], 1, 1070 "=wpas_dbus_get_scan_ies;wpas_dbus_handler_scan", 1071 "Scan"): 1072 iface.Scan({'Type': 'active', 1073 'IEs': [dbus.ByteArray(b"\xdd\x00")], 1074 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]}) 1075 1076 with alloc_fail_dbus(dev[0], 1, 1077 "=wpas_dbus_get_scan_ssids;wpas_dbus_handler_scan", 1078 "Scan"): 1079 iface.Scan({'Type': 'active', 1080 'SSIDs': [dbus.ByteArray(b"open"), 1081 dbus.ByteArray()], 1082 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]}) 1083 1084def test_dbus_scan(dev, apdev): 1085 """D-Bus scan and related signals""" 1086 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1087 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1088 1089 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 1090 1091 class TestDbusScan(TestDbus): 1092 def __init__(self, bus): 1093 TestDbus.__init__(self, bus) 1094 self.scan_completed = 0 1095 self.bss_added = False 1096 self.fail_reason = None 1097 1098 def __enter__(self): 1099 gobject.timeout_add(1, self.run_scan) 1100 gobject.timeout_add(15000, self.timeout) 1101 self.add_signal(self.scanDone, WPAS_DBUS_IFACE, "ScanDone") 1102 self.add_signal(self.bssAdded, WPAS_DBUS_IFACE, "BSSAdded") 1103 self.add_signal(self.bssRemoved, WPAS_DBUS_IFACE, "BSSRemoved") 1104 self.loop.run() 1105 return self 1106 1107 def scanDone(self, success): 1108 logger.debug("scanDone: success=%s" % success) 1109 self.scan_completed += 1 1110 if self.scan_completed == 1: 1111 iface.Scan({'Type': 'passive', 1112 'AllowRoam': True, 1113 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]}) 1114 elif self.scan_completed == 2: 1115 iface.Scan({'Type': 'passive', 1116 'AllowRoam': False}) 1117 elif self.bss_added and self.scan_completed == 3: 1118 self.loop.quit() 1119 1120 def bssAdded(self, bss, properties): 1121 logger.debug("bssAdded: %s" % bss) 1122 logger.debug(str(properties)) 1123 if 'WPS' in properties: 1124 if 'Type' in properties['WPS']: 1125 self.fail_reason = "Unexpected WPS dictionary entry in non-WPS BSS" 1126 self.loop.quit() 1127 self.bss_added = True 1128 if self.scan_completed == 3: 1129 self.loop.quit() 1130 1131 def bssRemoved(self, bss): 1132 logger.debug("bssRemoved: %s" % bss) 1133 1134 def run_scan(self, *args): 1135 logger.debug("run_scan") 1136 iface.Scan({'Type': 'active', 1137 'SSIDs': [dbus.ByteArray(b"open"), 1138 dbus.ByteArray()], 1139 'IEs': [dbus.ByteArray(b"\xdd\x00"), 1140 dbus.ByteArray()], 1141 'AllowRoam': False, 1142 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]}) 1143 return False 1144 1145 def success(self): 1146 return self.scan_completed == 3 and self.bss_added 1147 1148 with TestDbusScan(bus) as t: 1149 if t.fail_reason: 1150 raise Exception(t.fail_reason) 1151 if not t.success(): 1152 raise Exception("Expected signals not seen") 1153 1154 res = if_obj.Get(WPAS_DBUS_IFACE, "BSSs", 1155 dbus_interface=dbus.PROPERTIES_IFACE) 1156 if len(res) < 1: 1157 raise Exception("Scan result not in BSSs property") 1158 iface.FlushBSS(0) 1159 res = if_obj.Get(WPAS_DBUS_IFACE, "BSSs", 1160 dbus_interface=dbus.PROPERTIES_IFACE) 1161 if len(res) != 0: 1162 raise Exception("FlushBSS() did not remove scan results from BSSs property") 1163 iface.FlushBSS(1) 1164 1165def test_dbus_scan_rand(dev, apdev): 1166 """D-Bus MACAddressRandomizationMask property Get/Set""" 1167 try: 1168 run_dbus_scan_rand(dev, apdev) 1169 finally: 1170 dev[0].request("MAC_RAND_SCAN all enable=0") 1171 1172def run_dbus_scan_rand(dev, apdev): 1173 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1174 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1175 1176 res = if_obj.Get(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1177 dbus_interface=dbus.PROPERTIES_IFACE) 1178 if len(res) != 0: 1179 logger.info(str(res)) 1180 raise Exception("Unexpected initial MACAddressRandomizationMask value") 1181 1182 try: 1183 if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", "foo", 1184 dbus_interface=dbus.PROPERTIES_IFACE) 1185 raise Exception("Invalid Set accepted") 1186 except dbus.exceptions.DBusException as e: 1187 if "InvalidArgs: invalid message format" not in str(e): 1188 raise Exception("Unexpected error message: " + str(e)) 1189 1190 try: 1191 if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1192 {"foo": "bar"}, 1193 dbus_interface=dbus.PROPERTIES_IFACE) 1194 raise Exception("Invalid Set accepted") 1195 except dbus.exceptions.DBusException as e: 1196 if "wpas_dbus_setter_mac_address_randomization_mask: mask was not a byte array" not in str(e): 1197 raise Exception("Unexpected error message: " + str(e)) 1198 1199 try: 1200 if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1201 {"foo": dbus.ByteArray(b'123456')}, 1202 dbus_interface=dbus.PROPERTIES_IFACE) 1203 raise Exception("Invalid Set accepted") 1204 except dbus.exceptions.DBusException as e: 1205 if 'wpas_dbus_setter_mac_address_randomization_mask: bad scan type "foo"' not in str(e): 1206 raise Exception("Unexpected error message: " + str(e)) 1207 1208 try: 1209 if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1210 {"scan": dbus.ByteArray(b'12345')}, 1211 dbus_interface=dbus.PROPERTIES_IFACE) 1212 raise Exception("Invalid Set accepted") 1213 except dbus.exceptions.DBusException as e: 1214 if 'wpas_dbus_setter_mac_address_randomization_mask: malformed MAC mask given' not in str(e): 1215 raise Exception("Unexpected error message: " + str(e)) 1216 1217 if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1218 {"scan": dbus.ByteArray(b'123456')}, 1219 dbus_interface=dbus.PROPERTIES_IFACE) 1220 res = if_obj.Get(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1221 dbus_interface=dbus.PROPERTIES_IFACE) 1222 if len(res) != 1: 1223 logger.info(str(res)) 1224 raise Exception("Unexpected MACAddressRandomizationMask value") 1225 1226 try: 1227 if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1228 {"scan": dbus.ByteArray(b'123456'), 1229 "sched_scan": dbus.ByteArray(b'987654')}, 1230 dbus_interface=dbus.PROPERTIES_IFACE) 1231 except dbus.exceptions.DBusException as e: 1232 # sched_scan is unlikely to be supported 1233 pass 1234 1235 if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1236 dbus.Dictionary({}, signature='sv'), 1237 dbus_interface=dbus.PROPERTIES_IFACE) 1238 res = if_obj.Get(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", 1239 dbus_interface=dbus.PROPERTIES_IFACE) 1240 if len(res) != 0: 1241 logger.info(str(res)) 1242 raise Exception("Unexpected MACAddressRandomizationMask value") 1243 1244def test_dbus_scan_busy(dev, apdev): 1245 """D-Bus scan trigger rejection when busy with previous scan""" 1246 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1247 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1248 1249 if "OK" not in dev[0].request("SCAN freq=2412-2462"): 1250 raise Exception("Failed to start scan") 1251 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], 15) 1252 if ev is None: 1253 raise Exception("Scan start timed out") 1254 1255 try: 1256 iface.Scan({'Type': 'active', 'AllowRoam': False}) 1257 raise Exception("Scan() accepted when busy") 1258 except dbus.exceptions.DBusException as e: 1259 if "ScanError: Scan request reject" not in str(e): 1260 raise Exception("Unexpected error message: " + str(e)) 1261 1262 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15) 1263 if ev is None: 1264 raise Exception("Scan timed out") 1265 1266def test_dbus_scan_abort(dev, apdev): 1267 """D-Bus scan trigger and abort""" 1268 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1269 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1270 1271 iface.Scan({'Type': 'active', 'AllowRoam': False}) 1272 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], 15) 1273 if ev is None: 1274 raise Exception("Scan start timed out") 1275 1276 iface.AbortScan() 1277 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15) 1278 if ev is None: 1279 raise Exception("Scan abort result timed out") 1280 dev[0].dump_monitor() 1281 iface.Scan({'Type': 'active', 'AllowRoam': False}) 1282 iface.AbortScan() 1283 1284 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15) 1285 if ev is None: 1286 raise Exception("Scan timed out") 1287 1288def test_dbus_connect(dev, apdev): 1289 """D-Bus AddNetwork and connect""" 1290 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1291 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1292 1293 ssid = "test-wpa2-psk" 1294 passphrase = 'qwertyuiop' 1295 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 1296 hapd = hostapd.add_ap(apdev[0], params) 1297 1298 class TestDbusConnect(TestDbus): 1299 def __init__(self, bus): 1300 TestDbus.__init__(self, bus) 1301 self.network_added = False 1302 self.network_selected = False 1303 self.network_removed = False 1304 self.state = 0 1305 1306 def __enter__(self): 1307 gobject.timeout_add(1, self.run_connect) 1308 gobject.timeout_add(15000, self.timeout) 1309 self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded") 1310 self.add_signal(self.networkRemoved, WPAS_DBUS_IFACE, 1311 "NetworkRemoved") 1312 self.add_signal(self.networkSelected, WPAS_DBUS_IFACE, 1313 "NetworkSelected") 1314 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 1315 "PropertiesChanged") 1316 self.loop.run() 1317 return self 1318 1319 def networkAdded(self, network, properties): 1320 logger.debug("networkAdded: %s" % str(network)) 1321 logger.debug(str(properties)) 1322 self.network_added = True 1323 1324 def networkRemoved(self, network): 1325 logger.debug("networkRemoved: %s" % str(network)) 1326 self.network_removed = True 1327 1328 def networkSelected(self, network): 1329 logger.debug("networkSelected: %s" % str(network)) 1330 self.network_selected = True 1331 1332 def propertiesChanged(self, properties): 1333 logger.debug("propertiesChanged: %s" % str(properties)) 1334 if 'State' in properties and properties['State'] == "completed": 1335 if self.state == 0: 1336 self.state = 1 1337 iface.Disconnect() 1338 elif self.state == 2: 1339 self.state = 3 1340 iface.Disconnect() 1341 elif self.state == 4: 1342 self.state = 5 1343 iface.Reattach() 1344 elif self.state == 5: 1345 self.state = 6 1346 iface.Disconnect() 1347 elif self.state == 7: 1348 self.state = 8 1349 res = iface.SignalPoll() 1350 logger.debug("SignalPoll: " + str(res)) 1351 if 'frequency' not in res or res['frequency'] != 2412: 1352 self.state = -1 1353 logger.info("Unexpected SignalPoll result") 1354 iface.RemoveNetwork(self.netw) 1355 if 'State' in properties and properties['State'] == "disconnected": 1356 if self.state == 1: 1357 self.state = 2 1358 iface.SelectNetwork(self.netw) 1359 elif self.state == 3: 1360 self.state = 4 1361 iface.Reassociate() 1362 elif self.state == 6: 1363 self.state = 7 1364 iface.Reconnect() 1365 elif self.state == 8: 1366 self.state = 9 1367 self.loop.quit() 1368 1369 def run_connect(self, *args): 1370 logger.debug("run_connect") 1371 args = dbus.Dictionary({'ssid': ssid, 1372 'key_mgmt': 'WPA-PSK', 1373 'psk': passphrase, 1374 'scan_freq': 2412}, 1375 signature='sv') 1376 self.netw = iface.AddNetwork(args) 1377 iface.SelectNetwork(self.netw) 1378 return False 1379 1380 def success(self): 1381 if not self.network_added or \ 1382 not self.network_removed or \ 1383 not self.network_selected: 1384 return False 1385 return self.state == 9 1386 1387 with TestDbusConnect(bus) as t: 1388 if not t.success(): 1389 raise Exception("Expected signals not seen") 1390 1391def test_dbus_remove_connected(dev, apdev): 1392 """D-Bus RemoveAllNetworks while connected""" 1393 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1394 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1395 1396 ssid = "test-open" 1397 hapd = hostapd.add_ap(apdev[0], {"ssid": ssid}) 1398 1399 class TestDbusConnect(TestDbus): 1400 def __init__(self, bus): 1401 TestDbus.__init__(self, bus) 1402 self.network_added = False 1403 self.network_selected = False 1404 self.network_removed = False 1405 self.state = 0 1406 1407 def __enter__(self): 1408 gobject.timeout_add(1, self.run_connect) 1409 gobject.timeout_add(15000, self.timeout) 1410 self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded") 1411 self.add_signal(self.networkRemoved, WPAS_DBUS_IFACE, 1412 "NetworkRemoved") 1413 self.add_signal(self.networkSelected, WPAS_DBUS_IFACE, 1414 "NetworkSelected") 1415 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 1416 "PropertiesChanged") 1417 self.loop.run() 1418 return self 1419 1420 def networkAdded(self, network, properties): 1421 logger.debug("networkAdded: %s" % str(network)) 1422 logger.debug(str(properties)) 1423 self.network_added = True 1424 1425 def networkRemoved(self, network): 1426 logger.debug("networkRemoved: %s" % str(network)) 1427 self.network_removed = True 1428 1429 def networkSelected(self, network): 1430 logger.debug("networkSelected: %s" % str(network)) 1431 self.network_selected = True 1432 1433 def propertiesChanged(self, properties): 1434 logger.debug("propertiesChanged: %s" % str(properties)) 1435 if 'State' in properties and properties['State'] == "completed": 1436 if self.state == 0: 1437 self.state = 1 1438 iface.Disconnect() 1439 elif self.state == 2: 1440 self.state = 3 1441 iface.Disconnect() 1442 elif self.state == 4: 1443 self.state = 5 1444 iface.Reattach() 1445 elif self.state == 5: 1446 self.state = 6 1447 iface.Disconnect() 1448 elif self.state == 7: 1449 self.state = 8 1450 res = iface.SignalPoll() 1451 logger.debug("SignalPoll: " + str(res)) 1452 if 'frequency' not in res or res['frequency'] != 2412: 1453 self.state = -1 1454 logger.info("Unexpected SignalPoll result") 1455 iface.RemoveAllNetworks() 1456 if 'State' in properties and properties['State'] == "disconnected": 1457 if self.state == 1: 1458 self.state = 2 1459 iface.SelectNetwork(self.netw) 1460 elif self.state == 3: 1461 self.state = 4 1462 iface.Reassociate() 1463 elif self.state == 6: 1464 self.state = 7 1465 iface.Reconnect() 1466 elif self.state == 8: 1467 self.state = 9 1468 self.loop.quit() 1469 1470 def run_connect(self, *args): 1471 logger.debug("run_connect") 1472 args = dbus.Dictionary({'ssid': ssid, 1473 'key_mgmt': 'NONE', 1474 'scan_freq': 2412}, 1475 signature='sv') 1476 self.netw = iface.AddNetwork(args) 1477 iface.SelectNetwork(self.netw) 1478 return False 1479 1480 def success(self): 1481 if not self.network_added or \ 1482 not self.network_removed or \ 1483 not self.network_selected: 1484 return False 1485 return self.state == 9 1486 1487 with TestDbusConnect(bus) as t: 1488 if not t.success(): 1489 raise Exception("Expected signals not seen") 1490 1491def test_dbus_connect_psk_mem(dev, apdev): 1492 """D-Bus AddNetwork and connect with memory-only PSK""" 1493 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1494 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1495 1496 ssid = "test-wpa2-psk" 1497 passphrase = 'qwertyuiop' 1498 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 1499 hapd = hostapd.add_ap(apdev[0], params) 1500 1501 class TestDbusConnect(TestDbus): 1502 def __init__(self, bus): 1503 TestDbus.__init__(self, bus) 1504 self.connected = False 1505 1506 def __enter__(self): 1507 gobject.timeout_add(1, self.run_connect) 1508 gobject.timeout_add(15000, self.timeout) 1509 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 1510 "PropertiesChanged") 1511 self.add_signal(self.networkRequest, WPAS_DBUS_IFACE, 1512 "NetworkRequest") 1513 self.loop.run() 1514 return self 1515 1516 def propertiesChanged(self, properties): 1517 logger.debug("propertiesChanged: %s" % str(properties)) 1518 if 'State' in properties and properties['State'] == "completed": 1519 self.connected = True 1520 self.loop.quit() 1521 1522 def networkRequest(self, path, field, txt): 1523 logger.debug("networkRequest: %s %s %s" % (path, field, txt)) 1524 if field == "PSK_PASSPHRASE": 1525 iface.NetworkReply(path, field, '"' + passphrase + '"') 1526 1527 def run_connect(self, *args): 1528 logger.debug("run_connect") 1529 args = dbus.Dictionary({'ssid': ssid, 1530 'key_mgmt': 'WPA-PSK', 1531 'mem_only_psk': 1, 1532 'scan_freq': 2412}, 1533 signature='sv') 1534 self.netw = iface.AddNetwork(args) 1535 iface.SelectNetwork(self.netw) 1536 return False 1537 1538 def success(self): 1539 return self.connected 1540 1541 with TestDbusConnect(bus) as t: 1542 if not t.success(): 1543 raise Exception("Expected signals not seen") 1544 1545def test_dbus_connect_oom(dev, apdev): 1546 """D-Bus AddNetwork and connect when out-of-memory""" 1547 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1548 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1549 1550 if "OK" not in dev[0].request("TEST_ALLOC_FAIL 0:"): 1551 raise HwsimSkip("TEST_ALLOC_FAIL not supported in the build") 1552 1553 ssid = "test-wpa2-psk" 1554 passphrase = 'qwertyuiop' 1555 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 1556 hapd = hostapd.add_ap(apdev[0], params) 1557 1558 class TestDbusConnect(TestDbus): 1559 def __init__(self, bus): 1560 TestDbus.__init__(self, bus) 1561 self.network_added = False 1562 self.network_selected = False 1563 self.network_removed = False 1564 self.state = 0 1565 1566 def __enter__(self): 1567 gobject.timeout_add(1, self.run_connect) 1568 gobject.timeout_add(1500, self.timeout) 1569 self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded") 1570 self.add_signal(self.networkRemoved, WPAS_DBUS_IFACE, 1571 "NetworkRemoved") 1572 self.add_signal(self.networkSelected, WPAS_DBUS_IFACE, 1573 "NetworkSelected") 1574 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 1575 "PropertiesChanged") 1576 self.loop.run() 1577 return self 1578 1579 def networkAdded(self, network, properties): 1580 logger.debug("networkAdded: %s" % str(network)) 1581 logger.debug(str(properties)) 1582 self.network_added = True 1583 1584 def networkRemoved(self, network): 1585 logger.debug("networkRemoved: %s" % str(network)) 1586 self.network_removed = True 1587 1588 def networkSelected(self, network): 1589 logger.debug("networkSelected: %s" % str(network)) 1590 self.network_selected = True 1591 1592 def propertiesChanged(self, properties): 1593 logger.debug("propertiesChanged: %s" % str(properties)) 1594 if 'State' in properties and properties['State'] == "completed": 1595 if self.state == 0: 1596 self.state = 1 1597 iface.Disconnect() 1598 elif self.state == 2: 1599 self.state = 3 1600 iface.Disconnect() 1601 elif self.state == 4: 1602 self.state = 5 1603 iface.Reattach() 1604 elif self.state == 5: 1605 self.state = 6 1606 res = iface.SignalPoll() 1607 logger.debug("SignalPoll: " + str(res)) 1608 if 'frequency' not in res or res['frequency'] != 2412: 1609 self.state = -1 1610 logger.info("Unexpected SignalPoll result") 1611 iface.RemoveNetwork(self.netw) 1612 if 'State' in properties and properties['State'] == "disconnected": 1613 if self.state == 1: 1614 self.state = 2 1615 iface.SelectNetwork(self.netw) 1616 elif self.state == 3: 1617 self.state = 4 1618 iface.Reassociate() 1619 elif self.state == 6: 1620 self.state = 7 1621 self.loop.quit() 1622 1623 def run_connect(self, *args): 1624 logger.debug("run_connect") 1625 args = dbus.Dictionary({'ssid': ssid, 1626 'key_mgmt': 'WPA-PSK', 1627 'psk': passphrase, 1628 'scan_freq': 2412}, 1629 signature='sv') 1630 try: 1631 self.netw = iface.AddNetwork(args) 1632 except Exception as e: 1633 logger.info("Exception on AddNetwork: " + str(e)) 1634 self.loop.quit() 1635 return False 1636 try: 1637 iface.SelectNetwork(self.netw) 1638 except Exception as e: 1639 logger.info("Exception on SelectNetwork: " + str(e)) 1640 self.loop.quit() 1641 1642 return False 1643 1644 def success(self): 1645 if not self.network_added or \ 1646 not self.network_removed or \ 1647 not self.network_selected: 1648 return False 1649 return self.state == 7 1650 1651 count = 0 1652 for i in range(1, 1000): 1653 for j in range(3): 1654 dev[j].dump_monitor() 1655 dev[0].request("TEST_ALLOC_FAIL %d:main" % i) 1656 try: 1657 with TestDbusConnect(bus) as t: 1658 if not t.success(): 1659 logger.info("Iteration %d - Expected signals not seen" % i) 1660 else: 1661 logger.info("Iteration %d - success" % i) 1662 1663 state = dev[0].request('GET_ALLOC_FAIL') 1664 logger.info("GET_ALLOC_FAIL: " + state) 1665 dev[0].dump_monitor() 1666 dev[0].request("TEST_ALLOC_FAIL 0:") 1667 if i < 3: 1668 raise Exception("Connection succeeded during out-of-memory") 1669 if not state.startswith('0:'): 1670 count += 1 1671 if count == 5: 1672 break 1673 except: 1674 pass 1675 1676 # Force regulatory update to re-fetch hw capabilities for the following 1677 # test cases. 1678 try: 1679 dev[0].dump_monitor() 1680 subprocess.call(['iw', 'reg', 'set', 'US']) 1681 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) 1682 finally: 1683 dev[0].dump_monitor() 1684 subprocess.call(['iw', 'reg', 'set', '00']) 1685 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) 1686 1687def test_dbus_while_not_connected(dev, apdev): 1688 """D-Bus invalid operations while not connected""" 1689 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1690 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1691 1692 try: 1693 iface.Disconnect() 1694 raise Exception("Disconnect() accepted when not connected") 1695 except dbus.exceptions.DBusException as e: 1696 if "NotConnected" not in str(e): 1697 raise Exception("Unexpected error message for invalid Disconnect: " + str(e)) 1698 1699 try: 1700 iface.Reattach() 1701 raise Exception("Reattach() accepted when not connected") 1702 except dbus.exceptions.DBusException as e: 1703 if "NotConnected" not in str(e): 1704 raise Exception("Unexpected error message for invalid Reattach: " + str(e)) 1705 1706def test_dbus_connect_eap(dev, apdev): 1707 """D-Bus AddNetwork and connect to EAP network""" 1708 check_altsubject_match_support(dev[0]) 1709 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1710 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1711 1712 ssid = "ieee8021x-open" 1713 params = hostapd.radius_params() 1714 params["ssid"] = ssid 1715 params["ieee8021x"] = "1" 1716 hapd = hostapd.add_ap(apdev[0], params) 1717 1718 class TestDbusConnect(TestDbus): 1719 def __init__(self, bus): 1720 TestDbus.__init__(self, bus) 1721 self.certification_received = False 1722 self.eap_status = False 1723 self.state = 0 1724 1725 def __enter__(self): 1726 gobject.timeout_add(1, self.run_connect) 1727 gobject.timeout_add(15000, self.timeout) 1728 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 1729 "PropertiesChanged") 1730 self.add_signal(self.certification, WPAS_DBUS_IFACE, 1731 "Certification", byte_arrays=True) 1732 self.add_signal(self.networkRequest, WPAS_DBUS_IFACE, 1733 "NetworkRequest") 1734 self.add_signal(self.eap, WPAS_DBUS_IFACE, "EAP") 1735 self.loop.run() 1736 return self 1737 1738 def propertiesChanged(self, properties): 1739 logger.debug("propertiesChanged: %s" % str(properties)) 1740 if 'State' in properties and properties['State'] == "completed": 1741 if self.state == 0: 1742 self.state = 1 1743 iface.EAPLogoff() 1744 logger.info("Set dNSName constraint") 1745 net_obj = bus.get_object(WPAS_DBUS_SERVICE, self.netw) 1746 args = dbus.Dictionary({'altsubject_match': 1747 self.server_dnsname}, 1748 signature='sv') 1749 net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args, 1750 dbus_interface=dbus.PROPERTIES_IFACE) 1751 elif self.state == 2: 1752 self.state = 3 1753 iface.Disconnect() 1754 logger.info("Set non-matching dNSName constraint") 1755 net_obj = bus.get_object(WPAS_DBUS_SERVICE, self.netw) 1756 args = dbus.Dictionary({'altsubject_match': 1757 self.server_dnsname + "FOO"}, 1758 signature='sv') 1759 net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args, 1760 dbus_interface=dbus.PROPERTIES_IFACE) 1761 if 'State' in properties and properties['State'] == "disconnected": 1762 if self.state == 1: 1763 self.state = 2 1764 iface.EAPLogon() 1765 iface.SelectNetwork(self.netw) 1766 if self.state == 3: 1767 self.state = 4 1768 iface.SelectNetwork(self.netw) 1769 1770 def certification(self, args): 1771 logger.debug("certification: %s" % str(args)) 1772 self.certification_received = True 1773 if args['depth'] == 0: 1774 # The test server certificate is supposed to have dNSName 1775 if len(args['altsubject']) < 1: 1776 raise Exception("Missing dNSName") 1777 dnsname = args['altsubject'][0] 1778 if not dnsname.startswith("DNS:"): 1779 raise Exception("Expected dNSName not found: " + dnsname) 1780 logger.info("altsubject: " + dnsname) 1781 self.server_dnsname = dnsname 1782 1783 def eap(self, status, parameter): 1784 logger.debug("EAP: status=%s parameter=%s" % (status, parameter)) 1785 if status == 'completion' and parameter == 'success': 1786 self.eap_status = True 1787 if self.state == 4 and status == 'remote certificate verification' and parameter == 'AltSubject mismatch': 1788 self.state = 5 1789 self.loop.quit() 1790 1791 def networkRequest(self, path, field, txt): 1792 logger.debug("networkRequest: %s %s %s" % (path, field, txt)) 1793 if field == "PASSWORD": 1794 iface.NetworkReply(path, field, "password") 1795 1796 def run_connect(self, *args): 1797 logger.debug("run_connect") 1798 args = dbus.Dictionary({'ssid': ssid, 1799 'key_mgmt': 'IEEE8021X', 1800 'eapol_flags': 0, 1801 'eap': 'TTLS', 1802 'anonymous_identity': 'ttls', 1803 'identity': 'pap user', 1804 'ca_cert': 'auth_serv/ca.pem', 1805 'phase2': 'auth=PAP', 1806 'scan_freq': 2412}, 1807 signature='sv') 1808 self.netw = iface.AddNetwork(args) 1809 iface.SelectNetwork(self.netw) 1810 return False 1811 1812 def success(self): 1813 if not self.eap_status or not self.certification_received: 1814 return False 1815 return self.state == 5 1816 1817 with TestDbusConnect(bus) as t: 1818 if not t.success(): 1819 raise Exception("Expected signals not seen") 1820 1821def test_dbus_network(dev, apdev): 1822 """D-Bus AddNetwork/RemoveNetwork parameters and error cases""" 1823 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1824 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1825 1826 args = dbus.Dictionary({'ssid': "foo", 1827 'key_mgmt': 'WPA-PSK', 1828 'psk': "12345678", 1829 'identity': dbus.ByteArray([1, 2]), 1830 'priority': dbus.Int32(0), 1831 'scan_freq': dbus.UInt32(2412)}, 1832 signature='sv') 1833 netw = iface.AddNetwork(args) 1834 id = int(dev[0].list_networks()[0]['id']) 1835 val = dev[0].get_network(id, "scan_freq") 1836 if val != "2412": 1837 raise Exception("Invalid scan_freq value: " + str(val)) 1838 iface.RemoveNetwork(netw) 1839 1840 args = dbus.Dictionary({'ssid': "foo", 1841 'key_mgmt': 'NONE', 1842 'scan_freq': "2412 2432", 1843 'freq_list': "2412 2417 2432"}, 1844 signature='sv') 1845 netw = iface.AddNetwork(args) 1846 id = int(dev[0].list_networks()[0]['id']) 1847 val = dev[0].get_network(id, "scan_freq") 1848 if val != "2412 2432": 1849 raise Exception("Invalid scan_freq value (2): " + str(val)) 1850 val = dev[0].get_network(id, "freq_list") 1851 if val != "2412 2417 2432": 1852 raise Exception("Invalid freq_list value: " + str(val)) 1853 iface.RemoveNetwork(netw) 1854 try: 1855 iface.RemoveNetwork(netw) 1856 raise Exception("Invalid RemoveNetwork() accepted") 1857 except dbus.exceptions.DBusException as e: 1858 if "NetworkUnknown" not in str(e): 1859 raise Exception("Unexpected error message for invalid RemoveNetwork: " + str(e)) 1860 try: 1861 iface.SelectNetwork(netw) 1862 raise Exception("Invalid SelectNetwork() accepted") 1863 except dbus.exceptions.DBusException as e: 1864 if "NetworkUnknown" not in str(e): 1865 raise Exception("Unexpected error message for invalid RemoveNetwork: " + str(e)) 1866 1867 args = dbus.Dictionary({'ssid': "foo1", 'key_mgmt': 'NONE', 1868 'identity': "testuser", 'scan_freq': '2412'}, 1869 signature='sv') 1870 netw1 = iface.AddNetwork(args) 1871 args = dbus.Dictionary({'ssid': "foo2", 'key_mgmt': 'NONE'}, 1872 signature='sv') 1873 netw2 = iface.AddNetwork(args) 1874 res = if_obj.Get(WPAS_DBUS_IFACE, "Networks", 1875 dbus_interface=dbus.PROPERTIES_IFACE) 1876 if len(res) != 2: 1877 raise Exception("Unexpected number of networks") 1878 1879 net_obj = bus.get_object(WPAS_DBUS_SERVICE, netw1) 1880 res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled", 1881 dbus_interface=dbus.PROPERTIES_IFACE) 1882 if res != False: 1883 raise Exception("Added network was unexpectedly enabled by default") 1884 net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.Boolean(True), 1885 dbus_interface=dbus.PROPERTIES_IFACE) 1886 res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled", 1887 dbus_interface=dbus.PROPERTIES_IFACE) 1888 if res != True: 1889 raise Exception("Set(Enabled,True) did not seem to change property value") 1890 net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.Boolean(False), 1891 dbus_interface=dbus.PROPERTIES_IFACE) 1892 res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled", 1893 dbus_interface=dbus.PROPERTIES_IFACE) 1894 if res != False: 1895 raise Exception("Set(Enabled,False) did not seem to change property value") 1896 try: 1897 net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.UInt32(1), 1898 dbus_interface=dbus.PROPERTIES_IFACE) 1899 raise Exception("Invalid Set(Enabled,1) accepted") 1900 except dbus.exceptions.DBusException as e: 1901 if "Error.Failed: wrong property type" not in str(e): 1902 raise Exception("Unexpected error message for invalid Set(Enabled,1): " + str(e)) 1903 1904 args = dbus.Dictionary({'ssid': "foo1new"}, signature='sv') 1905 net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args, 1906 dbus_interface=dbus.PROPERTIES_IFACE) 1907 res = net_obj.Get(WPAS_DBUS_NETWORK, "Properties", 1908 dbus_interface=dbus.PROPERTIES_IFACE) 1909 if res['ssid'] != '"foo1new"': 1910 raise Exception("Set(Properties) failed to update ssid") 1911 if res['identity'] != '"testuser"': 1912 raise Exception("Set(Properties) unexpectedly changed unrelated parameter") 1913 1914 iface.RemoveAllNetworks() 1915 res = if_obj.Get(WPAS_DBUS_IFACE, "Networks", 1916 dbus_interface=dbus.PROPERTIES_IFACE) 1917 if len(res) != 0: 1918 raise Exception("Unexpected number of networks") 1919 iface.RemoveAllNetworks() 1920 1921 tests = [dbus.Dictionary({'psk': "1234567"}, signature='sv'), 1922 dbus.Dictionary({'identity': dbus.ByteArray()}, 1923 signature='sv'), 1924 dbus.Dictionary({'identity': dbus.Byte(1)}, signature='sv')] 1925 for args in tests: 1926 try: 1927 iface.AddNetwork(args) 1928 raise Exception("Invalid AddNetwork args accepted: " + str(args)) 1929 except dbus.exceptions.DBusException as e: 1930 if "InvalidArgs" not in str(e): 1931 raise Exception("Unexpected error message for invalid AddNetwork: " + str(e)) 1932 1933def test_dbus_network_oom(dev, apdev): 1934 """D-Bus AddNetwork/RemoveNetwork parameters and OOM error cases""" 1935 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 1936 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 1937 1938 args = dbus.Dictionary({'ssid': "foo1", 'key_mgmt': 'NONE', 1939 'identity': "testuser", 'scan_freq': '2412'}, 1940 signature='sv') 1941 netw1 = iface.AddNetwork(args) 1942 net_obj = bus.get_object(WPAS_DBUS_SERVICE, netw1) 1943 1944 with alloc_fail_dbus(dev[0], 1, 1945 "wpa_config_get_all;wpas_dbus_getter_network_properties", 1946 "Get"): 1947 net_obj.Get(WPAS_DBUS_NETWORK, "Properties", 1948 dbus_interface=dbus.PROPERTIES_IFACE) 1949 1950 iface.RemoveAllNetworks() 1951 1952 with alloc_fail_dbus(dev[0], 1, 1953 "wpas_dbus_new_decompose_object_path;wpas_dbus_handler_remove_network", 1954 "RemoveNetwork", "InvalidArgs"): 1955 iface.RemoveNetwork(dbus.ObjectPath("/fi/w1/wpa_supplicant1/Interfaces/1234/Networks/1234")) 1956 1957 with alloc_fail(dev[0], 1, "wpa_dbus_register_object_per_iface;wpas_dbus_register_network"): 1958 args = dbus.Dictionary({'ssid': "foo2", 'key_mgmt': 'NONE'}, 1959 signature='sv') 1960 try: 1961 netw = iface.AddNetwork(args) 1962 # Currently, AddNetwork() succeeds even if os_strdup() for path 1963 # fails, so remove the network if that occurs. 1964 iface.RemoveNetwork(netw) 1965 except dbus.exceptions.DBusException as e: 1966 pass 1967 1968 for i in range(1, 3): 1969 with alloc_fail(dev[0], i, "=wpas_dbus_register_network"): 1970 try: 1971 netw = iface.AddNetwork(args) 1972 # Currently, AddNetwork() succeeds even if network registration 1973 # fails, so remove the network if that occurs. 1974 iface.RemoveNetwork(netw) 1975 except dbus.exceptions.DBusException as e: 1976 pass 1977 1978 with alloc_fail_dbus(dev[0], 1, 1979 "=wpa_config_add_network;wpas_dbus_handler_add_network", 1980 "AddNetwork", 1981 "UnknownError: wpa_supplicant could not add a network"): 1982 args = dbus.Dictionary({'ssid': "foo2", 'key_mgmt': 'NONE'}, 1983 signature='sv') 1984 netw = iface.AddNetwork(args) 1985 1986 tests = [(1, 1987 'wpa_dbus_dict_get_entry;set_network_properties;wpas_dbus_handler_add_network', 1988 dbus.Dictionary({'ssid': dbus.ByteArray(b' ')}, 1989 signature='sv')), 1990 (1, '=set_network_properties;wpas_dbus_handler_add_network', 1991 dbus.Dictionary({'ssid': 'foo'}, signature='sv')), 1992 (1, '=set_network_properties;wpas_dbus_handler_add_network', 1993 dbus.Dictionary({'eap': 'foo'}, signature='sv')), 1994 (1, '=set_network_properties;wpas_dbus_handler_add_network', 1995 dbus.Dictionary({'priority': dbus.UInt32(1)}, 1996 signature='sv')), 1997 (1, '=set_network_properties;wpas_dbus_handler_add_network', 1998 dbus.Dictionary({'priority': dbus.Int32(1)}, 1999 signature='sv')), 2000 (1, '=set_network_properties;wpas_dbus_handler_add_network', 2001 dbus.Dictionary({'ssid': dbus.ByteArray(b' ')}, 2002 signature='sv'))] 2003 for (count, funcs, args) in tests: 2004 with alloc_fail_dbus(dev[0], count, funcs, "AddNetwork", "InvalidArgs"): 2005 netw = iface.AddNetwork(args) 2006 2007 if len(if_obj.Get(WPAS_DBUS_IFACE, 'Networks', 2008 dbus_interface=dbus.PROPERTIES_IFACE)) > 0: 2009 raise Exception("Unexpected network block added") 2010 if len(dev[0].list_networks()) > 0: 2011 raise Exception("Unexpected network block visible") 2012 2013def test_dbus_interface(dev, apdev): 2014 """D-Bus CreateInterface/GetInterface/RemoveInterface parameters and error cases""" 2015 try: 2016 _test_dbus_interface(dev, apdev) 2017 finally: 2018 # Need to force P2P channel list update since the 'lo' interface 2019 # with driver=none ends up configuring default dualband channels. 2020 dev[0].dump_monitor() 2021 dev[0].request("SET country US") 2022 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) 2023 if ev is None: 2024 ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], 2025 timeout=1) 2026 if ev is None or "alpha2=US" not in ev: 2027 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) 2028 ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], 2029 timeout=1) 2030 dev[0].dump_monitor() 2031 2032 dev[0].request("SET country 00") 2033 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) 2034 if ev is None: 2035 ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], 2036 timeout=1) 2037 if ev is None or "type=WORLD" not in ev: 2038 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) 2039 ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], 2040 timeout=1) 2041 2042 subprocess.call(['iw', 'reg', 'set', '00']) 2043 cc = dev[0].get_driver_status_field("country") 2044 if cc != '00': 2045 logger.info("Country code not cleared to 00: " + cc) 2046 2047def _test_dbus_interface(dev, apdev): 2048 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2049 wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE) 2050 2051 params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none', 'Type': 'sta', 2052 'Address': '02:03:11:22:33:44'}, 2053 signature='sv') 2054 path = wpas.CreateInterface(params) 2055 logger.debug("New interface path: " + str(path)) 2056 path2 = wpas.GetInterface("lo") 2057 if path != path2: 2058 raise Exception("Interface object mismatch") 2059 2060 params = dbus.Dictionary({'Ifname': 'lo', 2061 'Driver': 'none', 2062 'ConfigFile': 'foo', 2063 'BridgeIfname': 'foo',}, 2064 signature='sv') 2065 try: 2066 wpas.CreateInterface(params) 2067 raise Exception("Invalid CreateInterface() accepted") 2068 except dbus.exceptions.DBusException as e: 2069 if "InterfaceExists" not in str(e): 2070 raise Exception("Unexpected error message for invalid CreateInterface: " + str(e)) 2071 2072 wpas.RemoveInterface(path) 2073 try: 2074 wpas.RemoveInterface(path) 2075 raise Exception("Invalid RemoveInterface() accepted") 2076 except dbus.exceptions.DBusException as e: 2077 if "InterfaceUnknown" not in str(e): 2078 raise Exception("Unexpected error message for invalid RemoveInterface: " + str(e)) 2079 2080 params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none', 2081 'Foo': 123}, 2082 signature='sv') 2083 try: 2084 wpas.CreateInterface(params) 2085 raise Exception("Invalid CreateInterface() accepted") 2086 except dbus.exceptions.DBusException as e: 2087 if "InvalidArgs" not in str(e): 2088 raise Exception("Unexpected error message for invalid CreateInterface: " + str(e)) 2089 2090 params = dbus.Dictionary({'Driver': 'none'}, signature='sv') 2091 try: 2092 wpas.CreateInterface(params) 2093 raise Exception("Invalid CreateInterface() accepted") 2094 except dbus.exceptions.DBusException as e: 2095 if "InvalidArgs" not in str(e): 2096 raise Exception("Unexpected error message for invalid CreateInterface: " + str(e)) 2097 2098 try: 2099 wpas.GetInterface("lo") 2100 raise Exception("Invalid GetInterface() accepted") 2101 except dbus.exceptions.DBusException as e: 2102 if "InterfaceUnknown" not in str(e): 2103 raise Exception("Unexpected error message for invalid RemoveInterface: " + str(e)) 2104 2105 params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none', 2106 'Type': 'foo'}, signature='sv') 2107 try: 2108 wpas.CreateInterface(params) 2109 raise Exception("Invalid CreateInterface() accepted") 2110 except dbus.exceptions.DBusException as e: 2111 if "InvalidArgs" not in str(e): 2112 raise Exception("Unexpected error message for invalid CreateInterface: " + str(e)) 2113 2114 try: 2115 wpas.GetInterface("lo") 2116 raise Exception("Invalid GetInterface() accepted") 2117 except dbus.exceptions.DBusException as e: 2118 if "InterfaceUnknown" not in str(e): 2119 raise Exception("Unexpected error message for invalid RemoveInterface: " + str(e)) 2120 2121 params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none', 2122 'Address': 'foo'}, signature='sv') 2123 try: 2124 wpas.CreateInterface(params) 2125 raise Exception("Invalid CreateInterface() accepted") 2126 except dbus.exceptions.DBusException as e: 2127 if "InvalidArgs" not in str(e): 2128 raise Exception("Unexpected error message for invalid CreateInterface: " + str(e)) 2129 2130 try: 2131 wpas.GetInterface("lo") 2132 raise Exception("Invalid GetInterface() accepted") 2133 except dbus.exceptions.DBusException as e: 2134 if "InterfaceUnknown" not in str(e): 2135 raise Exception("Unexpected error message for invalid RemoveInterface: " + str(e)) 2136 2137def test_dbus_interface_oom(dev, apdev): 2138 """D-Bus CreateInterface/GetInterface/RemoveInterface OOM error cases""" 2139 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2140 wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE) 2141 2142 with alloc_fail_dbus(dev[0], 1, "wpa_dbus_dict_get_entry;wpas_dbus_handler_create_interface", "CreateInterface", "InvalidArgs"): 2143 params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none'}, 2144 signature='sv') 2145 wpas.CreateInterface(params) 2146 2147 for i in range(1, 1000): 2148 dev[0].request("TEST_ALLOC_FAIL %d:wpa_supplicant_add_iface;wpas_dbus_handler_create_interface" % i) 2149 params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none'}, 2150 signature='sv') 2151 try: 2152 npath = wpas.CreateInterface(params) 2153 wpas.RemoveInterface(npath) 2154 logger.info("CreateInterface succeeds after %d allocation failures" % i) 2155 state = dev[0].request('GET_ALLOC_FAIL') 2156 logger.info("GET_ALLOC_FAIL: " + state) 2157 dev[0].dump_monitor() 2158 dev[0].request("TEST_ALLOC_FAIL 0:") 2159 if i < 5: 2160 raise Exception("CreateInterface succeeded during out-of-memory") 2161 if not state.startswith('0:'): 2162 break 2163 except dbus.exceptions.DBusException as e: 2164 pass 2165 2166 for arg in ['Driver', 'Ifname', 'ConfigFile', 'BridgeIfname']: 2167 with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_handler_create_interface", 2168 "CreateInterface"): 2169 params = dbus.Dictionary({arg: 'foo'}, signature='sv') 2170 wpas.CreateInterface(params) 2171 2172def test_dbus_blob(dev, apdev): 2173 """D-Bus AddNetwork/RemoveNetwork parameters and error cases""" 2174 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2175 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2176 2177 blob = dbus.ByteArray(b"\x01\x02\x03") 2178 iface.AddBlob('blob1', blob) 2179 try: 2180 iface.AddBlob('blob1', dbus.ByteArray(b"\x01\x02\x04")) 2181 raise Exception("Invalid AddBlob() accepted") 2182 except dbus.exceptions.DBusException as e: 2183 if "BlobExists" not in str(e): 2184 raise Exception("Unexpected error message for invalid AddBlob: " + str(e)) 2185 res = iface.GetBlob('blob1') 2186 if len(res) != len(blob): 2187 raise Exception("Unexpected blob data length") 2188 for i in range(len(res)): 2189 if res[i] != dbus.Byte(blob[i]): 2190 raise Exception("Unexpected blob data") 2191 res = if_obj.Get(WPAS_DBUS_IFACE, "Blobs", 2192 dbus_interface=dbus.PROPERTIES_IFACE) 2193 if 'blob1' not in res: 2194 raise Exception("Added blob missing from Blobs property") 2195 iface.RemoveBlob('blob1') 2196 try: 2197 iface.RemoveBlob('blob1') 2198 raise Exception("Invalid RemoveBlob() accepted") 2199 except dbus.exceptions.DBusException as e: 2200 if "BlobUnknown" not in str(e): 2201 raise Exception("Unexpected error message for invalid RemoveBlob: " + str(e)) 2202 try: 2203 iface.GetBlob('blob1') 2204 raise Exception("Invalid GetBlob() accepted") 2205 except dbus.exceptions.DBusException as e: 2206 if "BlobUnknown" not in str(e): 2207 raise Exception("Unexpected error message for invalid GetBlob: " + str(e)) 2208 2209 class TestDbusBlob(TestDbus): 2210 def __init__(self, bus): 2211 TestDbus.__init__(self, bus) 2212 self.blob_added = False 2213 self.blob_removed = False 2214 2215 def __enter__(self): 2216 gobject.timeout_add(1, self.run_blob) 2217 gobject.timeout_add(15000, self.timeout) 2218 self.add_signal(self.blobAdded, WPAS_DBUS_IFACE, "BlobAdded") 2219 self.add_signal(self.blobRemoved, WPAS_DBUS_IFACE, "BlobRemoved") 2220 self.loop.run() 2221 return self 2222 2223 def blobAdded(self, blobName): 2224 logger.debug("blobAdded: %s" % blobName) 2225 if blobName == 'blob2': 2226 self.blob_added = True 2227 2228 def blobRemoved(self, blobName): 2229 logger.debug("blobRemoved: %s" % blobName) 2230 if blobName == 'blob2': 2231 self.blob_removed = True 2232 self.loop.quit() 2233 2234 def run_blob(self, *args): 2235 logger.debug("run_blob") 2236 iface.AddBlob('blob2', dbus.ByteArray(b"\x01\x02\x04")) 2237 iface.RemoveBlob('blob2') 2238 return False 2239 2240 def success(self): 2241 return self.blob_added and self.blob_removed 2242 2243 with TestDbusBlob(bus) as t: 2244 if not t.success(): 2245 raise Exception("Expected signals not seen") 2246 2247def test_dbus_blob_oom(dev, apdev): 2248 """D-Bus AddNetwork/RemoveNetwork OOM error cases""" 2249 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2250 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2251 2252 for i in range(1, 4): 2253 with alloc_fail_dbus(dev[0], i, "wpas_dbus_handler_add_blob", 2254 "AddBlob"): 2255 iface.AddBlob('blob_no_mem', dbus.ByteArray(b"\x01\x02\x03\x04")) 2256 2257def test_dbus_autoscan(dev, apdev): 2258 """D-Bus Autoscan()""" 2259 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2260 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2261 2262 iface.AutoScan("foo") 2263 iface.AutoScan("periodic:1") 2264 iface.AutoScan("") 2265 dev[0].request("AUTOSCAN ") 2266 2267def test_dbus_autoscan_oom(dev, apdev): 2268 """D-Bus Autoscan() OOM""" 2269 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2270 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2271 2272 with alloc_fail_dbus(dev[0], 1, "wpas_dbus_handler_autoscan", "AutoScan"): 2273 iface.AutoScan("foo") 2274 dev[0].request("AUTOSCAN ") 2275 2276def test_dbus_tdls_invalid(dev, apdev): 2277 """D-Bus invalid TDLS operations""" 2278 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2279 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2280 2281 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"}) 2282 connect_2sta_open(dev, hapd) 2283 addr1 = dev[1].p2p_interface_addr() 2284 2285 try: 2286 iface.TDLSDiscover("foo") 2287 raise Exception("Invalid TDLSDiscover() accepted") 2288 except dbus.exceptions.DBusException as e: 2289 if "InvalidArgs" not in str(e): 2290 raise Exception("Unexpected error message for invalid TDLSDiscover: " + str(e)) 2291 2292 try: 2293 iface.TDLSStatus("foo") 2294 raise Exception("Invalid TDLSStatus() accepted") 2295 except dbus.exceptions.DBusException as e: 2296 if "InvalidArgs" not in str(e): 2297 raise Exception("Unexpected error message for invalid TDLSStatus: " + str(e)) 2298 2299 res = iface.TDLSStatus(addr1) 2300 if res != "peer does not exist": 2301 raise Exception("Unexpected TDLSStatus response") 2302 2303 try: 2304 iface.TDLSSetup("foo") 2305 raise Exception("Invalid TDLSSetup() accepted") 2306 except dbus.exceptions.DBusException as e: 2307 if "InvalidArgs" not in str(e): 2308 raise Exception("Unexpected error message for invalid TDLSSetup: " + str(e)) 2309 2310 try: 2311 iface.TDLSTeardown("foo") 2312 raise Exception("Invalid TDLSTeardown() accepted") 2313 except dbus.exceptions.DBusException as e: 2314 if "InvalidArgs" not in str(e): 2315 raise Exception("Unexpected error message for invalid TDLSTeardown: " + str(e)) 2316 2317 try: 2318 iface.TDLSTeardown("00:11:22:33:44:55") 2319 raise Exception("TDLSTeardown accepted for unknown peer") 2320 except dbus.exceptions.DBusException as e: 2321 if "UnknownError: error performing TDLS teardown" not in str(e): 2322 raise Exception("Unexpected error message: " + str(e)) 2323 2324 try: 2325 iface.TDLSChannelSwitch({}) 2326 raise Exception("Invalid TDLSChannelSwitch() accepted") 2327 except dbus.exceptions.DBusException as e: 2328 if "InvalidArgs" not in str(e): 2329 raise Exception("Unexpected error message for invalid TDLSChannelSwitch: " + str(e)) 2330 2331 try: 2332 iface.TDLSCancelChannelSwitch("foo") 2333 raise Exception("Invalid TDLSCancelChannelSwitch() accepted") 2334 except dbus.exceptions.DBusException as e: 2335 if "InvalidArgs" not in str(e): 2336 raise Exception("Unexpected error message for invalid TDLSCancelChannelSwitch: " + str(e)) 2337 2338def test_dbus_tdls_oom(dev, apdev): 2339 """D-Bus TDLS operations during OOM""" 2340 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2341 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2342 2343 with alloc_fail_dbus(dev[0], 1, "wpa_tdls_add_peer", "TDLSSetup", 2344 "UnknownError: error performing TDLS setup"): 2345 iface.TDLSSetup("00:11:22:33:44:55") 2346 2347def test_dbus_tdls(dev, apdev): 2348 """D-Bus TDLS""" 2349 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2350 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2351 2352 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"}) 2353 connect_2sta_open(dev, hapd) 2354 2355 addr1 = dev[1].p2p_interface_addr() 2356 2357 class TestDbusTdls(TestDbus): 2358 def __init__(self, bus): 2359 TestDbus.__init__(self, bus) 2360 self.tdls_setup = False 2361 self.tdls_teardown = False 2362 2363 def __enter__(self): 2364 gobject.timeout_add(1, self.run_tdls) 2365 gobject.timeout_add(15000, self.timeout) 2366 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 2367 "PropertiesChanged") 2368 self.loop.run() 2369 return self 2370 2371 def propertiesChanged(self, properties): 2372 logger.debug("propertiesChanged: %s" % str(properties)) 2373 2374 def run_tdls(self, *args): 2375 logger.debug("run_tdls") 2376 iface.TDLSDiscover(addr1) 2377 gobject.timeout_add(100, self.run_tdls2) 2378 return False 2379 2380 def run_tdls2(self, *args): 2381 logger.debug("run_tdls2") 2382 iface.TDLSSetup(addr1) 2383 gobject.timeout_add(500, self.run_tdls3) 2384 return False 2385 2386 def run_tdls3(self, *args): 2387 logger.debug("run_tdls3") 2388 res = iface.TDLSStatus(addr1) 2389 if res == "connected": 2390 self.tdls_setup = True 2391 else: 2392 logger.info("Unexpected TDLSStatus: " + res) 2393 iface.TDLSTeardown(addr1) 2394 gobject.timeout_add(200, self.run_tdls4) 2395 return False 2396 2397 def run_tdls4(self, *args): 2398 logger.debug("run_tdls4") 2399 res = iface.TDLSStatus(addr1) 2400 if res == "peer does not exist": 2401 self.tdls_teardown = True 2402 else: 2403 logger.info("Unexpected TDLSStatus: " + res) 2404 self.loop.quit() 2405 return False 2406 2407 def success(self): 2408 return self.tdls_setup and self.tdls_teardown 2409 2410 with TestDbusTdls(bus) as t: 2411 if not t.success(): 2412 raise Exception("Expected signals not seen") 2413 2414def test_dbus_tdls_channel_switch(dev, apdev): 2415 """D-Bus TDLS channel switch configuration""" 2416 flags = int(dev[0].get_driver_status_field('capa.flags'), 16) 2417 if flags & 0x800000000 == 0: 2418 raise HwsimSkip("Driver does not support TDLS channel switching") 2419 2420 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2421 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2422 2423 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"}) 2424 connect_2sta_open(dev, hapd) 2425 2426 addr1 = dev[1].p2p_interface_addr() 2427 2428 class TestDbusTdls(TestDbus): 2429 def __init__(self, bus): 2430 TestDbus.__init__(self, bus) 2431 self.tdls_setup = False 2432 self.tdls_done = False 2433 2434 def __enter__(self): 2435 gobject.timeout_add(1, self.run_tdls) 2436 gobject.timeout_add(15000, self.timeout) 2437 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 2438 "PropertiesChanged") 2439 self.loop.run() 2440 return self 2441 2442 def propertiesChanged(self, properties): 2443 logger.debug("propertiesChanged: %s" % str(properties)) 2444 2445 def run_tdls(self, *args): 2446 logger.debug("run_tdls") 2447 iface.TDLSDiscover(addr1) 2448 gobject.timeout_add(100, self.run_tdls2) 2449 return False 2450 2451 def run_tdls2(self, *args): 2452 logger.debug("run_tdls2") 2453 iface.TDLSSetup(addr1) 2454 gobject.timeout_add(500, self.run_tdls3) 2455 return False 2456 2457 def run_tdls3(self, *args): 2458 logger.debug("run_tdls3") 2459 res = iface.TDLSStatus(addr1) 2460 if res == "connected": 2461 self.tdls_setup = True 2462 else: 2463 logger.info("Unexpected TDLSStatus: " + res) 2464 2465 # Unknown dict entry 2466 args = dbus.Dictionary({'Foobar': dbus.Byte(1)}, 2467 signature='sv') 2468 try: 2469 iface.TDLSChannelSwitch(args) 2470 except Exception as e: 2471 if "InvalidArgs" not in str(e): 2472 raise Exception("Unexpected exception") 2473 2474 # Missing OperClass 2475 args = dbus.Dictionary({}, signature='sv') 2476 try: 2477 iface.TDLSChannelSwitch(args) 2478 except Exception as e: 2479 if "InvalidArgs" not in str(e): 2480 raise Exception("Unexpected exception") 2481 2482 # Missing Frequency 2483 args = dbus.Dictionary({'OperClass': dbus.Byte(1)}, 2484 signature='sv') 2485 try: 2486 iface.TDLSChannelSwitch(args) 2487 except Exception as e: 2488 if "InvalidArgs" not in str(e): 2489 raise Exception("Unexpected exception") 2490 2491 # Missing PeerAddress 2492 args = dbus.Dictionary({'OperClass': dbus.Byte(1), 2493 'Frequency': dbus.UInt32(2417)}, 2494 signature='sv') 2495 try: 2496 iface.TDLSChannelSwitch(args) 2497 except Exception as e: 2498 if "InvalidArgs" not in str(e): 2499 raise Exception("Unexpected exception") 2500 2501 # Valid parameters 2502 args = dbus.Dictionary({'OperClass': dbus.Byte(1), 2503 'Frequency': dbus.UInt32(2417), 2504 'PeerAddress': addr1, 2505 'SecChannelOffset': dbus.UInt32(0), 2506 'CenterFrequency1': dbus.UInt32(0), 2507 'CenterFrequency2': dbus.UInt32(0), 2508 'Bandwidth': dbus.UInt32(20), 2509 'HT': dbus.Boolean(False), 2510 'VHT': dbus.Boolean(False)}, 2511 signature='sv') 2512 iface.TDLSChannelSwitch(args) 2513 2514 gobject.timeout_add(200, self.run_tdls4) 2515 return False 2516 2517 def run_tdls4(self, *args): 2518 logger.debug("run_tdls4") 2519 iface.TDLSCancelChannelSwitch(addr1) 2520 self.tdls_done = True 2521 self.loop.quit() 2522 return False 2523 2524 def success(self): 2525 return self.tdls_setup and self.tdls_done 2526 2527 with TestDbusTdls(bus) as t: 2528 if not t.success(): 2529 raise Exception("Expected signals not seen") 2530 2531def test_dbus_pkcs11(dev, apdev): 2532 """D-Bus SetPKCS11EngineAndModulePath()""" 2533 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2534 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2535 2536 try: 2537 iface.SetPKCS11EngineAndModulePath("foo", "bar") 2538 except dbus.exceptions.DBusException as e: 2539 if "Error.Failed: Reinit of the EAPOL" not in str(e): 2540 raise Exception("Unexpected error message for invalid SetPKCS11EngineAndModulePath: " + str(e)) 2541 2542 try: 2543 iface.SetPKCS11EngineAndModulePath("foo", "") 2544 except dbus.exceptions.DBusException as e: 2545 if "Error.Failed: Reinit of the EAPOL" not in str(e): 2546 raise Exception("Unexpected error message for invalid SetPKCS11EngineAndModulePath: " + str(e)) 2547 2548 iface.SetPKCS11EngineAndModulePath("", "bar") 2549 res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11EnginePath", 2550 dbus_interface=dbus.PROPERTIES_IFACE) 2551 if res != "": 2552 raise Exception("Unexpected PKCS11EnginePath value: " + res) 2553 res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11ModulePath", 2554 dbus_interface=dbus.PROPERTIES_IFACE) 2555 if res != "bar": 2556 raise Exception("Unexpected PKCS11ModulePath value: " + res) 2557 2558 iface.SetPKCS11EngineAndModulePath("", "") 2559 res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11EnginePath", 2560 dbus_interface=dbus.PROPERTIES_IFACE) 2561 if res != "": 2562 raise Exception("Unexpected PKCS11EnginePath value: " + res) 2563 res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11ModulePath", 2564 dbus_interface=dbus.PROPERTIES_IFACE) 2565 if res != "": 2566 raise Exception("Unexpected PKCS11ModulePath value: " + res) 2567 2568def test_dbus_apscan(dev, apdev): 2569 """D-Bus Get/Set ApScan""" 2570 try: 2571 _test_dbus_apscan(dev, apdev) 2572 finally: 2573 dev[0].request("AP_SCAN 1") 2574 2575def _test_dbus_apscan(dev, apdev): 2576 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2577 2578 res = if_obj.Get(WPAS_DBUS_IFACE, "ApScan", 2579 dbus_interface=dbus.PROPERTIES_IFACE) 2580 if res != 1: 2581 raise Exception("Unexpected initial ApScan value: %d" % res) 2582 2583 for i in range(3): 2584 if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(i), 2585 dbus_interface=dbus.PROPERTIES_IFACE) 2586 res = if_obj.Get(WPAS_DBUS_IFACE, "ApScan", 2587 dbus_interface=dbus.PROPERTIES_IFACE) 2588 if res != i: 2589 raise Exception("Unexpected ApScan value %d (expected %d)" % (res, i)) 2590 2591 try: 2592 if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.Int16(-1), 2593 dbus_interface=dbus.PROPERTIES_IFACE) 2594 raise Exception("Invalid Set(ApScan,-1) accepted") 2595 except dbus.exceptions.DBusException as e: 2596 if "Error.Failed: wrong property type" not in str(e): 2597 raise Exception("Unexpected error message for invalid Set(ApScan,-1): " + str(e)) 2598 2599 try: 2600 if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(123), 2601 dbus_interface=dbus.PROPERTIES_IFACE) 2602 raise Exception("Invalid Set(ApScan,123) accepted") 2603 except dbus.exceptions.DBusException as e: 2604 if "Error.Failed: ap_scan must be 0, 1, or 2" not in str(e): 2605 raise Exception("Unexpected error message for invalid Set(ApScan,123): " + str(e)) 2606 2607 if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(1), 2608 dbus_interface=dbus.PROPERTIES_IFACE) 2609 2610def test_dbus_pmf(dev, apdev): 2611 """D-Bus Get/Set Pmf""" 2612 try: 2613 _test_dbus_pmf(dev, apdev) 2614 finally: 2615 dev[0].request("SET pmf 0") 2616 2617def _test_dbus_pmf(dev, apdev): 2618 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2619 2620 dev[0].set("pmf", "0") 2621 res = if_obj.Get(WPAS_DBUS_IFACE, "Pmf", 2622 dbus_interface=dbus.PROPERTIES_IFACE) 2623 if res != "0": 2624 raise Exception("Unexpected initial Pmf value: %s" % res) 2625 2626 for i in range(3): 2627 if_obj.Set(WPAS_DBUS_IFACE, "Pmf", str(i), 2628 dbus_interface=dbus.PROPERTIES_IFACE) 2629 res = if_obj.Get(WPAS_DBUS_IFACE, "Pmf", 2630 dbus_interface=dbus.PROPERTIES_IFACE) 2631 if res != str(i): 2632 raise Exception("Unexpected Pmf value %s (expected %d)" % (res, i)) 2633 2634 if_obj.Set(WPAS_DBUS_IFACE, "Pmf", "1", 2635 dbus_interface=dbus.PROPERTIES_IFACE) 2636 2637def test_dbus_fastreauth(dev, apdev): 2638 """D-Bus Get/Set FastReauth""" 2639 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2640 2641 res = if_obj.Get(WPAS_DBUS_IFACE, "FastReauth", 2642 dbus_interface=dbus.PROPERTIES_IFACE) 2643 if res != True: 2644 raise Exception("Unexpected initial FastReauth value: " + str(res)) 2645 2646 for i in [False, True]: 2647 if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Boolean(i), 2648 dbus_interface=dbus.PROPERTIES_IFACE) 2649 res = if_obj.Get(WPAS_DBUS_IFACE, "FastReauth", 2650 dbus_interface=dbus.PROPERTIES_IFACE) 2651 if res != i: 2652 raise Exception("Unexpected FastReauth value %d (expected %d)" % (res, i)) 2653 2654 try: 2655 if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Int16(-1), 2656 dbus_interface=dbus.PROPERTIES_IFACE) 2657 raise Exception("Invalid Set(FastReauth,-1) accepted") 2658 except dbus.exceptions.DBusException as e: 2659 if "Error.Failed: wrong property type" not in str(e): 2660 raise Exception("Unexpected error message for invalid Set(ApScan,-1): " + str(e)) 2661 2662 if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Boolean(True), 2663 dbus_interface=dbus.PROPERTIES_IFACE) 2664 2665def test_dbus_bss_expire(dev, apdev): 2666 """D-Bus Get/Set BSSExpireAge and BSSExpireCount""" 2667 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2668 2669 if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(179), 2670 dbus_interface=dbus.PROPERTIES_IFACE) 2671 res = if_obj.Get(WPAS_DBUS_IFACE, "BSSExpireAge", 2672 dbus_interface=dbus.PROPERTIES_IFACE) 2673 if res != 179: 2674 raise Exception("Unexpected BSSExpireAge value %d (expected %d)" % (res, i)) 2675 2676 if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(3), 2677 dbus_interface=dbus.PROPERTIES_IFACE) 2678 res = if_obj.Get(WPAS_DBUS_IFACE, "BSSExpireCount", 2679 dbus_interface=dbus.PROPERTIES_IFACE) 2680 if res != 3: 2681 raise Exception("Unexpected BSSExpireCount value %d (expected %d)" % (res, i)) 2682 2683 try: 2684 if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.Int16(-1), 2685 dbus_interface=dbus.PROPERTIES_IFACE) 2686 raise Exception("Invalid Set(BSSExpireAge,-1) accepted") 2687 except dbus.exceptions.DBusException as e: 2688 if "Error.Failed: wrong property type" not in str(e): 2689 raise Exception("Unexpected error message for invalid Set(BSSExpireAge,-1): " + str(e)) 2690 2691 try: 2692 if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(9), 2693 dbus_interface=dbus.PROPERTIES_IFACE) 2694 raise Exception("Invalid Set(BSSExpireAge,9) accepted") 2695 except dbus.exceptions.DBusException as e: 2696 if "Error.Failed: BSSExpireAge must be >= 10" not in str(e): 2697 raise Exception("Unexpected error message for invalid Set(BSSExpireAge,9): " + str(e)) 2698 2699 try: 2700 if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.Int16(-1), 2701 dbus_interface=dbus.PROPERTIES_IFACE) 2702 raise Exception("Invalid Set(BSSExpireCount,-1) accepted") 2703 except dbus.exceptions.DBusException as e: 2704 if "Error.Failed: wrong property type" not in str(e): 2705 raise Exception("Unexpected error message for invalid Set(BSSExpireCount,-1): " + str(e)) 2706 2707 try: 2708 if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(0), 2709 dbus_interface=dbus.PROPERTIES_IFACE) 2710 raise Exception("Invalid Set(BSSExpireCount,0) accepted") 2711 except dbus.exceptions.DBusException as e: 2712 if "Error.Failed: BSSExpireCount must be > 0" not in str(e): 2713 raise Exception("Unexpected error message for invalid Set(BSSExpireCount,0): " + str(e)) 2714 2715 if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(180), 2716 dbus_interface=dbus.PROPERTIES_IFACE) 2717 if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(2), 2718 dbus_interface=dbus.PROPERTIES_IFACE) 2719 2720def test_dbus_country(dev, apdev): 2721 """D-Bus Get/Set Country""" 2722 try: 2723 _test_dbus_country(dev, apdev) 2724 finally: 2725 dev[0].request("SET country 00") 2726 subprocess.call(['iw', 'reg', 'set', '00']) 2727 2728def _test_dbus_country(dev, apdev): 2729 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2730 2731 # work around issues with possible pending regdom event from the end of 2732 # the previous test case 2733 time.sleep(0.2) 2734 dev[0].dump_monitor() 2735 2736 if_obj.Set(WPAS_DBUS_IFACE, "Country", "FI", 2737 dbus_interface=dbus.PROPERTIES_IFACE) 2738 res = if_obj.Get(WPAS_DBUS_IFACE, "Country", 2739 dbus_interface=dbus.PROPERTIES_IFACE) 2740 if res != "FI": 2741 raise Exception("Unexpected Country value %s (expected FI)" % res) 2742 2743 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"]) 2744 if ev is None: 2745 # For now, work around separate P2P Device interface event delivery 2746 ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) 2747 if ev is None: 2748 raise Exception("regdom change event not seen") 2749 if "init=USER type=COUNTRY alpha2=FI" not in ev: 2750 raise Exception("Unexpected event contents: " + ev) 2751 2752 try: 2753 if_obj.Set(WPAS_DBUS_IFACE, "Country", dbus.Int16(-1), 2754 dbus_interface=dbus.PROPERTIES_IFACE) 2755 raise Exception("Invalid Set(Country,-1) accepted") 2756 except dbus.exceptions.DBusException as e: 2757 if "Error.Failed: wrong property type" not in str(e): 2758 raise Exception("Unexpected error message for invalid Set(Country,-1): " + str(e)) 2759 2760 try: 2761 if_obj.Set(WPAS_DBUS_IFACE, "Country", "F", 2762 dbus_interface=dbus.PROPERTIES_IFACE) 2763 raise Exception("Invalid Set(Country,F) accepted") 2764 except dbus.exceptions.DBusException as e: 2765 if "Error.Failed: invalid country code" not in str(e): 2766 raise Exception("Unexpected error message for invalid Set(Country,F): " + str(e)) 2767 2768 if_obj.Set(WPAS_DBUS_IFACE, "Country", "00", 2769 dbus_interface=dbus.PROPERTIES_IFACE) 2770 2771 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"]) 2772 if ev is None: 2773 # For now, work around separate P2P Device interface event delivery 2774 ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) 2775 if ev is None: 2776 raise Exception("regdom change event not seen") 2777 # init=CORE was previously used due to invalid db.txt data for 00. For 2778 # now, allow both it and the new init=USER after fixed db.txt. 2779 if "init=CORE type=WORLD" not in ev and "init=USER type=WORLD" not in ev: 2780 raise Exception("Unexpected event contents: " + ev) 2781 2782def test_dbus_scan_interval(dev, apdev): 2783 """D-Bus Get/Set ScanInterval""" 2784 try: 2785 _test_dbus_scan_interval(dev, apdev) 2786 finally: 2787 dev[0].request("SCAN_INTERVAL 5") 2788 2789def _test_dbus_scan_interval(dev, apdev): 2790 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2791 2792 if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(3), 2793 dbus_interface=dbus.PROPERTIES_IFACE) 2794 res = if_obj.Get(WPAS_DBUS_IFACE, "ScanInterval", 2795 dbus_interface=dbus.PROPERTIES_IFACE) 2796 if res != 3: 2797 raise Exception("Unexpected ScanInterval value %d (expected %d)" % (res, i)) 2798 2799 try: 2800 if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.UInt16(100), 2801 dbus_interface=dbus.PROPERTIES_IFACE) 2802 raise Exception("Invalid Set(ScanInterval,100) accepted") 2803 except dbus.exceptions.DBusException as e: 2804 if "Error.Failed: wrong property type" not in str(e): 2805 raise Exception("Unexpected error message for invalid Set(ScanInterval,100): " + str(e)) 2806 2807 try: 2808 if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(-1), 2809 dbus_interface=dbus.PROPERTIES_IFACE) 2810 raise Exception("Invalid Set(ScanInterval,-1) accepted") 2811 except dbus.exceptions.DBusException as e: 2812 if "Error.Failed: scan_interval must be >= 0" not in str(e): 2813 raise Exception("Unexpected error message for invalid Set(ScanInterval,-1): " + str(e)) 2814 2815 if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(5), 2816 dbus_interface=dbus.PROPERTIES_IFACE) 2817 2818def test_dbus_probe_req_reporting(dev, apdev): 2819 """D-Bus Probe Request reporting""" 2820 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2821 2822 dev[1].p2p_find(social=True) 2823 2824 class TestDbusProbe(TestDbus): 2825 def __init__(self, bus): 2826 TestDbus.__init__(self, bus) 2827 self.reported = False 2828 2829 def __enter__(self): 2830 gobject.timeout_add(1, self.run_test) 2831 gobject.timeout_add(15000, self.timeout) 2832 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 2833 "GroupStarted") 2834 self.add_signal(self.probeRequest, WPAS_DBUS_IFACE, "ProbeRequest", 2835 byte_arrays=True) 2836 self.loop.run() 2837 return self 2838 2839 def groupStarted(self, properties): 2840 logger.debug("groupStarted: " + str(properties)) 2841 g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 2842 properties['interface_object']) 2843 self.iface = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE) 2844 self.iface.SubscribeProbeReq() 2845 self.group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 2846 2847 def probeRequest(self, args): 2848 logger.debug("probeRequest: args=%s" % str(args)) 2849 self.reported = True 2850 self.loop.quit() 2851 2852 def run_test(self, *args): 2853 logger.debug("run_test") 2854 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 2855 params = dbus.Dictionary({'frequency': 2412}) 2856 p2p.GroupAdd(params) 2857 return False 2858 2859 def success(self): 2860 return self.reported 2861 2862 with TestDbusProbe(bus) as t: 2863 if not t.success(): 2864 raise Exception("Expected signals not seen") 2865 t.iface.UnsubscribeProbeReq() 2866 try: 2867 t.iface.UnsubscribeProbeReq() 2868 raise Exception("Invalid UnsubscribeProbeReq() accepted") 2869 except dbus.exceptions.DBusException as e: 2870 if "NoSubscription" not in str(e): 2871 raise Exception("Unexpected error message for invalid UnsubscribeProbeReq(): " + str(e)) 2872 t.group_p2p.Disconnect() 2873 2874 with TestDbusProbe(bus) as t: 2875 if not t.success(): 2876 raise Exception("Expected signals not seen") 2877 # On purpose, leave ProbeReq subscription in place to test automatic 2878 # cleanup. 2879 2880 dev[1].p2p_stop_find() 2881 2882def test_dbus_probe_req_reporting_oom(dev, apdev): 2883 """D-Bus Probe Request reporting (OOM)""" 2884 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2885 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 2886 2887 # Need to make sure this process has not already subscribed to avoid false 2888 # failures due to the operation succeeding due to os_strdup() not even 2889 # getting called. 2890 try: 2891 iface.UnsubscribeProbeReq() 2892 was_subscribed = True 2893 except dbus.exceptions.DBusException as e: 2894 was_subscribed = False 2895 pass 2896 2897 with alloc_fail_dbus(dev[0], 1, "wpas_dbus_handler_subscribe_preq", 2898 "SubscribeProbeReq"): 2899 iface.SubscribeProbeReq() 2900 2901 if was_subscribed: 2902 # On purpose, leave ProbeReq subscription in place to test automatic 2903 # cleanup. 2904 iface.SubscribeProbeReq() 2905 2906def test_dbus_p2p_invalid(dev, apdev): 2907 """D-Bus invalid P2P operations""" 2908 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 2909 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 2910 2911 try: 2912 p2p.RejectPeer(path + "/Peers/00112233445566") 2913 raise Exception("Invalid RejectPeer accepted") 2914 except dbus.exceptions.DBusException as e: 2915 if "UnknownError: Failed to call wpas_p2p_reject" not in str(e): 2916 raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e)) 2917 2918 try: 2919 p2p.RejectPeer("/foo") 2920 raise Exception("Invalid RejectPeer accepted") 2921 except dbus.exceptions.DBusException as e: 2922 if "InvalidArgs" not in str(e): 2923 raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e)) 2924 2925 tests = [{}, 2926 {'peer': 'foo'}, 2927 {'foo': "bar"}, 2928 {'iface': "abc"}, 2929 {'iface': 123}] 2930 for t in tests: 2931 try: 2932 p2p.RemoveClient(t) 2933 raise Exception("Invalid RemoveClient accepted") 2934 except dbus.exceptions.DBusException as e: 2935 if "InvalidArgs" not in str(e): 2936 raise Exception("Unexpected error message for invalid RemoveClient(): " + str(e)) 2937 2938 tests = [{'DiscoveryType': 'foo'}, 2939 {'RequestedDeviceTypes': 'foo'}, 2940 {'RequestedDeviceTypes': ['foo']}, 2941 {'RequestedDeviceTypes': ['1', '2', '3', '4', '5', '6', '7', '8', 2942 '9', '10', '11', '12', '13', '14', '15', 2943 '16', '17']}, 2944 {'RequestedDeviceTypes': dbus.Array([], signature="s")}, 2945 {'RequestedDeviceTypes': dbus.Array([['foo']], signature="as")}, 2946 {'RequestedDeviceTypes': dbus.Array([], signature="i")}, 2947 {'RequestedDeviceTypes': [dbus.ByteArray(b'12345678'), 2948 dbus.ByteArray(b'1234567')]}, 2949 {'Foo': dbus.Int16(1)}, 2950 {'Foo': dbus.UInt16(1)}, 2951 {'Foo': dbus.Int64(1)}, 2952 {'Foo': dbus.UInt64(1)}, 2953 {'Foo': dbus.Double(1.23)}, 2954 {'Foo': dbus.Signature('s')}, 2955 {'Foo': 'bar'}] 2956 for t in tests: 2957 try: 2958 p2p.Find(dbus.Dictionary(t)) 2959 raise Exception("Invalid Find accepted") 2960 except dbus.exceptions.DBusException as e: 2961 if "InvalidArgs" not in str(e): 2962 raise Exception("Unexpected error message for invalid Find(): " + str(e)) 2963 2964 for p in ["/foo", 2965 "/fi/w1/wpa_supplicant1/Interfaces/1234", 2966 "/fi/w1/wpa_supplicant1/Interfaces/1234/Networks/1234"]: 2967 try: 2968 p2p.RemovePersistentGroup(dbus.ObjectPath(p)) 2969 raise Exception("Invalid RemovePersistentGroup accepted") 2970 except dbus.exceptions.DBusException as e: 2971 if "InvalidArgs" not in str(e): 2972 raise Exception("Unexpected error message for invalid RemovePersistentGroup: " + str(e)) 2973 2974 try: 2975 dev[0].request("P2P_SET disabled 1") 2976 p2p.Listen(5) 2977 raise Exception("Invalid Listen accepted") 2978 except dbus.exceptions.DBusException as e: 2979 if "UnknownError: Could not start P2P listen" not in str(e): 2980 raise Exception("Unexpected error message for invalid Listen: " + str(e)) 2981 finally: 2982 dev[0].request("P2P_SET disabled 0") 2983 2984 test_obj = bus.get_object(WPAS_DBUS_SERVICE, path, introspect=False) 2985 test_p2p = dbus.Interface(test_obj, WPAS_DBUS_IFACE_P2PDEVICE) 2986 try: 2987 test_p2p.Listen("foo") 2988 raise Exception("Invalid Listen accepted") 2989 except dbus.exceptions.DBusException as e: 2990 if "InvalidArgs" not in str(e): 2991 raise Exception("Unexpected error message for invalid Listen: " + str(e)) 2992 2993 try: 2994 dev[0].request("P2P_SET disabled 1") 2995 p2p.ExtendedListen(dbus.Dictionary({})) 2996 raise Exception("Invalid ExtendedListen accepted") 2997 except dbus.exceptions.DBusException as e: 2998 if "UnknownError: failed to initiate a p2p_ext_listen" not in str(e): 2999 raise Exception("Unexpected error message for invalid ExtendedListen: " + str(e)) 3000 finally: 3001 dev[0].request("P2P_SET disabled 0") 3002 3003 try: 3004 dev[0].request("P2P_SET disabled 1") 3005 args = {'duration1': 30000, 'interval1': 102400, 3006 'duration2': 20000, 'interval2': 102400} 3007 p2p.PresenceRequest(args) 3008 raise Exception("Invalid PresenceRequest accepted") 3009 except dbus.exceptions.DBusException as e: 3010 if "UnknownError: Failed to invoke presence request" not in str(e): 3011 raise Exception("Unexpected error message for invalid PresenceRequest: " + str(e)) 3012 finally: 3013 dev[0].request("P2P_SET disabled 0") 3014 3015 try: 3016 params = dbus.Dictionary({'frequency': dbus.Int32(-1)}) 3017 p2p.GroupAdd(params) 3018 raise Exception("Invalid GroupAdd accepted") 3019 except dbus.exceptions.DBusException as e: 3020 if "InvalidArgs" not in str(e): 3021 raise Exception("Unexpected error message for invalid GroupAdd: " + str(e)) 3022 3023 try: 3024 params = dbus.Dictionary({'persistent_group_object': 3025 dbus.ObjectPath(path), 3026 'frequency': 2412}) 3027 p2p.GroupAdd(params) 3028 raise Exception("Invalid GroupAdd accepted") 3029 except dbus.exceptions.DBusException as e: 3030 if "InvalidArgs" not in str(e): 3031 raise Exception("Unexpected error message for invalid GroupAdd: " + str(e)) 3032 3033 try: 3034 p2p.Disconnect() 3035 raise Exception("Invalid Disconnect accepted") 3036 except dbus.exceptions.DBusException as e: 3037 if "UnknownError: failed to disconnect" not in str(e): 3038 raise Exception("Unexpected error message for invalid Disconnect: " + str(e)) 3039 3040 try: 3041 dev[0].request("P2P_SET disabled 1") 3042 p2p.Flush() 3043 raise Exception("Invalid Flush accepted") 3044 except dbus.exceptions.DBusException as e: 3045 if "Error.Failed: P2P is not available for this interface" not in str(e): 3046 raise Exception("Unexpected error message for invalid Flush: " + str(e)) 3047 finally: 3048 dev[0].request("P2P_SET disabled 0") 3049 3050 try: 3051 dev[0].request("P2P_SET disabled 1") 3052 args = {'peer': path, 3053 'join': True, 3054 'wps_method': 'pbc', 3055 'frequency': 2412} 3056 pin = p2p.Connect(args) 3057 raise Exception("Invalid Connect accepted") 3058 except dbus.exceptions.DBusException as e: 3059 if "Error.Failed: P2P is not available for this interface" not in str(e): 3060 raise Exception("Unexpected error message for invalid Connect: " + str(e)) 3061 finally: 3062 dev[0].request("P2P_SET disabled 0") 3063 3064 tests = [{'frequency': dbus.Int32(-1)}, 3065 {'wps_method': 'pbc'}, 3066 {'wps_method': 'foo'}] 3067 for args in tests: 3068 try: 3069 pin = p2p.Connect(args) 3070 raise Exception("Invalid Connect accepted") 3071 except dbus.exceptions.DBusException as e: 3072 if "InvalidArgs" not in str(e): 3073 raise Exception("Unexpected error message for invalid Connect: " + str(e)) 3074 3075 try: 3076 dev[0].request("P2P_SET disabled 1") 3077 args = {'peer': path} 3078 pin = p2p.Invite(args) 3079 raise Exception("Invalid Invite accepted") 3080 except dbus.exceptions.DBusException as e: 3081 if "Error.Failed: P2P is not available for this interface" not in str(e): 3082 raise Exception("Unexpected error message for invalid Invite: " + str(e)) 3083 finally: 3084 dev[0].request("P2P_SET disabled 0") 3085 3086 try: 3087 args = {'foo': 'bar'} 3088 pin = p2p.Invite(args) 3089 raise Exception("Invalid Invite accepted") 3090 except dbus.exceptions.DBusException as e: 3091 if "InvalidArgs" not in str(e): 3092 raise Exception("Unexpected error message for invalid Connect: " + str(e)) 3093 3094 tests = [(path, 'display', "InvalidArgs"), 3095 (dbus.ObjectPath(path + "/Peers/00112233445566"), 3096 'display', 3097 "UnknownError: Failed to send provision discovery request"), 3098 (dbus.ObjectPath(path + "/Peers/00112233445566"), 3099 'keypad', 3100 "UnknownError: Failed to send provision discovery request"), 3101 (dbus.ObjectPath(path + "/Peers/00112233445566"), 3102 'pbc', 3103 "UnknownError: Failed to send provision discovery request"), 3104 (dbus.ObjectPath(path + "/Peers/00112233445566"), 3105 'pushbutton', 3106 "UnknownError: Failed to send provision discovery request"), 3107 (dbus.ObjectPath(path + "/Peers/00112233445566"), 3108 'foo', "InvalidArgs")] 3109 for (p, method, err) in tests: 3110 try: 3111 p2p.ProvisionDiscoveryRequest(p, method) 3112 raise Exception("Invalid ProvisionDiscoveryRequest accepted") 3113 except dbus.exceptions.DBusException as e: 3114 if err not in str(e): 3115 raise Exception("Unexpected error message for invalid ProvisionDiscoveryRequest: " + str(e)) 3116 3117 try: 3118 dev[0].request("P2P_SET disabled 1") 3119 if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Peers", 3120 dbus_interface=dbus.PROPERTIES_IFACE) 3121 raise Exception("Invalid Get(Peers) accepted") 3122 except dbus.exceptions.DBusException as e: 3123 if "Error.Failed: P2P is not available for this interface" not in str(e): 3124 raise Exception("Unexpected error message for invalid Get(Peers): " + str(e)) 3125 finally: 3126 dev[0].request("P2P_SET disabled 0") 3127 3128def test_dbus_p2p_oom(dev, apdev): 3129 """D-Bus P2P operations and OOM""" 3130 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 3131 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 3132 3133 with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_string_array", 3134 "Find", "InvalidArgs"): 3135 p2p.Find(dbus.Dictionary({'Foo': ['bar']})) 3136 3137 with alloc_fail_dbus(dev[0], 2, "_wpa_dbus_dict_entry_get_string_array", 3138 "Find", "InvalidArgs"): 3139 p2p.Find(dbus.Dictionary({'Foo': ['bar']})) 3140 3141 with alloc_fail_dbus(dev[0], 10, "_wpa_dbus_dict_entry_get_string_array", 3142 "Find", "InvalidArgs"): 3143 p2p.Find(dbus.Dictionary({'Foo': ['1', '2', '3', '4', '5', '6', '7', 3144 '8', '9']})) 3145 3146 with alloc_fail_dbus(dev[0], 1, ":=_wpa_dbus_dict_entry_get_binarray", 3147 "Find", "InvalidArgs"): 3148 p2p.Find(dbus.Dictionary({'Foo': [dbus.ByteArray(b'123')]})) 3149 3150 with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_byte_array;_wpa_dbus_dict_entry_get_binarray", 3151 "Find", "InvalidArgs"): 3152 p2p.Find(dbus.Dictionary({'Foo': [dbus.ByteArray(b'123')]})) 3153 3154 with alloc_fail_dbus(dev[0], 2, "=_wpa_dbus_dict_entry_get_binarray", 3155 "Find", "InvalidArgs"): 3156 p2p.Find(dbus.Dictionary({'Foo': [dbus.ByteArray(b'123'), 3157 dbus.ByteArray(b'123'), 3158 dbus.ByteArray(b'123'), 3159 dbus.ByteArray(b'123'), 3160 dbus.ByteArray(b'123'), 3161 dbus.ByteArray(b'123'), 3162 dbus.ByteArray(b'123'), 3163 dbus.ByteArray(b'123'), 3164 dbus.ByteArray(b'123'), 3165 dbus.ByteArray(b'123'), 3166 dbus.ByteArray(b'123')]})) 3167 3168 with alloc_fail_dbus(dev[0], 1, "wpabuf_alloc_ext_data;_wpa_dbus_dict_entry_get_binarray", 3169 "Find", "InvalidArgs"): 3170 p2p.Find(dbus.Dictionary({'Foo': [dbus.ByteArray(b'123')]})) 3171 3172 with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_fill_value_from_variant;wpas_dbus_handler_p2p_find", 3173 "Find", "InvalidArgs"): 3174 p2p.Find(dbus.Dictionary({'Foo': path})) 3175 3176 with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_byte_array", 3177 "AddService", "InvalidArgs"): 3178 args = {'service_type': 'bonjour', 3179 'response': dbus.ByteArray(500*b'b')} 3180 p2p.AddService(args) 3181 3182 with alloc_fail_dbus(dev[0], 2, "_wpa_dbus_dict_entry_get_byte_array", 3183 "AddService", "InvalidArgs"): 3184 p2p.AddService(args) 3185 3186def test_dbus_p2p_discovery(dev, apdev): 3187 """D-Bus P2P discovery""" 3188 try: 3189 run_dbus_p2p_discovery(dev, apdev) 3190 finally: 3191 dev[1].request("VENDOR_ELEM_REMOVE 1 *") 3192 3193def run_dbus_p2p_discovery(dev, apdev): 3194 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 3195 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 3196 3197 addr0 = dev[0].p2p_dev_addr() 3198 3199 dev[1].request("SET sec_device_type 1-0050F204-2") 3200 dev[1].request("VENDOR_ELEM_ADD 1 dd0c0050f2041049000411223344") 3201 dev[1].request("VENDOR_ELEM_ADD 1 dd06001122335566") 3202 dev[1].p2p_listen() 3203 addr1 = dev[1].p2p_dev_addr() 3204 a1 = binascii.unhexlify(addr1.replace(':', '')) 3205 3206 wfd_devinfo = "00001c440028" 3207 dev[2].request("SET wifi_display 1") 3208 dev[2].request("WFD_SUBELEM_SET 0 0006" + wfd_devinfo) 3209 wfd = binascii.unhexlify('000006' + wfd_devinfo) 3210 dev[2].p2p_listen() 3211 addr2 = dev[2].p2p_dev_addr() 3212 a2 = binascii.unhexlify(addr2.replace(':', '')) 3213 3214 res = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE, 3215 dbus_interface=dbus.PROPERTIES_IFACE) 3216 if 'Peers' not in res: 3217 raise Exception("GetAll result missing Peers") 3218 if len(res['Peers']) != 0: 3219 raise Exception("Unexpected peer(s) in the list") 3220 3221 args = {'DiscoveryType': 'social', 3222 'RequestedDeviceTypes': [dbus.ByteArray(b'12345678')], 3223 'Timeout': dbus.Int32(1)} 3224 p2p.Find(dbus.Dictionary(args)) 3225 p2p.StopFind() 3226 3227 class TestDbusP2p(TestDbus): 3228 def __init__(self, bus): 3229 TestDbus.__init__(self, bus) 3230 self.found = False 3231 self.found2 = False 3232 self.found_prop = False 3233 self.lost = False 3234 self.find_stopped = False 3235 3236 def __enter__(self): 3237 gobject.timeout_add(1, self.run_test) 3238 gobject.timeout_add(15000, self.timeout) 3239 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 3240 "DeviceFound") 3241 self.add_signal(self.deviceFoundProperties, 3242 WPAS_DBUS_IFACE_P2PDEVICE, "DeviceFoundProperties") 3243 self.add_signal(self.deviceLost, WPAS_DBUS_IFACE_P2PDEVICE, 3244 "DeviceLost") 3245 self.add_signal(self.provisionDiscoveryResponseEnterPin, 3246 WPAS_DBUS_IFACE_P2PDEVICE, 3247 "ProvisionDiscoveryResponseEnterPin") 3248 self.add_signal(self.findStopped, WPAS_DBUS_IFACE_P2PDEVICE, 3249 "FindStopped") 3250 self.loop.run() 3251 return self 3252 3253 def deviceFound(self, path): 3254 logger.debug("deviceFound: path=%s" % path) 3255 res = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Peers", 3256 dbus_interface=dbus.PROPERTIES_IFACE) 3257 if len(res) < 1: 3258 raise Exception("Unexpected number of peers") 3259 if path not in res: 3260 raise Exception("Mismatch in peer object path") 3261 peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path) 3262 res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER, 3263 dbus_interface=dbus.PROPERTIES_IFACE, 3264 byte_arrays=True) 3265 logger.debug("peer properties: " + str(res)) 3266 3267 if res['DeviceAddress'] == a1: 3268 if 'SecondaryDeviceTypes' not in res: 3269 raise Exception("Missing SecondaryDeviceTypes") 3270 sec = res['SecondaryDeviceTypes'] 3271 if len(sec) < 1: 3272 raise Exception("Secondary device type missing") 3273 if b"\x00\x01\x00\x50\xF2\x04\x00\x02" not in sec: 3274 raise Exception("Secondary device type mismatch") 3275 3276 if 'VendorExtension' not in res: 3277 raise Exception("Missing VendorExtension") 3278 vendor = res['VendorExtension'] 3279 if len(vendor) < 1: 3280 raise Exception("Vendor extension missing") 3281 if b"\x11\x22\x33\x44" not in vendor: 3282 raise Exception("Secondary device type mismatch") 3283 3284 if 'VSIE' not in res: 3285 raise Exception("Missing VSIE") 3286 vendor = res['VSIE'] 3287 if len(vendor) < 1: 3288 raise Exception("VSIE missing") 3289 if vendor != b"\xdd\x06\x00\x11\x22\x33\x55\x66": 3290 raise Exception("VSIE mismatch") 3291 3292 self.found = True 3293 elif res['DeviceAddress'] == a2: 3294 if 'IEs' not in res: 3295 raise Exception("IEs missing") 3296 if res['IEs'] != wfd: 3297 raise Exception("IEs mismatch") 3298 self.found2 = True 3299 else: 3300 raise Exception("Unexpected peer device address") 3301 3302 if self.found and self.found2: 3303 p2p.StopFind() 3304 p2p.RejectPeer(path) 3305 p2p.ProvisionDiscoveryRequest(path, 'display') 3306 3307 def deviceLost(self, path): 3308 logger.debug("deviceLost: path=%s" % path) 3309 if not self.found or not self.found2: 3310 # This may happen if a previous test case ended up scheduling 3311 # deviceLost event and that event did not get delivered before 3312 # starting the next test execution. 3313 logger.debug("Ignore deviceLost before the deviceFound events") 3314 return 3315 self.lost = True 3316 try: 3317 p2p.RejectPeer(path) 3318 raise Exception("Invalid RejectPeer accepted") 3319 except dbus.exceptions.DBusException as e: 3320 if "UnknownError: Failed to call wpas_p2p_reject" not in str(e): 3321 raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e)) 3322 self.loop.quit() 3323 3324 def deviceFoundProperties(self, path, properties): 3325 logger.debug("deviceFoundProperties: path=%s" % path) 3326 logger.debug("peer properties: " + str(properties)) 3327 if properties['DeviceAddress'] == a1: 3328 self.found_prop = True 3329 3330 def provisionDiscoveryResponseEnterPin(self, peer_object): 3331 logger.debug("provisionDiscoveryResponseEnterPin - peer=%s" % peer_object) 3332 p2p.Flush() 3333 3334 def findStopped(self): 3335 logger.debug("findStopped") 3336 self.find_stopped = True 3337 3338 def run_test(self, *args): 3339 logger.debug("run_test") 3340 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social', 3341 'Timeout': dbus.Int32(10)})) 3342 return False 3343 3344 def success(self): 3345 return self.found and self.lost and self.found2 and self.find_stopped 3346 3347 with TestDbusP2p(bus) as t: 3348 if not t.success(): 3349 raise Exception("Expected signals not seen") 3350 3351 dev[1].request("VENDOR_ELEM_REMOVE 1 *") 3352 dev[1].p2p_stop_find() 3353 3354 p2p.Listen(1) 3355 dev[2].p2p_stop_find() 3356 dev[2].request("P2P_FLUSH") 3357 if not dev[2].discover_peer(addr0): 3358 raise Exception("Peer not found") 3359 p2p.StopFind() 3360 dev[2].p2p_stop_find() 3361 3362 try: 3363 p2p.ExtendedListen(dbus.Dictionary({'foo': 100})) 3364 raise Exception("Invalid ExtendedListen accepted") 3365 except dbus.exceptions.DBusException as e: 3366 if "InvalidArgs" not in str(e): 3367 raise Exception("Unexpected error message for invalid ExtendedListen(): " + str(e)) 3368 3369 p2p.ExtendedListen(dbus.Dictionary({'period': 100, 'interval': 1000})) 3370 p2p.ExtendedListen(dbus.Dictionary({})) 3371 dev[0].global_request("P2P_EXT_LISTEN") 3372 3373def test_dbus_p2p_discovery_freq(dev, apdev): 3374 """D-Bus P2P discovery on a specific non-social channel""" 3375 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 3376 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 3377 3378 addr1 = dev[1].p2p_dev_addr() 3379 autogo(dev[1], freq=2422) 3380 3381 class TestDbusP2p(TestDbus): 3382 def __init__(self, bus): 3383 TestDbus.__init__(self, bus) 3384 self.found = False 3385 3386 def __enter__(self): 3387 gobject.timeout_add(1, self.run_test) 3388 gobject.timeout_add(5000, self.timeout) 3389 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 3390 "DeviceFound") 3391 self.loop.run() 3392 return self 3393 3394 def deviceFound(self, path): 3395 logger.debug("deviceFound: path=%s" % path) 3396 self.found = True 3397 self.loop.quit() 3398 3399 def run_test(self, *args): 3400 logger.debug("run_test") 3401 p2p.Find(dbus.Dictionary({'freq': 2422})) 3402 return False 3403 3404 def success(self): 3405 return self.found 3406 3407 with TestDbusP2p(bus) as t: 3408 if not t.success(): 3409 raise Exception("Expected signals not seen") 3410 3411 dev[1].remove_group() 3412 p2p.StopFind() 3413 3414def test_dbus_p2p_service_discovery(dev, apdev): 3415 """D-Bus P2P service discovery""" 3416 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 3417 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 3418 3419 addr0 = dev[0].p2p_dev_addr() 3420 addr1 = dev[1].p2p_dev_addr() 3421 3422 bonjour_query = dbus.ByteArray(binascii.unhexlify('0b5f6166706f766572746370c00c000c01')) 3423 bonjour_response = dbus.ByteArray(binascii.unhexlify('074578616d706c65c027')) 3424 3425 tests = [{'service_type': 'bonjour', 3426 'query': bonjour_query, 3427 'response': bonjour_response}, 3428 {'service_type': 'upnp', 3429 'version': 0x10, 3430 'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice', 3431 'query': bonjour_query, 3432 'response': bonjour_response}] 3433 for args in tests: 3434 p2p.AddService(args) 3435 p2p.FlushService() 3436 3437 args = {'service_type': 'bonjour', 3438 'query': bonjour_query, 3439 'response': bonjour_response} 3440 p2p.AddService(args) 3441 3442 try: 3443 p2p.DeleteService(args) 3444 raise Exception("Invalid DeleteService() accepted") 3445 except dbus.exceptions.DBusException as e: 3446 if "InvalidArgs" not in str(e): 3447 raise Exception("Unexpected error message for invalid DeleteService(): " + str(e)) 3448 3449 args = {'service_type': 'bonjour', 3450 'query': bonjour_query} 3451 p2p.DeleteService(args) 3452 try: 3453 p2p.DeleteService(args) 3454 raise Exception("Invalid DeleteService() accepted") 3455 except dbus.exceptions.DBusException as e: 3456 if "InvalidArgs" not in str(e): 3457 raise Exception("Unexpected error message for invalid DeleteService(): " + str(e)) 3458 3459 args = {'service_type': 'upnp', 3460 'version': 0x10, 3461 'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'} 3462 p2p.AddService(args) 3463 p2p.DeleteService(args) 3464 try: 3465 p2p.DeleteService(args) 3466 raise Exception("Invalid DeleteService() accepted") 3467 except dbus.exceptions.DBusException as e: 3468 if "InvalidArgs" not in str(e): 3469 raise Exception("Unexpected error message for invalid DeleteService(): " + str(e)) 3470 3471 tests = [{'service_type': 'foo'}, 3472 {'service_type': 'foo', 'query': bonjour_query}, 3473 {'service_type': 'upnp'}, 3474 {'service_type': 'upnp', 'version': 0x10}, 3475 {'service_type': 'upnp', 3476 'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'}, 3477 {'version': 0x10, 3478 'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'}, 3479 {'service_type': 'upnp', 'foo': 'bar'}, 3480 {'service_type': 'bonjour'}, 3481 {'service_type': 'bonjour', 'query': 'foo'}, 3482 {'service_type': 'bonjour', 'foo': 'bar'}] 3483 for args in tests: 3484 try: 3485 p2p.DeleteService(args) 3486 raise Exception("Invalid DeleteService() accepted") 3487 except dbus.exceptions.DBusException as e: 3488 if "InvalidArgs" not in str(e): 3489 raise Exception("Unexpected error message for invalid DeleteService(): " + str(e)) 3490 3491 tests = [{'service_type': 'foo'}, 3492 {'service_type': 'upnp'}, 3493 {'service_type': 'upnp', 'version': 0x10}, 3494 {'service_type': 'upnp', 3495 'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'}, 3496 {'version': 0x10, 3497 'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'}, 3498 {'service_type': 'upnp', 'foo': 'bar'}, 3499 {'service_type': 'bonjour'}, 3500 {'service_type': 'bonjour', 'query': 'foo'}, 3501 {'service_type': 'bonjour', 'response': 'foo'}, 3502 {'service_type': 'bonjour', 'query': bonjour_query}, 3503 {'service_type': 'bonjour', 'response': bonjour_response}, 3504 {'service_type': 'bonjour', 'query': dbus.ByteArray(500*b'a')}, 3505 {'service_type': 'bonjour', 'foo': 'bar'}] 3506 for args in tests: 3507 try: 3508 p2p.AddService(args) 3509 raise Exception("Invalid AddService() accepted") 3510 except dbus.exceptions.DBusException as e: 3511 if "InvalidArgs" not in str(e): 3512 raise Exception("Unexpected error message for invalid AddService(): " + str(e)) 3513 3514 args = {'tlv': dbus.ByteArray(b"\x02\x00\x00\x01")} 3515 ref = p2p.ServiceDiscoveryRequest(args) 3516 p2p.ServiceDiscoveryCancelRequest(ref) 3517 try: 3518 p2p.ServiceDiscoveryCancelRequest(ref) 3519 raise Exception("Invalid ServiceDiscoveryCancelRequest() accepted") 3520 except dbus.exceptions.DBusException as e: 3521 if "InvalidArgs" not in str(e): 3522 raise Exception("Unexpected error message for invalid AddService(): " + str(e)) 3523 try: 3524 p2p.ServiceDiscoveryCancelRequest(dbus.UInt64(0)) 3525 raise Exception("Invalid ServiceDiscoveryCancelRequest() accepted") 3526 except dbus.exceptions.DBusException as e: 3527 if "InvalidArgs" not in str(e): 3528 raise Exception("Unexpected error message for invalid AddService(): " + str(e)) 3529 3530 tests= [{'service_type': 'upnp', 3531 'version': 0x10, 3532 'service': 'ssdp:foo'}, 3533 {'service_type': 'upnp', 3534 'version': 0x10, 3535 'service': 'ssdp:bar', 3536 'tlv': dbus.ByteArray(b"\x02\x00\x00\x01")}] 3537 for args in tests: 3538 ref = p2p.ServiceDiscoveryRequest(args) 3539 p2p.ServiceDiscoveryCancelRequest(ref) 3540 3541 tests = [{'service_type': 'foo'}, 3542 {'foo': 'bar'}, 3543 {'tlv': 'foo'}, 3544 {}, 3545 {'version': 0}, 3546 {'service_type': 'upnp', 3547 'service': 'ssdp:foo'}, 3548 {'service_type': 'upnp', 3549 'version': 0x10}, 3550 {'service_type': 'upnp', 3551 'version': 0x10, 3552 'service': 'ssdp:foo', 3553 'peer_object': dbus.ObjectPath(path + "/Peers")}, 3554 {'service_type': 'upnp', 3555 'version': 0x10, 3556 'service': 'ssdp:foo', 3557 'peer_object': path + "/Peers"}, 3558 {'service_type': 'upnp', 3559 'version': 0x10, 3560 'service': 'ssdp:foo', 3561 'peer_object': dbus.ObjectPath(path + "/Peers/00112233445566")}] 3562 for args in tests: 3563 try: 3564 p2p.ServiceDiscoveryRequest(args) 3565 raise Exception("Invalid ServiceDiscoveryRequest accepted") 3566 except dbus.exceptions.DBusException as e: 3567 if "InvalidArgs" not in str(e): 3568 raise Exception("Unexpected error message for invalid ServiceDiscoveryRequest(): " + str(e)) 3569 3570 tests = [{'foo': 'bar'}, 3571 {'tlvs': dbus.ByteArray(b"\x02\x00\x00\x01"), 3572 'bar': 'foo'}] 3573 for args in tests: 3574 try: 3575 p2p.ServiceDiscoveryResponse(dbus.Dictionary(args, signature='sv')) 3576 raise Exception("Invalid ServiceDiscoveryResponse accepted") 3577 except dbus.exceptions.DBusException as e: 3578 if "InvalidArgs" not in str(e): 3579 raise Exception("Unexpected error message for invalid ServiceDiscoveryResponse(): " + str(e)) 3580 3581def test_dbus_p2p_service_discovery_query(dev, apdev): 3582 """D-Bus P2P service discovery query""" 3583 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 3584 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 3585 3586 addr0 = dev[0].p2p_dev_addr() 3587 dev[1].request("P2P_SERVICE_ADD bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027") 3588 dev[1].p2p_listen() 3589 addr1 = dev[1].p2p_dev_addr() 3590 3591 class TestDbusP2p(TestDbus): 3592 def __init__(self, bus): 3593 TestDbus.__init__(self, bus) 3594 self.done = False 3595 3596 def __enter__(self): 3597 gobject.timeout_add(1, self.run_test) 3598 gobject.timeout_add(15000, self.timeout) 3599 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 3600 "DeviceFound") 3601 self.add_signal(self.serviceDiscoveryResponse, 3602 WPAS_DBUS_IFACE_P2PDEVICE, 3603 "ServiceDiscoveryResponse", byte_arrays=True) 3604 self.loop.run() 3605 return self 3606 3607 def deviceFound(self, path): 3608 logger.debug("deviceFound: path=%s" % path) 3609 args = {'peer_object': path, 3610 'tlv': dbus.ByteArray(b"\x02\x00\x00\x01")} 3611 p2p.ServiceDiscoveryRequest(args) 3612 3613 def serviceDiscoveryResponse(self, sd_request): 3614 logger.debug("serviceDiscoveryResponse: sd_request=%s" % str(sd_request)) 3615 self.done = True 3616 self.loop.quit() 3617 3618 def run_test(self, *args): 3619 logger.debug("run_test") 3620 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social', 3621 'Timeout': dbus.Int32(10)})) 3622 return False 3623 3624 def success(self): 3625 return self.done 3626 3627 with TestDbusP2p(bus) as t: 3628 if not t.success(): 3629 raise Exception("Expected signals not seen") 3630 3631 dev[1].p2p_stop_find() 3632 3633def test_dbus_p2p_service_discovery_external(dev, apdev): 3634 """D-Bus P2P service discovery with external response""" 3635 try: 3636 _test_dbus_p2p_service_discovery_external(dev, apdev) 3637 finally: 3638 dev[0].request("P2P_SERV_DISC_EXTERNAL 0") 3639 3640def _test_dbus_p2p_service_discovery_external(dev, apdev): 3641 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 3642 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 3643 3644 addr0 = dev[0].p2p_dev_addr() 3645 addr1 = dev[1].p2p_dev_addr() 3646 resp = "0300000101" 3647 3648 dev[1].request("P2P_FLUSH") 3649 dev[1].request("P2P_SERV_DISC_REQ " + addr0 + " 02000001") 3650 dev[1].p2p_find(social=True) 3651 3652 class TestDbusP2p(TestDbus): 3653 def __init__(self, bus): 3654 TestDbus.__init__(self, bus) 3655 self.sd = False 3656 3657 def __enter__(self): 3658 gobject.timeout_add(1, self.run_test) 3659 gobject.timeout_add(15000, self.timeout) 3660 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 3661 "DeviceFound") 3662 self.add_signal(self.serviceDiscoveryRequest, 3663 WPAS_DBUS_IFACE_P2PDEVICE, 3664 "ServiceDiscoveryRequest") 3665 self.loop.run() 3666 return self 3667 3668 def deviceFound(self, path): 3669 logger.debug("deviceFound: path=%s" % path) 3670 3671 def serviceDiscoveryRequest(self, sd_request): 3672 logger.debug("serviceDiscoveryRequest: sd_request=%s" % str(sd_request)) 3673 self.sd = True 3674 args = {'peer_object': sd_request['peer_object'], 3675 'frequency': sd_request['frequency'], 3676 'dialog_token': sd_request['dialog_token'], 3677 'tlvs': dbus.ByteArray(binascii.unhexlify(resp))} 3678 p2p.ServiceDiscoveryResponse(dbus.Dictionary(args, signature='sv')) 3679 self.loop.quit() 3680 3681 def run_test(self, *args): 3682 logger.debug("run_test") 3683 p2p.ServiceDiscoveryExternal(1) 3684 p2p.ServiceUpdate() 3685 p2p.Listen(15) 3686 return False 3687 3688 def success(self): 3689 return self.sd 3690 3691 with TestDbusP2p(bus) as t: 3692 if not t.success(): 3693 raise Exception("Expected signals not seen") 3694 3695 ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=5) 3696 if ev is None: 3697 raise Exception("Service discovery timed out") 3698 if addr0 not in ev: 3699 raise Exception("Unexpected address in SD Response: " + ev) 3700 if ev.split(' ')[4] != resp: 3701 raise Exception("Unexpected response data SD Response: " + ev) 3702 dev[1].p2p_stop_find() 3703 3704 p2p.StopFind() 3705 p2p.ServiceDiscoveryExternal(0) 3706 3707def test_dbus_p2p_autogo(dev, apdev): 3708 """D-Bus P2P autonomous GO""" 3709 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 3710 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 3711 3712 addr0 = dev[0].p2p_dev_addr() 3713 3714 class TestDbusP2p(TestDbus): 3715 def __init__(self, bus): 3716 TestDbus.__init__(self, bus) 3717 self.first = True 3718 self.waiting_end = False 3719 self.exceptions = False 3720 self.deauthorized = False 3721 self.done = False 3722 3723 def __enter__(self): 3724 gobject.timeout_add(1, self.run_test) 3725 gobject.timeout_add(15000, self.timeout) 3726 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 3727 "DeviceFound") 3728 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 3729 "GroupStarted") 3730 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 3731 "GroupFinished") 3732 self.add_signal(self.persistentGroupAdded, 3733 WPAS_DBUS_IFACE_P2PDEVICE, 3734 "PersistentGroupAdded") 3735 self.add_signal(self.persistentGroupRemoved, 3736 WPAS_DBUS_IFACE_P2PDEVICE, 3737 "PersistentGroupRemoved") 3738 self.add_signal(self.provisionDiscoveryRequestDisplayPin, 3739 WPAS_DBUS_IFACE_P2PDEVICE, 3740 "ProvisionDiscoveryRequestDisplayPin") 3741 self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE, 3742 "StaAuthorized") 3743 self.add_signal(self.staDeauthorized, WPAS_DBUS_IFACE, 3744 "StaDeauthorized") 3745 self.loop.run() 3746 return self 3747 3748 def groupStarted(self, properties): 3749 logger.debug("groupStarted: " + str(properties)) 3750 self.group = properties['group_object'] 3751 self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 3752 properties['interface_object']) 3753 role = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Role", 3754 dbus_interface=dbus.PROPERTIES_IFACE) 3755 if role != "GO": 3756 self.exceptions = True 3757 raise Exception("Unexpected role reported: " + role) 3758 group = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Group", 3759 dbus_interface=dbus.PROPERTIES_IFACE) 3760 if group != properties['group_object']: 3761 self.exceptions = True 3762 raise Exception("Unexpected Group reported: " + str(group)) 3763 go = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PeerGO", 3764 dbus_interface=dbus.PROPERTIES_IFACE) 3765 if go != '/': 3766 self.exceptions = True 3767 raise Exception("Unexpected PeerGO value: " + str(go)) 3768 if self.first: 3769 self.first = False 3770 logger.info("Remove persistent group instance") 3771 group_p2p = dbus.Interface(self.g_if_obj, 3772 WPAS_DBUS_IFACE_P2PDEVICE) 3773 group_p2p.Disconnect() 3774 else: 3775 dev[1].global_request("P2P_CONNECT " + addr0 + " 12345670 join") 3776 3777 def groupFinished(self, properties): 3778 logger.debug("groupFinished: " + str(properties)) 3779 if self.waiting_end: 3780 logger.info("Remove persistent group") 3781 p2p.RemovePersistentGroup(self.persistent) 3782 else: 3783 logger.info("Re-start persistent group") 3784 params = dbus.Dictionary({'persistent_group_object': 3785 self.persistent, 3786 'frequency': 2412}) 3787 p2p.GroupAdd(params) 3788 3789 def persistentGroupAdded(self, path, properties): 3790 logger.debug("persistentGroupAdded: %s %s" % (path, str(properties))) 3791 self.persistent = path 3792 3793 def persistentGroupRemoved(self, path): 3794 logger.debug("persistentGroupRemoved: %s" % path) 3795 self.done = True 3796 self.loop.quit() 3797 3798 def deviceFound(self, path): 3799 logger.debug("deviceFound: path=%s" % path) 3800 peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path) 3801 self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER, 3802 dbus_interface=dbus.PROPERTIES_IFACE, 3803 byte_arrays=True) 3804 logger.debug('peer properties: ' + str(self.peer)) 3805 3806 def provisionDiscoveryRequestDisplayPin(self, peer_object, pin): 3807 logger.debug("provisionDiscoveryRequestDisplayPin - peer=%s pin=%s" % (peer_object, pin)) 3808 self.peer_path = peer_object 3809 peer = binascii.unhexlify(peer_object.split('/')[-1]) 3810 addr = ':'.join(["%02x" % i for i in struct.unpack('6B', peer)]) 3811 3812 params = {'Role': 'registrar', 3813 'P2PDeviceAddress': self.peer['DeviceAddress'], 3814 'Bssid': self.peer['DeviceAddress'], 3815 'Type': 'pin'} 3816 wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS) 3817 try: 3818 wps.Start(params) 3819 self.exceptions = True 3820 raise Exception("Invalid WPS.Start() accepted") 3821 except dbus.exceptions.DBusException as e: 3822 if "InvalidArgs" not in str(e): 3823 self.exceptions = True 3824 raise Exception("Unexpected error message: " + str(e)) 3825 params = {'Role': 'registrar', 3826 'P2PDeviceAddress': self.peer['DeviceAddress'], 3827 'Type': 'pin', 3828 'Pin': '12345670'} 3829 logger.info("Authorize peer to connect to the group") 3830 wps.Start(params) 3831 3832 def staAuthorized(self, name): 3833 logger.debug("staAuthorized: " + name) 3834 peer_obj = bus.get_object(WPAS_DBUS_SERVICE, self.peer_path) 3835 res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER, 3836 dbus_interface=dbus.PROPERTIES_IFACE, 3837 byte_arrays=True) 3838 logger.debug("Peer properties: " + str(res)) 3839 if 'Groups' not in res or len(res['Groups']) != 1: 3840 self.exceptions = True 3841 raise Exception("Unexpected number of peer Groups entries") 3842 if res['Groups'][0] != self.group: 3843 self.exceptions = True 3844 raise Exception("Unexpected peer Groups[0] value") 3845 3846 g_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group) 3847 res = g_obj.GetAll(WPAS_DBUS_GROUP, 3848 dbus_interface=dbus.PROPERTIES_IFACE, 3849 byte_arrays=True) 3850 logger.debug("Group properties: " + str(res)) 3851 if 'Members' not in res or len(res['Members']) != 1: 3852 self.exceptions = True 3853 raise Exception("Unexpected number of group members") 3854 3855 ext = dbus.ByteArray(b"\x11\x22\x33\x44") 3856 # Earlier implementation of this interface was a bit strange. The 3857 # property is defined to have aay signature and that is what the 3858 # getter returned. However, the setter expected there to be a 3859 # dictionary with 'WPSVendorExtensions' as the key surrounding these 3860 # values.. The current implementations maintains support for that 3861 # for backwards compability reasons. Verify that encoding first. 3862 vals = dbus.Dictionary({'WPSVendorExtensions': [ext]}, 3863 signature='sv') 3864 g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals, 3865 dbus_interface=dbus.PROPERTIES_IFACE) 3866 res = g_obj.Get(WPAS_DBUS_GROUP, 'WPSVendorExtensions', 3867 dbus_interface=dbus.PROPERTIES_IFACE, 3868 byte_arrays=True) 3869 if len(res) != 1: 3870 self.exceptions = True 3871 raise Exception("Unexpected number of vendor extensions") 3872 if res[0] != ext: 3873 self.exceptions = True 3874 raise Exception("Vendor extension value changed") 3875 3876 # And now verify that the more appropriate encoding is accepted as 3877 # well. 3878 res.append(dbus.ByteArray(b'\xaa\xbb\xcc\xdd\xee\xff')) 3879 g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res, 3880 dbus_interface=dbus.PROPERTIES_IFACE) 3881 res2 = g_obj.Get(WPAS_DBUS_GROUP, 'WPSVendorExtensions', 3882 dbus_interface=dbus.PROPERTIES_IFACE, 3883 byte_arrays=True) 3884 if len(res) != 2: 3885 self.exceptions = True 3886 raise Exception("Unexpected number of vendor extensions") 3887 if res[0] != res2[0] or res[1] != res2[1]: 3888 self.exceptions = True 3889 raise Exception("Vendor extension value changed") 3890 3891 for i in range(10): 3892 res.append(dbus.ByteArray(b'\xaa\xbb')) 3893 try: 3894 g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res, 3895 dbus_interface=dbus.PROPERTIES_IFACE) 3896 self.exceptions = True 3897 raise Exception("Invalid Set(WPSVendorExtensions) accepted") 3898 except dbus.exceptions.DBusException as e: 3899 if "Error.Failed" not in str(e): 3900 self.exceptions = True 3901 raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e)) 3902 3903 vals = dbus.Dictionary({'Foo': [ext]}, signature='sv') 3904 try: 3905 g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals, 3906 dbus_interface=dbus.PROPERTIES_IFACE) 3907 self.exceptions = True 3908 raise Exception("Invalid Set(WPSVendorExtensions) accepted") 3909 except dbus.exceptions.DBusException as e: 3910 if "InvalidArgs" not in str(e): 3911 self.exceptions = True 3912 raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e)) 3913 3914 vals = ["foo"] 3915 try: 3916 g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals, 3917 dbus_interface=dbus.PROPERTIES_IFACE) 3918 self.exceptions = True 3919 raise Exception("Invalid Set(WPSVendorExtensions) accepted") 3920 except dbus.exceptions.DBusException as e: 3921 if "Error.Failed" not in str(e): 3922 self.exceptions = True 3923 raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e)) 3924 3925 vals = [["foo"]] 3926 try: 3927 g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals, 3928 dbus_interface=dbus.PROPERTIES_IFACE) 3929 self.exceptions = True 3930 raise Exception("Invalid Set(WPSVendorExtensions) accepted") 3931 except dbus.exceptions.DBusException as e: 3932 if "Error.Failed" not in str(e): 3933 self.exceptions = True 3934 raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e)) 3935 3936 p2p.RemoveClient({'peer': self.peer_path}) 3937 3938 self.waiting_end = True 3939 3940 # wait for client to be fully connected 3941 dev[1].wait_connected() 3942 # so we can cleanly disconnect it now 3943 group_p2p = dbus.Interface(self.g_if_obj, 3944 WPAS_DBUS_IFACE_P2PDEVICE) 3945 group_p2p.Disconnect() 3946 3947 def staDeauthorized(self, name): 3948 logger.debug("staDeauthorized: " + name) 3949 self.deauthorized = True 3950 3951 def run_test(self, *args): 3952 logger.debug("run_test") 3953 params = dbus.Dictionary({'persistent': True, 3954 'frequency': 2412}) 3955 logger.info("Add a persistent group") 3956 p2p.GroupAdd(params) 3957 return False 3958 3959 def success(self): 3960 return self.done and self.deauthorized and not self.exceptions 3961 3962 with TestDbusP2p(bus) as t: 3963 if not t.success(): 3964 raise Exception("Expected signals not seen") 3965 3966 dev[1].wait_go_ending_session() 3967 3968def test_dbus_p2p_autogo_pbc(dev, apdev): 3969 """D-Bus P2P autonomous GO and PBC""" 3970 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 3971 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 3972 3973 addr0 = dev[0].p2p_dev_addr() 3974 3975 class TestDbusP2p(TestDbus): 3976 def __init__(self, bus): 3977 TestDbus.__init__(self, bus) 3978 self.first = True 3979 self.waiting_end = False 3980 self.done = False 3981 3982 def __enter__(self): 3983 gobject.timeout_add(1, self.run_test) 3984 gobject.timeout_add(15000, self.timeout) 3985 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 3986 "DeviceFound") 3987 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 3988 "GroupStarted") 3989 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 3990 "GroupFinished") 3991 self.add_signal(self.provisionDiscoveryPBCRequest, 3992 WPAS_DBUS_IFACE_P2PDEVICE, 3993 "ProvisionDiscoveryPBCRequest") 3994 self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE, 3995 "StaAuthorized") 3996 self.loop.run() 3997 return self 3998 3999 def groupStarted(self, properties): 4000 logger.debug("groupStarted: " + str(properties)) 4001 self.group = properties['group_object'] 4002 self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4003 properties['interface_object']) 4004 dev[1].global_request("P2P_CONNECT " + addr0 + " pbc join") 4005 4006 def groupFinished(self, properties): 4007 logger.debug("groupFinished: " + str(properties)) 4008 self.done = True 4009 self.loop.quit() 4010 4011 def deviceFound(self, path): 4012 logger.debug("deviceFound: path=%s" % path) 4013 peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path) 4014 self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER, 4015 dbus_interface=dbus.PROPERTIES_IFACE, 4016 byte_arrays=True) 4017 logger.debug('peer properties: ' + str(self.peer)) 4018 4019 def provisionDiscoveryPBCRequest(self, peer_object): 4020 logger.debug("provisionDiscoveryPBCRequest - peer=%s" % peer_object) 4021 self.peer_path = peer_object 4022 peer = binascii.unhexlify(peer_object.split('/')[-1]) 4023 addr = ':'.join(["%02x" % i for i in struct.unpack('6B', peer)]) 4024 params = {'Role': 'registrar', 4025 'P2PDeviceAddress': self.peer['DeviceAddress'], 4026 'Type': 'pbc'} 4027 logger.info("Authorize peer to connect to the group") 4028 wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS) 4029 wps.Start(params) 4030 4031 def staAuthorized(self, name): 4032 logger.debug("staAuthorized: " + name) 4033 # wait for client to be fully connected 4034 dev[1].wait_connected() 4035 # so we can cleanly disconnect it now 4036 group_p2p = dbus.Interface(self.g_if_obj, 4037 WPAS_DBUS_IFACE_P2PDEVICE) 4038 group_p2p.Disconnect() 4039 4040 def run_test(self, *args): 4041 logger.debug("run_test") 4042 params = dbus.Dictionary({'frequency': 2412}) 4043 p2p.GroupAdd(params) 4044 return False 4045 4046 def success(self): 4047 return self.done 4048 4049 with TestDbusP2p(bus) as t: 4050 if not t.success(): 4051 raise Exception("Expected signals not seen") 4052 4053 dev[1].wait_go_ending_session() 4054 dev[1].flush_scan_cache() 4055 4056def test_dbus_p2p_autogo_legacy(dev, apdev): 4057 """D-Bus P2P autonomous GO and legacy STA""" 4058 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4059 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4060 4061 addr0 = dev[0].p2p_dev_addr() 4062 4063 class TestDbusP2p(TestDbus): 4064 def __init__(self, bus): 4065 TestDbus.__init__(self, bus) 4066 self.done = False 4067 4068 def __enter__(self): 4069 gobject.timeout_add(1, self.run_test) 4070 gobject.timeout_add(15000, self.timeout) 4071 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 4072 "GroupStarted") 4073 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 4074 "GroupFinished") 4075 self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE, 4076 "StaAuthorized") 4077 self.loop.run() 4078 return self 4079 4080 def groupStarted(self, properties): 4081 logger.debug("groupStarted: " + str(properties)) 4082 g_obj = bus.get_object(WPAS_DBUS_SERVICE, 4083 properties['group_object']) 4084 res = g_obj.GetAll(WPAS_DBUS_GROUP, 4085 dbus_interface=dbus.PROPERTIES_IFACE, 4086 byte_arrays=True) 4087 bssid = ':'.join(["%02x" % i for i in struct.unpack('6B', res['BSSID'])]) 4088 4089 pin = '12345670' 4090 params = {'Role': 'enrollee', 4091 'Type': 'pin', 4092 'Pin': pin} 4093 g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4094 properties['interface_object']) 4095 wps = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_WPS) 4096 wps.Start(params) 4097 dev[1].scan_for_bss(bssid, freq=2412) 4098 dev[1].request("WPS_PIN " + bssid + " " + pin) 4099 self.group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4100 4101 def groupFinished(self, properties): 4102 logger.debug("groupFinished: " + str(properties)) 4103 self.done = True 4104 self.loop.quit() 4105 4106 def staAuthorized(self, name): 4107 logger.debug("staAuthorized: " + name) 4108 dev[1].request("DISCONNECT") 4109 self.group_p2p.Disconnect() 4110 4111 def run_test(self, *args): 4112 logger.debug("run_test") 4113 params = dbus.Dictionary({'frequency': 2412}) 4114 p2p.GroupAdd(params) 4115 return False 4116 4117 def success(self): 4118 return self.done 4119 4120 with TestDbusP2p(bus) as t: 4121 if not t.success(): 4122 raise Exception("Expected signals not seen") 4123 4124def test_dbus_p2p_join(dev, apdev): 4125 """D-Bus P2P join an autonomous GO""" 4126 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4127 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4128 4129 addr1 = dev[1].p2p_dev_addr() 4130 addr2 = dev[2].p2p_dev_addr() 4131 dev[1].p2p_start_go(freq=2412) 4132 dev[2].p2p_listen() 4133 4134 class TestDbusP2p(TestDbus): 4135 def __init__(self, bus): 4136 TestDbus.__init__(self, bus) 4137 self.done = False 4138 self.peer = None 4139 self.go = None 4140 4141 def __enter__(self): 4142 gobject.timeout_add(1, self.run_test) 4143 gobject.timeout_add(15000, self.timeout) 4144 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 4145 "DeviceFound") 4146 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 4147 "GroupStarted") 4148 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 4149 "GroupFinished") 4150 self.add_signal(self.invitationResult, WPAS_DBUS_IFACE_P2PDEVICE, 4151 "InvitationResult") 4152 self.loop.run() 4153 return self 4154 4155 def deviceFound(self, path): 4156 logger.debug("deviceFound: path=%s" % path) 4157 peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path) 4158 res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER, 4159 dbus_interface=dbus.PROPERTIES_IFACE, 4160 byte_arrays=True) 4161 logger.debug('peer properties: ' + str(res)) 4162 if addr2.replace(':', '') in path: 4163 self.peer = path 4164 elif addr1.replace(':', '') in path: 4165 self.go = path 4166 if self.peer and self.go: 4167 logger.info("Join the group") 4168 p2p.StopFind() 4169 args = {'peer': self.go, 4170 'join': True, 4171 'wps_method': 'pin', 4172 'frequency': 2412} 4173 pin = p2p.Connect(args) 4174 4175 dev[1].group_request("WPS_PIN any " + pin) 4176 4177 def groupStarted(self, properties): 4178 logger.debug("groupStarted: " + str(properties)) 4179 g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4180 properties['interface_object']) 4181 role = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Role", 4182 dbus_interface=dbus.PROPERTIES_IFACE) 4183 if role != "client": 4184 raise Exception("Unexpected role reported: " + role) 4185 group = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Group", 4186 dbus_interface=dbus.PROPERTIES_IFACE) 4187 if group != properties['group_object']: 4188 raise Exception("Unexpected Group reported: " + str(group)) 4189 go = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PeerGO", 4190 dbus_interface=dbus.PROPERTIES_IFACE) 4191 if go != self.go: 4192 raise Exception("Unexpected PeerGO value: " + str(go)) 4193 4194 g_obj = bus.get_object(WPAS_DBUS_SERVICE, 4195 properties['group_object']) 4196 res = g_obj.GetAll(WPAS_DBUS_GROUP, 4197 dbus_interface=dbus.PROPERTIES_IFACE, 4198 byte_arrays=True) 4199 logger.debug("Group properties: " + str(res)) 4200 4201 ext = dbus.ByteArray(b"\x11\x22\x33\x44") 4202 try: 4203 # Set(WPSVendorExtensions) not allowed for P2P Client 4204 g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res, 4205 dbus_interface=dbus.PROPERTIES_IFACE) 4206 raise Exception("Invalid Set(WPSVendorExtensions) accepted") 4207 except dbus.exceptions.DBusException as e: 4208 if "Error.Failed: Failed to set property" not in str(e): 4209 raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e)) 4210 4211 group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4212 args = {'duration1': 30000, 'interval1': 102400, 4213 'duration2': 20000, 'interval2': 102400} 4214 group_p2p.PresenceRequest(args) 4215 4216 args = {'peer': self.peer} 4217 group_p2p.Invite(args) 4218 4219 def groupFinished(self, properties): 4220 logger.debug("groupFinished: " + str(properties)) 4221 self.done = True 4222 self.loop.quit() 4223 4224 def invitationResult(self, result): 4225 logger.debug("invitationResult: " + str(result)) 4226 if result['status'] != 1: 4227 raise Exception("Unexpected invitation result: " + str(result)) 4228 dev[1].remove_group() 4229 4230 def run_test(self, *args): 4231 logger.debug("run_test") 4232 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'})) 4233 return False 4234 4235 def success(self): 4236 return self.done 4237 4238 with TestDbusP2p(bus) as t: 4239 if not t.success(): 4240 raise Exception("Expected signals not seen") 4241 4242 dev[2].p2p_stop_find() 4243 4244def test_dbus_p2p_invitation_received(dev, apdev): 4245 """D-Bus P2P and InvitationReceived""" 4246 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4247 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4248 4249 form(dev[0], dev[1]) 4250 addr0 = dev[0].p2p_dev_addr() 4251 dev[0].p2p_listen() 4252 dev[0].global_request("SET persistent_reconnect 0") 4253 4254 if not dev[1].discover_peer(addr0, social=True): 4255 raise Exception("Peer " + addr0 + " not found") 4256 peer = dev[1].get_peer(addr0) 4257 4258 class TestDbusP2p(TestDbus): 4259 def __init__(self, bus): 4260 TestDbus.__init__(self, bus) 4261 self.done = False 4262 4263 def __enter__(self): 4264 gobject.timeout_add(1, self.run_test) 4265 gobject.timeout_add(15000, self.timeout) 4266 self.add_signal(self.invitationReceived, WPAS_DBUS_IFACE_P2PDEVICE, 4267 "InvitationReceived") 4268 self.loop.run() 4269 return self 4270 4271 def invitationReceived(self, result): 4272 logger.debug("invitationReceived: " + str(result)) 4273 self.done = True 4274 self.loop.quit() 4275 4276 def run_test(self, *args): 4277 logger.debug("run_test") 4278 cmd = "P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr0 4279 dev[1].global_request(cmd) 4280 return False 4281 4282 def success(self): 4283 return self.done 4284 4285 with TestDbusP2p(bus) as t: 4286 if not t.success(): 4287 raise Exception("Expected signals not seen") 4288 4289 dev[0].p2p_stop_find() 4290 dev[1].p2p_stop_find() 4291 4292def test_dbus_p2p_config(dev, apdev): 4293 """D-Bus Get/Set P2PDeviceConfig""" 4294 try: 4295 _test_dbus_p2p_config(dev, apdev) 4296 finally: 4297 dev[0].request("P2P_SET ssid_postfix ") 4298 4299def _test_dbus_p2p_config(dev, apdev): 4300 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4301 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4302 4303 res = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4304 dbus_interface=dbus.PROPERTIES_IFACE, 4305 byte_arrays=True) 4306 if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", res, 4307 dbus_interface=dbus.PROPERTIES_IFACE) 4308 res2 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4309 dbus_interface=dbus.PROPERTIES_IFACE, 4310 byte_arrays=True) 4311 4312 if len(res) != len(res2): 4313 raise Exception("Different number of parameters") 4314 for k in res: 4315 if res[k] != res2[k]: 4316 raise Exception("Parameter %s value changes" % k) 4317 4318 changes = {'SsidPostfix': 'foo', 4319 'VendorExtension': [dbus.ByteArray(b'\x11\x22\x33\x44')], 4320 'SecondaryDeviceTypes': [dbus.ByteArray(b'\x11\x22\x33\x44\x55\x66\x77\x88')]} 4321 if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4322 dbus.Dictionary(changes, signature='sv'), 4323 dbus_interface=dbus.PROPERTIES_IFACE) 4324 4325 res2 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4326 dbus_interface=dbus.PROPERTIES_IFACE, 4327 byte_arrays=True) 4328 logger.debug("P2PDeviceConfig: " + str(res2)) 4329 if 'VendorExtension' not in res2 or len(res2['VendorExtension']) != 1: 4330 raise Exception("VendorExtension does not match") 4331 if 'SecondaryDeviceTypes' not in res2 or len(res2['SecondaryDeviceTypes']) != 1: 4332 raise Exception("SecondaryDeviceType does not match") 4333 4334 changes = {'SsidPostfix': '', 4335 'VendorExtension': dbus.Array([], signature="ay"), 4336 'SecondaryDeviceTypes': dbus.Array([], signature="ay")} 4337 if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4338 dbus.Dictionary(changes, signature='sv'), 4339 dbus_interface=dbus.PROPERTIES_IFACE) 4340 4341 res3 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4342 dbus_interface=dbus.PROPERTIES_IFACE, 4343 byte_arrays=True) 4344 logger.debug("P2PDeviceConfig: " + str(res3)) 4345 if 'VendorExtension' in res3: 4346 raise Exception("VendorExtension not removed") 4347 if 'SecondaryDeviceTypes' in res3: 4348 raise Exception("SecondaryDeviceType not removed") 4349 4350 try: 4351 dev[0].request("P2P_SET disabled 1") 4352 if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4353 dbus_interface=dbus.PROPERTIES_IFACE, 4354 byte_arrays=True) 4355 raise Exception("Invalid Get(P2PDeviceConfig) accepted") 4356 except dbus.exceptions.DBusException as e: 4357 if "Error.Failed: P2P is not available for this interface" not in str(e): 4358 raise Exception("Unexpected error message for invalid Invite: " + str(e)) 4359 finally: 4360 dev[0].request("P2P_SET disabled 0") 4361 4362 try: 4363 dev[0].request("P2P_SET disabled 1") 4364 changes = {'SsidPostfix': 'foo'} 4365 if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4366 dbus.Dictionary(changes, signature='sv'), 4367 dbus_interface=dbus.PROPERTIES_IFACE) 4368 raise Exception("Invalid Set(P2PDeviceConfig) accepted") 4369 except dbus.exceptions.DBusException as e: 4370 if "Error.Failed: P2P is not available for this interface" not in str(e): 4371 raise Exception("Unexpected error message for invalid Invite: " + str(e)) 4372 finally: 4373 dev[0].request("P2P_SET disabled 0") 4374 4375 tests = [{'DeviceName': 123}, 4376 {'SsidPostfix': 123}, 4377 {'Foo': 'Bar'}] 4378 for changes in tests: 4379 try: 4380 if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", 4381 dbus.Dictionary(changes, signature='sv'), 4382 dbus_interface=dbus.PROPERTIES_IFACE) 4383 raise Exception("Invalid Set(P2PDeviceConfig) accepted") 4384 except dbus.exceptions.DBusException as e: 4385 if "InvalidArgs" not in str(e): 4386 raise Exception("Unexpected error message for invalid Invite: " + str(e)) 4387 4388def test_dbus_p2p_persistent(dev, apdev): 4389 """D-Bus P2P persistent group""" 4390 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4391 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4392 4393 class TestDbusP2p(TestDbus): 4394 def __init__(self, bus): 4395 TestDbus.__init__(self, bus) 4396 4397 def __enter__(self): 4398 gobject.timeout_add(1, self.run_test) 4399 gobject.timeout_add(15000, self.timeout) 4400 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 4401 "GroupStarted") 4402 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 4403 "GroupFinished") 4404 self.add_signal(self.persistentGroupAdded, 4405 WPAS_DBUS_IFACE_P2PDEVICE, 4406 "PersistentGroupAdded") 4407 self.loop.run() 4408 return self 4409 4410 def groupStarted(self, properties): 4411 logger.debug("groupStarted: " + str(properties)) 4412 g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4413 properties['interface_object']) 4414 group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4415 group_p2p.Disconnect() 4416 4417 def groupFinished(self, properties): 4418 logger.debug("groupFinished: " + str(properties)) 4419 self.loop.quit() 4420 4421 def persistentGroupAdded(self, path, properties): 4422 logger.debug("persistentGroupAdded: %s %s" % (path, str(properties))) 4423 self.persistent = path 4424 4425 def run_test(self, *args): 4426 logger.debug("run_test") 4427 params = dbus.Dictionary({'persistent': True, 4428 'frequency': 2412}) 4429 logger.info("Add a persistent group") 4430 p2p.GroupAdd(params) 4431 return False 4432 4433 def success(self): 4434 return True 4435 4436 with TestDbusP2p(bus) as t: 4437 if not t.success(): 4438 raise Exception("Expected signals not seen") 4439 persistent = t.persistent 4440 4441 p_obj = bus.get_object(WPAS_DBUS_SERVICE, persistent) 4442 res = p_obj.Get(WPAS_DBUS_PERSISTENT_GROUP, "Properties", 4443 dbus_interface=dbus.PROPERTIES_IFACE, byte_arrays=True) 4444 logger.info("Persistent group Properties: " + str(res)) 4445 vals = dbus.Dictionary({'ssid': 'DIRECT-foo'}, signature='sv') 4446 p_obj.Set(WPAS_DBUS_PERSISTENT_GROUP, "Properties", vals, 4447 dbus_interface=dbus.PROPERTIES_IFACE) 4448 res2 = p_obj.Get(WPAS_DBUS_PERSISTENT_GROUP, "Properties", 4449 dbus_interface=dbus.PROPERTIES_IFACE) 4450 if len(res) != len(res2): 4451 raise Exception("Different number of parameters") 4452 for k in res: 4453 if k != 'ssid' and res[k] != res2[k]: 4454 raise Exception("Parameter %s value changes" % k) 4455 if res2['ssid'] != '"DIRECT-foo"': 4456 raise Exception("Unexpected ssid") 4457 4458 args = dbus.Dictionary({'ssid': 'DIRECT-testing', 4459 'psk': '1234567890'}, signature='sv') 4460 group = p2p.AddPersistentGroup(args) 4461 4462 groups = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PersistentGroups", 4463 dbus_interface=dbus.PROPERTIES_IFACE) 4464 if len(groups) != 2: 4465 raise Exception("Unexpected number of persistent groups: " + str(groups)) 4466 4467 p2p.RemoveAllPersistentGroups() 4468 4469 groups = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PersistentGroups", 4470 dbus_interface=dbus.PROPERTIES_IFACE) 4471 if len(groups) != 0: 4472 raise Exception("Unexpected number of persistent groups: " + str(groups)) 4473 4474 try: 4475 p2p.RemovePersistentGroup(persistent) 4476 raise Exception("Invalid RemovePersistentGroup accepted") 4477 except dbus.exceptions.DBusException as e: 4478 if "NetworkUnknown: There is no such persistent group" not in str(e): 4479 raise Exception("Unexpected error message for invalid RemovePersistentGroup: " + str(e)) 4480 4481def test_dbus_p2p_reinvoke_persistent(dev, apdev): 4482 """D-Bus P2P reinvoke persistent group""" 4483 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4484 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4485 4486 addr0 = dev[0].p2p_dev_addr() 4487 4488 class TestDbusP2p(TestDbus): 4489 def __init__(self, bus): 4490 TestDbus.__init__(self, bus) 4491 self.first = True 4492 self.waiting_end = False 4493 self.done = False 4494 self.invited = False 4495 4496 def __enter__(self): 4497 gobject.timeout_add(1, self.run_test) 4498 gobject.timeout_add(15000, self.timeout) 4499 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 4500 "DeviceFound") 4501 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 4502 "GroupStarted") 4503 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 4504 "GroupFinished") 4505 self.add_signal(self.persistentGroupAdded, 4506 WPAS_DBUS_IFACE_P2PDEVICE, 4507 "PersistentGroupAdded") 4508 self.add_signal(self.provisionDiscoveryRequestDisplayPin, 4509 WPAS_DBUS_IFACE_P2PDEVICE, 4510 "ProvisionDiscoveryRequestDisplayPin") 4511 self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE, 4512 "StaAuthorized") 4513 self.loop.run() 4514 return self 4515 4516 def groupStarted(self, properties): 4517 logger.debug("groupStarted: " + str(properties)) 4518 self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4519 properties['interface_object']) 4520 if not self.invited: 4521 g_obj = bus.get_object(WPAS_DBUS_SERVICE, 4522 properties['group_object']) 4523 res = g_obj.GetAll(WPAS_DBUS_GROUP, 4524 dbus_interface=dbus.PROPERTIES_IFACE, 4525 byte_arrays=True) 4526 bssid = ':'.join(["%02x" % i for i in struct.unpack('6B', res['BSSID'])]) 4527 dev[1].scan_for_bss(bssid, freq=2412) 4528 dev[1].global_request("P2P_CONNECT " + addr0 + " 12345670 join") 4529 4530 def groupFinished(self, properties): 4531 logger.debug("groupFinished: " + str(properties)) 4532 if self.invited: 4533 self.done = True 4534 self.loop.quit() 4535 else: 4536 dev[1].global_request("SET persistent_reconnect 1") 4537 dev[1].p2p_listen() 4538 4539 args = {'persistent_group_object': dbus.ObjectPath(path), 4540 'peer': self.peer_path} 4541 try: 4542 pin = p2p.Invite(args) 4543 raise Exception("Invalid Invite accepted") 4544 except dbus.exceptions.DBusException as e: 4545 if "InvalidArgs" not in str(e): 4546 raise Exception("Unexpected error message for invalid Invite: " + str(e)) 4547 4548 args = {'persistent_group_object': self.persistent, 4549 'peer': self.peer_path} 4550 pin = p2p.Invite(args) 4551 self.invited = True 4552 4553 self.sta_group_ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], 4554 timeout=15) 4555 if self.sta_group_ev is None: 4556 raise Exception("P2P-GROUP-STARTED event not seen") 4557 4558 def persistentGroupAdded(self, path, properties): 4559 logger.debug("persistentGroupAdded: %s %s" % (path, str(properties))) 4560 self.persistent = path 4561 4562 def deviceFound(self, path): 4563 logger.debug("deviceFound: path=%s" % path) 4564 peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path) 4565 self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER, 4566 dbus_interface=dbus.PROPERTIES_IFACE, 4567 byte_arrays=True) 4568 4569 def provisionDiscoveryRequestDisplayPin(self, peer_object, pin): 4570 logger.debug("provisionDiscoveryRequestDisplayPin - peer=%s pin=%s" % (peer_object, pin)) 4571 self.peer_path = peer_object 4572 peer = binascii.unhexlify(peer_object.split('/')[-1]) 4573 addr = ':'.join(["%02x" % i for i in struct.unpack('6B', peer)]) 4574 params = {'Role': 'registrar', 4575 'P2PDeviceAddress': self.peer['DeviceAddress'], 4576 'Bssid': self.peer['DeviceAddress'], 4577 'Type': 'pin', 4578 'Pin': '12345670'} 4579 logger.info("Authorize peer to connect to the group") 4580 wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS) 4581 wps.Start(params) 4582 self.sta_group_ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], 4583 timeout=15) 4584 if self.sta_group_ev is None: 4585 raise Exception("P2P-GROUP-STARTED event not seen") 4586 4587 def staAuthorized(self, name): 4588 logger.debug("staAuthorized: " + name) 4589 dev[1].group_form_result(self.sta_group_ev) 4590 dev[1].remove_group() 4591 ev = dev[1].wait_global_event(["P2P-GROUP-REMOVED"], timeout=10) 4592 if ev is None: 4593 raise Exception("Group removal timed out") 4594 group_p2p = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4595 group_p2p.Disconnect() 4596 4597 def run_test(self, *args): 4598 logger.debug("run_test") 4599 params = dbus.Dictionary({'persistent': True, 4600 'frequency': 2412}) 4601 logger.info("Add a persistent group") 4602 p2p.GroupAdd(params) 4603 return False 4604 4605 def success(self): 4606 return self.done 4607 4608 with TestDbusP2p(bus) as t: 4609 if not t.success(): 4610 raise Exception("Expected signals not seen") 4611 4612def test_dbus_p2p_go_neg_rx(dev, apdev): 4613 """D-Bus P2P GO Negotiation receive""" 4614 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4615 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4616 addr0 = dev[0].p2p_dev_addr() 4617 4618 class TestDbusP2p(TestDbus): 4619 def __init__(self, bus): 4620 TestDbus.__init__(self, bus) 4621 self.done = False 4622 4623 def __enter__(self): 4624 gobject.timeout_add(1, self.run_test) 4625 gobject.timeout_add(15000, self.timeout) 4626 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 4627 "DeviceFound") 4628 self.add_signal(self.goNegotiationRequest, 4629 WPAS_DBUS_IFACE_P2PDEVICE, 4630 "GONegotiationRequest", 4631 byte_arrays=True) 4632 self.add_signal(self.goNegotiationSuccess, 4633 WPAS_DBUS_IFACE_P2PDEVICE, 4634 "GONegotiationSuccess", 4635 byte_arrays=True) 4636 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 4637 "GroupStarted") 4638 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 4639 "GroupFinished") 4640 self.loop.run() 4641 return self 4642 4643 def deviceFound(self, path): 4644 logger.debug("deviceFound: path=%s" % path) 4645 4646 def goNegotiationRequest(self, path, dev_passwd_id, go_intent=0): 4647 logger.debug("goNegotiationRequest: path=%s dev_passwd_id=%d go_intent=%d" % (path, dev_passwd_id, go_intent)) 4648 if dev_passwd_id != 1: 4649 raise Exception("Unexpected dev_passwd_id=%d" % dev_passwd_id) 4650 args = {'peer': path, 'wps_method': 'display', 'pin': '12345670', 4651 'go_intent': 15, 'persistent': False, 'frequency': 5175} 4652 try: 4653 p2p.Connect(args) 4654 raise Exception("Invalid Connect accepted") 4655 except dbus.exceptions.DBusException as e: 4656 if "ConnectChannelUnsupported" not in str(e): 4657 raise Exception("Unexpected error message for invalid Connect: " + str(e)) 4658 4659 args = {'peer': path, 'wps_method': 'display', 'pin': '12345670', 4660 'go_intent': 15, 'persistent': False} 4661 p2p.Connect(args) 4662 4663 def goNegotiationSuccess(self, properties): 4664 logger.debug("goNegotiationSuccess: properties=%s" % str(properties)) 4665 4666 def groupStarted(self, properties): 4667 logger.debug("groupStarted: " + str(properties)) 4668 g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4669 properties['interface_object']) 4670 group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4671 group_p2p.Disconnect() 4672 4673 def groupFinished(self, properties): 4674 logger.debug("groupFinished: " + str(properties)) 4675 self.done = True 4676 self.loop.quit() 4677 4678 def run_test(self, *args): 4679 logger.debug("run_test") 4680 p2p.Listen(10) 4681 if not dev[1].discover_peer(addr0): 4682 raise Exception("Peer not found") 4683 dev[1].global_request("P2P_CONNECT " + addr0 + " 12345670 enter") 4684 return False 4685 4686 def success(self): 4687 return self.done 4688 4689 with TestDbusP2p(bus) as t: 4690 if not t.success(): 4691 raise Exception("Expected signals not seen") 4692 4693def test_dbus_p2p_go_neg_auth(dev, apdev): 4694 """D-Bus P2P GO Negotiation authorized""" 4695 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4696 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4697 addr0 = dev[0].p2p_dev_addr() 4698 dev[1].p2p_listen() 4699 4700 class TestDbusP2p(TestDbus): 4701 def __init__(self, bus): 4702 TestDbus.__init__(self, bus) 4703 self.done = False 4704 self.peer_joined = False 4705 self.peer_disconnected = False 4706 4707 def __enter__(self): 4708 gobject.timeout_add(1, self.run_test) 4709 gobject.timeout_add(15000, self.timeout) 4710 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 4711 "DeviceFound") 4712 self.add_signal(self.goNegotiationSuccess, 4713 WPAS_DBUS_IFACE_P2PDEVICE, 4714 "GONegotiationSuccess", 4715 byte_arrays=True) 4716 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 4717 "GroupStarted") 4718 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 4719 "GroupFinished") 4720 self.add_signal(self.staDeauthorized, WPAS_DBUS_IFACE, 4721 "StaDeauthorized") 4722 self.add_signal(self.peerJoined, WPAS_DBUS_GROUP, 4723 "PeerJoined") 4724 self.add_signal(self.peerDisconnected, WPAS_DBUS_GROUP, 4725 "PeerDisconnected") 4726 self.loop.run() 4727 return self 4728 4729 def deviceFound(self, path): 4730 logger.debug("deviceFound: path=%s" % path) 4731 args = {'peer': path, 'wps_method': 'keypad', 4732 'go_intent': 15, 'authorize_only': True} 4733 try: 4734 p2p.Connect(args) 4735 raise Exception("Invalid Connect accepted") 4736 except dbus.exceptions.DBusException as e: 4737 if "InvalidArgs" not in str(e): 4738 raise Exception("Unexpected error message for invalid Connect: " + str(e)) 4739 4740 args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670', 4741 'go_intent': 15, 'authorize_only': True} 4742 p2p.Connect(args) 4743 p2p.Listen(10) 4744 if not dev[1].discover_peer(addr0): 4745 raise Exception("Peer not found") 4746 dev[1].global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=0") 4747 ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=15) 4748 if ev is None: 4749 raise Exception("Group formation timed out") 4750 self.sta_group_ev = ev 4751 4752 def goNegotiationSuccess(self, properties): 4753 logger.debug("goNegotiationSuccess: properties=%s" % str(properties)) 4754 4755 def groupStarted(self, properties): 4756 logger.debug("groupStarted: " + str(properties)) 4757 self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4758 properties['interface_object']) 4759 dev[1].group_form_result(self.sta_group_ev) 4760 dev[1].remove_group() 4761 4762 def staDeauthorized(self, name): 4763 logger.debug("staDeuthorized: " + name) 4764 group_p2p = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4765 group_p2p.Disconnect() 4766 4767 def peerJoined(self, peer): 4768 logger.debug("peerJoined: " + peer) 4769 self.peer_joined = True 4770 4771 def peerDisconnected(self, peer): 4772 logger.debug("peerDisconnected: " + peer) 4773 self.peer_disconnected = True 4774 4775 def groupFinished(self, properties): 4776 logger.debug("groupFinished: " + str(properties)) 4777 self.done = True 4778 self.loop.quit() 4779 4780 def run_test(self, *args): 4781 logger.debug("run_test") 4782 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'})) 4783 return False 4784 4785 def success(self): 4786 return self.done and self.peer_joined and self.peer_disconnected 4787 4788 with TestDbusP2p(bus) as t: 4789 if not t.success(): 4790 raise Exception("Expected signals not seen") 4791 4792def test_dbus_p2p_go_neg_init(dev, apdev): 4793 """D-Bus P2P GO Negotiation initiation""" 4794 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4795 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4796 addr0 = dev[0].p2p_dev_addr() 4797 dev[1].p2p_listen() 4798 4799 class TestDbusP2p(TestDbus): 4800 def __init__(self, bus): 4801 TestDbus.__init__(self, bus) 4802 self.done = False 4803 self.peer_group_added = False 4804 self.peer_group_removed = False 4805 4806 def __enter__(self): 4807 gobject.timeout_add(1, self.run_test) 4808 gobject.timeout_add(15000, self.timeout) 4809 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 4810 "DeviceFound") 4811 self.add_signal(self.goNegotiationSuccess, 4812 WPAS_DBUS_IFACE_P2PDEVICE, 4813 "GONegotiationSuccess", 4814 byte_arrays=True) 4815 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 4816 "GroupStarted") 4817 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 4818 "GroupFinished") 4819 self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE, 4820 "PropertiesChanged") 4821 self.loop.run() 4822 return self 4823 4824 def deviceFound(self, path): 4825 logger.debug("deviceFound: path=%s" % path) 4826 args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670', 4827 'go_intent': 0} 4828 p2p.Connect(args) 4829 4830 ev = dev[1].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15) 4831 if ev is None: 4832 raise Exception("Timeout while waiting for GO Neg Request") 4833 dev[1].global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15") 4834 ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=15) 4835 if ev is None: 4836 raise Exception("Group formation timed out") 4837 self.sta_group_ev = ev 4838 4839 def goNegotiationSuccess(self, properties): 4840 logger.debug("goNegotiationSuccess: properties=%s" % str(properties)) 4841 4842 def groupStarted(self, properties): 4843 logger.debug("groupStarted: " + str(properties)) 4844 g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4845 properties['interface_object']) 4846 group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4847 group_p2p.Disconnect() 4848 dev[1].group_form_result(self.sta_group_ev) 4849 dev[1].remove_group() 4850 4851 def groupFinished(self, properties): 4852 logger.debug("groupFinished: " + str(properties)) 4853 self.done = True 4854 4855 def propertiesChanged(self, interface_name, changed_properties, 4856 invalidated_properties): 4857 logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties))) 4858 if interface_name != WPAS_DBUS_P2P_PEER: 4859 return 4860 if "Groups" not in changed_properties: 4861 return 4862 if len(changed_properties["Groups"]) > 0: 4863 self.peer_group_added = True 4864 if len(changed_properties["Groups"]) == 0: 4865 if not self.peer_group_added: 4866 # This is likely a leftover event from an earlier test case, 4867 # ignore it to allow this test case to go through its steps. 4868 logger.info("Ignore propertiesChanged indicating group removal before group has been added") 4869 return 4870 self.peer_group_removed = True 4871 self.loop.quit() 4872 4873 def run_test(self, *args): 4874 logger.debug("run_test") 4875 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'})) 4876 return False 4877 4878 def success(self): 4879 return self.done and self.peer_group_added and self.peer_group_removed 4880 4881 with TestDbusP2p(bus) as t: 4882 if not t.success(): 4883 raise Exception("Expected signals not seen") 4884 4885def test_dbus_p2p_group_termination_by_go(dev, apdev): 4886 """D-Bus P2P group removal on GO terminating the group""" 4887 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4888 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4889 addr0 = dev[0].p2p_dev_addr() 4890 dev[1].p2p_listen() 4891 4892 class TestDbusP2p(TestDbus): 4893 def __init__(self, bus): 4894 TestDbus.__init__(self, bus) 4895 self.done = False 4896 self.peer_group_added = False 4897 self.peer_group_removed = False 4898 4899 def __enter__(self): 4900 gobject.timeout_add(1, self.run_test) 4901 gobject.timeout_add(15000, self.timeout) 4902 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 4903 "DeviceFound") 4904 self.add_signal(self.goNegotiationSuccess, 4905 WPAS_DBUS_IFACE_P2PDEVICE, 4906 "GONegotiationSuccess", 4907 byte_arrays=True) 4908 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 4909 "GroupStarted") 4910 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 4911 "GroupFinished") 4912 self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE, 4913 "PropertiesChanged") 4914 self.loop.run() 4915 return self 4916 4917 def deviceFound(self, path): 4918 logger.debug("deviceFound: path=%s" % path) 4919 args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670', 4920 'go_intent': 0} 4921 p2p.Connect(args) 4922 4923 ev = dev[1].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15) 4924 if ev is None: 4925 raise Exception("Timeout while waiting for GO Neg Request") 4926 dev[1].global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15") 4927 ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=15) 4928 if ev is None: 4929 raise Exception("Group formation timed out") 4930 self.sta_group_ev = ev 4931 4932 def goNegotiationSuccess(self, properties): 4933 logger.debug("goNegotiationSuccess: properties=%s" % str(properties)) 4934 4935 def groupStarted(self, properties): 4936 logger.debug("groupStarted: " + str(properties)) 4937 g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 4938 properties['interface_object']) 4939 dev[1].group_form_result(self.sta_group_ev) 4940 dev[1].remove_group() 4941 4942 def groupFinished(self, properties): 4943 logger.debug("groupFinished: " + str(properties)) 4944 self.done = True 4945 4946 def propertiesChanged(self, interface_name, changed_properties, 4947 invalidated_properties): 4948 logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties))) 4949 if interface_name != WPAS_DBUS_P2P_PEER: 4950 return 4951 if "Groups" not in changed_properties: 4952 return 4953 if len(changed_properties["Groups"]) > 0: 4954 self.peer_group_added = True 4955 if len(changed_properties["Groups"]) == 0 and self.peer_group_added: 4956 self.peer_group_removed = True 4957 self.loop.quit() 4958 4959 def run_test(self, *args): 4960 logger.debug("run_test") 4961 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'})) 4962 return False 4963 4964 def success(self): 4965 return self.done and self.peer_group_added and self.peer_group_removed 4966 4967 with TestDbusP2p(bus) as t: 4968 if not t.success(): 4969 raise Exception("Expected signals not seen") 4970 4971def test_dbus_p2p_group_idle_timeout(dev, apdev): 4972 """D-Bus P2P group removal on idle timeout""" 4973 try: 4974 dev[0].global_request("SET p2p_group_idle 1") 4975 _test_dbus_p2p_group_idle_timeout(dev, apdev) 4976 finally: 4977 dev[0].global_request("SET p2p_group_idle 0") 4978 4979def _test_dbus_p2p_group_idle_timeout(dev, apdev): 4980 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 4981 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 4982 addr0 = dev[0].p2p_dev_addr() 4983 dev[1].p2p_listen() 4984 4985 class TestDbusP2p(TestDbus): 4986 def __init__(self, bus): 4987 TestDbus.__init__(self, bus) 4988 self.done = False 4989 self.group_started = False 4990 self.peer_group_added = False 4991 self.peer_group_removed = False 4992 4993 def __enter__(self): 4994 gobject.timeout_add(1, self.run_test) 4995 gobject.timeout_add(15000, self.timeout) 4996 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 4997 "DeviceFound") 4998 self.add_signal(self.goNegotiationSuccess, 4999 WPAS_DBUS_IFACE_P2PDEVICE, 5000 "GONegotiationSuccess", 5001 byte_arrays=True) 5002 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 5003 "GroupStarted") 5004 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 5005 "GroupFinished") 5006 self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE, 5007 "PropertiesChanged") 5008 self.loop.run() 5009 return self 5010 5011 def deviceFound(self, path): 5012 logger.debug("deviceFound: path=%s" % path) 5013 args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670', 5014 'go_intent': 0} 5015 p2p.Connect(args) 5016 5017 ev = dev[1].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15) 5018 if ev is None: 5019 raise Exception("Timeout while waiting for GO Neg Request") 5020 dev[1].global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15") 5021 ev = dev[1].wait_global_event(["P2P-GROUP-STARTED"], timeout=15) 5022 if ev is None: 5023 raise Exception("Group formation timed out") 5024 self.sta_group_ev = ev 5025 5026 def goNegotiationSuccess(self, properties): 5027 logger.debug("goNegotiationSuccess: properties=%s" % str(properties)) 5028 5029 def groupStarted(self, properties): 5030 logger.debug("groupStarted: " + str(properties)) 5031 self.group_started = True 5032 g_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 5033 properties['interface_object']) 5034 dev[1].group_form_result(self.sta_group_ev) 5035 ifaddr = dev[1].group_request("STA-FIRST").splitlines()[0] 5036 # Force disassociation with different reason code so that the 5037 # P2P Client using D-Bus does not get normal group termination event 5038 # from the GO. 5039 dev[1].group_request("DEAUTHENTICATE " + ifaddr + " reason=0 test=0") 5040 dev[1].remove_group() 5041 5042 def groupFinished(self, properties): 5043 logger.debug("groupFinished: " + str(properties)) 5044 self.done = True 5045 5046 def propertiesChanged(self, interface_name, changed_properties, 5047 invalidated_properties): 5048 logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties))) 5049 if interface_name != WPAS_DBUS_P2P_PEER: 5050 return 5051 if not self.group_started: 5052 return 5053 if "Groups" not in changed_properties: 5054 return 5055 if len(changed_properties["Groups"]) > 0: 5056 self.peer_group_added = True 5057 if len(changed_properties["Groups"]) == 0: 5058 self.peer_group_removed = True 5059 self.loop.quit() 5060 5061 def run_test(self, *args): 5062 logger.debug("run_test") 5063 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'})) 5064 return False 5065 5066 def success(self): 5067 return self.done and self.peer_group_added and self.peer_group_removed 5068 5069 with TestDbusP2p(bus) as t: 5070 if not t.success(): 5071 raise Exception("Expected signals not seen") 5072 5073def test_dbus_p2p_wps_failure(dev, apdev): 5074 """D-Bus P2P WPS failure""" 5075 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5076 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 5077 addr0 = dev[0].p2p_dev_addr() 5078 5079 class TestDbusP2p(TestDbus): 5080 def __init__(self, bus): 5081 TestDbus.__init__(self, bus) 5082 self.wps_failed = False 5083 self.formation_failure = False 5084 5085 def __enter__(self): 5086 gobject.timeout_add(1, self.run_test) 5087 gobject.timeout_add(15000, self.timeout) 5088 self.add_signal(self.goNegotiationRequest, 5089 WPAS_DBUS_IFACE_P2PDEVICE, 5090 "GONegotiationRequest", 5091 byte_arrays=True) 5092 self.add_signal(self.goNegotiationSuccess, 5093 WPAS_DBUS_IFACE_P2PDEVICE, 5094 "GONegotiationSuccess", 5095 byte_arrays=True) 5096 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 5097 "GroupStarted") 5098 self.add_signal(self.wpsFailed, WPAS_DBUS_IFACE_P2PDEVICE, 5099 "WpsFailed") 5100 self.add_signal(self.groupFormationFailure, 5101 WPAS_DBUS_IFACE_P2PDEVICE, 5102 "GroupFormationFailure") 5103 self.loop.run() 5104 return self 5105 5106 def goNegotiationRequest(self, path, dev_passwd_id, go_intent=0): 5107 logger.debug("goNegotiationRequest: path=%s dev_passwd_id=%d go_intent=%d" % (path, dev_passwd_id, go_intent)) 5108 if dev_passwd_id != 1: 5109 raise Exception("Unexpected dev_passwd_id=%d" % dev_passwd_id) 5110 args = {'peer': path, 'wps_method': 'display', 'pin': '12345670', 5111 'go_intent': 15} 5112 p2p.Connect(args) 5113 5114 def goNegotiationSuccess(self, properties): 5115 logger.debug("goNegotiationSuccess: properties=%s" % str(properties)) 5116 5117 def groupStarted(self, properties): 5118 logger.debug("groupStarted: " + str(properties)) 5119 raise Exception("Unexpected GroupStarted") 5120 5121 def wpsFailed(self, name, args): 5122 logger.debug("wpsFailed - name=%s args=%s" % (name, str(args))) 5123 self.wps_failed = True 5124 if self.formation_failure: 5125 self.loop.quit() 5126 5127 def groupFormationFailure(self, reason): 5128 logger.debug("groupFormationFailure - reason=%s" % reason) 5129 self.formation_failure = True 5130 if self.wps_failed: 5131 self.loop.quit() 5132 5133 def run_test(self, *args): 5134 logger.debug("run_test") 5135 p2p.Listen(10) 5136 if not dev[1].discover_peer(addr0): 5137 raise Exception("Peer not found") 5138 dev[1].global_request("P2P_CONNECT " + addr0 + " 87654321 enter") 5139 return False 5140 5141 def success(self): 5142 return self.wps_failed and self.formation_failure 5143 5144 with TestDbusP2p(bus) as t: 5145 if not t.success(): 5146 raise Exception("Expected signals not seen") 5147 5148def test_dbus_p2p_two_groups(dev, apdev): 5149 """D-Bus P2P with two concurrent groups""" 5150 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5151 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 5152 5153 dev[0].request("SET p2p_no_group_iface 0") 5154 addr0 = dev[0].p2p_dev_addr() 5155 addr1 = dev[1].p2p_dev_addr() 5156 addr2 = dev[2].p2p_dev_addr() 5157 dev[1].p2p_start_go(freq=2412) 5158 5159 class TestDbusP2p(TestDbus): 5160 def __init__(self, bus): 5161 TestDbus.__init__(self, bus) 5162 self.done = False 5163 self.peer = None 5164 self.go = None 5165 self.group1 = None 5166 self.group2 = None 5167 self.groups_removed = False 5168 5169 def __enter__(self): 5170 gobject.timeout_add(1, self.run_test) 5171 gobject.timeout_add(15000, self.timeout) 5172 self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE, 5173 "PropertiesChanged", byte_arrays=True) 5174 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 5175 "DeviceFound") 5176 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 5177 "GroupStarted") 5178 self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE, 5179 "GroupFinished") 5180 self.add_signal(self.peerJoined, WPAS_DBUS_GROUP, 5181 "PeerJoined") 5182 self.loop.run() 5183 return self 5184 5185 def propertiesChanged(self, interface_name, changed_properties, 5186 invalidated_properties): 5187 logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties))) 5188 5189 def deviceFound(self, path): 5190 logger.debug("deviceFound: path=%s" % path) 5191 if addr2.replace(':', '') in path: 5192 self.peer = path 5193 elif addr1.replace(':', '') in path: 5194 self.go = path 5195 if self.go and not self.group1: 5196 logger.info("Join the group") 5197 p2p.StopFind() 5198 pin = '12345670' 5199 dev[1].group_request("WPS_PIN any " + pin) 5200 args = {'peer': self.go, 5201 'join': True, 5202 'wps_method': 'pin', 5203 'pin': pin, 5204 'frequency': 2412} 5205 p2p.Connect(args) 5206 5207 def groupStarted(self, properties): 5208 logger.debug("groupStarted: " + str(properties)) 5209 prop = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE, 5210 dbus_interface=dbus.PROPERTIES_IFACE) 5211 logger.debug("p2pdevice properties: " + str(prop)) 5212 5213 g_obj = bus.get_object(WPAS_DBUS_SERVICE, 5214 properties['group_object']) 5215 res = g_obj.GetAll(WPAS_DBUS_GROUP, 5216 dbus_interface=dbus.PROPERTIES_IFACE, 5217 byte_arrays=True) 5218 logger.debug("Group properties: " + str(res)) 5219 5220 if not self.group1: 5221 self.group1 = properties['group_object'] 5222 self.group1iface = properties['interface_object'] 5223 self.g1_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 5224 self.group1iface) 5225 5226 logger.info("Start autonomous GO") 5227 params = dbus.Dictionary({'frequency': 2412}) 5228 p2p.GroupAdd(params) 5229 elif not self.group2: 5230 self.group2 = properties['group_object'] 5231 self.group2iface = properties['interface_object'] 5232 self.g2_if_obj = bus.get_object(WPAS_DBUS_SERVICE, 5233 self.group2iface) 5234 self.g2_bssid = res['BSSID'] 5235 5236 if self.group1 and self.group2: 5237 logger.info("Authorize peer to join the group") 5238 a2 = binascii.unhexlify(addr2.replace(':', '')) 5239 params = {'Role': 'enrollee', 5240 'P2PDeviceAddress': dbus.ByteArray(a2), 5241 'Bssid': dbus.ByteArray(a2), 5242 'Type': 'pin', 5243 'Pin': '12345670'} 5244 g_wps = dbus.Interface(self.g2_if_obj, WPAS_DBUS_IFACE_WPS) 5245 g_wps.Start(params) 5246 5247 bssid = ':'.join(["%02x" % i for i in struct.unpack('6B', self.g2_bssid)]) 5248 dev[2].scan_for_bss(bssid, freq=2412) 5249 dev[2].global_request("P2P_CONNECT " + bssid + " 12345670 join freq=2412") 5250 ev = dev[2].wait_global_event(["P2P-GROUP-STARTED"], timeout=15) 5251 if ev is None: 5252 raise Exception("Group join timed out") 5253 dev[2].group_form_result(ev) 5254 5255 def groupFinished(self, properties): 5256 logger.debug("groupFinished: " + str(properties)) 5257 5258 if self.group1 == properties['group_object']: 5259 self.group1 = None 5260 elif self.group2 == properties['group_object']: 5261 self.group2 = None 5262 5263 if not self.group1 and not self.group2: 5264 self.done = True 5265 self.loop.quit() 5266 5267 def peerJoined(self, peer): 5268 logger.debug("peerJoined: " + peer) 5269 if self.groups_removed: 5270 return 5271 self.check_results() 5272 5273 dev[2].remove_group() 5274 5275 logger.info("Disconnect group2") 5276 group_p2p = dbus.Interface(self.g2_if_obj, 5277 WPAS_DBUS_IFACE_P2PDEVICE) 5278 group_p2p.Disconnect() 5279 5280 logger.info("Disconnect group1") 5281 group_p2p = dbus.Interface(self.g1_if_obj, 5282 WPAS_DBUS_IFACE_P2PDEVICE) 5283 group_p2p.Disconnect() 5284 self.groups_removed = True 5285 5286 def check_results(self): 5287 logger.info("Check results with two concurrent groups in operation") 5288 5289 g1_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group1) 5290 res1 = g1_obj.GetAll(WPAS_DBUS_GROUP, 5291 dbus_interface=dbus.PROPERTIES_IFACE, 5292 byte_arrays=True) 5293 5294 g2_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group2) 5295 res2 = g2_obj.GetAll(WPAS_DBUS_GROUP, 5296 dbus_interface=dbus.PROPERTIES_IFACE, 5297 byte_arrays=True) 5298 5299 logger.info("group1 = " + self.group1) 5300 logger.debug("Group properties: " + str(res1)) 5301 5302 logger.info("group2 = " + self.group2) 5303 logger.debug("Group properties: " + str(res2)) 5304 5305 prop = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE, 5306 dbus_interface=dbus.PROPERTIES_IFACE) 5307 logger.debug("p2pdevice properties: " + str(prop)) 5308 5309 if res1['Role'] != 'client': 5310 raise Exception("Group1 role reported incorrectly: " + res1['Role']) 5311 if res2['Role'] != 'GO': 5312 raise Exception("Group2 role reported incorrectly: " + res2['Role']) 5313 if prop['Role'] != 'device': 5314 raise Exception("p2pdevice role reported incorrectly: " + prop['Role']) 5315 5316 if len(res2['Members']) != 1: 5317 raise Exception("Unexpected Members value for group 2") 5318 5319 def run_test(self, *args): 5320 logger.debug("run_test") 5321 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'})) 5322 return False 5323 5324 def success(self): 5325 return self.done 5326 5327 with TestDbusP2p(bus) as t: 5328 if not t.success(): 5329 raise Exception("Expected signals not seen") 5330 5331 dev[1].remove_group() 5332 5333def test_dbus_p2p_cancel(dev, apdev): 5334 """D-Bus P2P Cancel""" 5335 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5336 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 5337 try: 5338 p2p.Cancel() 5339 raise Exception("Unexpected p2p.Cancel() success") 5340 except dbus.exceptions.DBusException as e: 5341 pass 5342 5343 addr0 = dev[0].p2p_dev_addr() 5344 dev[1].p2p_listen() 5345 5346 class TestDbusP2p(TestDbus): 5347 def __init__(self, bus): 5348 TestDbus.__init__(self, bus) 5349 self.done = False 5350 5351 def __enter__(self): 5352 gobject.timeout_add(1, self.run_test) 5353 gobject.timeout_add(15000, self.timeout) 5354 self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE, 5355 "DeviceFound") 5356 self.loop.run() 5357 return self 5358 5359 def deviceFound(self, path): 5360 logger.debug("deviceFound: path=%s" % path) 5361 args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670', 5362 'go_intent': 0} 5363 p2p.Connect(args) 5364 p2p.Cancel() 5365 self.done = True 5366 self.loop.quit() 5367 5368 def run_test(self, *args): 5369 logger.debug("run_test") 5370 p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'})) 5371 return False 5372 5373 def success(self): 5374 return self.done 5375 5376 with TestDbusP2p(bus) as t: 5377 if not t.success(): 5378 raise Exception("Expected signals not seen") 5379 5380def test_dbus_p2p_ip_addr(dev, apdev): 5381 """D-Bus P2P and IP address parameters""" 5382 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5383 p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE) 5384 5385 vals = [("IpAddrGo", "192.168.43.1"), 5386 ("IpAddrMask", "255.255.255.0"), 5387 ("IpAddrStart", "192.168.43.100"), 5388 ("IpAddrEnd", "192.168.43.199")] 5389 for field, value in vals: 5390 if_obj.Set(WPAS_DBUS_IFACE, field, value, 5391 dbus_interface=dbus.PROPERTIES_IFACE) 5392 val = if_obj.Get(WPAS_DBUS_IFACE, field, 5393 dbus_interface=dbus.PROPERTIES_IFACE) 5394 if val != value: 5395 raise Exception("Unexpected %s value: %s" % (field, val)) 5396 5397 set_ip_addr_info(dev[1]) 5398 5399 dev[0].global_request("SET p2p_go_intent 0") 5400 5401 req = dev[0].global_request("NFC_GET_HANDOVER_REQ NDEF P2P-CR").rstrip() 5402 if "FAIL" in req: 5403 raise Exception("Failed to generate NFC connection handover request") 5404 sel = dev[1].global_request("NFC_GET_HANDOVER_SEL NDEF P2P-CR").rstrip() 5405 if "FAIL" in sel: 5406 raise Exception("Failed to generate NFC connection handover select") 5407 dev[0].dump_monitor() 5408 dev[1].dump_monitor() 5409 res = dev[1].global_request("NFC_REPORT_HANDOVER RESP P2P " + req + " " + sel) 5410 if "FAIL" in res: 5411 raise Exception("Failed to report NFC connection handover to wpa_supplicant(resp)") 5412 res = dev[0].global_request("NFC_REPORT_HANDOVER INIT P2P " + req + " " + sel) 5413 if "FAIL" in res: 5414 raise Exception("Failed to report NFC connection handover to wpa_supplicant(init)") 5415 5416 class TestDbusP2p(TestDbus): 5417 def __init__(self, bus): 5418 TestDbus.__init__(self, bus) 5419 self.done = False 5420 5421 def __enter__(self): 5422 gobject.timeout_add(1, self.run_test) 5423 gobject.timeout_add(15000, self.timeout) 5424 self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE, 5425 "GroupStarted") 5426 self.loop.run() 5427 return self 5428 5429 def groupStarted(self, properties): 5430 logger.debug("groupStarted: " + str(properties)) 5431 self.loop.quit() 5432 5433 if 'IpAddrGo' not in properties: 5434 logger.info("IpAddrGo missing from GroupStarted") 5435 ip_addr_go = properties['IpAddrGo'] 5436 addr = "%d.%d.%d.%d" % (ip_addr_go[0], ip_addr_go[1], ip_addr_go[2], ip_addr_go[3]) 5437 if addr != "192.168.42.1": 5438 logger.info("Unexpected IpAddrGo value: " + addr) 5439 self.done = True 5440 5441 def run_test(self, *args): 5442 logger.debug("run_test") 5443 return False 5444 5445 def success(self): 5446 return self.done 5447 5448 with TestDbusP2p(bus) as t: 5449 if not t.success(): 5450 raise Exception("Expected signals not seen") 5451 5452def test_dbus_introspect(dev, apdev): 5453 """D-Bus introspection""" 5454 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5455 5456 res = if_obj.Introspect(WPAS_DBUS_IFACE, 5457 dbus_interface=dbus.INTROSPECTABLE_IFACE) 5458 logger.info("Initial Introspect: " + str(res)) 5459 if res is None or "Introspectable" not in res or "GroupStarted" not in res: 5460 raise Exception("Unexpected initial Introspect response: " + str(res)) 5461 if "FastReauth" not in res or "PassiveScan" not in res: 5462 raise Exception("Unexpected initial Introspect response: " + str(res)) 5463 5464 with alloc_fail(dev[0], 1, "wpa_dbus_introspect"): 5465 res2 = if_obj.Introspect(WPAS_DBUS_IFACE, 5466 dbus_interface=dbus.INTROSPECTABLE_IFACE) 5467 logger.info("Introspect: " + str(res2)) 5468 if res2 is not None: 5469 raise Exception("Unexpected Introspect response") 5470 5471 with alloc_fail(dev[0], 1, "=add_interface;wpa_dbus_introspect"): 5472 res2 = if_obj.Introspect(WPAS_DBUS_IFACE, 5473 dbus_interface=dbus.INTROSPECTABLE_IFACE) 5474 logger.info("Introspect: " + str(res2)) 5475 if res2 is None: 5476 raise Exception("No Introspect response") 5477 if len(res2) >= len(res): 5478 raise Exception("Unexpected Introspect response") 5479 5480 with alloc_fail(dev[0], 1, "wpabuf_alloc;add_interface;wpa_dbus_introspect"): 5481 res2 = if_obj.Introspect(WPAS_DBUS_IFACE, 5482 dbus_interface=dbus.INTROSPECTABLE_IFACE) 5483 logger.info("Introspect: " + str(res2)) 5484 if res2 is None: 5485 raise Exception("No Introspect response") 5486 if len(res2) >= len(res): 5487 raise Exception("Unexpected Introspect response") 5488 5489 with alloc_fail(dev[0], 2, "=add_interface;wpa_dbus_introspect"): 5490 res2 = if_obj.Introspect(WPAS_DBUS_IFACE, 5491 dbus_interface=dbus.INTROSPECTABLE_IFACE) 5492 logger.info("Introspect: " + str(res2)) 5493 if res2 is None: 5494 raise Exception("No Introspect response") 5495 if len(res2) >= len(res): 5496 raise Exception("Unexpected Introspect response") 5497 5498def run_busctl(service, obj): 5499 if not shutil.which("busctl"): 5500 raise HwsimSkip("No busctl available") 5501 logger.info("busctl introspect %s %s" % (service, obj)) 5502 cmd = subprocess.Popen(['busctl', 'introspect', service, obj], 5503 stdout=subprocess.PIPE, 5504 stderr=subprocess.PIPE) 5505 out = cmd.communicate() 5506 cmd.wait() 5507 logger.info("busctl stdout:\n%s" % out[0].strip()) 5508 if len(out[1]) > 0: 5509 logger.info("busctl stderr: %s" % out[1].decode().strip()) 5510 if "Duplicate property" in out[1].decode(): 5511 raise Exception("Duplicate property") 5512 5513def test_dbus_introspect_busctl(dev, apdev): 5514 """D-Bus introspection with busctl""" 5515 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5516 ifaces = dbus_get(dbus, wpas_obj, "Interfaces") 5517 run_busctl(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH) 5518 run_busctl(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH + "/Interfaces") 5519 run_busctl(WPAS_DBUS_SERVICE, ifaces[0]) 5520 5521 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 5522 bssid = apdev[0]['bssid'] 5523 dev[0].scan_for_bss(bssid, freq=2412) 5524 id = dev[0].add_network() 5525 dev[0].set_network(id, "disabled", "0") 5526 dev[0].set_network_quoted(id, "ssid", "test") 5527 5528 run_busctl(WPAS_DBUS_SERVICE, ifaces[0] + "/BSSs/0") 5529 run_busctl(WPAS_DBUS_SERVICE, ifaces[0] + "/Networks/0") 5530 5531def test_dbus_ap(dev, apdev): 5532 """D-Bus AddNetwork for AP mode""" 5533 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5534 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 5535 5536 ssid = "test-wpa2-psk" 5537 passphrase = 'qwertyuiop' 5538 5539 class TestDbusConnect(TestDbus): 5540 def __init__(self, bus): 5541 TestDbus.__init__(self, bus) 5542 self.started = False 5543 self.sta_added = False 5544 self.sta_removed = False 5545 self.authorized = False 5546 self.deauthorized = False 5547 self.stations = False 5548 5549 def __enter__(self): 5550 gobject.timeout_add(1, self.run_connect) 5551 gobject.timeout_add(15000, self.timeout) 5552 self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded") 5553 self.add_signal(self.networkSelected, WPAS_DBUS_IFACE, 5554 "NetworkSelected") 5555 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 5556 "PropertiesChanged") 5557 self.add_signal(self.stationAdded, WPAS_DBUS_IFACE, "StationAdded") 5558 self.add_signal(self.stationRemoved, WPAS_DBUS_IFACE, 5559 "StationRemoved") 5560 self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE, 5561 "StaAuthorized") 5562 self.add_signal(self.staDeauthorized, WPAS_DBUS_IFACE, 5563 "StaDeauthorized") 5564 self.loop.run() 5565 return self 5566 5567 def networkAdded(self, network, properties): 5568 logger.debug("networkAdded: %s" % str(network)) 5569 logger.debug(str(properties)) 5570 5571 def networkSelected(self, network): 5572 logger.debug("networkSelected: %s" % str(network)) 5573 self.network_selected = True 5574 5575 def propertiesChanged(self, properties): 5576 logger.debug("propertiesChanged: %s" % str(properties)) 5577 if 'State' in properties and properties['State'] == "completed": 5578 self.started = True 5579 dev[1].connect(ssid, psk=passphrase, scan_freq="2412") 5580 5581 def stationAdded(self, station, properties): 5582 logger.debug("stationAdded: %s" % str(station)) 5583 logger.debug(str(properties)) 5584 self.sta_added = True 5585 res = if_obj.Get(WPAS_DBUS_IFACE, 'Stations', 5586 dbus_interface=dbus.PROPERTIES_IFACE) 5587 logger.info("Stations: " + str(res)) 5588 if len(res) == 1: 5589 self.stations = True 5590 else: 5591 raise Exception("Missing Stations entry: " + str(res)) 5592 5593 def stationRemoved(self, station): 5594 logger.debug("stationRemoved: %s" % str(station)) 5595 self.sta_removed = True 5596 res = if_obj.Get(WPAS_DBUS_IFACE, 'Stations', 5597 dbus_interface=dbus.PROPERTIES_IFACE) 5598 logger.info("Stations: " + str(res)) 5599 if len(res) != 0: 5600 self.stations = False 5601 raise Exception("Unexpected Stations entry: " + str(res)) 5602 self.loop.quit() 5603 5604 def staAuthorized(self, name): 5605 logger.debug("staAuthorized: " + name) 5606 self.authorized = True 5607 dev[1].request("DISCONNECT") 5608 5609 def staDeauthorized(self, name): 5610 logger.debug("staDeauthorized: " + name) 5611 self.deauthorized = True 5612 5613 def run_connect(self, *args): 5614 logger.debug("run_connect") 5615 args = dbus.Dictionary({'ssid': ssid, 5616 'key_mgmt': 'WPA-PSK', 5617 'psk': passphrase, 5618 'mode': 2, 5619 'frequency': 2412, 5620 'scan_freq': 2412}, 5621 signature='sv') 5622 self.netw = iface.AddNetwork(args) 5623 iface.SelectNetwork(self.netw) 5624 return False 5625 5626 def success(self): 5627 return self.started and self.sta_added and self.sta_removed and \ 5628 self.authorized and self.deauthorized 5629 5630 with TestDbusConnect(bus) as t: 5631 if not t.success(): 5632 raise Exception("Expected signals not seen") 5633 5634def test_dbus_ap_scan(dev, apdev): 5635 """D-Bus AddNetwork for AP mode and scan""" 5636 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5637 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 5638 5639 ssid = "test-wpa2-psk" 5640 passphrase = 'qwertyuiop' 5641 5642 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 5643 bssid = hapd.own_addr() 5644 5645 class TestDbusConnect(TestDbus): 5646 def __init__(self, bus): 5647 TestDbus.__init__(self, bus) 5648 self.started = False 5649 self.scan_completed = False 5650 5651 def __enter__(self): 5652 gobject.timeout_add(1, self.run_connect) 5653 gobject.timeout_add(15000, self.timeout) 5654 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 5655 "PropertiesChanged") 5656 self.add_signal(self.scanDone, WPAS_DBUS_IFACE, "ScanDone") 5657 self.loop.run() 5658 return self 5659 5660 def propertiesChanged(self, properties): 5661 logger.debug("propertiesChanged: %s" % str(properties)) 5662 if 'State' in properties and properties['State'] == "completed": 5663 self.started = True 5664 logger.info("Try to scan in AP mode") 5665 iface.Scan({'Type': 'active', 5666 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]}) 5667 logger.info("Scan() returned") 5668 5669 def scanDone(self, success): 5670 logger.debug("scanDone: success=%s" % success) 5671 if self.started: 5672 self.scan_completed = True 5673 self.loop.quit() 5674 5675 def run_connect(self, *args): 5676 logger.debug("run_connect") 5677 args = dbus.Dictionary({'ssid': ssid, 5678 'key_mgmt': 'WPA-PSK', 5679 'psk': passphrase, 5680 'mode': 2, 5681 'frequency': 2412, 5682 'scan_freq': 2412}, 5683 signature='sv') 5684 self.netw = iface.AddNetwork(args) 5685 iface.SelectNetwork(self.netw) 5686 return False 5687 5688 def success(self): 5689 return self.started and self.scan_completed 5690 5691 with TestDbusConnect(bus) as t: 5692 if not t.success(): 5693 raise Exception("Expected signals not seen") 5694 5695def test_dbus_connect_wpa_eap(dev, apdev): 5696 """D-Bus AddNetwork and connection with WPA+WPA2-Enterprise AP""" 5697 skip_without_tkip(dev[0]) 5698 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5699 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 5700 5701 ssid = "test-wpa-eap" 5702 params = hostapd.wpa_eap_params(ssid=ssid) 5703 params["wpa"] = "3" 5704 params["rsn_pairwise"] = "CCMP" 5705 hapd = hostapd.add_ap(apdev[0], params) 5706 5707 class TestDbusConnect(TestDbus): 5708 def __init__(self, bus): 5709 TestDbus.__init__(self, bus) 5710 self.done = False 5711 5712 def __enter__(self): 5713 gobject.timeout_add(1, self.run_connect) 5714 gobject.timeout_add(15000, self.timeout) 5715 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 5716 "PropertiesChanged") 5717 self.add_signal(self.eap, WPAS_DBUS_IFACE, "EAP") 5718 self.loop.run() 5719 return self 5720 5721 def propertiesChanged(self, properties): 5722 logger.debug("propertiesChanged: %s" % str(properties)) 5723 if 'State' in properties and properties['State'] == "completed": 5724 self.done = True 5725 self.loop.quit() 5726 5727 def eap(self, status, parameter): 5728 logger.debug("EAP: status=%s parameter=%s" % (status, parameter)) 5729 5730 def run_connect(self, *args): 5731 logger.debug("run_connect") 5732 args = dbus.Dictionary({'ssid': ssid, 5733 'key_mgmt': 'WPA-EAP', 5734 'eap': 'PEAP', 5735 'identity': 'user', 5736 'password': 'password', 5737 'ca_cert': 'auth_serv/ca.pem', 5738 'phase2': 'auth=MSCHAPV2', 5739 'scan_freq': 2412}, 5740 signature='sv') 5741 self.netw = iface.AddNetwork(args) 5742 iface.SelectNetwork(self.netw) 5743 return False 5744 5745 def success(self): 5746 return self.done 5747 5748 with TestDbusConnect(bus) as t: 5749 if not t.success(): 5750 raise Exception("Expected signals not seen") 5751 5752def test_dbus_ap_scan_2_ap_mode_scan(dev, apdev): 5753 """AP_SCAN 2 AP mode and D-Bus Scan()""" 5754 try: 5755 _test_dbus_ap_scan_2_ap_mode_scan(dev, apdev) 5756 finally: 5757 dev[0].request("AP_SCAN 1") 5758 5759def _test_dbus_ap_scan_2_ap_mode_scan(dev, apdev): 5760 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5761 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 5762 5763 if "OK" not in dev[0].request("AP_SCAN 2"): 5764 raise Exception("Failed to set AP_SCAN 2") 5765 5766 id = dev[0].add_network() 5767 dev[0].set_network(id, "mode", "2") 5768 dev[0].set_network_quoted(id, "ssid", "wpas-ap-open") 5769 dev[0].set_network(id, "key_mgmt", "NONE") 5770 dev[0].set_network(id, "frequency", "2412") 5771 dev[0].set_network(id, "scan_freq", "2412") 5772 dev[0].set_network(id, "disabled", "0") 5773 dev[0].select_network(id) 5774 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5) 5775 if ev is None: 5776 raise Exception("AP failed to start") 5777 5778 with fail_test(dev[0], 1, "wpa_driver_nl80211_scan"): 5779 iface.Scan({'Type': 'active', 5780 'AllowRoam': True, 5781 'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]}) 5782 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED", 5783 "AP-DISABLED"], timeout=5) 5784 if ev is None: 5785 raise Exception("CTRL-EVENT-SCAN-FAILED not seen") 5786 if "AP-DISABLED" in ev: 5787 raise Exception("Unexpected AP-DISABLED event") 5788 if "retry=1" in ev: 5789 # Wait for the retry to scan happen 5790 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED", 5791 "AP-DISABLED"], timeout=5) 5792 if ev is None: 5793 raise Exception("CTRL-EVENT-SCAN-FAILED not seen - retry") 5794 if "AP-DISABLED" in ev: 5795 raise Exception("Unexpected AP-DISABLED event - retry") 5796 5797 dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412") 5798 dev[1].request("DISCONNECT") 5799 dev[1].wait_disconnected() 5800 dev[0].request("DISCONNECT") 5801 dev[0].wait_disconnected() 5802 5803def test_dbus_expectdisconnect(dev, apdev): 5804 """D-Bus ExpectDisconnect""" 5805 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5806 wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE) 5807 5808 params = {"ssid": "test-open"} 5809 hapd = hostapd.add_ap(apdev[0], params) 5810 dev[0].connect("test-open", key_mgmt="NONE", scan_freq="2412") 5811 5812 # This does not really verify the behavior other than by going through the 5813 # code path for additional coverage. 5814 wpas.ExpectDisconnect() 5815 dev[0].request("DISCONNECT") 5816 dev[0].wait_disconnected() 5817 5818def test_dbus_save_config(dev, apdev): 5819 """D-Bus SaveConfig""" 5820 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5821 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 5822 try: 5823 iface.SaveConfig() 5824 raise Exception("SaveConfig() accepted unexpectedly") 5825 except dbus.exceptions.DBusException as e: 5826 if not str(e).startswith("fi.w1.wpa_supplicant1.UnknownError: Not allowed to update configuration"): 5827 raise Exception("Unexpected error message for SaveConfig(): " + str(e)) 5828 5829def test_dbus_vendor_elem(dev, apdev): 5830 """D-Bus vendor element operations""" 5831 try: 5832 _test_dbus_vendor_elem(dev, apdev) 5833 finally: 5834 dev[0].request("VENDOR_ELEM_REMOVE 1 *") 5835 5836def _test_dbus_vendor_elem(dev, apdev): 5837 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5838 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 5839 5840 dev[0].request("VENDOR_ELEM_REMOVE 1 *") 5841 5842 try: 5843 ie = dbus.ByteArray(b"\x00\x00") 5844 iface.VendorElemAdd(-1, ie) 5845 raise Exception("Invalid VendorElemAdd() accepted") 5846 except dbus.exceptions.DBusException as e: 5847 if "InvalidArgs" not in str(e) or "Invalid ID" not in str(e): 5848 raise Exception("Unexpected error message for invalid VendorElemAdd[1]: " + str(e)) 5849 5850 try: 5851 ie = dbus.ByteArray(b'') 5852 iface.VendorElemAdd(1, ie) 5853 raise Exception("Invalid VendorElemAdd() accepted") 5854 except dbus.exceptions.DBusException as e: 5855 if "InvalidArgs" not in str(e) or "Invalid value" not in str(e): 5856 raise Exception("Unexpected error message for invalid VendorElemAdd[2]: " + str(e)) 5857 5858 try: 5859 ie = dbus.ByteArray(b"\x00\x01") 5860 iface.VendorElemAdd(1, ie) 5861 raise Exception("Invalid VendorElemAdd() accepted") 5862 except dbus.exceptions.DBusException as e: 5863 if "InvalidArgs" not in str(e) or "Parse error" not in str(e): 5864 raise Exception("Unexpected error message for invalid VendorElemAdd[3]: " + str(e)) 5865 5866 try: 5867 iface.VendorElemGet(-1) 5868 raise Exception("Invalid VendorElemGet() accepted") 5869 except dbus.exceptions.DBusException as e: 5870 if "InvalidArgs" not in str(e) or "Invalid ID" not in str(e): 5871 raise Exception("Unexpected error message for invalid VendorElemGet[1]: " + str(e)) 5872 5873 try: 5874 iface.VendorElemGet(1) 5875 raise Exception("Invalid VendorElemGet() accepted") 5876 except dbus.exceptions.DBusException as e: 5877 if "InvalidArgs" not in str(e) or "ID value does not exist" not in str(e): 5878 raise Exception("Unexpected error message for invalid VendorElemGet[2]: " + str(e)) 5879 5880 try: 5881 ie = dbus.ByteArray(b"\x00\x00") 5882 iface.VendorElemRem(-1, ie) 5883 raise Exception("Invalid VendorElemRemove() accepted") 5884 except dbus.exceptions.DBusException as e: 5885 if "InvalidArgs" not in str(e) or "Invalid ID" not in str(e): 5886 raise Exception("Unexpected error message for invalid VendorElemRemove[1]: " + str(e)) 5887 5888 try: 5889 ie = dbus.ByteArray(b'') 5890 iface.VendorElemRem(1, ie) 5891 raise Exception("Invalid VendorElemRemove() accepted") 5892 except dbus.exceptions.DBusException as e: 5893 if "InvalidArgs" not in str(e) or "Invalid value" not in str(e): 5894 raise Exception("Unexpected error message for invalid VendorElemRemove[1]: " + str(e)) 5895 5896 iface.VendorElemRem(1, b"*") 5897 5898 ie = dbus.ByteArray(b"\x00\x01\x00") 5899 iface.VendorElemAdd(1, ie) 5900 5901 val = iface.VendorElemGet(1) 5902 if len(val) != len(ie): 5903 raise Exception("Unexpected VendorElemGet length") 5904 for i in range(len(val)): 5905 if val[i] != dbus.Byte(ie[i]): 5906 raise Exception("Unexpected VendorElemGet data") 5907 5908 ie2 = dbus.ByteArray(b"\xe0\x00") 5909 iface.VendorElemAdd(1, ie2) 5910 5911 ies = ie + ie2 5912 val = iface.VendorElemGet(1) 5913 if len(val) != len(ies): 5914 raise Exception("Unexpected VendorElemGet length[2]") 5915 for i in range(len(val)): 5916 if val[i] != dbus.Byte(ies[i]): 5917 raise Exception("Unexpected VendorElemGet data[2]") 5918 5919 try: 5920 test_ie = dbus.ByteArray(b"\x01\x01") 5921 iface.VendorElemRem(1, test_ie) 5922 raise Exception("Invalid VendorElemRemove() accepted") 5923 except dbus.exceptions.DBusException as e: 5924 if "InvalidArgs" not in str(e) or "Parse error" not in str(e): 5925 raise Exception("Unexpected error message for invalid VendorElemRemove[1]: " + str(e)) 5926 5927 iface.VendorElemRem(1, ie) 5928 val = iface.VendorElemGet(1) 5929 if len(val) != len(ie2): 5930 raise Exception("Unexpected VendorElemGet length[3]") 5931 5932 iface.VendorElemRem(1, b"*") 5933 try: 5934 iface.VendorElemGet(1) 5935 raise Exception("Invalid VendorElemGet() accepted after removal") 5936 except dbus.exceptions.DBusException as e: 5937 if "InvalidArgs" not in str(e) or "ID value does not exist" not in str(e): 5938 raise Exception("Unexpected error message for invalid VendorElemGet after removal: " + str(e)) 5939 5940def test_dbus_assoc_reject(dev, apdev): 5941 """D-Bus AssocStatusCode""" 5942 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5943 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 5944 5945 ssid = "test-open" 5946 params = {"ssid": ssid, 5947 "max_listen_interval": "1"} 5948 hapd = hostapd.add_ap(apdev[0], params) 5949 5950 class TestDbusConnect(TestDbus): 5951 def __init__(self, bus): 5952 TestDbus.__init__(self, bus) 5953 self.assoc_status_seen = False 5954 self.state = 0 5955 5956 def __enter__(self): 5957 gobject.timeout_add(1, self.run_connect) 5958 gobject.timeout_add(15000, self.timeout) 5959 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 5960 "PropertiesChanged") 5961 self.loop.run() 5962 return self 5963 5964 def propertiesChanged(self, properties): 5965 logger.debug("propertiesChanged: %s" % str(properties)) 5966 if 'AssocStatusCode' in properties: 5967 status = properties['AssocStatusCode'] 5968 if status != 51: 5969 logger.info("Unexpected status code: " + str(status)) 5970 else: 5971 self.assoc_status_seen = True 5972 iface.Disconnect() 5973 self.loop.quit() 5974 5975 def run_connect(self, *args): 5976 args = dbus.Dictionary({'ssid': ssid, 5977 'key_mgmt': 'NONE', 5978 'scan_freq': 2412}, 5979 signature='sv') 5980 self.netw = iface.AddNetwork(args) 5981 iface.SelectNetwork(self.netw) 5982 return False 5983 5984 def success(self): 5985 return self.assoc_status_seen 5986 5987 with TestDbusConnect(bus) as t: 5988 if not t.success(): 5989 raise Exception("Expected signals not seen") 5990 5991def test_dbus_mesh(dev, apdev): 5992 """D-Bus mesh""" 5993 check_mesh_support(dev[0]) 5994 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 5995 mesh = dbus.Interface(if_obj, WPAS_DBUS_IFACE_MESH) 5996 5997 add_open_mesh_network(dev[1]) 5998 addr1 = dev[1].own_addr() 5999 6000 class TestDbusMesh(TestDbus): 6001 def __init__(self, bus): 6002 TestDbus.__init__(self, bus) 6003 self.done = False 6004 6005 def __enter__(self): 6006 gobject.timeout_add(1, self.run_test) 6007 gobject.timeout_add(15000, self.timeout) 6008 self.add_signal(self.meshGroupStarted, WPAS_DBUS_IFACE_MESH, 6009 "MeshGroupStarted") 6010 self.add_signal(self.meshGroupRemoved, WPAS_DBUS_IFACE_MESH, 6011 "MeshGroupRemoved") 6012 self.add_signal(self.meshPeerConnected, WPAS_DBUS_IFACE_MESH, 6013 "MeshPeerConnected") 6014 self.add_signal(self.meshPeerDisconnected, WPAS_DBUS_IFACE_MESH, 6015 "MeshPeerDisconnected") 6016 self.loop.run() 6017 return self 6018 6019 def meshGroupStarted(self, args): 6020 logger.debug("MeshGroupStarted: " + str(args)) 6021 6022 def meshGroupRemoved(self, args): 6023 logger.debug("MeshGroupRemoved: " + str(args)) 6024 self.done = True 6025 self.loop.quit() 6026 6027 def meshPeerConnected(self, args): 6028 logger.debug("MeshPeerConnected: " + str(args)) 6029 6030 res = if_obj.Get(WPAS_DBUS_IFACE_MESH, 'MeshPeers', 6031 dbus_interface=dbus.PROPERTIES_IFACE, 6032 byte_arrays=True) 6033 logger.debug("MeshPeers: " + str(res)) 6034 if len(res) != 1: 6035 raise Exception("Unexpected number of MeshPeer values") 6036 if binascii.hexlify(res[0]).decode() != addr1.replace(':', ''): 6037 raise Exception("Unexpected peer address") 6038 6039 res = if_obj.Get(WPAS_DBUS_IFACE_MESH, 'MeshGroup', 6040 dbus_interface=dbus.PROPERTIES_IFACE, 6041 byte_arrays=True) 6042 logger.debug("MeshGroup: " + str(res)) 6043 if res != b"wpas-mesh-open": 6044 raise Exception("Unexpected MeshGroup") 6045 dev[1].mesh_group_remove() 6046 6047 def meshPeerDisconnected(self, args): 6048 logger.debug("MeshPeerDisconnected: " + str(args)) 6049 dev[0].mesh_group_remove() 6050 6051 def run_test(self, *args): 6052 logger.debug("run_test") 6053 add_open_mesh_network(dev[0]) 6054 return False 6055 6056 def success(self): 6057 return self.done 6058 6059 with TestDbusMesh(bus) as t: 6060 if not t.success(): 6061 raise Exception("Expected signals not seen") 6062 6063def test_dbus_roam(dev, apdev): 6064 """D-Bus Roam""" 6065 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 6066 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6067 6068 ssid = "test-wpa2-psk" 6069 passphrase = 'qwertyuiop' 6070 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase) 6071 hapd = hostapd.add_ap(apdev[0], params) 6072 hapd2 = hostapd.add_ap(apdev[1], params) 6073 bssid = apdev[0]['bssid'] 6074 dev[0].scan_for_bss(bssid, freq=2412) 6075 bssid2 = apdev[1]['bssid'] 6076 dev[0].scan_for_bss(bssid2, freq=2412) 6077 6078 class TestDbusConnect(TestDbus): 6079 def __init__(self, bus): 6080 TestDbus.__init__(self, bus) 6081 self.state = 0 6082 6083 def __enter__(self): 6084 gobject.timeout_add(1, self.run_connect) 6085 gobject.timeout_add(15000, self.timeout) 6086 self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE, 6087 "PropertiesChanged") 6088 self.loop.run() 6089 return self 6090 6091 def propertiesChanged(self, properties): 6092 logger.debug("propertiesChanged: %s" % str(properties)) 6093 if 'State' in properties and properties['State'] == "completed": 6094 if self.state == 0: 6095 self.state = 1 6096 cur = properties["CurrentBSS"] 6097 bss_obj = bus.get_object(WPAS_DBUS_SERVICE, cur) 6098 res = bss_obj.Get(WPAS_DBUS_BSS, 'BSSID', 6099 dbus_interface=dbus.PROPERTIES_IFACE) 6100 bssid_str = '' 6101 for item in res: 6102 if len(bssid_str) > 0: 6103 bssid_str += ':' 6104 bssid_str += '%02x' % item 6105 dst = bssid if bssid_str == bssid2 else bssid2 6106 iface.Roam(dst) 6107 elif self.state == 1: 6108 if "RoamComplete" in properties and \ 6109 properties["RoamComplete"]: 6110 self.state = 2 6111 self.loop.quit() 6112 6113 def run_connect(self, *args): 6114 logger.debug("run_connect") 6115 args = dbus.Dictionary({'ssid': ssid, 6116 'key_mgmt': 'WPA-PSK', 6117 'psk': passphrase, 6118 'scan_freq': 2412}, 6119 signature='sv') 6120 self.netw = iface.AddNetwork(args) 6121 iface.SelectNetwork(self.netw) 6122 return False 6123 6124 def success(self): 6125 return self.state == 2 6126 6127 with TestDbusConnect(bus) as t: 6128 if not t.success(): 6129 raise Exception("Expected signals not seen") 6130 6131def test_dbus_creds(dev, apdev): 6132 """D-Bus interworking credentials""" 6133 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 6134 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6135 6136 args = {'domain': ['server.w1.fi','server2.w1.fi'], 6137 'realm': 'server.w1.fi', 6138 'home_ois': '50a9bf', 6139 'required_home_ois': '23bf50', 6140 'eap': 'TTLS', 6141 'phase2': 'auth=MSCHAPV2', 6142 'username': 'user', 6143 'password': 'password', 6144 'domain_suffix_match': 'server.w1.fi', 6145 'ca_cert': 'auth_serv/ca.pem'} 6146 6147 path = iface.AddCred(dbus.Dictionary(args, signature='sv')) 6148 for k, v in args.items(): 6149 if k == 'password': 6150 continue 6151 prop = dev[0].get_cred(0, k) 6152 if isinstance(v, list): 6153 v = '\n'.join(v) 6154 if prop != v: 6155 raise Exception('Credential add failed: %s does not match %s' % (prop, v)) 6156 6157 iface.RemoveCred(path) 6158 if not "FAIL" in dev[0].get_cred(0, 'domain'): 6159 raise Exception("Credential remove failed") 6160 6161 # Removal of multiple credentials 6162 cred1 = {'domain': 'server1.w1.fi','realm': 'server1.w1.fi','eap': 'TTLS'} 6163 iface.AddCred(dbus.Dictionary(cred1, signature='sv')) 6164 if "FAIL" in dev[0].get_cred(0, 'domain'): 6165 raise Exception("Failed to add credential") 6166 6167 cred2 = {'domain': 'server2.w1.fi','realm': 'server2.w1.fi','eap': 'TTLS'} 6168 iface.AddCred(dbus.Dictionary(cred2, signature='sv')) 6169 if "FAIL" in dev[0].get_cred(1, 'domain'): 6170 raise Exception("Failed to add credential") 6171 6172 iface.RemoveAllCreds() 6173 if not "FAIL" in dev[0].get_cred(0, 'domain'): 6174 raise Exception("Credential remove failed") 6175 if not "FAIL" in dev[0].get_cred(1, 'domain'): 6176 raise Exception("Credential remove failed") 6177 6178def test_dbus_interworking(dev, apdev): 6179 """D-Bus interworking selection""" 6180 (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) 6181 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6182 6183 params = {"ssid": "test-interworking", "wpa": "2", 6184 "wpa_key_mgmt": "WPA-EAP", "rsn_pairwise": "CCMP", 6185 "ieee8021x": "1", "eapol_version": "2", 6186 "eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf", 6187 "ca_cert": "auth_serv/ca.pem", 6188 "server_cert": "auth_serv/server.pem", 6189 "private_key": "auth_serv/server.key", 6190 "interworking": "1", 6191 "domain_name": "server.w1.fi", 6192 "nai_realm": "0,server.w1.fi,21[2:4][5:7]", 6193 "roaming_consortium": "2233445566", 6194 "hs20": "1", "anqp_domain_id": "1234"} 6195 6196 hapd = hostapd.add_ap(apdev[0], params) 6197 6198 class TestDbusInterworking(TestDbus): 6199 def __init__(self, bus): 6200 TestDbus.__init__(self, bus) 6201 self.interworking_ap_seen = False 6202 self.interworking_select_done = False 6203 6204 def __enter__(self): 6205 gobject.timeout_add(1, self.run_select) 6206 gobject.timeout_add(15000, self.timeout) 6207 self.add_signal(self.interworkingAPAdded, WPAS_DBUS_IFACE, 6208 "InterworkingAPAdded") 6209 self.add_signal(self.interworkingSelectDone, WPAS_DBUS_IFACE, 6210 "InterworkingSelectDone") 6211 self.loop.run() 6212 return self 6213 6214 def interworkingAPAdded(self, bss, cred, properties): 6215 logger.debug("interworkingAPAdded: bss=%s cred=%s %s" % (bss, cred, str(properties))) 6216 if self.cred == cred: 6217 self.interworking_ap_seen = True 6218 6219 def interworkingSelectDone(self): 6220 logger.debug("interworkingSelectDone") 6221 self.interworking_select_done = True 6222 self.loop.quit() 6223 6224 def run_select(self, *args): 6225 args = {"domain": "server.w1.fi", 6226 "realm": "server.w1.fi", 6227 "eap": "TTLS", 6228 "phase2": "auth=MSCHAPV2", 6229 "username": "user", 6230 "password": "password", 6231 "domain_suffix_match": "server.w1.fi", 6232 "ca_cert": "auth_serv/ca.pem"} 6233 self.cred = iface.AddCred(dbus.Dictionary(args, signature='sv')) 6234 iface.InterworkingSelect() 6235 return False 6236 6237 def success(self): 6238 return self.interworking_ap_seen and self.interworking_select_done 6239 6240 with TestDbusInterworking(bus) as t: 6241 if not t.success(): 6242 raise Exception("Expected signals not seen") 6243 6244def test_dbus_hs20_terms_and_conditions(dev, apdev): 6245 """D-Bus HS2.0 Terms and Conditions acceptance""" 6246 check_eap_capa(dev[0], "MSCHAPV2") 6247 6248 (bus, wpa_obj, path, if_obj) = prepare_dbus(dev[0]) 6249 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6250 6251 bssid = apdev[0]['bssid'] 6252 params = {"ssid": "test-hs20", "hessid": bssid, "wpa": "2", 6253 "rsn_pairwise": "CCMP", "wpa_key_mgmt": "WPA-EAP", 6254 "ieee80211w": "1", "ieee8021x": "1", 6255 "auth_server_addr": "127.0.0.1", "auth_server_port": "1812", 6256 "auth_server_shared_secret": "radius", "interworking": "1", 6257 "access_network_type": "14", "internet": "1", "asra": "0", 6258 "esr": "0", "uesa": "0", "venue_group": "7", "venue_type": "1", 6259 "venue_name": ["eng:Example venue", "fin:Esimerkkipaikka"], 6260 "roaming_consortium": ["112233", "1020304050", "010203040506", 6261 "fedcba"], "domain_name": "example.com,another.example.com", 6262 "nai_realm": ["0,example.com,13[5:6],21[2:4][5:7]", 6263 "0,another.example.com"], "hs20": "1", 6264 "hs20_wan_metrics": "01:8000:1000:80:240:3000", 6265 "hs20_conn_capab": ["1:0:2", "6:22:1", "17:5060:0"], 6266 "hs20_operating_class": "5173", "anqp_3gpp_cell_net": "244,91", 6267 "hs20_t_c_filename": "terms-and-conditions", 6268 "hs20_t_c_timestamp": "123456789"} 6269 6270 hapd = hostapd.add_ap(apdev[0], params) 6271 6272 class TestDbusInterworking(TestDbus): 6273 def __init__(self, bus): 6274 TestDbus.__init__(self, bus) 6275 self.hs20_t_and_c_seen = False 6276 6277 def __enter__(self): 6278 gobject.timeout_add(1, self.run_connect) 6279 gobject.timeout_add(15000, self.timeout) 6280 self.add_signal(self.hs20TermsAndConditions, WPAS_DBUS_IFACE, 6281 "HS20TermsAndConditions") 6282 self.loop.run() 6283 return self 6284 6285 def hs20TermsAndConditions(self, t_c_url): 6286 logger.debug("hs20TermsAndConditions: url=%s" % (t_c_url)) 6287 url = "https://example.com/t_and_c?addr=%s&ap=123" % dev[0].own_addr() 6288 if url in t_c_url: 6289 self.hs20_t_and_c_seen = True 6290 6291 def run_connect(self, *args): 6292 dev[0].hs20_enable() 6293 dev[0].connect("test-hs20", proto="RSN", key_mgmt="WPA-EAP", eap="TTLS", 6294 identity="hs20-t-c-test", password="password", 6295 ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2", 6296 ieee80211w='2', scan_freq="2412") 6297 return False 6298 6299 def success(self): 6300 return self.hs20_t_and_c_seen 6301 6302 with TestDbusInterworking(bus) as t: 6303 if not t.success(): 6304 raise Exception("Expected signals not seen") 6305 6306def test_dbus_anqp_get(dev, apdev): 6307 """D-Bus ANQP get test""" 6308 (bus, wpa_obj, path, if_obj) = prepare_dbus(dev[0]) 6309 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6310 6311 bssid = apdev[0]['bssid'] 6312 params = hs20_ap_params(ssid="test-anqp") 6313 params["hessid"] = bssid 6314 params['mbo'] = '1' 6315 params['mbo_cell_data_conn_pref'] = '1' 6316 params['hs20_oper_friendly_name'] = ["eng:Example operator", 6317 "fin:Esimerkkioperaattori"] 6318 hapd = hostapd.add_ap(apdev[0], params) 6319 6320 dev[0].flush_scan_cache() 6321 dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) 6322 iface.ANQPGet({"addr": bssid, 6323 "ids": dbus.Array([257], dbus.Signature("q")), 6324 "mbo_ids": dbus.Array([2], dbus.Signature("y")), 6325 "hs20_ids": dbus.Array([3, 4], dbus.Signature("y"))}) 6326 6327 ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10) 6328 if ev is None: 6329 raise Exception("GAS query timed out") 6330 6331 ev = dev[0].wait_event(["RX-ANQP"], timeout=1) 6332 if ev is None or "ANQP Capability list" not in ev: 6333 raise Exception("Did not receive Capability list") 6334 6335 ev = dev[0].wait_event(["RX-HS20-ANQP"], timeout=1) 6336 if ev is None or "Operator Friendly Name" not in ev: 6337 raise Exception("Did not receive Operator Friendly Name") 6338 6339 ev = dev[0].wait_event(["RX-MBO-ANQP"], timeout=1) 6340 if ev is None or "cell_conn_pref" not in ev: 6341 raise Exception("Did not receive MBO Cellular Data Connection Preference") 6342 6343 bss = dev[0].get_bss(bssid) 6344 if 'anqp_capability_list' not in bss: 6345 raise Exception("Capability List ANQP-element not seen") 6346 6347def test_dbus_anqp_query_done(dev, apdev): 6348 """D-Bus ANQP get test""" 6349 (bus, wpa_obj, path, if_obj) = prepare_dbus(dev[0]) 6350 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6351 6352 bssid = apdev[0]['bssid'] 6353 params = hs20_ap_params(ssid="test-anqp") 6354 params["hessid"] = bssid 6355 params['mbo'] = '1' 6356 params['mbo_cell_data_conn_pref'] = '1' 6357 params['hs20_oper_friendly_name'] = ["eng:Example operator", 6358 "fin:Esimerkkioperaattori"] 6359 hapd = hostapd.add_ap(apdev[0], params) 6360 6361 class TestDbusANQPGet(TestDbus): 6362 def __init__(self, bus): 6363 TestDbus.__init__(self, bus) 6364 self.anqp_query_done = False 6365 6366 def __enter__(self): 6367 gobject.timeout_add(1, self.run_query) 6368 gobject.timeout_add(15000, self.timeout) 6369 self.add_signal(self.anqpQueryDone, WPAS_DBUS_IFACE, 6370 "ANQPQueryDone") 6371 self.loop.run() 6372 return self 6373 6374 def anqpQueryDone(self, addr, result): 6375 logger.debug("anqpQueryDone: addr=%s result=%s" % (addr, result)) 6376 if addr == bssid and "SUCCESS" in result: 6377 self.anqp_query_done = True 6378 6379 def run_query(self, *args): 6380 dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) 6381 iface.ANQPGet({"addr": bssid, 6382 "ids": dbus.Array([257], dbus.Signature("q"))}) 6383 return False 6384 6385 def success(self): 6386 return self.anqp_query_done 6387 6388 with TestDbusANQPGet(bus) as t: 6389 if not t.success(): 6390 raise Exception("Expected signals not seen") 6391 6392def test_dbus_bss_anqp_properties(dev, apdev): 6393 """D-Bus ANQP BSS properties changed""" 6394 (bus, wpa_obj, path, if_obj) = prepare_dbus(dev[0]) 6395 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6396 6397 bssid = apdev[0]['bssid'] 6398 params = hs20_ap_params(ssid="test-anqp") 6399 params["hessid"] = bssid 6400 params['mbo'] = '1' 6401 params['mbo_cell_data_conn_pref'] = '1' 6402 params['hs20_oper_friendly_name'] = ["eng:Example operator", 6403 "fin:Esimerkkioperaattori"] 6404 hapd = hostapd.add_ap(apdev[0], params) 6405 6406 class TestDbusANQPBSSPropertiesChanged(TestDbus): 6407 def __init__(self, bus): 6408 TestDbus.__init__(self, bus) 6409 self.capability_list = False 6410 self.venue_name = False 6411 self.roaming_consortium = False 6412 self.nai_realm = False 6413 6414 def __enter__(self): 6415 gobject.timeout_add(1, self.run_query) 6416 gobject.timeout_add(15000, self.timeout) 6417 self.add_signal(self.propertiesChanged, WPAS_DBUS_BSS, 6418 "PropertiesChanged") 6419 self.loop.run() 6420 return self 6421 6422 def propertiesChanged(self, properties): 6423 logger.debug("propertiesChanged: %s" % str(properties)) 6424 if 'ANQP' in properties: 6425 anqp_properties = properties['ANQP'] 6426 self.capability_list = 'CapabilityList' in anqp_properties 6427 self.venue_name = 'VenueName' in anqp_properties 6428 self.roaming_consortium = 'RoamingConsortium' in anqp_properties 6429 self.nai_realm = 'NAIRealm' in anqp_properties 6430 6431 def run_query(self, *args): 6432 dev[0].scan_for_bss(bssid, freq="2412", force_scan=True) 6433 iface.ANQPGet({"addr": bssid, 6434 "ids": dbus.Array([257,258,261,263], dbus.Signature("q"))}) 6435 return False 6436 6437 def success(self): 6438 return self.capability_list and self.venue_name and self.roaming_consortium and self.nai_realm 6439 6440 with TestDbusANQPBSSPropertiesChanged(bus) as t: 6441 if not t.success(): 6442 raise Exception("Expected signals not seen") 6443 6444def test_dbus_nan_usd_publish(dev, apdev): 6445 """D-Bus NAN USD publish""" 6446 check_nan_usd_capab(dev[0]) 6447 (bus, wpa_obj, path, if_obj) = prepare_dbus(dev[0]) 6448 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6449 6450 class TestDbusNANUSD(TestDbus): 6451 def __init__(self, bus): 6452 TestDbus.__init__(self, bus) 6453 self.publish_terminated = False 6454 6455 def __enter__(self): 6456 gobject.timeout_add(1, self.start_publish) 6457 gobject.timeout_add(500, self.stop_publish) 6458 gobject.timeout_add(15000, self.timeout) 6459 self.add_signal(self.nanPublishTerminated, WPAS_DBUS_IFACE, 6460 "NANPublishTerminated") 6461 self.loop.run() 6462 return self 6463 6464 def nanPublishTerminated(self, publish_id, reason): 6465 logger.debug("nanPublishTerminated: %d %s" % (publish_id, reason)) 6466 if publish_id == self.publish_id: 6467 self.publish_terminated = True 6468 6469 def start_publish(self, *args): 6470 self.publish_id = iface.NANPublish({'srv_name': 'test service', 6471 'srv_proto_type': 2, 6472 'ssi': dbus.ByteArray(b'test')}) 6473 iface.NANUpdatePublish({'publish_id': self.publish_id, 6474 'ssi': dbus.ByteArray(b'new')}) 6475 return False 6476 6477 def stop_publish(self, *args): 6478 iface.NANCancelPublish(self.publish_id) 6479 return False 6480 6481 def success(self): 6482 return self.publish_terminated 6483 6484 with TestDbusNANUSD(bus) as t: 6485 if not t.success(): 6486 raise Exception("Expected signals not seen") 6487 6488def test_dbus_nan_usd_subscribe(dev, apdev): 6489 """D-Bus NAN USD subscribe""" 6490 check_nan_usd_capab(dev[0]) 6491 (bus, wpa_obj, path, if_obj) = prepare_dbus(dev[0]) 6492 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6493 6494 class TestDbusNANUSD(TestDbus): 6495 def __init__(self, bus): 6496 TestDbus.__init__(self, bus) 6497 self.subscribe_terminated = False 6498 6499 def __enter__(self): 6500 gobject.timeout_add(1, self.start_subscribe) 6501 gobject.timeout_add(500, self.stop_subscribe) 6502 gobject.timeout_add(15000, self.timeout) 6503 self.add_signal(self.nanSubscribeTerminated, WPAS_DBUS_IFACE, 6504 "NANSubscribeTerminated") 6505 self.loop.run() 6506 return self 6507 6508 def nanSubscribeTerminated(self, subscribe_id, reason): 6509 logger.debug("nanSubscribeTerminated: %d %s" % (subscribe_id, reason)) 6510 if subscribe_id == self.subscribe_id: 6511 self.subscribe_terminated = True 6512 self.loop.quit() 6513 6514 def start_subscribe(self, *args): 6515 self.subscribe_id = iface.NANSubscribe({'srv_name': 'test service', 6516 'srv_proto_type': 2, 6517 'ssi': dbus.ByteArray(b'test')}) 6518 return False 6519 6520 def stop_subscribe(self, *args): 6521 iface.NANCancelSubscribe(self.subscribe_id) 6522 return False 6523 6524 def success(self): 6525 return self.subscribe_terminated 6526 6527 with TestDbusNANUSD(bus) as t: 6528 if not t.success(): 6529 raise Exception("Expected signals not seen") 6530 6531def test_dbus_nan_usd_subscribe_followup(dev, apdev): 6532 """D-Bus NAN USD subscribe and followup""" 6533 check_nan_usd_capab(dev[0]) 6534 check_nan_usd_capab(dev[1]) 6535 (bus, wpa_obj, path, if_obj) = prepare_dbus(dev[0]) 6536 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6537 6538 class TestDbusNANUSD(TestDbus): 6539 def __init__(self, bus): 6540 TestDbus.__init__(self, bus) 6541 self.subscribe_terminated = False 6542 self.discovered = False 6543 self.followup = False 6544 6545 def __enter__(self): 6546 gobject.timeout_add(1, self.start_subscribe) 6547 gobject.timeout_add(15000, self.timeout) 6548 self.add_signal(self.nanDiscoveryResult, WPAS_DBUS_IFACE, 6549 "NANDiscoveryResult") 6550 self.add_signal(self.nanSubscribeTerminated, WPAS_DBUS_IFACE, 6551 "NANSubscribeTerminated") 6552 self.loop.run() 6553 return self 6554 6555 def nanDiscoveryResult(self, args): 6556 logger.debug("nanDiscoveryResult: %s" % str(args)) 6557 ssi = args['ssi'] 6558 publish_id = args['publish_id'] 6559 subscribe_id = args['subscribe_id'] 6560 peer_addr = args['peer_addr'] 6561 if publish_id == self.id1 and \ 6562 subscribe_id == self.subscribe_id and \ 6563 args['srv_proto_type'] == 3 and \ 6564 peer_addr == dev[1].own_addr() and \ 6565 len(ssi) == 2 and ssi[0] == 0x66 and ssi[1] == 0x77: 6566 self.discovered = True 6567 ev = dev[1].wait_event(["NAN-RECEIVE"], timeout=5) 6568 if ev is None: 6569 raise Exception("Automatically sent Follow-up message without ssi not seen") 6570 iface.NANTransmit({'handle': subscribe_id, 6571 'req_instance_id': publish_id, 6572 'peer_addr': peer_addr, 6573 'ssi': dbus.ByteArray(b'followup')}) 6574 ev = dev[1].wait_event(["NAN-RECEIVE"], timeout=5) 6575 if ev is None: 6576 raise Exception("Follow-up message not seen") 6577 if "ssi=666f6c6c6f777570" not in ev.split(' '): 6578 raise Exception("Expected SSI not seen in Follow-up") 6579 self.followup = True 6580 iface.NANCancelSubscribe(self.subscribe_id) 6581 else: 6582 logger.info("nanDiscoveryResult values did not match") 6583 6584 def nanSubscribeTerminated(self, subscribe_id, reason): 6585 logger.debug("nanSubscribeTerminated: %d %s" % (subscribe_id, reason)) 6586 if subscribe_id == self.subscribe_id: 6587 self.subscribe_terminated = True 6588 self.loop.quit() 6589 6590 def start_subscribe(self, *args): 6591 self.subscribe_id = iface.NANSubscribe({'srv_name': '_test', 6592 'srv_proto_type': 3, 6593 'ssi': dbus.ByteArray(b'test')}) 6594 6595 cmd = "NAN_PUBLISH service_name=_test srv_proto_type=3 ssi=6677 ttl=10" 6596 self.id1 = dev[1].request(cmd) 6597 if "FAIL" in self.id1: 6598 raise Exception("NAN_PUBLISH failed") 6599 self.id1 = int(self.id1) 6600 return False 6601 6602 def success(self): 6603 return self.subscribe_terminated and self.discovered and \ 6604 self.followup 6605 6606 with TestDbusNANUSD(bus) as t: 6607 if not t.success(): 6608 raise Exception("Expected signals not seen") 6609 6610def test_dbus_nan_usd_publish_followup(dev, apdev): 6611 """D-Bus NAN USD publish and followup""" 6612 check_nan_usd_capab(dev[0]) 6613 (bus, wpa_obj, path, if_obj) = prepare_dbus(dev[0]) 6614 iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) 6615 6616 class TestDbusNANUSD(TestDbus): 6617 def __init__(self, bus): 6618 TestDbus.__init__(self, bus) 6619 self.publish_terminated = False 6620 self.receive = False 6621 self.first_receive = True 6622 self.followup = False 6623 6624 def __enter__(self): 6625 gobject.timeout_add(1, self.start_publish) 6626 gobject.timeout_add(15000, self.timeout) 6627 self.add_signal(self.nanPublishTerminated, WPAS_DBUS_IFACE, 6628 "NANPublishTerminated") 6629 self.add_signal(self.nanReceive, WPAS_DBUS_IFACE, 6630 "NANReceive") 6631 self.loop.run() 6632 return self 6633 6634 def nanPublishTerminated(self, publish_id, reason): 6635 logger.debug("nanPublishTerminated: %d %s" % (publish_id, reason)) 6636 if publish_id == self.publish_id: 6637 self.publish_terminated = True 6638 self.loop.quit() 6639 6640 def nanReceive(self, args): 6641 logger.debug("nanReceive: %s" % str(args)) 6642 self.receive = True 6643 if self.first_receive: 6644 self.first_receive = False 6645 return 6646 ssi = args['ssi'] 6647 if len(ssi) == 2 and ssi[0] == 0x88 and ssi[1] == 0x99: 6648 self.followup = True 6649 iface.NANTransmit({'handle': args['id'], 6650 'req_instance_id': args['peer_id'], 6651 'peer_addr': args['peer_addr'], 6652 'ssi': dbus.ByteArray(b'followup')}) 6653 iface.NANCancelPublish(self.publish_id) 6654 6655 def start_publish(self, *args): 6656 cmd = "NAN_SUBSCRIBE service_name=_test srv_proto_type=3 ssi=1122334455" 6657 id1 = dev[1].request(cmd) 6658 if "FAIL" in id1: 6659 raise Exception("NAN_SUBSCRIBE failed") 6660 6661 self.publish_id = iface.NANPublish({'srv_name': '_test', 6662 'srv_proto_type': 2, 6663 'ssi': dbus.ByteArray(b'test')}) 6664 6665 ev = dev[1].wait_event(["NAN-DISCOVERY-RESULT"], timeout=10) 6666 if ev is None: 6667 raise Exception("DiscoveryResult event not seen") 6668 6669 vals = split_nan_event(ev) 6670 cmd = "NAN_TRANSMIT handle={} req_instance_id={} address={} ssi=8899".format(vals['subscribe_id'], vals['publish_id'], vals['address']) 6671 if "FAIL" in dev[1].request(cmd): 6672 raise Exception("NAN_TRANSMIT failed") 6673 6674 return False 6675 6676 def success(self): 6677 return self.publish_terminated and self.receive and self.followup 6678 6679 with TestDbusNANUSD(bus) as t: 6680 if not t.success(): 6681 raise Exception("Expected signals not seen") 6682