diff options
Diffstat (limited to 'src/config.c')
-rw-r--r-- | src/config.c | 148 |
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; |