From 2a66b3bfe5dd22c1fbe8bb7b8de775f84778e7dd Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 8 Jul 2021 16:47:50 -0500 Subject: [PATCH] network: Move handshake parameter setup from station Most parameters set into the handshake object are actually known by the network object itself and not station. This includes address randomization settings, EAPoL settings, passphrase/psk/8021x settings, etc. Since the number of these settings will only keep growing, move the handshake setup into network itself. This also helps keep network internals better encapsulated. --- src/network.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++--- src/network.h | 7 ++- src/station.c | 88 +------------------------------------- 3 files changed, 117 insertions(+), 94 deletions(-) diff --git a/src/network.c b/src/network.c index 22c9cfdd..114e4746 100644 --- a/src/network.c +++ b/src/network.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -53,6 +54,7 @@ #include "src/blacklist.h" #include "src/util.h" #include "src/erp.h" +#include "src/handshake.h" static uint32_t known_networks_watch; static uint32_t anqp_watch; @@ -259,7 +261,7 @@ enum security network_get_security(const struct network *network) return network->security; } -const uint8_t *network_get_psk(struct network *network) +static const uint8_t *network_get_psk(struct network *network) { int r; @@ -281,11 +283,6 @@ const uint8_t *network_get_psk(struct network *network) return network->psk; } -const char *network_get_passphrase(const struct network *network) -{ - return network->passphrase; -} - static bool __network_set_passphrase(struct network *network, const char *passphrase) { @@ -388,6 +385,113 @@ static bool network_set_8021x_secrets(struct network *network) return true; } +static int network_set_handshake_secrets_psk(struct network *network, + struct handshake_state *hs) +{ + /* SAE will generate/set the PMK */ + if (IE_AKM_IS_SAE(hs->akm_suite)) { + if (!network->passphrase) + return -ENOKEY; + + handshake_state_set_passphrase(hs, network->passphrase); + } else { + const uint8_t *psk = network_get_psk(network); + + if (!psk) + return -ENOKEY; + + handshake_state_set_pmk(hs, psk, 32); + } + + return 0; +} + +int network_handshake_setup(struct network *network, + struct handshake_state *hs) +{ + struct station *station = network->station; + struct wiphy *wiphy = station_get_wiphy(station); + struct l_settings *settings = network->settings; + uint32_t eapol_proto_version; + const char *value; + bool full_random; + bool override = false; + uint8_t new_addr[ETH_ALEN]; + int r; + + switch (network->security) { + case SECURITY_PSK: + r = network_set_handshake_secrets_psk(network, hs); + if (r < 0) + return r; + + break; + case SECURITY_8021X: + handshake_state_set_8021x_config(hs, settings); + break; + case SECURITY_NONE: + break; + case SECURITY_WEP: + return -ENOTSUP; + } + + handshake_state_set_ssid(hs, (void *) network->ssid, + strlen(network->ssid)); + + if (settings && l_settings_get_uint(settings, "EAPoL", + "ProtocolVersion", + &eapol_proto_version)) { + if (eapol_proto_version > 3) { + l_warn("Invalid ProtocolVersion value - should be 0-3"); + eapol_proto_version = 0; + } + + if (eapol_proto_version) + l_debug("Overriding EAPoL protocol version to: %u", + eapol_proto_version); + + handshake_state_set_protocol_version(hs, eapol_proto_version); + } + + /* + * We have three possible options here: + * 1. per-network MAC generation (default, no option in network config) + * 2. per-network full MAC randomization + * 3. per-network MAC override + */ + + if (!l_settings_get_bool(settings, "Settings", + "AlwaysRandomizeAddress", + &full_random)) + full_random = false; + + value = l_settings_get_value(settings, "Settings", + "AddressOverride"); + if (value) { + if (util_string_to_address(value, new_addr) && + util_is_valid_sta_address(new_addr)) + override = true; + else + l_warn("[Network].AddressOverride is not a valid " + "MAC address"); + } + + if (override && full_random) { + l_warn("Cannot use both AlwaysRandomizeAddress and " + "AddressOverride concurrently, defaulting to override"); + full_random = false; + } + + if (override) + handshake_state_set_supplicant_address(hs, new_addr); + else if (full_random) { + wiphy_generate_random_address(wiphy, new_addr); + handshake_state_set_supplicant_address(hs, new_addr); + } + + return 0; +} + static int network_load_psk(struct network *network, bool need_passphrase) { const char *ssid = network_get_ssid(network); diff --git a/src/network.h b/src/network.h index 5d23216e..14a8fdc8 100644 --- a/src/network.h +++ b/src/network.h @@ -28,6 +28,7 @@ struct device; struct station; struct network; struct scan_bss; +struct handshake_state; void network_connected(struct network *network); void network_disconnected(struct network *network); @@ -39,14 +40,16 @@ struct network *network_create(struct station *station, const char *ssid, const char *network_get_ssid(const struct network *network); const char *network_get_path(const struct network *network); enum security network_get_security(const struct network *network); -const uint8_t *network_get_psk(struct network *network); -const char *network_get_passphrase(const struct network *network); bool network_set_passphrase(struct network *network, const char *passphrase); struct l_queue *network_get_secrets(const struct network *network); int network_get_signal_strength(const struct network *network); struct l_settings *network_get_settings(const struct network *network); bool network_set_psk(struct network *network, const uint8_t *psk); + +int network_handshake_setup(struct network *network, + struct handshake_state *hs); + void network_sync_settings(struct network *network); const struct network_info *network_get_info(const struct network *network); diff --git a/src/station.c b/src/station.c index 32fe0374..9bf3bbce 100644 --- a/src/station.c +++ b/src/station.c @@ -865,16 +865,8 @@ static struct handshake_state *station_handshake_setup(struct station *station, struct network *network, struct scan_bss *bss) { - enum security security = network_get_security(network); - struct l_settings *settings = network_get_settings(network); struct wiphy *wiphy = station->wiphy; struct handshake_state *hs; - const char *ssid; - uint32_t eapol_proto_version; - const char *value; - bool full_random; - bool override = false; - uint8_t new_addr[ETH_ALEN]; hs = netdev_handshake_state_new(station->netdev); @@ -883,45 +875,8 @@ static struct handshake_state *station_handshake_setup(struct station *station, if (station_build_handshake_rsn(hs, wiphy, network, bss) < 0) goto not_supported; - ssid = network_get_ssid(network); - handshake_state_set_ssid(hs, (void *) ssid, strlen(ssid)); - - if (settings && l_settings_get_uint(settings, "EAPoL", - "ProtocolVersion", - &eapol_proto_version)) { - if (eapol_proto_version > 3) { - l_warn("Invalid ProtocolVersion value - should be 0-3"); - eapol_proto_version = 0; - } - - if (eapol_proto_version) - l_debug("Overriding EAPoL protocol version to: %u", - eapol_proto_version); - - handshake_state_set_protocol_version(hs, eapol_proto_version); - } - - if (security == SECURITY_PSK) { - /* SAE will generate/set the PMK */ - if (IE_AKM_IS_SAE(hs->akm_suite)) { - const char *passphrase = - network_get_passphrase(network); - - if (!passphrase) - goto no_psk; - - handshake_state_set_passphrase(hs, passphrase); - } else { - const uint8_t *psk = network_get_psk(network); - - if (!psk) - goto no_psk; - - handshake_state_set_pmk(hs, psk, 32); - } - } else if (security == SECURITY_8021X) - handshake_state_set_8021x_config(hs, - network_get_settings(network)); + if (network_handshake_setup(network, hs) < 0) + goto not_supported; /* * If FILS was chosen, the ERP cache has been verified to exist. We @@ -934,49 +889,10 @@ static struct handshake_state *station_handshake_setup(struct station *station, IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384)) hs->erp_cache = erp_cache_get(network_get_ssid(network)); - /* - * We have three possible options here: - * 1. per-network MAC generation (default, no option in network config) - * 2. per-network full MAC randomization - * 3. per-network MAC override - */ - - if (!l_settings_get_bool(settings, "Settings", - "AlwaysRandomizeAddress", - &full_random)) - full_random = false; - - value = l_settings_get_value(settings, "Settings", - "AddressOverride"); - if (value) { - if (util_string_to_address(value, new_addr) && - util_is_valid_sta_address(new_addr)) - override = true; - else - l_warn("[Network].AddressOverride is not a valid " - "MAC address"); - } - - if (override && full_random) { - l_warn("Cannot use both AlwaysRandomizeAddress and " - "AddressOverride concurrently, defaulting to override"); - full_random = false; - } - - if (override) - handshake_state_set_supplicant_address(hs, new_addr); - else if (full_random) { - wiphy_generate_random_address(wiphy, new_addr); - handshake_state_set_supplicant_address(hs, new_addr); - } - return hs; -no_psk: - l_warn("Missing network PSK/passphrase"); not_supported: handshake_state_free(hs); - return NULL; }