/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2013  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/vfs.h>
#include <sys/inotify.h>
#include <netdb.h>
#include <glib.h>

#include <connman/provision.h>
#include <connman/ipaddress.h>
#include "connman.h"

struct connman_config_service {
	char *ident;
	char *name;
	char *type;
	void *ssid;
	unsigned int ssid_len;
	char *eap;
	char *identity;
	char *ca_cert_file;
	char *client_cert_file;
	char *private_key_file;
	char *private_key_passphrase;
	char *private_key_passphrase_type;
	char *phase2;
	char *passphrase;
	enum connman_service_security security;
	GSList *service_identifiers;
	uint64_t xpan_id;
	char *config_ident; /* file prefix */
	char *config_entry; /* entry name */
	bool hidden;
	bool virtual;
	char *virtual_file;
	char *ipv4_address;
	char *ipv4_netmask;
	char *ipv4_gateway;
	char *ipv6_address;
	unsigned char ipv6_prefix_length;
	char *ipv6_gateway;
	char *ipv6_privacy;
	char *mac;
	char **nameservers;
	char **search_domains;
	char **timeservers;
	char *domain_name;
};

struct connman_config {
	char *ident;
	char *name;
	char *description;
	GHashTable *service_table;
};

static GHashTable *config_table = NULL;

static bool cleanup = false;

/* Definition of possible strings in the .config files */
#define CONFIG_KEY_NAME                "Name"
#define CONFIG_KEY_DESC                "Description"

#define SERVICE_KEY_TYPE               "Type"
#define SERVICE_KEY_NAME               "Name"
#define SERVICE_KEY_SSID               "SSID"
#define SERVICE_KEY_EAP                "EAP"
#define SERVICE_KEY_CA_CERT            "CACertFile"
#define SERVICE_KEY_CL_CERT            "ClientCertFile"
#define SERVICE_KEY_PRV_KEY            "PrivateKeyFile"
#define SERVICE_KEY_PRV_KEY_PASS       "PrivateKeyPassphrase"
#define SERVICE_KEY_PRV_KEY_PASS_TYPE  "PrivateKeyPassphraseType"
#define SERVICE_KEY_IDENTITY           "Identity"
#define SERVICE_KEY_PHASE2             "Phase2"
#define SERVICE_KEY_PASSPHRASE         "Passphrase"
#define SERVICE_KEY_SECURITY           "Security"
#define SERVICE_KEY_HIDDEN             "Hidden"

#define SERVICE_KEY_IPv4               "IPv4"
#define SERVICE_KEY_IPv6               "IPv6"
#define SERVICE_KEY_IPv6_PRIVACY       "IPv6.Privacy"
#define SERVICE_KEY_MAC                "MAC"
#define SERVICE_KEY_NAMESERVERS        "Nameservers"
#define SERVICE_KEY_SEARCH_DOMAINS     "SearchDomains"
#define SERVICE_KEY_TIMESERVERS        "Timeservers"
#define SERVICE_KEY_DOMAIN             "Domain"

#define SERVICE_KEY_EXTENDED_PAN_ID    "ExtendedPANID"

static const char *config_possible_keys[] = {
	CONFIG_KEY_NAME,
	CONFIG_KEY_DESC,
	NULL,
};

static const char *service_possible_keys[] = {
	SERVICE_KEY_TYPE,
	SERVICE_KEY_NAME,
	SERVICE_KEY_SSID,
	SERVICE_KEY_EAP,
	SERVICE_KEY_CA_CERT,
	SERVICE_KEY_CL_CERT,
	SERVICE_KEY_PRV_KEY,
	SERVICE_KEY_PRV_KEY_PASS,
	SERVICE_KEY_PRV_KEY_PASS_TYPE,
	SERVICE_KEY_IDENTITY,
	SERVICE_KEY_PHASE2,
	SERVICE_KEY_PASSPHRASE,
	SERVICE_KEY_SECURITY,
	SERVICE_KEY_HIDDEN,
	SERVICE_KEY_IPv4,
	SERVICE_KEY_IPv6,
	SERVICE_KEY_IPv6_PRIVACY,
	SERVICE_KEY_MAC,
	SERVICE_KEY_NAMESERVERS,
	SERVICE_KEY_SEARCH_DOMAINS,
	SERVICE_KEY_TIMESERVERS,
	SERVICE_KEY_DOMAIN,
	SERVICE_KEY_EXTENDED_PAN_ID,
	NULL,
};

static void unregister_config(gpointer data)
{
	struct connman_config *config = data;

	connman_info("Removing configuration %s", config->ident);

	g_hash_table_destroy(config->service_table);

	g_free(config->description);
	g_free(config->name);
	g_free(config->ident);
	g_free(config);
}

