/*
 * WPA Supplicant / dbus-based control interface (WPS)
 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
 * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "../config.h"
#include "../wpa_supplicant_i.h"
#include "../wps_supplicant.h"
#include "../driver_i.h"
#include "../ap.h"
#include "dbus_new_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
#include "dbus_dict_helpers.h"


struct wps_start_params {
	int role; /* 0 - not set, 1 - enrollee, 2 - registrar */
	int type; /* 0 - not set, 1 - pin,      2 - pbc       */
	u8 *bssid;
	char *pin;
	u8 *p2p_dev_addr;
};


static int wpas_dbus_handler_wps_role(DBusMessage *message,
				      DBusMessageIter *entry_iter,
				      struct wps_start_params *params,
				      DBusMessage **reply)
{
	DBusMessageIter variant_iter;
	char *val;

	dbus_message_iter_recurse(entry_iter, &variant_iter);
	if (dbus_message_iter_get_arg_type(&variant_iter) !=
	    DBUS_TYPE_STRING) {
		wpa_printf(MSG_DEBUG,
			   "dbus: WPS.Start - Wrong Role type, string required");
		*reply = wpas_dbus_error_invalid_args(message,
						      "Role must be a string");
		return -1;
	}
	dbus_message_iter_get_basic(&variant_iter, &val);
	if (os_strcmp(val, "enrollee") == 0)
		params->role = 1;
	else if (os_strcmp(val, "registrar") == 0)
		params->role = 2;
	else {
		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown role %s", val);
		*reply = wpas_dbus_error_invalid_args(message, val);
		return -1;
	}
	return 0;
}


static int wpas_dbus_handler_wps_type(DBusMessage *message,
				      DBusMessageIter *entry_iter,
				      struct wps_start_params *params,
				      DBusMessage **reply)
{
	DBusMessageIter variant_iter;
	char *val;

	dbus_message_iter_recurse(entry_iter, &variant_iter);
	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRING) {
		wpa_printf(MSG_DEBUG,
			   "dbus: WPS.Start - Wrong Type type, string required");
		*reply = wpas_dbus_error_invalid_args(message,
						      "Type must be a string");
		return -1;
	}
	dbus_message_iter_get_basic(&variant_iter, &val);
	if (os_strcmp(val, "pin") == 0)
		params->type = 1;
	else if (os_strcmp(val, "pbc") == 0)
		params->type = 2;
	else {
		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown type %s",
			   val);
		*reply = wpas_dbus_error_invalid_args(message, val);
		return -1;
	}
	return 0;
}


static int wpas_dbus_handler_wps_bssid(DBusMessage *message,
				       DBusMessageIter *entry_iter,
				       struct wps_start_params *params,
				       DBusMessage **reply)
{
	DBusMessageIter variant_iter, array_iter;
	int len;

	dbus_message_iter_recurse(entry_iter, &variant_iter);
	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
	    dbus_message_iter_get_element_type(&variant_iter) !=
	    DBUS_TYPE_BYTE) {
		wpa_printf(MSG_DEBUG,
			   "dbus: WPS.Start - Wrong Bssid type, byte array required");
		*reply = wpas_dbus_error_invalid_args(
			message, "Bssid must be a byte array");
		return -1;
	}
	dbus_message_iter_recurse(&variant_iter, &array_iter);
	dbus_message_iter_get_fixed_array(&array_iter, &params->bssid, &len);
	if (len != ETH_ALEN) {
		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Bssid length %d",
			   len);
		*reply = wpas_dbus_error_invalid_args(message,
						      "Bssid is wrong length");
		return -1;
	}
	return 0;
}


static int wpas_dbus_handler_wps_pin(DBusMessage *message,
				     DBusMessageIter *entry_iter,
				     struct wps_start_params *params,
				     DBusMessage **reply)
{
	DBusMessageIter variant_iter;

	dbus_message_iter_recurse(entry_iter, &variant_iter);
	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRING) {
		wpa_printf(MSG_DEBUG,
			   "dbus: WPS.Start - Wrong Pin type, string required");
		*reply = wpas_dbus_error_invalid_args(message,
						      "Pin must be a string");
		return -1;
	}
	dbus_message_iter_get_basic(&variant_iter, &params->pin);
	return 0;
}


