* WPA Supplicant / dbus-based control interface
* Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
* Copyright (c) 2009-2010, Witold Sowa <witold.sowa@gmail.com>
- * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2009-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
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;
} 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;
if (wpa_config_set(ssid, entry.key, value, 0) < 0)
goto error;
+ if (os_strcmp(entry.key, "bssid") != 0 &&
+ os_strcmp(entry.key, "priority") != 0)
+ wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
+
+ if (wpa_s->current_ssid == ssid ||
+ wpa_s->current_ssid == NULL) {
+ /*
+ * Invalidate the EAP session cache if anything in the
+ * current or previously used configuration changes.
+ */
+ eapol_sm_invalidate_cached_session(wpa_s->eapol);
+ }
+
if ((os_strcmp(entry.key, "psk") == 0 &&
value[0] == '"' && ssid->ssid_len) ||
(os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
driver = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (driver == NULL)
- goto error;
+ goto oom;
} else if (os_strcmp(entry.key, "Ifname") == 0 &&
entry.type == DBUS_TYPE_STRING) {
os_free(ifname);
ifname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (ifname == NULL)
- goto error;
+ goto oom;
} else if (os_strcmp(entry.key, "ConfigFile") == 0 &&
entry.type == DBUS_TYPE_STRING) {
os_free(confname);
confname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (confname == NULL)
- goto error;
+ goto oom;
} else if (os_strcmp(entry.key, "BridgeIfname") == 0 &&
entry.type == DBUS_TYPE_STRING) {
os_free(bridge_ifname);
bridge_ifname = os_strdup(entry.str_value);
wpa_dbus_dict_entry_clear(&entry);
if (bridge_ifname == NULL)
- goto error;
+ goto oom;
} else {
wpa_dbus_dict_entry_clear(&entry);
goto error;
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);
error:
reply = wpas_dbus_error_invalid_args(message, NULL);
goto out;
+oom:
+ reply = wpas_dbus_error_no_memory(message);
+ goto out;
}
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;
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) {
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,
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;
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) {
#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");
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__);
/**
+ * 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
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;
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;
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;
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;
}
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);
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);
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");
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++;
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,
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";
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__);
#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))
}
#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;
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)