From a02fdac7348afb0bd4bc1caf08d65ee13322ed58 Mon Sep 17 00:00:00 2001
From: Bernhard M. Wiedemann <bwiedemann+opensusegit@suse.de>
Date: Apr 23 2020 16:31:13 +0000
Subject: update 2020-04-23 16:31


---

diff --git a/.files b/.files
index 97cde5f..712f625 100644
Binary files a/.files and b/.files differ
diff --git a/.rev b/.rev
index b2433d4..82e9a86 100644
--- a/.rev
+++ b/.rev
@@ -630,4 +630,12 @@
     <comment></comment>
     <requestid>789823</requestid>
   </revision>
+  <revision rev="78" vrev="3">
+    <srcmd5>90f9e4b3589deeddc681789cc7159791</srcmd5>
+    <version>2.9</version>
+    <time>1587659350</time>
+    <user>dimstar_suse</user>
+    <comment></comment>
+    <requestid>796019</requestid>
+  </revision>
 </revisionlist>
diff --git a/fi.epitest.hostap.WPASupplicant.service b/fi.epitest.hostap.WPASupplicant.service
new file mode 100644
index 0000000..f16eaef
--- /dev/null
+++ b/fi.epitest.hostap.WPASupplicant.service
@@ -0,0 +1,5 @@
+[D-BUS Service]
+Name=fi.epitest.hostap.WPASupplicant
+Exec=/usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -u -t -f /var/log/wpa_supplicant.log
+User=root
+SystemdService=wpa_supplicant.service
diff --git a/restore-old-dbus-interface.patch b/restore-old-dbus-interface.patch
new file mode 100644
index 0000000..4248993
--- /dev/null
+++ b/restore-old-dbus-interface.patch
@@ -0,0 +1,3180 @@
+commit 3d256b3e5c7e3673c11a4130970227012e9518d3
+Author: Bernhard M. Wiedemann <bwiedemann@suse.de>
+Date:   Fri Apr 17 10:34:30 2020 +0200
+
+    Revert "wpa_supplicant: Drop the old D-Bus interface support"
+    
+    This reverts commit 6a8dee76d4090287c016680c009b1334e01b5fbd.
+    
+    Because https://bugzilla.opensuse.org/show_bug.cgi?id=1156920
+    wicked still uses the old dbus interface
+    and porting it is hard.
+
+diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
+index b5d982de3..37be1ce35 100644
+--- a/wpa_supplicant/Android.mk
++++ b/wpa_supplicant/Android.mk
+@@ -1448,25 +1448,44 @@ endif
+ OBJS += ctrl_iface.c ctrl_iface_$(CONFIG_CTRL_IFACE).c
+ endif
+ 
++ifdef CONFIG_CTRL_IFACE_DBUS
++DBUS=y
++DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE
++DBUS_OBJS += dbus/dbus_old.c dbus/dbus_old_handlers.c
++ifdef CONFIG_WPS
++DBUS_OBJS += dbus/dbus_old_handlers_wps.c
++endif
++DBUS_OBJS += dbus/dbus_dict_helpers.c
++DBUS_CFLAGS += $(DBUS_INCLUDE)
++endif
++
+ ifdef CONFIG_CTRL_IFACE_DBUS_NEW
+-L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
+-OBJS += dbus/dbus_dict_helpers.c
+-OBJS += dbus/dbus_new_helpers.c
+-OBJS += dbus/dbus_new.c dbus/dbus_new_handlers.c
+-OBJS += dbus/dbus_common.c
++DBUS=y
++DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
++DBUS_OBJS ?= dbus/dbus_dict_helpers.c
++DBUS_OBJS += dbus/dbus_new_helpers.c
++DBUS_OBJS += dbus/dbus_new.c dbus/dbus_new_handlers.c
+ ifdef CONFIG_WPS
+-OBJS += dbus/dbus_new_handlers_wps.c
++DBUS_OBJS += dbus/dbus_new_handlers_wps.c
+ endif
+ ifdef CONFIG_P2P
+-OBJS += dbus/dbus_new_handlers_p2p.c
++DBUS_OBJS += dbus/dbus_new_handlers_p2p.c
+ endif
+ ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
+-OBJS += dbus/dbus_new_introspect.c
+-L_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
++DBUS_OBJS += dbus/dbus_new_introspect.c
++DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
+ endif
+-L_CFLAGS += $(DBUS_INCLUDE)
++DBUS_CFLAGS += $(DBUS_INCLUDE)
+ endif
+ 
++ifdef DBUS
++DBUS_CFLAGS += -DCONFIG_DBUS
++DBUS_OBJS += dbus/dbus_common.c
++endif
++
++OBJS += $(DBUS_OBJS)
++L_CFLAGS += $(DBUS_CFLAGS)
++
+ ifdef CONFIG_CTRL_IFACE_BINDER
+ WPA_SUPPLICANT_USE_BINDER=y
+ L_CFLAGS += -DCONFIG_BINDER -DCONFIG_CTRL_IFACE_BINDER
+diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
+index f1384d5fa..9555495e1 100644
+--- a/wpa_supplicant/Makefile
++++ b/wpa_supplicant/Makefile
+@@ -55,6 +55,7 @@ ALL += systemd/wpa_supplicant.service
+ ALL += systemd/wpa_supplicant@.service
+ ALL += systemd/wpa_supplicant-nl80211@.service
+ ALL += systemd/wpa_supplicant-wired@.service
++ALL += dbus/fi.epitest.hostap.WPASupplicant.service
+ ALL += dbus/fi.w1.wpa_supplicant1.service
+ ifdef CONFIG_BUILD_WPA_CLIENT_SO
+ ALL += libwpa_client.so
+@@ -1605,17 +1606,35 @@ endif
+ OBJS += ctrl_iface.o ctrl_iface_$(CONFIG_CTRL_IFACE).o
+ endif
+ 
++ifdef CONFIG_CTRL_IFACE_DBUS
++DBUS=y
++DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE
++DBUS_OBJS += dbus/dbus_old.o dbus/dbus_old_handlers.o
++ifdef CONFIG_WPS
++DBUS_OBJS += dbus/dbus_old_handlers_wps.o
++endif
++DBUS_OBJS += dbus/dbus_dict_helpers.o
++ifndef DBUS_LIBS
++DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
++endif
++ifndef DBUS_INCLUDE
++DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
++endif
++DBUS_CFLAGS += $(DBUS_INCLUDE)
++DBUS_INTERFACE=fi.epitest.hostap.WPASupplicant
++endif
++
+ ifdef CONFIG_CTRL_IFACE_DBUS_NEW
+-CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
+-OBJS += dbus/dbus_dict_helpers.o
+-OBJS += dbus/dbus_new_helpers.o
+-OBJS += dbus/dbus_new.o dbus/dbus_new_handlers.o
+-OBJS += dbus/dbus_common.o
++DBUS=y
++DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
++DBUS_OBJS ?= dbus/dbus_dict_helpers.o
++DBUS_OBJS += dbus/dbus_new_helpers.o
++DBUS_OBJS += dbus/dbus_new.o dbus/dbus_new_handlers.o
+ ifdef CONFIG_WPS
+-OBJS += dbus/dbus_new_handlers_wps.o
++DBUS_OBJS += dbus/dbus_new_handlers_wps.o
+ endif
+ ifdef CONFIG_P2P
+-OBJS += dbus/dbus_new_handlers_p2p.o
++DBUS_OBJS += dbus/dbus_new_handlers_p2p.o
+ endif
+ ifndef DBUS_LIBS
+ DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
+@@ -1624,13 +1643,22 @@ ifndef DBUS_INCLUDE
+ DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
+ endif
+ ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
+-OBJS += dbus/dbus_new_introspect.o
+-CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
++DBUS_OBJS += dbus/dbus_new_introspect.o
++DBUS_CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_INTRO
+ endif
+-CFLAGS += $(DBUS_INCLUDE)
+-LIBS += $(DBUS_LIBS)
++DBUS_CFLAGS += $(DBUS_INCLUDE)
++DBUS_INTERFACE=fi.w1.wpa_supplicant1
+ endif
+ 
++ifdef DBUS
++DBUS_CFLAGS += -DCONFIG_DBUS
++DBUS_OBJS += dbus/dbus_common.o
++endif
++
++OBJS += $(DBUS_OBJS)
++CFLAGS += $(DBUS_CFLAGS)
++LIBS += $(DBUS_LIBS)
++
+ ifdef CONFIG_READLINE
+ OBJS_c += ../src/utils/edit_readline.o
+ LIBS_c += -lreadline -lncurses
+@@ -1992,11 +2020,13 @@ else
+ endif
+ 
+ %.service: %.service.in
+-	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
++	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' \
++		-e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
+ 	@$(E) "  sed" $<
+ 
+ %@.service: %.service.arg.in
+-	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
++	$(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' \
++		-e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
+ 	@$(E) "  sed" $<
+ 
+ wpa_supplicant.exe: wpa_supplicant
+diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
+index 6536c110a..854f48167 100644
+--- a/wpa_supplicant/android.config
++++ b/wpa_supplicant/android.config
+@@ -327,6 +327,10 @@ CONFIG_IEEE80211W=y
+ #CONFIG_NDIS_EVENTS_INTEGRATED=y
+ #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
+ 
++# Add support for old DBus control interface
++# (fi.epitest.hostap.WPASupplicant)
++#CONFIG_CTRL_IFACE_DBUS=y
++
+ # Add support for new DBus control interface
+ # (fi.w1.hostap.wpa_supplicant1)
+ #CONFIG_CTRL_IFACE_DBUS_NEW=y
+diff --git a/wpa_supplicant/dbus/Makefile b/wpa_supplicant/dbus/Makefile
+index 4d8700428..f355ebef5 100644
+--- a/wpa_supplicant/dbus/Makefile
++++ b/wpa_supplicant/dbus/Makefile
+@@ -36,6 +36,7 @@ CFLAGS += -DCONFIG_WPS
+ endif
+ 
+ CFLAGS += -DCONFIG_CTRL_IFACE_DBUS_NEW
++CFLAGS += -DCONFIG_CTRL_IFACE_DBUS
+ 
+ ifndef DBUS_LIBS
+ DBUS_LIBS := $(shell $(PKG_CONFIG) --libs dbus-1)
+@@ -53,6 +54,8 @@ CFLAGS += $(DBUS_INCLUDE)
+ 
+ LIB_OBJS= \
+ 	dbus_common.o \
++	dbus_old.o \
++	dbus_old_handlers.o \
+ 	dbus_new.o \
+ 	dbus_new_handlers.o \
+ 	dbus_new_helpers.o \
+@@ -60,6 +63,7 @@ LIB_OBJS= \
+ 	dbus_dict_helpers.o
+ 
+ ifdef CONFIG_WPS
++LIB_OBJS += dbus_old_handlers_wps.o
+ LIB_OBJS += dbus_new_handlers_wps.o
+ endif
+ 
+diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
+index e81b495f4..382dcb343 100644
+--- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
++++ b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf
+@@ -3,6 +3,11 @@
+  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+ <busconfig>
+         <policy user="root">
++                <allow own="fi.epitest.hostap.WPASupplicant"/>
++
++                <allow send_destination="fi.epitest.hostap.WPASupplicant"/>
++                <allow send_interface="fi.epitest.hostap.WPASupplicant"/>
++
+                 <allow own="fi.w1.wpa_supplicant1"/>
+ 
+                 <allow send_destination="fi.w1.wpa_supplicant1"/>
+@@ -10,6 +15,9 @@
+                 <allow receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
+         </policy>
+         <policy context="default">
++                <deny own="fi.epitest.hostap.WPASupplicant"/>
++                <deny send_destination="fi.epitest.hostap.WPASupplicant"/>
++
+                 <deny own="fi.w1.wpa_supplicant1"/>
+                 <deny send_destination="fi.w1.wpa_supplicant1"/>
+                 <deny receive_sender="fi.w1.wpa_supplicant1" receive_type="signal"/>
+diff --git a/wpa_supplicant/dbus/dbus_common.c b/wpa_supplicant/dbus/dbus_common.c
+index efa6c7b20..7ef6cad62 100644
+--- a/wpa_supplicant/dbus/dbus_common.c
++++ b/wpa_supplicant/dbus/dbus_common.c
+@@ -16,6 +16,7 @@
+ #include "dbus_common.h"
+ #include "dbus_common_i.h"
+ #include "dbus_new.h"
++#include "dbus_old.h"
+ #include "../wpa_supplicant_i.h"
+ 
+ 
+@@ -350,6 +351,9 @@ struct wpas_dbus_priv * wpas_dbus_init(struct wpa_global *global)
+ #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
+ 	    wpas_dbus_ctrl_iface_init(priv) < 0 ||
+ #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
++#ifdef CONFIG_CTRL_IFACE_DBUS
++	    wpa_supplicant_dbus_ctrl_iface_init(priv) < 0 ||
++#endif /* CONFIG_CTRL_IFACE_DBUS */
+ 	    wpas_dbus_init_common_finish(priv) < 0) {
+ 		wpas_dbus_deinit(priv);
+ 		return NULL;
+@@ -368,5 +372,9 @@ void wpas_dbus_deinit(struct wpas_dbus_priv *priv)
+ 	wpas_dbus_ctrl_iface_deinit(priv);
+ #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
+ 
++#ifdef CONFIG_CTRL_IFACE_DBUS
++	/* TODO: is any deinit needed? */
++#endif /* CONFIG_CTRL_IFACE_DBUS */
++
+ 	wpas_dbus_deinit_common(priv);
+ }
+diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c
+new file mode 100644
+index 000000000..88227af7c
+--- /dev/null
++++ b/wpa_supplicant/dbus/dbus_old.c
+@@ -0,0 +1,745 @@
++/*
++ * WPA Supplicant / dbus-based control interface
++ * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
++ *
++ * This software may be distributed under the terms of the BSD license.
++ * See README for more details.
++ */
++
++#include "includes.h"
++#include <dbus/dbus.h>
++
++#include "common.h"
++#include "eloop.h"
++#include "wps/wps.h"
++#include "../config.h"
++#include "../wpa_supplicant_i.h"
++#include "../bss.h"
++#include "dbus_old.h"
++#include "dbus_old_handlers.h"
++#include "dbus_common_i.h"
++
++
++/**
++ * wpas_dbus_decompose_object_path - Decompose an interface object path into parts
++ * @path: The dbus object path
++ * @network: (out) the configured network this object path refers to, if any
++ * @bssid: (out) the scanned bssid this object path refers to, if any
++ * Returns: The object path of the network interface this path refers to
++ *
++ * For a given object path, decomposes the object path into object id, network,
++ * and BSSID parts, if those parts exist.
++ */
++char * wpas_dbus_decompose_object_path(const char *path, char **network,
++				       char **bssid)
++{
++	const unsigned int dev_path_prefix_len =
++		strlen(WPAS_DBUS_PATH_INTERFACES "/");
++	char *obj_path_only;
++	char *next_sep;
++
++	/* Be a bit paranoid about path */
++	if (!path || strncmp(path, WPAS_DBUS_PATH_INTERFACES "/",
++			     dev_path_prefix_len))
++		return NULL;
++
++	/* Ensure there's something at the end of the path */
++	if ((path + dev_path_prefix_len)[0] == '\0')
++		return NULL;
++
++	obj_path_only = os_strdup(path);
++	if (obj_path_only == NULL)
++		return NULL;
++
++	next_sep = strchr(obj_path_only + dev_path_prefix_len, '/');
++	if (next_sep != NULL) {
++		const char *net_part = strstr(next_sep,
++					      WPAS_DBUS_NETWORKS_PART "/");
++		const char *bssid_part = strstr(next_sep,
++						WPAS_DBUS_BSSIDS_PART "/");
++
++		if (network && net_part) {
++			/* Deal with a request for a configured network */
++			const char *net_name = net_part +
++				strlen(WPAS_DBUS_NETWORKS_PART "/");
++			*network = NULL;
++			if (strlen(net_name))
++				*network = os_strdup(net_name);
++		} else if (bssid && bssid_part) {
++			/* Deal with a request for a scanned BSSID */
++			const char *bssid_name = bssid_part +
++				strlen(WPAS_DBUS_BSSIDS_PART "/");
++			if (strlen(bssid_name))
++				*bssid = os_strdup(bssid_name);
++			else
++				*bssid = NULL;
++		}
++
++		/* Cut off interface object path before "/" */
++		*next_sep = '\0';
++	}
++
++	return obj_path_only;
++}
++
++
++/**
++ * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message
++ * @message: Pointer to incoming dbus message this error refers to
++ * Returns: A dbus error message
++ *
++ * Convenience function to create and return an invalid interface error
++ */
++DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message)
++{
++	return dbus_message_new_error(
++		message, WPAS_ERROR_INVALID_IFACE,
++		"wpa_supplicant knows nothing about this interface.");
++}
++
++
++/**
++ * wpas_dbus_new_invalid_network_error - Return a new invalid network error message
++ * @message: Pointer to incoming dbus message this error refers to
++ * Returns: a dbus error message
++ *
++ * Convenience function to create and return an invalid network error
++ */
++DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message)
++{
++	return dbus_message_new_error(message, WPAS_ERROR_INVALID_NETWORK,
++				      "The requested network does not exist.");
++}
++
++
++/**
++ * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message
++ * @message: Pointer to incoming dbus message this error refers to
++ * Returns: a dbus error message
++ *
++ * Convenience function to create and return an invalid bssid error
++ */
++static DBusMessage * wpas_dbus_new_invalid_bssid_error(DBusMessage *message)
++{
++	return dbus_message_new_error(message, WPAS_ERROR_INVALID_BSSID,
++				      "The BSSID requested was invalid.");
++}
++
++
++/**
++ * wpas_dispatch_network_method - dispatch messages for configured networks
++ * @message: the incoming dbus message
++ * @wpa_s: a network interface's data
++ * @network_id: id of the configured network we're interested in
++ * Returns: a reply dbus message, or a dbus error message
++ *
++ * This function dispatches all incoming dbus messages for configured networks.
++ */
++static DBusMessage * wpas_dispatch_network_method(DBusMessage *message,
++						  struct wpa_supplicant *wpa_s,
++						  int network_id)
++{
++	DBusMessage *reply = NULL;
++	const char *method = dbus_message_get_member(message);
++	struct wpa_ssid *ssid;
++
++	ssid = wpa_config_get_network(wpa_s->conf, network_id);
++	if (ssid == NULL)
++		return wpas_dbus_new_invalid_network_error(message);
++
++	if (!strcmp(method, "set"))
++		reply = wpas_dbus_iface_set_network(message, wpa_s, ssid);
++	else if (!strcmp(method, "enable"))
++		reply = wpas_dbus_iface_enable_network(message, wpa_s, ssid);
++	else if (!strcmp(method, "disable"))
++		reply = wpas_dbus_iface_disable_network(message, wpa_s, ssid);
++
++	return reply;
++}
++
++
++/**
++ * wpas_dispatch_bssid_method - dispatch messages for scanned networks
++ * @message: the incoming dbus message
++ * @wpa_s: a network interface's data
++ * @bssid: bssid of the scanned network we're interested in
++ * Returns: a reply dbus message, or a dbus error message
++ *
++ * This function dispatches all incoming dbus messages for scanned networks.
++ */
++static DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message,
++						struct wpa_supplicant *wpa_s,
++						const char *bssid_txt)
++{
++	u8 bssid[ETH_ALEN];
++	struct wpa_bss *bss;
++
++	if (hexstr2bin(bssid_txt, bssid, ETH_ALEN) < 0)
++		return wpas_dbus_new_invalid_bssid_error(message);
++
++	bss = wpa_bss_get_bssid(wpa_s, bssid);
++	if (bss == NULL)
++		return wpas_dbus_new_invalid_bssid_error(message);
++
++	/* Dispatch the method call against the scanned bssid */
++	if (os_strcmp(dbus_message_get_member(message), "properties") == 0)
++		return wpas_dbus_bssid_properties(message, wpa_s, bss);
++
++	return NULL;
++}
++
++
++/**
++ * wpas_iface_message_handler - Dispatch messages for interfaces or networks
++ * @connection: Connection to the system message bus
++ * @message: An incoming dbus message
++ * @user_data: A pointer to a dbus control interface data structure
++ * Returns: Whether or not the message was handled
++ *
++ * This function dispatches all incoming dbus messages for network interfaces,
++ * or objects owned by them, such as scanned BSSIDs and configured networks.
++ */
++static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
++						    DBusMessage *message,
++						    void *user_data)
++{
++	struct wpa_supplicant *wpa_s = user_data;
++	const char *method = dbus_message_get_member(message);
++	const char *path = dbus_message_get_path(message);
++	const char *msg_interface = dbus_message_get_interface(message);
++	char *iface_obj_path = NULL;
++	char *network = NULL;
++	char *bssid = NULL;
++	DBusMessage *reply = NULL;
++
++	/* Caller must specify a message interface */
++	if (!msg_interface)
++		goto out;
++
++	wpa_printf(MSG_MSGDUMP, "dbus[old/iface]: %s.%s (%s) [%s]",
++		   msg_interface, method, path,
++		   dbus_message_get_signature(message));
++
++	iface_obj_path = wpas_dbus_decompose_object_path(path, &network,
++							 &bssid);
++	if (iface_obj_path == NULL) {
++		reply = wpas_dbus_new_invalid_iface_error(message);
++		goto out;
++	}
++
++	/* Make sure the message's object path actually refers to the
++	 * wpa_supplicant structure it's supposed to (which is wpa_s)
++	 */
++	if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global,
++						  iface_obj_path) != wpa_s) {
++		reply = wpas_dbus_new_invalid_iface_error(message);
++		goto out;
++	}
++
++	if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) {
++		/* A method for one of this interface's configured networks */
++		int nid = strtoul(network, NULL, 10);
++
++		if (errno != EINVAL)
++			reply = wpas_dispatch_network_method(message, wpa_s,
++							     nid);
++		else
++			reply = wpas_dbus_new_invalid_network_error(message);
++	} else if (bssid && !strcmp(msg_interface, WPAS_DBUS_IFACE_BSSID)) {
++		/* A method for one of this interface's scanned BSSIDs */
++		reply = wpas_dispatch_bssid_method(message, wpa_s, bssid);
++	} else if (!strcmp(msg_interface, WPAS_DBUS_IFACE_INTERFACE)) {
++		/* A method for an interface only. */
++		if (!strcmp(method, "scan"))
++			reply = wpas_dbus_iface_scan(message, wpa_s);
++		else if (!strcmp(method, "scanResults"))
++			reply = wpas_dbus_iface_scan_results(message, wpa_s);
++		else if (!strcmp(method, "addNetwork"))
++			reply = wpas_dbus_iface_add_network(message, wpa_s);
++		else if (!strcmp(method, "removeNetwork"))
++			reply = wpas_dbus_iface_remove_network(message, wpa_s);
++		else if (!strcmp(method, "selectNetwork"))
++			reply = wpas_dbus_iface_select_network(message, wpa_s);
++		else if (!strcmp(method, "capabilities"))
++			reply = wpas_dbus_iface_capabilities(message, wpa_s);
++		else if (!strcmp(method, "disconnect"))
++			reply = wpas_dbus_iface_disconnect(message, wpa_s);
++		else if (!strcmp(method, "setAPScan"))
++			reply = wpas_dbus_iface_set_ap_scan(message, wpa_s);
++		else if (!strcmp(method, "setSmartcardModules"))
++			reply = wpas_dbus_iface_set_smartcard_modules(message,
++								      wpa_s);
++		else if (!strcmp(method, "state"))
++			reply = wpas_dbus_iface_get_state(message, wpa_s);
++		else if (!strcmp(method, "scanning"))
++			reply = wpas_dbus_iface_get_scanning(message, wpa_s);
++#ifndef CONFIG_NO_CONFIG_BLOBS
++		else if (!strcmp(method, "setBlobs"))
++			reply = wpas_dbus_iface_set_blobs(message, wpa_s);
++		else if (!strcmp(method, "removeBlobs"))
++			reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
++#endif /* CONFIG_NO_CONFIG_BLOBS */
++#ifdef CONFIG_WPS
++		else if (os_strcmp(method, "wpsPbc") == 0)
++			reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
++		else if (os_strcmp(method, "wpsPin") == 0)
++			reply = wpas_dbus_iface_wps_pin(message, wpa_s);
++		else if (os_strcmp(method, "wpsReg") == 0)
++			reply = wpas_dbus_iface_wps_reg(message, wpa_s);
++#endif /* CONFIG_WPS */
++		else if (os_strcmp(method, "flush") == 0)
++			reply = wpas_dbus_iface_flush(message, wpa_s);
++	}
++
++	/* If the message was handled, send back the reply */
++out:
++	if (reply) {
++		if (!dbus_message_get_no_reply(message))
++			dbus_connection_send(connection, reply, NULL);
++		dbus_message_unref(reply);
++	}
++
++	os_free(iface_obj_path);
++	os_free(network);
++	os_free(bssid);
++	return reply ? DBUS_HANDLER_RESULT_HANDLED :
++		DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++}
++
++
++/**
++ * wpas_message_handler - dispatch incoming dbus messages
++ * @connection: connection to the system message bus
++ * @message: an incoming dbus message
++ * @user_data: a pointer to a dbus control interface data structure
++ * Returns: whether or not the message was handled
++ *
++ * This function dispatches all incoming dbus messages to the correct
++ * handlers, depending on what the message's target object path is,
++ * and what the method call is.
++ */
++static DBusHandlerResult wpas_message_handler(DBusConnection *connection,
++	DBusMessage *message, void *user_data)
++{
++	struct wpas_dbus_priv *ctrl_iface = user_data;
++	const char *method;
++	const char *path;
++	const char *msg_interface;
++	DBusMessage *reply = NULL;
++
++	method = dbus_message_get_member(message);
++	path = dbus_message_get_path(message);
++	msg_interface = dbus_message_get_interface(message);
++	if (!method || !path || !ctrl_iface || !msg_interface)
++		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++
++	wpa_printf(MSG_MSGDUMP, "dbus[old]: %s.%s (%s) [%s]",
++		   msg_interface, method, path,
++		   dbus_message_get_signature(message));
++
++	/* Validate the method interface */
++	if (strcmp(msg_interface, WPAS_DBUS_INTERFACE) != 0)
++		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++
++	if (!strcmp(path, WPAS_DBUS_PATH)) {
++		/* dispatch methods against our global dbus interface here */
++		if (!strcmp(method, "addInterface")) {
++			reply = wpas_dbus_global_add_interface(
++				message, ctrl_iface->global);
++		} else if (!strcmp(method, "removeInterface")) {
++			reply = wpas_dbus_global_remove_interface(
++				message, ctrl_iface->global);
++		} else if (!strcmp(method, "getInterface")) {
++			reply = wpas_dbus_global_get_interface(
++				message, ctrl_iface->global);
++		} else if (!strcmp(method, "setDebugParams")) {
++			reply = wpas_dbus_global_set_debugparams(
++				message, ctrl_iface->global);
++		}
++	}
++
++	/* If the message was handled, send back the reply */
++	if (reply) {
++		if (!dbus_message_get_no_reply(message))
++			dbus_connection_send(connection, reply, NULL);
++		dbus_message_unref(reply);
++	}
++
++	return reply ? DBUS_HANDLER_RESULT_HANDLED :
++		DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++}
++
++
++/**
++ * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal
++ * @wpa_s: %wpa_supplicant network interface data
++ * Returns: 0 on success, -1 on failure
++ *
++ * Notify listeners that this interface has updated scan results.
++ */
++void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
++{
++	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
++	DBusMessage *_signal;
++
++	/* Do nothing if the control interface is not turned on */
++	if (iface == NULL || !wpa_s->dbus_path)
++		return;
++
++	_signal = dbus_message_new_signal(wpa_s->dbus_path,
++					  WPAS_DBUS_IFACE_INTERFACE,
++					  "ScanResultsAvailable");
++	if (_signal == NULL) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: Not enough memory to send scan results signal");
++		return;
++	}
++	dbus_connection_send(iface->con, _signal, NULL);
++	dbus_message_unref(_signal);
++}
++
++
++/**
++ * wpa_supplicant_dbus_notify_state_change - Send a state change signal
++ * @wpa_s: %wpa_supplicant network interface data
++ * @new_state: new state wpa_supplicant is entering
++ * @old_state: old state wpa_supplicant is leaving
++ * Returns: 0 on success, -1 on failure
++ *
++ * Notify listeners that wpa_supplicant has changed state
++ */
++void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
++					     enum wpa_states new_state,
++					     enum wpa_states old_state)
++{
++	struct wpas_dbus_priv *iface;
++	DBusMessage *_signal = NULL;
++	const char *new_state_str, *old_state_str;
++
++	if (wpa_s->dbus_path == NULL)
++		return; /* Skip signal since D-Bus setup is not yet ready */
++
++	/* Do nothing if the control interface is not turned on */
++	if (wpa_s->global == NULL)
++		return;
++	iface = wpa_s->global->dbus;
++	if (iface == NULL)
++		return;
++
++	/* Only send signal if state really changed */
++	if (new_state == old_state)
++		return;
++
++	_signal = dbus_message_new_signal(wpa_s->dbus_path,
++					  WPAS_DBUS_IFACE_INTERFACE,
++					  "StateChange");
++	if (_signal == NULL) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: %s: could not create dbus signal; likely out of memory",
++			   __func__);
++		return;
++	}
++
++	new_state_str = wpa_supplicant_state_txt(new_state);
++	old_state_str = wpa_supplicant_state_txt(old_state);
++
++	if (!dbus_message_append_args(_signal,
++				      DBUS_TYPE_STRING, &new_state_str,
++				      DBUS_TYPE_STRING, &old_state_str,
++				      DBUS_TYPE_INVALID)) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: %s: Not enough memory to construct state change signal",
++			   __func__);
++		goto out;
++	}
++
++	dbus_connection_send(iface->con, _signal, NULL);
++
++out:
++	dbus_message_unref(_signal);
++}
++
++
++/**
++ * wpa_supplicant_dbus_notify_scanning - send scanning status
++ * @wpa_s: %wpa_supplicant network interface data
++ * Returns: 0 on success, -1 on failure
++ *
++ * Notify listeners of interface scanning state changes
++ */
++void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
++{
++	struct wpas_dbus_priv *iface = wpa_s->global->dbus;
++	DBusMessage *_signal;
++	dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
++
++	/* Do nothing if the control interface is not turned on */
++	if (iface == NULL || !wpa_s->dbus_path)
++		return;
++
++	_signal = dbus_message_new_signal(wpa_s->dbus_path,
++					  WPAS_DBUS_IFACE_INTERFACE,
++					  "Scanning");
++	if (_signal == NULL) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: Not enough memory to send scan results signal");
++		return;
++	}
++
++	if (dbus_message_append_args(_signal,
++				     DBUS_TYPE_BOOLEAN, &scanning,
++				     DBUS_TYPE_INVALID)) {
++		dbus_connection_send(iface->con, _signal, NULL);
++	} else {
++		wpa_printf(MSG_ERROR,
++			   "dbus: Not enough memory to construct signal");
++	}
++	dbus_message_unref(_signal);
++}
++
++
++#ifdef CONFIG_WPS
++void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
++					 const struct wps_credential *cred)
++{
++	struct wpas_dbus_priv *iface;
++	DBusMessage *_signal = NULL;
++
++	/* Do nothing if the control interface is not turned on */
++	if (wpa_s->global == NULL)
++		return;
++	iface = wpa_s->global->dbus;
++	if (iface == NULL || !wpa_s->dbus_path)
++		return;
++
++	_signal = dbus_message_new_signal(wpa_s->dbus_path,
++					  WPAS_DBUS_IFACE_INTERFACE,
++					  "WpsCred");
++	if (_signal == NULL) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: %s: Could not create dbus signal; likely out of memory",
++			   __func__);
++		return;
++	}
++
++	if (!dbus_message_append_args(_signal,
++				      DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
++				      &cred->cred_attr, cred->cred_attr_len,
++				      DBUS_TYPE_INVALID)) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: %s: Not enough memory to construct signal",
++			   __func__);
++		goto out;
++	}
++
++	dbus_connection_send(iface->con, _signal, NULL);
++
++out:
++	dbus_message_unref(_signal);
++}
++#else /* CONFIG_WPS */
++void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
++					 const struct wps_credential *cred)
++{
++}
++#endif /* CONFIG_WPS */
++
++void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
++					      int depth, const char *subject,
++					      const char *cert_hash,
++					      const struct wpabuf *cert)
++{
++	struct wpas_dbus_priv *iface;
++	DBusMessage *_signal = NULL;
++	const char *hash;
++	const char *cert_hex;
++	int cert_hex_len;
++
++	/* Do nothing if the control interface is not turned on */
++	if (wpa_s->global == NULL)
++		return;
++	iface = wpa_s->global->dbus;
++	if (iface == NULL || !wpa_s->dbus_path)
++		return;
++
++	_signal = dbus_message_new_signal(wpa_s->dbus_path,
++					  WPAS_DBUS_IFACE_INTERFACE,
++					  "Certification");
++	if (_signal == NULL) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: %s: Could not create dbus signal; likely out of memory",
++			   __func__);
++		return;
++	}
++
++	hash = cert_hash ? cert_hash : "";
++	cert_hex = cert ? wpabuf_head(cert) : "";
++	cert_hex_len = cert ? wpabuf_len(cert) : 0;
++
++	if (!dbus_message_append_args(_signal,
++				      DBUS_TYPE_INT32, &depth,
++				      DBUS_TYPE_STRING, &subject,
++				      DBUS_TYPE_STRING, &hash,
++				      DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
++				      &cert_hex, cert_hex_len,
++				      DBUS_TYPE_INVALID)) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: %s: Not enough memory to construct signal",
++			   __func__);
++		goto out;
++	}
++
++	dbus_connection_send(iface->con, _signal, NULL);
++
++out:
++	dbus_message_unref(_signal);
++
++}
++
++
++/**
++ * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
++ * @global: Pointer to global data from wpa_supplicant_init()
++ * Returns: 0 on success, -1 on failure
++ *
++ * Initialize the dbus control interface and start receiving commands from
++ * external programs over the bus.
++ */
++int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface)
++{
++	DBusError error;
++	int ret = -1;
++	DBusObjectPathVTable wpas_vtable = {
++		NULL, &wpas_message_handler, NULL, NULL, NULL, NULL
++	};
++
++	/* Register the message handler for the global dbus interface */
++	if (!dbus_connection_register_object_path(iface->con,
++						  WPAS_DBUS_PATH, &wpas_vtable,
++						  iface)) {
++		wpa_printf(MSG_ERROR, "dbus: Could not set up message handler");
++		return -1;
++	}
++
++	/* Register our service with the message bus */
++	dbus_error_init(&error);
++	switch (dbus_bus_request_name(iface->con, WPAS_DBUS_SERVICE,
++				      0, &error)) {
++	case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
++		ret = 0;
++		break;
++	case DBUS_REQUEST_NAME_REPLY_EXISTS:
++	case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
++	case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
++		wpa_printf(MSG_ERROR,
++			   "dbus: Could not request service name: already registered");
++		break;
++	default:
++		wpa_printf(MSG_ERROR,
++			   "dbus: Could not request service name: %s %s",
++			   error.name, error.message);
++		break;
++	}
++	dbus_error_free(&error);
++
++	if (ret != 0)
++		return -1;
++
++	wpa_printf(MSG_DEBUG, "Providing DBus service '" WPAS_DBUS_SERVICE
++		   "'.");
++
++	return 0;
++}
++
++
++/**
++ * wpas_dbus_register_new_iface - Register a new interface with dbus
++ * @wpa_s: %wpa_supplicant interface description structure to register
++ * Returns: 0 on success, -1 on error
++ *
++ * Registers a new interface with dbus and assigns it a dbus object path.
++ */
++int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
++{
++	struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
++	DBusConnection * con;
++	u32 next;
++	DBusObjectPathVTable vtable = {
++		NULL, &wpas_iface_message_handler, NULL, NULL, NULL, NULL
++	};
++
++	/* Do nothing if the control interface is not turned on */
++	if (ctrl_iface == NULL)
++		return 0;
++
++	con = ctrl_iface->con;
++	next = ctrl_iface->next_objid++;
++
++	/* Create and set the interface's object path */
++	wpa_s->dbus_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
++	if (wpa_s->dbus_path == NULL)
++		return -1;
++	os_snprintf(wpa_s->dbus_path, WPAS_DBUS_OBJECT_PATH_MAX,
++		    WPAS_DBUS_PATH_INTERFACES "/%u",
++		    next);
++
++	/* Register the message handler for the interface functions */
++	if (!dbus_connection_register_fallback(con, wpa_s->dbus_path, &vtable,
++					       wpa_s)) {
++		wpa_printf(MSG_ERROR,
++			   "dbus: Could not set up message handler for interface %s",
++			   wpa_s->ifname);
++		return -1;
++	}
++
++	return 0;
++}
++
++
++/**
++ * wpas_dbus_unregister_iface - Unregister an interface from dbus
++ * @wpa_s: wpa_supplicant interface structure
++ * Returns: 0 on success, -1 on failure
++ *
++ * Unregisters the interface with dbus
++ */
++int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
++{
++	struct wpas_dbus_priv *ctrl_iface;
++	DBusConnection *con;
++
++	/* Do nothing if the control interface is not turned on */
++	if (wpa_s == NULL || wpa_s->global == NULL)
++		return 0;
++	ctrl_iface = wpa_s->global->dbus;
++	if (ctrl_iface == NULL || wpa_s->dbus_path == NULL)
++		return 0;
++
++	con = ctrl_iface->con;
++	if (!dbus_connection_unregister_object_path(con, wpa_s->dbus_path))
++		return -1;
++
++	os_free(wpa_s->dbus_path);
++	wpa_s->dbus_path = NULL;
++
++	return 0;
++}
++
++
++/**
++ * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface
++ * @global: Pointer to global data from wpa_supplicant_init()
++ * @path: Pointer to a dbus object path representing an interface
++ * Returns: Pointer to the interface or %NULL if not found
++ */
++struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
++	struct wpa_global *global, const char *path)
++{
++	struct wpa_supplicant *wpa_s;
++
++	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
++		if (wpa_s->dbus_path && strcmp(wpa_s->dbus_path, path) == 0)
++			return wpa_s;
++	}
++	return NULL;
++}
+diff --git a/wpa_supplicant/dbus/dbus_old.h b/wpa_supplicant/dbus/dbus_old.h
+new file mode 100644
+index 000000000..451a9f827
+--- /dev/null
++++ b/wpa_supplicant/dbus/dbus_old.h
+@@ -0,0 +1,142 @@
++/*
++ * WPA Supplicant / dbus-based control interface
++ * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
++ *
++ * This software may be distributed under the terms of the BSD license.
++ * See README for more details.
++ */
++
++#ifndef CTRL_IFACE_DBUS_H
++#define CTRL_IFACE_DBUS_H
++
++struct wps_credential;
++
++#ifdef CONFIG_CTRL_IFACE_DBUS
++
++#define WPAS_DBUS_OBJECT_PATH_MAX 150
++
++#define WPAS_DBUS_SERVICE	"fi.epitest.hostap.WPASupplicant"
++#define WPAS_DBUS_PATH		"/fi/epitest/hostap/WPASupplicant"
++#define WPAS_DBUS_INTERFACE	"fi.epitest.hostap.WPASupplicant"
++
++#define WPAS_DBUS_PATH_INTERFACES	WPAS_DBUS_PATH "/Interfaces"
++#define WPAS_DBUS_IFACE_INTERFACE	WPAS_DBUS_INTERFACE ".Interface"
++
++#define WPAS_DBUS_NETWORKS_PART "Networks"
++#define WPAS_DBUS_IFACE_NETWORK	WPAS_DBUS_INTERFACE ".Network"
++
++#define WPAS_DBUS_BSSIDS_PART	"BSSIDs"
++#define WPAS_DBUS_IFACE_BSSID	WPAS_DBUS_INTERFACE ".BSSID"
++
++
++/* Errors */
++#define WPAS_ERROR_INVALID_NETWORK \
++	WPAS_DBUS_IFACE_INTERFACE ".InvalidNetwork"
++#define WPAS_ERROR_INVALID_BSSID \
++	WPAS_DBUS_IFACE_INTERFACE ".InvalidBSSID"
++
++#define WPAS_ERROR_INVALID_OPTS \
++	WPAS_DBUS_INTERFACE ".InvalidOptions"
++#define WPAS_ERROR_INVALID_IFACE \
++	WPAS_DBUS_INTERFACE ".InvalidInterface"
++
++#define WPAS_ERROR_ADD_ERROR \
++	WPAS_DBUS_INTERFACE ".AddError"
++#define WPAS_ERROR_EXISTS_ERROR \
++	WPAS_DBUS_INTERFACE ".ExistsError"
++#define WPAS_ERROR_REMOVE_ERROR \
++	WPAS_DBUS_INTERFACE ".RemoveError"
++
++#define WPAS_ERROR_SCAN_ERROR \
++	WPAS_DBUS_IFACE_INTERFACE ".ScanError"
++#define WPAS_ERROR_ADD_NETWORK_ERROR \
++	WPAS_DBUS_IFACE_INTERFACE ".AddNetworkError"
++#define WPAS_ERROR_INTERNAL_ERROR \
++	WPAS_DBUS_IFACE_INTERFACE ".InternalError"
++#define WPAS_ERROR_REMOVE_NETWORK_ERROR \
++	WPAS_DBUS_IFACE_INTERFACE ".RemoveNetworkError"
++
++#define WPAS_ERROR_WPS_PBC_ERROR \
++	WPAS_DBUS_IFACE_INTERFACE ".WpsPbcError"
++#define WPAS_ERROR_WPS_PIN_ERROR \
++	WPAS_DBUS_IFACE_INTERFACE ".WpsPinError"
++#define WPAS_ERROR_WPS_REG_ERROR \
++	WPAS_DBUS_IFACE_INTERFACE ".WpsRegError"
++
++#define WPAS_DBUS_BSSID_FORMAT "%02x%02x%02x%02x%02x%02x"
++
++struct wpa_global;
++struct wpa_supplicant;
++
++int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface);
++void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s);
++void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s);
++void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
++					     enum wpa_states new_state,
++					     enum wpa_states old_state);
++void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
++					 const struct wps_credential *cred);
++void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
++					      int depth, const char *subject,
++					      const char *cert_hash,
++					      const struct wpabuf *cert);
++
++char * wpas_dbus_decompose_object_path(const char *path, char **network,
++				       char **bssid);
++
++int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s);
++int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s);
++
++
++/* Methods internal to the dbus control interface */
++struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
++	struct wpa_global *global, const char *path);
++
++#else /* CONFIG_CTRL_IFACE_DBUS */
++
++static inline void
++wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
++{
++}
++
++static inline void
++wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
++{
++}
++
++static inline void
++wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
++					enum wpa_states new_state,
++					enum wpa_states old_state)
++{
++}
++
++static inline void
++wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
++				    const struct wps_credential *cred)
++{
++}
++
++static inline void
++wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
++					      int depth, const char *subject,
++					      const char *cert_hash,
++					      const struct wpabuf *cert)
++{
++}
++
++static inline int
++wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
++{
++	return 0;
++}
++
++static inline int
++wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
++{
++	return 0;
++}
++
++#endif /* CONFIG_CTRL_IFACE_DBUS */
++
++#endif /* CTRL_IFACE_DBUS_H */
+diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c
+new file mode 100644
+index 000000000..e540832f2
+--- /dev/null
++++ b/wpa_supplicant/dbus/dbus_old_handlers.c
+@@ -0,0 +1,1393 @@
++/*
++ * WPA Supplicant / dbus-based control interface
++ * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
++ *
++ * This software may be distributed under the terms of the BSD license.
++ * See README for more details.
++ */
++
++#include "includes.h"
++#include <dbus/dbus.h>
++
++#include "common.h"
++#include "eap_peer/eap_methods.h"
++#include "common/ieee802_11_defs.h"
++#include "eapol_supp/eapol_supp_sm.h"
++#include "rsn_supp/wpa.h"
++#include "../config.h"
++#include "../wpa_supplicant_i.h"
++#include "../driver_i.h"
++#include "../notify.h"
++#include "../wpas_glue.h"
++#include "../bss.h"
++#include "../scan.h"
++#include "dbus_old.h"
++#include "dbus_old_handlers.h"
++#include "dbus_dict_helpers.h"
++
++/**
++ * wpas_dbus_new_invalid_opts_error - Return a new invalid options error message
++ * @message: Pointer to incoming dbus message this error refers to
++ * Returns: a dbus error message
++ *
++ * Convenience function to create and return an invalid options error
++ */
++DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
++					       const char *arg)
++{
++	DBusMessage *reply;
++
++	reply = dbus_message_new_error(
++		message, WPAS_ERROR_INVALID_OPTS,
++		"Did not receive correct message arguments.");
++	if (arg != NULL)
++		dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
++					 DBUS_TYPE_INVALID);
++
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_new_success_reply - Return a new success reply message
++ * @message: Pointer to incoming dbus message this reply refers to
++ * Returns: a dbus message containing a single UINT32 that indicates
++ *          success (ie, a value of 1)
++ *
++ * Convenience function to create and return a success reply message
++ */
++DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message)
++{
++	DBusMessage *reply;
++	unsigned int success = 1;
++
++	reply = dbus_message_new_method_return(message);
++	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &success,
++				 DBUS_TYPE_INVALID);
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_global_add_interface - Request registration of a network interface
++ * @message: Pointer to incoming dbus message
++ * @global: %wpa_supplicant global data structure
++ * Returns: The object path of the new interface object,
++ *          or a dbus error message with more information
++ *
++ * Handler function for "addInterface" method call. Handles requests
++ * by dbus clients to register a network interface that wpa_supplicant
++ * will manage.
++ */
++DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
++					     struct wpa_global *global)
++{
++	char *ifname = NULL;
++	char *driver = NULL;
++	char *driver_param = NULL;
++	char *confname = NULL;
++	char *bridge_ifname = NULL;
++	DBusMessage *reply = NULL;
++	DBusMessageIter iter;
++
++	dbus_message_iter_init(message, &iter);
++
++	/* First argument: interface name (DBUS_TYPE_STRING)
++	 *    Required; must be non-zero length
++	 */
++	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
++		goto error;
++	dbus_message_iter_get_basic(&iter, &ifname);
++	if (!os_strlen(ifname))
++		goto error;
++
++	/* Second argument: dict of options */
++	if (dbus_message_iter_next(&iter)) {
++		DBusMessageIter iter_dict;
++		struct wpa_dbus_dict_entry entry;
++
++		if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
++			goto error;
++		while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
++			if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
++				goto error;
++			if (!strcmp(entry.key, "driver") &&
++			    entry.type == DBUS_TYPE_STRING) {
++				os_free(driver);
++				driver = os_strdup(entry.str_value);
++				wpa_dbus_dict_entry_clear(&entry);
++				if (driver == NULL)
++					goto error;
++			} else if (!strcmp(entry.key, "driver-params") &&
++				   entry.type == DBUS_TYPE_STRING) {
++				os_free(driver_param);
++				driver_param = os_strdup(entry.str_value);
++				wpa_dbus_dict_entry_clear(&entry);
++				if (driver_param == NULL)
++					goto error;
++			} else if (!strcmp(entry.key, "config-file") &&
++				   entry.type == DBUS_TYPE_STRING) {
++				os_free(confname);
++				confname = os_strdup(entry.str_value);
++				wpa_dbus_dict_entry_clear(&entry);
++				if (confname == NULL)
++					goto error;
++			} else if (!strcmp(entry.key, "bridge-ifname") &&
++				   entry.type == DBUS_TYPE_STRING) {
++				os_free(bridge_ifname);
++				bridge_ifname = os_strdup(entry.str_value);
++				wpa_dbus_dict_entry_clear(&entry);
++				if (bridge_ifname == NULL)
++					goto error;
++			} else {
++				wpa_dbus_dict_entry_clear(&entry);
++				goto error;
++			}
++		}
++	}
++
++	/*
++	 * Try to get the wpa_supplicant record for this iface, return
++	 * an error if we already control it.
++	 */
++	if (wpa_supplicant_get_iface(global, ifname) != NULL) {
++		reply = dbus_message_new_error(
++			message, WPAS_ERROR_EXISTS_ERROR,
++			"wpa_supplicant already controls this interface.");
++	} else {
++		struct wpa_supplicant *wpa_s;
++		struct wpa_interface iface;
++
++		os_memset(&iface, 0, sizeof(iface));
++		iface.ifname = ifname;
++		iface.driver = driver;
++		iface.driver_param = driver_param;
++		iface.confname = confname;
++		iface.bridge_ifname = bridge_ifname;
++		/* Otherwise, have wpa_supplicant attach to it. */
++		wpa_s = wpa_supplicant_add_iface(global, &iface, NULL);
++		if (wpa_s && wpa_s->dbus_path) {
++			const char *path = wpa_s->dbus_path;
++
++			reply = dbus_message_new_method_return(message);
++			dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
++						 &path, DBUS_TYPE_INVALID);
++		} else {
++			reply = dbus_message_new_error(
++				message, WPAS_ERROR_ADD_ERROR,
++				"wpa_supplicant couldn't grab this interface.");
++		}
++	}
++
++out:
++	os_free(driver);
++	os_free(driver_param);
++	os_free(confname);
++	os_free(bridge_ifname);
++	return reply;
++
++error:
++	reply = wpas_dbus_new_invalid_opts_error(message, NULL);
++	goto out;
++}
++
++
++/**
++ * wpas_dbus_global_remove_interface - Request deregistration of an interface
++ * @message: Pointer to incoming dbus message
++ * @global: wpa_supplicant global data structure
++ * Returns: a dbus message containing a UINT32 indicating success (1) or
++ *          failure (0), or returns a dbus error message with more information
++ *
++ * Handler function for "removeInterface" method call.  Handles requests
++ * by dbus clients to deregister a network interface that wpa_supplicant
++ * currently manages.
++ */
++DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
++						struct wpa_global *global)
++{
++	struct wpa_supplicant *wpa_s;
++	char *path;
++	DBusMessage *reply = NULL;
++
++	if (!dbus_message_get_args(message, NULL,
++				   DBUS_TYPE_OBJECT_PATH, &path,
++				   DBUS_TYPE_INVALID)) {
++		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
++		goto out;
++	}
++
++	wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path);
++	if (wpa_s == NULL) {
++		reply = wpas_dbus_new_invalid_iface_error(message);
++		goto out;
++	}
++
++	if (!wpa_supplicant_remove_iface(global, wpa_s, 0)) {
++		reply = wpas_dbus_new_success_reply(message);
++	} else {
++		reply = dbus_message_new_error(
++			message, WPAS_ERROR_REMOVE_ERROR,
++			"wpa_supplicant couldn't remove this interface.");
++	}
++
++out:
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_global_get_interface - Get the object path for an interface name
++ * @message: Pointer to incoming dbus message
++ * @global: %wpa_supplicant global data structure
++ * Returns: The object path of the interface object,
++ *          or a dbus error message with more information
++ *
++ * Handler function for "getInterface" method call. Handles requests
++ * by dbus clients for the object path of an specific network interface.
++ */
++DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
++					     struct wpa_global *global)
++{
++	DBusMessage *reply = NULL;
++	const char *ifname;
++	const char *path;
++	struct wpa_supplicant *wpa_s;
++
++	if (!dbus_message_get_args(message, NULL,
++				   DBUS_TYPE_STRING, &ifname,
++				   DBUS_TYPE_INVALID)) {
++		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
++		goto out;
++	}
++
++	wpa_s = wpa_supplicant_get_iface(global, ifname);
++	if (wpa_s == NULL || !wpa_s->dbus_path) {
++		reply = wpas_dbus_new_invalid_iface_error(message);
++		goto out;
++	}
++
++	path = wpa_s->dbus_path;
++	reply = dbus_message_new_method_return(message);
++	dbus_message_append_args(reply,
++				 DBUS_TYPE_OBJECT_PATH, &path,
++				 DBUS_TYPE_INVALID);
++
++out:
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_global_set_debugparams- Set the debug params
++ * @message: Pointer to incoming dbus message
++ * @global: %wpa_supplicant global data structure
++ * Returns: a dbus message containing a UINT32 indicating success (1) or
++ *          failure (0), or returns a dbus error message with more information
++ *
++ * Handler function for "setDebugParams" method call. Handles requests
++ * by dbus clients for the object path of an specific network interface.
++ */
++DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,
++					       struct wpa_global *global)
++{
++	DBusMessage *reply = NULL;
++	int debug_level;
++	dbus_bool_t debug_timestamp;
++	dbus_bool_t debug_show_keys;
++
++	if (!dbus_message_get_args(message, NULL,
++				   DBUS_TYPE_INT32, &debug_level,
++				   DBUS_TYPE_BOOLEAN, &debug_timestamp,
++				   DBUS_TYPE_BOOLEAN, &debug_show_keys,
++				   DBUS_TYPE_INVALID)) {
++		return wpas_dbus_new_invalid_opts_error(message, NULL);
++	}
++
++	if (wpa_supplicant_set_debug_params(global, debug_level,
++					    debug_timestamp ? 1 : 0,
++					    debug_show_keys ? 1 : 0)) {
++		return wpas_dbus_new_invalid_opts_error(message, NULL);
++	}
++
++	reply = wpas_dbus_new_success_reply(message);
++
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_iface_scan - Request a wireless scan on an interface
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: a dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "scan" method call of a network device. Requests
++ * that wpa_supplicant perform a wireless scan as soon as possible
++ * on a particular wireless interface.
++ */
++DBusMessage * wpas_dbus_iface_scan(DBusMessage *message,
++				   struct wpa_supplicant *wpa_s)
++{
++	wpa_s->scan_req = MANUAL_SCAN_REQ;
++	wpa_supplicant_req_scan(wpa_s, 0, 0);
++	return wpas_dbus_new_success_reply(message);
++}
++
++
++/**
++ * wpas_dbus_iface_scan_results - Get the results of a recent scan request
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: a dbus message containing a dbus array of objects paths, or returns
++ *          a dbus error message if not scan results could be found
++ *
++ * Handler function for "scanResults" method call of a network device. Returns
++ * a dbus message containing the object paths of wireless networks found.
++ */
++DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,
++					   struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply;
++	DBusMessageIter iter;
++	DBusMessageIter sub_iter;
++	struct wpa_bss *bss;
++
++	if (!wpa_s->dbus_path)
++		return dbus_message_new_error(message,
++					      WPAS_ERROR_INTERNAL_ERROR,
++					      "no D-Bus interface available");
++
++	/* Create and initialize the return message */
++	reply = dbus_message_new_method_return(message);
++	dbus_message_iter_init_append(reply, &iter);
++	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
++					      DBUS_TYPE_OBJECT_PATH_AS_STRING,
++					      &sub_iter))
++		goto error;
++
++	/* Loop through scan results and append each result's object path */
++	dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
++		char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
++		char *path = path_buf;
++
++		/* Construct the object path for this network.  Note that ':'
++		 * is not a valid character in dbus object paths.
++		 */
++		os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
++			    "%s/" WPAS_DBUS_BSSIDS_PART "/"
++			    WPAS_DBUS_BSSID_FORMAT,
++			    wpa_s->dbus_path, MAC2STR(bss->bssid));
++		if (!dbus_message_iter_append_basic(&sub_iter,
++						    DBUS_TYPE_OBJECT_PATH,
++						    &path))
++			goto error;
++	}
++
++	if (!dbus_message_iter_close_container(&iter, &sub_iter))
++		goto error;
++
++	return reply;
++
++error:
++	dbus_message_unref(reply);
++	return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR,
++				      "an internal error occurred returning scan results");
++}
++
++
++/**
++ * wpas_dbus_bssid_properties - Return the properties of a scanned network
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * @res: wpa_supplicant scan result for which to get properties
++ * Returns: a dbus message containing the properties for the requested network
++ *
++ * Handler function for "properties" method call of a scanned network.
++ * Returns a dbus message containing the the properties.
++ */
++DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,
++					 struct wpa_supplicant *wpa_s,
++					 struct wpa_bss *bss)
++{
++	DBusMessage *reply;
++	DBusMessageIter iter, iter_dict;
++	const u8 *wpa_ie, *rsn_ie, *wps_ie;
++
++	/* Dump the properties into a dbus message */
++	reply = dbus_message_new_method_return(message);
++
++	wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
++	rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
++	wps_ie = wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
++
++	dbus_message_iter_init_append(reply, &iter);
++	if (!wpa_dbus_dict_open_write(&iter, &iter_dict) ||
++	    !wpa_dbus_dict_append_byte_array(&iter_dict, "bssid",
++					     (const char *) bss->bssid,
++					     ETH_ALEN) ||
++	    !wpa_dbus_dict_append_byte_array(&iter_dict, "ssid",
++					     (const char *) bss->ssid,
++					     bss->ssid_len) ||
++	    (wpa_ie &&
++	     !wpa_dbus_dict_append_byte_array(&iter_dict, "wpaie",
++					      (const char *) wpa_ie,
++					      wpa_ie[1] + 2)) ||
++	    (rsn_ie &&
++	     !wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie",
++					      (const char *) rsn_ie,
++					      rsn_ie[1] + 2)) ||
++	    (wps_ie &&
++	     !wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie",
++					     (const char *) wps_ie,
++					      wps_ie[1] + 2)) ||
++	    (bss->freq &&
++	     !wpa_dbus_dict_append_int32(&iter_dict, "frequency", bss->freq)) ||
++	    !wpa_dbus_dict_append_uint16(&iter_dict, "capabilities",
++					 bss->caps) ||
++	    (!(bss->flags & WPA_BSS_QUAL_INVALID) &&
++	     !wpa_dbus_dict_append_int32(&iter_dict, "quality", bss->qual)) ||
++	    (!(bss->flags & WPA_BSS_NOISE_INVALID) &&
++	     !wpa_dbus_dict_append_int32(&iter_dict, "noise", bss->noise)) ||
++	    (!(bss->flags & WPA_BSS_LEVEL_INVALID) &&
++	     !wpa_dbus_dict_append_int32(&iter_dict, "level", bss->level)) ||
++	    !wpa_dbus_dict_append_int32(&iter_dict, "maxrate",
++					wpa_bss_get_max_rate(bss) * 500000) ||
++	    !wpa_dbus_dict_close_write(&iter, &iter_dict)) {
++		if (reply)
++			dbus_message_unref(reply);
++		reply = dbus_message_new_error(
++			message, WPAS_ERROR_INTERNAL_ERROR,
++			"an internal error occurred returning BSSID properties.");
++	}
++
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_iface_capabilities - Return interface capabilities
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing a dict of strings
++ *
++ * Handler function for "capabilities" method call of an interface.
++ */
++DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,
++					   struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	struct wpa_driver_capa capa;
++	int res;
++	DBusMessageIter iter, iter_dict;
++	char **eap_methods;
++	size_t num_items;
++	dbus_bool_t strict = FALSE;
++	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
++
++	if (!dbus_message_get_args(message, NULL,
++				   DBUS_TYPE_BOOLEAN, &strict,
++				   DBUS_TYPE_INVALID))
++		strict = FALSE;
++
++	reply = dbus_message_new_method_return(message);
++
++	dbus_message_iter_init_append(reply, &iter);
++	if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
++		goto error;
++
++	/* EAP methods */
++	eap_methods = eap_get_names_as_string_array(&num_items);
++	if (eap_methods) {
++		dbus_bool_t success;
++		size_t i = 0;
++
++		success = wpa_dbus_dict_append_string_array(
++			&iter_dict, "eap", (const char **) eap_methods,
++			num_items);
++
++		/* free returned method array */
++		while (eap_methods[i])
++			os_free(eap_methods[i++]);
++		os_free(eap_methods);
++
++		if (!success)
++			goto error;
++	}
++
++	res = wpa_drv_get_capa(wpa_s, &capa);
++
++	/***** pairwise cipher */
++	if (res < 0) {
++		if (!strict) {
++			const char *args[] = {"CCMP", "TKIP", "NONE"};
++
++			if (!wpa_dbus_dict_append_string_array(
++				    &iter_dict, "pairwise", args,
++				    ARRAY_SIZE(args)))
++				goto error;
++		}
++	} else {
++		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "pairwise",
++						      &iter_dict_entry,
++						      &iter_dict_val,
++						      &iter_array) ||
++		    ((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "CCMP")) ||
++		    ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "TKIP")) ||
++		    ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "NONE")) ||
++		    !wpa_dbus_dict_end_string_array(&iter_dict,
++						    &iter_dict_entry,
++						    &iter_dict_val,
++						    &iter_array))
++			goto error;
++	}
++
++	/***** group cipher */
++	if (res < 0) {
++		if (!strict) {
++			const char *args[] = {
++				"CCMP", "TKIP", "WEP104", "WEP40"
++			};
++
++			if (!wpa_dbus_dict_append_string_array(
++				    &iter_dict, "group", args,
++				    ARRAY_SIZE(args)))
++				goto error;
++		}
++	} else {
++		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "group",
++						      &iter_dict_entry,
++						      &iter_dict_val,
++						      &iter_array))
++			goto error;
++
++		if (((capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "CCMP")) ||
++		    ((capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "TKIP")) ||
++		    ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "WEP104")) ||
++		    ((capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "WEP40")) ||
++		    !wpa_dbus_dict_end_string_array(&iter_dict,
++						    &iter_dict_entry,
++						    &iter_dict_val,
++						    &iter_array))
++			goto error;
++	}
++
++	/***** key management */
++	if (res < 0) {
++		if (!strict) {
++			const char *args[] = {
++				"WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE",
++				"NONE"
++			};
++			if (!wpa_dbus_dict_append_string_array(
++				    &iter_dict, "key_mgmt", args,
++				    ARRAY_SIZE(args)))
++				goto error;
++		}
++	} else {
++		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "key_mgmt",
++						      &iter_dict_entry,
++						      &iter_dict_val,
++						      &iter_array) ||
++		    !wpa_dbus_dict_string_array_add_element(&iter_array,
++							    "NONE") ||
++		    !wpa_dbus_dict_string_array_add_element(&iter_array,
++							    "IEEE8021X") ||
++		    ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
++				       WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "WPA-EAP")) ||
++		    ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
++				       WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "WPA-PSK")) ||
++		    ((capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "WPA-NONE")) ||
++		    !wpa_dbus_dict_end_string_array(&iter_dict,
++						    &iter_dict_entry,
++						    &iter_dict_val,
++						    &iter_array))
++			goto error;
++	}
++
++	/***** WPA protocol */
++	if (res < 0) {
++		if (!strict) {
++			const char *args[] = { "RSN", "WPA" };
++
++			if (!wpa_dbus_dict_append_string_array(
++				    &iter_dict, "proto", args,
++				    ARRAY_SIZE(args)))
++				goto error;
++		}
++	} else {
++		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "proto",
++						      &iter_dict_entry,
++						      &iter_dict_val,
++						      &iter_array) ||
++		    ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
++				       WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "RSN")) ||
++		    ((capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
++				       WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "WPA")) ||
++		    !wpa_dbus_dict_end_string_array(&iter_dict,
++						    &iter_dict_entry,
++						    &iter_dict_val,
++						    &iter_array))
++			goto error;
++	}
++
++	/***** auth alg */
++	if (res < 0) {
++		if (!strict) {
++			const char *args[] = { "OPEN", "SHARED", "LEAP" };
++
++			if (!wpa_dbus_dict_append_string_array(
++				    &iter_dict, "auth_alg", args,
++				    ARRAY_SIZE(args)))
++				goto error;
++		}
++	} else {
++		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "auth_alg",
++						      &iter_dict_entry,
++						      &iter_dict_val,
++						      &iter_array) ||
++		    ((capa.auth & WPA_DRIVER_AUTH_OPEN) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "OPEN")) ||
++		    ((capa.auth & WPA_DRIVER_AUTH_SHARED) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "SHARED")) ||
++		    ((capa.auth & WPA_DRIVER_AUTH_LEAP) &&
++		     !wpa_dbus_dict_string_array_add_element(
++			     &iter_array, "LEAP")) ||
++		    !wpa_dbus_dict_end_string_array(&iter_dict,
++						    &iter_dict_entry,
++						    &iter_dict_val,
++						    &iter_array))
++			goto error;
++	}
++
++	if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
++		goto error;
++
++	return reply;
++
++error:
++	if (reply)
++		dbus_message_unref(reply);
++	return dbus_message_new_error(
++		message, WPAS_ERROR_INTERNAL_ERROR,
++		"an internal error occurred returning interface capabilities.");
++}
++
++
++/**
++ * wpas_dbus_iface_add_network - Add a new configured network
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing the object path of the new network
++ *
++ * Handler function for "addNetwork" method call of a network interface.
++ */
++DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,
++					  struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	struct wpa_ssid *ssid = NULL;
++	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
++
++	if (wpa_s->dbus_path)
++		ssid = wpa_supplicant_add_network(wpa_s);
++	if (ssid == NULL) {
++		reply = dbus_message_new_error(
++			message, WPAS_ERROR_ADD_NETWORK_ERROR,
++			"wpa_supplicant could not add a network on this interface.");
++		goto out;
++	}
++
++	/* Construct the object path for this network. */
++	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
++		    "%s/" WPAS_DBUS_NETWORKS_PART "/%d",
++		    wpa_s->dbus_path, ssid->id);
++
++	reply = dbus_message_new_method_return(message);
++	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
++				 &path, DBUS_TYPE_INVALID);
++
++out:
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_iface_remove_network - Remove a configured network
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "removeNetwork" method call of a network interface.
++ */
++DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
++					     struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	const char *op;
++	char *iface = NULL, *net_id = NULL;
++	int id;
++	int result;
++
++	if (!dbus_message_get_args(message, NULL,
++				   DBUS_TYPE_OBJECT_PATH, &op,
++				   DBUS_TYPE_INVALID)) {
++		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
++		goto out;
++	}
++
++	/* Extract the network ID */
++	iface = wpas_dbus_decompose_object_path(op, &net_id, NULL);
++	if (iface == NULL || net_id == NULL) {
++		reply = wpas_dbus_new_invalid_network_error(message);
++		goto out;
++	}
++
++	/* Ensure the network is actually a child of this interface */
++	if (!wpa_s->dbus_path || os_strcmp(iface, wpa_s->dbus_path) != 0) {
++		reply = wpas_dbus_new_invalid_network_error(message);
++		goto out;
++	}
++
++	id = strtoul(net_id, NULL, 10);
++	result = wpa_supplicant_remove_network(wpa_s, id);
++	if (result == -1) {
++		reply = wpas_dbus_new_invalid_network_error(message);
++		goto out;
++	}
++	if (result == -2) {
++		reply = dbus_message_new_error(
++			message, WPAS_ERROR_REMOVE_NETWORK_ERROR,
++			"error removing the specified on this interface.");
++		goto out;
++	}
++
++	reply = wpas_dbus_new_success_reply(message);
++
++out:
++	os_free(iface);
++	os_free(net_id);
++	return reply;
++}
++
++
++static const char * const dont_quote[] = {
++	"key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
++	"opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
++	"bssid", "scan_freq", "freq_list", NULL
++};
++
++
++static dbus_bool_t should_quote_opt(const char *key)
++{
++	int i = 0;
++
++	while (dont_quote[i] != NULL) {
++		if (os_strcmp(key, dont_quote[i]) == 0)
++			return FALSE;
++		i++;
++	}
++	return TRUE;
++}
++
++
++/**
++ * wpas_dbus_iface_set_network - Set options for a configured network
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * @ssid: wpa_ssid structure for a configured network
++ * Returns: a dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "set" method call of a configured network.
++ */
++DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
++					  struct wpa_supplicant *wpa_s,
++					  struct wpa_ssid *ssid)
++{
++	DBusMessage *reply = NULL;
++	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
++	DBusMessageIter	iter, iter_dict;
++
++	dbus_message_iter_init(message, &iter);
++
++	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) {
++		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
++		goto out;
++	}
++
++	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
++		char *value = NULL;
++		size_t size = 50;
++		int ret;
++
++		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
++			reply = wpas_dbus_new_invalid_opts_error(message,
++								 NULL);
++			goto out;
++		}
++
++		/* Type conversions, since wpa_supplicant wants strings */
++		if (entry.type == DBUS_TYPE_ARRAY &&
++		    entry.array_type == DBUS_TYPE_BYTE) {
++			if (entry.array_len <= 0)
++				goto error;
++
++			size = entry.array_len * 2 + 1;
++			value = os_zalloc(size);
++			if (value == NULL)
++				goto error;
++			ret = wpa_snprintf_hex(value, size,
++					       (u8 *) entry.bytearray_value,
++					       entry.array_len);
++			if (ret <= 0)
++				goto error;
++		} else if (entry.type == DBUS_TYPE_STRING) {
++			if (should_quote_opt(entry.key)) {
++				size = os_strlen(entry.str_value);
++				/* Zero-length option check */
++				if (size == 0)
++					goto error;
++				size += 3;  /* For quotes and terminator */
++				value = os_zalloc(size);
++				if (value == NULL)
++					goto error;
++				ret = os_snprintf(value, size, "\"%s\"",
++						  entry.str_value);
++				if (os_snprintf_error(size, ret))
++					goto error;
++			} else {
++				value = os_strdup(entry.str_value);
++				if (value == NULL)
++					goto error;
++			}
++		} else if (entry.type == DBUS_TYPE_UINT32) {
++			value = os_zalloc(size);
++			if (value == NULL)
++				goto error;
++			ret = os_snprintf(value, size, "%u",
++					  entry.uint32_value);
++			if (os_snprintf_error(size, ret))
++				goto error;
++		} else if (entry.type == DBUS_TYPE_INT32) {
++			value = os_zalloc(size);
++			if (value == NULL)
++				goto error;
++			ret = os_snprintf(value, size, "%d",
++					  entry.int32_value);
++			if (os_snprintf_error(size, ret))
++				goto error;
++		} else
++			goto error;
++
++		if (wpa_config_set(ssid, entry.key, value, 0) < 0)
++			goto error;
++
++		if ((os_strcmp(entry.key, "psk") == 0 &&
++		     value[0] == '"' && ssid->ssid_len) ||
++		    (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
++			wpa_config_update_psk(ssid);
++		else if (os_strcmp(entry.key, "priority") == 0)
++			wpa_config_update_prio_list(wpa_s->conf);
++
++		os_free(value);
++		wpa_dbus_dict_entry_clear(&entry);
++		continue;
++
++	error:
++		os_free(value);
++		reply = wpas_dbus_new_invalid_opts_error(message, entry.key);
++		wpa_dbus_dict_entry_clear(&entry);
++		break;
++	}
++
++	if (!reply)
++		reply = wpas_dbus_new_success_reply(message);
++
++out:
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_iface_enable_network - Mark a configured network as enabled
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * @ssid: wpa_ssid structure for a configured network
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "enable" method call of a configured network.
++ */
++DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,
++					     struct wpa_supplicant *wpa_s,
++					     struct wpa_ssid *ssid)
++{
++	wpa_supplicant_enable_network(wpa_s, ssid);
++	return wpas_dbus_new_success_reply(message);
++}
++
++
++/**
++ * wpas_dbus_iface_disable_network - Mark a configured network as disabled
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * @ssid: wpa_ssid structure for a configured network
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "disable" method call of a configured network.
++ */
++DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,
++					      struct wpa_supplicant *wpa_s,
++					      struct wpa_ssid *ssid)
++{
++	wpa_supplicant_disable_network(wpa_s, ssid);
++	return wpas_dbus_new_success_reply(message);
++}
++
++
++/**
++ * wpas_dbus_iface_select_network - Attempt association with a configured network
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "selectNetwork" method call of network interface.
++ */
++DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
++					     struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	const char *op;
++	struct wpa_ssid *ssid;
++	char *iface_obj_path = NULL;
++	char *network = NULL;
++
++	if (os_strlen(dbus_message_get_signature(message)) == 0) {
++		/* Any network */
++		ssid = NULL;
++	} else {
++		int nid;
++
++		if (!dbus_message_get_args(message, NULL,
++					   DBUS_TYPE_OBJECT_PATH, &op,
++					   DBUS_TYPE_INVALID)) {
++			reply = wpas_dbus_new_invalid_opts_error(message,
++								 NULL);
++			goto out;
++		}
++
++		/* Extract the network number */
++		iface_obj_path = wpas_dbus_decompose_object_path(op,
++								 &network,
++								 NULL);
++		if (iface_obj_path == NULL) {
++			reply = wpas_dbus_new_invalid_iface_error(message);
++			goto out;
++		}
++		/* Ensure the object path really points to this interface */
++		if (network == NULL || !wpa_s->dbus_path ||
++		    os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) {
++			reply = wpas_dbus_new_invalid_network_error(message);
++			goto out;
++		}
++
++		nid = strtoul(network, NULL, 10);
++		if (errno == EINVAL) {
++			reply = wpas_dbus_new_invalid_network_error(message);
++			goto out;
++		}
++
++		ssid = wpa_config_get_network(wpa_s->conf, nid);
++		if (ssid == NULL) {
++			reply = wpas_dbus_new_invalid_network_error(message);
++			goto out;
++		}
++	}
++
++	/* Finally, associate with the network */
++	wpa_supplicant_select_network(wpa_s, ssid);
++
++	reply = wpas_dbus_new_success_reply(message);
++
++out:
++	os_free(iface_obj_path);
++	os_free(network);
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_iface_disconnect - Terminate the current connection
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "disconnect" method call of network interface.
++ */
++DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
++					 struct wpa_supplicant *wpa_s)
++{
++	wpas_request_disconnection(wpa_s);
++
++	return wpas_dbus_new_success_reply(message);
++}
++
++
++/**
++ * wpas_dbus_iface_set_ap_scan - Control roaming mode
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "setAPScan" method call.
++ */
++DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
++					  struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	dbus_uint32_t ap_scan = 1;
++
++	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ap_scan,
++				   DBUS_TYPE_INVALID)) {
++		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
++		goto out;
++	}
++
++	if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
++		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
++		goto out;
++	}
++
++	reply = wpas_dbus_new_success_reply(message);
++
++out:
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_iface_set_smartcard_modules - Set smartcard related module paths
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "setSmartcardModules" method call.
++ */
++DBusMessage * wpas_dbus_iface_set_smartcard_modules(
++	DBusMessage *message, struct wpa_supplicant *wpa_s)
++{
++	DBusMessageIter iter, iter_dict;
++	char *opensc_engine_path = NULL;
++	char *pkcs11_engine_path = NULL;
++	char *pkcs11_module_path = NULL;
++	struct wpa_dbus_dict_entry entry;
++
++	if (!dbus_message_iter_init(message, &iter))
++		goto error;
++
++	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
++		goto error;
++
++	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
++		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
++			goto error;
++		if (!strcmp(entry.key, "opensc_engine_path") &&
++		    entry.type == DBUS_TYPE_STRING) {
++			os_free(opensc_engine_path);
++			opensc_engine_path = os_strdup(entry.str_value);
++			wpa_dbus_dict_entry_clear(&entry);
++			if (opensc_engine_path == NULL)
++				goto error;
++		} else if (!strcmp(entry.key, "pkcs11_engine_path") &&
++			   entry.type == DBUS_TYPE_STRING) {
++			os_free(pkcs11_engine_path);
++			pkcs11_engine_path = os_strdup(entry.str_value);
++			wpa_dbus_dict_entry_clear(&entry);
++			if (pkcs11_engine_path == NULL)
++				goto error;
++		} else if (!strcmp(entry.key, "pkcs11_module_path") &&
++				 entry.type == DBUS_TYPE_STRING) {
++			os_free(pkcs11_module_path);
++			pkcs11_module_path = os_strdup(entry.str_value);
++			wpa_dbus_dict_entry_clear(&entry);
++			if (pkcs11_module_path == NULL)
++				goto error;
++		} else {
++			wpa_dbus_dict_entry_clear(&entry);
++			goto error;
++		}
++	}
++
++	os_free(wpa_s->conf->opensc_engine_path);
++	wpa_s->conf->opensc_engine_path = opensc_engine_path;
++	os_free(wpa_s->conf->pkcs11_engine_path);
++	wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path;
++	os_free(wpa_s->conf->pkcs11_module_path);
++	wpa_s->conf->pkcs11_module_path = pkcs11_module_path;
++
++	wpa_sm_set_eapol(wpa_s->wpa, NULL);
++	eapol_sm_deinit(wpa_s->eapol);
++	wpa_s->eapol = NULL;
++	wpa_supplicant_init_eapol(wpa_s);
++	wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
++
++	return wpas_dbus_new_success_reply(message);
++
++error:
++	os_free(opensc_engine_path);
++	os_free(pkcs11_engine_path);
++	os_free(pkcs11_module_path);
++	return wpas_dbus_new_invalid_opts_error(message, NULL);
++}
++
++
++/**
++ * wpas_dbus_iface_get_state - Get interface state
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing a STRING representing the current
++ *          interface state
++ *
++ * Handler function for "state" method call.
++ */
++DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
++					struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	const char *str_state;
++
++	reply = dbus_message_new_method_return(message);
++	if (reply != NULL) {
++		str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
++		dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state,
++					 DBUS_TYPE_INVALID);
++	}
++
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_iface_get_scanning - Get interface scanning state
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: wpa_supplicant structure for a network interface
++ * Returns: A dbus message containing whether the interface is scanning
++ *
++ * Handler function for "scanning" method call.
++ */
++DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
++					   struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
++
++	reply = dbus_message_new_method_return(message);
++	if (reply != NULL) {
++		dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning,
++					 DBUS_TYPE_INVALID);
++	} else {
++		wpa_printf(MSG_ERROR,
++			   "dbus: Not enough memory to return scanning state");
++	}
++
++	return reply;
++}
++
++
++#ifndef CONFIG_NO_CONFIG_BLOBS
++
++/**
++ * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: %wpa_supplicant data structure
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Asks wpa_supplicant to internally store a one or more binary blobs.
++ */
++DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
++					struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
++	DBusMessageIter	iter, iter_dict;
++
++	dbus_message_iter_init(message, &iter);
++
++	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
++		return wpas_dbus_new_invalid_opts_error(message, NULL);
++
++	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
++		struct wpa_config_blob *blob;
++
++		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
++			reply = wpas_dbus_new_invalid_opts_error(message,
++								 NULL);
++			break;
++		}
++
++		if (entry.type != DBUS_TYPE_ARRAY ||
++		    entry.array_type != DBUS_TYPE_BYTE) {
++			reply = wpas_dbus_new_invalid_opts_error(
++				message, "Byte array expected.");
++			break;
++		}
++
++		if ((entry.array_len <= 0) || (entry.array_len > 65536) ||
++		    !strlen(entry.key)) {
++			reply = wpas_dbus_new_invalid_opts_error(
++				message, "Invalid array size.");
++			break;
++		}
++
++		blob = os_zalloc(sizeof(*blob));
++		if (blob == NULL) {
++			reply = dbus_message_new_error(
++				message, WPAS_ERROR_ADD_ERROR,
++				"Not enough memory to add blob.");
++			break;
++		}
++		blob->data = os_zalloc(entry.array_len);
++		if (blob->data == NULL) {
++			reply = dbus_message_new_error(
++				message, WPAS_ERROR_ADD_ERROR,
++				"Not enough memory to add blob data.");
++			os_free(blob);
++			break;
++		}
++
++		blob->name = os_strdup(entry.key);
++		blob->len = entry.array_len;
++		os_memcpy(blob->data, (u8 *) entry.bytearray_value,
++				entry.array_len);
++		if (blob->name == NULL) {
++			wpa_config_free_blob(blob);
++			reply = dbus_message_new_error(
++				message, WPAS_ERROR_ADD_ERROR,
++				"Error adding blob.");
++			break;
++		}
++
++		/* Success */
++		if (!wpa_config_remove_blob(wpa_s->conf, blob->name))
++			wpas_notify_blob_removed(wpa_s, blob->name);
++		wpa_config_set_blob(wpa_s->conf, blob);
++		wpas_notify_blob_added(wpa_s, blob->name);
++
++		wpa_dbus_dict_entry_clear(&entry);
++	}
++	wpa_dbus_dict_entry_clear(&entry);
++
++	return reply ? reply : wpas_dbus_new_success_reply(message);
++}
++
++
++/**
++ * wpas_dbus_iface_remove_blob - Remove named binary blobs
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: %wpa_supplicant data structure
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Asks wpa_supplicant to remove one or more previously stored binary blobs.
++ */
++DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
++					   struct wpa_supplicant *wpa_s)
++{
++	DBusMessageIter iter, array;
++	char *err_msg = NULL;
++
++	dbus_message_iter_init(message, &iter);
++
++	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
++	    dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING)
++		return wpas_dbus_new_invalid_opts_error(message, NULL);
++
++	dbus_message_iter_recurse(&iter, &array);
++	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
++		const char *name;
++
++		dbus_message_iter_get_basic(&array, &name);
++		if (!os_strlen(name))
++			err_msg = "Invalid blob name.";
++		else if (wpa_config_remove_blob(wpa_s->conf, name) != 0)
++			err_msg = "Error removing blob.";
++		else
++			wpas_notify_blob_removed(wpa_s, name);
++		dbus_message_iter_next(&array);
++	}
++
++	if (err_msg)
++		return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR,
++					      err_msg);
++
++	return wpas_dbus_new_success_reply(message);
++}
++
++#endif /* CONFIG_NO_CONFIG_BLOBS */
++
++
++/**
++ * wpas_dbus_iface_flush - Clear BSS of old or all inactive entries
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: %wpa_supplicant data structure
++ * Returns: a dbus message containing a UINT32 indicating success (1) or
++ *          failure (0), or returns a dbus error message with more information
++ *
++ * Handler function for "flush" method call. Handles requests for an
++ * interface with an optional "age" parameter that specifies the minimum
++ * age of a BSS to be flushed.
++ */
++DBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
++				    struct wpa_supplicant *wpa_s)
++{
++	int flush_age = 0;
++
++	if (os_strlen(dbus_message_get_signature(message)) != 0 &&
++	    !dbus_message_get_args(message, NULL,
++				   DBUS_TYPE_INT32, &flush_age,
++				   DBUS_TYPE_INVALID)) {
++		return wpas_dbus_new_invalid_opts_error(message, NULL);
++	}
++
++	if (flush_age == 0)
++		wpa_bss_flush(wpa_s);
++	else
++		wpa_bss_flush_by_age(wpa_s, flush_age);
++
++	return wpas_dbus_new_success_reply(message);
++}
+diff --git a/wpa_supplicant/dbus/dbus_old_handlers.h b/wpa_supplicant/dbus/dbus_old_handlers.h
+new file mode 100644
+index 000000000..e60ad06a0
+--- /dev/null
++++ b/wpa_supplicant/dbus/dbus_old_handlers.h
+@@ -0,0 +1,101 @@
++/*
++ * WPA Supplicant / dbus-based control interface
++ * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
++ *
++ * This software may be distributed under the terms of the BSD license.
++ * See README for more details.
++ */
++
++#ifndef CTRL_IFACE_DBUS_HANDLERS_H
++#define CTRL_IFACE_DBUS_HANDLERS_H
++
++struct wpa_bss;
++
++DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message);
++DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message);
++
++DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
++					     struct wpa_global *global);
++
++DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
++						struct wpa_global *global);
++
++DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
++					     struct wpa_global *global);
++
++DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,
++					       struct wpa_global *global);
++
++DBusMessage * wpas_dbus_iface_scan(DBusMessage *message,
++				   struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,
++					   struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,
++					 struct wpa_supplicant *wpa_s,
++					 struct wpa_bss *bss);
++
++DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,
++					   struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,
++					  struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
++					     struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
++					  struct wpa_supplicant *wpa_s,
++					  struct wpa_ssid *ssid);
++
++DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,
++					     struct wpa_supplicant *wpa_s,
++					     struct wpa_ssid *ssid);
++
++DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,
++					      struct wpa_supplicant *wpa_s,
++					      struct wpa_ssid *ssid);
++
++DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
++					     struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
++					 struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
++					  struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_set_smartcard_modules(
++	DBusMessage *message, struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
++					struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
++					   struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
++					struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
++					   struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
++				      struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
++				      struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
++				      struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
++				    struct wpa_supplicant *wpa_s);
++
++DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message);
++DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
++					       const char *arg);
++
++#endif /* CTRL_IFACE_DBUS_HANDLERS_H */
++
+diff --git a/wpa_supplicant/dbus/dbus_old_handlers_wps.c b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
+new file mode 100644
+index 000000000..6c8405b85
+--- /dev/null
++++ b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
+@@ -0,0 +1,156 @@
++/*
++ * WPA Supplicant / dbus-based control interface (WPS)
++ * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
++ *
++ * This software may be distributed under the terms of the BSD license.
++ * See README for more details.
++ */
++
++#include "includes.h"
++#include <dbus/dbus.h>
++
++#include "common.h"
++#include "../config.h"
++#include "../wpa_supplicant_i.h"
++#include "../wps_supplicant.h"
++#include "dbus_old.h"
++#include "dbus_old_handlers.h"
++
++/**
++ * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: %wpa_supplicant data structure
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "wpsPbc" method call
++ */
++DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
++				      struct wpa_supplicant *wpa_s)
++{
++	char *arg_bssid = NULL;
++	u8 bssid[ETH_ALEN];
++	int ret = 0;
++
++	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
++				   DBUS_TYPE_INVALID))
++		return wpas_dbus_new_invalid_opts_error(message, NULL);
++
++	if (os_strcmp(arg_bssid, "any") == 0)
++		ret = wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
++	else if (!hwaddr_aton(arg_bssid, bssid))
++		ret = wpas_wps_start_pbc(wpa_s, bssid, 0, 0);
++	else {
++		return wpas_dbus_new_invalid_opts_error(message,
++							"Invalid BSSID");
++	}
++
++	if (ret < 0) {
++		return dbus_message_new_error(
++			message, WPAS_ERROR_WPS_PBC_ERROR,
++			"Could not start PBC negotiation");
++	}
++
++	return wpas_dbus_new_success_reply(message);
++}
++
++
++/**
++ * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: %wpa_supplicant data structure
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "wpsPin" method call
++ */
++DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
++				      struct wpa_supplicant *wpa_s)
++{
++	DBusMessage *reply = NULL;
++	char *arg_bssid;
++	char *pin = NULL;
++	u8 bssid[ETH_ALEN], *_bssid = NULL;
++	int ret;
++	char npin[9];
++
++	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
++				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
++		return wpas_dbus_new_invalid_opts_error(message, NULL);
++
++	if (os_strcmp(arg_bssid, "any") == 0)
++		_bssid = NULL;
++	else if (!hwaddr_aton(arg_bssid, bssid))
++		_bssid = bssid;
++	else {
++		return wpas_dbus_new_invalid_opts_error(message,
++							"Invalid BSSID");
++	}
++
++	if (os_strlen(pin) > 0)
++		ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
++					 DEV_PW_DEFAULT);
++	else
++		ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0,
++					 DEV_PW_DEFAULT);
++
++	if (ret < 0) {
++		return dbus_message_new_error(message,
++					      WPAS_ERROR_WPS_PIN_ERROR,
++					      "Could not init PIN");
++	}
++
++	reply = dbus_message_new_method_return(message);
++	if (reply == NULL)
++		return NULL;
++
++	if (ret > 0) {
++		ret = os_snprintf(npin, sizeof(npin), "%08d", ret);
++		if (os_snprintf_error(sizeof(npin), ret))
++			return wpas_dbus_new_invalid_opts_error(message,
++								"invalid PIN");
++
++		pin = npin;
++	}
++	dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin,
++				 DBUS_TYPE_INVALID);
++	return reply;
++}
++
++
++/**
++ * wpas_dbus_iface_wps_reg - Request credentials using the PIN of the AP
++ * @message: Pointer to incoming dbus message
++ * @wpa_s: %wpa_supplicant data structure
++ * Returns: A dbus message containing a UINT32 indicating success (1) or
++ *          failure (0)
++ *
++ * Handler function for "wpsReg" method call
++ */
++DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
++				      struct wpa_supplicant *wpa_s)
++{
++	char *arg_bssid;
++	char *pin = NULL;
++	u8 bssid[ETH_ALEN];
++	int ret = 0;
++
++	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
++				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
++		return wpas_dbus_new_invalid_opts_error(message, NULL);
++
++	if (!hwaddr_aton(arg_bssid, bssid))
++		ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
++	else {
++		return wpas_dbus_new_invalid_opts_error(message,
++							"Invalid BSSID");
++	}
++
++	if (ret < 0) {
++		return dbus_message_new_error(message,
++					      WPAS_ERROR_WPS_REG_ERROR,
++					      "Could not request credentials");
++	}
++
++	return wpas_dbus_new_success_reply(message);
++}
+diff --git a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in
+new file mode 100644
+index 000000000..a75918f93
+--- /dev/null
++++ b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in
+@@ -0,0 +1,5 @@
++[D-BUS Service]
++Name=fi.epitest.hostap.WPASupplicant
++Exec=@BINDIR@/wpa_supplicant -u
++User=root
++SystemdService=wpa_supplicant.service
+diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
+index cdfb1974d..57550d495 100644
+--- a/wpa_supplicant/defconfig
++++ b/wpa_supplicant/defconfig
+@@ -365,6 +365,10 @@ CONFIG_IEEE80211W=y
+ #CONFIG_NDIS_EVENTS_INTEGRATED=y
+ #PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
+ 
++# Add support for old DBus control interface
++# (fi.epitest.hostap.WPASupplicant)
++#CONFIG_CTRL_IFACE_DBUS=y
++
+ # Add support for new DBus control interface
+ # (fi.w1.hostap.wpa_supplicant1)
+ CONFIG_CTRL_IFACE_DBUS_NEW=y
+diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+index aaff15002..ebf102edf 100644
+--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
++++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+@@ -471,7 +471,7 @@
+ 	  <para>Enable DBus control interface. If enabled, interface
+ 	  definitions may be omitted. (This is only available
+ 	  if <command>wpa_supplicant</command> was built with
+-	  the <literal>CONFIG_CTRL_IFACE_DBUS_NEW</literal> option.)</para>
++	  the <literal>CONFIG_DBUS</literal> option.)</para>
+ 	</listitem>
+       </varlistentry>
+ 
+diff --git a/wpa_supplicant/examples/wpas-test.py b/wpa_supplicant/examples/wpas-test.py
+new file mode 100755
+index 000000000..bdd16a8a8
+--- /dev/null
++++ b/wpa_supplicant/examples/wpas-test.py
+@@ -0,0 +1,91 @@
++#!/usr/bin/python
++
++import dbus
++import sys, os
++import time
++
++WPAS_DBUS_SERVICE = "fi.epitest.hostap.WPASupplicant"
++WPAS_DBUS_INTERFACE = "fi.epitest.hostap.WPASupplicant"
++WPAS_DBUS_OPATH = "/fi/epitest/hostap/WPASupplicant"
++
++WPAS_DBUS_INTERFACES_INTERFACE = "fi.epitest.hostap.WPASupplicant.Interface"
++WPAS_DBUS_INTERFACES_OPATH = "/fi/epitest/hostap/WPASupplicant/Interfaces"
++WPAS_DBUS_BSSID_INTERFACE = "fi.epitest.hostap.WPASupplicant.BSSID"
++
++def byte_array_to_string(s):
++	import urllib
++	r = ""    
++	for c in s:
++		if c >= 32 and c < 127:
++			r += "%c" % c
++		else:
++			r += urllib.quote(chr(c))
++	return r
++
++def main():
++	if len(sys.argv) != 2:
++		print("Usage: wpas-test.py <interface>")
++		os._exit(1)
++
++	ifname = sys.argv[1]
++
++	bus = dbus.SystemBus()
++	wpas_obj = bus.get_object(WPAS_DBUS_SERVICE, WPAS_DBUS_OPATH)
++	wpas = dbus.Interface(wpas_obj, WPAS_DBUS_INTERFACE)
++
++	# See if wpa_supplicant already knows about this interface
++	path = None
++	try:
++		path = wpas.getInterface(ifname)
++	except dbus.dbus_bindings.DBusException as exc:
++		if str(exc) != "wpa_supplicant knows nothing about this interface.":
++			raise exc
++		try:
++			path = wpas.addInterface(ifname, {'driver': dbus.Variant('wext')})
++		except dbus.dbus_bindings.DBusException as exc:
++			if str(exc) != "wpa_supplicant already controls this interface.":
++				raise exc
++
++	if_obj = bus.get_object(WPAS_DBUS_SERVICE, path)
++	iface = dbus.Interface(if_obj, WPAS_DBUS_INTERFACES_INTERFACE)
++	iface.scan()
++	# Should really wait for the "scanResults" signal instead of sleeping
++	time.sleep(5)
++	res = iface.scanResults()
++
++	print("Scanned wireless networks:")
++	for opath in res:
++		net_obj = bus.get_object(WPAS_DBUS_SERVICE, opath)
++		net = dbus.Interface(net_obj, WPAS_DBUS_BSSID_INTERFACE)
++		props = net.properties()
++
++		# Convert the byte-array for SSID and BSSID to printable strings
++		bssid = ""
++		for item in props["bssid"]:
++			bssid = bssid + ":%02x" % item
++		bssid = bssid[1:]
++		ssid = byte_array_to_string(props["ssid"])
++		wpa = "no"
++		if props.has_key("wpaie"):
++			wpa = "yes"
++		wpa2 = "no"
++		if props.has_key("rsnie"):
++			wpa2 = "yes"
++		freq = 0
++		if props.has_key("frequency"):
++			freq = props["frequency"]
++		caps = props["capabilities"]
++		qual = props["quality"]
++		level = props["level"]
++		noise = props["noise"]
++		maxrate = props["maxrate"] / 1000000
++
++		print("  %s  ::  ssid='%s'  wpa=%s  wpa2=%s  quality=%d%%  rate=%d  freq=%d" % (bssid, ssid, wpa, wpa2, qual, maxrate, freq))
++
++	wpas.removeInterface(dbus.ObjectPath(path))
++	# Should fail here with unknown interface error
++	iface.scan()
++
++if __name__ == "__main__":
++	main()
++
+diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
+index 51a8a0298..e08c2fd26 100644
+--- a/wpa_supplicant/main.c
++++ b/wpa_supplicant/main.c
+@@ -28,9 +28,9 @@ static void usage(void)
+ 	       "s"
+ #endif /* CONFIG_DEBUG_SYSLOG */
+ 	       "t"
+-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
++#ifdef CONFIG_DBUS
+ 	       "u"
+-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
++#endif /* CONFIG_DBUS */
+ 	       "vW] [-P<pid file>] "
+ 	       "[-g<global ctrl>] \\\n"
+ 	       "        [-G<group>] \\\n"
+@@ -98,9 +98,9 @@ static void usage(void)
+ 	       "  -T = record to Linux tracing in addition to logging\n"
+ 	       "       (records all messages regardless of debug verbosity)\n"
+ #endif /* CONFIG_DEBUG_LINUX_TRACING */
+-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
++#ifdef CONFIG_DBUS
+ 	       "  -u = enable DBus control interface\n"
+-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
++#endif /* CONFIG_DBUS */
+ 	       "  -v = show version\n"
+ 	       "  -W = wait for a control interface monitor before starting\n");
+ 
+@@ -295,11 +295,11 @@ int main(int argc, char *argv[])
+ 		case 't':
+ 			params.wpa_debug_timestamp++;
+ 			break;
+-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
++#ifdef CONFIG_DBUS
+ 		case 'u':
+ 			params.dbus_ctrl_interface = 1;
+ 			break;
+-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
++#endif /* CONFIG_DBUS */
+ 		case 'v':
+ 			printf("%s\n", wpa_supplicant_version);
+ 			exitcode = 0;
+diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
+index e41d7c41c..f47f9bb76 100644
+--- a/wpa_supplicant/notify.c
++++ b/wpa_supplicant/notify.c
+@@ -15,6 +15,7 @@
+ #include "wps_supplicant.h"
+ #include "binder/binder.h"
+ #include "dbus/dbus_common.h"
++#include "dbus/dbus_old.h"
+ #include "dbus/dbus_new.h"
+ #include "rsn_supp/wpa.h"
+ #include "fst/fst.h"
+@@ -27,13 +28,13 @@
+ 
+ int wpas_notify_supplicant_initialized(struct wpa_global *global)
+ {
+-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
++#ifdef CONFIG_DBUS
+ 	if (global->params.dbus_ctrl_interface) {
+ 		global->dbus = wpas_dbus_init(global);
+ 		if (global->dbus == NULL)
+ 			return -1;
+ 	}
+-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
++#endif /* CONFIG_DBUS */
+ 
+ #ifdef CONFIG_BINDER
+ 	global->binder = wpas_binder_init(global);
+@@ -47,10 +48,10 @@ int wpas_notify_supplicant_initialized(struct wpa_global *global)
+ 
+ void wpas_notify_supplicant_deinitialized(struct wpa_global *global)
+ {
+-#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
++#ifdef CONFIG_DBUS
+ 	if (global->dbus)
+ 		wpas_dbus_deinit(global->dbus);
+-#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
++#endif /* CONFIG_DBUS */
+ 
+ #ifdef CONFIG_BINDER
+ 	if (global->binder)
+@@ -64,6 +65,9 @@ int wpas_notify_iface_added(struct wpa_supplicant *wpa_s)
+ 	if (wpa_s->p2p_mgmt)
+ 		return 0;
+ 
++	if (wpas_dbus_register_iface(wpa_s))
++		return -1;
++
+ 	if (wpas_dbus_register_interface(wpa_s))
+ 		return -1;
+ 
+@@ -76,6 +80,9 @@ void wpas_notify_iface_removed(struct wpa_supplicant *wpa_s)
+ 	if (wpa_s->p2p_mgmt)
+ 		return;
+ 
++	/* unregister interface in old DBus ctrl iface */
++	wpas_dbus_unregister_iface(wpa_s);
++
+ 	/* unregister interface in new DBus ctrl iface */
+ 	wpas_dbus_unregister_interface(wpa_s);
+ }
+@@ -88,6 +95,10 @@ void wpas_notify_state_changed(struct wpa_supplicant *wpa_s,
+ 	if (wpa_s->p2p_mgmt)
+ 		return;
+ 
++	/* notify the old DBus API */
++	wpa_supplicant_dbus_notify_state_change(wpa_s, new_state,
++						old_state);
++
+ 	/* notify the new DBus API */
+ 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_STATE);
+ 
+@@ -257,6 +268,9 @@ void wpas_notify_scanning(struct wpa_supplicant *wpa_s)
+ 	if (wpa_s->p2p_mgmt)
+ 		return;
+ 
++	/* notify the old DBus API */
++	wpa_supplicant_dbus_notify_scanning(wpa_s);
++
+ 	/* notify the new DBus API */
+ 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_SCANNING);
+ }
+@@ -276,6 +290,9 @@ void wpas_notify_scan_results(struct wpa_supplicant *wpa_s)
+ 	if (wpa_s->p2p_mgmt)
+ 		return;
+ 
++	/* notify the old DBus API */
++	wpa_supplicant_dbus_notify_scan_results(wpa_s);
++
+ 	wpas_wps_notify_scan_results(wpa_s);
+ }
+ 
+@@ -287,6 +304,8 @@ void wpas_notify_wps_credential(struct wpa_supplicant *wpa_s,
+ 		return;
+ 
+ #ifdef CONFIG_WPS
++	/* notify the old DBus API */
++	wpa_supplicant_dbus_notify_wps_cred(wpa_s, cred);
+ 	/* notify the new DBus API */
+ 	wpas_dbus_signal_wps_cred(wpa_s, cred);
+ #endif /* CONFIG_WPS */
+@@ -818,6 +837,9 @@ void wpas_notify_certification(struct wpa_supplicant *wpa_s,
+ 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
+ 			"depth=%d %s", cert->depth, cert->altsubject[i]);
+ 
++	/* notify the old DBus API */
++	wpa_supplicant_dbus_notify_certification(wpa_s, depth, subject,
++						 cert_hash, cert);
+ 	/* notify the new DBus API */
+ 	wpas_dbus_signal_certification(wpa_s, cert->depth, cert->subject,
+ 				       cert->altsubject, cert->num_altsubject,
+diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in
+index 75a37a8cd..bc5d49af8 100644
+--- a/wpa_supplicant/systemd/wpa_supplicant.service.in
++++ b/wpa_supplicant/systemd/wpa_supplicant.service.in
+@@ -5,9 +5,9 @@ Wants=network.target
+ 
+ [Service]
+ Type=dbus
+-BusName=fi.w1.wpa_supplicant1
++BusName=@DBUS_INTERFACE@
+ ExecStart=@BINDIR@/wpa_supplicant -u
+ 
+ [Install]
+ WantedBy=multi-user.target
+-Alias=dbus-fi.w1.wpa_supplicant1.service
++Alias=dbus-@DBUS_INTERFACE@.service
+diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
+index 8a4bdf8cb..c7b131cc1 100644
+--- a/wpa_supplicant/wpa_supplicant_i.h
++++ b/wpa_supplicant/wpa_supplicant_i.h
+@@ -504,6 +504,9 @@ struct wpa_supplicant {
+ #ifdef CONFIG_MATCH_IFACE
+ 	int matched;
+ #endif /* CONFIG_MATCH_IFACE */
++#ifdef CONFIG_CTRL_IFACE_DBUS
++	char *dbus_path;
++#endif /* CONFIG_CTRL_IFACE_DBUS */
+ #ifdef CONFIG_CTRL_IFACE_DBUS_NEW
+ 	char *dbus_new_path;
+ 	char *dbus_groupobj_path;
+commit 2df86203526b872c3c17cf135340b9b3c8c35594
+Author: Bernhard M. Wiedemann <bwiedemann@suse.de>
+Date:   Fri Apr 17 10:46:56 2020 +0200
+
+    Fixup ^ for 2019 API changes
+    
+    From bc0634da4a3ef468f3142fb39ebdabb08566f411
+
+diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
+index f47f9bb76..2db8bc850 100644
+--- a/wpa_supplicant/notify.c
++++ b/wpa_supplicant/notify.c
+@@ -838,8 +838,8 @@ void wpas_notify_certification(struct wpa_supplicant *wpa_s,
+ 			"depth=%d %s", cert->depth, cert->altsubject[i]);
+ 
+ 	/* notify the old DBus API */
+-	wpa_supplicant_dbus_notify_certification(wpa_s, depth, subject,
+-						 cert_hash, cert);
++	wpa_supplicant_dbus_notify_certification(wpa_s, cert->depth, cert->subject,
++						 cert_hash, cert->cert);
+ 	/* notify the new DBus API */
+ 	wpas_dbus_signal_certification(wpa_s, cert->depth, cert->subject,
+ 				       cert->altsubject, cert->num_altsubject,
diff --git a/wpa_supplicant.changes b/wpa_supplicant.changes
index 968d842..449fab5 100644
--- a/wpa_supplicant.changes
+++ b/wpa_supplicant.changes
@@ -1,4 +1,10 @@
 -------------------------------------------------------------------
+Fri Apr 17 08:37:34 UTC 2020 - Bernhard Wiedemann <bwiedemann@suse.com>
+
+- Add restore-old-dbus-interface.patch to fix wicked wlan (boo#1156920)
+- Restore fi.epitest.hostap.WPASupplicant.service (bsc#1167331)
+
+-------------------------------------------------------------------
 Thu Mar 26 16:03:38 UTC 2020 - Clemens Famulla-Conrad <cfamullaconrad@suse.com>
 
 - With v2.9 fi.epitest.hostap.WPASupplicant.service is obsolete (bsc#1167331)
diff --git a/wpa_supplicant.spec b/wpa_supplicant.spec
index 25113d5..25409e5 100644
--- a/wpa_supplicant.spec
+++ b/wpa_supplicant.spec
@@ -25,6 +25,7 @@ URL:            https://w1.fi/wpa_supplicant
 Source0:        https://w1.fi/releases/%{name}-%{version}.tar.gz
 Source1:        config
 Source2:        %{name}.conf
+Source3:        fi.epitest.hostap.WPASupplicant.service
 Source4:        logrotate.wpa_supplicant
 Source5:        fi.w1.wpa_supplicant1.service
 Source6:        wpa_supplicant.service
@@ -38,6 +39,7 @@ Patch2:         wpa_supplicant-sigusr1-changes-debuglevel.patch
 Patch3:         wpa_supplicant-alloc_size.patch
 Patch4:         wpa_supplicant-getrandom.patch
 Patch5:         wpa_supplicant-dump-certificate-as-PEM-in-debug-mode.diff
+Patch6:         restore-old-dbus-interface.patch
 BuildRequires:  pkgconfig
 BuildRequires:  readline-devel
 BuildRequires:  systemd-rpm-macros
@@ -87,6 +89,7 @@ install -m 0644 wpa_supplicant/dbus/dbus-wpa_supplicant.conf %{buildroot}%{_sysc
 install -d %{buildroot}/%{_sysconfdir}/%{name}
 install -m 0600 %{SOURCE2} %{buildroot}/%{_sysconfdir}/%{name}
 install -d %{buildroot}/%{_datadir}/dbus-1/system-services
+install -m 0644 %{SOURCE3} %{buildroot}/%{_datadir}/dbus-1/system-services
 install -m 0644 %{SOURCE5} %{buildroot}/%{_datadir}/dbus-1/system-services
 install -d %{buildroot}/%{_sysconfdir}/logrotate.d/
 install -m 644 %{SOURCE4} %{buildroot}/%{_sysconfdir}/logrotate.d/wpa_supplicant
@@ -104,6 +107,7 @@ ln -s service %{buildroot}/%{_sbindir}/rcwpa_supplicant
 # avoid spurious dependency on /usr/bin/python
 chmod -x wpa_supplicant/examples/*.py
 # dbus auto activation boo#966535
+ln -s wpa_supplicant.service %{buildroot}%{_unitdir}/dbus-fi.epitest.hostap.WPASupplicant.service
 ln -s wpa_supplicant.service %{buildroot}%{_unitdir}/dbus-fi.w1.wpa_supplicant1.service
 
 %pre
@@ -134,6 +138,7 @@ ln -s wpa_supplicant.service %{buildroot}%{_unitdir}/dbus-fi.w1.wpa_supplicant1.
 %ghost %{_rundir}/%{name}
 %{_unitdir}/wpa_supplicant.service
 %{_unitdir}/wpa_supplicant@.service
+%{_unitdir}/dbus-fi.epitest.hostap.WPASupplicant.service
 %{_unitdir}/dbus-fi.w1.wpa_supplicant1.service
 %dir %{_sysconfdir}/%{name}
 %{_mandir}/man8/*