#ifdef CONFIG_P2P
static int wpas_dbus_handler_wps_p2p_dev_addr(DBusMessage *message,
					      DBusMessageIter *entry_iter,
					      struct wps_start_params *params,
					      DBusMessage **reply)
{
	DBusMessageIter variant_iter, array_iter;
	int len;

	dbus_message_iter_recurse(entry_iter, &variant_iter);
	if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY ||
	    dbus_message_iter_get_element_type(&variant_iter) !=
	    DBUS_TYPE_BYTE) {
		wpa_printf(MSG_DEBUG,
			   "dbus: WPS.Start - Wrong P2PDeviceAddress type, byte array required");
		*reply = wpas_dbus_error_invalid_args(
			message, "P2PDeviceAddress must be a byte array");
		return -1;
	}
	dbus_message_iter_recurse(&variant_iter, &array_iter);
	dbus_message_iter_get_fixed_array(&array_iter, &params->p2p_dev_addr,
					  &len);
	if (len != ETH_ALEN) {
		wpa_printf(MSG_DEBUG,
			   "dbus: WPS.Start - Wrong P2PDeviceAddress length %d",
			   len);
		*reply = wpas_dbus_error_invalid_args(
			message, "P2PDeviceAddress has wrong length");
		return -1;
	}
	return 0;
}
#endif /* CONFIG_P2P */


static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key,
					     DBusMessageIter *entry_iter,
					     struct wps_start_params *params,
					     DBusMessage **reply)
{
	if (os_strcmp(key, "Role") == 0)
		return wpas_dbus_handler_wps_role(message, entry_iter,
						  params, reply);
	else if (os_strcmp(key, "Type") == 0)
		return wpas_dbus_handler_wps_type(message, entry_iter,
						  params, reply);
	else if (os_strcmp(key, "Bssid") == 0)
		return wpas_dbus_handler_wps_bssid(message, entry_iter,
						   params, reply);
	else if (os_strcmp(key, "Pin") == 0)
		return wpas_dbus_handler_wps_pin(message, entry_iter,
						 params, reply);
#ifdef CONFIG_P2P
	else if (os_strcmp(key, "P2PDeviceAddress") == 0)
		return wpas_dbus_handler_wps_p2p_dev_addr(message, entry_iter,
							  params, reply);
#endif /* CONFIG_P2P */

	wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key);
	*reply = wpas_dbus_error_invalid_args(message, key);
	return -1;
}


/**
 * wpas_dbus_handler_wps_start - Start WPS configuration
 * @message: Pointer to incoming dbus message
 * @wpa_s: %wpa_supplicant data structure
 * Returns: DBus message dictionary on success or DBus error on failure
 *
 * Handler for "Start" method call. DBus dictionary argument contains
 * information about role (enrollee or registrar), authorization method
 * (pin or push button) and optionally pin and bssid. Returned message
 * has a dictionary argument which may contain newly generated pin (optional).
 */
DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
					  struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	DBusMessageIter iter, dict_iter, entry_iter;
	struct wps_start_params params;
	char *key;
	char npin[9] = { '\0' };
	int ret;

	os_memset(&params, 0, sizeof(params));
	dbus_message_iter_init(message, &iter);

	dbus_message_iter_recurse(&iter, &dict_iter);
	while (dbus_message_iter_get_arg_type(&dict_iter) ==
	       DBUS_TYPE_DICT_ENTRY) {
		dbus_message_iter_recurse(&dict_iter, &entry_iter);

		dbus_message_iter_get_basic(&entry_iter, &key);
		dbus_message_iter_next(&entry_iter);

		if (wpas_dbus_handler_wps_start_entry(message, key,
						      &entry_iter,
						      &params, &reply))
			return reply;

		dbus_message_iter_next(&dict_iter);
	}

#ifdef CONFIG_AP
	if (wpa_s->ap_iface && params.type == 1) {
		if (params.pin == NULL) {
			wpa_printf(MSG_DEBUG,
				   "dbus: WPS.Start - Pin required for registrar role");
			return wpas_dbus_error_invalid_args(
				message, "Pin required for registrar role.");
		}
		ret = wpa_supplicant_ap_wps_pin(wpa_s,
						params.bssid,
						params.pin,
						npin, sizeof(npin), 0);
	} else if (wpa_s->ap_iface) {
		ret = wpa_supplicant_ap_wps_pbc(wpa_s,
						params.bssid,
						params.p2p_dev_addr);
	} else
