From f4ef431e8d39712caf1966edded75f6cdbed3f52 Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Mon, 19 Aug 2019 11:11:56 -0700 Subject: [PATCH] knownnetworks: add matching ops to network_info These operations will allow the hotspot module to implement matching HESSID, Roaming Consortium, and NAI realms. This offloads the matching details into the hotspot module. --- src/hotspot.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ src/knownnetworks.c | 28 +++++++++++++++++++ src/knownnetworks.h | 16 +++++++++++ 3 files changed, 112 insertions(+) diff --git a/src/hotspot.c b/src/hotspot.c index c950de42..68218c25 100644 --- a/src/hotspot.c +++ b/src/hotspot.c @@ -166,6 +166,70 @@ static const char *hotspot_network_get_path(const struct network_info *info) return config->object_path; } +static bool hotspot_match_hessid(const struct network_info *info, + const uint8_t *hessid) +{ + struct hs20_config *config = l_container_of(info, struct hs20_config, + super); + + if (util_mem_is_zero(config->hessid, 6) || !hessid) + return false; + + return !memcmp(config->hessid, hessid, 6); +} + +static bool hotspot_match_roaming_consortium(const struct network_info *info, + const uint8_t *rc_ie, + size_t rc_len) +{ + const uint8_t *rc1, *rc2, *rc3; + size_t rc1_len, rc2_len, rc3_len; + struct hs20_config *config = l_container_of(info, struct hs20_config, + super); + + if (!config->rc || !rc_ie) + return false; + + if (ie_parse_roaming_consortium_from_data(rc_ie, rc_ie[1] + 2, NULL, + &rc1, &rc1_len, &rc2, &rc2_len, + &rc3, &rc3_len) < 0) + return false; + + /* rc1 is guarenteed to be set if the above returns success */ + if (rc1_len == config->rc_len && !memcmp(rc1, config->rc, rc1_len)) + return true; + + if (rc2 && rc2_len == config->rc_len && + !memcmp(rc2, config->rc, rc2_len)) + return true; + + if (rc3 && rc1_len == config->rc_len && + !memcmp(rc3, config->rc, rc3_len)) + return true; + + return false; +} + +static bool hotspot_match_nai_realms(const struct network_info *info, + const char **nai_realms) +{ + const char **realms = nai_realms; + struct hs20_config *config = l_container_of(info, struct hs20_config, + super); + + if (!config->nai_realms || !nai_realms) + return false; + + while (*realms) { + if (l_strv_contains(config->nai_realms, *realms)) + return true; + + realms++; + } + + return false; +} + static struct network_info_ops hotspot_ops = { .open = hotspot_network_open, .touch = hotspot_network_touch, @@ -173,6 +237,10 @@ static struct network_info_ops hotspot_ops = { .remove = hotspot_network_remove, .free = hotspot_network_free, .get_path = hotspot_network_get_path, + + .match_hessid = hotspot_match_hessid, + .match_roaming_consortium = hotspot_match_roaming_consortium, + .match_nai_realms = hotspot_match_nai_realms, }; static struct hs20_config *hs20_config_new(struct l_settings *settings, diff --git a/src/knownnetworks.c b/src/knownnetworks.c index 88862ad8..7e754103 100644 --- a/src/knownnetworks.c +++ b/src/knownnetworks.c @@ -187,6 +187,34 @@ const char *network_info_get_path(const struct network_info *info) return info->ops->get_path(info); } +bool network_info_match_hessid(const struct network_info *info, + const uint8_t *hessid) +{ + if (!info->ops->match_hessid) + return false; + + return info->ops->match_hessid(info, hessid); +} + +bool network_info_match_roaming_consortium(const struct network_info *info, + const uint8_t *rc, + size_t rc_len) +{ + if (!info->ops->match_roaming_consortium) + return false; + + return info->ops->match_roaming_consortium(info, rc, rc_len); +} + +bool network_info_match_nai_realm(const struct network_info *info, + const char **nai_realms) +{ + if (!info->ops->match_nai_realms) + return false; + + return info->ops->match_nai_realms(info, nai_realms); +} + static void known_network_update(struct network_info *orig_network, const char *ssid, enum security security, diff --git a/src/knownnetworks.h b/src/knownnetworks.h index de42b803..5cb4a4c2 100644 --- a/src/knownnetworks.h +++ b/src/knownnetworks.h @@ -36,6 +36,14 @@ struct network_info_ops { void (*remove)(struct network_info *info); void (*free)(struct network_info *info); const char *(*get_path)(const struct network_info *info); + + bool (*match_hessid)(const struct network_info *info, + const uint8_t *hessid); + bool (*match_roaming_consortium)(const struct network_info *info, + const uint8_t *rc_ie, + size_t rc_len); + bool (*match_nai_realms)(const struct network_info *info, + const char **nai_realms); }; struct network_info { @@ -82,5 +90,13 @@ struct l_settings *network_info_open_settings(struct network_info *info); int network_info_touch(struct network_info *info); const char *network_info_get_path(const struct network_info *info); +bool network_info_match_hessid(const struct network_info *info, + const uint8_t *hessid); +bool network_info_match_roaming_consortium(const struct network_info *info, + const uint8_t *rc, + size_t rc_len); +bool network_info_match_nai_realm(const struct network_info *info, + const char **nai_realms); + void known_networks_add(struct network_info *info); void known_networks_remove(struct network_info *info);