예제 #1
0
/**
 * wpas_dbus_global_get_interface - Get the object path for an interface name
 * @message: Pointer to incoming dbus message
 * @global: %wpa_supplicant global data structure
 * Returns: The object path of the interface object,
 *          or a dbus error message with more information
 *
 * Handler function for "getInterface" method call. Handles requests
 * by dbus clients for the object path of an specific network interface.
 */
DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
					     struct wpa_global *global)
{
	DBusMessage *reply = NULL;
	const char *ifname;
	const char *path;
	struct wpa_supplicant *wpa_s;

	if (!dbus_message_get_args(message, NULL,
	                           DBUS_TYPE_STRING, &ifname,
	                           DBUS_TYPE_INVALID)) {
		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
		goto out;
	}

	wpa_s = wpa_supplicant_get_iface(global, ifname);
	if (wpa_s == NULL) {
		reply = wpas_dbus_new_invalid_iface_error(message);
		goto out;
	}

	path = wpa_s->dbus_path;
	reply = dbus_message_new_method_return(message);
	dbus_message_append_args(reply,
	                         DBUS_TYPE_OBJECT_PATH, &path,
	                         DBUS_TYPE_INVALID);

out:
	return reply;
}
예제 #2
0
/**
 * wpas_dbus_iface_select_network - Attempt association with a configured network
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: A dbus message containing a UINT32 indicating success (1) or
 *          failure (0)
 *
 * Handler function for "selectNetwork" method call of network interface.
 */
DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
					     struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	const char *op;
	struct wpa_ssid *ssid;
	char *iface_obj_path = NULL;
	char *network = NULL;

	if (os_strlen(dbus_message_get_signature(message)) == 0) {
		/* Any network */
		ssid = NULL;
	} else {
		int nid;

		if (!dbus_message_get_args(message, NULL,
					   DBUS_TYPE_OBJECT_PATH, &op,
					   DBUS_TYPE_INVALID)) {
			reply = wpas_dbus_new_invalid_opts_error(message,
								 NULL);
			goto out;
		}

		/* Extract the network number */
		iface_obj_path = wpas_dbus_decompose_object_path(op,
								 &network,
								 NULL);
		if (iface_obj_path == NULL) {
			reply = wpas_dbus_new_invalid_iface_error(message);
			goto out;
		}
		/* Ensure the object path really points to this interface */
		if (os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		nid = strtoul(network, NULL, 10);
		if (errno == EINVAL) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		ssid = wpa_config_get_network(wpa_s->conf, nid);
		if (ssid == NULL) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}
	}

	/* Finally, associate with the network */
	wpa_supplicant_select_network(wpa_s, ssid);

	reply = wpas_dbus_new_success_reply(message);

out:
	os_free(iface_obj_path);
	os_free(network);
	return reply;
}
예제 #3
0
/**
 * wpas_dbus_global_remove_interface - Request deregistration of an interface
 * @message: Pointer to incoming dbus message
 * @global: wpa_supplicant global data structure
 * Returns: a dbus message containing a UINT32 indicating success (1) or
 *          failure (0), or returns a dbus error message with more information
 *
 * Handler function for "removeInterface" method call.  Handles requests
 * by dbus clients to deregister a network interface that wpa_supplicant
 * currently manages.
 */
DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
						struct wpa_global *global)
{
	struct wpa_supplicant *wpa_s;
	char *path;
	DBusMessage *reply = NULL;

	if (!dbus_message_get_args(message, NULL,
				   DBUS_TYPE_OBJECT_PATH, &path,
				   DBUS_TYPE_INVALID)) {
		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
		goto out;
	}

	wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path);
	if (wpa_s == NULL) {
		reply = wpas_dbus_new_invalid_iface_error(message);
		goto out;
	}

	if (!wpa_supplicant_remove_iface(global, wpa_s, 0)) {
		reply = wpas_dbus_new_success_reply(message);
	} else {
		reply = dbus_message_new_error(message,
					       WPAS_ERROR_REMOVE_ERROR,
					       "wpa_supplicant couldn't "
					       "remove this interface.");
	}

out:
	return reply;
}
/**
 * wpas_iface_message_handler - Dispatch messages for interfaces or networks
 * @connection: Connection to the system message bus
 * @message: An incoming dbus message
 * @user_data: A pointer to a dbus control interface data structure
 * Returns: Whether or not the message was handled
 *
 * This function dispatches all incoming dbus messages for network interfaces,
 * or objects owned by them, such as scanned BSSIDs and configured networks.
 */
