aboutsummaryrefslogtreecommitdiff
path: root/contrib/wpa/wpa_supplicant/dbus
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/wpa/wpa_supplicant/dbus')
-rw-r--r--contrib/wpa/wpa_supplicant/dbus/dbus_new.c133
-rw-r--r--contrib/wpa/wpa_supplicant/dbus/dbus_new.h27
-rw-r--r--contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c287
-rw-r--r--contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h13
-rw-r--r--contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_p2p.c5
5 files changed, 464 insertions, 1 deletions
diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new.c b/contrib/wpa/wpa_supplicant/dbus/dbus_new.c
index 2c01943f754e..9279ae4d5847 100644
--- a/contrib/wpa/wpa_supplicant/dbus/dbus_new.c
+++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new.c
@@ -937,6 +937,95 @@ void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_MESH */
+#ifdef CONFIG_INTERWORKING
+
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss,
+ struct wpa_cred *cred,
+ const char *type,
+ int excluded,
+ int bh,
+ int bss_load,
+ int conn_capab)
+{
+ struct wpas_dbus_priv *iface;
+ DBusMessage *msg;
+ DBusMessageIter iter, dict_iter;
+ char bss_path[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path;
+ char cred_path[WPAS_DBUS_OBJECT_PATH_MAX], *cred_obj_path;
+
+ iface = wpa_s->global->dbus;
+
+ /* Do nothing if the control interface is not turned on */
+ if (!iface || !wpa_s->dbus_new_path)
+ return;
+
+ msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE,
+ "InterworkingAPAdded");
+ if (!msg)
+ return;
+
+ os_snprintf(bss_path, WPAS_DBUS_OBJECT_PATH_MAX,
+ "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
+ wpa_s->dbus_new_path, bss->id);
+ bss_obj_path = bss_path;
+
+ os_snprintf(cred_path, WPAS_DBUS_OBJECT_PATH_MAX,
+ "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%u",
+ wpa_s->dbus_new_path, cred->id);
+ cred_obj_path = cred_path;
+
+ dbus_message_iter_init_append(msg, &iter);
+ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &bss_obj_path) ||
+ !dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
+ &cred_obj_path) ||
+ !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
+ !wpa_dbus_dict_append_string(&dict_iter, "type", type) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "excluded", excluded) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "priority",
+ cred->priority) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "sp_priority",
+ cred->sp_priority) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "below_min_backhaul", bh) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "over_max_bss_load",
+ bss_load) ||
+ !wpa_dbus_dict_append_int32(&dict_iter, "conn_capab_missing",
+ conn_capab) ||
+ !wpa_dbus_dict_close_write(&iter, &dict_iter))
+ wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+ else
+ dbus_connection_send(iface->con, msg, NULL);
+ dbus_message_unref(msg);
+}
+
+
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
+{
+ struct wpas_dbus_priv *iface;
+ DBusMessage *msg;
+
+ iface = wpa_s->global->dbus;
+
+ /* Do nothing if the control interface is not turned on */
+ if (!iface || !wpa_s->dbus_new_path)
+ return;
+
+ msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE,
+ "InterworkingSelectDone");
+ if (!msg)
+ return;
+
+ dbus_connection_send(iface->con, msg, NULL);
+
+ dbus_message_unref(msg);
+}
+
+#endif /* CONFIG_INTERWORKING */
+
+
void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
int depth, const char *subject,
const char *altsubject[],
@@ -3570,6 +3659,35 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
END_ARGS
}
},
+#ifdef CONFIG_INTERWORKING
+ { "AddCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_add_cred,
+ {
+ { "args", "a{sv}", ARG_IN },
+ { "path", "o", ARG_OUT },
+ END_ARGS
+ }
+ },
+ { "RemoveCred", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_remove_cred,
+ {
+ { "path", "o", ARG_IN },
+ END_ARGS
+ }
+ },
+ { "RemoveAllCreds", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_remove_all_creds,
+ {
+ END_ARGS
+ }
+ },
+ { "InterworkingSelect", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) wpas_dbus_handler_interworking_select,
+ {
+ END_ARGS
+ }
+ },
+#endif /* CONFIG_INTERWORKING */
{ NULL, NULL, NULL, { END_ARGS } }
};
@@ -4137,6 +4255,21 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
}
},
#endif /* CONFIG_MESH */
+#ifdef CONFIG_INTERWORKING
+ { "InterworkingAPAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ {
+ { "bss", "o", ARG_OUT },
+ { "cred", "o", ARG_OUT },
+ { "properties", "a{sv}", ARG_OUT },
+ END_ARGS
+ }
+ },
+ { "InterworkingSelectDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ {
+ END_ARGS
+ }
+ },
+#endif /* CONFIG_INTERWORKING */
{ NULL, NULL, { END_ARGS } }
};
diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new.h b/contrib/wpa/wpa_supplicant/dbus/dbus_new.h
index 42db3892ed77..26bdcb548de8 100644
--- a/contrib/wpa/wpa_supplicant/dbus/dbus_new.h
+++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new.h
@@ -16,6 +16,8 @@
struct wpa_global;
struct wpa_supplicant;
struct wpa_ssid;
+struct wpa_cred;
+struct wpa_bss;
struct wps_event_m2d;
struct wps_event_fail;
struct wps_credential;
@@ -96,6 +98,9 @@ enum wpas_dbus_sta_prop {
#define WPAS_DBUS_NEW_P2P_PEERS_PART "Peers"
#define WPAS_DBUS_NEW_IFACE_P2P_PEER WPAS_DBUS_NEW_INTERFACE ".Peer"
+#define WPAS_DBUS_NEW_CREDENTIALS_PART "Credentials"
+#define WPAS_DBUS_NEW_IFACE_CREDENTIAL WPAS_DBUS_NEW_INTERFACE ".Credential"
+
/* Top-level Errors */
#define WPAS_DBUS_ERROR_UNKNOWN_ERROR \
WPAS_DBUS_NEW_INTERFACE ".UnknownError"
@@ -264,6 +269,13 @@ void wpas_dbus_signal_mesh_peer_connected(struct wpa_supplicant *wpa_s,
const u8 *peer_addr);
void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
const u8 *peer_addr, int reason);
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss,
+ struct wpa_cred *cred,
+ const char *type, int excluded,
+ int bh, int bss_load,
+ int conn_capab);
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s);
#else /* CONFIG_CTRL_IFACE_DBUS_NEW */
@@ -616,6 +628,21 @@ void wpas_dbus_signal_mesh_peer_disconnected(struct wpa_supplicant *wpa_s,
{
}
+static inline
+void wpas_dbus_signal_interworking_ap_added(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *bss,
+ struct wpa_cred *cred,
+ const char *type, int excluded,
+ int bh, int bss_load,
+ int conn_capab)
+{
+}
+
+static inline
+void wpas_dbus_signal_interworking_select_done(struct wpa_supplicant *wpa_s)
+{
+}
+
#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
#endif /* CTRL_IFACE_DBUS_H_NEW */
diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c
index db9f30c9aabf..545e9f64295a 100644
--- a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -26,6 +26,7 @@
#include "../scan.h"
#include "../autoscan.h"
#include "../ap.h"
+#include "../interworking.h"
#include "dbus_new_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
@@ -148,6 +149,9 @@ static const char * const dont_quote[] = {
#ifdef CONFIG_P2P
"go_p2p_dev_addr", "p2p_client_list", "psk_list",
#endif /* CONFIG_P2P */
+#ifdef CONFIG_INTERWORKING
+ "roaming_consortium", "required_roaming_consortium",
+#endif /* CONFIG_INTERWORKING */
NULL
};
@@ -329,6 +333,110 @@ error:
/**
+ * set_cred_properties - Set the properties of a configured credential
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * @cred: wpa_cred structure for a configured credential
+ * @iter: DBus message iterator containing dictionary of network
+ * properties to set.
+ * @error: On failure, an error describing the failure
+ * Returns: TRUE if the request succeeds, FALSE if it failed
+ */
+static dbus_bool_t set_cred_properties(struct wpa_supplicant *wpa_s,
+ struct wpa_cred *cred,
+ DBusMessageIter *iter,
+ DBusError *error)
+{
+ struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
+ DBusMessageIter iter_dict;
+ char *value = NULL;
+
+ if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
+ return FALSE;
+
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ size_t size = 50;
+ int ret;
+
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+ goto error;
+
+ value = NULL;
+ if (entry.type == DBUS_TYPE_ARRAY &&
+ entry.array_type == DBUS_TYPE_BYTE) {
+ if (entry.array_len <= 0)
+ goto error;
+
+ size = entry.array_len * 2 + 1;
+ value = os_zalloc(size);
+ if (!value)
+ goto error;
+
+ ret = wpa_snprintf_hex(value, size,
+ (u8 *) entry.bytearray_value,
+ entry.array_len);
+ if (ret <= 0)
+ goto error;
+ } else if (entry.type == DBUS_TYPE_STRING) {
+ if (should_quote_opt(entry.key)) {
+ size = os_strlen(entry.str_value);
+
+ size += 3;
+ value = os_zalloc(size);
+ if (!value)
+ goto error;
+
+ ret = os_snprintf(value, size, "\"%s\"",
+ entry.str_value);
+ if (os_snprintf_error(size, ret))
+ goto error;
+ } else {
+ value = os_strdup(entry.str_value);
+ if (!value)
+ goto error;
+ }
+ } else if (entry.type == DBUS_TYPE_UINT32) {
+ value = os_zalloc(size);
+ if (!value)
+ goto error;
+
+ ret = os_snprintf(value, size, "%u",
+ entry.uint32_value);
+ if (os_snprintf_error(size, ret))
+ goto error;
+ } else if (entry.type == DBUS_TYPE_INT32) {
+ value = os_zalloc(size);
+ if (!value)
+ goto error;
+
+ ret = os_snprintf(value, size, "%d",
+ entry.int32_value);
+ if (os_snprintf_error(size, ret))
+ goto error;
+ } else {
+ goto error;
+ }
+
+ ret = wpa_config_set_cred(cred, entry.key, value, 0);
+ if (ret < 0)
+ goto error;
+
+ os_free(value);
+ value = NULL;
+ wpa_dbus_dict_entry_clear(&entry);
+ }
+
+ return TRUE;
+
+error:
+ os_free(value);
+ wpa_dbus_dict_entry_clear(&entry);
+ dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
+ "invalid message format");
+ return FALSE;
+}
+
+
+/**
* wpas_dbus_simple_property_getter - Get basic type property
* @iter: Message iter to use when appending arguments
* @type: DBus type of property (must be basic type)
@@ -1516,6 +1624,185 @@ DBusMessage * wpas_dbus_handler_abort_scan(DBusMessage *message,
/**
+ * wpas_dbus_new_iface_add_cred - Add a new credential
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: A dbus message containing the object path of the new credential
+ *
+ * Handler function for "AddCred" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter;
+ struct wpa_cred *cred = NULL;
+ char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
+ DBusError error;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (wpa_s->dbus_new_path)
+ cred = wpa_config_add_cred(wpa_s->conf);
+ if (!cred) {
+ wpa_printf(MSG_ERROR, "%s[dbus]: can't add new credential.",
+ __func__);
+ reply = wpas_dbus_error_unknown_error(
+ message,
+ "wpa_supplicant could not add a credential on this interface.");
+ goto err;
+ }
+
+ dbus_error_init(&error);
+ if (!set_cred_properties(wpa_s, cred, &iter, &error)) {
+ wpa_printf(MSG_DEBUG,
+ "%s[dbus]: control interface couldn't set credential properties",
+ __func__);
+ reply = wpas_dbus_reply_new_from_error(message, &error,
+ DBUS_ERROR_INVALID_ARGS,
+ "Failed to add credential");
+ dbus_error_free(&error);
+ goto err;
+ }
+
+ /* Construct the object path for this network. */
+ os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
+ "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%d",
+ wpa_s->dbus_new_path, cred->id);
+
+ reply = dbus_message_new_method_return(message);
+ if (!reply) {
+ reply = wpas_dbus_error_no_memory(message);
+ goto err;
+ }
+ if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID)) {
+ dbus_message_unref(reply);
+ reply = wpas_dbus_error_no_memory(message);
+ goto err;
+ }
+
+ return reply;
+
+err:
+ if (cred)
+ wpa_config_remove_cred(wpa_s->conf, cred->id);
+ return reply;
+}
+
+
+/**
+ * wpas_dbus_handler_remove_cred - Remove a configured credential
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL on success or dbus error on failure
+ *
+ * Handler function for "RemoveCred" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessage *reply = NULL;
+ const char *op;
+ char *iface, *cred_id;
+ int id;
+ struct wpa_cred *cred;
+
+ dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
+ DBUS_TYPE_INVALID);
+
+ /* Extract the network ID and ensure the network is actually a child of
+ * this interface */
+ iface = wpas_dbus_new_decompose_object_path(
+ op, WPAS_DBUS_NEW_CREDENTIALS_PART, &cred_id);
+ if (!iface || !cred_id || !wpa_s->dbus_new_path ||
+ os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
+ reply = wpas_dbus_error_invalid_args(message, op);
+ goto out;
+ }
+
+ errno = 0;
+ id = strtoul(cred_id, NULL, 10);
+ if (errno != 0) {
+ reply = wpas_dbus_error_invalid_args(message, op);
+ goto out;
+ }
+
+ cred = wpa_config_get_cred(wpa_s->conf, id);
+ if (!cred) {
+ wpa_printf(MSG_ERROR, "%s[dbus]: could not find credential %s",
+ __func__, op);
+ reply = wpas_dbus_error_invalid_args(
+ message, "could not find credential");
+ goto out;
+ }
+
+ if (wpas_remove_cred(wpa_s, cred) < 0) {
+ wpa_printf(MSG_ERROR,
+ "%s[dbus]: error occurred when removing cred %d",
+ __func__, id);
+ reply = wpas_dbus_error_unknown_error(
+ message,
+ "error removing the specified credential on its interface.");
+ goto out;
+ }
+
+out:
+ os_free(iface);
+ return reply;
+}
+
+
+/**
+ * wpas_dbus_handler_remove_all_creds - Remove all the configured credentials
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "RemoveAllCreds" method call of a network interface.
+ */
+DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ int res;
+ DBusMessage *reply = NULL;
+
+ res = wpas_remove_all_creds(wpa_s);
+ if (res < 0) {
+ wpa_printf(MSG_ERROR,
+ "%s[dbus]: failed to remove all credentials",
+ __func__);
+ reply = wpas_dbus_error_unknown_error(
+ message, "failed to remove all credentials");
+ }
+
+ return reply;
+}
+
+
+DBusMessage *
+wpas_dbus_handler_interworking_select(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ int result;
+ DBusMessage *reply = NULL;
+
+ /* Automatic selection is disabled and no constraint on channels */
+ result = interworking_select(wpa_s, 0, NULL);
+ if (result < 0) {
+ wpa_printf(MSG_ERROR,
+ "%s[dbus]: failed to start Interworking selection",
+ __func__);
+ reply = wpas_dbus_error_scan_error(
+ message,
+ "error starting Interworking selection.");
+ }
+
+ return reply;
+}
+
+
+/**
* wpas_dbus_handler_signal_poll - Request immediate signal properties
* @message: Pointer to incoming dbus message
* @wpa_s: wpa_supplicant structure for a network interface
diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h
index c36383f05668..a421083f7fe2 100644
--- a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -144,6 +144,19 @@ DBusMessage * wpas_dbus_handler_eap_logoff(DBusMessage *message,
DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_handler_remove_all_creds(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
+DBusMessage *
+wpas_dbus_handler_interworking_select(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
DECLARE_ACCESSOR(wpas_dbus_getter_capabilities);
DECLARE_ACCESSOR(wpas_dbus_getter_state);
DECLARE_ACCESSOR(wpas_dbus_getter_scanning);
diff --git a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 565ced0fd7e2..de79178f4655 100644
--- a/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -744,6 +744,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
unsigned int group_id = 0;
int persistent = 0;
struct wpa_ssid *ssid;
+ const char *group_ifname;
if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
return reply;
@@ -777,6 +778,8 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
!p2p_peer_known(wpa_s->global->p2p, peer_addr))
goto err;
+ /* Capture the interface name for the group first */
+ group_ifname = wpa_s->ifname;
wpa_s = wpa_s->global->p2p_init_wpa_s;
if (persistent) {
@@ -821,7 +824,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
/*
* No group ID means propose to a peer to join my active group
*/
- if (wpas_p2p_invite_group(wpa_s, wpa_s->ifname,
+ if (wpas_p2p_invite_group(wpa_s, group_ifname,
peer_addr, NULL, false)) {
reply = wpas_dbus_error_unknown_error(
message, "Failed to join to an active group");