static void unregister_service(gpointer data)
{
	struct connman_config_service *config_service = data;
	struct connman_service *service;
	struct connman_network *network;
	char *service_id;
	GSList *list;

	if (cleanup)
		goto free_only;

	connman_info("Removing service configuration %s",
						config_service->ident);

	if (config_service->virtual)
		goto free_only;

	for (list = config_service->service_identifiers; list;
							list = list->next) {
		service_id = list->data;

		service = __connman_service_lookup_from_ident(service_id);
		if (service) {
			__connman_service_set_immutable(service, false);
			__connman_service_set_config(service, NULL, NULL);
			__connman_service_remove(service);
			/*
			 * When the provisioned service is being deleted
			 * network object should forget the passphrase.
			 */
			network = __connman_service_get_network(service);
			if (network) {
				connman_network_set_string(network,
						"WiFi.Passphrase", NULL);
			}
			/*
			 * Ethernet or gadget service cannot be removed by
			 * __connman_service_remove() so reset the ipconfig
			 * here.
			 */
			if (connman_service_get_type(service) ==
						CONNMAN_SERVICE_TYPE_ETHERNET ||
					connman_service_get_type(service) ==
						CONNMAN_SERVICE_TYPE_GADGET) {
				__connman_service_disconnect(service);
				__connman_service_reset_ipconfig(service,
					CONNMAN_IPCONFIG_TYPE_IPV4, NULL, NULL);
				__connman_service_reset_ipconfig(service,
					CONNMAN_IPCONFIG_TYPE_IPV6, NULL, NULL);
				__connman_service_set_ignore(service, true);

				/*
				 * After these operations, user needs to
				 * reconnect ethernet cable to get IP
				 * address.
				 */
			}
		}

		if (!__connman_storage_remove_service(service_id))
			DBG("Could not remove all files for service %s",
								service_id);
	}

free_only:
	g_free(config_service->ident);
	g_free(config_service->type);
	g_free(config_service->name);
	g_free(config_service->ssid);
	g_free(config_service->eap);
	g_free(config_service->identity);
	g_free(config_service->ca_cert_file);
	g_free(config_service->client_cert_file);
	g_free(config_service->private_key_file);
	g_free(config_service->private_key_passphrase);
	g_free(config_service->private_key_passphrase_type);
	g_free(config_service->phase2);
	g_free(config_service->passphrase);
	g_free(config_service->ipv4_address);
	g_free(config_service->ipv4_gateway);
	g_free(config_service->ipv4_netmask);
	g_free(config_service->ipv6_address);
	g_free(config_service->ipv6_gateway);
	g_free(config_service->ipv6_privacy);
	g_free(config_service->mac);
	g_strfreev(config_service->nameservers);
	g_strfreev(config_service->search_domains);
	g_strfreev(config_service->timeservers);
	g_free(config_service->domain_name);
	g_slist_free_full(config_service->service_identifiers, g_free);
	g_free(config_service->config_ident);
	g_free(config_service->config_entry);
	g_free(config_service->virtual_file);
	g_free(config_service);
}

static void check_keys(GKeyFile *keyfile, const char *group,
			const char **possible_keys)
{
	char **avail_keys;
	gsize nb_avail_keys, i, j;

	avail_keys = g_key_file_get_keys(keyfile, group, &nb_avail_keys, NULL);
	if (!avail_keys)
		return;

	/*
	 * For each key in the configuration file,
	 * verify it is understood by connman
	 */
	for (i = 0 ; i < nb_avail_keys; i++) {
		for (j = 0; possible_keys[j] ; j++)
			if (g_strcmp0(avail_keys[i], possible_keys[j]) == 0)
				break;

		if (!possible_keys[j])
			connman_warn("Unknown configuration key %s in [%s]",
					avail_keys[i], group);
	}

	g_strfreev(avail_keys);
}

static int check_family(const char *address, int expected_family)
{
	int family;
	int err = 0;

	family = connman_inet_check_ipaddress(address);
	if (family < 0) {
		DBG("Cannot get address family of %s (%d/%s)", address,
			family, gai_strerror(family));
		err = -EINVAL;
		goto out;
	}

	switch (family) {
	case AF_INET:
		if (expected_family != AF_INET) {
			DBG("Wrong type address %s, expecting IPv4", address);
			err = -EINVAL;
			goto out;
		}
		break;
	case AF_INET6:
		if (expected_family != AF_INET6) {
			DBG("Wrong type address %s, expecting IPv6", address);
			err = -EINVAL;
			goto out;
		}
		break;
	default:
		DBG("Unsupported address family %d", family);
		err = -EINVAL;
		goto out;
	}

out:
	return err;
}

static int parse_address(const char *address_str, int address_family,
			char **address, char **netmask, char **gateway)
{
	char *addr_str, *mask_str, *gw_str;
	int err = 0;
	char **route;

	route = g_strsplit(address_str, "/", 0);
	if (!route)
		return -EINVAL;

	addr_str = route[0];
	if (!addr_str || addr_str[0] == '\0') {
		err = -EINVAL;
		goto out;
	}

	if ((err = check_family(addr_str, address_family)) < 0)
		goto out;

	mask_str = route[1];
	if (!mask_str || mask_str[0] == '\0') {
		err = -EINVAL;
		goto out;
	}

	gw_str = route[2];
	if (gw_str && gw_str[0]) {
		if ((err = check_family(gw_str, address_family)) < 0)
			goto out;
	}

	g_free(*address);
	*address = g_strdup(addr_str);

	g_free(*netmask);
	*netmask = g_strdup(mask_str);

	g_free(*gateway);
	*gateway = g_strdup(gw_str);

	if (*gateway)
		DBG("address %s/%s via %s", *address, *netmask, *gateway);
	else
		DBG("address %s/%s", *address, *netmask);

out:
	g_strfreev(route);

	return err;
}

static bool check_address(char *address_str, char **address)
{
	if (g_ascii_strcasecmp(address_str, "auto") == 0 ||
			g_ascii_strcasecmp(address_str, "dhcp") == 0 ||
			g_ascii_strcasecmp(address_str, "off") == 0) {
		*address = address_str;
		return false;
	}

	return true;
}

