summaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2009-12-23 23:16:41 +0100
committerMarcel Holtmann <marcel@holtmann.org>2009-12-23 14:30:57 -0800
commit5d5dd0f33a2f4f1fb282b14d93f9f51eebd82cf2 (patch)
tree1a96fed55b756ad2d224866e40f291b55265c798 /src/config.c
parent13175359d3d87d9510cb3f46481e9bfd49beb49d (diff)
downloadconnman-5d5dd0f33a2f4f1fb282b14d93f9f51eebd82cf2.tar.gz
connman-5d5dd0f33a2f4f1fb282b14d93f9f51eebd82cf2.tar.bz2
connman-5d5dd0f33a2f4f1fb282b14d93f9f51eebd82cf2.zip
Load service entries from configuration files
For IEEE 802.1x networks, the various certificate paths, private key paths and identities are configured through an external configuration file. They belong to a "service" group in this file and loaded at startup. Any matching service with the corresponding service group will be provisioned with this configuration. These settings will also be then propagated to the network structure at connection time.
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c199
1 files changed, 198 insertions, 1 deletions
diff --git a/src/config.c b/src/config.c
index cf8e42aa..d5cfd9eb 100644
--- a/src/config.c
+++ b/src/config.c
@@ -23,22 +23,141 @@
#include <config.h>
#endif
+#include <stdio.h>
+#include <string.h>
#include <glib.h>
#include "connman.h"
+struct connman_config_service {
+ 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 *phase2;
+};
+
struct connman_config {
char *ident;
char *name;
char *description;
+ struct connman_config_service *service;
};
static GHashTable *config_hash = NULL;
+static int load_service(GKeyFile *keyfile, struct connman_config *config)
+{
+ char *str, *hex_ssid;
+ struct connman_config_service *service;
+
+ service = g_try_new0(struct connman_config_service, 1);
+ if (service == NULL)
+ return -ENOMEM;
+
+ config->service = service;
+
+ str = g_key_file_get_string(keyfile, "service", "Type", NULL);
+ if (str != NULL) {
+ g_free(service->ssid);
+ service->type = str;
+ }
+
+ hex_ssid = g_key_file_get_string(keyfile, "service", "Type", NULL);
+ if (hex_ssid != NULL) {
+ 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 == NULL) {
+ g_free(hex_ssid);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < hex_ssid_len; i += 2) {
+ sscanf(hex_ssid + i, "%02x", &hex);
+ ssid[j++] = hex;
+ }
+
+ g_free(hex_ssid);
+
+ g_free(service->type);
+ service->ssid = ssid;
+ service->ssid_len = hex_ssid_len / 2;
+ }
+
+ str = g_key_file_get_string(keyfile, "service", "EAP", NULL);
+ if (str != NULL) {
+ g_free(service->eap);
+ service->eap = str;
+ }
+
+ str = g_key_file_get_string(keyfile, "service", "CACertFile", NULL);
+ if (str != NULL) {
+ g_free(service->ca_cert_file);
+ service->ca_cert_file = str;
+ }
+
+ str = g_key_file_get_string(keyfile, "service", "ClientCertFile", NULL);
+ if (str != NULL) {
+ g_free(service->client_cert_file);
+ service->client_cert_file = str;
+ }
+
+ str = g_key_file_get_string(keyfile, "service", "PrivateKeyFile", NULL);
+ if (str != NULL) {
+ g_free(service->private_key_file);
+ service->private_key_file = str;
+ }
+
+ str = g_key_file_get_string(keyfile, "service", "PrivateKeyPassphrase",
+ NULL);
+ if (str != NULL) {
+ g_free(service->private_key_passphrase);
+ service->private_key_passphrase = str;
+ }
+
+ str = g_key_file_get_string(keyfile, "service", "Identity", NULL);
+ if (str != NULL) {
+ g_free(service->identity);
+ service->identity = str;
+ }
+
+ str = g_key_file_get_string(keyfile, "service", "Phase2", NULL);
+ if (str != NULL) {
+ g_free(service->phase2);
+ service->phase2 = str;
+ }
+
+
+ return 0;
+}
+
+static void free_service(struct connman_config_service *service)
+{
+ g_free(service->type);
+ g_free(service->ssid);
+ g_free(service->eap);
+ g_free(service->identity);
+ g_free(service->ca_cert_file);
+ g_free(service->client_cert_file);
+ g_free(service->private_key_file);
+ g_free(service->private_key_passphrase);
+ g_free(service->phase2);
+ g_free(service);
+}
+
static int load_config(struct connman_config *config)
{
GKeyFile *keyfile;
char *str;
+ int err;
DBG("config %p", config);
@@ -58,9 +177,18 @@ static int load_config(struct connman_config *config)
config->description = str;
}
+ if (g_key_file_has_group(keyfile, "service") == TRUE) {
+ err = load_service(keyfile, config);
+ if (err < 0)
+ goto done;
+ }
+
+ err = 0;
+
+done:
__connman_storage_close_config(config->ident, keyfile, FALSE);
- return 0;
+ return err;
}
static void free_config(struct connman_config *config)
@@ -68,6 +196,7 @@ static void free_config(struct connman_config *config)
g_free(config->description);
g_free(config->name);
g_free(config->ident);
+ free_service(config->service);
g_free(config);
}
@@ -149,6 +278,39 @@ static int config_init(void)
return 0;
}
+static void config_service_setup(struct connman_service *service,
+ struct connman_config_service *config)
+{
+ if (config == NULL)
+ return;
+
+ 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 (config->private_key_passphrase)
+ __connman_service_set_string(service, "PrivateKeyPassphrase",
+ config->private_key_passphrase);
+
+ if (config->phase2)
+ __connman_service_set_string(service, "Phase2", config->phase2);
+}
+
int __connman_config_init(void)
{
DBG("");
@@ -169,7 +331,42 @@ void __connman_config_cleanup(void)
int __connman_config_provision_service(struct connman_service *service)
{
+ GHashTableIter iter;
+ gpointer value, key;
+ struct connman_network *network;
+ struct connman_config *config = NULL;
+ const void *ssid;
+ unsigned int ssid_len;
+
DBG("service %p", service);
+ network = __connman_service_get_network(service);
+ if (network == NULL) {
+ connman_error("Network not set");
+ return -EINVAL;
+ }
+
+ ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len);
+ if (ssid == NULL) {
+ connman_error("Network SSID not set");
+ return -EINVAL;
+ }
+
+ g_hash_table_iter_init(&iter, config_hash);
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ config = value;
+
+ /* For now we only support wifi services entries */
+ if (config->service &&
+ g_strcmp0(config->service->type, "wifi") == 0 &&
+ ssid_len == config->service->ssid_len)
+ if (config->service->ssid &&
+ memcmp(config->service->ssid, ssid,
+ ssid_len) == 0)
+ break;
+ }
+
+ config_service_setup(service, config->service);
+
return 0;
}