dbus_old_handlers.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant / dbus-based control interface
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify
68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation.
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license.
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details.
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <dbus/dbus.h>
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_peer/eap_methods.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/wpa.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../config.h"
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../wpa_supplicant_i.h"
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../driver_i.h"
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../notify.h"
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../wpas_glue.h"
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../bss.h"
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "../scan.h"
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_old.h"
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_old_handlers.h"
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_dict_helpers.h"
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_level;
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_show_keys;
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_timestamp;
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_new_invalid_opts_error - Return a new invalid options error message
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message this error refers to
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus error message
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Convenience function to create and return an invalid options error
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       const char *arg)
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_error(message, WPAS_ERROR_INVALID_OPTS,
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       "Did not receive correct message "
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       "arguments.");
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (arg != NULL)
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 DBUS_TYPE_INVALID);
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_new_success_reply - Return a new success reply message
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message this reply refers to
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus message containing a single UINT32 that indicates
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          success (ie, a value of 1)
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Convenience function to create and return a success reply message
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_new_success_reply(DBusMessage *message)
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply;
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int success = 1;
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_method_return(message);
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &success,
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 DBUS_TYPE_INVALID);
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_global_add_interface - Request registration of a network interface
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: %wpa_supplicant global data structure
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: The object path of the new interface object,
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          or a dbus error message with more information
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "addInterface" method call. Handles requests
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * by dbus clients to register a network interface that wpa_supplicant
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * will manage.
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     struct wpa_global *global)
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *ifname = NULL;
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *driver = NULL;
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *driver_param = NULL;
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *confname = NULL;
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *bridge_ifname = NULL;
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter iter;
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_init(message, &iter);
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* First argument: interface name (DBUS_TYPE_STRING)
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 *    Required; must be non-zero length
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_get_basic(&iter, &ifname);
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!os_strlen(ifname))
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Second argument: dict of options */
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dbus_message_iter_next(&iter)) {
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		DBusMessageIter iter_dict;
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_dbus_dict_entry entry;
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!strcmp(entry.key, "driver") &&
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    (entry.type == DBUS_TYPE_STRING)) {
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				driver = os_strdup(entry.str_value);
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_dbus_dict_entry_clear(&entry);
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (driver == NULL)
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto error;
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else if (!strcmp(entry.key, "driver-params") &&
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (entry.type == DBUS_TYPE_STRING)) {
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				driver_param = os_strdup(entry.str_value);
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_dbus_dict_entry_clear(&entry);
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (driver_param == NULL)
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto error;
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else if (!strcmp(entry.key, "config-file") &&
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (entry.type == DBUS_TYPE_STRING)) {
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				confname = os_strdup(entry.str_value);
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_dbus_dict_entry_clear(&entry);
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (confname == NULL)
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto error;
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else if (!strcmp(entry.key, "bridge-ifname") &&
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (entry.type == DBUS_TYPE_STRING)) {
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bridge_ifname = os_strdup(entry.str_value);
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_dbus_dict_entry_clear(&entry);
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (bridge_ifname == NULL)
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto error;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else {
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_dbus_dict_entry_clear(&entry);
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Try to get the wpa_supplicant record for this iface, return
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * an error if we already control it.
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_get_iface(global, ifname) != NULL) {
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = dbus_message_new_error(message,
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       WPAS_ERROR_EXISTS_ERROR,
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       "wpa_supplicant already "
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       "controls this interface.");
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_supplicant *wpa_s;
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_interface iface;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(&iface, 0, sizeof(iface));
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.ifname = ifname;
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.driver = driver;
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.driver_param = driver_param;
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.confname = confname;
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface.bridge_ifname = bridge_ifname;
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Otherwise, have wpa_supplicant attach to it. */
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *path = wpa_s->dbus_path;
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = dbus_message_new_method_return(message);
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			                         &path, DBUS_TYPE_INVALID);
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = dbus_message_new_error(message,
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						       WPAS_ERROR_ADD_ERROR,
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						       "wpa_supplicant "
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						       "couldn't grab this "
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						       "interface.");
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(driver);
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(driver_param);
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(confname);
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(bridge_ifname);
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterror:
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = wpas_dbus_new_invalid_opts_error(message, NULL);
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	goto out;
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_global_remove_interface - Request deregistration of an interface
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: wpa_supplicant global data structure
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus message containing a UINT32 indicating success (1) or
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0), or returns a dbus error message with more information
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "removeInterface" method call.  Handles requests
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * by dbus clients to deregister a network interface that wpa_supplicant
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * currently manages.
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						struct wpa_global *global)
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *path;
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_get_args(message, NULL,
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DBUS_TYPE_OBJECT_PATH, &path,
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DBUS_TYPE_INVALID)) {
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path);
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL) {
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_iface_error(message);
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_supplicant_remove_iface(global, wpa_s)) {
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_success_reply(message);
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = dbus_message_new_error(message,
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       WPAS_ERROR_REMOVE_ERROR,
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       "wpa_supplicant couldn't "
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       "remove this interface.");
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_global_get_interface - Get the object path for an interface name
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: %wpa_supplicant global data structure
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: The object path of the interface object,
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          or a dbus error message with more information
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "getInterface" method call. Handles requests
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * by dbus clients for the object path of an specific network interface.
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     struct wpa_global *global)
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *ifname;
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *path;
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_get_args(message, NULL,
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                           DBUS_TYPE_STRING, &ifname,
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                           DBUS_TYPE_INVALID)) {
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = wpa_supplicant_get_iface(global, ifname);
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL) {
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_iface_error(message);
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	path = wpa_s->dbus_path;
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_method_return(message);
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_append_args(reply,
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                         DBUS_TYPE_OBJECT_PATH, &path,
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                         DBUS_TYPE_INVALID);
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_global_set_debugparams- Set the debug params
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: %wpa_supplicant global data structure
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus message containing a UINT32 indicating success (1) or
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0), or returns a dbus error message with more information
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "setDebugParams" method call. Handles requests
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * by dbus clients for the object path of an specific network interface.
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       struct wpa_global *global)
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int debug_level;
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_bool_t debug_timestamp;
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_bool_t debug_show_keys;
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_get_args(message, NULL,
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                           DBUS_TYPE_INT32, &debug_level,
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                           DBUS_TYPE_BOOLEAN, &debug_timestamp,
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                           DBUS_TYPE_BOOLEAN, &debug_show_keys,
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                           DBUS_TYPE_INVALID)) {
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_new_invalid_opts_error(message, NULL);
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_set_debug_params(global, debug_level,
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    debug_timestamp ? 1 : 0,
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    debug_show_keys ? 1 : 0)) {
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_new_invalid_opts_error(message, NULL);
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = wpas_dbus_new_success_reply(message);
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_scan - Request a wireless scan on an interface
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus message containing a UINT32 indicating success (1) or
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "scan" method call of a network device. Requests
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that wpa_supplicant perform a wireless scan as soon as possible
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * on a particular wireless interface.
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_scan(DBusMessage *message,
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   struct wpa_supplicant *wpa_s)
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->scan_req = 2;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_req_scan(wpa_s, 0, 0);
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_dbus_new_success_reply(message);
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_scan_results - Get the results of a recent scan request
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus message containing a dbus array of objects paths, or returns
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          a dbus error message if not scan results could be found
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "scanResults" method call of a network device. Returns
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a dbus message containing the object paths of wireless networks found.
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   struct wpa_supplicant *wpa_s)
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter iter;
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter sub_iter;
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *bss;
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Create and initialize the return message */
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_method_return(message);
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_init_append(reply, &iter);
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 DBUS_TYPE_OBJECT_PATH_AS_STRING,
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 &sub_iter);
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Loop through scan results and append each result's object path */
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char *path = path_buf;
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Construct the object path for this network.  Note that ':'
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * is not a valid character in dbus object paths.
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    "%s/" WPAS_DBUS_BSSIDS_PART "/"
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    WPAS_DBUS_BSSID_FORMAT,
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    wpa_s->dbus_path, MAC2STR(bss->bssid));
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_iter_append_basic(&sub_iter,
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       DBUS_TYPE_OBJECT_PATH, &path);
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_close_container(&iter, &sub_iter);
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_bssid_properties - Return the properties of a scanned network
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @res: wpa_supplicant scan result for which to get properties
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus message containing the properties for the requested network
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "properties" method call of a scanned network.
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns a dbus message containing the the properties.
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_supplicant *wpa_s,
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_bss *bss)
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply;
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter iter, iter_dict;
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *ie;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Dump the properties into a dbus message */
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_method_return(message);
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_init_append(reply, &iter);
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_dbus_dict_append_byte_array(&iter_dict, "bssid",
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     (const char *) bss->bssid,
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     ETH_ALEN))
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ie) {
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_append_byte_array(&iter_dict, "ssid",
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     (const char *) (ie + 2),
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     ie[1]))
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ie) {
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpaie",
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     (const char *) ie,
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     ie[1] + 2))
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ie) {
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie",
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     (const char *) ie,
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     ie[1] + 2))
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ie = wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ie) {
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie",
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     (const char *) ie,
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     ie[1] + 2))
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->freq) {
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_append_int32(&iter_dict, "frequency",
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						bss->freq))
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_dbus_dict_append_uint16(&iter_dict, "capabilities",
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 bss->caps))
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(bss->flags & WPA_BSS_QUAL_INVALID) &&
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !wpa_dbus_dict_append_int32(&iter_dict, "quality", bss->qual))
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(bss->flags & WPA_BSS_NOISE_INVALID) &&
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !wpa_dbus_dict_append_int32(&iter_dict, "noise", bss->noise))
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(bss->flags & WPA_BSS_LEVEL_INVALID) &&
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !wpa_dbus_dict_append_int32(&iter_dict, "level", bss->level))
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_dbus_dict_append_int32(&iter_dict, "maxrate",
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_bss_get_max_rate(bss) * 500000))
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterror:
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply)
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_unref(reply);
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR,
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "an internal error occurred returning "
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "BSSID properties.");
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_capabilities - Return interface capabilities
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a dict of strings
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "capabilities" method call of an interface.
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   struct wpa_supplicant *wpa_s)
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_capa capa;
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter iter, iter_dict;
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char **eap_methods;
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t num_items;
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_bool_t strict = FALSE;
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_get_args(message, NULL,
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DBUS_TYPE_BOOLEAN, &strict,
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DBUS_TYPE_INVALID))
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		strict = FALSE;
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_method_return(message);
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_init_append(reply, &iter);
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* EAP methods */
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eap_methods = eap_get_names_as_string_array(&num_items);
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eap_methods) {
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_bool_t success = FALSE;
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		size_t i = 0;
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		success = wpa_dbus_dict_append_string_array(
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			&iter_dict, "eap", (const char **) eap_methods,
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			num_items);
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* free returned method array */
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (eap_methods[i])
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(eap_methods[i++]);
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(eap_methods);
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!success)
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	res = wpa_drv_get_capa(wpa_s, &capa);
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/***** pairwise cipher */
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!strict) {
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *args[] = {"CCMP", "TKIP", "NONE"};
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_append_string_array(
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_dict, "pairwise", args,
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    sizeof(args) / sizeof(char*)))
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "pairwise",
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_entry,
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_val,
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_array))
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "CCMP"))
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "TKIP"))
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "NONE"))
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_end_string_array(&iter_dict,
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_entry,
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_val,
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_array))
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/***** group cipher */
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!strict) {
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *args[] = {
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"CCMP", "TKIP", "WEP104", "WEP40"
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			};
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_append_string_array(
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_dict, "group", args,
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    sizeof(args) / sizeof(char*)))
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "group",
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_entry,
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_val,
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_array))
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "CCMP"))
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "TKIP"))
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "WEP104"))
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "WEP40"))
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_end_string_array(&iter_dict,
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_entry,
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_val,
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_array))
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/***** key management */
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!strict) {
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *args[] = {
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE",
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"NONE"
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			};
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_append_string_array(
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_dict, "key_mgmt", args,
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    sizeof(args) / sizeof(char*)))
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "key_mgmt",
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_entry,
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_val,
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_array))
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_string_array_add_element(&iter_array,
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							    "NONE"))
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_string_array_add_element(&iter_array,
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							    "IEEE8021X"))
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "WPA-EAP"))
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "WPA-PSK"))
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "WPA-NONE"))
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_end_string_array(&iter_dict,
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_entry,
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_val,
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_array))
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/***** WPA protocol */
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!strict) {
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *args[] = { "RSN", "WPA" };
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_append_string_array(
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_dict, "proto", args,
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    sizeof(args) / sizeof(char*)))
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "proto",
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_entry,
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_val,
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_array))
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "RSN"))
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "WPA"))
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_end_string_array(&iter_dict,
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_entry,
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_val,
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_array))
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/***** auth alg */
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (res < 0) {
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!strict) {
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const char *args[] = { "OPEN", "SHARED", "LEAP" };
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_append_string_array(
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_dict, "auth_alg", args,
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    sizeof(args) / sizeof(char*)))
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_begin_string_array(&iter_dict, "auth_alg",
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_entry,
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_dict_val,
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						      &iter_array))
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "OPEN"))
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "SHARED"))
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (!wpa_dbus_dict_string_array_add_element(
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    &iter_array, "LEAP"))
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_end_string_array(&iter_dict,
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_entry,
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_dict_val,
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						    &iter_array))
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterror:
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply)
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_unref(reply);
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR,
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "an internal error occurred returning "
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "interface capabilities.");
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_add_network - Add a new configured network
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing the object path of the new network
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "addNetwork" method call of a network interface.
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  struct wpa_supplicant *wpa_s)
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_add_network(wpa_s->conf);
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = dbus_message_new_error(message,
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       WPAS_ERROR_ADD_NETWORK_ERROR,
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       "wpa_supplicant could not add "
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       "a network on this interface.");
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_network_added(wpa_s, ssid);
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid->disabled = 1;
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_set_network_defaults(ssid);
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Construct the object path for this network. */
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    "%s/" WPAS_DBUS_NETWORKS_PART "/%d",
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_s->dbus_path, ssid->id);
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_method_return(message);
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 &path, DBUS_TYPE_INVALID);
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_remove_network - Remove a configured network
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "removeNetwork" method call of a network interface.
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     struct wpa_supplicant *wpa_s)
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *op;
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *iface = NULL, *net_id = NULL;
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int id;
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_get_args(message, NULL,
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                           DBUS_TYPE_OBJECT_PATH, &op,
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	                           DBUS_TYPE_INVALID)) {
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Extract the network ID */
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface = wpas_dbus_decompose_object_path(op, &net_id, NULL);
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface == NULL) {
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_network_error(message);
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Ensure the network is actually a child of this interface */
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(iface, wpa_s->dbus_path) != 0) {
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_network_error(message);
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	id = strtoul(net_id, NULL, 10);
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid = wpa_config_get_network(wpa_s->conf, id);
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_network_error(message);
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_network_removed(wpa_s, ssid);
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = dbus_message_new_error(message,
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       WPAS_ERROR_REMOVE_NETWORK_ERROR,
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       "error removing the specified "
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       "on this interface.");
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == wpa_s->current_ssid)
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s,
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      WLAN_REASON_DEAUTH_LEAVING);
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = wpas_dbus_new_success_reply(message);
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(iface);
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(net_id);
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char *dont_quote[] = {
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	"key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	"opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	"bssid", NULL
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic dbus_bool_t should_quote_opt(const char *key)
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i = 0;
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (dont_quote[i] != NULL) {
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (strcmp(key, dont_quote[i]) == 0)
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return FALSE;
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		i++;
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return TRUE;
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_set_network - Set options for a configured network
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus message containing a UINT32 indicating success (1) or
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "set" method call of a configured network.
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  struct wpa_supplicant *wpa_s,
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  struct wpa_ssid *ssid)
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter	iter, iter_dict;
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_init(message, &iter);
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) {
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char *value = NULL;
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		size_t size = 50;
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int ret;
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_opts_error(message,
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt								 NULL);
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Type conversions, since wpa_supplicant wants strings */
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (entry.type == DBUS_TYPE_ARRAY &&
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    entry.array_type == DBUS_TYPE_BYTE) {
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (entry.array_len <= 0)
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			size = entry.array_len * 2 + 1;
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			value = os_zalloc(size);
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (value == NULL)
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = wpa_snprintf_hex(value, size,
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       (u8 *) entry.bytearray_value,
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       entry.array_len);
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ret <= 0)
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (entry.type == DBUS_TYPE_STRING) {
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (should_quote_opt(entry.key)) {
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				size = os_strlen(entry.str_value);
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				/* Zero-length option check */
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (size <= 0)
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto error;
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				size += 3;  /* For quotes and terminator */
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				value = os_zalloc(size);
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (value == NULL)
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto error;
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ret = os_snprintf(value, size, "\"%s\"",
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						  entry.str_value);
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (ret < 0 || (size_t) ret != (size - 1))
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto error;
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			} else {
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				value = os_strdup(entry.str_value);
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				if (value == NULL)
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					goto error;
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (entry.type == DBUS_TYPE_UINT32) {
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			value = os_zalloc(size);
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (value == NULL)
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = os_snprintf(value, size, "%u",
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  entry.uint32_value);
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ret <= 0)
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (entry.type == DBUS_TYPE_INT32) {
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			value = os_zalloc(size);
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (value == NULL)
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ret = os_snprintf(value, size, "%d",
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  entry.int32_value);
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ret <= 0)
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_config_set(ssid, entry.key, value, 0) < 0)
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((os_strcmp(entry.key, "psk") == 0 &&
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     value[0] == '"' && ssid->ssid_len) ||
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_config_update_psk(ssid);
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else if (os_strcmp(entry.key, "priority") == 0)
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_config_update_prio_list(wpa_s->conf);
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(value);
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbus_dict_entry_clear(&entry);
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		continue;
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	error:
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(value);
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_opts_error(message, entry.key);
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbus_dict_entry_clear(&entry);
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!reply)
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_success_reply(message);
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_enable_network - Mark a configured network as enabled
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "enable" method call of a configured network.
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     struct wpa_supplicant *wpa_s,
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     struct wpa_ssid *ssid)
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_enable_network(wpa_s, ssid);
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_dbus_new_success_reply(message);
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_disable_network - Mark a configured network as disabled
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "disable" method call of a configured network.
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      struct wpa_supplicant *wpa_s,
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      struct wpa_ssid *ssid)
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_disable_network(wpa_s, ssid);
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_dbus_new_success_reply(message);
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_select_network - Attempt association with a configured network
10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "selectNetwork" method call of network interface.
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     struct wpa_supplicant *wpa_s)
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *op;
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *iface_obj_path = NULL;
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *network = NULL;
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strlen(dbus_message_get_signature(message)) == 0) {
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Any network */
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = NULL;
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int nid;
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!dbus_message_get_args(message, NULL,
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   DBUS_TYPE_OBJECT_PATH, &op,
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   DBUS_TYPE_INVALID)) {
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_opts_error(message,
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt								 NULL);
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Extract the network number */
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface_obj_path = wpas_dbus_decompose_object_path(op,
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt								 &network,
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt								 NULL);
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface_obj_path == NULL) {
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_iface_error(message);
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Ensure the object path really points to this interface */
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) {
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_network_error(message);
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		nid = strtoul(network, NULL, 10);
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (errno == EINVAL) {
11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_network_error(message);
11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid = wpa_config_get_network(wpa_s->conf, nid);
11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == NULL) {
11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_network_error(message);
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Finally, associate with the network */
11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_select_network(wpa_s, ssid);
11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = wpas_dbus_new_success_reply(message);
11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(iface_obj_path);
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(network);
11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_disconnect - Terminate the current connection
11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "disconnect" method call of network interface.
11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_supplicant *wpa_s)
11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->disconnected = 1;
11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_dbus_new_success_reply(message);
11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_set_ap_scan - Control roaming mode
11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "setAPScan" method call.
11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  struct wpa_supplicant *wpa_s)
11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_uint32_t ap_scan = 1;
11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ap_scan,
11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DBUS_TYPE_INVALID)) {
11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = wpas_dbus_new_success_reply(message);
11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_set_smartcard_modules - Set smartcard related module paths
11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "setSmartcardModules" method call.
11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_set_smartcard_modules(
11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *message, struct wpa_supplicant *wpa_s)
11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter iter, iter_dict;
11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *opensc_engine_path = NULL;
11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pkcs11_engine_path = NULL;
11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pkcs11_module_path = NULL;
12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_dbus_dict_entry entry;
12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!dbus_message_iter_init(message, &iter))
12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto error;
12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!strcmp(entry.key, "opensc_engine_path") &&
12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (entry.type == DBUS_TYPE_STRING)) {
12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			opensc_engine_path = os_strdup(entry.str_value);
12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (opensc_engine_path == NULL)
12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (!strcmp(entry.key, "pkcs11_engine_path") &&
12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (entry.type == DBUS_TYPE_STRING)) {
12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pkcs11_engine_path = os_strdup(entry.str_value);
12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pkcs11_engine_path == NULL)
12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (!strcmp(entry.key, "pkcs11_module_path") &&
12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 (entry.type == DBUS_TYPE_STRING)) {
12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pkcs11_module_path = os_strdup(entry.str_value);
12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (pkcs11_module_path == NULL)
12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto error;
12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbus_dict_entry_clear(&entry);
12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto error;
12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbus_dict_entry_clear(&entry);
12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->conf->opensc_engine_path);
12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->opensc_engine_path = opensc_engine_path;
12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->conf->pkcs11_engine_path);
12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path;
12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->conf->pkcs11_module_path);
12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->pkcs11_module_path = pkcs11_module_path;
12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_eapol(wpa_s->wpa, NULL);
12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_deinit(wpa_s->eapol);
12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->eapol = NULL;
12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_init_eapol(wpa_s);
12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_dbus_new_success_reply(message);
12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidterror:
12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(opensc_engine_path);
12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(pkcs11_engine_path);
12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(pkcs11_module_path);
12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_dbus_new_invalid_opts_error(message, NULL);
12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_get_state - Get interface state
12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a STRING representing the current
12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          interface state
12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "state" method call.
12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					struct wpa_supplicant *wpa_s)
12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *str_state;
12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_method_return(message);
12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply != NULL) {
12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state,
12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 DBUS_TYPE_INVALID);
12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_get_scanning - Get interface scanning state
12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing whether the interface is scanning
12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "scanning" method call.
12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   struct wpa_supplicant *wpa_s)
12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reply = dbus_message_new_method_return(message);
12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reply != NULL) {
12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning,
12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 DBUS_TYPE_INVALID);
13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "dbus: Not enough memory to return "
13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "scanning state");
13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply;
13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: %wpa_supplicant data structure
13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Asks wpa_supplicant to internally store a one or more binary blobs.
13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					struct wpa_supplicant *wpa_s)
13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessage *reply = NULL;
13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter	iter, iter_dict;
13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_init(message, &iter);
13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_new_invalid_opts_error(message, NULL);
13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_config_blob *blob;
13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_opts_error(message,
13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt								 NULL);
13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (entry.type != DBUS_TYPE_ARRAY ||
13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    entry.array_type != DBUS_TYPE_BYTE) {
13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_opts_error(
13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, "Byte array expected.");
13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((entry.array_len <= 0) || (entry.array_len > 65536) ||
13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !strlen(entry.key)) {
13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = wpas_dbus_new_invalid_opts_error(
13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, "Invalid array size.");
13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		blob = os_zalloc(sizeof(*blob));
13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (blob == NULL) {
13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = dbus_message_new_error(
13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, WPAS_ERROR_ADD_ERROR,
13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"Not enough memory to add blob.");
13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		blob->data = os_zalloc(entry.array_len);
13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (blob->data == NULL) {
13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = dbus_message_new_error(
13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, WPAS_ERROR_ADD_ERROR,
13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"Not enough memory to add blob data.");
13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(blob);
13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		blob->name = os_strdup(entry.key);
13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		blob->len = entry.array_len;
13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(blob->data, (u8 *) entry.bytearray_value,
13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				entry.array_len);
13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (blob->name == NULL || blob->data == NULL) {
13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_config_free_blob(blob);
13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			reply = dbus_message_new_error(
13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				message, WPAS_ERROR_ADD_ERROR,
13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"Error adding blob.");
13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Success */
13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!wpa_config_remove_blob(wpa_s->conf, blob->name))
13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_blob_removed(wpa_s, blob->name);
13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_config_set_blob(wpa_s->conf, blob);
13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_blob_added(wpa_s, blob->name);
13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbus_dict_entry_clear(&entry);
13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbus_dict_entry_clear(&entry);
13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return reply ? reply : wpas_dbus_new_success_reply(message);
13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_remove_blob - Remove named binary blobs
13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: %wpa_supplicant data structure
13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A dbus message containing a UINT32 indicating success (1) or
14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0)
14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Asks wpa_supplicant to remove one or more previously stored binary blobs.
14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   struct wpa_supplicant *wpa_s)
14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	DBusMessageIter iter, array;
14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *err_msg = NULL;
14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_init(message, &iter);
14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) ||
14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING))
14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_new_invalid_opts_error(message, NULL);
14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dbus_message_iter_recurse(&iter, &array);
14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const char *name;
14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_iter_get_basic(&array, &name);
14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!os_strlen(name))
14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			err_msg = "Invalid blob name.";
14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_config_remove_blob(wpa_s->conf, name) != 0)
14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			err_msg = "Error removing blob.";
14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_blob_removed(wpa_s, name);
14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dbus_message_iter_next(&array);
14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (err_msg)
14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR,
14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      err_msg);
14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_dbus_new_success_reply(message);
14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpas_dbus_iface_flush - Clear BSS of old or all inactive entries
14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @message: Pointer to incoming dbus message
14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: %wpa_supplicant data structure
14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: a dbus message containing a UINT32 indicating success (1) or
14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *          failure (0), or returns a dbus error message with more information
14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Handler function for "flush" method call. Handles requests for an
14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface with an optional "age" parameter that specifies the minimum
14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * age of a BSS to be flushed.
14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDBusMessage * wpas_dbus_iface_flush(DBusMessage *message,
14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    struct wpa_supplicant *wpa_s)
14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int flush_age = 0;
14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strlen(dbus_message_get_signature(message)) != 0 &&
14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !dbus_message_get_args(message, NULL,
14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DBUS_TYPE_INT32, &flush_age,
14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   DBUS_TYPE_INVALID)) {
14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return wpas_dbus_new_invalid_opts_error(message, NULL);
14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flush_age == 0)
14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_bss_flush(wpa_s);
14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_bss_flush_by_age(wpa_s, flush_age);
14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpas_dbus_new_success_reply(message);
14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1469