static bool load_service_generic(GKeyFile *keyfile,
			const char *group, struct connman_config *config,
			struct connman_config_service *service)
{
	char *str, *mask;
	char **strlist;
	gsize length;

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_IPv4, NULL);
	if (str && check_address(str, &service->ipv4_address)) {
		mask = NULL;

		if (parse_address(str, AF_INET, &service->ipv4_address,
					&mask, &service->ipv4_gateway) < 0) {
			connman_warn("Invalid format for IPv4 address %s",
									str);
			g_free(str);
			goto err;
		}

		if (!g_strrstr(mask, ".")) {
			/* We have netmask length */
			in_addr_t addr;
			struct in_addr netmask_in;
			unsigned char prefix_len = 32;
			char *ptr;
			long int value = strtol(mask, &ptr, 10);

			if (ptr != mask && *ptr == '\0' && value && value <= 32)
				prefix_len = value;

			addr = 0xffffffff << (32 - prefix_len);
			netmask_in.s_addr = htonl(addr);
			service->ipv4_netmask =
				g_strdup(inet_ntoa(netmask_in));

			g_free(mask);
		} else
			service->ipv4_netmask = mask;

		g_free(str);
	}

	str =  __connman_config_get_string(keyfile, group, SERVICE_KEY_IPv6, NULL);
	if (str && check_address(str, &service->ipv6_address)) {
		long int value;
		char *ptr;

		mask = NULL;

		if (parse_address(str, AF_INET6, &service->ipv6_address,
					&mask, &service->ipv6_gateway) < 0) {
			connman_warn("Invalid format for IPv6 address %s",
									str);
			g_free(str);
			goto err;
		}

		value = strtol(mask, &ptr, 10);
		if (ptr != mask && *ptr == '\0' && value <= 128)
			service->ipv6_prefix_length = value;
		else
			service->ipv6_prefix_length = 128;

		g_free(mask);
		g_free(str);
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_IPv6_PRIVACY,
									NULL);
	if (str) {
		g_free(service->ipv6_privacy);
		service->ipv6_privacy = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_MAC, NULL);
	if (str) {
		g_free(service->mac);
		service->mac = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_DOMAIN, NULL);
	if (str) {
		g_free(service->domain_name);
		service->domain_name = str;
	}

	strlist = __connman_config_get_string_list(keyfile, group,
					SERVICE_KEY_NAMESERVERS,
					&length, NULL);
	if (strlist) {
		if (length != 0) {
			g_strfreev(service->nameservers);
			service->nameservers = strlist;
		} else
			g_strfreev(strlist);
	}

	strlist = __connman_config_get_string_list(keyfile, group,
					SERVICE_KEY_SEARCH_DOMAINS,
					&length, NULL);
	if (strlist) {
		if (length != 0) {
			g_strfreev(service->search_domains);
			service->search_domains = strlist;
		} else
			g_strfreev(strlist);
	}

	strlist = __connman_config_get_string_list(keyfile, group,
					SERVICE_KEY_TIMESERVERS,
					&length, NULL);
	if (strlist) {
		if (length != 0) {
			g_strfreev(service->timeservers);
			service->timeservers = strlist;
		} else
			g_strfreev(strlist);
	}

	return true;

err:
	g_free(service->ident);
	g_free(service->type);
	g_free(service->ipv4_address);
	g_free(service->ipv4_netmask);
	g_free(service->ipv4_gateway);
	g_free(service->ipv6_address);
	g_free(service->ipv6_gateway);
	g_free(service->mac);
	g_free(service);

	return false;
}

static bool load_service(GKeyFile *keyfile, const char *group,
						struct connman_config *config)
{
	struct connman_config_service *service;
	const char *ident;
	char *str, *hex_ssid;
	enum connman_service_security security;
	bool service_created = false;

	/* Strip off "service_" prefix */
	ident = group + 8;

	if (strlen(ident) < 1)
		return false;

	/* Verify that provided keys are good */
	check_keys(keyfile, group, service_possible_keys);

	service = g_hash_table_lookup(config->service_table, ident);
	if (!service) {
		service = g_try_new0(struct connman_config_service, 1);
		if (!service)
			return false;

		service->ident = g_strdup(ident);

		service_created = true;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_TYPE, NULL);
	if (str) {
		g_free(service->type);
		service->type = str;
	} else {
		DBG("Type of the configured service is missing for group %s",
									group);
		goto err;
	}

	if (!load_service_generic(keyfile, group, config, service))
		return false;

	if (g_strcmp0(str, "ethernet") == 0) {
		service->config_ident = g_strdup(config->ident);
		service->config_entry = g_strdup_printf("service_%s",
							service->ident);

		g_hash_table_insert(config->service_table, service->ident,
								service);
		return true;
	}
	else if (g_strcmp0(str, "lowpan") == 0) {
		service->xpan_id = (uint64_t)g_key_file_get_uint64(keyfile, group, SERVICE_KEY_EXTENDED_PAN_ID, NULL);

		// allow join, psk index and role are ignored for now.
		// name, security and passphrase will be parsed later.
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_NAME, NULL);
	if (str) {
		g_free(service->name);
		service->name = str;
	}
	else
	{
		if (g_strcmp0(service->type, "lowpan") == 0) {
			connman_warn("Name is missing for lowpan provision");
			goto err;
		}
	}

