X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fdbus%2Fdbus_new_handlers.c;h=de6d2161eefb24119fea000942832ade4189b199;hb=e8afaad7fd9a7fc9a761ed2f8a117bbb6ac9c730;hp=0b0292070f968525b84d3386fdf4bf9c327b310d;hpb=98a4cd447e9f1322f9f1e93a4deb34a51b10ca4d;p=mech_eap.git diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 0b02920..de6d216 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -2,7 +2,7 @@ * WPA Supplicant / dbus-based control interface * Copyright (c) 2006, Dan Williams and Red Hat, Inc. * Copyright (c) 2009-2010, Witold Sowa - * Copyright (c) 2009, Jouni Malinen + * Copyright (c) 2009-2015, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -157,7 +157,8 @@ static struct wpa_supplicant * get_iface_by_dbus_path( struct wpa_supplicant *wpa_s; for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { - if (os_strcmp(wpa_s->dbus_new_path, path) == 0) + if (wpa_s->dbus_new_path && + os_strcmp(wpa_s->dbus_new_path, path) == 0) return wpa_s; } return NULL; @@ -213,7 +214,7 @@ dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s, } else if (entry.type == DBUS_TYPE_STRING) { if (should_quote_opt(entry.key)) { size = os_strlen(entry.str_value); - if (size <= 0) + if (size == 0) goto error; size += 3; @@ -434,7 +435,8 @@ dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter, for (i = 0; i < array_len; i++) { if (!dbus_message_iter_append_basic(&array_iter, type, - array + i * element_size)) { + (const char *) array + + i * element_size)) { dbus_set_error(error, DBUS_ERROR_FAILED, "%s: failed to construct message 2.5", __func__); @@ -599,8 +601,8 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, iface.confname = confname; iface.bridge_ifname = bridge_ifname; /* Otherwise, have wpa_supplicant attach to it. */ - wpa_s = wpa_supplicant_add_iface(global, &iface); - if (wpa_s) { + wpa_s = wpa_supplicant_add_iface(global, &iface, NULL); + if (wpa_s && wpa_s->dbus_new_path) { const char *path = wpa_s->dbus_new_path; reply = dbus_message_new_method_return(message); @@ -684,7 +686,7 @@ DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message, DBUS_TYPE_INVALID); wpa_s = wpa_supplicant_get_iface(global, ifname); - if (wpa_s == NULL) + if (wpa_s == NULL || wpa_s->dbus_new_path == NULL) return wpas_dbus_error_iface_unknown(message); path = wpa_s->dbus_new_path; @@ -710,9 +712,9 @@ DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message, * * Getter for "DebugLevel" property. */ -dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_debug_level( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { const char *str; int idx = wpa_debug_level; @@ -736,9 +738,9 @@ dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter, * * Getter for "DebugTimestamp" property. */ -dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_debug_timestamp( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, &wpa_debug_timestamp, error); @@ -755,9 +757,9 @@ dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter, * * Getter for "DebugShowKeys" property. */ -dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_debug_show_keys( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN, &wpa_debug_show_keys, error); @@ -773,8 +775,9 @@ dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter, * * Setter for "DebugLevel" property. */ -dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter, - DBusError *error, void *user_data) +dbus_bool_t wpas_dbus_setter_debug_level( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_global *global = user_data; const char *str = NULL; @@ -811,9 +814,9 @@ dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter, * * Setter for "DebugTimestamp" property. */ -dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_debug_timestamp( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_global *global = user_data; dbus_bool_t val; @@ -837,9 +840,9 @@ dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter, * * Setter for "DebugShowKeys" property. */ -dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_debug_show_keys( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_global *global = user_data; dbus_bool_t val; @@ -866,9 +869,9 @@ dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter, * by dbus clients to return list of registered interfaces objects * paths */ -dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_interfaces( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_global *global = user_data; struct wpa_supplicant *wpa_s; @@ -876,8 +879,10 @@ dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, unsigned int i = 0, num = 0; dbus_bool_t success; - for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) - num++; + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { + if (wpa_s->dbus_new_path) + num++; + } paths = os_calloc(num, sizeof(char *)); if (!paths) { @@ -885,8 +890,10 @@ dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, return FALSE; } - for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) - paths[i++] = wpa_s->dbus_new_path; + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { + if (wpa_s->dbus_new_path) + paths[i++] = wpa_s->dbus_new_path; + } success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_OBJECT_PATH, @@ -907,8 +914,9 @@ dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, * Getter for "EapMethods" property. Handles requests * by dbus clients to return list of strings with supported EAP methods */ -dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter, - DBusError *error, void *user_data) +dbus_bool_t wpas_dbus_getter_eap_methods( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { char **eap_methods; size_t num_items = 0; @@ -943,9 +951,9 @@ dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter, * return a list of strings with supported capabilities like AP, RSN IBSS, * and P2P that are determined at compile time. */ -dbus_bool_t wpas_dbus_getter_global_capabilities(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_global_capabilities( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { const char *capabilities[5] = { NULL, NULL, NULL, NULL, NULL }; size_t num_items = 0; @@ -1034,10 +1042,10 @@ static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var, dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len); - if (len > MAX_SSID_LEN) { + if (len > SSID_MAX_LEN) { wpa_printf(MSG_DEBUG, "%s[dbus]: SSID too long (len=%d max_len=%d)", - __func__, len, MAX_SSID_LEN); + __func__, len, SSID_MAX_LEN); *reply = wpas_dbus_error_invalid_args( message, "Invalid SSID: too long"); return -1; @@ -1327,14 +1335,26 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, message, "You can specify only Channels in passive scan"); goto out; - } else if (params.freqs && params.freqs[0]) { - if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) { - reply = wpas_dbus_error_scan_error( - message, "Scan request rejected"); - } } else { - wpa_s->scan_req = MANUAL_SCAN_REQ; - wpa_supplicant_req_scan(wpa_s, 0, 0); + if (wpa_s->sched_scanning) { + wpa_printf(MSG_DEBUG, + "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed", + __func__); + wpa_supplicant_cancel_sched_scan(wpa_s); + } + + if (params.freqs && params.freqs[0]) { + wpa_s->last_scan_req = MANUAL_SCAN_REQ; + if (wpa_supplicant_trigger_scan(wpa_s, + ¶ms)) { + reply = wpas_dbus_error_scan_error( + message, + "Scan request rejected"); + } + } else { + wpa_s->scan_req = MANUAL_SCAN_REQ; + wpa_supplicant_req_scan(wpa_s, 0, 0); + } } } else if (os_strcmp(type, "active") == 0) { if (!params.num_ssids) { @@ -1344,6 +1364,14 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, #ifdef CONFIG_AUTOSCAN autoscan_deinit(wpa_s); #endif /* CONFIG_AUTOSCAN */ + if (wpa_s->sched_scanning) { + wpa_printf(MSG_DEBUG, + "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed", + __func__); + wpa_supplicant_cancel_sched_scan(wpa_s); + } + + wpa_s->last_scan_req = MANUAL_SCAN_REQ; if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) { reply = wpas_dbus_error_scan_error( message, "Scan request rejected"); @@ -1478,7 +1506,8 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, dbus_message_iter_init(message, &iter); - ssid = wpa_config_add_network(wpa_s->conf); + if (wpa_s->dbus_new_path) + ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) { wpa_printf(MSG_ERROR, "%s[dbus]: can't add new interface.", __func__); @@ -1554,6 +1583,27 @@ DBusMessage * wpas_dbus_handler_reassociate(DBusMessage *message, /** + * wpas_dbus_handler_expect_disconnect - ExpectDisconnect + * @message: Pointer to incoming dbus message + * @global: %wpa_supplicant global data structure + * Returns: NULL + * + * Handler function for notifying system there will be a expected disconnect. + * This will prevent wpa_supplicant from adding blacklists upon next disconnect.. + */ +DBusMessage * wpas_dbus_handler_expect_disconnect(DBusMessage *message, + struct wpa_global *global) +{ + struct wpa_supplicant *wpa_s = global->ifaces; + + for (; wpa_s; wpa_s = wpa_s->next) + if (wpa_s->wpa_state >= WPA_ASSOCIATED) + wpa_s->own_disconnect_req = 1; + return NULL; +} + + +/** * wpas_dbus_handler_reattach - Reattach to current AP * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface @@ -1577,6 +1627,30 @@ DBusMessage * wpas_dbus_handler_reattach(DBusMessage *message, /** + * wpas_dbus_handler_reconnect - Reconnect if disconnected + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: InterfaceDisabled DBus error message if disabled + * or NULL otherwise. + * + * Handler function for "Reconnect" method call of network interface. + */ +DBusMessage * wpas_dbus_handler_reconnect(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { + return dbus_message_new_error(message, + WPAS_DBUS_ERROR_IFACE_DISABLED, + "This interface is disabled"); + } + + if (wpa_s->disconnected) + wpas_request_connection(wpa_s); + return NULL; +} + + +/** * wpas_dbus_handler_remove_network - Remove a configured network * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface @@ -1602,7 +1676,7 @@ DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message, iface = wpas_dbus_new_decompose_object_path(op, WPAS_DBUS_NEW_NETWORKS_PART, &net_id); - if (iface == NULL || net_id == NULL || + if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, op); goto out; @@ -1715,7 +1789,7 @@ DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message, iface = wpas_dbus_new_decompose_object_path(op, WPAS_DBUS_NEW_NETWORKS_PART, &net_id); - if (iface == NULL || net_id == NULL || + if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, op); goto out; @@ -1773,7 +1847,7 @@ DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message, iface = wpas_dbus_new_decompose_object_path(op, WPAS_DBUS_NEW_NETWORKS_PART, &net_id); - if (iface == NULL || net_id == NULL || + if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, op); goto out; @@ -1804,7 +1878,7 @@ out: os_free(iface); return reply; #else /* IEEE8021X_EAPOL */ - wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included"); + wpa_printf(MSG_DEBUG, "dbus: 802.1X not included"); return wpas_dbus_error_unknown_error(message, "802.1X not included"); #endif /* IEEE8021X_EAPOL */ } @@ -2221,6 +2295,35 @@ DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message, #endif /* CONFIG_TDLS */ +#ifndef CONFIG_NO_CONFIG_WRITE +/** + * wpas_dbus_handler_save_config - Save configuration to configuration file + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NULL on Success, Otherwise errror message + * + * Handler function for "SaveConfig" method call of network interface. + */ +DBusMessage * wpas_dbus_handler_save_config(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + int ret; + + if (!wpa_s->conf->update_config) { + return wpas_dbus_error_unknown_error( + message, + "Not allowed to update configuration (update_config=0)"); + } + + ret = wpa_config_write(wpa_s->confname, wpa_s->conf); + if (ret) + return wpas_dbus_error_unknown_error( + message, "Failed to update configuration"); + return NULL; +} +#endif /* CONFIG_NO_CONFIG_WRITE */ + + /** * wpas_dbus_handler_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path * @message: Pointer to incoming dbus message @@ -2266,12 +2369,14 @@ DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path( message, DBUS_ERROR_FAILED, "Reinit of the EAPOL state machine with the new PKCS #11 engine and module path failed."); - wpa_dbus_mark_property_changed( - wpa_s->global->dbus, wpa_s->dbus_new_path, - WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11EnginePath"); - wpa_dbus_mark_property_changed( - wpa_s->global->dbus, wpa_s->dbus_new_path, - WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11ModulePath"); + if (wpa_s->dbus_new_path) { + wpa_dbus_mark_property_changed( + wpa_s->global->dbus, wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11EnginePath"); + wpa_dbus_mark_property_changed( + wpa_s->global->dbus, wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11ModulePath"); + } return NULL; } @@ -2286,8 +2391,9 @@ DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path( * * Getter for "Capabilities" property of an interface. */ -dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter, - DBusError *error, void *user_data) +dbus_bool_t wpas_dbus_getter_capabilities( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; struct wpa_driver_capa capa; @@ -2533,12 +2639,14 @@ dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter, &iter_array) || !wpa_dbus_dict_string_array_add_element( &iter_array, "infrastructure") || - !wpa_dbus_dict_string_array_add_element( - &iter_array, "ad-hoc") || + (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_IBSS) && + !wpa_dbus_dict_string_array_add_element( + &iter_array, "ad-hoc")) || (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_AP) && !wpa_dbus_dict_string_array_add_element( &iter_array, "ap")) || (res >= 0 && (capa.flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) && + !wpa_s->conf->p2p_disabled && !wpa_dbus_dict_string_array_add_element( &iter_array, "p2p")) || !wpa_dbus_dict_end_string_array(&iter_dict, @@ -2577,8 +2685,9 @@ nomem: * * Getter for "State" property. */ -dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_state( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; const char *str_state; @@ -2617,8 +2726,9 @@ dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error, * * Getter for "scanning" property. */ -dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_scanning( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; @@ -2637,8 +2747,9 @@ dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error, * * Getter function for "ApScan" property. */ -dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_ap_scan( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t ap_scan = wpa_s->conf->ap_scan; @@ -2657,8 +2768,9 @@ dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error, * * Setter function for "ApScan" property. */ -dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_ap_scan( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t ap_scan; @@ -2686,9 +2798,9 @@ dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error, * * Getter function for "FastReauth" property. */ -dbus_bool_t wpas_dbus_getter_fast_reauth(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_fast_reauth( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_bool_t fast_reauth = wpa_s->conf->fast_reauth ? TRUE : FALSE; @@ -2708,9 +2820,9 @@ dbus_bool_t wpas_dbus_getter_fast_reauth(DBusMessageIter *iter, * * Setter function for "FastReauth" property. */ -dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_fast_reauth( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_bool_t fast_reauth; @@ -2734,9 +2846,9 @@ dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter, * Getter for "DisconnectReason" property. The reason is negative if it is * locally generated. */ -dbus_bool_t wpas_dbus_getter_disconnect_reason(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_disconnect_reason( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_int32_t reason = wpa_s->disconnect_reason; @@ -2747,6 +2859,27 @@ dbus_bool_t wpas_dbus_getter_disconnect_reason(DBusMessageIter *iter, /** + * wpas_dbus_getter_assoc_status_code - Get most recent failed assoc status code + * @iter: Pointer to incoming dbus message iter + * @error: Location to store error on failure + * @user_data: Function specific data + * Returns: TRUE on success, FALSE on failure + * + * Getter for "AssocStatusCode" property. + */ +dbus_bool_t wpas_dbus_getter_assoc_status_code( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + dbus_int32_t status_code = wpa_s->assoc_status_code; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32, + &status_code, error); +} + + +/** * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age * @iter: Pointer to incoming dbus message iter * @error: Location to store error on failure @@ -2755,9 +2888,9 @@ dbus_bool_t wpas_dbus_getter_disconnect_reason(DBusMessageIter *iter, * * Getter function for "BSSExpireAge" property. */ -dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_expire_age( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t expire_age = wpa_s->conf->bss_expiration_age; @@ -2776,9 +2909,9 @@ dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter, * * Setter function for "BSSExpireAge" property. */ -dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_bss_expire_age( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t expire_age; @@ -2805,9 +2938,9 @@ dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter, * * Getter function for "BSSExpireCount" property. */ -dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_expire_count( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t expire_count = wpa_s->conf->bss_expiration_scan_count; @@ -2826,9 +2959,9 @@ dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter, * * Setter function for "BSSExpireCount" property. */ -dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_bss_expire_count( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_uint32_t expire_count; @@ -2855,8 +2988,9 @@ dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter, * * Getter function for "Country" property. */ -dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_country( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; char country[3]; @@ -2880,8 +3014,9 @@ dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error, * * Setter function for "Country" property. */ -dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_country( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; const char *country; @@ -2918,9 +3053,9 @@ dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error, * * Getter function for "ScanInterval" property. */ -dbus_bool_t wpas_dbus_getter_scan_interval(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_scan_interval( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_int32_t scan_interval = wpa_s->scan_interval; @@ -2939,9 +3074,9 @@ dbus_bool_t wpas_dbus_getter_scan_interval(DBusMessageIter *iter, * * Setter function for "ScanInterval" property. */ -dbus_bool_t wpas_dbus_setter_scan_interval(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_scan_interval( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; dbus_int32_t scan_interval; @@ -2968,8 +3103,9 @@ dbus_bool_t wpas_dbus_setter_scan_interval(DBusMessageIter *iter, * * Getter for "Ifname" property. */ -dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_ifname( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; const char *ifname = wpa_s->ifname; @@ -2988,8 +3124,9 @@ dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error, * * Getter for "Driver" property. */ -dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_driver( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; const char *driver; @@ -3017,14 +3154,14 @@ dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error, * * Getter for "CurrentBSS" property. */ -dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_current_bss( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf; - if (wpa_s->current_bss) + if (wpa_s->current_bss && wpa_s->dbus_new_path) os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", wpa_s->dbus_new_path, wpa_s->current_bss->id); @@ -3045,14 +3182,14 @@ dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter, * * Getter for "CurrentNetwork" property. */ -dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_current_network( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf; - if (wpa_s->current_ssid) + if (wpa_s->current_ssid && wpa_s->dbus_new_path) os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", wpa_s->dbus_new_path, wpa_s->current_ssid->id); @@ -3073,9 +3210,9 @@ dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter, * * Getter for "CurrentAuthMode" property. */ -dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_current_auth_mode( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; const char *eap_mode; @@ -3091,9 +3228,11 @@ dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter, "EAP-%s", eap_mode); auth_mode = eap_mode_buf; - } else { + } else if (wpa_s->current_ssid) { auth_mode = wpa_key_mgmt_txt(wpa_s->key_mgmt, wpa_s->current_ssid->proto); + } else { + auth_mode = "UNKNOWN"; } return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, @@ -3110,9 +3249,9 @@ dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter, * * Getter for "BridgeIfname" property. */ -dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bridge_ifname( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; const char *bridge_ifname = wpa_s->bridge_ifname; @@ -3131,8 +3270,9 @@ dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter, * * Getter for "BSSs" property. */ -dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bsss( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; struct wpa_bss *bss; @@ -3140,6 +3280,12 @@ dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error, unsigned int i = 0; dbus_bool_t success = FALSE; + if (!wpa_s->dbus_new_path) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: no D-Bus interface", __func__); + return FALSE; + } + paths = os_calloc(wpa_s->num_bss, sizeof(char *)); if (!paths) { dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); @@ -3182,8 +3328,9 @@ out: * * Getter for "Networks" property. */ -dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_networks( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; struct wpa_ssid *ssid; @@ -3191,6 +3338,12 @@ dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error, unsigned int i = 0, num = 0; dbus_bool_t success = FALSE; + if (!wpa_s->dbus_new_path) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: no D-Bus interface", __func__); + return FALSE; + } + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) if (!network_is_persistent_group(ssid)) num++; @@ -3239,9 +3392,9 @@ out: * * Getter for "PKCS11EnginePath" property. */ -dbus_bool_t wpas_dbus_getter_pkcs11_engine_path(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_pkcs11_engine_path( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; const char *pkcs11_engine_path; @@ -3264,9 +3417,9 @@ dbus_bool_t wpas_dbus_getter_pkcs11_engine_path(DBusMessageIter *iter, * * Getter for "PKCS11ModulePath" property. */ -dbus_bool_t wpas_dbus_getter_pkcs11_module_path(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_pkcs11_module_path( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; const char *pkcs11_module_path; @@ -3289,8 +3442,9 @@ dbus_bool_t wpas_dbus_getter_pkcs11_module_path(DBusMessageIter *iter, * * Getter for "Blobs" property. */ -dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_blobs( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct wpa_supplicant *wpa_s = user_data; DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter; @@ -3342,6 +3496,79 @@ dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error, } +dbus_bool_t wpas_dbus_getter_iface_global( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + int ret; + char buf[250]; + char *p = buf; + + if (!property_desc->data) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, + "Unhandled interface property %s", + property_desc->dbus_property); + return FALSE; + } + + ret = wpa_config_get_value(property_desc->data, wpa_s->conf, buf, + sizeof(buf)); + if (ret < 0) + *p = '\0'; + + return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &p, + error); +} + + +dbus_bool_t wpas_dbus_setter_iface_global( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) +{ + struct wpa_supplicant *wpa_s = user_data; + const char *new_value = NULL; + char buf[250]; + size_t combined_len; + int ret; + + if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING, + &new_value)) + return FALSE; + + combined_len = os_strlen(property_desc->data) + os_strlen(new_value) + + 3; + if (combined_len >= sizeof(buf)) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, + "Interface property %s value too large", + property_desc->dbus_property); + return FALSE; + } + + if (!new_value[0]) + new_value = "NULL"; + + ret = os_snprintf(buf, combined_len, "%s=%s", property_desc->data, + new_value); + if (os_snprintf_error(combined_len, ret)) { + dbus_set_error(error, WPAS_DBUS_ERROR_UNKNOWN_ERROR, + "Failed to construct new interface property %s", + property_desc->dbus_property); + return FALSE; + } + + if (wpa_config_process_global(wpa_s->conf, buf, -1)) { + dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, + "Failed to set interface property %s", + property_desc->dbus_property); + return FALSE; + } + + wpa_supplicant_update_config(wpa_s); + return TRUE; +} + + static struct wpa_bss * get_bss_helper(struct bss_handler_args *args, DBusError *error, const char *func_name) { @@ -3368,8 +3595,9 @@ static struct wpa_bss * get_bss_helper(struct bss_handler_args *args, * * Getter for "BSSID" property. */ -dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_bssid( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3393,8 +3621,9 @@ dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error, * * Getter for "SSID" property. */ -dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_ssid( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3418,8 +3647,9 @@ dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error, * * Getter for "Privacy" property. */ -dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter, - DBusError *error, void *user_data) +dbus_bool_t wpas_dbus_getter_bss_privacy( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3444,8 +3674,9 @@ dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter, * * Getter for "Mode" property. */ -dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_mode( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3485,8 +3716,9 @@ dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error, * * Getter for "Level" property. */ -dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter, - DBusError *error, void *user_data) +dbus_bool_t wpas_dbus_getter_bss_signal( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3511,8 +3743,9 @@ dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter, * * Getter for "Frequency" property. */ -dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter, - DBusError *error, void *user_data) +dbus_bool_t wpas_dbus_getter_bss_frequency( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3543,8 +3776,9 @@ static int cmp_u8s_desc(const void *a, const void *b) * * Getter for "Rates" property. */ -dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter, - DBusError *error, void *user_data) +dbus_bool_t wpas_dbus_getter_bss_rates( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3583,14 +3817,14 @@ dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter, } -static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter, - struct wpa_ie_data *ie_data, - DBusError *error) +static dbus_bool_t wpas_dbus_get_bss_security_prop( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, struct wpa_ie_data *ie_data, DBusError *error) { DBusMessageIter iter_dict, variant_iter; const char *group; const char *pairwise[5]; /* max 5 pairwise ciphers is supported */ - const char *key_mgmt[8]; /* max 8 key managements may be supported */ + const char *key_mgmt[9]; /* max 9 key managements may be supported */ int n; if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, @@ -3614,8 +3848,14 @@ static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter, key_mgmt[n++] = "wpa-ft-eap"; if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) key_mgmt[n++] = "wpa-eap-sha256"; +#ifdef CONFIG_SUITEB if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) key_mgmt[n++] = "wpa-eap-suite-b"; +#endif /* CONFIG_SUITEB */ +#ifdef CONFIG_SUITEB192 + if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) + key_mgmt[n++] = "wpa-eap-suite-b-192"; +#endif /* CONFIG_SUITEB192 */ if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE) key_mgmt[n++] = "wpa-none"; @@ -3710,8 +3950,9 @@ nomem: * * Getter for "WPA" property. */ -dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_wpa( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3730,7 +3971,7 @@ dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error, return FALSE; } - return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error); + return wpas_dbus_get_bss_security_prop(property_desc, iter, &wpa_data, error); } @@ -3743,8 +3984,9 @@ dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error, * * Getter for "RSN" property. */ -dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_rsn( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3763,7 +4005,7 @@ dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error, return FALSE; } - return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error); + return wpas_dbus_get_bss_security_prop(property_desc, iter, &wpa_data, error); } @@ -3776,8 +4018,9 @@ dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error, * * Getter for "WPS" property. */ -dbus_bool_t wpas_dbus_getter_bss_wps(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_wps( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3785,6 +4028,7 @@ dbus_bool_t wpas_dbus_getter_bss_wps(DBusMessageIter *iter, DBusError *error, struct wpabuf *wps_ie; #endif /* CONFIG_WPS */ DBusMessageIter iter_dict, variant_iter; + int wps_support = 0; const char *type = ""; res = get_bss_helper(args, error, __func__); @@ -3799,6 +4043,7 @@ dbus_bool_t wpas_dbus_getter_bss_wps(DBusMessageIter *iter, DBusError *error, #ifdef CONFIG_WPS wps_ie = wpa_bss_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE); if (wps_ie) { + wps_support = 1; if (wps_is_selected_pbc_registrar(wps_ie)) type = "pbc"; else if (wps_is_selected_pin_registrar(wps_ie)) @@ -3808,7 +4053,7 @@ dbus_bool_t wpas_dbus_getter_bss_wps(DBusMessageIter *iter, DBusError *error, } #endif /* CONFIG_WPS */ - if (!wpa_dbus_dict_append_string(&iter_dict, "Type", type) || + if ((wps_support && !wpa_dbus_dict_append_string(&iter_dict, "Type", type)) || !wpa_dbus_dict_close_write(&variant_iter, &iter_dict) || !dbus_message_iter_close_container(iter, &variant_iter)) goto nomem; @@ -3830,8 +4075,9 @@ nomem: * * Getter for "IEs" property. */ -dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_ies( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3855,8 +4101,9 @@ dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error, * * Getter for BSS age */ -dbus_bool_t wpas_dbus_getter_bss_age(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_bss_age( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct bss_handler_args *args = user_data; struct wpa_bss *res; @@ -3884,8 +4131,9 @@ dbus_bool_t wpas_dbus_getter_bss_age(DBusMessageIter *iter, DBusError *error, * * Getter for "enabled" property of a configured network. */ -dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_enabled( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct network_handler_args *net = user_data; dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE; @@ -3904,8 +4152,9 @@ dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error, * * Setter for "Enabled" property of a configured network. */ -dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_enabled( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct network_handler_args *net = user_data; struct wpa_supplicant *wpa_s; @@ -3937,9 +4186,9 @@ dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error, * * Getter for "Properties" property of a configured network. */ -dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_getter_network_properties( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct network_handler_args *net = user_data; DBusMessageIter variant_iter, dict_iter; @@ -3999,9 +4248,9 @@ out: * * Setter for "Properties" property of a configured network. */ -dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter, - DBusError *error, - void *user_data) +dbus_bool_t wpas_dbus_setter_network_properties( + const struct wpa_dbus_property_desc *property_desc, + DBusMessageIter *iter, DBusError *error, void *user_data) { struct network_handler_args *net = user_data; struct wpa_ssid *ssid = net->ssid; @@ -4096,7 +4345,7 @@ void wpas_dbus_signal_preq(struct wpa_supplicant *wpa_s, struct wpas_dbus_priv *priv = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (priv == NULL) + if (priv == NULL || !wpa_s->dbus_new_path) return; if (wpa_s->preq_notify_peer == NULL) @@ -4139,3 +4388,147 @@ out: } #endif /* CONFIG_AP */ + + +DBusMessage * wpas_dbus_handler_vendor_elem_add(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + u8 *ielems; + int len; + struct ieee802_11_elems elems; + dbus_int32_t frame_id; + DBusMessageIter iter, array; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &frame_id); + if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid ID"); + } + + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &array); + dbus_message_iter_get_fixed_array(&array, &ielems, &len); + if (!ielems || len == 0) { + return dbus_message_new_error( + message, DBUS_ERROR_INVALID_ARGS, "Invalid value"); + } + + if (ieee802_11_parse_elems(ielems, len, &elems, 0) == ParseFailed) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Parse error"); + } + + wpa_s = wpas_vendor_elem(wpa_s, frame_id); + if (!wpa_s->vendor_elem[frame_id]) { + wpa_s->vendor_elem[frame_id] = wpabuf_alloc_copy(ielems, len); + wpas_vendor_elem_update(wpa_s); + return NULL; + } + + if (wpabuf_resize(&wpa_s->vendor_elem[frame_id], len) < 0) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Resize error"); + } + + wpabuf_put_data(wpa_s->vendor_elem[frame_id], ielems, len); + wpas_vendor_elem_update(wpa_s); + return NULL; +} + + +DBusMessage * wpas_dbus_handler_vendor_elem_get(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply; + DBusMessageIter iter, array_iter; + dbus_int32_t frame_id; + const u8 *elem; + size_t elem_len; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &frame_id); + + if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid ID"); + } + + wpa_s = wpas_vendor_elem(wpa_s, frame_id); + if (!wpa_s->vendor_elem[frame_id]) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "ID value does not exist"); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + return wpas_dbus_error_no_memory(message); + + dbus_message_iter_init_append(reply, &iter); + + elem = wpabuf_head_u8(wpa_s->vendor_elem[frame_id]); + elem_len = wpabuf_len(wpa_s->vendor_elem[frame_id]); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, + &array_iter) || + !dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE, + &elem, elem_len) || + !dbus_message_iter_close_container(&iter, &array_iter)) { + dbus_message_unref(reply); + reply = wpas_dbus_error_no_memory(message); + } + + return reply; +} + + +DBusMessage * wpas_dbus_handler_vendor_elem_remove(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + u8 *ielems; + int len; + struct ieee802_11_elems elems; + DBusMessageIter iter, array; + dbus_int32_t frame_id; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_get_basic(&iter, &frame_id); + if (frame_id < 0 || frame_id >= NUM_VENDOR_ELEM_FRAMES) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid ID"); + } + + dbus_message_iter_next(&iter); + dbus_message_iter_recurse(&iter, &array); + dbus_message_iter_get_fixed_array(&array, &ielems, &len); + if (!ielems || len == 0) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Invalid value"); + } + + wpa_s = wpas_vendor_elem(wpa_s, frame_id); + + if (len == 1 && *ielems == '*') { + wpabuf_free(wpa_s->vendor_elem[frame_id]); + wpa_s->vendor_elem[frame_id] = NULL; + wpas_vendor_elem_update(wpa_s); + return NULL; + } + + if (!wpa_s->vendor_elem[frame_id]) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "ID value does not exist"); + } + + if (ieee802_11_parse_elems(ielems, len, &elems, 0) == ParseFailed) { + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Parse error"); + } + + if (wpas_vendor_elem_remove(wpa_s, frame_id, ielems, len) == 0) + return NULL; + + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "Not found"); +}