#endif /* CONFIG_AP */
	if (params.role == 0) {
		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Role not specified");
		return wpas_dbus_error_invalid_args(message,
						    "Role not specified");
	} else if (params.role == 2) {
		if (params.pin == NULL) {
			wpa_printf(MSG_DEBUG,
				   "dbus: WPS.Start - Pin required for registrar role");
			return wpas_dbus_error_invalid_args(
				message, "Pin required for registrar role.");
		}
		ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin,
					 NULL);
	} else if (params.type == 0) {
		wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Type not specified");
		return wpas_dbus_error_invalid_args(message,
						    "Type not specified");
	} else if (params.type == 1) {
		ret = wpas_wps_start_pin(wpa_s, params.bssid,
					 params.pin, 0,
					 DEV_PW_DEFAULT);
		if (ret > 0)
			os_snprintf(npin, sizeof(npin), "%08d", ret);
	} else {
		ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
	}

	if (ret < 0) {
		wpa_printf(MSG_DEBUG,
			   "dbus: WPS.Start wpas_wps_failed in role %s and key %s",
			   (params.role == 1 ? "enrollee" : "registrar"),
			   (params.type == 0 ? "" :
			    (params.type == 1 ? "pin" : "pbc")));
		return wpas_dbus_error_unknown_error(message,
						     "WPS start failed");
	}

	reply = dbus_message_new_method_return(message);
	if (!reply)
		return wpas_dbus_error_no_memory(message);

	dbus_message_iter_init_append(reply, &iter);
	if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
	    (os_strlen(npin) > 0 &&
	     !wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) ||
	    !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
		dbus_message_unref(reply);
		return wpas_dbus_error_no_memory(message);
	}

	return reply;
}


/**
 * wpas_dbus_handler_wps_cancel - Cancel ongoing WPS configuration
 * @message: Pointer to incoming dbus message
 * @wpa_s: %wpa_supplicant data structure
 * Returns: NULL on success or DBus error on failure
 *
 * Handler for "Cancel" method call. Returns NULL if WPS cancel successfull
 * or DBus error on WPS cancel failure
 */
DBusMessage * wpas_dbus_handler_wps_cancel(DBusMessage *message,
					   struct wpa_supplicant *wpa_s)
{
	if (wpas_wps_cancel(wpa_s))
		return wpas_dbus_error_unknown_error(message,
						     "WPS cancel failed");

	return NULL;
}


/**
 * wpas_dbus_getter_process_credentials - Check if credentials are processed
 * @message: Pointer to incoming dbus message
 * @wpa_s: %wpa_supplicant data structure
 * Returns: TRUE on success, FALSE on failure
 *
 * Getter for "ProcessCredentials" property. Returns returned boolean will be
 * true if wps_cred_processing configuration field is not equal to 1 or false
 * if otherwise.
 */
dbus_bool_t wpas_dbus_getter_process_credentials(DBusMessageIter *iter,
						 DBusError *error,
						 void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	dbus_bool_t process = wpa_s->conf->wps_cred_processing != 1;

	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
						&process, error);
}


/**
 * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
 * @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
 *
 * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
 * if boolean argument is true or on 1 if otherwise.
 */
dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
						 DBusError *error,
						 void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	dbus_bool_t process_credentials, old_pc;

	if (!wpa_s->dbus_new_path)
		return FALSE;
	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
					      &process_credentials))
		return FALSE;

	old_pc = wpa_s->conf->wps_cred_processing != 1;
	wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);

	if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
		wpa_dbus_mark_property_changed(wpa_s->global->dbus,
					       wpa_s->dbus_new_path,
					       WPAS_DBUS_NEW_IFACE_WPS,
					       "ProcessCredentials");

	return TRUE;
}


/**
 * wpas_dbus_getter_config_methods - Get current WPS configuration methods
 * @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 "ConfigMethods" property. Returned boolean will be true if
 * providing the relevant string worked, or false otherwise.
 */
dbus_bool_t wpas_dbus_getter_config_methods(DBusMessageIter *iter,
					    DBusError *error,
					    void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	char *methods = wpa_s->conf->config_methods;

	if (methods == NULL)
		methods = "";
	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
						&methods, error);
}


/**
 * wpas_dbus_setter_config_methods - Set WPS configuration methods
 * @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
 *
 * Setter for "ConfigMethods" property. Sets the methods string, apply such
 * change and returns true on success. Returns false otherwise.
 */
dbus_bool_t wpas_dbus_setter_config_methods(DBusMessageIter *iter,
					    DBusError *error,
					    void *user_data)
{
	struct wpa_supplicant *wpa_s = user_data;
	char *methods, *new_methods;

	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
					      &methods))
		return FALSE;

	new_methods = os_strdup(methods);
	if (!new_methods)
		return FALSE;

	os_free(wpa_s->conf->config_methods);
	wpa_s->conf->config_methods = new_methods;

	wpa_s->conf->changed_parameters |= CFG_CHANGED_CONFIG_METHODS;
	wpa_supplicant_update_config(wpa_s);

	return TRUE;
}