	hex_ssid = __connman_config_get_string(keyfile, group, SERVICE_KEY_SSID,
					 NULL);
	if (hex_ssid) {
		char *ssid;
		unsigned int i, j = 0, hex;
		size_t hex_ssid_len = strlen(hex_ssid);

		ssid = g_try_malloc0(hex_ssid_len / 2);
		if (!ssid) {
			g_free(hex_ssid);
			goto err;
		}

		for (i = 0; i < hex_ssid_len; i += 2) {
			if (sscanf(hex_ssid + i, "%02x", &hex) <= 0) {
				connman_warn("Invalid SSID %s", hex_ssid);
				g_free(ssid);
				g_free(hex_ssid);
				goto err;
			}
			ssid[j++] = hex;
		}

		g_free(hex_ssid);

		g_free(service->ssid);
		service->ssid = ssid;
		service->ssid_len = hex_ssid_len / 2;
	} else if (service->name && g_strcmp0(service->type, "wifi") == 0) {
		char *ssid;
		unsigned int ssid_len;

		ssid_len = strlen(service->name);
		ssid = g_try_malloc0(ssid_len);
		if (!ssid)
			goto err;

		memcpy(ssid, service->name, ssid_len);
		g_free(service->ssid);
		service->ssid = ssid;
		service->ssid_len = ssid_len;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_EAP, NULL);
	if (str) {
		g_free(service->eap);
		service->eap = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_CA_CERT, NULL);
	if (str) {
		g_free(service->ca_cert_file);
		service->ca_cert_file = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_CL_CERT, NULL);
	if (str) {
		g_free(service->client_cert_file);
		service->client_cert_file = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PRV_KEY, NULL);
	if (str) {
		g_free(service->private_key_file);
		service->private_key_file = str;
	}

	str = __connman_config_get_string(keyfile, group,
						SERVICE_KEY_PRV_KEY_PASS, NULL);
	if (str) {
		g_free(service->private_key_passphrase);
		service->private_key_passphrase = str;
	}

	str = __connman_config_get_string(keyfile, group,
					SERVICE_KEY_PRV_KEY_PASS_TYPE, NULL);
	if (str) {
		g_free(service->private_key_passphrase_type);
		service->private_key_passphrase_type = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_IDENTITY, NULL);
	if (str) {
		g_free(service->identity);
		service->identity = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PHASE2, NULL);
	if (str) {
		g_free(service->phase2);
		service->phase2 = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PASSPHRASE,
					NULL);
	if (str) {
		g_free(service->passphrase);
		service->passphrase = str;
	}

	str = __connman_config_get_string(keyfile, group, SERVICE_KEY_SECURITY,
			NULL);
	security = __connman_service_string2security(str);

	if (service->eap) {

		if (str && security != CONNMAN_SERVICE_SECURITY_8021X)
			connman_info("Mismatch between EAP configuration and "
					"setting %s = %s",
					SERVICE_KEY_SECURITY, str);

		service->security = CONNMAN_SERVICE_SECURITY_8021X;

	} else if (service->passphrase) {

		if (str) {
			if (security == CONNMAN_SERVICE_SECURITY_PSK ||
					security == CONNMAN_SERVICE_SECURITY_WEP) {
				service->security = security;
			} else {
				connman_info("Mismatch with passphrase and "
						"setting %s = %s",
						SERVICE_KEY_SECURITY, str);

				service->security =
					CONNMAN_SERVICE_SECURITY_PSK;
			}

		} else
			service->security = CONNMAN_SERVICE_SECURITY_PSK;
	} else if (str) {

		if (security != CONNMAN_SERVICE_SECURITY_NONE)
			connman_info("Mismatch no security and "
					"setting %s = %s",
					SERVICE_KEY_SECURITY, str);

			service->security = CONNMAN_SERVICE_SECURITY_NONE;
	} else
			service->security = CONNMAN_SERVICE_SECURITY_NONE;

	service->config_ident = g_strdup(config->ident);
	service->config_entry = g_strdup_printf("service_%s", service->ident);

	if (g_strcmp0(service->type, "wifi") == 0)
		service->hidden = __connman_config_get_bool(keyfile, group,
								SERVICE_KEY_HIDDEN, NULL);

	if (service_created)
		g_hash_table_insert(config->service_table, service->ident,
					service);

	connman_info("Adding service configuration %s", service->ident);

	return true;

err:
	if (service_created) {
		g_free(service->ident);
		g_free(service->type);
		g_free(service->name);
		g_free(service->ssid);
		g_free(service);
	}

	return false;
}

static bool load_service_from_keyfile(GKeyFile *keyfile,
						struct connman_config *config)
{
	bool found = false;
	char **groups;
	int i;

	groups = g_key_file_get_groups(keyfile, NULL);

	for (i = 0; groups[i]; i++) {
		if (!g_str_has_prefix(groups[i], "service_"))
			continue;
		if (load_service(keyfile, groups[i], config))
			found = true;
	}

	g_strfreev(groups);

	return found;
}

static int load_config(struct connman_config *config)
{
	GKeyFile *keyfile;
	char *str;

	DBG("config %p", config);

	keyfile = __connman_storage_load_config(config->ident);
	if (!keyfile)
		return -EIO;

	g_key_file_set_list_separator(keyfile, ',');

	/* Verify keys validity of the global section */
	check_keys(keyfile, "global", config_possible_keys);

	str = __connman_config_get_string(keyfile, "global", CONFIG_KEY_NAME, NULL);
	if (str) {
		g_free(config->name);
		config->name = str;
	}

	str = __connman_config_get_string(keyfile, "global", CONFIG_KEY_DESC, NULL);
	if (str) {
		g_free(config->description);
		config->description = str;
	}

	if (!load_service_from_keyfile(keyfile, config))
		connman_warn("Config file %s/%s.config does not contain any "
			"configuration that can be provisioned!",
			STORAGEDIR, config->ident);

	g_key_file_free(keyfile);

	return 0;
}

static struct connman_config *create_config(const char *ident)
{
	struct connman_config *config;

	DBG("ident %s", ident);

	if (g_hash_table_lookup(config_table, ident))
		return NULL;

	config = g_try_new0(struct connman_config, 1);
	if (!config)
		return NULL;

	config->ident = g_strdup(ident);

	config->service_table = g_hash_table_new_full(g_str_hash, g_str_equal,
						NULL, unregister_service);

