/*
 *
 *  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;
	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"

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,
	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;
	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);

			/*
			 * 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;
	}

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

	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) {
		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);

	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 || event->mask & IN_MOVED_TO)
		create_config(ident);

	if (event->mask & IN_MODIFY) {
		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)
		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;

	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);
}

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;

	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_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);
	}

	__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_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)
		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;
}
