From 4eaf93d26ace4aa871387a2309d411d7b1726232 Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Thu, 12 Sep 2019 09:53:36 -0700 Subject: [PATCH] knownnetworks: rework known frequencies The current format for the .known_networks.freq file had a hidden limitation of not being able to handle SSID's with some special characters. Since the provisioning file path was used as the group name the filename was limited to only characters supported by l_settings groups, which conflicted with allowable SSID characters. Instead we can generate a unique UUID for each network and use this as the group. For this particular case the group does not really matter, so long as its unique. But we can utilize this unique UUID for other purposes, including using it as a seed for changing the MAC address per-connection in the future. The .known_networks.freq file will now have the following format: [] name=/path/to/provisioning/file list= XXXX YYYY ZZZZ --- src/knownnetworks.c | 98 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 22 deletions(-) diff --git a/src/knownnetworks.c b/src/knownnetworks.c index f5c08449..d9768721 100644 --- a/src/knownnetworks.c +++ b/src/knownnetworks.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include @@ -735,9 +737,53 @@ static char *known_frequencies_to_string(struct l_queue *known_frequencies) return l_string_unwrap(str); } +struct hotspot_search { + struct network_info *info; + const char *path; +}; + +static bool match_hotspot_path(const struct network_info *info, void *user_data) +{ + struct hotspot_search *search = user_data; + char *path; + + if (!info->is_hotspot) + return true; + + path = info->ops->get_file_path(info); + + if (!strcmp(path, search->path)) { + l_free(path); + search->info = (struct network_info *)info; + return false; + } + + l_free(path); + + return true; +} + +static struct network_info *find_network_info_from_path(const char *path) +{ + enum security security; + struct hotspot_search search; + const char *ssid = storage_network_ssid_from_path(path, &security); + + if (ssid) + return known_networks_find(ssid, security); + + search.info = NULL; + search.path = path; + + /* Try hotspot */ + known_networks_foreach(match_hotspot_path, &search); + + return search.info; +} + static void known_network_frequencies_load(void) { - char **network_names; + char **groups; struct l_queue *known_frequencies; uint32_t i; @@ -747,41 +793,35 @@ static void known_network_frequencies_load(void) return; } - network_names = l_settings_get_groups(known_freqs); - if (!network_names[0]) - goto done; + groups = l_settings_get_groups(known_freqs); - for (i = 0; network_names[i]; i++) { - struct network_info *network_info; - enum security security; - const char *ssid; + for (i = 0; groups[i]; i++) { + struct network_info *info; char *freq_list; - - ssid = storage_network_ssid_from_path(network_names[i], - &security); - if (!ssid) + const char *path = l_settings_get_value(known_freqs, groups[i], + "name"); + if (!path) continue; - freq_list = l_settings_get_string(known_freqs, network_names[i], - "list"); + info = find_network_info_from_path(path); + if (!info) + continue; + + freq_list = l_settings_get_string(known_freqs, groups[i], + "list"); if (!freq_list) continue; - network_info = known_networks_find(ssid, security); - if (!network_info) - goto next; - known_frequencies = known_frequencies_from_string(freq_list); if (!known_frequencies) goto next; - network_info->known_frequencies = known_frequencies; + info->known_frequencies = known_frequencies; next: l_free(freq_list); } -done: - l_strv_free(network_names); + l_strv_free(groups); } /* @@ -791,6 +831,16 @@ void known_network_frequency_sync(const struct network_info *info) { char *freq_list_str; char *file_path; + char group[37]; + uint8_t uuid[16]; + /* + * 16 bytes of randomness. Since we only care about a unique value there + * is no need to use any special pre-defined namespace. + */ + static const uint8_t nsid[16] = { + 0xfd, 0x88, 0x6f, 0x1e, 0xdf, 0x02, 0xd7, 0x8b, + 0xc4, 0x90, 0x30, 0x59, 0x73, 0x8a, 0x86, 0x0d + }; if (!info->known_frequencies) return; @@ -802,7 +852,11 @@ void known_network_frequency_sync(const struct network_info *info) file_path = info->ops->get_file_path(info); - l_settings_set_value(known_freqs, file_path, "list", freq_list_str); + l_uuid_v5(nsid, file_path, strlen(file_path), uuid); + l_uuid_to_string(uuid, group, sizeof(group)); + + l_settings_set_value(known_freqs, group, "name", file_path); + l_settings_set_value(known_freqs, group, "list", freq_list_str); l_free(file_path); l_free(freq_list_str);