	g_hash_table_insert(config_table, config->ident, config);

	connman_info("Adding configuration %s", config->ident);

	return config;
}

static bool validate_ident(const char *ident)
{
	unsigned int i;

	if (!ident)
		return false;

	for (i = 0; i < strlen(ident); i++)
		if (!g_ascii_isprint(ident[i]))
			return false;

	return true;
}

static int read_configs(void)
{
	GDir *dir;

	DBG("");

	dir = g_dir_open(STORAGEDIR, 0, NULL);
	if (dir) {
		const gchar *file;

		while ((file = g_dir_read_name(dir))) {
			GString *str;
			gchar *ident;

			if (!g_str_has_suffix(file, ".config"))
				continue;

			ident = g_strrstr(file, ".config");
			if (!ident)
				continue;

			str = g_string_new_len(file, ident - file);
			if (!str)
				continue;

			ident = g_string_free(str, FALSE);

			if (validate_ident(ident)) {
				struct connman_config *config;

				config = create_config(ident);
				if (config)
					load_config(config);
			} else {
				connman_error("Invalid config ident %s", ident);
			}
			g_free(ident);
		}

		g_dir_close(dir);
	}

	return 0;
}

static void config_notify_handler(struct inotify_event *event,
                                        const char *ident)
{
	char *ext;

	if (!ident)
		return;

	if (!g_str_has_suffix(ident, ".config"))
		return;

	ext = g_strrstr(ident, ".config");
	if (!ext)
		return;

	*ext = '\0';

	if (!validate_ident(ident)) {
		connman_error("Invalid config ident %s", ident);
		return;
	}

	if (event->mask & (IN_CREATE | IN_MOVED_TO))
		create_config(ident);

	if (event->mask & (IN_MODIFY | IN_MOVED_TO)) {
		struct connman_config *config;

		config = g_hash_table_lookup(config_table, ident);
		if (config) {
			int ret;

			g_hash_table_remove_all(config->service_table);
			load_config(config);
			ret = __connman_service_provision_changed(ident);
			if (ret > 0) {
				/*
				 * Re-scan the config file for any
				 * changes
				 */
				g_hash_table_remove_all(config->service_table);
				load_config(config);
				__connman_service_provision_changed(ident);
			}
		}
	}

	if (event->mask & (IN_DELETE | IN_MOVED_FROM))
		g_hash_table_remove(config_table, ident);
}

int __connman_config_init(void)
{
	DBG("");

	config_table = g_hash_table_new_full(g_str_hash, g_str_equal,
						NULL, unregister_config);

	connman_inotify_register(STORAGEDIR, config_notify_handler);

	return read_configs();
}

void __connman_config_cleanup(void)
{
	DBG("");

	cleanup = true;

	connman_inotify_unregister(STORAGEDIR, config_notify_handler);

	g_hash_table_destroy(config_table);
	config_table = NULL;

	cleanup = false;
}

char *__connman_config_get_string(GKeyFile *key_file,
	const char *group_name, const char *key, GError **error)
{
	char *str = g_key_file_get_string(key_file, group_name, key, error);
	if (!str)
		return NULL;

	/*
	 * Passphrase can have space anywhere in the string
	 * read out of example.config. If passphrase in example.config
	 * has \s (space) as the last character, it will be truncated and
	 * in the resulting service directory we will have wrong passphrase
	 * resulting in 4 way hand shake failure.
	 */
	if (g_strcmp0(key, SERVICE_KEY_PASSPHRASE) == 0)
	{
		return str;
	}

	return g_strchomp(str);
}

char **__connman_config_get_string_list(GKeyFile *key_file,
	const char *group_name, const char *key, gsize *length, GError **error)
{
	char **p;
	char **strlist = g_key_file_get_string_list(key_file, group_name, key,
		length, error);
	if (!strlist)
		return NULL;

	p = strlist;
	while (*p) {
		*p = g_strstrip(*p);
		p++;
	}

	return strlist;
}

bool __connman_config_get_bool(GKeyFile *key_file,
	const char *group_name, const char *key, GError **error)
{
	char *valstr;
	bool val = false;

	valstr = g_key_file_get_value(key_file, group_name, key, error);
	if (!valstr)
		return false;

	valstr = g_strchomp(valstr);
	if (strcmp(valstr, "true") == 0 || strcmp(valstr, "1") == 0)
		val = true;

	g_free(valstr);

	return val;
}

static char *config_pem_fsid(const char *pem_file)
{
	struct statfs buf;
	unsigned *fsid = (unsigned *) &buf.f_fsid;
	unsigned long long fsid64;

	if (!pem_file)
		return NULL;

	if (statfs(pem_file, &buf) < 0) {
		connman_error("statfs error %s for %s",
						strerror(errno), pem_file);
		return NULL;
	}

	fsid64 = ((unsigned long long) fsid[0] << 32) | fsid[1];

	return g_strdup_printf("%llx", fsid64);
}

