/*
 * UFD routines for Wi-Fi Protected Setup
 * Copyright (c) 2009-2012, Masashi Honma <masashi.honma@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 <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>

#include "wps/wps.h"
#include "wps/wps_i.h"

#ifdef CONFIG_NATIVE_WINDOWS
#define UFD_DIR1 "%s\\SMRTNTKY"
#define UFD_DIR2 UFD_DIR1 "\\WFAWSC"
#define UFD_FILE UFD_DIR2 "\\%s"
#else /* CONFIG_NATIVE_WINDOWS */
#define UFD_DIR1 "%s/SMRTNTKY"
#define UFD_DIR2 UFD_DIR1 "/WFAWSC"
#define UFD_FILE UFD_DIR2 "/%s"
#endif /* CONFIG_NATIVE_WINDOWS */


struct wps_ufd_data {
	int ufd_fd;
};


static int dev_pwd_e_file_filter(const struct dirent *entry)
{
	unsigned int prefix;
	char ext[5];

	if (sscanf(entry->d_name, "%8x.%4s", &prefix, ext) != 2)
		return 0;
	if (prefix == 0)
		return 0;
	if (os_strcasecmp(ext, "WFA") != 0)
		return 0;

	return 1;
}


static int wps_get_dev_pwd_e_file_name(char *path, char *file_name)
{
	struct dirent **namelist;
	int i, file_num;

	file_num = scandir(path, &namelist, &dev_pwd_e_file_filter,
			   alphasort);
	if (file_num < 0) {
		wpa_printf(MSG_ERROR, "WPS: OOB file not found: %d (%s)",
			   errno, strerror(errno));
		return -1;
	}
	if (file_num == 0) {
		wpa_printf(MSG_ERROR, "WPS: OOB file not found");
		os_free(namelist);
		return -1;
	}
	os_strlcpy(file_name, namelist[0]->d_name, 13);
	for (i = 0; i < file_num; i++)
		os_free(namelist[i]);
	os_free(namelist);
	return 0;
}


static int get_file_name(struct wps_context *wps, int registrar,
			 const char *path, char *file_name)
{
	switch (wps->oob_conf.oob_method) {
	case OOB_METHOD_CRED:
		os_snprintf(file_name, 13, "00000000.WSC");
		break;
	case OOB_METHOD_DEV_PWD_E:
		if (registrar) {
			char temp[128];
			os_snprintf(temp, sizeof(temp), UFD_DIR2, path);
			if (wps_get_dev_pwd_e_file_name(temp, file_name) < 0)
				return -1;
		} else {
			u8 *mac_addr = wps->dev.mac_addr;

			os_snprintf(file_name, 13, "%02X%02X%02X%02X.WFA",
				    mac_addr[2], mac_addr[3], mac_addr[4],
				    mac_addr[5]);
		}
		break;
	case OOB_METHOD_DEV_PWD_R:
		os_snprintf(file_name, 13, "00000000.WFA");
		break;
	default:
		wpa_printf(MSG_ERROR, "WPS: Invalid USBA OOB method");
		return -1;
	}
	return 0;
}


static int ufd_mkdir(const char *path)
{
	if (mkdir(path, S_IRWXU) < 0 && errno != EEXIST) {
		wpa_printf(MSG_ERROR, "WPS (UFD): Failed to create directory "
			   "'%s': %d (%s)", path, errno, strerror(errno));
		return -1;
	}
	return 0;
}


static void * init_ufd(struct wps_context *wps,
		       struct oob_device_data *oob_dev, int registrar)
{
	int write_f;
	char temp[128];
	char *path = oob_dev->device_path;
	char filename[13];
	struct wps_ufd_data *data;
	int ufd_fd;

	if (path == NULL)
		return NULL;

	write_f = wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E ?
		!registrar : registrar;

	if (get_file_name(wps, registrar, path, filename) < 0) {
		wpa_printf(MSG_ERROR, "WPS (UFD): Failed to get file name");
		return NULL;
	}

	if (write_f) {
		os_snprintf(temp, sizeof(temp), UFD_DIR1, path);
		if (ufd_mkdir(temp))
			return NULL;
		os_snprintf(temp, sizeof(temp), UFD_DIR2, path);
		if (ufd_mkdir(temp))
			return NULL;
	}

	os_snprintf(temp, sizeof(temp), UFD_FILE, path, filename);
	if (write_f)
		ufd_fd = open(temp, O_WRONLY | O_CREAT | O_TRUNC,
			      S_IRUSR | S_IWUSR);
	else
		ufd_fd = open(temp, O_RDONLY);
	if (ufd_fd < 0) {
		wpa_printf(MSG_ERROR, "WPS (UFD): Failed to open %s: %s",
			   temp, strerror(errno));
		return NULL;
	}

	data = os_zalloc(sizeof(*data));
	if (data == NULL) {
		close(ufd_fd);
		return NULL;
	}
	data->ufd_fd = ufd_fd;
	return data;
}


static struct wpabuf * read_ufd(void *priv)
{
	struct wps_ufd_data *data = priv;
	struct wpabuf *buf;
	struct stat s;
	size_t file_size;

	if (fstat(data->ufd_fd, &s) < 0) {
		wpa_printf(MSG_ERROR, "WPS (UFD): Failed to get file size");
		return NULL;
	}

	file_size = s.st_size;
	buf = wpabuf_alloc(file_size);
	if (buf == NULL) {
		wpa_printf(MSG_ERROR, "WPS (UFD): Failed to alloc read "
			   "buffer");
		return NULL;
	}

	if (read(data->ufd_fd, wpabuf_mhead(buf), file_size) !=
	    (int) file_size) {
		wpabuf_free(buf);
		wpa_printf(MSG_ERROR, "WPS (UFD): Failed to read");
		return NULL;
	}
	wpabuf_put(buf, file_size);
	return buf;
}


static int write_ufd(void *priv, struct wpabuf *buf)
{
	struct wps_ufd_data *data = priv;

	if (write(data->ufd_fd, wpabuf_mhead(buf), wpabuf_len(buf)) !=
	    (int) wpabuf_len(buf)) {
		wpa_printf(MSG_ERROR, "WPS (UFD): Failed to write");
		return -1;
	}
	return 0;
}


static void deinit_ufd(void *priv)
{
	struct wps_ufd_data *data = priv;
	close(data->ufd_fd);
	os_free(data);
}


struct oob_device_data oob_ufd_device_data = {
	.device_name	= NULL,
	.device_path	= NULL,
	.init_func	= init_ufd,
	.read_func	= read_ufd,
	.write_func	= write_ufd,
	.deinit_func	= deinit_ufd,
};
