summaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c148
1 files changed, 130 insertions, 18 deletions
diff --git a/src/config.c b/src/config.c
index a4c117e1..a8c3da89 100644
--- a/src/config.c
+++ b/src/config.c
@@ -45,7 +45,12 @@ struct connman_config_service {
unsigned int ssid_len;
char *eap;
char *identity;
+ char *anonymous_identity;
char *ca_cert_file;
+ char *subject_match;
+ char *altsubject_match;
+ char *domain_suffix_match;
+ char *domain_match;
char *client_cert_file;
char *private_key_file;
char *private_key_passphrase;
@@ -98,6 +103,11 @@ static bool cleanup = false;
#define SERVICE_KEY_PRV_KEY_PASS "PrivateKeyPassphrase"
#define SERVICE_KEY_PRV_KEY_PASS_TYPE "PrivateKeyPassphraseType"
#define SERVICE_KEY_IDENTITY "Identity"
+#define SERVICE_KEY_ANONYMOUS_IDENTITY "AnonymousIdentity"
+#define SERVICE_KEY_SUBJECT_MATCH "SubjectMatch"
+#define SERVICE_KEY_ALT_SUBJECT_MATCH "AltSubjectMatch"
+#define SERVICE_KEY_DOMAIN_SUFF_MATCH "DomainSuffixMatch"
+#define SERVICE_KEY_DOMAIN_MATCH "DomainMatch"
#define SERVICE_KEY_PHASE2 "Phase2"
#define SERVICE_KEY_PASSPHRASE "Passphrase"
#define SERVICE_KEY_SECURITY "Security"
@@ -129,6 +139,11 @@ static const char *service_possible_keys[] = {
SERVICE_KEY_PRV_KEY_PASS,
SERVICE_KEY_PRV_KEY_PASS_TYPE,
SERVICE_KEY_IDENTITY,
+ SERVICE_KEY_ANONYMOUS_IDENTITY,
+ SERVICE_KEY_SUBJECT_MATCH,
+ SERVICE_KEY_ALT_SUBJECT_MATCH,
+ SERVICE_KEY_DOMAIN_SUFF_MATCH,
+ SERVICE_KEY_DOMAIN_MATCH,
SERVICE_KEY_PHASE2,
SERVICE_KEY_PASSPHRASE,
SERVICE_KEY_SECURITY,
@@ -220,7 +235,12 @@ free_only:
g_free(config_service->ssid);
g_free(config_service->eap);
g_free(config_service->identity);
+ g_free(config_service->anonymous_identity);
g_free(config_service->ca_cert_file);
+ g_free(config_service->subject_match);
+ g_free(config_service->altsubject_match);
+ g_free(config_service->domain_suffix_match);
+ g_free(config_service->domain_match);
g_free(config_service->client_cert_file);
g_free(config_service->private_key_file);
g_free(config_service->private_key_passphrase);
@@ -655,6 +675,41 @@ static bool load_service(GKeyFile *keyfile, const char *group,
service->identity = str;
}
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_ANONYMOUS_IDENTITY, NULL);
+ if (str) {
+ g_free(service->anonymous_identity);
+ service->anonymous_identity = str;
+ }
+
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_SUBJECT_MATCH, NULL);
+ if (str) {
+ g_free(service->subject_match);
+ service->subject_match = str;
+ }
+
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_ALT_SUBJECT_MATCH, NULL);
+ if (str) {
+ g_free(service->altsubject_match);
+ service->altsubject_match = str;
+ }
+
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_DOMAIN_SUFF_MATCH, NULL);
+ if (str) {
+ g_free(service->domain_suffix_match);
+ service->domain_suffix_match = str;
+ }
+
+ str = __connman_config_get_string(keyfile, group,
+ SERVICE_KEY_DOMAIN_MATCH, NULL);
+ if (str) {
+ g_free(service->domain_match);
+ service->domain_match = str;
+ }
+
str = __connman_config_get_string(keyfile, group, SERVICE_KEY_PHASE2, NULL);
if (str) {
g_free(service->phase2);
@@ -698,7 +753,18 @@ static bool load_service(GKeyFile *keyfile, const char *group,
} 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;
+
+ g_free(str);
service->config_ident = g_strdup(config->ident);
service->config_entry = g_strdup_printf("service_%s", service->ident);
@@ -891,10 +957,10 @@ static void config_notify_handler(struct inotify_event *event,
return;
}
- if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO)
+ if (event->mask & (IN_CREATE | IN_MOVED_TO))
create_config(ident);
- if (event->mask & IN_MODIFY) {
+ if (event->mask & (IN_MODIFY | IN_MOVED_TO)) {
struct connman_config *config;
config = g_hash_table_lookup(config_table, ident);
@@ -916,7 +982,7 @@ static void config_notify_handler(struct inotify_event *event,
}
}
- if (event->mask & IN_DELETE)
+ if (event->mask & (IN_DELETE | IN_MOVED_FROM))
g_hash_table_remove(config_table, ident);
}
@@ -953,6 +1019,11 @@ char *__connman_config_get_string(GKeyFile *key_file,
if (!str)
return NULL;
+ /* passphrases can have spaces in the end */
+ if (!g_strcmp0(key, SERVICE_KEY_PASSPHRASE) ||
+ !g_strcmp0(key, SERVICE_KEY_PRV_KEY_PASS))
+ return str;
+
return g_strchomp(str);
}
@@ -1025,10 +1096,30 @@ static void provision_service_wifi(struct connman_config_service *config,
__connman_service_set_string(service, "Identity",
config->identity);
+ if (config->anonymous_identity)
+ __connman_service_set_string(service, "AnonymousIdentity",
+ config->anonymous_identity);
+
if (config->ca_cert_file)
__connman_service_set_string(service, "CACertFile",
config->ca_cert_file);
+ if (config->subject_match)
+ __connman_service_set_string(service, "SubjectMatch",
+ config->subject_match);
+
+ if (config->altsubject_match)
+ __connman_service_set_string(service, "AltSubjectMatch",
+ config->altsubject_match);
+
+ if (config->domain_suffix_match)
+ __connman_service_set_string(service, "DomainSuffixMatch",
+ config->domain_suffix_match);
+
+ if (config->domain_match)
+ __connman_service_set_string(service, "DomainMatch",
+ config->domain_match);
+
if (config->client_cert_file)
__connman_service_set_string(service, "ClientCertFile",
config->client_cert_file);
@@ -1306,7 +1397,7 @@ static int try_provision_service(struct connman_config_service *config,
virtual->service = service;
virtual->vfile = config->virtual_file;
- g_timeout_add(0, remove_virtual_config, virtual);
+ g_idle_add(remove_virtual_config, virtual);
return 0;
}
@@ -1326,22 +1417,35 @@ static int try_provision_service(struct connman_config_service *config,
return 0;
}
+static int
+find_and_provision_service_from_config(struct connman_service *service,
+ struct connman_config *config)
+{
+ GHashTableIter iter;
+ gpointer value, key;
+
+ g_hash_table_iter_init(&iter, config->service_table);
+ while (g_hash_table_iter_next(&iter, &key,
+ &value)) {
+ if (!try_provision_service(value, service))
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
static int find_and_provision_service(struct connman_service *service)
{
- GHashTableIter iter, iter_service;
- gpointer value, key, value_service, key_service;
+ GHashTableIter iter;
+ gpointer value, key;
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;
- }
+ if (!find_and_provision_service_from_config(service, config))
+ return 0;
}
return -ENOENT;
@@ -1425,7 +1529,7 @@ int __connman_config_provision_service_ident(struct connman_service *service,
}
}
- find_and_provision_service(service);
+ find_and_provision_service_from_config(service, config);
}
return ret;
@@ -1455,7 +1559,7 @@ int connman_config_provision_mutable_service(GKeyFile *keyfile)
{
struct connman_config_service *service_config;
struct connman_config *config;
- char *vfile, *group;
+ char *vfile, *group = NULL;
char rstr[11];
DBG("");
@@ -1491,13 +1595,14 @@ int connman_config_provision_mutable_service(GKeyFile *keyfile)
if (g_strcmp0(service_config->type, "wifi") == 0)
__connman_device_request_scan(CONNMAN_SERVICE_TYPE_WIFI);
+ g_free(group);
return 0;
error:
DBG("Could not proceed");
g_hash_table_remove(config_table, vfile);
g_free(vfile);
-
+ g_free(group);
return -EINVAL;
}
@@ -1511,13 +1616,16 @@ struct connman_config_entry **connman_config_get_entries(const char *type)
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;
+ struct connman_config_entry **tmp_entries = entries;
count = g_hash_table_size(config_file->service_table);
entries = g_try_realloc(entries, (i + count + 1) *
sizeof(struct connman_config_entry *));
- if (!entries)
+ if (!entries) {
+ g_free(tmp_entries);
return NULL;
+ }
g_hash_table_iter_init(&iter_config,
config_file->service_table);
@@ -1550,10 +1658,14 @@ struct connman_config_entry **connman_config_get_entries(const char *type)
}
if (entries) {
+ struct connman_config_entry **tmp_entries = entries;
+
entries = g_try_realloc(entries, (i + 1) *
sizeof(struct connman_config_entry *));
- if (!entries)
+ if (!entries) {
+ g_free(tmp_entries);
return NULL;
+ }
entries[i] = NULL;