static void provision_service_wifi(struct connman_config_service *config,
				struct connman_service *service,
				struct connman_network *network,
				const void *ssid, unsigned int ssid_len)
{
	if (config->eap)
		__connman_service_set_string(service, "EAP", config->eap);

	if (config->identity)
		__connman_service_set_string(service, "Identity",
							config->identity);

	if (config->ca_cert_file)
		__connman_service_set_string(service, "CACertFile",
							config->ca_cert_file);

	if (config->client_cert_file)
		__connman_service_set_string(service, "ClientCertFile",
						config->client_cert_file);

	if (config->private_key_file)
		__connman_service_set_string(service, "PrivateKeyFile",
						config->private_key_file);

	if (g_strcmp0(config->private_key_passphrase_type, "fsid") == 0 &&
					config->private_key_file) {
		char *fsid;

		fsid = config_pem_fsid(config->private_key_file);
		if (!fsid)
			return;

		g_free(config->private_key_passphrase);
		config->private_key_passphrase = fsid;
	}

	if (config->private_key_passphrase) {
		__connman_service_set_string(service, "PrivateKeyPassphrase",
						config->private_key_passphrase);
		/*
		 * TODO: Support for PEAP with both identity and key passwd.
		 * In that case, we should check if both of them are found
		 * from the config file. If not, we should not set the
		 * service passphrase in order for the UI to request for an
		 * additional passphrase.
		 */
	}

	if (config->phase2)
		__connman_service_set_string(service, "Phase2", config->phase2);

	if (config->passphrase)
		__connman_service_set_string(service, "Passphrase",
						config->passphrase);

	if (config->hidden)
		__connman_service_set_hidden(service);
}

static void provision_service_lowpan(struct connman_config_service *config,
				struct connman_service *service,
				struct connman_network *network)
{
	if (config->passphrase) {
		DBG("provision_service_lowpan, load passphrase");
		__connman_service_set_string(service, "Passphrase", config->passphrase);
	}
}

struct connect_virtual {
	struct connman_service *service;
	const char *vfile;
};

static gboolean remove_virtual_config(gpointer user_data)
{
	struct connect_virtual *virtual = user_data;

	__connman_service_connect(virtual->service,
				CONNMAN_SERVICE_CONNECT_REASON_AUTO);
	g_hash_table_remove(config_table, virtual->vfile);

	g_free(virtual);

	return FALSE;
}

static int try_provision_service(struct connman_config_service *config,
				struct connman_service *service)
{
	struct connman_network *network;
	const void *service_id;
	enum connman_service_type type;
	const void *ssid;
	unsigned int ssid_len;
	const char *str;
	uint64_t xpan_id;

	network = __connman_service_get_network(service);
	if (!network) {
		connman_error("Service has no network set");
		return -EINVAL;
	}

	DBG("network %p ident %s", network,
				connman_network_get_identifier(network));

	type = connman_service_get_type(service);

	switch(type) {
	case CONNMAN_SERVICE_TYPE_WIFI:
		if (__connman_service_string2type(config->type) != type)
			return -ENOENT;

		ssid = connman_network_get_blob(network, "WiFi.SSID",
						&ssid_len);
		if (!ssid) {
			connman_error("Network SSID not set");
			return -EINVAL;
		}

		if (!config->ssid || ssid_len != config->ssid_len)
			return -ENOENT;

		if (memcmp(config->ssid, ssid, ssid_len))
			return -ENOENT;

		str = connman_network_get_string(network, "WiFi.Security");
		if (config->security != __connman_service_string2security(str))
			return -ENOENT;

		break;

	case CONNMAN_SERVICE_TYPE_ETHERNET:
	case CONNMAN_SERVICE_TYPE_GADGET:

		if (__connman_service_string2type(config->type) != type)
			return -ENOENT;
		break;

	case CONNMAN_SERVICE_TYPE_LOWPAN:
		if (__connman_service_string2type(config->type) != type)
			return -ENOENT;

		str = connman_network_get_string(network, "Name");
		if (!str || memcmp(str, config->name, strlen(config->name)))
			return -ENOENT;

		xpan_id = connman_network_get_lowpan_xpan_id(network);
		if (xpan_id != config->xpan_id)
			return -ENOENT;

		str = connman_network_get_string(network, "WiFi.Security");
		if (config->security != CONNMAN_SERVICE_SECURITY_NONE
			&& config->security != __connman_service_string2security(str))
			return -ENOENT;

		break;

	case CONNMAN_SERVICE_TYPE_UNKNOWN:
	case CONNMAN_SERVICE_TYPE_SYSTEM:
	case CONNMAN_SERVICE_TYPE_BLUETOOTH:
	case CONNMAN_SERVICE_TYPE_CELLULAR:
	case CONNMAN_SERVICE_TYPE_GPS:
	case CONNMAN_SERVICE_TYPE_VPN:
	case CONNMAN_SERVICE_TYPE_P2P:

		return -ENOENT;
	}

	DBG("service %p ident %s", service,
					__connman_service_get_ident(service));

	if (config->mac) {
		struct connman_device *device;
		const char *device_addr;

		device = connman_network_get_device(network);
		if (!device) {
			connman_error("Network device is missing");
			return -ENODEV;
		}

		device_addr = connman_device_get_string(device, "Address");

		DBG("wants %s has %s", config->mac, device_addr);

		if (g_ascii_strcasecmp(device_addr, config->mac) != 0)
			return -ENOENT;
	}

	if (!config->ipv6_address) {
		connman_network_set_ipv6_method(network,
						CONNMAN_IPCONFIG_METHOD_AUTO);
	} else if (g_ascii_strcasecmp(config->ipv6_address, "off") == 0) {
		connman_network_set_ipv6_method(network,
						CONNMAN_IPCONFIG_METHOD_OFF);
	} else if (g_ascii_strcasecmp(config->ipv6_address, "auto") == 0 ||
			g_ascii_strcasecmp(config->ipv6_address, "dhcp") == 0) {
		connman_network_set_ipv6_method(network,
						CONNMAN_IPCONFIG_METHOD_AUTO);
	} else {
		struct connman_ipaddress *address;

		if (config->ipv6_prefix_length == 0) {
			DBG("IPv6 prefix missing");
			return -EINVAL;
		}

		address = connman_ipaddress_alloc(AF_INET6);
		if (!address)
			return -ENOENT;

		connman_ipaddress_set_ipv6(address, config->ipv6_address,
					config->ipv6_prefix_length,
					config->ipv6_gateway);

		connman_network_set_ipv6_method(network,
						CONNMAN_IPCONFIG_METHOD_FIXED);

		if (connman_network_set_ipaddress(network, address) < 0)
			DBG("Unable to set IPv6 address to network %p",
								network);

		connman_ipaddress_free(address);
	}

