diff options
Diffstat (limited to 'contrib/wpa/wpa_supplicant/dbus')
| -rw-r--r-- | contrib/wpa/wpa_supplicant/dbus/dbus_new.c | 133 | ||||
| -rw-r--r-- | contrib/wpa/wpa_supplicant/dbus/dbus_new.h | 27 | ||||
| -rw-r--r-- | contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.c | 287 | ||||
| -rw-r--r-- | contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers.h | 13 | ||||
| -rw-r--r-- | contrib/wpa/wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 5 |
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"); |