static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
						    DBusMessage *message,
						    void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	const char *method = dbus_message_get_member(message);
	const char *path = dbus_message_get_path(message);
	const char *msg_interface = dbus_message_get_interface(message);
	char *iface_obj_path = NULL;
	char *network = NULL;
	char *bssid = NULL;
	DBusMessage *reply = NULL;

	/* Caller must specify a message interface */
	if (!msg_interface)
		goto out;

	iface_obj_path = wpas_dbus_decompose_object_path(path, &network,
	                                                 &bssid);
	if (iface_obj_path == NULL) {
		reply = wpas_dbus_new_invalid_iface_error(message);
		goto out;
	}

	/* Make sure the message's object path actually refers to the
	 * wpa_supplicant structure it's supposed to (which is wpa_s)
	 */
	if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global,
	                                          iface_obj_path) != wpa_s) {
		reply = wpas_dbus_new_invalid_iface_error(message);
		goto out;
	}

	if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) {
		/* A method for one of this interface's configured networks */
		int nid = strtoul(network, NULL, 10);
		if (errno != EINVAL)
			reply = wpas_dispatch_network_method(message, wpa_s,
							     nid);
		else
			reply = wpas_dbus_new_invalid_network_error(message);
	} else if (bssid && !strcmp(msg_interface, WPAS_DBUS_IFACE_BSSID)) {
		/* A method for one of this interface's scanned BSSIDs */
		reply = wpas_dispatch_bssid_method(message, wpa_s, bssid);
	} else if (!strcmp(msg_interface, WPAS_DBUS_IFACE_INTERFACE)) {
		/* A method for an interface only. */
		if (!strcmp(method, "scan"))
			reply = wpas_dbus_iface_scan(message, wpa_s);
		else if (!strcmp(method, "scanResults"))
			reply = wpas_dbus_iface_scan_results(message, wpa_s);
		else if (!strcmp(method, "addNetwork"))
			reply = wpas_dbus_iface_add_network(message, wpa_s);
		else if (!strcmp(method, "removeNetwork"))
			reply = wpas_dbus_iface_remove_network(message, wpa_s);
		else if (!strcmp(method, "selectNetwork"))
			reply = wpas_dbus_iface_select_network(message, wpa_s);
		else if (!strcmp(method, "capabilities"))
			reply = wpas_dbus_iface_capabilities(message, wpa_s);
		else if (!strcmp(method, "disconnect"))
			reply = wpas_dbus_iface_disconnect(message, wpa_s);
		else if (!strcmp(method, "setAPScan"))
			reply = wpas_dbus_iface_set_ap_scan(message, wpa_s);
		else if (!strcmp(method, "setSmartcardModules"))
			reply = wpas_dbus_iface_set_smartcard_modules(message,
								      wpa_s);
		else if (!strcmp(method, "state"))
			reply = wpas_dbus_iface_get_state(message, wpa_s);
		else if (!strcmp(method, "scanning"))
			reply = wpas_dbus_iface_get_scanning(message, wpa_s);
		else if (!strcmp(method, "setBlobs"))
			reply = wpas_dbus_iface_set_blobs(message, wpa_s);
		else if (!strcmp(method, "removeBlobs"))
			reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
#ifdef CONFIG_WPS
		else if (!os_strcmp(method, "wpsPbc"))
			reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
		else if (!os_strcmp(method, "wpsPin"))
			reply = wpas_dbus_iface_wps_pin(message, wpa_s);
		else if (!os_strcmp(method, "wpsReg"))
			reply = wpas_dbus_iface_wps_reg(message, wpa_s);
#endif /* CONFIG_WPS */
		else if (!os_strcmp(method, "flush"))
			reply = wpas_dbus_iface_flush(message, wpa_s);
	}

	/* If the message was handled, send back the reply */
	if (reply) {
		if (!dbus_message_get_no_reply(message))
			dbus_connection_send(connection, reply, NULL);
		dbus_message_unref(reply);
	}

out:
	os_free(iface_obj_path);
	os_free(network);
	os_free(bssid);
	return reply ? DBUS_HANDLER_RESULT_HANDLED :
		DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
예제 #5
0
/**
 * wpas_dbus_iface_select_network - Attempt association with a configured network
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: A dbus message containing a UINT32 indicating success (1) or
 *          failure (0)
 *
 * Handler function for "selectNetwork" method call of network interface.
 */
DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
					     struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	const char *op;
	struct wpa_ssid *ssid;
	char *iface_obj_path = NULL;
	char *network = NULL;

	if (strlen(dbus_message_get_signature(message)) == 0) {
		/* Any network */
		ssid = wpa_s->conf->ssid;
		while (ssid) {
			ssid->disabled = 0;
			ssid = ssid->next;
		}
		wpa_s->reassociate = 1;
		wpa_supplicant_req_scan(wpa_s, 0, 0);
	} else {
		const char *obj_path;
		int nid;

		if (!dbus_message_get_args(message, NULL,
					   DBUS_TYPE_OBJECT_PATH, &op,
					   DBUS_TYPE_INVALID)) {
			reply = wpas_dbus_new_invalid_opts_error(message,
								 NULL);
			goto out;
		}

		/* Extract the network number */
		iface_obj_path = wpas_dbus_decompose_object_path(op,
								 &network,
								 NULL);
		if (iface_obj_path == NULL) {
			reply = wpas_dbus_new_invalid_iface_error(message);
			goto out;
		}
		/* Ensure the object path really points to this interface */
		obj_path = wpa_supplicant_get_dbus_path(wpa_s);
		if (strcmp(iface_obj_path, obj_path) != 0) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		nid = strtoul(network, NULL, 10);
		if (errno == EINVAL) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		ssid = wpa_config_get_network(wpa_s->conf, nid);
		if (ssid == NULL) {
			reply = wpas_dbus_new_invalid_network_error(message);
			goto out;
		}

		/* Finally, associate with the network */
		if (ssid != wpa_s->current_ssid && wpa_s->current_ssid)
			wpa_supplicant_disassociate(
				wpa_s, WLAN_REASON_DEAUTH_LEAVING);

		/* Mark all other networks disabled and trigger reassociation
		 */
		ssid = wpa_s->conf->ssid;
		while (ssid) {
			ssid->disabled = (nid != ssid->id);
			ssid = ssid->next;
		}
		wpa_s->disconnected = 0;
		wpa_s->reassociate = 1;
		wpa_supplicant_req_scan(wpa_s, 0, 0);
	}

	reply = wpas_dbus_new_success_reply(message);

out:
	free(iface_obj_path);
	free(network);
	return reply;
}