	if (config->ipv6_privacy) {
		struct connman_ipconfig *ipconfig;

		ipconfig = __connman_service_get_ip6config(service);
		if (ipconfig)
			__connman_ipconfig_ipv6_set_privacy(ipconfig,
							config->ipv6_privacy);
	}

	if (!config->ipv4_address) {
		connman_network_set_ipv4_method(network,
						CONNMAN_IPCONFIG_METHOD_DHCP);
	} else if (g_ascii_strcasecmp(config->ipv4_address, "off") == 0) {
		connman_network_set_ipv4_method(network,
						CONNMAN_IPCONFIG_METHOD_OFF);
	} else if (g_ascii_strcasecmp(config->ipv4_address, "auto") == 0 ||
			g_ascii_strcasecmp(config->ipv4_address, "dhcp") == 0) {
		connman_network_set_ipv4_method(network,
						CONNMAN_IPCONFIG_METHOD_DHCP);
	} else {
		struct connman_ipaddress *address;

		if (!config->ipv4_netmask) {
			DBG("IPv4 netmask missing");
			return -EINVAL;
		}

		address = connman_ipaddress_alloc(AF_INET);
		if (!address)
			return -ENOENT;

		connman_ipaddress_set_ipv4(address, config->ipv4_address,
					config->ipv4_netmask,
					config->ipv4_gateway);

		connman_network_set_ipv4_method(network,
						CONNMAN_IPCONFIG_METHOD_FIXED);

		if (connman_network_set_ipaddress(network, address) < 0)
			DBG("Unable to set IPv4 address to network %p",
								network);

		connman_ipaddress_free(address);
	}

	__connman_service_disconnect(service);

	service_id = __connman_service_get_ident(service);
	config->service_identifiers =
		g_slist_prepend(config->service_identifiers,
				g_strdup(service_id));

	__connman_service_set_favorite_delayed(service, true, true);

	__connman_service_set_config(service, config->config_ident,
						config->config_entry);

	if (config->domain_name)
		__connman_service_set_domainname(service, config->domain_name);

	if (config->nameservers) {
		int i;

		__connman_service_nameserver_clear(service);

		for (i = 0; config->nameservers[i]; i++) {
			__connman_service_nameserver_append(service,
						config->nameservers[i], false);
		}
	}

	if (config->search_domains)
		__connman_service_set_search_domains(service,
						config->search_domains);

	if (config->timeservers)
		__connman_service_set_timeservers(service,
						config->timeservers);

	if (type == CONNMAN_SERVICE_TYPE_WIFI) {
		provision_service_wifi(config, service, network,
							ssid, ssid_len);
	}
	else if (type == CONNMAN_SERVICE_TYPE_LOWPAN) {
		provision_service_lowpan(config, service, network);
	}

	__connman_service_mark_dirty();

	__connman_service_load_modifiable(service);

	if (config->virtual) {
		struct connect_virtual *virtual;

		virtual = g_malloc0(sizeof(struct connect_virtual));
		virtual->service = service;
		virtual->vfile = config->virtual_file;

		g_timeout_add(0, remove_virtual_config, virtual);

		return 0;
	}

	__connman_service_set_immutable(service, true);

	if (type == CONNMAN_SERVICE_TYPE_ETHERNET ||
			type == CONNMAN_SERVICE_TYPE_GADGET) {
		__connman_service_connect(service,
				CONNMAN_SERVICE_CONNECT_REASON_AUTO);

		return 0;
	}

	__connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);

	return 0;
}

static int find_and_provision_service(struct connman_service *service)
{
	GHashTableIter iter, iter_service;
	gpointer value, key, value_service, key_service;

	g_hash_table_iter_init(&iter, config_table);

	while (g_hash_table_iter_next(&iter, &key, &value)) {
		struct connman_config *config = value;

		g_hash_table_iter_init(&iter_service, config->service_table);
		while (g_hash_table_iter_next(&iter_service, &key_service,
						&value_service)) {
			if (!try_provision_service(value_service, service))
				return 0;
		}
	}

	return -ENOENT;
}

int __connman_config_provision_service(struct connman_service *service)
{
	enum connman_service_type type;

	/* For now only WiFi, Gadget and Ethernet services are supported */
	type = connman_service_get_type(service);

	DBG("service %p type %d", service, type);

	if (type != CONNMAN_SERVICE_TYPE_WIFI &&
			type != CONNMAN_SERVICE_TYPE_LOWPAN &&
			type != CONNMAN_SERVICE_TYPE_ETHERNET &&
			type != CONNMAN_SERVICE_TYPE_GADGET)
		return -ENOSYS;

	return find_and_provision_service(service);
}

