hostapd/tests/hwsim/test_dbus.py
Jouni Malinen fa34e3255e tests: Make test cases more robust by clearing scan cache explicitly
This test cases can fail if previously executed tests leave older scan
results in cfg80211 scan table. Clear that scan table explicitly to
avoid such issues.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
2022-02-26 19:12:11 +02:00

6209 lines
253 KiB
Python

# wpa_supplicant D-Bus interface tests
# Copyright (c) 2014-2015, Jouni Malinen <j@w1.fi>
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
import binascii
import logging
logger = logging.getLogger()
import subprocess
import time
import shutil
import struct
import sys
try:
if sys.version_info[0] > 2:
from gi.repository import GObject as gobject
else:
import gobject
import dbus
dbus_imported = True
except ImportError:
dbus_imported = False
import hostapd
from wpasupplicant import WpaSupplicant
from utils import *
from p2p_utils import *
from test_ap_tdls import connect_2sta_open
from test_ap_eap import check_altsubject_match_support
from test_nfc_p2p import set_ip_addr_info
from test_wpas_mesh import check_mesh_support, add_open_mesh_network
WPAS_DBUS_SERVICE = "fi.w1.wpa_supplicant1"
WPAS_DBUS_PATH = "/fi/w1/wpa_supplicant1"
WPAS_DBUS_IFACE = "fi.w1.wpa_supplicant1.Interface"
WPAS_DBUS_IFACE_WPS = WPAS_DBUS_IFACE + ".WPS"
WPAS_DBUS_NETWORK = "fi.w1.wpa_supplicant1.Network"
WPAS_DBUS_BSS = "fi.w1.wpa_supplicant1.BSS"
WPAS_DBUS_IFACE_P2PDEVICE = WPAS_DBUS_IFACE + ".P2PDevice"
WPAS_DBUS_P2P_PEER = "fi.w1.wpa_supplicant1.Peer"
WPAS_DBUS_GROUP = "fi.w1.wpa_supplicant1.Group"
WPAS_DBUS_PERSISTENT_GROUP = "fi.w1.wpa_supplicant1.PersistentGroup"
WPAS_DBUS_IFACE_MESH = WPAS_DBUS_IFACE + ".Mesh"
def prepare_dbus(dev):
if not dbus_imported:
logger.info("No dbus module available")
raise HwsimSkip("No dbus module available")
try:
from dbus.mainloop.glib import DBusGMainLoop
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH)
wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE)
path = wpas.GetInterface(dev.ifname)
if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
return (bus, wpas_obj, path, if_obj)
except Exception as e:
raise HwsimSkip("Could not connect to D-Bus: %s" % e)
class TestDbus(object):
def __init__(self, bus):
self.loop = gobject.MainLoop()
self.signals = []
self.bus = bus
def __exit__(self, type, value, traceback):
for s in self.signals:
s.remove()
def add_signal(self, handler, interface, name, byte_arrays=False):
s = self.bus.add_signal_receiver(handler, dbus_interface=interface,
signal_name=name,
byte_arrays=byte_arrays)
self.signals.append(s)
def timeout(self, *args):
logger.debug("timeout")
self.loop.quit()
return False
class alloc_fail_dbus(object):
def __init__(self, dev, count, funcs, operation="Operation",
expected="NoMemory"):
self._dev = dev
self._count = count
self._funcs = funcs
self._operation = operation
self._expected = expected
def __enter__(self):
cmd = "TEST_ALLOC_FAIL %d:%s" % (self._count, self._funcs)
if "OK" not in self._dev.request(cmd):
raise HwsimSkip("TEST_ALLOC_FAIL not supported")
def __exit__(self, type, value, traceback):
if type is None:
raise Exception("%s succeeded during out-of-memory" % self._operation)
if type == dbus.exceptions.DBusException and self._expected in str(value):
return True
if self._dev.request("GET_ALLOC_FAIL") != "0:%s" % self._funcs:
raise Exception("%s did not trigger allocation failure" % self._operation)
return False
def start_ap(ap, ssid="test-wps",
ap_uuid="27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"):
params = {"ssid": ssid, "eap_server": "1", "wps_state": "2",
"wpa_passphrase": "12345678", "wpa": "2",
"wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
"ap_pin": "12345670", "uuid": ap_uuid}
return hostapd.add_ap(ap, params)
def test_dbus_getall(dev, apdev):
"""D-Bus GetAll"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
dev[0].flush_scan_cache()
props = wpas_obj.GetAll(WPAS_DBUS_SERVICE,
dbus_interface=dbus.PROPERTIES_IFACE)
logger.debug("GetAll(fi.w1.wpa.supplicant1, /fi/w1/wpa_supplicant1) ==> " + str(props))
props = if_obj.GetAll(WPAS_DBUS_IFACE,
dbus_interface=dbus.PROPERTIES_IFACE)
logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_IFACE, path, str(props)))
props = if_obj.GetAll(WPAS_DBUS_IFACE_WPS,
dbus_interface=dbus.PROPERTIES_IFACE)
logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_IFACE_WPS, path, str(props)))
res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs',
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 0:
raise Exception("Unexpected BSSs entry: " + str(res))
res = if_obj.Get(WPAS_DBUS_IFACE, 'Networks',
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 0:
raise Exception("Unexpected Networks entry: " + str(res))
hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq=2412)
id = dev[0].add_network()
dev[0].set_network(id, "disabled", "0")
dev[0].set_network_quoted(id, "ssid", "test")
res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs',
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) < 1:
raise Exception("Missing BSSs entry: " + str(res))
if len(res) > 1:
raise Exception("Too manu BSSs entries: " + str(res))
bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
props = bss_obj.GetAll(WPAS_DBUS_BSS, dbus_interface=dbus.PROPERTIES_IFACE)
logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_BSS, res[0], str(props)))
bssid_str = ''
for item in props['BSSID']:
if len(bssid_str) > 0:
bssid_str += ':'
bssid_str += '%02x' % item
if bssid_str != bssid:
raise Exception("Unexpected BSSID in BSSs entry")
res = if_obj.Get(WPAS_DBUS_IFACE, 'Networks',
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 1:
raise Exception("Missing Networks entry: " + str(res))
net_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
props = net_obj.GetAll(WPAS_DBUS_NETWORK,
dbus_interface=dbus.PROPERTIES_IFACE)
logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_NETWORK, res[0], str(props)))
ssid = props['Properties']['ssid']
if ssid != '"test"':
raise Exception("Unexpected SSID in network entry")
def test_dbus_getall_oom(dev, apdev):
"""D-Bus GetAll wpa_config_get_all() OOM"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
id = dev[0].add_network()
dev[0].set_network(id, "disabled", "0")
dev[0].set_network_quoted(id, "ssid", "test")
res = if_obj.Get(WPAS_DBUS_IFACE, 'Networks',
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 1:
raise Exception("Missing Networks entry: " + str(res))
net_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
for i in range(1, 50):
with alloc_fail(dev[0], i, "wpa_config_get_all"):
try:
props = net_obj.GetAll(WPAS_DBUS_NETWORK,
dbus_interface=dbus.PROPERTIES_IFACE)
except dbus.exceptions.DBusException as e:
pass
def dbus_get(dbus, wpas_obj, prop, expect=None, byte_arrays=False):
val = wpas_obj.Get(WPAS_DBUS_SERVICE, prop,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=byte_arrays)
if expect is not None and val != expect:
raise Exception("Unexpected %s: %s (expected: %s)" %
(prop, str(val), str(expect)))
return val
def dbus_set(dbus, wpas_obj, prop, val):
wpas_obj.Set(WPAS_DBUS_SERVICE, prop, val,
dbus_interface=dbus.PROPERTIES_IFACE)
def test_dbus_properties(dev, apdev):
"""D-Bus Get/Set fi.w1.wpa_supplicant1 properties"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
dbus_get(dbus, wpas_obj, "DebugLevel", expect="msgdump")
dbus_set(dbus, wpas_obj, "DebugLevel", "debug")
dbus_get(dbus, wpas_obj, "DebugLevel", expect="debug")
for (val, err) in [(3, "Error.Failed: wrong property type"),
("foo", "Error.Failed: wrong debug level value")]:
try:
dbus_set(dbus, wpas_obj, "DebugLevel", val)
raise Exception("Invalid DebugLevel value accepted: " + str(val))
except dbus.exceptions.DBusException as e:
if err not in str(e):
raise Exception("Unexpected error message: " + str(e))
dbus_set(dbus, wpas_obj, "DebugLevel", "msgdump")
dbus_get(dbus, wpas_obj, "DebugLevel", expect="msgdump")
dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=True)
dbus_set(dbus, wpas_obj, "DebugTimestamp", False)
dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=False)
try:
dbus_set(dbus, wpas_obj, "DebugTimestamp", "foo")
raise Exception("Invalid DebugTimestamp value accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message: " + str(e))
dbus_set(dbus, wpas_obj, "DebugTimestamp", True)
dbus_get(dbus, wpas_obj, "DebugTimestamp", expect=True)
dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=True)
dbus_set(dbus, wpas_obj, "DebugShowKeys", False)
dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=False)
try:
dbus_set(dbus, wpas_obj, "DebugShowKeys", "foo")
raise Exception("Invalid DebugShowKeys value accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message: " + str(e))
dbus_set(dbus, wpas_obj, "DebugShowKeys", True)
dbus_get(dbus, wpas_obj, "DebugShowKeys", expect=True)
res = dbus_get(dbus, wpas_obj, "Interfaces")
if len(res) != 1:
raise Exception("Unexpected Interfaces value: " + str(res))
res = dbus_get(dbus, wpas_obj, "EapMethods")
if len(res) < 5 or "TTLS" not in res:
raise Exception("Unexpected EapMethods value: " + str(res))
res = dbus_get(dbus, wpas_obj, "Capabilities")
if len(res) < 2 or "p2p" not in res:
raise Exception("Unexpected Capabilities value: " + str(res))
dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True)
val = binascii.unhexlify("010006020304050608")
dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(val))
res = dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True)
if val != res:
raise Exception("WFDIEs value changed")
try:
dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(b'\x00'))
raise Exception("Invalid WFDIEs value accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message: " + str(e))
dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(b''))
dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(val))
dbus_set(dbus, wpas_obj, "WFDIEs", dbus.ByteArray(b''))
res = dbus_get(dbus, wpas_obj, "WFDIEs", byte_arrays=True)
if len(res) != 0:
raise Exception("WFDIEs not cleared properly")
res = dbus_get(dbus, wpas_obj, "EapMethods")
try:
dbus_set(dbus, wpas_obj, "EapMethods", res)
raise Exception("Invalid Set accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs: Property is read-only" not in str(e):
raise Exception("Unexpected error message: " + str(e))
try:
wpas_obj.SetFoo(WPAS_DBUS_SERVICE, "DebugShowKeys", True,
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Unknown method accepted")
except dbus.exceptions.DBusException as e:
if "UnknownMethod" not in str(e):
raise Exception("Unexpected error message: " + str(e))
try:
wpas_obj.Get("foo", "DebugShowKeys",
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Get accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs: No such property" not in str(e):
raise Exception("Unexpected error message: " + str(e))
test_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH,
introspect=False)
try:
test_obj.Get(123, "DebugShowKeys",
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Get accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs: Invalid arguments" not in str(e):
raise Exception("Unexpected error message: " + str(e))
try:
test_obj.Get(WPAS_DBUS_SERVICE, 123,
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Get accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs: Invalid arguments" not in str(e):
raise Exception("Unexpected error message: " + str(e))
try:
wpas_obj.Set(WPAS_DBUS_SERVICE, "WFDIEs",
dbus.ByteArray(b'', variant_level=2),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs: invalid message format" not in str(e):
raise Exception("Unexpected error message: " + str(e))
def test_dbus_set_global_properties(dev, apdev):
"""D-Bus Get/Set fi.w1.wpa_supplicant1 interface global properties"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
dev[0].set("model_name", "")
props = [('Okc', '0', '1'), ('ModelName', '', 'blahblahblah')]
for p in props:
res = if_obj.Get(WPAS_DBUS_IFACE, p[0],
dbus_interface=dbus.PROPERTIES_IFACE)
if res != p[1]:
raise Exception("Unexpected " + p[0] + " value: " + str(res))
if_obj.Set(WPAS_DBUS_IFACE, p[0], p[2],
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, p[0],
dbus_interface=dbus.PROPERTIES_IFACE)
if res != p[2]:
raise Exception("Unexpected " + p[0] + " value after set: " + str(res))
dev[0].set("model_name", "")
def test_dbus_invalid_method(dev, apdev):
"""D-Bus invalid method"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
try:
wps.Foo()
raise Exception("Unknown method accepted")
except dbus.exceptions.DBusException as e:
if "UnknownMethod" not in str(e):
raise Exception("Unexpected error message: " + str(e))
test_obj = bus.get_object(WPAS_DBUS_SERVICE, path, introspect=False)
test_wps = dbus.Interface(test_obj, WPAS_DBUS_IFACE_WPS)
try:
test_wps.Start(123)
raise Exception("WPS.Start with incorrect signature accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs: Invalid arg" not in str(e):
raise Exception("Unexpected error message: " + str(e))
def test_dbus_get_set_wps(dev, apdev):
"""D-Bus Get/Set for WPS properties"""
try:
_test_dbus_get_set_wps(dev, apdev)
finally:
dev[0].request("SET wps_cred_processing 0")
dev[0].request("SET config_methods display keypad virtual_display nfc_interface p2ps")
dev[0].set("device_name", "Device A")
dev[0].set("manufacturer", "")
dev[0].set("model_name", "")
dev[0].set("model_number", "")
dev[0].set("serial_number", "")
dev[0].set("device_type", "0-00000000-0")
def _test_dbus_get_set_wps(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods",
dbus_interface=dbus.PROPERTIES_IFACE)
val = "display keypad virtual_display nfc_interface"
dev[0].request("SET config_methods " + val)
config = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods",
dbus_interface=dbus.PROPERTIES_IFACE)
if config != val:
raise Exception("Unexpected Get(ConfigMethods) result: " + config)
val2 = "push_button display"
if_obj.Set(WPAS_DBUS_IFACE_WPS, "ConfigMethods", val2,
dbus_interface=dbus.PROPERTIES_IFACE)
config = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ConfigMethods",
dbus_interface=dbus.PROPERTIES_IFACE)
if config != val2:
raise Exception("Unexpected Get(ConfigMethods) result after Set: " + config)
dev[0].request("SET config_methods " + val)
for i in range(3):
dev[0].request("SET wps_cred_processing " + str(i))
val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
dbus_interface=dbus.PROPERTIES_IFACE)
expected_val = False if i == 1 else True
if val != expected_val:
raise Exception("Unexpected Get(ProcessCredentials) result({}): {}".format(i, val))
tests = [("device_name", "DeviceName"),
("manufacturer", "Manufacturer"),
("model_name", "ModelName"),
("model_number", "ModelNumber"),
("serial_number", "SerialNumber")]
for f1, f2 in tests:
val2 = "test-value-test"
dev[0].set(f1, val2)
val = if_obj.Get(WPAS_DBUS_IFACE_WPS, f2,
dbus_interface=dbus.PROPERTIES_IFACE)
if val != val2:
raise Exception("Get(%s) returned unexpected value" % f2)
val2 = "TEST-value"
if_obj.Set(WPAS_DBUS_IFACE_WPS, f2, val2,
dbus_interface=dbus.PROPERTIES_IFACE)
val = if_obj.Get(WPAS_DBUS_IFACE_WPS, f2,
dbus_interface=dbus.PROPERTIES_IFACE)
if val != val2:
raise Exception("Get(%s) returned unexpected value after Set" % f2)
dev[0].set("device_type", "5-0050F204-1")
val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "DeviceType",
dbus_interface=dbus.PROPERTIES_IFACE)
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:
raise Exception("DeviceType mismatch")
if_obj.Set(WPAS_DBUS_IFACE_WPS, "DeviceType", val,
dbus_interface=dbus.PROPERTIES_IFACE)
val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "DeviceType",
dbus_interface=dbus.PROPERTIES_IFACE)
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:
raise Exception("DeviceType mismatch after Set")
val2 = b'\x01\x02\x03\x04\x05\x06\x07\x08'
if_obj.Set(WPAS_DBUS_IFACE_WPS, "DeviceType", dbus.ByteArray(val2),
dbus_interface=dbus.PROPERTIES_IFACE)
val = if_obj.Get(WPAS_DBUS_IFACE_WPS, "DeviceType",
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
if val != val2:
raise Exception("DeviceType mismatch after Set (2)")
class TestDbusGetSet(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.signal_received = False
self.signal_received_deprecated = False
self.sets_done = False
def __enter__(self):
gobject.timeout_add(1, self.run_sets)
gobject.timeout_add(1000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE_WPS,
"PropertiesChanged")
self.add_signal(self.propertiesChanged2, dbus.PROPERTIES_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("PropertiesChanged: " + str(properties))
if "ProcessCredentials" in properties:
self.signal_received_deprecated = True
if self.sets_done and self.signal_received:
self.loop.quit()
def propertiesChanged2(self, interface_name, changed_properties,
invalidated_properties):
logger.debug("propertiesChanged2: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
if interface_name != WPAS_DBUS_IFACE_WPS:
return
if "ProcessCredentials" in changed_properties:
self.signal_received = True
if self.sets_done and self.signal_received_deprecated:
self.loop.quit()
def run_sets(self, *args):
logger.debug("run_sets")
if_obj.Set(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
dbus.Boolean(1),
dbus_interface=dbus.PROPERTIES_IFACE)
if if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
dbus_interface=dbus.PROPERTIES_IFACE) != True:
raise Exception("Unexpected Get(ProcessCredentials) result after Set")
if_obj.Set(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
dbus.Boolean(0),
dbus_interface=dbus.PROPERTIES_IFACE)
if if_obj.Get(WPAS_DBUS_IFACE_WPS, "ProcessCredentials",
dbus_interface=dbus.PROPERTIES_IFACE) != False:
raise Exception("Unexpected Get(ProcessCredentials) result after Set")
self.dbus_sets_done = True
return False
def success(self):
return self.signal_received and self.signal_received_deprecated
with TestDbusGetSet(bus) as t:
if not t.success():
raise Exception("No signal received for ProcessCredentials change")
def test_dbus_wps_invalid(dev, apdev):
"""D-Bus invaldi WPS operation"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
failures = [{'Role': 'foo', 'Type': 'pbc'},
{'Role': 123, 'Type': 'pbc'},
{'Type': 'pbc'},
{'Role': 'enrollee'},
{'Role': 'registrar'},
{'Role': 'enrollee', 'Type': 123},
{'Role': 'enrollee', 'Type': 'foo'},
{'Role': 'enrollee', 'Type': 'pbc',
'Bssid': '02:33:44:55:66:77'},
{'Role': 'enrollee', 'Type': 'pin', 'Pin': 123},
{'Role': 'enrollee', 'Type': 'pbc',
'Bssid': dbus.ByteArray(b'12345')},
{'Role': 'enrollee', 'Type': 'pbc',
'P2PDeviceAddress': 12345},
{'Role': 'enrollee', 'Type': 'pbc',
'P2PDeviceAddress': dbus.ByteArray(b'12345')},
{'Role': 'enrollee', 'Type': 'pbc', 'Foo': 'bar'}]
for args in failures:
try:
wps.Start(args)
raise Exception("Invalid WPS.Start() arguments accepted: " + str(args))
except dbus.exceptions.DBusException as e:
if not str(e).startswith("fi.w1.wpa_supplicant1.InvalidArgs"):
raise Exception("Unexpected error message: " + str(e))
def test_dbus_wps_oom(dev, apdev):
"""D-Bus WPS operation (OOM)"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_getter_state", "Get"):
if_obj.Get(WPAS_DBUS_IFACE, "State",
dbus_interface=dbus.PROPERTIES_IFACE)
hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq=2412)
time.sleep(0.05)
for i in range(1, 3):
with alloc_fail_dbus(dev[0], i, "=wpas_dbus_getter_bsss", "Get"):
if_obj.Get(WPAS_DBUS_IFACE, "BSSs",
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs',
dbus_interface=dbus.PROPERTIES_IFACE)
bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_getter_bss_rates", "Get"):
bss_obj.Get(WPAS_DBUS_BSS, "Rates",
dbus_interface=dbus.PROPERTIES_IFACE)
with alloc_fail(dev[0], 1,
"wpa_bss_get_bit_rates;wpas_dbus_getter_bss_rates"):
try:
bss_obj.Get(WPAS_DBUS_BSS, "Rates",
dbus_interface=dbus.PROPERTIES_IFACE)
except dbus.exceptions.DBusException as e:
pass
id = dev[0].add_network()
dev[0].set_network(id, "disabled", "0")
dev[0].set_network_quoted(id, "ssid", "test")
for i in range(1, 3):
with alloc_fail_dbus(dev[0], i, "=wpas_dbus_getter_networks", "Get"):
if_obj.Get(WPAS_DBUS_IFACE, "Networks",
dbus_interface=dbus.PROPERTIES_IFACE)
with alloc_fail_dbus(dev[0], 1, "wpas_dbus_getter_interfaces", "Get"):
dbus_get(dbus, wpas_obj, "Interfaces")
for i in range(1, 6):
with alloc_fail_dbus(dev[0], i, "=eap_get_names_as_string_array;wpas_dbus_getter_eap_methods", "Get"):
dbus_get(dbus, wpas_obj, "EapMethods")
with alloc_fail_dbus(dev[0], 1, "wpas_dbus_setter_config_methods", "Set",
expected="Error.Failed: Failed to set property"):
val2 = "push_button display"
if_obj.Set(WPAS_DBUS_IFACE_WPS, "ConfigMethods", val2,
dbus_interface=dbus.PROPERTIES_IFACE)
with alloc_fail_dbus(dev[0], 1, "=wpa_config_add_network;wpas_dbus_handler_wps_start",
"WPS.Start",
expected="UnknownError: WPS start failed"):
wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670'})
def test_dbus_wps_pbc(dev, apdev):
"""D-Bus WPS/PBC operation and signals"""
try:
_test_dbus_wps_pbc(dev, apdev)
finally:
dev[0].request("SET wps_cred_processing 0")
def _test_dbus_wps_pbc(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
hapd = start_ap(apdev[0])
hapd.request("WPS_PBC")
bssid = apdev[0]['bssid']
dev[0].flush_scan_cache()
dev[0].scan_for_bss(bssid, freq="2412")
dev[0].request("SET wps_cred_processing 2")
res = if_obj.Get(WPAS_DBUS_IFACE, 'BSSs',
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 1:
raise Exception("Missing BSSs entry: " + str(res))
bss_obj = bus.get_object(WPAS_DBUS_SERVICE, res[0])
props = bss_obj.GetAll(WPAS_DBUS_BSS, dbus_interface=dbus.PROPERTIES_IFACE)
logger.debug("GetAll(%s, %s): %s" % (WPAS_DBUS_BSS, res[0], str(props)))
if 'WPS' not in props:
raise Exception("No WPS information in the BSS entry")
if 'Type' not in props['WPS']:
raise Exception("No Type field in the WPS dictionary")
if props['WPS']['Type'] != 'pbc':
raise Exception("Unexpected WPS Type: " + props['WPS']['Type'])
class TestDbusWps(TestDbus):
def __init__(self, bus, wps):
TestDbus.__init__(self, bus)
self.success_seen = False
self.credentials_received = False
self.wps = wps
def __enter__(self):
gobject.timeout_add(1, self.start_pbc)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
"Credentials")
self.loop.run()
return self
def wpsEvent(self, name, args):
logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
if name == "success":
self.success_seen = True
if self.credentials_received:
self.loop.quit()
def credentials(self, args):
logger.debug("credentials: " + str(args))
self.credentials_received = True
if self.success_seen:
self.loop.quit()
def start_pbc(self, *args):
logger.debug("start_pbc")
self.wps.Start({'Role': 'enrollee', 'Type': 'pbc'})
return False
def success(self):
return self.success_seen and self.credentials_received
with TestDbusWps(bus, wps) as t:
if not t.success():
raise Exception("Failure in D-Bus operations")
dev[0].wait_connected(timeout=10)
dev[0].request("DISCONNECT")
hapd.disable()
dev[0].flush_scan_cache()
def test_dbus_wps_pbc_overlap(dev, apdev):
"""D-Bus WPS/PBC operation and signal for PBC overlap"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
hapd = start_ap(apdev[0])
hapd2 = start_ap(apdev[1], ssid="test-wps2",
ap_uuid="27ea801a-9e5c-4e73-bd82-f89cbcd10d7f")
hapd.request("WPS_PBC")
hapd2.request("WPS_PBC")
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq="2412")
bssid2 = apdev[1]['bssid']
dev[0].scan_for_bss(bssid2, freq="2412")
class TestDbusWps(TestDbus):
def __init__(self, bus, wps):
TestDbus.__init__(self, bus)
self.overlap_seen = False
self.wps = wps
def __enter__(self):
gobject.timeout_add(1, self.start_pbc)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
self.loop.run()
return self
def wpsEvent(self, name, args):
logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
if name == "pbc-overlap":
self.overlap_seen = True
self.loop.quit()
def start_pbc(self, *args):
logger.debug("start_pbc")
self.wps.Start({'Role': 'enrollee', 'Type': 'pbc'})
return False
def success(self):
return self.overlap_seen
with TestDbusWps(bus, wps) as t:
if not t.success():
raise Exception("Failure in D-Bus operations")
dev[0].request("WPS_CANCEL")
dev[0].request("DISCONNECT")
hapd.disable()
dev[0].flush_scan_cache()
def test_dbus_wps_pin(dev, apdev):
"""D-Bus WPS/PIN operation and signals"""
try:
_test_dbus_wps_pin(dev, apdev)
finally:
dev[0].request("SET wps_cred_processing 0")
def _test_dbus_wps_pin(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
hapd = start_ap(apdev[0])
hapd.request("WPS_PIN any 12345670")
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq="2412")
dev[0].request("SET wps_cred_processing 2")
class TestDbusWps(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.success_seen = False
self.credentials_received = False
def __enter__(self):
gobject.timeout_add(1, self.start_pin)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
"Credentials")
self.loop.run()
return self
def wpsEvent(self, name, args):
logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
if name == "success":
self.success_seen = True
if self.credentials_received:
self.loop.quit()
def credentials(self, args):
logger.debug("credentials: " + str(args))
self.credentials_received = True
if self.success_seen:
self.loop.quit()
def start_pin(self, *args):
logger.debug("start_pin")
bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode()))
wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670',
'Bssid': bssid_ay})
return False
def success(self):
return self.success_seen and self.credentials_received
with TestDbusWps(bus) as t:
if not t.success():
raise Exception("Failure in D-Bus operations")
dev[0].wait_connected(timeout=10)
def test_dbus_wps_pin2(dev, apdev):
"""D-Bus WPS/PIN operation and signals (PIN from wpa_supplicant)"""
try:
_test_dbus_wps_pin2(dev, apdev)
finally:
dev[0].request("SET wps_cred_processing 0")
def _test_dbus_wps_pin2(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
hapd = start_ap(apdev[0])
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq="2412")
dev[0].request("SET wps_cred_processing 2")
class TestDbusWps(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.success_seen = False
self.failed = False
def __enter__(self):
gobject.timeout_add(1, self.start_pin)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
"Credentials")
self.loop.run()
return self
def wpsEvent(self, name, args):
logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
if name == "success":
self.success_seen = True
if self.credentials_received:
self.loop.quit()
def credentials(self, args):
logger.debug("credentials: " + str(args))
self.credentials_received = True
if self.success_seen:
self.loop.quit()
def start_pin(self, *args):
logger.debug("start_pin")
bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode()))
res = wps.Start({'Role': 'enrollee', 'Type': 'pin',
'Bssid': bssid_ay})
pin = res['Pin']
h = hostapd.Hostapd(apdev[0]['ifname'])
h.request("WPS_PIN any " + pin)
return False
def success(self):
return self.success_seen and self.credentials_received
with TestDbusWps(bus) as t:
if not t.success():
raise Exception("Failure in D-Bus operations")
dev[0].wait_connected(timeout=10)
def test_dbus_wps_pin_m2d(dev, apdev):
"""D-Bus WPS/PIN operation and signals with M2D"""
try:
_test_dbus_wps_pin_m2d(dev, apdev)
finally:
dev[0].request("SET wps_cred_processing 0")
def _test_dbus_wps_pin_m2d(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
hapd = start_ap(apdev[0])
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq="2412")
dev[0].request("SET wps_cred_processing 2")
class TestDbusWps(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.success_seen = False
self.credentials_received = False
def __enter__(self):
gobject.timeout_add(1, self.start_pin)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
"Credentials")
self.loop.run()
return self
def wpsEvent(self, name, args):
logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
if name == "success":
self.success_seen = True
if self.credentials_received:
self.loop.quit()
elif name == "m2d":
h = hostapd.Hostapd(apdev[0]['ifname'])
h.request("WPS_PIN any 12345670")
def credentials(self, args):
logger.debug("credentials: " + str(args))
self.credentials_received = True
if self.success_seen:
self.loop.quit()
def start_pin(self, *args):
logger.debug("start_pin")
bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode()))
wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670',
'Bssid': bssid_ay})
return False
def success(self):
return self.success_seen and self.credentials_received
with TestDbusWps(bus) as t:
if not t.success():
raise Exception("Failure in D-Bus operations")
dev[0].wait_connected(timeout=10)
def test_dbus_wps_reg(dev, apdev):
"""D-Bus WPS/Registrar operation and signals"""
try:
_test_dbus_wps_reg(dev, apdev)
finally:
dev[0].request("SET wps_cred_processing 0")
def _test_dbus_wps_reg(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
hapd = start_ap(apdev[0])
hapd.request("WPS_PIN any 12345670")
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq="2412")
dev[0].request("SET wps_cred_processing 2")
class TestDbusWps(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.credentials_received = False
def __enter__(self):
gobject.timeout_add(100, self.start_reg)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.wpsEvent, WPAS_DBUS_IFACE_WPS, "Event")
self.add_signal(self.credentials, WPAS_DBUS_IFACE_WPS,
"Credentials")
self.loop.run()
return self
def wpsEvent(self, name, args):
logger.debug("wpsEvent: %s args='%s'" % (name, str(args)))
def credentials(self, args):
logger.debug("credentials: " + str(args))
self.credentials_received = True
self.loop.quit()
def start_reg(self, *args):
logger.debug("start_reg")
bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode()))
wps.Start({'Role': 'registrar', 'Type': 'pin',
'Pin': '12345670', 'Bssid': bssid_ay})
return False
def success(self):
return self.credentials_received
with TestDbusWps(bus) as t:
if not t.success():
raise Exception("Failure in D-Bus operations")
dev[0].wait_connected(timeout=10)
def test_dbus_wps_cancel(dev, apdev):
"""D-Bus WPS Cancel operation"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wps = dbus.Interface(if_obj, WPAS_DBUS_IFACE_WPS)
hapd = start_ap(apdev[0])
bssid = apdev[0]['bssid']
wps.Cancel()
dev[0].scan_for_bss(bssid, freq="2412")
bssid_ay = dbus.ByteArray(binascii.unhexlify(bssid.replace(':', '').encode()))
wps.Start({'Role': 'enrollee', 'Type': 'pin', 'Pin': '12345670',
'Bssid': bssid_ay})
wps.Cancel()
dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 1)
def test_dbus_scan_invalid(dev, apdev):
"""D-Bus invalid scan method"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
tests = [({}, "InvalidArgs"),
({'Type': 123}, "InvalidArgs"),
({'Type': 'foo'}, "InvalidArgs"),
({'Type': 'active', 'Foo': 'bar'}, "InvalidArgs"),
({'Type': 'active', 'SSIDs': 'foo'}, "InvalidArgs"),
({'Type': 'active', 'SSIDs': ['foo']}, "InvalidArgs"),
({'Type': 'active',
'SSIDs': [dbus.ByteArray(b"1"), dbus.ByteArray(b"2"),
dbus.ByteArray(b"3"), dbus.ByteArray(b"4"),
dbus.ByteArray(b"5"), dbus.ByteArray(b"6"),
dbus.ByteArray(b"7"), dbus.ByteArray(b"8"),
dbus.ByteArray(b"9"), dbus.ByteArray(b"10"),
dbus.ByteArray(b"11"), dbus.ByteArray(b"12"),
dbus.ByteArray(b"13"), dbus.ByteArray(b"14"),
dbus.ByteArray(b"15"), dbus.ByteArray(b"16"),
dbus.ByteArray(b"17")]},
"InvalidArgs"),
({'Type': 'active',
'SSIDs': [dbus.ByteArray(b"1234567890abcdef1234567890abcdef1")]},
"InvalidArgs"),
({'Type': 'active', 'IEs': 'foo'}, "InvalidArgs"),
({'Type': 'active', 'IEs': ['foo']}, "InvalidArgs"),
({'Type': 'active', 'Channels': 2412}, "InvalidArgs"),
({'Type': 'active', 'Channels': [2412]}, "InvalidArgs"),
({'Type': 'active',
'Channels': [(dbus.Int32(2412), dbus.UInt32(20))]},
"InvalidArgs"),
({'Type': 'active',
'Channels': [(dbus.UInt32(2412), dbus.Int32(20))]},
"InvalidArgs"),
({'Type': 'active', 'AllowRoam': "yes"}, "InvalidArgs"),
({'Type': 'passive', 'IEs': [dbus.ByteArray(b"\xdd\x00")]},
"InvalidArgs"),
({'Type': 'passive', 'SSIDs': [dbus.ByteArray(b"foo")]},
"InvalidArgs")]
for (t, err) in tests:
try:
iface.Scan(t)
raise Exception("Invalid Scan() arguments accepted: " + str(t))
except dbus.exceptions.DBusException as e:
if err not in str(e):
raise Exception("Unexpected error message for invalid Scan(%s): %s" % (str(t), str(e)))
def test_dbus_scan_oom(dev, apdev):
"""D-Bus scan method and OOM"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
with alloc_fail_dbus(dev[0], 1,
"wpa_scan_clone_params;wpas_dbus_handler_scan",
"Scan", expected="ScanError: Scan request rejected"):
iface.Scan({'Type': 'passive',
'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
with alloc_fail_dbus(dev[0], 1,
"=wpas_dbus_get_scan_channels;wpas_dbus_handler_scan",
"Scan"):
iface.Scan({'Type': 'passive',
'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
with alloc_fail_dbus(dev[0], 1,
"=wpas_dbus_get_scan_ies;wpas_dbus_handler_scan",
"Scan"):
iface.Scan({'Type': 'active',
'IEs': [dbus.ByteArray(b"\xdd\x00")],
'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
with alloc_fail_dbus(dev[0], 1,
"=wpas_dbus_get_scan_ssids;wpas_dbus_handler_scan",
"Scan"):
iface.Scan({'Type': 'active',
'SSIDs': [dbus.ByteArray(b"open"),
dbus.ByteArray()],
'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
def test_dbus_scan(dev, apdev):
"""D-Bus scan and related signals"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
class TestDbusScan(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.scan_completed = 0
self.bss_added = False
self.fail_reason = None
def __enter__(self):
gobject.timeout_add(1, self.run_scan)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.scanDone, WPAS_DBUS_IFACE, "ScanDone")
self.add_signal(self.bssAdded, WPAS_DBUS_IFACE, "BSSAdded")
self.add_signal(self.bssRemoved, WPAS_DBUS_IFACE, "BSSRemoved")
self.loop.run()
return self
def scanDone(self, success):
logger.debug("scanDone: success=%s" % success)
self.scan_completed += 1
if self.scan_completed == 1:
iface.Scan({'Type': 'passive',
'AllowRoam': True,
'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
elif self.scan_completed == 2:
iface.Scan({'Type': 'passive',
'AllowRoam': False})
elif self.bss_added and self.scan_completed == 3:
self.loop.quit()
def bssAdded(self, bss, properties):
logger.debug("bssAdded: %s" % bss)
logger.debug(str(properties))
if 'WPS' in properties:
if 'Type' in properties['WPS']:
self.fail_reason = "Unexpected WPS dictionary entry in non-WPS BSS"
self.loop.quit()
self.bss_added = True
if self.scan_completed == 3:
self.loop.quit()
def bssRemoved(self, bss):
logger.debug("bssRemoved: %s" % bss)
def run_scan(self, *args):
logger.debug("run_scan")
iface.Scan({'Type': 'active',
'SSIDs': [dbus.ByteArray(b"open"),
dbus.ByteArray()],
'IEs': [dbus.ByteArray(b"\xdd\x00"),
dbus.ByteArray()],
'AllowRoam': False,
'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
return False
def success(self):
return self.scan_completed == 3 and self.bss_added
with TestDbusScan(bus) as t:
if t.fail_reason:
raise Exception(t.fail_reason)
if not t.success():
raise Exception("Expected signals not seen")
res = if_obj.Get(WPAS_DBUS_IFACE, "BSSs",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) < 1:
raise Exception("Scan result not in BSSs property")
iface.FlushBSS(0)
res = if_obj.Get(WPAS_DBUS_IFACE, "BSSs",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 0:
raise Exception("FlushBSS() did not remove scan results from BSSs property")
iface.FlushBSS(1)
def test_dbus_scan_rand(dev, apdev):
"""D-Bus MACAddressRandomizationMask property Get/Set"""
try:
run_dbus_scan_rand(dev, apdev)
finally:
dev[0].request("MAC_RAND_SCAN all enable=0")
def run_dbus_scan_rand(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 0:
logger.info(str(res))
raise Exception("Unexpected initial MACAddressRandomizationMask value")
try:
if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask", "foo",
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs: invalid message format" not in str(e):
raise Exception("Unexpected error message: " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
{"foo": "bar"},
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set accepted")
except dbus.exceptions.DBusException as e:
if "wpas_dbus_setter_mac_address_randomization_mask: mask was not a byte array" not in str(e):
raise Exception("Unexpected error message: " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
{"foo": dbus.ByteArray(b'123456')},
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set accepted")
except dbus.exceptions.DBusException as e:
if 'wpas_dbus_setter_mac_address_randomization_mask: bad scan type "foo"' not in str(e):
raise Exception("Unexpected error message: " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
{"scan": dbus.ByteArray(b'12345')},
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set accepted")
except dbus.exceptions.DBusException as e:
if 'wpas_dbus_setter_mac_address_randomization_mask: malformed MAC mask given' not in str(e):
raise Exception("Unexpected error message: " + str(e))
if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
{"scan": dbus.ByteArray(b'123456')},
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 1:
logger.info(str(res))
raise Exception("Unexpected MACAddressRandomizationMask value")
try:
if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
{"scan": dbus.ByteArray(b'123456'),
"sched_scan": dbus.ByteArray(b'987654')},
dbus_interface=dbus.PROPERTIES_IFACE)
except dbus.exceptions.DBusException as e:
# sched_scan is unlikely to be supported
pass
if_obj.Set(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
dbus.Dictionary({}, signature='sv'),
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "MACAddressRandomizationMask",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 0:
logger.info(str(res))
raise Exception("Unexpected MACAddressRandomizationMask value")
def test_dbus_scan_busy(dev, apdev):
"""D-Bus scan trigger rejection when busy with previous scan"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
if "OK" not in dev[0].request("SCAN freq=2412-2462"):
raise Exception("Failed to start scan")
ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], 15)
if ev is None:
raise Exception("Scan start timed out")
try:
iface.Scan({'Type': 'active', 'AllowRoam': False})
raise Exception("Scan() accepted when busy")
except dbus.exceptions.DBusException as e:
if "ScanError: Scan request reject" not in str(e):
raise Exception("Unexpected error message: " + str(e))
ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
if ev is None:
raise Exception("Scan timed out")
def test_dbus_scan_abort(dev, apdev):
"""D-Bus scan trigger and abort"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
iface.Scan({'Type': 'active', 'AllowRoam': False})
ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], 15)
if ev is None:
raise Exception("Scan start timed out")
iface.AbortScan()
ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
if ev is None:
raise Exception("Scan abort result timed out")
dev[0].dump_monitor()
iface.Scan({'Type': 'active', 'AllowRoam': False})
iface.AbortScan()
ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
if ev is None:
raise Exception("Scan timed out")
def test_dbus_connect(dev, apdev):
"""D-Bus AddNetwork and connect"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "test-wpa2-psk"
passphrase = 'qwertyuiop'
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
hapd = hostapd.add_ap(apdev[0], params)
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.network_added = False
self.network_selected = False
self.network_removed = False
self.state = 0
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded")
self.add_signal(self.networkRemoved, WPAS_DBUS_IFACE,
"NetworkRemoved")
self.add_signal(self.networkSelected, WPAS_DBUS_IFACE,
"NetworkSelected")
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def networkAdded(self, network, properties):
logger.debug("networkAdded: %s" % str(network))
logger.debug(str(properties))
self.network_added = True
def networkRemoved(self, network):
logger.debug("networkRemoved: %s" % str(network))
self.network_removed = True
def networkSelected(self, network):
logger.debug("networkSelected: %s" % str(network))
self.network_selected = True
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
if self.state == 0:
self.state = 1
iface.Disconnect()
elif self.state == 2:
self.state = 3
iface.Disconnect()
elif self.state == 4:
self.state = 5
iface.Reattach()
elif self.state == 5:
self.state = 6
iface.Disconnect()
elif self.state == 7:
self.state = 8
res = iface.SignalPoll()
logger.debug("SignalPoll: " + str(res))
if 'frequency' not in res or res['frequency'] != 2412:
self.state = -1
logger.info("Unexpected SignalPoll result")
iface.RemoveNetwork(self.netw)
if 'State' in properties and properties['State'] == "disconnected":
if self.state == 1:
self.state = 2
iface.SelectNetwork(self.netw)
elif self.state == 3:
self.state = 4
iface.Reassociate()
elif self.state == 6:
self.state = 7
iface.Reconnect()
elif self.state == 8:
self.state = 9
self.loop.quit()
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'WPA-PSK',
'psk': passphrase,
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
if not self.network_added or \
not self.network_removed or \
not self.network_selected:
return False
return self.state == 9
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_remove_connected(dev, apdev):
"""D-Bus RemoveAllNetworks while connected"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "test-open"
hapd = hostapd.add_ap(apdev[0], {"ssid": ssid})
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.network_added = False
self.network_selected = False
self.network_removed = False
self.state = 0
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded")
self.add_signal(self.networkRemoved, WPAS_DBUS_IFACE,
"NetworkRemoved")
self.add_signal(self.networkSelected, WPAS_DBUS_IFACE,
"NetworkSelected")
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def networkAdded(self, network, properties):
logger.debug("networkAdded: %s" % str(network))
logger.debug(str(properties))
self.network_added = True
def networkRemoved(self, network):
logger.debug("networkRemoved: %s" % str(network))
self.network_removed = True
def networkSelected(self, network):
logger.debug("networkSelected: %s" % str(network))
self.network_selected = True
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
if self.state == 0:
self.state = 1
iface.Disconnect()
elif self.state == 2:
self.state = 3
iface.Disconnect()
elif self.state == 4:
self.state = 5
iface.Reattach()
elif self.state == 5:
self.state = 6
iface.Disconnect()
elif self.state == 7:
self.state = 8
res = iface.SignalPoll()
logger.debug("SignalPoll: " + str(res))
if 'frequency' not in res or res['frequency'] != 2412:
self.state = -1
logger.info("Unexpected SignalPoll result")
iface.RemoveAllNetworks()
if 'State' in properties and properties['State'] == "disconnected":
if self.state == 1:
self.state = 2
iface.SelectNetwork(self.netw)
elif self.state == 3:
self.state = 4
iface.Reassociate()
elif self.state == 6:
self.state = 7
iface.Reconnect()
elif self.state == 8:
self.state = 9
self.loop.quit()
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'NONE',
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
if not self.network_added or \
not self.network_removed or \
not self.network_selected:
return False
return self.state == 9
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_connect_psk_mem(dev, apdev):
"""D-Bus AddNetwork and connect with memory-only PSK"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "test-wpa2-psk"
passphrase = 'qwertyuiop'
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
hapd = hostapd.add_ap(apdev[0], params)
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.connected = False
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.add_signal(self.networkRequest, WPAS_DBUS_IFACE,
"NetworkRequest")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
self.connected = True
self.loop.quit()
def networkRequest(self, path, field, txt):
logger.debug("networkRequest: %s %s %s" % (path, field, txt))
if field == "PSK_PASSPHRASE":
iface.NetworkReply(path, field, '"' + passphrase + '"')
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'WPA-PSK',
'mem_only_psk': 1,
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
return self.connected
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_connect_oom(dev, apdev):
"""D-Bus AddNetwork and connect when out-of-memory"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
if "OK" not in dev[0].request("TEST_ALLOC_FAIL 0:"):
raise HwsimSkip("TEST_ALLOC_FAIL not supported in the build")
ssid = "test-wpa2-psk"
passphrase = 'qwertyuiop'
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
hapd = hostapd.add_ap(apdev[0], params)
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.network_added = False
self.network_selected = False
self.network_removed = False
self.state = 0
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(1500, self.timeout)
self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded")
self.add_signal(self.networkRemoved, WPAS_DBUS_IFACE,
"NetworkRemoved")
self.add_signal(self.networkSelected, WPAS_DBUS_IFACE,
"NetworkSelected")
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def networkAdded(self, network, properties):
logger.debug("networkAdded: %s" % str(network))
logger.debug(str(properties))
self.network_added = True
def networkRemoved(self, network):
logger.debug("networkRemoved: %s" % str(network))
self.network_removed = True
def networkSelected(self, network):
logger.debug("networkSelected: %s" % str(network))
self.network_selected = True
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
if self.state == 0:
self.state = 1
iface.Disconnect()
elif self.state == 2:
self.state = 3
iface.Disconnect()
elif self.state == 4:
self.state = 5
iface.Reattach()
elif self.state == 5:
self.state = 6
res = iface.SignalPoll()
logger.debug("SignalPoll: " + str(res))
if 'frequency' not in res or res['frequency'] != 2412:
self.state = -1
logger.info("Unexpected SignalPoll result")
iface.RemoveNetwork(self.netw)
if 'State' in properties and properties['State'] == "disconnected":
if self.state == 1:
self.state = 2
iface.SelectNetwork(self.netw)
elif self.state == 3:
self.state = 4
iface.Reassociate()
elif self.state == 6:
self.state = 7
self.loop.quit()
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'WPA-PSK',
'psk': passphrase,
'scan_freq': 2412},
signature='sv')
try:
self.netw = iface.AddNetwork(args)
except Exception as e:
logger.info("Exception on AddNetwork: " + str(e))
self.loop.quit()
return False
try:
iface.SelectNetwork(self.netw)
except Exception as e:
logger.info("Exception on SelectNetwork: " + str(e))
self.loop.quit()
return False
def success(self):
if not self.network_added or \
not self.network_removed or \
not self.network_selected:
return False
return self.state == 7
count = 0
for i in range(1, 1000):
for j in range(3):
dev[j].dump_monitor()
dev[0].request("TEST_ALLOC_FAIL %d:main" % i)
try:
with TestDbusConnect(bus) as t:
if not t.success():
logger.info("Iteration %d - Expected signals not seen" % i)
else:
logger.info("Iteration %d - success" % i)
state = dev[0].request('GET_ALLOC_FAIL')
logger.info("GET_ALLOC_FAIL: " + state)
dev[0].dump_monitor()
dev[0].request("TEST_ALLOC_FAIL 0:")
if i < 3:
raise Exception("Connection succeeded during out-of-memory")
if not state.startswith('0:'):
count += 1
if count == 5:
break
except:
pass
# Force regulatory update to re-fetch hw capabilities for the following
# test cases.
try:
dev[0].dump_monitor()
subprocess.call(['iw', 'reg', 'set', 'US'])
ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
finally:
dev[0].dump_monitor()
subprocess.call(['iw', 'reg', 'set', '00'])
ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
def test_dbus_while_not_connected(dev, apdev):
"""D-Bus invalid operations while not connected"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
try:
iface.Disconnect()
raise Exception("Disconnect() accepted when not connected")
except dbus.exceptions.DBusException as e:
if "NotConnected" not in str(e):
raise Exception("Unexpected error message for invalid Disconnect: " + str(e))
try:
iface.Reattach()
raise Exception("Reattach() accepted when not connected")
except dbus.exceptions.DBusException as e:
if "NotConnected" not in str(e):
raise Exception("Unexpected error message for invalid Reattach: " + str(e))
def test_dbus_connect_eap(dev, apdev):
"""D-Bus AddNetwork and connect to EAP network"""
check_altsubject_match_support(dev[0])
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "ieee8021x-open"
params = hostapd.radius_params()
params["ssid"] = ssid
params["ieee8021x"] = "1"
hapd = hostapd.add_ap(apdev[0], params)
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.certification_received = False
self.eap_status = False
self.state = 0
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.add_signal(self.certification, WPAS_DBUS_IFACE,
"Certification", byte_arrays=True)
self.add_signal(self.networkRequest, WPAS_DBUS_IFACE,
"NetworkRequest")
self.add_signal(self.eap, WPAS_DBUS_IFACE, "EAP")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
if self.state == 0:
self.state = 1
iface.EAPLogoff()
logger.info("Set dNSName constraint")
net_obj = bus.get_object(WPAS_DBUS_SERVICE, self.netw)
args = dbus.Dictionary({'altsubject_match':
self.server_dnsname},
signature='sv')
net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args,
dbus_interface=dbus.PROPERTIES_IFACE)
elif self.state == 2:
self.state = 3
iface.Disconnect()
logger.info("Set non-matching dNSName constraint")
net_obj = bus.get_object(WPAS_DBUS_SERVICE, self.netw)
args = dbus.Dictionary({'altsubject_match':
self.server_dnsname + "FOO"},
signature='sv')
net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args,
dbus_interface=dbus.PROPERTIES_IFACE)
if 'State' in properties and properties['State'] == "disconnected":
if self.state == 1:
self.state = 2
iface.EAPLogon()
iface.SelectNetwork(self.netw)
if self.state == 3:
self.state = 4
iface.SelectNetwork(self.netw)
def certification(self, args):
logger.debug("certification: %s" % str(args))
self.certification_received = True
if args['depth'] == 0:
# The test server certificate is supposed to have dNSName
if len(args['altsubject']) < 1:
raise Exception("Missing dNSName")
dnsname = args['altsubject'][0]
if not dnsname.startswith("DNS:"):
raise Exception("Expected dNSName not found: " + dnsname)
logger.info("altsubject: " + dnsname)
self.server_dnsname = dnsname
def eap(self, status, parameter):
logger.debug("EAP: status=%s parameter=%s" % (status, parameter))
if status == 'completion' and parameter == 'success':
self.eap_status = True
if self.state == 4 and status == 'remote certificate verification' and parameter == 'AltSubject mismatch':
self.state = 5
self.loop.quit()
def networkRequest(self, path, field, txt):
logger.debug("networkRequest: %s %s %s" % (path, field, txt))
if field == "PASSWORD":
iface.NetworkReply(path, field, "password")
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'IEEE8021X',
'eapol_flags': 0,
'eap': 'TTLS',
'anonymous_identity': 'ttls',
'identity': 'pap user',
'ca_cert': 'auth_serv/ca.pem',
'phase2': 'auth=PAP',
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
if not self.eap_status or not self.certification_received:
return False
return self.state == 5
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_network(dev, apdev):
"""D-Bus AddNetwork/RemoveNetwork parameters and error cases"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
args = dbus.Dictionary({'ssid': "foo",
'key_mgmt': 'WPA-PSK',
'psk': "12345678",
'identity': dbus.ByteArray([1, 2]),
'priority': dbus.Int32(0),
'scan_freq': dbus.UInt32(2412)},
signature='sv')
netw = iface.AddNetwork(args)
id = int(dev[0].list_networks()[0]['id'])
val = dev[0].get_network(id, "scan_freq")
if val != "2412":
raise Exception("Invalid scan_freq value: " + str(val))
iface.RemoveNetwork(netw)
args = dbus.Dictionary({'ssid': "foo",
'key_mgmt': 'NONE',
'scan_freq': "2412 2432",
'freq_list': "2412 2417 2432"},
signature='sv')
netw = iface.AddNetwork(args)
id = int(dev[0].list_networks()[0]['id'])
val = dev[0].get_network(id, "scan_freq")
if val != "2412 2432":
raise Exception("Invalid scan_freq value (2): " + str(val))
val = dev[0].get_network(id, "freq_list")
if val != "2412 2417 2432":
raise Exception("Invalid freq_list value: " + str(val))
iface.RemoveNetwork(netw)
try:
iface.RemoveNetwork(netw)
raise Exception("Invalid RemoveNetwork() accepted")
except dbus.exceptions.DBusException as e:
if "NetworkUnknown" not in str(e):
raise Exception("Unexpected error message for invalid RemoveNetwork: " + str(e))
try:
iface.SelectNetwork(netw)
raise Exception("Invalid SelectNetwork() accepted")
except dbus.exceptions.DBusException as e:
if "NetworkUnknown" not in str(e):
raise Exception("Unexpected error message for invalid RemoveNetwork: " + str(e))
args = dbus.Dictionary({'ssid': "foo1", 'key_mgmt': 'NONE',
'identity': "testuser", 'scan_freq': '2412'},
signature='sv')
netw1 = iface.AddNetwork(args)
args = dbus.Dictionary({'ssid': "foo2", 'key_mgmt': 'NONE'},
signature='sv')
netw2 = iface.AddNetwork(args)
res = if_obj.Get(WPAS_DBUS_IFACE, "Networks",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 2:
raise Exception("Unexpected number of networks")
net_obj = bus.get_object(WPAS_DBUS_SERVICE, netw1)
res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != False:
raise Exception("Added network was unexpectedly enabled by default")
net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.Boolean(True),
dbus_interface=dbus.PROPERTIES_IFACE)
res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != True:
raise Exception("Set(Enabled,True) did not seem to change property value")
net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.Boolean(False),
dbus_interface=dbus.PROPERTIES_IFACE)
res = net_obj.Get(WPAS_DBUS_NETWORK, "Enabled",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != False:
raise Exception("Set(Enabled,False) did not seem to change property value")
try:
net_obj.Set(WPAS_DBUS_NETWORK, "Enabled", dbus.UInt32(1),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(Enabled,1) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message for invalid Set(Enabled,1): " + str(e))
args = dbus.Dictionary({'ssid': "foo1new"}, signature='sv')
net_obj.Set(WPAS_DBUS_NETWORK, "Properties", args,
dbus_interface=dbus.PROPERTIES_IFACE)
res = net_obj.Get(WPAS_DBUS_NETWORK, "Properties",
dbus_interface=dbus.PROPERTIES_IFACE)
if res['ssid'] != '"foo1new"':
raise Exception("Set(Properties) failed to update ssid")
if res['identity'] != '"testuser"':
raise Exception("Set(Properties) unexpectedly changed unrelated parameter")
iface.RemoveAllNetworks()
res = if_obj.Get(WPAS_DBUS_IFACE, "Networks",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != 0:
raise Exception("Unexpected number of networks")
iface.RemoveAllNetworks()
tests = [dbus.Dictionary({'psk': "1234567"}, signature='sv'),
dbus.Dictionary({'identity': dbus.ByteArray()},
signature='sv'),
dbus.Dictionary({'identity': dbus.Byte(1)}, signature='sv')]
for args in tests:
try:
iface.AddNetwork(args)
raise Exception("Invalid AddNetwork args accepted: " + str(args))
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid AddNetwork: " + str(e))
def test_dbus_network_oom(dev, apdev):
"""D-Bus AddNetwork/RemoveNetwork parameters and OOM error cases"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
args = dbus.Dictionary({'ssid': "foo1", 'key_mgmt': 'NONE',
'identity': "testuser", 'scan_freq': '2412'},
signature='sv')
netw1 = iface.AddNetwork(args)
net_obj = bus.get_object(WPAS_DBUS_SERVICE, netw1)
with alloc_fail_dbus(dev[0], 1,
"wpa_config_get_all;wpas_dbus_getter_network_properties",
"Get"):
net_obj.Get(WPAS_DBUS_NETWORK, "Properties",
dbus_interface=dbus.PROPERTIES_IFACE)
iface.RemoveAllNetworks()
with alloc_fail_dbus(dev[0], 1,
"wpas_dbus_new_decompose_object_path;wpas_dbus_handler_remove_network",
"RemoveNetwork", "InvalidArgs"):
iface.RemoveNetwork(dbus.ObjectPath("/fi/w1/wpa_supplicant1/Interfaces/1234/Networks/1234"))
with alloc_fail(dev[0], 1, "wpa_dbus_register_object_per_iface;wpas_dbus_register_network"):
args = dbus.Dictionary({'ssid': "foo2", 'key_mgmt': 'NONE'},
signature='sv')
try:
netw = iface.AddNetwork(args)
# Currently, AddNetwork() succeeds even if os_strdup() for path
# fails, so remove the network if that occurs.
iface.RemoveNetwork(netw)
except dbus.exceptions.DBusException as e:
pass
for i in range(1, 3):
with alloc_fail(dev[0], i, "=wpas_dbus_register_network"):
try:
netw = iface.AddNetwork(args)
# Currently, AddNetwork() succeeds even if network registration
# fails, so remove the network if that occurs.
iface.RemoveNetwork(netw)
except dbus.exceptions.DBusException as e:
pass
with alloc_fail_dbus(dev[0], 1,
"=wpa_config_add_network;wpas_dbus_handler_add_network",
"AddNetwork",
"UnknownError: wpa_supplicant could not add a network"):
args = dbus.Dictionary({'ssid': "foo2", 'key_mgmt': 'NONE'},
signature='sv')
netw = iface.AddNetwork(args)
tests = [(1,
'wpa_dbus_dict_get_entry;set_network_properties;wpas_dbus_handler_add_network',
dbus.Dictionary({'ssid': dbus.ByteArray(b' ')},
signature='sv')),
(1, '=set_network_properties;wpas_dbus_handler_add_network',
dbus.Dictionary({'ssid': 'foo'}, signature='sv')),
(1, '=set_network_properties;wpas_dbus_handler_add_network',
dbus.Dictionary({'eap': 'foo'}, signature='sv')),
(1, '=set_network_properties;wpas_dbus_handler_add_network',
dbus.Dictionary({'priority': dbus.UInt32(1)},
signature='sv')),
(1, '=set_network_properties;wpas_dbus_handler_add_network',
dbus.Dictionary({'priority': dbus.Int32(1)},
signature='sv')),
(1, '=set_network_properties;wpas_dbus_handler_add_network',
dbus.Dictionary({'ssid': dbus.ByteArray(b' ')},
signature='sv'))]
for (count, funcs, args) in tests:
with alloc_fail_dbus(dev[0], count, funcs, "AddNetwork", "InvalidArgs"):
netw = iface.AddNetwork(args)
if len(if_obj.Get(WPAS_DBUS_IFACE, 'Networks',
dbus_interface=dbus.PROPERTIES_IFACE)) > 0:
raise Exception("Unexpected network block added")
if len(dev[0].list_networks()) > 0:
raise Exception("Unexpected network block visible")
def test_dbus_interface(dev, apdev):
"""D-Bus CreateInterface/GetInterface/RemoveInterface parameters and error cases"""
try:
_test_dbus_interface(dev, apdev)
finally:
# Need to force P2P channel list update since the 'lo' interface
# with driver=none ends up configuring default dualband channels.
dev[0].request("SET country US")
ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
if ev is None:
ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"],
timeout=1)
dev[0].request("SET country 00")
ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
if ev is None:
ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"],
timeout=1)
subprocess.call(['iw', 'reg', 'set', '00'])
def _test_dbus_interface(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE)
params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none'},
signature='sv')
path = wpas.CreateInterface(params)
logger.debug("New interface path: " + str(path))
path2 = wpas.GetInterface("lo")
if path != path2:
raise Exception("Interface object mismatch")
params = dbus.Dictionary({'Ifname': 'lo',
'Driver': 'none',
'ConfigFile': 'foo',
'BridgeIfname': 'foo',},
signature='sv')
try:
wpas.CreateInterface(params)
raise Exception("Invalid CreateInterface() accepted")
except dbus.exceptions.DBusException as e:
if "InterfaceExists" not in str(e):
raise Exception("Unexpected error message for invalid CreateInterface: " + str(e))
wpas.RemoveInterface(path)
try:
wpas.RemoveInterface(path)
raise Exception("Invalid RemoveInterface() accepted")
except dbus.exceptions.DBusException as e:
if "InterfaceUnknown" not in str(e):
raise Exception("Unexpected error message for invalid RemoveInterface: " + str(e))
params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none',
'Foo': 123},
signature='sv')
try:
wpas.CreateInterface(params)
raise Exception("Invalid CreateInterface() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid CreateInterface: " + str(e))
params = dbus.Dictionary({'Driver': 'none'}, signature='sv')
try:
wpas.CreateInterface(params)
raise Exception("Invalid CreateInterface() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid CreateInterface: " + str(e))
try:
wpas.GetInterface("lo")
raise Exception("Invalid GetInterface() accepted")
except dbus.exceptions.DBusException as e:
if "InterfaceUnknown" not in str(e):
raise Exception("Unexpected error message for invalid RemoveInterface: " + str(e))
def test_dbus_interface_oom(dev, apdev):
"""D-Bus CreateInterface/GetInterface/RemoveInterface OOM error cases"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE)
with alloc_fail_dbus(dev[0], 1, "wpa_dbus_dict_get_entry;wpas_dbus_handler_create_interface", "CreateInterface", "InvalidArgs"):
params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none'},
signature='sv')
wpas.CreateInterface(params)
for i in range(1, 1000):
dev[0].request("TEST_ALLOC_FAIL %d:wpa_supplicant_add_iface;wpas_dbus_handler_create_interface" % i)
params = dbus.Dictionary({'Ifname': 'lo', 'Driver': 'none'},
signature='sv')
try:
npath = wpas.CreateInterface(params)
wpas.RemoveInterface(npath)
logger.info("CreateInterface succeeds after %d allocation failures" % i)
state = dev[0].request('GET_ALLOC_FAIL')
logger.info("GET_ALLOC_FAIL: " + state)
dev[0].dump_monitor()
dev[0].request("TEST_ALLOC_FAIL 0:")
if i < 5:
raise Exception("CreateInterface succeeded during out-of-memory")
if not state.startswith('0:'):
break
except dbus.exceptions.DBusException as e:
pass
for arg in ['Driver', 'Ifname', 'ConfigFile', 'BridgeIfname']:
with alloc_fail_dbus(dev[0], 1, "=wpas_dbus_handler_create_interface",
"CreateInterface"):
params = dbus.Dictionary({arg: 'foo'}, signature='sv')
wpas.CreateInterface(params)
def test_dbus_blob(dev, apdev):
"""D-Bus AddNetwork/RemoveNetwork parameters and error cases"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
blob = dbus.ByteArray(b"\x01\x02\x03")
iface.AddBlob('blob1', blob)
try:
iface.AddBlob('blob1', dbus.ByteArray(b"\x01\x02\x04"))
raise Exception("Invalid AddBlob() accepted")
except dbus.exceptions.DBusException as e:
if "BlobExists" not in str(e):
raise Exception("Unexpected error message for invalid AddBlob: " + str(e))
res = iface.GetBlob('blob1')
if len(res) != len(blob):
raise Exception("Unexpected blob data length")
for i in range(len(res)):
if res[i] != dbus.Byte(blob[i]):
raise Exception("Unexpected blob data")
res = if_obj.Get(WPAS_DBUS_IFACE, "Blobs",
dbus_interface=dbus.PROPERTIES_IFACE)
if 'blob1' not in res:
raise Exception("Added blob missing from Blobs property")
iface.RemoveBlob('blob1')
try:
iface.RemoveBlob('blob1')
raise Exception("Invalid RemoveBlob() accepted")
except dbus.exceptions.DBusException as e:
if "BlobUnknown" not in str(e):
raise Exception("Unexpected error message for invalid RemoveBlob: " + str(e))
try:
iface.GetBlob('blob1')
raise Exception("Invalid GetBlob() accepted")
except dbus.exceptions.DBusException as e:
if "BlobUnknown" not in str(e):
raise Exception("Unexpected error message for invalid GetBlob: " + str(e))
class TestDbusBlob(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.blob_added = False
self.blob_removed = False
def __enter__(self):
gobject.timeout_add(1, self.run_blob)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.blobAdded, WPAS_DBUS_IFACE, "BlobAdded")
self.add_signal(self.blobRemoved, WPAS_DBUS_IFACE, "BlobRemoved")
self.loop.run()
return self
def blobAdded(self, blobName):
logger.debug("blobAdded: %s" % blobName)
if blobName == 'blob2':
self.blob_added = True
def blobRemoved(self, blobName):
logger.debug("blobRemoved: %s" % blobName)
if blobName == 'blob2':
self.blob_removed = True
self.loop.quit()
def run_blob(self, *args):
logger.debug("run_blob")
iface.AddBlob('blob2', dbus.ByteArray(b"\x01\x02\x04"))
iface.RemoveBlob('blob2')
return False
def success(self):
return self.blob_added and self.blob_removed
with TestDbusBlob(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_blob_oom(dev, apdev):
"""D-Bus AddNetwork/RemoveNetwork OOM error cases"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
for i in range(1, 4):
with alloc_fail_dbus(dev[0], i, "wpas_dbus_handler_add_blob",
"AddBlob"):
iface.AddBlob('blob_no_mem', dbus.ByteArray(b"\x01\x02\x03\x04"))
def test_dbus_autoscan(dev, apdev):
"""D-Bus Autoscan()"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
iface.AutoScan("foo")
iface.AutoScan("periodic:1")
iface.AutoScan("")
dev[0].request("AUTOSCAN ")
def test_dbus_autoscan_oom(dev, apdev):
"""D-Bus Autoscan() OOM"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
with alloc_fail_dbus(dev[0], 1, "wpas_dbus_handler_autoscan", "AutoScan"):
iface.AutoScan("foo")
dev[0].request("AUTOSCAN ")
def test_dbus_tdls_invalid(dev, apdev):
"""D-Bus invalid TDLS operations"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"})
connect_2sta_open(dev, hapd)
addr1 = dev[1].p2p_interface_addr()
try:
iface.TDLSDiscover("foo")
raise Exception("Invalid TDLSDiscover() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid TDLSDiscover: " + str(e))
try:
iface.TDLSStatus("foo")
raise Exception("Invalid TDLSStatus() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid TDLSStatus: " + str(e))
res = iface.TDLSStatus(addr1)
if res != "peer does not exist":
raise Exception("Unexpected TDLSStatus response")
try:
iface.TDLSSetup("foo")
raise Exception("Invalid TDLSSetup() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid TDLSSetup: " + str(e))
try:
iface.TDLSTeardown("foo")
raise Exception("Invalid TDLSTeardown() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid TDLSTeardown: " + str(e))
try:
iface.TDLSTeardown("00:11:22:33:44:55")
raise Exception("TDLSTeardown accepted for unknown peer")
except dbus.exceptions.DBusException as e:
if "UnknownError: error performing TDLS teardown" not in str(e):
raise Exception("Unexpected error message: " + str(e))
try:
iface.TDLSChannelSwitch({})
raise Exception("Invalid TDLSChannelSwitch() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid TDLSChannelSwitch: " + str(e))
try:
iface.TDLSCancelChannelSwitch("foo")
raise Exception("Invalid TDLSCancelChannelSwitch() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid TDLSCancelChannelSwitch: " + str(e))
def test_dbus_tdls_oom(dev, apdev):
"""D-Bus TDLS operations during OOM"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
with alloc_fail_dbus(dev[0], 1, "wpa_tdls_add_peer", "TDLSSetup",
"UnknownError: error performing TDLS setup"):
iface.TDLSSetup("00:11:22:33:44:55")
def test_dbus_tdls(dev, apdev):
"""D-Bus TDLS"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"})
connect_2sta_open(dev, hapd)
addr1 = dev[1].p2p_interface_addr()
class TestDbusTdls(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.tdls_setup = False
self.tdls_teardown = False
def __enter__(self):
gobject.timeout_add(1, self.run_tdls)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
def run_tdls(self, *args):
logger.debug("run_tdls")
iface.TDLSDiscover(addr1)
gobject.timeout_add(100, self.run_tdls2)
return False
def run_tdls2(self, *args):
logger.debug("run_tdls2")
iface.TDLSSetup(addr1)
gobject.timeout_add(500, self.run_tdls3)
return False
def run_tdls3(self, *args):
logger.debug("run_tdls3")
res = iface.TDLSStatus(addr1)
if res == "connected":
self.tdls_setup = True
else:
logger.info("Unexpected TDLSStatus: " + res)
iface.TDLSTeardown(addr1)
gobject.timeout_add(200, self.run_tdls4)
return False
def run_tdls4(self, *args):
logger.debug("run_tdls4")
res = iface.TDLSStatus(addr1)
if res == "peer does not exist":
self.tdls_teardown = True
else:
logger.info("Unexpected TDLSStatus: " + res)
self.loop.quit()
return False
def success(self):
return self.tdls_setup and self.tdls_teardown
with TestDbusTdls(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_tdls_channel_switch(dev, apdev):
"""D-Bus TDLS channel switch configuration"""
flags = int(dev[0].get_driver_status_field('capa.flags'), 16)
if flags & 0x800000000 == 0:
raise HwsimSkip("Driver does not support TDLS channel switching")
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
hapd = hostapd.add_ap(apdev[0], {"ssid": "test-open"})
connect_2sta_open(dev, hapd)
addr1 = dev[1].p2p_interface_addr()
class TestDbusTdls(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.tdls_setup = False
self.tdls_done = False
def __enter__(self):
gobject.timeout_add(1, self.run_tdls)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
def run_tdls(self, *args):
logger.debug("run_tdls")
iface.TDLSDiscover(addr1)
gobject.timeout_add(100, self.run_tdls2)
return False
def run_tdls2(self, *args):
logger.debug("run_tdls2")
iface.TDLSSetup(addr1)
gobject.timeout_add(500, self.run_tdls3)
return False
def run_tdls3(self, *args):
logger.debug("run_tdls3")
res = iface.TDLSStatus(addr1)
if res == "connected":
self.tdls_setup = True
else:
logger.info("Unexpected TDLSStatus: " + res)
# Unknown dict entry
args = dbus.Dictionary({'Foobar': dbus.Byte(1)},
signature='sv')
try:
iface.TDLSChannelSwitch(args)
except Exception as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected exception")
# Missing OperClass
args = dbus.Dictionary({}, signature='sv')
try:
iface.TDLSChannelSwitch(args)
except Exception as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected exception")
# Missing Frequency
args = dbus.Dictionary({'OperClass': dbus.Byte(1)},
signature='sv')
try:
iface.TDLSChannelSwitch(args)
except Exception as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected exception")
# Missing PeerAddress
args = dbus.Dictionary({'OperClass': dbus.Byte(1),
'Frequency': dbus.UInt32(2417)},
signature='sv')
try:
iface.TDLSChannelSwitch(args)
except Exception as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected exception")
# Valid parameters
args = dbus.Dictionary({'OperClass': dbus.Byte(1),
'Frequency': dbus.UInt32(2417),
'PeerAddress': addr1,
'SecChannelOffset': dbus.UInt32(0),
'CenterFrequency1': dbus.UInt32(0),
'CenterFrequency2': dbus.UInt32(0),
'Bandwidth': dbus.UInt32(20),
'HT': dbus.Boolean(False),
'VHT': dbus.Boolean(False)},
signature='sv')
iface.TDLSChannelSwitch(args)
gobject.timeout_add(200, self.run_tdls4)
return False
def run_tdls4(self, *args):
logger.debug("run_tdls4")
iface.TDLSCancelChannelSwitch(addr1)
self.tdls_done = True
self.loop.quit()
return False
def success(self):
return self.tdls_setup and self.tdls_done
with TestDbusTdls(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_pkcs11(dev, apdev):
"""D-Bus SetPKCS11EngineAndModulePath()"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
try:
iface.SetPKCS11EngineAndModulePath("foo", "bar")
except dbus.exceptions.DBusException as e:
if "Error.Failed: Reinit of the EAPOL" not in str(e):
raise Exception("Unexpected error message for invalid SetPKCS11EngineAndModulePath: " + str(e))
try:
iface.SetPKCS11EngineAndModulePath("foo", "")
except dbus.exceptions.DBusException as e:
if "Error.Failed: Reinit of the EAPOL" not in str(e):
raise Exception("Unexpected error message for invalid SetPKCS11EngineAndModulePath: " + str(e))
iface.SetPKCS11EngineAndModulePath("", "bar")
res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11EnginePath",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != "":
raise Exception("Unexpected PKCS11EnginePath value: " + res)
res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11ModulePath",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != "bar":
raise Exception("Unexpected PKCS11ModulePath value: " + res)
iface.SetPKCS11EngineAndModulePath("", "")
res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11EnginePath",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != "":
raise Exception("Unexpected PKCS11EnginePath value: " + res)
res = if_obj.Get(WPAS_DBUS_IFACE, "PKCS11ModulePath",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != "":
raise Exception("Unexpected PKCS11ModulePath value: " + res)
def test_dbus_apscan(dev, apdev):
"""D-Bus Get/Set ApScan"""
try:
_test_dbus_apscan(dev, apdev)
finally:
dev[0].request("AP_SCAN 1")
def _test_dbus_apscan(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
res = if_obj.Get(WPAS_DBUS_IFACE, "ApScan",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != 1:
raise Exception("Unexpected initial ApScan value: %d" % res)
for i in range(3):
if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(i),
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "ApScan",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != i:
raise Exception("Unexpected ApScan value %d (expected %d)" % (res, i))
try:
if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.Int16(-1),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(ApScan,-1) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message for invalid Set(ApScan,-1): " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(123),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(ApScan,123) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: ap_scan must be 0, 1, or 2" not in str(e):
raise Exception("Unexpected error message for invalid Set(ApScan,123): " + str(e))
if_obj.Set(WPAS_DBUS_IFACE, "ApScan", dbus.UInt32(1),
dbus_interface=dbus.PROPERTIES_IFACE)
def test_dbus_pmf(dev, apdev):
"""D-Bus Get/Set Pmf"""
try:
_test_dbus_pmf(dev, apdev)
finally:
dev[0].request("SET pmf 0")
def _test_dbus_pmf(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
dev[0].set("pmf", "0")
res = if_obj.Get(WPAS_DBUS_IFACE, "Pmf",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != "0":
raise Exception("Unexpected initial Pmf value: %s" % res)
for i in range(3):
if_obj.Set(WPAS_DBUS_IFACE, "Pmf", str(i),
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "Pmf",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != str(i):
raise Exception("Unexpected Pmf value %s (expected %d)" % (res, i))
if_obj.Set(WPAS_DBUS_IFACE, "Pmf", "1",
dbus_interface=dbus.PROPERTIES_IFACE)
def test_dbus_fastreauth(dev, apdev):
"""D-Bus Get/Set FastReauth"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
res = if_obj.Get(WPAS_DBUS_IFACE, "FastReauth",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != True:
raise Exception("Unexpected initial FastReauth value: " + str(res))
for i in [False, True]:
if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Boolean(i),
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "FastReauth",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != i:
raise Exception("Unexpected FastReauth value %d (expected %d)" % (res, i))
try:
if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Int16(-1),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(FastReauth,-1) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message for invalid Set(ApScan,-1): " + str(e))
if_obj.Set(WPAS_DBUS_IFACE, "FastReauth", dbus.Boolean(True),
dbus_interface=dbus.PROPERTIES_IFACE)
def test_dbus_bss_expire(dev, apdev):
"""D-Bus Get/Set BSSExpireAge and BSSExpireCount"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(179),
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "BSSExpireAge",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != 179:
raise Exception("Unexpected BSSExpireAge value %d (expected %d)" % (res, i))
if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(3),
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "BSSExpireCount",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != 3:
raise Exception("Unexpected BSSExpireCount value %d (expected %d)" % (res, i))
try:
if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.Int16(-1),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(BSSExpireAge,-1) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message for invalid Set(BSSExpireAge,-1): " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(9),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(BSSExpireAge,9) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: BSSExpireAge must be >= 10" not in str(e):
raise Exception("Unexpected error message for invalid Set(BSSExpireAge,9): " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.Int16(-1),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(BSSExpireCount,-1) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message for invalid Set(BSSExpireCount,-1): " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(0),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(BSSExpireCount,0) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: BSSExpireCount must be > 0" not in str(e):
raise Exception("Unexpected error message for invalid Set(BSSExpireCount,0): " + str(e))
if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireAge", dbus.UInt32(180),
dbus_interface=dbus.PROPERTIES_IFACE)
if_obj.Set(WPAS_DBUS_IFACE, "BSSExpireCount", dbus.UInt32(2),
dbus_interface=dbus.PROPERTIES_IFACE)
def test_dbus_country(dev, apdev):
"""D-Bus Get/Set Country"""
try:
_test_dbus_country(dev, apdev)
finally:
dev[0].request("SET country 00")
subprocess.call(['iw', 'reg', 'set', '00'])
def _test_dbus_country(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
# work around issues with possible pending regdom event from the end of
# the previous test case
time.sleep(0.2)
dev[0].dump_monitor()
if_obj.Set(WPAS_DBUS_IFACE, "Country", "FI",
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "Country",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != "FI":
raise Exception("Unexpected Country value %s (expected FI)" % res)
ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"])
if ev is None:
# For now, work around separate P2P Device interface event delivery
ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
if ev is None:
raise Exception("regdom change event not seen")
if "init=USER type=COUNTRY alpha2=FI" not in ev:
raise Exception("Unexpected event contents: " + ev)
try:
if_obj.Set(WPAS_DBUS_IFACE, "Country", dbus.Int16(-1),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(Country,-1) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message for invalid Set(Country,-1): " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "Country", "F",
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(Country,F) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: invalid country code" not in str(e):
raise Exception("Unexpected error message for invalid Set(Country,F): " + str(e))
if_obj.Set(WPAS_DBUS_IFACE, "Country", "00",
dbus_interface=dbus.PROPERTIES_IFACE)
ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"])
if ev is None:
# For now, work around separate P2P Device interface event delivery
ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1)
if ev is None:
raise Exception("regdom change event not seen")
# init=CORE was previously used due to invalid db.txt data for 00. For
# now, allow both it and the new init=USER after fixed db.txt.
if "init=CORE type=WORLD" not in ev and "init=USER type=WORLD" not in ev:
raise Exception("Unexpected event contents: " + ev)
def test_dbus_scan_interval(dev, apdev):
"""D-Bus Get/Set ScanInterval"""
try:
_test_dbus_scan_interval(dev, apdev)
finally:
dev[0].request("SCAN_INTERVAL 5")
def _test_dbus_scan_interval(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(3),
dbus_interface=dbus.PROPERTIES_IFACE)
res = if_obj.Get(WPAS_DBUS_IFACE, "ScanInterval",
dbus_interface=dbus.PROPERTIES_IFACE)
if res != 3:
raise Exception("Unexpected ScanInterval value %d (expected %d)" % (res, i))
try:
if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.UInt16(100),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(ScanInterval,100) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: wrong property type" not in str(e):
raise Exception("Unexpected error message for invalid Set(ScanInterval,100): " + str(e))
try:
if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(-1),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(ScanInterval,-1) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: scan_interval must be >= 0" not in str(e):
raise Exception("Unexpected error message for invalid Set(ScanInterval,-1): " + str(e))
if_obj.Set(WPAS_DBUS_IFACE, "ScanInterval", dbus.Int32(5),
dbus_interface=dbus.PROPERTIES_IFACE)
def test_dbus_probe_req_reporting(dev, apdev):
"""D-Bus Probe Request reporting"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
dev[1].p2p_find(social=True)
class TestDbusProbe(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.reported = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.probeRequest, WPAS_DBUS_IFACE, "ProbeRequest",
byte_arrays=True)
self.loop.run()
return self
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
self.iface = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE)
self.iface.SubscribeProbeReq()
self.group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
def probeRequest(self, args):
logger.debug("probeRequest: args=%s" % str(args))
self.reported = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
params = dbus.Dictionary({'frequency': 2412})
p2p.GroupAdd(params)
return False
def success(self):
return self.reported
with TestDbusProbe(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
t.iface.UnsubscribeProbeReq()
try:
t.iface.UnsubscribeProbeReq()
raise Exception("Invalid UnsubscribeProbeReq() accepted")
except dbus.exceptions.DBusException as e:
if "NoSubscription" not in str(e):
raise Exception("Unexpected error message for invalid UnsubscribeProbeReq(): " + str(e))
t.group_p2p.Disconnect()
with TestDbusProbe(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
# On purpose, leave ProbeReq subscription in place to test automatic
# cleanup.
dev[1].p2p_stop_find()
def test_dbus_probe_req_reporting_oom(dev, apdev):
"""D-Bus Probe Request reporting (OOM)"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
# Need to make sure this process has not already subscribed to avoid false
# failures due to the operation succeeding due to os_strdup() not even
# getting called.
try:
iface.UnsubscribeProbeReq()
was_subscribed = True
except dbus.exceptions.DBusException as e:
was_subscribed = False
pass
with alloc_fail_dbus(dev[0], 1, "wpas_dbus_handler_subscribe_preq",
"SubscribeProbeReq"):
iface.SubscribeProbeReq()
if was_subscribed:
# On purpose, leave ProbeReq subscription in place to test automatic
# cleanup.
iface.SubscribeProbeReq()
def test_dbus_p2p_invalid(dev, apdev):
"""D-Bus invalid P2P operations"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
try:
p2p.RejectPeer(path + "/Peers/00112233445566")
raise Exception("Invalid RejectPeer accepted")
except dbus.exceptions.DBusException as e:
if "UnknownError: Failed to call wpas_p2p_reject" not in str(e):
raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e))
try:
p2p.RejectPeer("/foo")
raise Exception("Invalid RejectPeer accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e))
tests = [{},
{'peer': 'foo'},
{'foo': "bar"},
{'iface': "abc"},
{'iface': 123}]
for t in tests:
try:
p2p.RemoveClient(t)
raise Exception("Invalid RemoveClient accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid RemoveClient(): " + str(e))
tests = [{'DiscoveryType': 'foo'},
{'RequestedDeviceTypes': 'foo'},
{'RequestedDeviceTypes': ['foo']},
{'RequestedDeviceTypes': ['1', '2', '3', '4', '5', '6', '7', '8',
'9', '10', '11', '12', '13', '14', '15',
'16', '17']},
{'RequestedDeviceTypes': dbus.Array([], signature="s")},
{'RequestedDeviceTypes': dbus.Array([['foo']], signature="as")},
{'RequestedDeviceTypes': dbus.Array([], signature="i")},
{'RequestedDeviceTypes': [dbus.ByteArray(b'12345678'),
dbus.ByteArray(b'1234567')]},
{'Foo': dbus.Int16(1)},
{'Foo': dbus.UInt16(1)},
{'Foo': dbus.Int64(1)},
{'Foo': dbus.UInt64(1)},
{'Foo': dbus.Double(1.23)},
{'Foo': dbus.Signature('s')},
{'Foo': 'bar'}]
for t in tests:
try:
p2p.Find(dbus.Dictionary(t))
raise Exception("Invalid Find accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid Find(): " + str(e))
for p in ["/foo",
"/fi/w1/wpa_supplicant1/Interfaces/1234",
"/fi/w1/wpa_supplicant1/Interfaces/1234/Networks/1234"]:
try:
p2p.RemovePersistentGroup(dbus.ObjectPath(p))
raise Exception("Invalid RemovePersistentGroup accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid RemovePersistentGroup: " + str(e))
try:
dev[0].request("P2P_SET disabled 1")
p2p.Listen(5)
raise Exception("Invalid Listen accepted")
except dbus.exceptions.DBusException as e:
if "UnknownError: Could not start P2P listen" not in str(e):
raise Exception("Unexpected error message for invalid Listen: " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
test_obj = bus.get_object(WPAS_DBUS_SERVICE, path, introspect=False)
test_p2p = dbus.Interface(test_obj, WPAS_DBUS_IFACE_P2PDEVICE)
try:
test_p2p.Listen("foo")
raise Exception("Invalid Listen accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid Listen: " + str(e))
try:
dev[0].request("P2P_SET disabled 1")
p2p.ExtendedListen(dbus.Dictionary({}))
raise Exception("Invalid ExtendedListen accepted")
except dbus.exceptions.DBusException as e:
if "UnknownError: failed to initiate a p2p_ext_listen" not in str(e):
raise Exception("Unexpected error message for invalid ExtendedListen: " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
try:
dev[0].request("P2P_SET disabled 1")
args = {'duration1': 30000, 'interval1': 102400,
'duration2': 20000, 'interval2': 102400}
p2p.PresenceRequest(args)
raise Exception("Invalid PresenceRequest accepted")
except dbus.exceptions.DBusException as e:
if "UnknownError: Failed to invoke presence request" not in str(e):
raise Exception("Unexpected error message for invalid PresenceRequest: " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
try:
params = dbus.Dictionary({'frequency': dbus.Int32(-1)})
p2p.GroupAdd(params)
raise Exception("Invalid GroupAdd accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid GroupAdd: " + str(e))
try:
params = dbus.Dictionary({'persistent_group_object':
dbus.ObjectPath(path),
'frequency': 2412})
p2p.GroupAdd(params)
raise Exception("Invalid GroupAdd accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid GroupAdd: " + str(e))
try:
p2p.Disconnect()
raise Exception("Invalid Disconnect accepted")
except dbus.exceptions.DBusException as e:
if "UnknownError: failed to disconnect" not in str(e):
raise Exception("Unexpected error message for invalid Disconnect: " + str(e))
try:
dev[0].request("P2P_SET disabled 1")
p2p.Flush()
raise Exception("Invalid Flush accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: P2P is not available for this interface" not in str(e):
raise Exception("Unexpected error message for invalid Flush: " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
try:
dev[0].request("P2P_SET disabled 1")
args = {'peer': path,
'join': True,
'wps_method': 'pbc',
'frequency': 2412}
pin = p2p.Connect(args)
raise Exception("Invalid Connect accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: P2P is not available for this interface" not in str(e):
raise Exception("Unexpected error message for invalid Connect: " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
tests = [{'frequency': dbus.Int32(-1)},
{'wps_method': 'pbc'},
{'wps_method': 'foo'}]
for args in tests:
try:
pin = p2p.Connect(args)
raise Exception("Invalid Connect accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid Connect: " + str(e))
try:
dev[0].request("P2P_SET disabled 1")
args = {'peer': path}
pin = p2p.Invite(args)
raise Exception("Invalid Invite accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: P2P is not available for this interface" not in str(e):
raise Exception("Unexpected error message for invalid Invite: " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
try:
args = {'foo': 'bar'}
pin = p2p.Invite(args)
raise Exception("Invalid Invite accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid Connect: " + str(e))
tests = [(path, 'display', "InvalidArgs"),
(dbus.ObjectPath(path + "/Peers/00112233445566"),
'display',
"UnknownError: Failed to send provision discovery request"),
(dbus.ObjectPath(path + "/Peers/00112233445566"),
'keypad',
"UnknownError: Failed to send provision discovery request"),
(dbus.ObjectPath(path + "/Peers/00112233445566"),
'pbc',
"UnknownError: Failed to send provision discovery request"),
(dbus.ObjectPath(path + "/Peers/00112233445566"),
'pushbutton',
"UnknownError: Failed to send provision discovery request"),
(dbus.ObjectPath(path + "/Peers/00112233445566"),
'foo', "InvalidArgs")]
for (p, method, err) in tests:
try:
p2p.ProvisionDiscoveryRequest(p, method)
raise Exception("Invalid ProvisionDiscoveryRequest accepted")
except dbus.exceptions.DBusException as e:
if err not in str(e):
raise Exception("Unexpected error message for invalid ProvisionDiscoveryRequest: " + str(e))
try:
dev[0].request("P2P_SET disabled 1")
if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Peers",
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Get(Peers) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: P2P is not available for this interface" not in str(e):
raise Exception("Unexpected error message for invalid Get(Peers): " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
def test_dbus_p2p_oom(dev, apdev):
"""D-Bus P2P operations and OOM"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_string_array",
"Find", "InvalidArgs"):
p2p.Find(dbus.Dictionary({'Foo': ['bar']}))
with alloc_fail_dbus(dev[0], 2, "_wpa_dbus_dict_entry_get_string_array",
"Find", "InvalidArgs"):
p2p.Find(dbus.Dictionary({'Foo': ['bar']}))
with alloc_fail_dbus(dev[0], 10, "_wpa_dbus_dict_entry_get_string_array",
"Find", "InvalidArgs"):
p2p.Find(dbus.Dictionary({'Foo': ['1', '2', '3', '4', '5', '6', '7',
'8', '9']}))
with alloc_fail_dbus(dev[0], 1, ":=_wpa_dbus_dict_entry_get_binarray",
"Find", "InvalidArgs"):
p2p.Find(dbus.Dictionary({'Foo': [dbus.ByteArray(b'123')]}))
with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_byte_array;_wpa_dbus_dict_entry_get_binarray",
"Find", "InvalidArgs"):
p2p.Find(dbus.Dictionary({'Foo': [dbus.ByteArray(b'123')]}))
with alloc_fail_dbus(dev[0], 2, "=_wpa_dbus_dict_entry_get_binarray",
"Find", "InvalidArgs"):
p2p.Find(dbus.Dictionary({'Foo': [dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123'),
dbus.ByteArray(b'123')]}))
with alloc_fail_dbus(dev[0], 1, "wpabuf_alloc_ext_data;_wpa_dbus_dict_entry_get_binarray",
"Find", "InvalidArgs"):
p2p.Find(dbus.Dictionary({'Foo': [dbus.ByteArray(b'123')]}))
with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_fill_value_from_variant;wpas_dbus_handler_p2p_find",
"Find", "InvalidArgs"):
p2p.Find(dbus.Dictionary({'Foo': path}))
with alloc_fail_dbus(dev[0], 1, "_wpa_dbus_dict_entry_get_byte_array",
"AddService", "InvalidArgs"):
args = {'service_type': 'bonjour',
'response': dbus.ByteArray(500*b'b')}
p2p.AddService(args)
with alloc_fail_dbus(dev[0], 2, "_wpa_dbus_dict_entry_get_byte_array",
"AddService", "InvalidArgs"):
p2p.AddService(args)
def test_dbus_p2p_discovery(dev, apdev):
"""D-Bus P2P discovery"""
try:
run_dbus_p2p_discovery(dev, apdev)
finally:
dev[1].request("VENDOR_ELEM_REMOVE 1 *")
def run_dbus_p2p_discovery(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
dev[1].request("SET sec_device_type 1-0050F204-2")
dev[1].request("VENDOR_ELEM_ADD 1 dd0c0050f2041049000411223344")
dev[1].request("VENDOR_ELEM_ADD 1 dd06001122335566")
dev[1].p2p_listen()
addr1 = dev[1].p2p_dev_addr()
a1 = binascii.unhexlify(addr1.replace(':', ''))
wfd_devinfo = "00001c440028"
dev[2].request("SET wifi_display 1")
dev[2].request("WFD_SUBELEM_SET 0 0006" + wfd_devinfo)
wfd = binascii.unhexlify('000006' + wfd_devinfo)
dev[2].p2p_listen()
addr2 = dev[2].p2p_dev_addr()
a2 = binascii.unhexlify(addr2.replace(':', ''))
res = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE,
dbus_interface=dbus.PROPERTIES_IFACE)
if 'Peers' not in res:
raise Exception("GetAll result missing Peers")
if len(res['Peers']) != 0:
raise Exception("Unexpected peer(s) in the list")
args = {'DiscoveryType': 'social',
'RequestedDeviceTypes': [dbus.ByteArray(b'12345678')],
'Timeout': dbus.Int32(1)}
p2p.Find(dbus.Dictionary(args))
p2p.StopFind()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.found = False
self.found2 = False
self.found_prop = False
self.lost = False
self.find_stopped = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.deviceFoundProperties,
WPAS_DBUS_IFACE_P2PDEVICE, "DeviceFoundProperties")
self.add_signal(self.deviceLost, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceLost")
self.add_signal(self.provisionDiscoveryResponseEnterPin,
WPAS_DBUS_IFACE_P2PDEVICE,
"ProvisionDiscoveryResponseEnterPin")
self.add_signal(self.findStopped, WPAS_DBUS_IFACE_P2PDEVICE,
"FindStopped")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
res = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Peers",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) < 1:
raise Exception("Unexpected number of peers")
if path not in res:
raise Exception("Mismatch in peer object path")
peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("peer properties: " + str(res))
if res['DeviceAddress'] == a1:
if 'SecondaryDeviceTypes' not in res:
raise Exception("Missing SecondaryDeviceTypes")
sec = res['SecondaryDeviceTypes']
if len(sec) < 1:
raise Exception("Secondary device type missing")
if b"\x00\x01\x00\x50\xF2\x04\x00\x02" not in sec:
raise Exception("Secondary device type mismatch")
if 'VendorExtension' not in res:
raise Exception("Missing VendorExtension")
vendor = res['VendorExtension']
if len(vendor) < 1:
raise Exception("Vendor extension missing")
if b"\x11\x22\x33\x44" not in vendor:
raise Exception("Secondary device type mismatch")
if 'VSIE' not in res:
raise Exception("Missing VSIE")
vendor = res['VSIE']
if len(vendor) < 1:
raise Exception("VSIE missing")
if vendor != b"\xdd\x06\x00\x11\x22\x33\x55\x66":
raise Exception("VSIE mismatch")
self.found = True
elif res['DeviceAddress'] == a2:
if 'IEs' not in res:
raise Exception("IEs missing")
if res['IEs'] != wfd:
raise Exception("IEs mismatch")
self.found2 = True
else:
raise Exception("Unexpected peer device address")
if self.found and self.found2:
p2p.StopFind()
p2p.RejectPeer(path)
p2p.ProvisionDiscoveryRequest(path, 'display')
def deviceLost(self, path):
logger.debug("deviceLost: path=%s" % path)
if not self.found or not self.found2:
# This may happen if a previous test case ended up scheduling
# deviceLost event and that event did not get delivered before
# starting the next test execution.
logger.debug("Ignore deviceLost before the deviceFound events")
return
self.lost = True
try:
p2p.RejectPeer(path)
raise Exception("Invalid RejectPeer accepted")
except dbus.exceptions.DBusException as e:
if "UnknownError: Failed to call wpas_p2p_reject" not in str(e):
raise Exception("Unexpected error message for invalid RejectPeer(): " + str(e))
self.loop.quit()
def deviceFoundProperties(self, path, properties):
logger.debug("deviceFoundProperties: path=%s" % path)
logger.debug("peer properties: " + str(properties))
if properties['DeviceAddress'] == a1:
self.found_prop = True
def provisionDiscoveryResponseEnterPin(self, peer_object):
logger.debug("provisionDiscoveryResponseEnterPin - peer=%s" % peer_object)
p2p.Flush()
def findStopped(self):
logger.debug("findStopped")
self.find_stopped = True
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social',
'Timeout': dbus.Int32(10)}))
return False
def success(self):
return self.found and self.lost and self.found2 and self.find_stopped
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
dev[1].request("VENDOR_ELEM_REMOVE 1 *")
dev[1].p2p_stop_find()
p2p.Listen(1)
dev[2].p2p_stop_find()
dev[2].request("P2P_FLUSH")
if not dev[2].discover_peer(addr0):
raise Exception("Peer not found")
p2p.StopFind()
dev[2].p2p_stop_find()
try:
p2p.ExtendedListen(dbus.Dictionary({'foo': 100}))
raise Exception("Invalid ExtendedListen accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid ExtendedListen(): " + str(e))
p2p.ExtendedListen(dbus.Dictionary({'period': 100, 'interval': 1000}))
p2p.ExtendedListen(dbus.Dictionary({}))
dev[0].global_request("P2P_EXT_LISTEN")
def test_dbus_p2p_discovery_freq(dev, apdev):
"""D-Bus P2P discovery on a specific non-social channel"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr1 = dev[1].p2p_dev_addr()
autogo(dev[1], freq=2422)
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.found = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(5000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
self.found = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'freq': 2422}))
return False
def success(self):
return self.found
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
dev[1].remove_group()
p2p.StopFind()
def test_dbus_p2p_service_discovery(dev, apdev):
"""D-Bus P2P service discovery"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
addr1 = dev[1].p2p_dev_addr()
bonjour_query = dbus.ByteArray(binascii.unhexlify('0b5f6166706f766572746370c00c000c01'))
bonjour_response = dbus.ByteArray(binascii.unhexlify('074578616d706c65c027'))
args = {'service_type': 'bonjour',
'query': bonjour_query,
'response': bonjour_response}
p2p.AddService(args)
p2p.FlushService()
p2p.AddService(args)
try:
p2p.DeleteService(args)
raise Exception("Invalid DeleteService() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid DeleteService(): " + str(e))
args = {'service_type': 'bonjour',
'query': bonjour_query}
p2p.DeleteService(args)
try:
p2p.DeleteService(args)
raise Exception("Invalid DeleteService() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid DeleteService(): " + str(e))
args = {'service_type': 'upnp',
'version': 0x10,
'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'}
p2p.AddService(args)
p2p.DeleteService(args)
try:
p2p.DeleteService(args)
raise Exception("Invalid DeleteService() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid DeleteService(): " + str(e))
tests = [{'service_type': 'foo'},
{'service_type': 'foo', 'query': bonjour_query},
{'service_type': 'upnp'},
{'service_type': 'upnp', 'version': 0x10},
{'service_type': 'upnp',
'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'},
{'version': 0x10,
'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'},
{'service_type': 'upnp', 'foo': 'bar'},
{'service_type': 'bonjour'},
{'service_type': 'bonjour', 'query': 'foo'},
{'service_type': 'bonjour', 'foo': 'bar'}]
for args in tests:
try:
p2p.DeleteService(args)
raise Exception("Invalid DeleteService() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid DeleteService(): " + str(e))
tests = [{'service_type': 'foo'},
{'service_type': 'upnp'},
{'service_type': 'upnp', 'version': 0x10},
{'service_type': 'upnp',
'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'},
{'version': 0x10,
'service': 'uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice'},
{'service_type': 'upnp', 'foo': 'bar'},
{'service_type': 'bonjour'},
{'service_type': 'bonjour', 'query': 'foo'},
{'service_type': 'bonjour', 'response': 'foo'},
{'service_type': 'bonjour', 'query': bonjour_query},
{'service_type': 'bonjour', 'response': bonjour_response},
{'service_type': 'bonjour', 'query': dbus.ByteArray(500*b'a')},
{'service_type': 'bonjour', 'foo': 'bar'}]
for args in tests:
try:
p2p.AddService(args)
raise Exception("Invalid AddService() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid AddService(): " + str(e))
args = {'tlv': dbus.ByteArray(b"\x02\x00\x00\x01")}
ref = p2p.ServiceDiscoveryRequest(args)
p2p.ServiceDiscoveryCancelRequest(ref)
try:
p2p.ServiceDiscoveryCancelRequest(ref)
raise Exception("Invalid ServiceDiscoveryCancelRequest() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid AddService(): " + str(e))
try:
p2p.ServiceDiscoveryCancelRequest(dbus.UInt64(0))
raise Exception("Invalid ServiceDiscoveryCancelRequest() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid AddService(): " + str(e))
args = {'service_type': 'upnp',
'version': 0x10,
'service': 'ssdp:foo'}
ref = p2p.ServiceDiscoveryRequest(args)
p2p.ServiceDiscoveryCancelRequest(ref)
tests = [{'service_type': 'foo'},
{'foo': 'bar'},
{'tlv': 'foo'},
{},
{'version': 0},
{'service_type': 'upnp',
'service': 'ssdp:foo'},
{'service_type': 'upnp',
'version': 0x10},
{'service_type': 'upnp',
'version': 0x10,
'service': 'ssdp:foo',
'peer_object': dbus.ObjectPath(path + "/Peers")},
{'service_type': 'upnp',
'version': 0x10,
'service': 'ssdp:foo',
'peer_object': path + "/Peers"},
{'service_type': 'upnp',
'version': 0x10,
'service': 'ssdp:foo',
'peer_object': dbus.ObjectPath(path + "/Peers/00112233445566")}]
for args in tests:
try:
p2p.ServiceDiscoveryRequest(args)
raise Exception("Invalid ServiceDiscoveryRequest accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid ServiceDiscoveryRequest(): " + str(e))
args = {'foo': 'bar'}
try:
p2p.ServiceDiscoveryResponse(dbus.Dictionary(args, signature='sv'))
raise Exception("Invalid ServiceDiscoveryResponse accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid ServiceDiscoveryResponse(): " + str(e))
def test_dbus_p2p_service_discovery_query(dev, apdev):
"""D-Bus P2P service discovery query"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
dev[1].request("P2P_SERVICE_ADD bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027")
dev[1].p2p_listen()
addr1 = dev[1].p2p_dev_addr()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.serviceDiscoveryResponse,
WPAS_DBUS_IFACE_P2PDEVICE,
"ServiceDiscoveryResponse", byte_arrays=True)
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
args = {'peer_object': path,
'tlv': dbus.ByteArray(b"\x02\x00\x00\x01")}
p2p.ServiceDiscoveryRequest(args)
def serviceDiscoveryResponse(self, sd_request):
logger.debug("serviceDiscoveryResponse: sd_request=%s" % str(sd_request))
self.done = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social',
'Timeout': dbus.Int32(10)}))
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
dev[1].p2p_stop_find()
def test_dbus_p2p_service_discovery_external(dev, apdev):
"""D-Bus P2P service discovery with external response"""
try:
_test_dbus_p2p_service_discovery_external(dev, apdev)
finally:
dev[0].request("P2P_SERV_DISC_EXTERNAL 0")
def _test_dbus_p2p_service_discovery_external(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
addr1 = dev[1].p2p_dev_addr()
resp = "0300000101"
dev[1].request("P2P_FLUSH")
dev[1].request("P2P_SERV_DISC_REQ " + addr0 + " 02000001")
dev[1].p2p_find(social=True)
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.sd = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.serviceDiscoveryRequest,
WPAS_DBUS_IFACE_P2PDEVICE,
"ServiceDiscoveryRequest")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
def serviceDiscoveryRequest(self, sd_request):
logger.debug("serviceDiscoveryRequest: sd_request=%s" % str(sd_request))
self.sd = True
args = {'peer_object': sd_request['peer_object'],
'frequency': sd_request['frequency'],
'dialog_token': sd_request['dialog_token'],
'tlvs': dbus.ByteArray(binascii.unhexlify(resp))}
p2p.ServiceDiscoveryResponse(dbus.Dictionary(args, signature='sv'))
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.ServiceDiscoveryExternal(1)
p2p.ServiceUpdate()
p2p.Listen(15)
return False
def success(self):
return self.sd
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
ev = dev[1].wait_global_event(["P2P-SERV-DISC-RESP"], timeout=5)
if ev is None:
raise Exception("Service discovery timed out")
if addr0 not in ev:
raise Exception("Unexpected address in SD Response: " + ev)
if ev.split(' ')[4] != resp:
raise Exception("Unexpected response data SD Response: " + ev)
dev[1].p2p_stop_find()
p2p.StopFind()
p2p.ServiceDiscoveryExternal(0)
def test_dbus_p2p_autogo(dev, apdev):
"""D-Bus P2P autonomous GO"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.first = True
self.waiting_end = False
self.exceptions = False
self.deauthorized = False
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.persistentGroupAdded,
WPAS_DBUS_IFACE_P2PDEVICE,
"PersistentGroupAdded")
self.add_signal(self.persistentGroupRemoved,
WPAS_DBUS_IFACE_P2PDEVICE,
"PersistentGroupRemoved")
self.add_signal(self.provisionDiscoveryRequestDisplayPin,
WPAS_DBUS_IFACE_P2PDEVICE,
"ProvisionDiscoveryRequestDisplayPin")
self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
"StaAuthorized")
self.add_signal(self.staDeauthorized, WPAS_DBUS_IFACE,
"StaDeauthorized")
self.loop.run()
return self
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
self.group = properties['group_object']
self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
role = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Role",
dbus_interface=dbus.PROPERTIES_IFACE)
if role != "GO":
self.exceptions = True
raise Exception("Unexpected role reported: " + role)
group = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Group",
dbus_interface=dbus.PROPERTIES_IFACE)
if group != properties['group_object']:
self.exceptions = True
raise Exception("Unexpected Group reported: " + str(group))
go = self.g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PeerGO",
dbus_interface=dbus.PROPERTIES_IFACE)
if go != '/':
self.exceptions = True
raise Exception("Unexpected PeerGO value: " + str(go))
if self.first:
self.first = False
logger.info("Remove persistent group instance")
group_p2p = dbus.Interface(self.g_if_obj,
WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
else:
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 join")
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
if self.waiting_end:
logger.info("Remove persistent group")
p2p.RemovePersistentGroup(self.persistent)
else:
logger.info("Re-start persistent group")
params = dbus.Dictionary({'persistent_group_object':
self.persistent,
'frequency': 2412})
p2p.GroupAdd(params)
def persistentGroupAdded(self, path, properties):
logger.debug("persistentGroupAdded: %s %s" % (path, str(properties)))
self.persistent = path
def persistentGroupRemoved(self, path):
logger.debug("persistentGroupRemoved: %s" % path)
self.done = True
self.loop.quit()
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug('peer properties: ' + str(self.peer))
def provisionDiscoveryRequestDisplayPin(self, peer_object, pin):
logger.debug("provisionDiscoveryRequestDisplayPin - peer=%s pin=%s" % (peer_object, pin))
self.peer_path = peer_object
peer = binascii.unhexlify(peer_object.split('/')[-1])
addr = ':'.join(["%02x" % i for i in struct.unpack('6B', peer)])
params = {'Role': 'registrar',
'P2PDeviceAddress': self.peer['DeviceAddress'],
'Bssid': self.peer['DeviceAddress'],
'Type': 'pin'}
wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS)
try:
wps.Start(params)
self.exceptions = True
raise Exception("Invalid WPS.Start() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
self.exceptions = True
raise Exception("Unexpected error message: " + str(e))
params = {'Role': 'registrar',
'P2PDeviceAddress': self.peer['DeviceAddress'],
'Type': 'pin',
'Pin': '12345670'}
logger.info("Authorize peer to connect to the group")
wps.Start(params)
def staAuthorized(self, name):
logger.debug("staAuthorized: " + name)
peer_obj = bus.get_object(WPAS_DBUS_SERVICE, self.peer_path)
res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("Peer properties: " + str(res))
if 'Groups' not in res or len(res['Groups']) != 1:
self.exceptions = True
raise Exception("Unexpected number of peer Groups entries")
if res['Groups'][0] != self.group:
self.exceptions = True
raise Exception("Unexpected peer Groups[0] value")
g_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group)
res = g_obj.GetAll(WPAS_DBUS_GROUP,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("Group properties: " + str(res))
if 'Members' not in res or len(res['Members']) != 1:
self.exceptions = True
raise Exception("Unexpected number of group members")
ext = dbus.ByteArray(b"\x11\x22\x33\x44")
# Earlier implementation of this interface was a bit strange. The
# property is defined to have aay signature and that is what the
# getter returned. However, the setter expected there to be a
# dictionary with 'WPSVendorExtensions' as the key surrounding these
# values.. The current implementations maintains support for that
# for backwards compability reasons. Verify that encoding first.
vals = dbus.Dictionary({'WPSVendorExtensions': [ext]},
signature='sv')
g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals,
dbus_interface=dbus.PROPERTIES_IFACE)
res = g_obj.Get(WPAS_DBUS_GROUP, 'WPSVendorExtensions',
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
if len(res) != 1:
self.exceptions = True
raise Exception("Unexpected number of vendor extensions")
if res[0] != ext:
self.exceptions = True
raise Exception("Vendor extension value changed")
# And now verify that the more appropriate encoding is accepted as
# well.
res.append(dbus.ByteArray(b'\xaa\xbb\xcc\xdd\xee\xff'))
g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res,
dbus_interface=dbus.PROPERTIES_IFACE)
res2 = g_obj.Get(WPAS_DBUS_GROUP, 'WPSVendorExtensions',
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
if len(res) != 2:
self.exceptions = True
raise Exception("Unexpected number of vendor extensions")
if res[0] != res2[0] or res[1] != res2[1]:
self.exceptions = True
raise Exception("Vendor extension value changed")
for i in range(10):
res.append(dbus.ByteArray(b'\xaa\xbb'))
try:
g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res,
dbus_interface=dbus.PROPERTIES_IFACE)
self.exceptions = True
raise Exception("Invalid Set(WPSVendorExtensions) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed" not in str(e):
self.exceptions = True
raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))
vals = dbus.Dictionary({'Foo': [ext]}, signature='sv')
try:
g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals,
dbus_interface=dbus.PROPERTIES_IFACE)
self.exceptions = True
raise Exception("Invalid Set(WPSVendorExtensions) accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
self.exceptions = True
raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))
vals = ["foo"]
try:
g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals,
dbus_interface=dbus.PROPERTIES_IFACE)
self.exceptions = True
raise Exception("Invalid Set(WPSVendorExtensions) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed" not in str(e):
self.exceptions = True
raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))
vals = [["foo"]]
try:
g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', vals,
dbus_interface=dbus.PROPERTIES_IFACE)
self.exceptions = True
raise Exception("Invalid Set(WPSVendorExtensions) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed" not in str(e):
self.exceptions = True
raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))
p2p.RemoveClient({'peer': self.peer_path})
self.waiting_end = True
group_p2p = dbus.Interface(self.g_if_obj,
WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
def staDeauthorized(self, name):
logger.debug("staDeauthorized: " + name)
self.deauthorized = True
def run_test(self, *args):
logger.debug("run_test")
params = dbus.Dictionary({'persistent': True,
'frequency': 2412})
logger.info("Add a persistent group")
p2p.GroupAdd(params)
return False
def success(self):
return self.done and self.deauthorized and not self.exceptions
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
dev[1].wait_go_ending_session()
def test_dbus_p2p_autogo_pbc(dev, apdev):
"""D-Bus P2P autonomous GO and PBC"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.first = True
self.waiting_end = False
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.provisionDiscoveryPBCRequest,
WPAS_DBUS_IFACE_P2PDEVICE,
"ProvisionDiscoveryPBCRequest")
self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
"StaAuthorized")
self.loop.run()
return self
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
self.group = properties['group_object']
self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.global_request("P2P_CONNECT " + addr0 + " pbc join")
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.done = True
self.loop.quit()
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug('peer properties: ' + str(self.peer))
def provisionDiscoveryPBCRequest(self, peer_object):
logger.debug("provisionDiscoveryPBCRequest - peer=%s" % peer_object)
self.peer_path = peer_object
peer = binascii.unhexlify(peer_object.split('/')[-1])
addr = ':'.join(["%02x" % i for i in struct.unpack('6B', peer)])
params = {'Role': 'registrar',
'P2PDeviceAddress': self.peer['DeviceAddress'],
'Type': 'pbc'}
logger.info("Authorize peer to connect to the group")
wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS)
wps.Start(params)
def staAuthorized(self, name):
logger.debug("staAuthorized: " + name)
group_p2p = dbus.Interface(self.g_if_obj,
WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
def run_test(self, *args):
logger.debug("run_test")
params = dbus.Dictionary({'frequency': 2412})
p2p.GroupAdd(params)
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
dev[1].wait_go_ending_session()
dev[1].flush_scan_cache()
def test_dbus_p2p_autogo_legacy(dev, apdev):
"""D-Bus P2P autonomous GO and legacy STA"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
"StaAuthorized")
self.loop.run()
return self
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
g_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['group_object'])
res = g_obj.GetAll(WPAS_DBUS_GROUP,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
bssid = ':'.join(["%02x" % i for i in struct.unpack('6B', res['BSSID'])])
pin = '12345670'
params = {'Role': 'enrollee',
'Type': 'pin',
'Pin': pin}
g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
wps = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_WPS)
wps.Start(params)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.scan_for_bss(bssid, freq=2412)
dev1.request("WPS_PIN " + bssid + " " + pin)
self.group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.done = True
self.loop.quit()
def staAuthorized(self, name):
logger.debug("staAuthorized: " + name)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.request("DISCONNECT")
self.group_p2p.Disconnect()
def run_test(self, *args):
logger.debug("run_test")
params = dbus.Dictionary({'frequency': 2412})
p2p.GroupAdd(params)
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_join(dev, apdev):
"""D-Bus P2P join an autonomous GO"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr1 = dev[1].p2p_dev_addr()
addr2 = dev[2].p2p_dev_addr()
dev[1].p2p_start_go(freq=2412)
dev1_group_ifname = dev[1].group_ifname
dev[2].p2p_listen()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
self.peer = None
self.go = None
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.invitationResult, WPAS_DBUS_IFACE_P2PDEVICE,
"InvitationResult")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
res = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug('peer properties: ' + str(res))
if addr2.replace(':', '') in path:
self.peer = path
elif addr1.replace(':', '') in path:
self.go = path
if self.peer and self.go:
logger.info("Join the group")
p2p.StopFind()
args = {'peer': self.go,
'join': True,
'wps_method': 'pin',
'frequency': 2412}
pin = p2p.Connect(args)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.group_ifname = dev1_group_ifname
dev1.group_request("WPS_PIN any " + pin)
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
role = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Role",
dbus_interface=dbus.PROPERTIES_IFACE)
if role != "client":
raise Exception("Unexpected role reported: " + role)
group = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "Group",
dbus_interface=dbus.PROPERTIES_IFACE)
if group != properties['group_object']:
raise Exception("Unexpected Group reported: " + str(group))
go = g_if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PeerGO",
dbus_interface=dbus.PROPERTIES_IFACE)
if go != self.go:
raise Exception("Unexpected PeerGO value: " + str(go))
g_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['group_object'])
res = g_obj.GetAll(WPAS_DBUS_GROUP,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("Group properties: " + str(res))
ext = dbus.ByteArray(b"\x11\x22\x33\x44")
try:
# Set(WPSVendorExtensions) not allowed for P2P Client
g_obj.Set(WPAS_DBUS_GROUP, 'WPSVendorExtensions', res,
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(WPSVendorExtensions) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: Failed to set property" not in str(e):
raise Exception("Unexpected error message for invalid Set(WPSVendorExtensions): " + str(e))
group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
args = {'duration1': 30000, 'interval1': 102400,
'duration2': 20000, 'interval2': 102400}
group_p2p.PresenceRequest(args)
args = {'peer': self.peer}
group_p2p.Invite(args)
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.done = True
self.loop.quit()
def invitationResult(self, result):
logger.debug("invitationResult: " + str(result))
if result['status'] != 1:
raise Exception("Unexpected invitation result: " + str(result))
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.group_ifname = dev1_group_ifname
dev1.remove_group()
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
dev[2].p2p_stop_find()
def test_dbus_p2p_invitation_received(dev, apdev):
"""D-Bus P2P and InvitationReceived"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
form(dev[0], dev[1])
addr0 = dev[0].p2p_dev_addr()
dev[0].p2p_listen()
dev[0].global_request("SET persistent_reconnect 0")
if not dev[1].discover_peer(addr0, social=True):
raise Exception("Peer " + addr0 + " not found")
peer = dev[1].get_peer(addr0)
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.invitationReceived, WPAS_DBUS_IFACE_P2PDEVICE,
"InvitationReceived")
self.loop.run()
return self
def invitationReceived(self, result):
logger.debug("invitationReceived: " + str(result))
self.done = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
cmd = "P2P_INVITE persistent=" + peer['persistent'] + " peer=" + addr0
dev1.global_request(cmd)
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
dev[0].p2p_stop_find()
dev[1].p2p_stop_find()
def test_dbus_p2p_config(dev, apdev):
"""D-Bus Get/Set P2PDeviceConfig"""
try:
_test_dbus_p2p_config(dev, apdev)
finally:
dev[0].request("P2P_SET ssid_postfix ")
def _test_dbus_p2p_config(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
res = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig", res,
dbus_interface=dbus.PROPERTIES_IFACE)
res2 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
if len(res) != len(res2):
raise Exception("Different number of parameters")
for k in res:
if res[k] != res2[k]:
raise Exception("Parameter %s value changes" % k)
changes = {'SsidPostfix': 'foo',
'VendorExtension': [dbus.ByteArray(b'\x11\x22\x33\x44')],
'SecondaryDeviceTypes': [dbus.ByteArray(b'\x11\x22\x33\x44\x55\x66\x77\x88')]}
if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus.Dictionary(changes, signature='sv'),
dbus_interface=dbus.PROPERTIES_IFACE)
res2 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("P2PDeviceConfig: " + str(res2))
if 'VendorExtension' not in res2 or len(res2['VendorExtension']) != 1:
raise Exception("VendorExtension does not match")
if 'SecondaryDeviceTypes' not in res2 or len(res2['SecondaryDeviceTypes']) != 1:
raise Exception("SecondaryDeviceType does not match")
changes = {'SsidPostfix': '',
'VendorExtension': dbus.Array([], signature="ay"),
'SecondaryDeviceTypes': dbus.Array([], signature="ay")}
if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus.Dictionary(changes, signature='sv'),
dbus_interface=dbus.PROPERTIES_IFACE)
res3 = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("P2PDeviceConfig: " + str(res3))
if 'VendorExtension' in res3:
raise Exception("VendorExtension not removed")
if 'SecondaryDeviceTypes' in res3:
raise Exception("SecondaryDeviceType not removed")
try:
dev[0].request("P2P_SET disabled 1")
if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
raise Exception("Invalid Get(P2PDeviceConfig) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: P2P is not available for this interface" not in str(e):
raise Exception("Unexpected error message for invalid Invite: " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
try:
dev[0].request("P2P_SET disabled 1")
changes = {'SsidPostfix': 'foo'}
if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus.Dictionary(changes, signature='sv'),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(P2PDeviceConfig) accepted")
except dbus.exceptions.DBusException as e:
if "Error.Failed: P2P is not available for this interface" not in str(e):
raise Exception("Unexpected error message for invalid Invite: " + str(e))
finally:
dev[0].request("P2P_SET disabled 0")
tests = [{'DeviceName': 123},
{'SsidPostfix': 123},
{'Foo': 'Bar'}]
for changes in tests:
try:
if_obj.Set(WPAS_DBUS_IFACE_P2PDEVICE, "P2PDeviceConfig",
dbus.Dictionary(changes, signature='sv'),
dbus_interface=dbus.PROPERTIES_IFACE)
raise Exception("Invalid Set(P2PDeviceConfig) accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid Invite: " + str(e))
def test_dbus_p2p_persistent(dev, apdev):
"""D-Bus P2P persistent group"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.persistentGroupAdded,
WPAS_DBUS_IFACE_P2PDEVICE,
"PersistentGroupAdded")
self.loop.run()
return self
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.loop.quit()
def persistentGroupAdded(self, path, properties):
logger.debug("persistentGroupAdded: %s %s" % (path, str(properties)))
self.persistent = path
def run_test(self, *args):
logger.debug("run_test")
params = dbus.Dictionary({'persistent': True,
'frequency': 2412})
logger.info("Add a persistent group")
p2p.GroupAdd(params)
return False
def success(self):
return True
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
persistent = t.persistent
p_obj = bus.get_object(WPAS_DBUS_SERVICE, persistent)
res = p_obj.Get(WPAS_DBUS_PERSISTENT_GROUP, "Properties",
dbus_interface=dbus.PROPERTIES_IFACE, byte_arrays=True)
logger.info("Persistent group Properties: " + str(res))
vals = dbus.Dictionary({'ssid': 'DIRECT-foo'}, signature='sv')
p_obj.Set(WPAS_DBUS_PERSISTENT_GROUP, "Properties", vals,
dbus_interface=dbus.PROPERTIES_IFACE)
res2 = p_obj.Get(WPAS_DBUS_PERSISTENT_GROUP, "Properties",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(res) != len(res2):
raise Exception("Different number of parameters")
for k in res:
if k != 'ssid' and res[k] != res2[k]:
raise Exception("Parameter %s value changes" % k)
if res2['ssid'] != '"DIRECT-foo"':
raise Exception("Unexpected ssid")
args = dbus.Dictionary({'ssid': 'DIRECT-testing',
'psk': '1234567890'}, signature='sv')
group = p2p.AddPersistentGroup(args)
groups = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PersistentGroups",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(groups) != 2:
raise Exception("Unexpected number of persistent groups: " + str(groups))
p2p.RemoveAllPersistentGroups()
groups = if_obj.Get(WPAS_DBUS_IFACE_P2PDEVICE, "PersistentGroups",
dbus_interface=dbus.PROPERTIES_IFACE)
if len(groups) != 0:
raise Exception("Unexpected number of persistent groups: " + str(groups))
try:
p2p.RemovePersistentGroup(persistent)
raise Exception("Invalid RemovePersistentGroup accepted")
except dbus.exceptions.DBusException as e:
if "NetworkUnknown: There is no such persistent group" not in str(e):
raise Exception("Unexpected error message for invalid RemovePersistentGroup: " + str(e))
def test_dbus_p2p_reinvoke_persistent(dev, apdev):
"""D-Bus P2P reinvoke persistent group"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.first = True
self.waiting_end = False
self.done = False
self.invited = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.persistentGroupAdded,
WPAS_DBUS_IFACE_P2PDEVICE,
"PersistentGroupAdded")
self.add_signal(self.provisionDiscoveryRequestDisplayPin,
WPAS_DBUS_IFACE_P2PDEVICE,
"ProvisionDiscoveryRequestDisplayPin")
self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
"StaAuthorized")
self.loop.run()
return self
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
if not self.invited:
g_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['group_object'])
res = g_obj.GetAll(WPAS_DBUS_GROUP,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
bssid = ':'.join(["%02x" % i for i in struct.unpack('6B', res['BSSID'])])
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.scan_for_bss(bssid, freq=2412)
dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 join")
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
if self.invited:
self.done = True
self.loop.quit()
else:
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.global_request("SET persistent_reconnect 1")
dev1.p2p_listen()
args = {'persistent_group_object': dbus.ObjectPath(path),
'peer': self.peer_path}
try:
pin = p2p.Invite(args)
raise Exception("Invalid Invite accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid Invite: " + str(e))
args = {'persistent_group_object': self.persistent,
'peer': self.peer_path}
pin = p2p.Invite(args)
self.invited = True
self.sta_group_ev = dev1.wait_global_event(["P2P-GROUP-STARTED"],
timeout=15)
if self.sta_group_ev is None:
raise Exception("P2P-GROUP-STARTED event not seen")
def persistentGroupAdded(self, path, properties):
logger.debug("persistentGroupAdded: %s %s" % (path, str(properties)))
self.persistent = path
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
peer_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
self.peer = peer_obj.GetAll(WPAS_DBUS_P2P_PEER,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
def provisionDiscoveryRequestDisplayPin(self, peer_object, pin):
logger.debug("provisionDiscoveryRequestDisplayPin - peer=%s pin=%s" % (peer_object, pin))
self.peer_path = peer_object
peer = binascii.unhexlify(peer_object.split('/')[-1])
addr = ':'.join(["%02x" % i for i in struct.unpack('6B', peer)])
params = {'Role': 'registrar',
'P2PDeviceAddress': self.peer['DeviceAddress'],
'Bssid': self.peer['DeviceAddress'],
'Type': 'pin',
'Pin': '12345670'}
logger.info("Authorize peer to connect to the group")
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
wps = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_WPS)
wps.Start(params)
self.sta_group_ev = dev1.wait_global_event(["P2P-GROUP-STARTED"],
timeout=15)
if self.sta_group_ev is None:
raise Exception("P2P-GROUP-STARTED event not seen")
def staAuthorized(self, name):
logger.debug("staAuthorized: " + name)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.group_form_result(self.sta_group_ev)
dev1.remove_group()
ev = dev1.wait_global_event(["P2P-GROUP-REMOVED"], timeout=10)
if ev is None:
raise Exception("Group removal timed out")
group_p2p = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
def run_test(self, *args):
logger.debug("run_test")
params = dbus.Dictionary({'persistent': True,
'frequency': 2412})
logger.info("Add a persistent group")
p2p.GroupAdd(params)
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_go_neg_rx(dev, apdev):
"""D-Bus P2P GO Negotiation receive"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.goNegotiationRequest,
WPAS_DBUS_IFACE_P2PDEVICE,
"GONegotiationRequest",
byte_arrays=True)
self.add_signal(self.goNegotiationSuccess,
WPAS_DBUS_IFACE_P2PDEVICE,
"GONegotiationSuccess",
byte_arrays=True)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
def goNegotiationRequest(self, path, dev_passwd_id, go_intent=0):
logger.debug("goNegotiationRequest: path=%s dev_passwd_id=%d go_intent=%d" % (path, dev_passwd_id, go_intent))
if dev_passwd_id != 1:
raise Exception("Unexpected dev_passwd_id=%d" % dev_passwd_id)
args = {'peer': path, 'wps_method': 'display', 'pin': '12345670',
'go_intent': 15, 'persistent': False, 'frequency': 5175}
try:
p2p.Connect(args)
raise Exception("Invalid Connect accepted")
except dbus.exceptions.DBusException as e:
if "ConnectChannelUnsupported" not in str(e):
raise Exception("Unexpected error message for invalid Connect: " + str(e))
args = {'peer': path, 'wps_method': 'display', 'pin': '12345670',
'go_intent': 15, 'persistent': False}
p2p.Connect(args)
def goNegotiationSuccess(self, properties):
logger.debug("goNegotiationSuccess: properties=%s" % str(properties))
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.done = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Listen(10)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
if not dev1.discover_peer(addr0):
raise Exception("Peer not found")
dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 enter")
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_go_neg_auth(dev, apdev):
"""D-Bus P2P GO Negotiation authorized"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
dev[1].p2p_listen()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
self.peer_joined = False
self.peer_disconnected = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.goNegotiationSuccess,
WPAS_DBUS_IFACE_P2PDEVICE,
"GONegotiationSuccess",
byte_arrays=True)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.staDeauthorized, WPAS_DBUS_IFACE,
"StaDeauthorized")
self.add_signal(self.peerJoined, WPAS_DBUS_GROUP,
"PeerJoined")
self.add_signal(self.peerDisconnected, WPAS_DBUS_GROUP,
"PeerDisconnected")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
args = {'peer': path, 'wps_method': 'keypad',
'go_intent': 15, 'authorize_only': True}
try:
p2p.Connect(args)
raise Exception("Invalid Connect accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e):
raise Exception("Unexpected error message for invalid Connect: " + str(e))
args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
'go_intent': 15, 'authorize_only': True}
p2p.Connect(args)
p2p.Listen(10)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
if not dev1.discover_peer(addr0):
raise Exception("Peer not found")
dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=0")
ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=15)
if ev is None:
raise Exception("Group formation timed out")
self.sta_group_ev = ev
def goNegotiationSuccess(self, properties):
logger.debug("goNegotiationSuccess: properties=%s" % str(properties))
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
self.g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.group_form_result(self.sta_group_ev)
dev1.remove_group()
def staDeauthorized(self, name):
logger.debug("staDeuthorized: " + name)
group_p2p = dbus.Interface(self.g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
def peerJoined(self, peer):
logger.debug("peerJoined: " + peer)
self.peer_joined = True
def peerDisconnected(self, peer):
logger.debug("peerDisconnected: " + peer)
self.peer_disconnected = True
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.done = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
return False
def success(self):
return self.done and self.peer_joined and self.peer_disconnected
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_go_neg_init(dev, apdev):
"""D-Bus P2P GO Negotiation initiation"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
dev[1].p2p_listen()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
self.peer_group_added = False
self.peer_group_removed = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.goNegotiationSuccess,
WPAS_DBUS_IFACE_P2PDEVICE,
"GONegotiationSuccess",
byte_arrays=True)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
'go_intent': 0}
p2p.Connect(args)
ev = dev1.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15)
if ev is None:
raise Exception("Timeout while waiting for GO Neg Request")
dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15")
ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=15)
if ev is None:
raise Exception("Group formation timed out")
self.sta_group_ev = ev
dev1.close_monitor_global()
dev1.close_monitor_mon()
dev1 = None
def goNegotiationSuccess(self, properties):
logger.debug("goNegotiationSuccess: properties=%s" % str(properties))
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
group_p2p = dbus.Interface(g_if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1', monitor=False)
dev1.group_form_result(self.sta_group_ev)
dev1.remove_group()
dev1 = None
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.done = True
def propertiesChanged(self, interface_name, changed_properties,
invalidated_properties):
logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
if interface_name != WPAS_DBUS_P2P_PEER:
return
if "Groups" not in changed_properties:
return
if len(changed_properties["Groups"]) > 0:
self.peer_group_added = True
if len(changed_properties["Groups"]) == 0:
if not self.peer_group_added:
# This is likely a leftover event from an earlier test case,
# ignore it to allow this test case to go through its steps.
logger.info("Ignore propertiesChanged indicating group removal before group has been added")
return
self.peer_group_removed = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
return False
def success(self):
return self.done and self.peer_group_added and self.peer_group_removed
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_group_termination_by_go(dev, apdev):
"""D-Bus P2P group removal on GO terminating the group"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
dev[1].p2p_listen()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
self.peer_group_added = False
self.peer_group_removed = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.goNegotiationSuccess,
WPAS_DBUS_IFACE_P2PDEVICE,
"GONegotiationSuccess",
byte_arrays=True)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
'go_intent': 0}
p2p.Connect(args)
ev = dev1.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15)
if ev is None:
raise Exception("Timeout while waiting for GO Neg Request")
dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15")
ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=15)
if ev is None:
raise Exception("Group formation timed out")
self.sta_group_ev = ev
dev1.close_monitor_global()
dev1.close_monitor_mon()
dev1 = None
def goNegotiationSuccess(self, properties):
logger.debug("goNegotiationSuccess: properties=%s" % str(properties))
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1', monitor=False)
dev1.group_form_result(self.sta_group_ev)
dev1.remove_group()
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.done = True
def propertiesChanged(self, interface_name, changed_properties,
invalidated_properties):
logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
if interface_name != WPAS_DBUS_P2P_PEER:
return
if "Groups" not in changed_properties:
return
if len(changed_properties["Groups"]) > 0:
self.peer_group_added = True
if len(changed_properties["Groups"]) == 0 and self.peer_group_added:
self.peer_group_removed = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
return False
def success(self):
return self.done and self.peer_group_added and self.peer_group_removed
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_group_idle_timeout(dev, apdev):
"""D-Bus P2P group removal on idle timeout"""
try:
dev[0].global_request("SET p2p_group_idle 1")
_test_dbus_p2p_group_idle_timeout(dev, apdev)
finally:
dev[0].global_request("SET p2p_group_idle 0")
def _test_dbus_p2p_group_idle_timeout(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
dev[1].p2p_listen()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
self.group_started = False
self.peer_group_added = False
self.peer_group_removed = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.goNegotiationSuccess,
WPAS_DBUS_IFACE_P2PDEVICE,
"GONegotiationSuccess",
byte_arrays=True)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
'go_intent': 0}
p2p.Connect(args)
ev = dev1.wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=15)
if ev is None:
raise Exception("Timeout while waiting for GO Neg Request")
dev1.global_request("P2P_CONNECT " + addr0 + " 12345670 display go_intent=15")
ev = dev1.wait_global_event(["P2P-GROUP-STARTED"], timeout=15)
if ev is None:
raise Exception("Group formation timed out")
self.sta_group_ev = ev
dev1.close_monitor_global()
dev1.close_monitor_mon()
dev1 = None
def goNegotiationSuccess(self, properties):
logger.debug("goNegotiationSuccess: properties=%s" % str(properties))
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
self.group_started = True
g_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['interface_object'])
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1', monitor=False)
dev1.group_form_result(self.sta_group_ev)
ifaddr = dev1.group_request("STA-FIRST").splitlines()[0]
# Force disassociation with different reason code so that the
# P2P Client using D-Bus does not get normal group termination event
# from the GO.
dev1.group_request("DEAUTHENTICATE " + ifaddr + " reason=0 test=0")
dev1.remove_group()
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
self.done = True
def propertiesChanged(self, interface_name, changed_properties,
invalidated_properties):
logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
if interface_name != WPAS_DBUS_P2P_PEER:
return
if not self.group_started:
return
if "Groups" not in changed_properties:
return
if len(changed_properties["Groups"]) > 0:
self.peer_group_added = True
if len(changed_properties["Groups"]) == 0:
self.peer_group_removed = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
return False
def success(self):
return self.done and self.peer_group_added and self.peer_group_removed
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_wps_failure(dev, apdev):
"""D-Bus P2P WPS failure"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
addr0 = dev[0].p2p_dev_addr()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.wps_failed = False
self.formation_failure = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.goNegotiationRequest,
WPAS_DBUS_IFACE_P2PDEVICE,
"GONegotiationRequest",
byte_arrays=True)
self.add_signal(self.goNegotiationSuccess,
WPAS_DBUS_IFACE_P2PDEVICE,
"GONegotiationSuccess",
byte_arrays=True)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.wpsFailed, WPAS_DBUS_IFACE_P2PDEVICE,
"WpsFailed")
self.add_signal(self.groupFormationFailure,
WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFormationFailure")
self.loop.run()
return self
def goNegotiationRequest(self, path, dev_passwd_id, go_intent=0):
logger.debug("goNegotiationRequest: path=%s dev_passwd_id=%d go_intent=%d" % (path, dev_passwd_id, go_intent))
if dev_passwd_id != 1:
raise Exception("Unexpected dev_passwd_id=%d" % dev_passwd_id)
args = {'peer': path, 'wps_method': 'display', 'pin': '12345670',
'go_intent': 15}
p2p.Connect(args)
def goNegotiationSuccess(self, properties):
logger.debug("goNegotiationSuccess: properties=%s" % str(properties))
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
raise Exception("Unexpected GroupStarted")
def wpsFailed(self, name, args):
logger.debug("wpsFailed - name=%s args=%s" % (name, str(args)))
self.wps_failed = True
if self.formation_failure:
self.loop.quit()
def groupFormationFailure(self, reason):
logger.debug("groupFormationFailure - reason=%s" % reason)
self.formation_failure = True
if self.wps_failed:
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Listen(10)
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
if not dev1.discover_peer(addr0):
raise Exception("Peer not found")
dev1.global_request("P2P_CONNECT " + addr0 + " 87654321 enter")
return False
def success(self):
return self.wps_failed and self.formation_failure
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_two_groups(dev, apdev):
"""D-Bus P2P with two concurrent groups"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
dev[0].request("SET p2p_no_group_iface 0")
addr0 = dev[0].p2p_dev_addr()
addr1 = dev[1].p2p_dev_addr()
addr2 = dev[2].p2p_dev_addr()
dev[1].p2p_start_go(freq=2412)
dev1_group_ifname = dev[1].group_ifname
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
self.peer = None
self.go = None
self.group1 = None
self.group2 = None
self.groups_removed = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, dbus.PROPERTIES_IFACE,
"PropertiesChanged", byte_arrays=True)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.add_signal(self.groupFinished, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupFinished")
self.add_signal(self.peerJoined, WPAS_DBUS_GROUP,
"PeerJoined")
self.loop.run()
return self
def propertiesChanged(self, interface_name, changed_properties,
invalidated_properties):
logger.debug("propertiesChanged: interface_name=%s changed_properties=%s invalidated_properties=%s" % (interface_name, str(changed_properties), str(invalidated_properties)))
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
if addr2.replace(':', '') in path:
self.peer = path
elif addr1.replace(':', '') in path:
self.go = path
if self.go and not self.group1:
logger.info("Join the group")
p2p.StopFind()
pin = '12345670'
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.group_ifname = dev1_group_ifname
dev1.group_request("WPS_PIN any " + pin)
args = {'peer': self.go,
'join': True,
'wps_method': 'pin',
'pin': pin,
'frequency': 2412}
p2p.Connect(args)
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
prop = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE,
dbus_interface=dbus.PROPERTIES_IFACE)
logger.debug("p2pdevice properties: " + str(prop))
g_obj = bus.get_object(WPAS_DBUS_SERVICE,
properties['group_object'])
res = g_obj.GetAll(WPAS_DBUS_GROUP,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("Group properties: " + str(res))
if not self.group1:
self.group1 = properties['group_object']
self.group1iface = properties['interface_object']
self.g1_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
self.group1iface)
logger.info("Start autonomous GO")
params = dbus.Dictionary({'frequency': 2412})
p2p.GroupAdd(params)
elif not self.group2:
self.group2 = properties['group_object']
self.group2iface = properties['interface_object']
self.g2_if_obj = bus.get_object(WPAS_DBUS_SERVICE,
self.group2iface)
self.g2_bssid = res['BSSID']
if self.group1 and self.group2:
logger.info("Authorize peer to join the group")
a2 = binascii.unhexlify(addr2.replace(':', ''))
params = {'Role': 'enrollee',
'P2PDeviceAddress': dbus.ByteArray(a2),
'Bssid': dbus.ByteArray(a2),
'Type': 'pin',
'Pin': '12345670'}
g_wps = dbus.Interface(self.g2_if_obj, WPAS_DBUS_IFACE_WPS)
g_wps.Start(params)
bssid = ':'.join(["%02x" % i for i in struct.unpack('6B', self.g2_bssid)])
dev2 = WpaSupplicant('wlan2', '/tmp/wpas-wlan2')
dev2.scan_for_bss(bssid, freq=2412)
dev2.global_request("P2P_CONNECT " + bssid + " 12345670 join freq=2412")
ev = dev2.wait_global_event(["P2P-GROUP-STARTED"], timeout=15)
if ev is None:
raise Exception("Group join timed out")
self.dev2_group_ev = ev
def groupFinished(self, properties):
logger.debug("groupFinished: " + str(properties))
if self.group1 == properties['group_object']:
self.group1 = None
elif self.group2 == properties['group_object']:
self.group2 = None
if not self.group1 and not self.group2:
self.done = True
self.loop.quit()
def peerJoined(self, peer):
logger.debug("peerJoined: " + peer)
if self.groups_removed:
return
self.check_results()
dev2 = WpaSupplicant('wlan2', '/tmp/wpas-wlan2')
dev2.group_form_result(self.dev2_group_ev)
dev2.remove_group()
logger.info("Disconnect group2")
group_p2p = dbus.Interface(self.g2_if_obj,
WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
logger.info("Disconnect group1")
group_p2p = dbus.Interface(self.g1_if_obj,
WPAS_DBUS_IFACE_P2PDEVICE)
group_p2p.Disconnect()
self.groups_removed = True
def check_results(self):
logger.info("Check results with two concurrent groups in operation")
g1_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group1)
res1 = g1_obj.GetAll(WPAS_DBUS_GROUP,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
g2_obj = bus.get_object(WPAS_DBUS_SERVICE, self.group2)
res2 = g2_obj.GetAll(WPAS_DBUS_GROUP,
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.info("group1 = " + self.group1)
logger.debug("Group properties: " + str(res1))
logger.info("group2 = " + self.group2)
logger.debug("Group properties: " + str(res2))
prop = if_obj.GetAll(WPAS_DBUS_IFACE_P2PDEVICE,
dbus_interface=dbus.PROPERTIES_IFACE)
logger.debug("p2pdevice properties: " + str(prop))
if res1['Role'] != 'client':
raise Exception("Group1 role reported incorrectly: " + res1['Role'])
if res2['Role'] != 'GO':
raise Exception("Group2 role reported incorrectly: " + res2['Role'])
if prop['Role'] != 'device':
raise Exception("p2pdevice role reported incorrectly: " + prop['Role'])
if len(res2['Members']) != 1:
raise Exception("Unexpected Members value for group 2")
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
dev[1].remove_group()
def test_dbus_p2p_cancel(dev, apdev):
"""D-Bus P2P Cancel"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
try:
p2p.Cancel()
raise Exception("Unexpected p2p.Cancel() success")
except dbus.exceptions.DBusException as e:
pass
addr0 = dev[0].p2p_dev_addr()
dev[1].p2p_listen()
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.deviceFound, WPAS_DBUS_IFACE_P2PDEVICE,
"DeviceFound")
self.loop.run()
return self
def deviceFound(self, path):
logger.debug("deviceFound: path=%s" % path)
args = {'peer': path, 'wps_method': 'keypad', 'pin': '12345670',
'go_intent': 0}
p2p.Connect(args)
p2p.Cancel()
self.done = True
self.loop.quit()
def run_test(self, *args):
logger.debug("run_test")
p2p.Find(dbus.Dictionary({'DiscoveryType': 'social'}))
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_p2p_ip_addr(dev, apdev):
"""D-Bus P2P and IP address parameters"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
p2p = dbus.Interface(if_obj, WPAS_DBUS_IFACE_P2PDEVICE)
vals = [("IpAddrGo", "192.168.43.1"),
("IpAddrMask", "255.255.255.0"),
("IpAddrStart", "192.168.43.100"),
("IpAddrEnd", "192.168.43.199")]
for field, value in vals:
if_obj.Set(WPAS_DBUS_IFACE, field, value,
dbus_interface=dbus.PROPERTIES_IFACE)
val = if_obj.Get(WPAS_DBUS_IFACE, field,
dbus_interface=dbus.PROPERTIES_IFACE)
if val != value:
raise Exception("Unexpected %s value: %s" % (field, val))
set_ip_addr_info(dev[1])
dev[0].global_request("SET p2p_go_intent 0")
req = dev[0].global_request("NFC_GET_HANDOVER_REQ NDEF P2P-CR").rstrip()
if "FAIL" in req:
raise Exception("Failed to generate NFC connection handover request")
sel = dev[1].global_request("NFC_GET_HANDOVER_SEL NDEF P2P-CR").rstrip()
if "FAIL" in sel:
raise Exception("Failed to generate NFC connection handover select")
dev[0].dump_monitor()
dev[1].dump_monitor()
res = dev[1].global_request("NFC_REPORT_HANDOVER RESP P2P " + req + " " + sel)
if "FAIL" in res:
raise Exception("Failed to report NFC connection handover to wpa_supplicant(resp)")
res = dev[0].global_request("NFC_REPORT_HANDOVER INIT P2P " + req + " " + sel)
if "FAIL" in res:
raise Exception("Failed to report NFC connection handover to wpa_supplicant(init)")
class TestDbusP2p(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.groupStarted, WPAS_DBUS_IFACE_P2PDEVICE,
"GroupStarted")
self.loop.run()
return self
def groupStarted(self, properties):
logger.debug("groupStarted: " + str(properties))
self.loop.quit()
if 'IpAddrGo' not in properties:
logger.info("IpAddrGo missing from GroupStarted")
ip_addr_go = properties['IpAddrGo']
addr = "%d.%d.%d.%d" % (ip_addr_go[0], ip_addr_go[1], ip_addr_go[2], ip_addr_go[3])
if addr != "192.168.42.1":
logger.info("Unexpected IpAddrGo value: " + addr)
self.done = True
def run_test(self, *args):
logger.debug("run_test")
return False
def success(self):
return self.done
with TestDbusP2p(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_introspect(dev, apdev):
"""D-Bus introspection"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
res = if_obj.Introspect(WPAS_DBUS_IFACE,
dbus_interface=dbus.INTROSPECTABLE_IFACE)
logger.info("Initial Introspect: " + str(res))
if res is None or "Introspectable" not in res or "GroupStarted" not in res:
raise Exception("Unexpected initial Introspect response: " + str(res))
if "FastReauth" not in res or "PassiveScan" not in res:
raise Exception("Unexpected initial Introspect response: " + str(res))
with alloc_fail(dev[0], 1, "wpa_dbus_introspect"):
res2 = if_obj.Introspect(WPAS_DBUS_IFACE,
dbus_interface=dbus.INTROSPECTABLE_IFACE)
logger.info("Introspect: " + str(res2))
if res2 is not None:
raise Exception("Unexpected Introspect response")
with alloc_fail(dev[0], 1, "=add_interface;wpa_dbus_introspect"):
res2 = if_obj.Introspect(WPAS_DBUS_IFACE,
dbus_interface=dbus.INTROSPECTABLE_IFACE)
logger.info("Introspect: " + str(res2))
if res2 is None:
raise Exception("No Introspect response")
if len(res2) >= len(res):
raise Exception("Unexpected Introspect response")
with alloc_fail(dev[0], 1, "wpabuf_alloc;add_interface;wpa_dbus_introspect"):
res2 = if_obj.Introspect(WPAS_DBUS_IFACE,
dbus_interface=dbus.INTROSPECTABLE_IFACE)
logger.info("Introspect: " + str(res2))
if res2 is None:
raise Exception("No Introspect response")
if len(res2) >= len(res):
raise Exception("Unexpected Introspect response")
with alloc_fail(dev[0], 2, "=add_interface;wpa_dbus_introspect"):
res2 = if_obj.Introspect(WPAS_DBUS_IFACE,
dbus_interface=dbus.INTROSPECTABLE_IFACE)
logger.info("Introspect: " + str(res2))
if res2 is None:
raise Exception("No Introspect response")
if len(res2) >= len(res):
raise Exception("Unexpected Introspect response")
def run_busctl(service, obj):
if not shutil.which("busctl"):
raise HwsimSkip("No busctl available")
logger.info("busctl introspect %s %s" % (service, obj))
cmd = subprocess.Popen(['busctl', 'introspect', service, obj],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out = cmd.communicate()
cmd.wait()
logger.info("busctl stdout:\n%s" % out[0].strip())
if len(out[1]) > 0:
logger.info("busctl stderr: %s" % out[1].decode().strip())
if "Duplicate property" in out[1].decode():
raise Exception("Duplicate property")
def test_dbus_introspect_busctl(dev, apdev):
"""D-Bus introspection with busctl"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
ifaces = dbus_get(dbus, wpas_obj, "Interfaces")
run_busctl(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH)
run_busctl(WPAS_DBUS_SERVICE, WPAS_DBUS_PATH + "/Interfaces")
run_busctl(WPAS_DBUS_SERVICE, ifaces[0])
hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq=2412)
id = dev[0].add_network()
dev[0].set_network(id, "disabled", "0")
dev[0].set_network_quoted(id, "ssid", "test")
run_busctl(WPAS_DBUS_SERVICE, ifaces[0] + "/BSSs/0")
run_busctl(WPAS_DBUS_SERVICE, ifaces[0] + "/Networks/0")
def test_dbus_ap(dev, apdev):
"""D-Bus AddNetwork for AP mode"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "test-wpa2-psk"
passphrase = 'qwertyuiop'
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.started = False
self.sta_added = False
self.sta_removed = False
self.authorized = False
self.deauthorized = False
self.stations = False
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.networkAdded, WPAS_DBUS_IFACE, "NetworkAdded")
self.add_signal(self.networkSelected, WPAS_DBUS_IFACE,
"NetworkSelected")
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.add_signal(self.stationAdded, WPAS_DBUS_IFACE, "StationAdded")
self.add_signal(self.stationRemoved, WPAS_DBUS_IFACE,
"StationRemoved")
self.add_signal(self.staAuthorized, WPAS_DBUS_IFACE,
"StaAuthorized")
self.add_signal(self.staDeauthorized, WPAS_DBUS_IFACE,
"StaDeauthorized")
self.loop.run()
return self
def networkAdded(self, network, properties):
logger.debug("networkAdded: %s" % str(network))
logger.debug(str(properties))
def networkSelected(self, network):
logger.debug("networkSelected: %s" % str(network))
self.network_selected = True
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
self.started = True
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.connect(ssid, psk=passphrase, scan_freq="2412")
def stationAdded(self, station, properties):
logger.debug("stationAdded: %s" % str(station))
logger.debug(str(properties))
self.sta_added = True
res = if_obj.Get(WPAS_DBUS_IFACE, 'Stations',
dbus_interface=dbus.PROPERTIES_IFACE)
logger.info("Stations: " + str(res))
if len(res) == 1:
self.stations = True
else:
raise Exception("Missing Stations entry: " + str(res))
def stationRemoved(self, station):
logger.debug("stationRemoved: %s" % str(station))
self.sta_removed = True
res = if_obj.Get(WPAS_DBUS_IFACE, 'Stations',
dbus_interface=dbus.PROPERTIES_IFACE)
logger.info("Stations: " + str(res))
if len(res) != 0:
self.stations = False
raise Exception("Unexpected Stations entry: " + str(res))
self.loop.quit()
def staAuthorized(self, name):
logger.debug("staAuthorized: " + name)
self.authorized = True
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.request("DISCONNECT")
def staDeauthorized(self, name):
logger.debug("staDeauthorized: " + name)
self.deauthorized = True
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'WPA-PSK',
'psk': passphrase,
'mode': 2,
'frequency': 2412,
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
return self.started and self.sta_added and self.sta_removed and \
self.authorized and self.deauthorized
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_ap_scan(dev, apdev):
"""D-Bus AddNetwork for AP mode and scan"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "test-wpa2-psk"
passphrase = 'qwertyuiop'
hapd = hostapd.add_ap(apdev[0], {"ssid": "open"})
bssid = hapd.own_addr()
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.started = False
self.scan_completed = False
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.add_signal(self.scanDone, WPAS_DBUS_IFACE, "ScanDone")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
self.started = True
logger.info("Try to scan in AP mode")
iface.Scan({'Type': 'active',
'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
logger.info("Scan() returned")
def scanDone(self, success):
logger.debug("scanDone: success=%s" % success)
if self.started:
self.scan_completed = True
self.loop.quit()
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'WPA-PSK',
'psk': passphrase,
'mode': 2,
'frequency': 2412,
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
return self.started and self.scan_completed
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_connect_wpa_eap(dev, apdev):
"""D-Bus AddNetwork and connection with WPA+WPA2-Enterprise AP"""
skip_without_tkip(dev[0])
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "test-wpa-eap"
params = hostapd.wpa_eap_params(ssid=ssid)
params["wpa"] = "3"
params["rsn_pairwise"] = "CCMP"
hapd = hostapd.add_ap(apdev[0], params)
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.add_signal(self.eap, WPAS_DBUS_IFACE, "EAP")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
self.done = True
self.loop.quit()
def eap(self, status, parameter):
logger.debug("EAP: status=%s parameter=%s" % (status, parameter))
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'WPA-EAP',
'eap': 'PEAP',
'identity': 'user',
'password': 'password',
'ca_cert': 'auth_serv/ca.pem',
'phase2': 'auth=MSCHAPV2',
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
return self.done
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_ap_scan_2_ap_mode_scan(dev, apdev):
"""AP_SCAN 2 AP mode and D-Bus Scan()"""
try:
_test_dbus_ap_scan_2_ap_mode_scan(dev, apdev)
finally:
dev[0].request("AP_SCAN 1")
def _test_dbus_ap_scan_2_ap_mode_scan(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
if "OK" not in dev[0].request("AP_SCAN 2"):
raise Exception("Failed to set AP_SCAN 2")
id = dev[0].add_network()
dev[0].set_network(id, "mode", "2")
dev[0].set_network_quoted(id, "ssid", "wpas-ap-open")
dev[0].set_network(id, "key_mgmt", "NONE")
dev[0].set_network(id, "frequency", "2412")
dev[0].set_network(id, "scan_freq", "2412")
dev[0].set_network(id, "disabled", "0")
dev[0].select_network(id)
ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5)
if ev is None:
raise Exception("AP failed to start")
with fail_test(dev[0], 1, "wpa_driver_nl80211_scan"):
iface.Scan({'Type': 'active',
'AllowRoam': True,
'Channels': [(dbus.UInt32(2412), dbus.UInt32(20))]})
ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED",
"AP-DISABLED"], timeout=5)
if ev is None:
raise Exception("CTRL-EVENT-SCAN-FAILED not seen")
if "AP-DISABLED" in ev:
raise Exception("Unexpected AP-DISABLED event")
if "retry=1" in ev:
# Wait for the retry to scan happen
ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED",
"AP-DISABLED"], timeout=5)
if ev is None:
raise Exception("CTRL-EVENT-SCAN-FAILED not seen - retry")
if "AP-DISABLED" in ev:
raise Exception("Unexpected AP-DISABLED event - retry")
dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412")
dev[1].request("DISCONNECT")
dev[1].wait_disconnected()
dev[0].request("DISCONNECT")
dev[0].wait_disconnected()
def test_dbus_expectdisconnect(dev, apdev):
"""D-Bus ExpectDisconnect"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
wpas = dbus.Interface(wpas_obj, WPAS_DBUS_SERVICE)
params = {"ssid": "test-open"}
hapd = hostapd.add_ap(apdev[0], params)
dev[0].connect("test-open", key_mgmt="NONE", scan_freq="2412")
# This does not really verify the behavior other than by going through the
# code path for additional coverage.
wpas.ExpectDisconnect()
dev[0].request("DISCONNECT")
dev[0].wait_disconnected()
def test_dbus_save_config(dev, apdev):
"""D-Bus SaveConfig"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
try:
iface.SaveConfig()
raise Exception("SaveConfig() accepted unexpectedly")
except dbus.exceptions.DBusException as e:
if not str(e).startswith("fi.w1.wpa_supplicant1.UnknownError: Not allowed to update configuration"):
raise Exception("Unexpected error message for SaveConfig(): " + str(e))
def test_dbus_vendor_elem(dev, apdev):
"""D-Bus vendor element operations"""
try:
_test_dbus_vendor_elem(dev, apdev)
finally:
dev[0].request("VENDOR_ELEM_REMOVE 1 *")
def _test_dbus_vendor_elem(dev, apdev):
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
dev[0].request("VENDOR_ELEM_REMOVE 1 *")
try:
ie = dbus.ByteArray(b"\x00\x00")
iface.VendorElemAdd(-1, ie)
raise Exception("Invalid VendorElemAdd() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "Invalid ID" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemAdd[1]: " + str(e))
try:
ie = dbus.ByteArray(b'')
iface.VendorElemAdd(1, ie)
raise Exception("Invalid VendorElemAdd() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "Invalid value" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemAdd[2]: " + str(e))
try:
ie = dbus.ByteArray(b"\x00\x01")
iface.VendorElemAdd(1, ie)
raise Exception("Invalid VendorElemAdd() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "Parse error" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemAdd[3]: " + str(e))
try:
iface.VendorElemGet(-1)
raise Exception("Invalid VendorElemGet() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "Invalid ID" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemGet[1]: " + str(e))
try:
iface.VendorElemGet(1)
raise Exception("Invalid VendorElemGet() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "ID value does not exist" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemGet[2]: " + str(e))
try:
ie = dbus.ByteArray(b"\x00\x00")
iface.VendorElemRem(-1, ie)
raise Exception("Invalid VendorElemRemove() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "Invalid ID" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemRemove[1]: " + str(e))
try:
ie = dbus.ByteArray(b'')
iface.VendorElemRem(1, ie)
raise Exception("Invalid VendorElemRemove() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "Invalid value" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemRemove[1]: " + str(e))
iface.VendorElemRem(1, b"*")
ie = dbus.ByteArray(b"\x00\x01\x00")
iface.VendorElemAdd(1, ie)
val = iface.VendorElemGet(1)
if len(val) != len(ie):
raise Exception("Unexpected VendorElemGet length")
for i in range(len(val)):
if val[i] != dbus.Byte(ie[i]):
raise Exception("Unexpected VendorElemGet data")
ie2 = dbus.ByteArray(b"\xe0\x00")
iface.VendorElemAdd(1, ie2)
ies = ie + ie2
val = iface.VendorElemGet(1)
if len(val) != len(ies):
raise Exception("Unexpected VendorElemGet length[2]")
for i in range(len(val)):
if val[i] != dbus.Byte(ies[i]):
raise Exception("Unexpected VendorElemGet data[2]")
try:
test_ie = dbus.ByteArray(b"\x01\x01")
iface.VendorElemRem(1, test_ie)
raise Exception("Invalid VendorElemRemove() accepted")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "Parse error" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemRemove[1]: " + str(e))
iface.VendorElemRem(1, ie)
val = iface.VendorElemGet(1)
if len(val) != len(ie2):
raise Exception("Unexpected VendorElemGet length[3]")
iface.VendorElemRem(1, b"*")
try:
iface.VendorElemGet(1)
raise Exception("Invalid VendorElemGet() accepted after removal")
except dbus.exceptions.DBusException as e:
if "InvalidArgs" not in str(e) or "ID value does not exist" not in str(e):
raise Exception("Unexpected error message for invalid VendorElemGet after removal: " + str(e))
def test_dbus_assoc_reject(dev, apdev):
"""D-Bus AssocStatusCode"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "test-open"
params = {"ssid": ssid,
"max_listen_interval": "1"}
hapd = hostapd.add_ap(apdev[0], params)
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.assoc_status_seen = False
self.state = 0
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'AssocStatusCode' in properties:
status = properties['AssocStatusCode']
if status != 51:
logger.info("Unexpected status code: " + str(status))
else:
self.assoc_status_seen = True
iface.Disconnect()
self.loop.quit()
def run_connect(self, *args):
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'NONE',
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
return self.assoc_status_seen
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_mesh(dev, apdev):
"""D-Bus mesh"""
check_mesh_support(dev[0])
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
mesh = dbus.Interface(if_obj, WPAS_DBUS_IFACE_MESH)
add_open_mesh_network(dev[1])
addr1 = dev[1].own_addr()
class TestDbusMesh(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.done = False
def __enter__(self):
gobject.timeout_add(1, self.run_test)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.meshGroupStarted, WPAS_DBUS_IFACE_MESH,
"MeshGroupStarted")
self.add_signal(self.meshGroupRemoved, WPAS_DBUS_IFACE_MESH,
"MeshGroupRemoved")
self.add_signal(self.meshPeerConnected, WPAS_DBUS_IFACE_MESH,
"MeshPeerConnected")
self.add_signal(self.meshPeerDisconnected, WPAS_DBUS_IFACE_MESH,
"MeshPeerDisconnected")
self.loop.run()
return self
def meshGroupStarted(self, args):
logger.debug("MeshGroupStarted: " + str(args))
def meshGroupRemoved(self, args):
logger.debug("MeshGroupRemoved: " + str(args))
self.done = True
self.loop.quit()
def meshPeerConnected(self, args):
logger.debug("MeshPeerConnected: " + str(args))
res = if_obj.Get(WPAS_DBUS_IFACE_MESH, 'MeshPeers',
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("MeshPeers: " + str(res))
if len(res) != 1:
raise Exception("Unexpected number of MeshPeer values")
if binascii.hexlify(res[0]).decode() != addr1.replace(':', ''):
raise Exception("Unexpected peer address")
res = if_obj.Get(WPAS_DBUS_IFACE_MESH, 'MeshGroup',
dbus_interface=dbus.PROPERTIES_IFACE,
byte_arrays=True)
logger.debug("MeshGroup: " + str(res))
if res != b"wpas-mesh-open":
raise Exception("Unexpected MeshGroup")
dev1 = WpaSupplicant('wlan1', '/tmp/wpas-wlan1')
dev1.mesh_group_remove()
def meshPeerDisconnected(self, args):
logger.debug("MeshPeerDisconnected: " + str(args))
dev0 = WpaSupplicant('wlan0', '/tmp/wpas-wlan0')
dev0.mesh_group_remove()
def run_test(self, *args):
logger.debug("run_test")
dev0 = WpaSupplicant('wlan0', '/tmp/wpas-wlan0')
add_open_mesh_network(dev0)
return False
def success(self):
return self.done
with TestDbusMesh(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_roam(dev, apdev):
"""D-Bus Roam"""
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
ssid = "test-wpa2-psk"
passphrase = 'qwertyuiop'
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
hapd = hostapd.add_ap(apdev[0], params)
hapd2 = hostapd.add_ap(apdev[1], params)
bssid = apdev[0]['bssid']
dev[0].scan_for_bss(bssid, freq=2412)
bssid2 = apdev[1]['bssid']
dev[0].scan_for_bss(bssid2, freq=2412)
class TestDbusConnect(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.state = 0
def __enter__(self):
gobject.timeout_add(1, self.run_connect)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.propertiesChanged, WPAS_DBUS_IFACE,
"PropertiesChanged")
self.loop.run()
return self
def propertiesChanged(self, properties):
logger.debug("propertiesChanged: %s" % str(properties))
if 'State' in properties and properties['State'] == "completed":
if self.state == 0:
self.state = 1
cur = properties["CurrentBSS"]
bss_obj = bus.get_object(WPAS_DBUS_SERVICE, cur)
res = bss_obj.Get(WPAS_DBUS_BSS, 'BSSID',
dbus_interface=dbus.PROPERTIES_IFACE)
bssid_str = ''
for item in res:
if len(bssid_str) > 0:
bssid_str += ':'
bssid_str += '%02x' % item
dst = bssid if bssid_str == bssid2 else bssid2
iface.Roam(dst)
elif self.state == 1:
if "RoamComplete" in properties and \
properties["RoamComplete"]:
self.state = 2
self.loop.quit()
def run_connect(self, *args):
logger.debug("run_connect")
args = dbus.Dictionary({'ssid': ssid,
'key_mgmt': 'WPA-PSK',
'psk': passphrase,
'scan_freq': 2412},
signature='sv')
self.netw = iface.AddNetwork(args)
iface.SelectNetwork(self.netw)
return False
def success(self):
return self.state == 2
with TestDbusConnect(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")
def test_dbus_creds(dev, apdev):
"D-Bus interworking credentials"
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
args = {'domain': 'server.w1.fi',
'realm': 'server.w1.fi',
'roaming_consortium': '50a9bf',
'required_roaming_consortium': '23bf50',
'eap': 'TTLS',
'phase2': 'auth=MSCHAPV2',
'username': 'user',
'password': 'password',
'domain_suffix_match': 'server.w1.fi',
'ca_cert': 'auth_serv/ca.pem'}
path = iface.AddCred(dbus.Dictionary(args, signature='sv'))
for k, v in args.items():
if k == 'password':
continue
prop = dev[0].get_cred(0, k)
if prop != v:
raise Exception('Credential add failed: %s does not match %s' % (prop, v))
iface.RemoveCred(path)
if not "FAIL" in dev[0].get_cred(0, 'domain'):
raise Exception("Credential remove failed")
# Removal of multiple credentials
cred1 = {'domain': 'server1.w1.fi','realm': 'server1.w1.fi','eap': 'TTLS'}
iface.AddCred(dbus.Dictionary(cred1, signature='sv'))
if "FAIL" in dev[0].get_cred(0, 'domain'):
raise Exception("Failed to add credential")
cred2 = {'domain': 'server2.w1.fi','realm': 'server2.w1.fi','eap': 'TTLS'}
iface.AddCred(dbus.Dictionary(cred2, signature='sv'))
if "FAIL" in dev[0].get_cred(1, 'domain'):
raise Exception("Failed to add credential")
iface.RemoveAllCreds()
if not "FAIL" in dev[0].get_cred(0, 'domain'):
raise Exception("Credential remove failed")
if not "FAIL" in dev[0].get_cred(1, 'domain'):
raise Exception("Credential remove failed")
def test_dbus_interworking(dev, apdev):
"D-Bus interworking selection"
(bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0])
iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE)
params = {"ssid": "test-interworking", "wpa": "2",
"wpa_key_mgmt": "WPA-EAP", "rsn_pairwise": "CCMP",
"ieee8021x": "1", "eapol_version": "2",
"eap_server": "1", "eap_user_file": "auth_serv/eap_user.conf",
"ca_cert": "auth_serv/ca.pem",
"server_cert": "auth_serv/server.pem",
"private_key": "auth_serv/server.key",
"interworking": "1",
"domain_name": "server.w1.fi",
"nai_realm": "0,server.w1.fi,21[2:4][5:7]",
"roaming_consortium": "2233445566",
"hs20": "1", "anqp_domain_id": "1234"}
hapd = hostapd.add_ap(apdev[0], params)
class TestDbusInterworking(TestDbus):
def __init__(self, bus):
TestDbus.__init__(self, bus)
self.interworking_ap_seen = False
self.interworking_select_done = False
def __enter__(self):
gobject.timeout_add(1, self.run_select)
gobject.timeout_add(15000, self.timeout)
self.add_signal(self.interworkingAPAdded, WPAS_DBUS_IFACE,
"InterworkingAPAdded")
self.add_signal(self.interworkingSelectDone, WPAS_DBUS_IFACE,
"InterworkingSelectDone")
self.loop.run()
return self
def interworkingAPAdded(self, bss, cred, properties):
logger.debug("interworkingAPAdded: bss=%s cred=%s %s" % (bss, cred, str(properties)))
if self.cred == cred:
self.interworking_ap_seen = True
def interworkingSelectDone(self):
logger.debug("interworkingSelectDone")
self.interworking_select_done = True
self.loop.quit()
def run_select(self, *args):
args = {"domain": "server.w1.fi",
"realm": "server.w1.fi",
"eap": "TTLS",
"phase2": "auth=MSCHAPV2",
"username": "user",
"password": "password",
"domain_suffix_match": "server.w1.fi",
"ca_cert": "auth_serv/ca.pem"}
self.cred = iface.AddCred(dbus.Dictionary(args, signature='sv'))
iface.InterworkingSelect()
return False
def success(self):
return self.interworking_ap_seen and self.interworking_select_done
with TestDbusInterworking(bus) as t:
if not t.success():
raise Exception("Expected signals not seen")