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

#define MONITOR_CONFIG_DIR

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) {
			enum connman_service_type service_type = connman_service_get_type(service);

			/* Do not remove 6lowpan & wifi services
			 */
			if ((service_type == CONNMAN_SERVICE_TYPE_LOWPAN) ||
				(service_type == CONNMAN_SERVICE_TYPE_WIFI)) {
				continue;
			}

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

#ifdef MONITOR_CONFIG_DIR
	connman_inotify_register(STORAGEDIR, config_notify_handler);
#endif

	return read_configs();
}

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

	cleanup = true;

#ifdef MONITOR_CONFIG_DIR
	connman_inotify_unregister(STORAGEDIR, config_notify_handler);
#endif

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

	connman_info("try_provision_service(): 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);
	}


	if (type != CONNMAN_SERVICE_TYPE_WIFI && 
		type != CONNMAN_SERVICE_TYPE_LOWPAN)
		__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;
	}

	if (type != CONNMAN_SERVICE_TYPE_WIFI)
		__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;
	}

	if (type != CONNMAN_SERVICE_TYPE_WIFI)
		__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;
}