int __connman_config_provision_service_ident(struct connman_service *service,
			const char *ident, const char *file, const char *entry)
{
	enum connman_service_type type;
	struct connman_config *config;
	int ret = 0;

	/* For now only WiFi, Gadget and Ethernet services are supported */
	type = connman_service_get_type(service);

	DBG("service %p type %d", service, type);

	if (type != CONNMAN_SERVICE_TYPE_WIFI &&
			type != CONNMAN_SERVICE_TYPE_ETHERNET &&
			type != CONNMAN_SERVICE_TYPE_GADGET &&
			type != CONNMAN_SERVICE_TYPE_LOWPAN)
		return -ENOSYS;

	config = g_hash_table_lookup(config_table, ident);
	if (config) {
		GHashTableIter iter;
		gpointer value, key;
		bool found = false;

		g_hash_table_iter_init(&iter, config->service_table);

		/*
		 * Check if we need to remove individual service if it
		 * is missing from config file.
		 */
		if (file && entry) {
			while (g_hash_table_iter_next(&iter, &key,
							&value)) {
				struct connman_config_service *config_service;

				config_service = value;

				if (g_strcmp0(config_service->config_ident,
								file) != 0)
					continue;

				if (g_strcmp0(config_service->config_entry,
								entry) != 0)
					continue;

				found = true;
				break;
			}

			DBG("found %d ident %s file %s entry %s", found, ident,
								file, entry);

			if (!found) {
				/*
				 * The entry+8 will skip "service_" prefix
				 */
				g_hash_table_remove(config->service_table,
						entry + 8);
				ret = 1;
			}
		}

		find_and_provision_service(service);
	}

	return ret;
}

static void generate_random_string(char *str, int length)
{
	uint8_t val;
	int i;
	uint64_t rand;

	memset(str, '\0', length);

	for (i = 0; i < length-1; i++) {
		do {
			__connman_util_get_random(&rand);
			val = (uint8_t)(rand % 122);
			if (val < 48)
				val += 48;
		} while((val > 57 && val < 65) || (val > 90 && val < 97));

		str[i] = val;
	}
}

int connman_config_provision_mutable_service(GKeyFile *keyfile)
{
	struct connman_config_service *service_config;
	struct connman_config *config;
	char *vfile, *group;
	char rstr[11];

	DBG("");

	generate_random_string(rstr, 11);

	vfile = g_strdup_printf("service_mutable_%s.config", rstr);

	config = create_config(vfile);
	if (!config)
		return -ENOMEM;

	if (!load_service_from_keyfile(keyfile, config))
		goto error;

	group = g_key_file_get_start_group(keyfile);

	service_config = g_hash_table_lookup(config->service_table, group+8);
	if (!service_config)
		goto error;

	/* Specific to non file based config: */
	g_free(service_config->config_ident);
	service_config->config_ident = NULL;
	g_free(service_config->config_entry);
	service_config->config_entry = NULL;

	service_config->virtual = true;
	service_config->virtual_file = vfile;

	__connman_service_provision_changed(vfile);

	if (g_strcmp0(service_config->type, "wifi") == 0)
		__connman_device_request_scan(CONNMAN_SERVICE_TYPE_WIFI);

	return 0;

error:
	DBG("Could not proceed");
	g_hash_table_remove(config_table, vfile);
	g_free(vfile);

	return -EINVAL;
}

struct connman_config_entry **connman_config_get_entries(const char *type)
{
	GHashTableIter iter_file, iter_config;
	gpointer value, key;
	struct connman_config_entry **entries = NULL;
	int i = 0, count;

	g_hash_table_iter_init(&iter_file, config_table);
	while (g_hash_table_iter_next(&iter_file, &key, &value)) {
		struct connman_config *config_file = value;

		count = g_hash_table_size(config_file->service_table);

		entries = g_try_realloc(entries, (i + count + 1) *
					sizeof(struct connman_config_entry *));
		if (!entries)
			return NULL;

		g_hash_table_iter_init(&iter_config,
						config_file->service_table);
		while (g_hash_table_iter_next(&iter_config, &key,
							&value)) {
			struct connman_config_service *config = value;

			if (type &&
					g_strcmp0(config->type, type) != 0)
				continue;

			entries[i] = g_try_new0(struct connman_config_entry,
						1);
			if (!entries[i])
				goto cleanup;

			entries[i]->ident = g_strdup(config->ident);
			entries[i]->name = g_strdup(config->name);
			entries[i]->ssid = g_try_malloc0(config->ssid_len + 1);
			if (!entries[i]->ssid)
				goto cleanup;

			memcpy(entries[i]->ssid, config->ssid,
							config->ssid_len);
			entries[i]->ssid_len = config->ssid_len;
			entries[i]->hidden = config->hidden;

			i++;
		}
	}

	if (entries) {
		entries = g_try_realloc(entries, (i + 1) *
					sizeof(struct connman_config_entry *));
		if (!entries)
			return NULL;

		entries[i] = NULL;

		DBG("%d provisioned AP found", i);
	}

	return entries;

cleanup:
	connman_config_free_entries(entries);
	return NULL;
}

void connman_config_free_entries(struct connman_config_entry **entries)
{
	int i;

	if (!entries)
		return;

	for (i = 0; entries[i]; i++) {
		g_free(entries[i]->ident);
		g_free(entries[i]->name);
		g_free(entries[i]->ssid);
		g_free(entries[i]);
	}

	g_free(entries);
	return;
}

bool __connman_config_address_provisioned(const char *address,
					const char *netmask)
{
	GHashTableIter iter, siter;
	gpointer value, key, svalue, skey;

	if (!address || !netmask)
		return false;

	g_hash_table_iter_init(&iter, config_table);

	while (g_hash_table_iter_next(&iter, &key, &value)) {
		struct connman_config *config = value;

		g_hash_table_iter_init(&siter, config->service_table);
		while (g_hash_table_iter_next(&siter, &skey, &svalue)) {
			struct connman_config_service *service = svalue;

			if (!g_strcmp0(address, service->ipv4_address) &&
					!g_strcmp0(netmask,
						service->ipv4_netmask))
				return true;
		}
	}

	return false;
}
