mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-05-06 09:27:25 +02:00
network: Enforce Transition Disable settings
Transition Disable indications and information stored in the network profile needs to be enforced. Since Transition Disable information is now stored inside the network object, add a new method 'network_can_connect_bss' that will take this information into account. wiphy_can_connect method is thus deprecated and removed. Transition Disable can also result in certain AKMs and pairwise ciphers being disabled, so wiphy_select_akm method's signature is changed and takes the (possibly overriden) ie_rsn_info as input.
This commit is contained in:
parent
ca8f3edc33
commit
2e777a0d31
178
src/network.c
178
src/network.c
@ -759,61 +759,144 @@ static bool bss_is_sae(const struct scan_bss *bss)
|
|||||||
return __bss_is_sae(bss, &rsn);
|
return __bss_is_sae(bss, &rsn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int network_autoconnect(struct network *network, struct scan_bss *bss)
|
int network_can_connect_bss(struct network *network, const struct scan_bss *bss)
|
||||||
{
|
{
|
||||||
struct station *station = network->station;
|
struct station *station = network->station;
|
||||||
struct wiphy *wiphy = station_get_wiphy(station);
|
struct wiphy *wiphy = station_get_wiphy(station);
|
||||||
enum security security = network_get_security(network);
|
enum security security = network_get_security(network);
|
||||||
struct network_info *info = network->info;
|
struct network_info *info = network->info;
|
||||||
|
struct network_config *config = info ? &info->config : NULL;
|
||||||
|
bool can_transition_disable = wiphy_can_transition_disable(wiphy);
|
||||||
struct ie_rsn_info rsn;
|
struct ie_rsn_info rsn;
|
||||||
bool is_rsn;
|
int ret;
|
||||||
|
|
||||||
|
switch (security) {
|
||||||
|
case SECURITY_NONE:
|
||||||
|
case SECURITY_PSK:
|
||||||
|
case SECURITY_8021X:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&rsn, 0, sizeof(rsn));
|
||||||
|
ret = scan_bss_get_rsn_info(bss, &rsn);
|
||||||
|
if (ret < 0) {
|
||||||
|
/*
|
||||||
|
* WPA3 Specification Version 3, Section 8
|
||||||
|
* Transition Disable implies PMF, no TKIP, yet
|
||||||
|
* Bit 3 is specified as 'Open system authentication without
|
||||||
|
* encryption'.
|
||||||
|
*
|
||||||
|
* We assume the spec means us to check bit 3 here
|
||||||
|
*/
|
||||||
|
if (ret == -ENOENT && security == SECURITY_NONE) {
|
||||||
|
if (!config)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!config->have_transition_disable ||
|
||||||
|
!test_bit(&config->transition_disable,
|
||||||
|
3))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!can_transition_disable) {
|
||||||
|
l_debug("HW not capable of Transition Disable");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config || !config->have_transition_disable)
|
||||||
|
goto no_transition_disable;
|
||||||
|
|
||||||
|
if (!can_transition_disable) {
|
||||||
|
l_debug("HW not capable of Transition Disable, skip");
|
||||||
|
goto no_transition_disable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WPA3 Specification, v3, Section 8:
|
||||||
|
* - Disable use of WEP and TKIP
|
||||||
|
* - Disallow association without negotiation of PMF
|
||||||
|
*/
|
||||||
|
rsn.pairwise_ciphers &= ~IE_RSN_CIPHER_SUITE_TKIP;
|
||||||
|
|
||||||
|
if (!rsn.group_management_cipher)
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
rsn.mfpr = true;
|
||||||
|
|
||||||
|
/* WPA3-Personal */
|
||||||
|
if (test_bit(&config->transition_disable, 0)) {
|
||||||
|
rsn.akm_suites &= ~IE_RSN_AKM_SUITE_PSK;
|
||||||
|
rsn.akm_suites &= ~IE_RSN_AKM_SUITE_PSK_SHA256;
|
||||||
|
rsn.akm_suites &= ~IE_RSN_AKM_SUITE_FT_USING_PSK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WPA3-Enterprise */
|
||||||
|
if (test_bit(&config->transition_disable, 2))
|
||||||
|
rsn.akm_suites &= ~IE_RSN_AKM_SUITE_8021X;
|
||||||
|
|
||||||
|
/* Enhanced Open */
|
||||||
|
if (test_bit(&config->transition_disable, 3)) {
|
||||||
|
if (!(rsn.akm_suites & IE_RSN_AKM_SUITE_OWE))
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
no_transition_disable:
|
||||||
|
if (!wiphy_select_cipher(wiphy, rsn.pairwise_ciphers))
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
|
if (!wiphy_select_cipher(wiphy, rsn.group_cipher))
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
|
if (rsn.mfpr && !wiphy_select_cipher(wiphy,
|
||||||
|
rsn.group_management_cipher))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (!wiphy_select_akm(wiphy, bss, security, &rsn, false))
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int network_autoconnect(struct network *network, struct scan_bss *bss)
|
||||||
|
{
|
||||||
|
struct station *station = network->station;
|
||||||
|
enum security security = network_get_security(network);
|
||||||
|
struct network_info *info = network->info;
|
||||||
|
struct network_config *config;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* already waiting for an agent request, connect in progress */
|
/* already waiting for an agent request, connect in progress */
|
||||||
if (network->agent_request)
|
if (network->agent_request)
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
|
|
||||||
switch (security) {
|
if (network->ask_passphrase)
|
||||||
case SECURITY_NONE:
|
|
||||||
is_rsn = false;
|
|
||||||
break;
|
|
||||||
case SECURITY_PSK:
|
|
||||||
if (network->ask_passphrase)
|
|
||||||
return -ENOKEY;
|
|
||||||
|
|
||||||
/* Fall through */
|
|
||||||
case SECURITY_8021X:
|
|
||||||
is_rsn = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!info || !network_settings_load(network))
|
|
||||||
return -ENOKEY;
|
return -ENOKEY;
|
||||||
|
|
||||||
ret = -EPERM;
|
if (!info)
|
||||||
if (!info->config.is_autoconnectable)
|
return -ENOENT;
|
||||||
goto close_settings;
|
|
||||||
|
|
||||||
if (!is_rsn)
|
config = &info->config;
|
||||||
goto done;
|
|
||||||
|
|
||||||
memset(&rsn, 0, sizeof(rsn));
|
if (!config->is_autoconnectable)
|
||||||
scan_bss_get_rsn_info(bss, &rsn);
|
return -EPERM;
|
||||||
|
|
||||||
if (!wiphy_select_cipher(wiphy, rsn.pairwise_ciphers) ||
|
if (!network_settings_load(network))
|
||||||
!wiphy_select_cipher(wiphy, rsn.group_cipher)) {
|
return -ENOKEY;
|
||||||
l_debug("Cipher mismatch");
|
|
||||||
ret = -ENETUNREACH;
|
|
||||||
goto close_settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (security == SECURITY_PSK) {
|
switch (security) {
|
||||||
ret = network_load_psk(network, __bss_is_sae(bss, &rsn));
|
case SECURITY_PSK:
|
||||||
|
ret = network_load_psk(network, bss_is_sae(bss));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto close_settings;
|
goto close_settings;
|
||||||
} else if (security == SECURITY_8021X) {
|
|
||||||
|
break;
|
||||||
|
case SECURITY_8021X:
|
||||||
|
{
|
||||||
struct l_queue *missing_secrets = NULL;
|
struct l_queue *missing_secrets = NULL;
|
||||||
|
|
||||||
ret = eap_check_settings(network->settings, network->secrets,
|
ret = eap_check_settings(network->settings, network->secrets,
|
||||||
@ -829,9 +912,16 @@ int network_autoconnect(struct network *network, struct scan_bss *bss)
|
|||||||
|
|
||||||
if (!network_set_8021x_secrets(network))
|
if (!network_set_8021x_secrets(network))
|
||||||
goto close_settings;
|
goto close_settings;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SECURITY_NONE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
return __station_connect_network(station, network, bss);
|
return __station_connect_network(station, network, bss);
|
||||||
|
|
||||||
close_settings:
|
close_settings:
|
||||||
@ -1016,26 +1106,18 @@ struct scan_bss *network_bss_select(struct network *network,
|
|||||||
bool fallback_to_blacklist)
|
bool fallback_to_blacklist)
|
||||||
{
|
{
|
||||||
struct l_queue *bss_list = network->bss_list;
|
struct l_queue *bss_list = network->bss_list;
|
||||||
struct wiphy *wiphy = station_get_wiphy(network->station);
|
|
||||||
const struct l_queue_entry *bss_entry;
|
const struct l_queue_entry *bss_entry;
|
||||||
struct scan_bss *candidate = NULL;
|
struct scan_bss *candidate = NULL;
|
||||||
bool fils_hint = network_has_erp_identity(network);
|
|
||||||
|
|
||||||
for (bss_entry = l_queue_get_entries(bss_list); bss_entry;
|
for (bss_entry = l_queue_get_entries(bss_list); bss_entry;
|
||||||
bss_entry = bss_entry->next) {
|
bss_entry = bss_entry->next) {
|
||||||
struct scan_bss *bss = bss_entry->data;
|
struct scan_bss *bss = bss_entry->data;
|
||||||
|
int ret = network_can_connect_bss(network, bss);
|
||||||
|
|
||||||
switch (network_get_security(network)) {
|
if (ret == -ENOSYS)
|
||||||
case SECURITY_PSK:
|
|
||||||
case SECURITY_8021X:
|
|
||||||
if (!wiphy_can_connect(wiphy, bss, fils_hint))
|
|
||||||
continue;
|
|
||||||
/* fall through */
|
|
||||||
case SECURITY_NONE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
else if (ret < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We only want to record the first (best) candidate. In case
|
* We only want to record the first (best) candidate. In case
|
||||||
|
@ -57,6 +57,8 @@ void network_sync_settings(struct network *network);
|
|||||||
const struct network_info *network_get_info(const struct network *network);
|
const struct network_info *network_get_info(const struct network *network);
|
||||||
void network_set_info(struct network *network, struct network_info *info);
|
void network_set_info(struct network *network, struct network_info *info);
|
||||||
|
|
||||||
|
int network_can_connect_bss(struct network *network,
|
||||||
|
const struct scan_bss *bss);
|
||||||
int network_autoconnect(struct network *network, struct scan_bss *bss);
|
int network_autoconnect(struct network *network, struct scan_bss *bss);
|
||||||
void network_connect_failed(struct network *network, bool in_handshake);
|
void network_connect_failed(struct network *network, bool in_handshake);
|
||||||
bool network_bss_add(struct network *network, struct scan_bss *bss);
|
bool network_bss_add(struct network *network, struct scan_bss *bss);
|
||||||
|
@ -1513,7 +1513,8 @@ static void p2p_try_connect_group(struct p2p_device *dev)
|
|||||||
|
|
||||||
scan_bss_get_rsn_info(bss, &bss_info);
|
scan_bss_get_rsn_info(bss, &bss_info);
|
||||||
|
|
||||||
rsn_info.akm_suites = wiphy_select_akm(dev->wiphy, bss, false);
|
rsn_info.akm_suites = wiphy_select_akm(dev->wiphy, bss, SECURITY_PSK,
|
||||||
|
&bss_info, false);
|
||||||
if (!rsn_info.akm_suites)
|
if (!rsn_info.akm_suites)
|
||||||
goto not_supported;
|
goto not_supported;
|
||||||
|
|
||||||
|
@ -766,7 +766,8 @@ static int station_build_handshake_rsn(struct handshake_state *hs,
|
|||||||
if (security == SECURITY_8021X && hs->support_fils)
|
if (security == SECURITY_8021X && hs->support_fils)
|
||||||
fils_hint = network_has_erp_identity(network);
|
fils_hint = network_has_erp_identity(network);
|
||||||
|
|
||||||
info.akm_suites = wiphy_select_akm(wiphy, bss, fils_hint);
|
info.akm_suites = wiphy_select_akm(wiphy, bss, security,
|
||||||
|
&bss_info, fils_hint);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special case for OWE. With OWE we still need to build up the
|
* Special case for OWE. With OWE we still need to build up the
|
||||||
@ -1823,7 +1824,6 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
|
|||||||
uint16_t mdid;
|
uint16_t mdid;
|
||||||
enum security orig_security, security;
|
enum security orig_security, security;
|
||||||
bool seen = false;
|
bool seen = false;
|
||||||
bool fils_hint = network_has_erp_identity(network);
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
station_roam_failed(station);
|
station_roam_failed(station);
|
||||||
@ -1880,7 +1880,7 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
|
|||||||
|
|
||||||
seen = true;
|
seen = true;
|
||||||
|
|
||||||
if (!wiphy_can_connect(station->wiphy, bss, fils_hint))
|
if (network_can_connect_bss(network, bss) < 0)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (blacklist_contains_bss(bss->addr))
|
if (blacklist_contains_bss(bss->addr))
|
||||||
|
66
src/wiphy.c
66
src/wiphy.c
@ -193,19 +193,14 @@ static bool wiphy_can_connect_sae(struct wiphy *wiphy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy,
|
enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy,
|
||||||
struct scan_bss *bss,
|
const struct scan_bss *bss,
|
||||||
|
enum security security,
|
||||||
|
const struct ie_rsn_info *info,
|
||||||
bool fils_capable_hint)
|
bool fils_capable_hint)
|
||||||
{
|
{
|
||||||
struct ie_rsn_info info;
|
|
||||||
enum security security;
|
|
||||||
bool psk_offload = wiphy_has_ext_feature(wiphy,
|
bool psk_offload = wiphy_has_ext_feature(wiphy,
|
||||||
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
|
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
|
||||||
|
|
||||||
memset(&info, 0, sizeof(info));
|
|
||||||
scan_bss_get_rsn_info(bss, &info);
|
|
||||||
|
|
||||||
security = security_determine(bss->capability, &info);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If FT is available, use FT authentication to keep the door open
|
* If FT is available, use FT authentication to keep the door open
|
||||||
* for fast transitions. Otherwise use SHA256 version if present.
|
* for fast transitions. Otherwise use SHA256 version if present.
|
||||||
@ -213,32 +208,32 @@ enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy,
|
|||||||
if (security == SECURITY_8021X) {
|
if (security == SECURITY_8021X) {
|
||||||
if (wiphy_has_feature(wiphy, NL80211_EXT_FEATURE_FILS_STA) &&
|
if (wiphy_has_feature(wiphy, NL80211_EXT_FEATURE_FILS_STA) &&
|
||||||
fils_capable_hint) {
|
fils_capable_hint) {
|
||||||
if ((info.akm_suites &
|
if ((info->akm_suites &
|
||||||
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384) &&
|
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384) &&
|
||||||
bss->rsne && bss->mde_present)
|
bss->rsne && bss->mde_present)
|
||||||
return IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384;
|
return IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA384;
|
||||||
|
|
||||||
if ((info.akm_suites &
|
if ((info->akm_suites &
|
||||||
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256) &&
|
IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256) &&
|
||||||
bss->rsne && bss->mde_present)
|
bss->rsne && bss->mde_present)
|
||||||
return IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256;
|
return IE_RSN_AKM_SUITE_FT_OVER_FILS_SHA256;
|
||||||
|
|
||||||
if (info.akm_suites & IE_RSN_AKM_SUITE_FILS_SHA384)
|
if (info->akm_suites & IE_RSN_AKM_SUITE_FILS_SHA384)
|
||||||
return IE_RSN_AKM_SUITE_FILS_SHA384;
|
return IE_RSN_AKM_SUITE_FILS_SHA384;
|
||||||
|
|
||||||
if (info.akm_suites & IE_RSN_AKM_SUITE_FILS_SHA256)
|
if (info->akm_suites & IE_RSN_AKM_SUITE_FILS_SHA256)
|
||||||
return IE_RSN_AKM_SUITE_FILS_SHA256;
|
return IE_RSN_AKM_SUITE_FILS_SHA256;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info.akm_suites & IE_RSN_AKM_SUITE_FT_OVER_8021X) &&
|
if ((info->akm_suites & IE_RSN_AKM_SUITE_FT_OVER_8021X) &&
|
||||||
bss->rsne && bss->mde_present &&
|
bss->rsne && bss->mde_present &&
|
||||||
wiphy->support_cmds_auth_assoc)
|
wiphy->support_cmds_auth_assoc)
|
||||||
return IE_RSN_AKM_SUITE_FT_OVER_8021X;
|
return IE_RSN_AKM_SUITE_FT_OVER_8021X;
|
||||||
|
|
||||||
if (info.akm_suites & IE_RSN_AKM_SUITE_8021X_SHA256)
|
if (info->akm_suites & IE_RSN_AKM_SUITE_8021X_SHA256)
|
||||||
return IE_RSN_AKM_SUITE_8021X_SHA256;
|
return IE_RSN_AKM_SUITE_8021X_SHA256;
|
||||||
|
|
||||||
if (info.akm_suites & IE_RSN_AKM_SUITE_8021X)
|
if (info->akm_suites & IE_RSN_AKM_SUITE_8021X)
|
||||||
return IE_RSN_AKM_SUITE_8021X;
|
return IE_RSN_AKM_SUITE_8021X;
|
||||||
} else if (security == SECURITY_PSK) {
|
} else if (security == SECURITY_PSK) {
|
||||||
/*
|
/*
|
||||||
@ -247,17 +242,17 @@ enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy,
|
|||||||
* MFPR/MFPC bits correctly. If any of these conditions are not
|
* MFPR/MFPC bits correctly. If any of these conditions are not
|
||||||
* met, we can fallback to WPA2 (if the AKM is present).
|
* met, we can fallback to WPA2 (if the AKM is present).
|
||||||
*/
|
*/
|
||||||
if (ie_rsne_is_wpa3_personal(&info)) {
|
if (ie_rsne_is_wpa3_personal(info)) {
|
||||||
l_debug("Network is WPA3-Personal...");
|
l_debug("Network is WPA3-Personal...");
|
||||||
|
|
||||||
if (!wiphy_can_connect_sae(wiphy))
|
if (!wiphy_can_connect_sae(wiphy))
|
||||||
goto wpa2_personal;
|
goto wpa2_personal;
|
||||||
|
|
||||||
if (info.akm_suites &
|
if (info->akm_suites &
|
||||||
IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256)
|
IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256)
|
||||||
return IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256;
|
return IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256;
|
||||||
|
|
||||||
if (info.akm_suites & IE_RSN_AKM_SUITE_SAE_SHA256)
|
if (info->akm_suites & IE_RSN_AKM_SUITE_SAE_SHA256)
|
||||||
return IE_RSN_AKM_SUITE_SAE_SHA256;
|
return IE_RSN_AKM_SUITE_SAE_SHA256;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,20 +262,20 @@ wpa2_personal:
|
|||||||
* supports PSK offload. Without Auth/Assoc, PSK offload is the
|
* supports PSK offload. Without Auth/Assoc, PSK offload is the
|
||||||
* only mechanism to allow FT on these cards.
|
* only mechanism to allow FT on these cards.
|
||||||
*/
|
*/
|
||||||
if ((info.akm_suites & IE_RSN_AKM_SUITE_FT_USING_PSK) &&
|
if ((info->akm_suites & IE_RSN_AKM_SUITE_FT_USING_PSK) &&
|
||||||
bss->rsne && bss->mde_present) {
|
bss->rsne && bss->mde_present) {
|
||||||
if (wiphy->support_cmds_auth_assoc ||
|
if (wiphy->support_cmds_auth_assoc ||
|
||||||
(psk_offload && wiphy->support_fw_roam))
|
(psk_offload && wiphy->support_fw_roam))
|
||||||
return IE_RSN_AKM_SUITE_FT_USING_PSK;
|
return IE_RSN_AKM_SUITE_FT_USING_PSK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.akm_suites & IE_RSN_AKM_SUITE_PSK_SHA256)
|
if (info->akm_suites & IE_RSN_AKM_SUITE_PSK_SHA256)
|
||||||
return IE_RSN_AKM_SUITE_PSK_SHA256;
|
return IE_RSN_AKM_SUITE_PSK_SHA256;
|
||||||
|
|
||||||
if (info.akm_suites & IE_RSN_AKM_SUITE_PSK)
|
if (info->akm_suites & IE_RSN_AKM_SUITE_PSK)
|
||||||
return IE_RSN_AKM_SUITE_PSK;
|
return IE_RSN_AKM_SUITE_PSK;
|
||||||
} else if (security == SECURITY_NONE) {
|
} else if (security == SECURITY_NONE) {
|
||||||
if (info.akm_suites & IE_RSN_AKM_SUITE_OWE)
|
if (info->akm_suites & IE_RSN_AKM_SUITE_OWE)
|
||||||
return IE_RSN_AKM_SUITE_OWE;
|
return IE_RSN_AKM_SUITE_OWE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,33 +418,6 @@ const struct scan_freq_set *wiphy_get_supported_freqs(
|
|||||||
return wiphy->supported_freqs;
|
return wiphy->supported_freqs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wiphy_can_connect(struct wiphy *wiphy, struct scan_bss *bss,
|
|
||||||
bool fils_hint)
|
|
||||||
{
|
|
||||||
struct ie_rsn_info rsn_info;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&rsn_info, 0, sizeof(rsn_info));
|
|
||||||
r = scan_bss_get_rsn_info(bss, &rsn_info);
|
|
||||||
|
|
||||||
if (r == 0) {
|
|
||||||
if (!wiphy_select_cipher(wiphy, rsn_info.pairwise_ciphers))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!wiphy_select_cipher(wiphy, rsn_info.group_cipher))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (rsn_info.mfpr && !wiphy_select_cipher(wiphy,
|
|
||||||
rsn_info.group_management_cipher))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return wiphy_select_akm(wiphy, bss, fils_hint);
|
|
||||||
} else if (r != -ENOENT)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wiphy_can_transition_disable(struct wiphy *wiphy)
|
bool wiphy_can_transition_disable(struct wiphy *wiphy)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -27,6 +27,8 @@ struct wiphy;
|
|||||||
struct scan_bss;
|
struct scan_bss;
|
||||||
struct scan_freq_set;
|
struct scan_freq_set;
|
||||||
struct wiphy_radio_work_item;
|
struct wiphy_radio_work_item;
|
||||||
|
struct ie_rsn_info;
|
||||||
|
enum security;
|
||||||
|
|
||||||
typedef bool (*wiphy_radio_work_func_t)(struct wiphy_radio_work_item *item);
|
typedef bool (*wiphy_radio_work_func_t)(struct wiphy_radio_work_item *item);
|
||||||
typedef void (*wiphy_radio_work_destroy_func_t)(
|
typedef void (*wiphy_radio_work_destroy_func_t)(
|
||||||
@ -56,7 +58,9 @@ typedef void (*wiphy_destroy_func_t)(void *user_data);
|
|||||||
enum ie_rsn_cipher_suite wiphy_select_cipher(struct wiphy *wiphy,
|
enum ie_rsn_cipher_suite wiphy_select_cipher(struct wiphy *wiphy,
|
||||||
uint16_t mask);
|
uint16_t mask);
|
||||||
enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy,
|
enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy,
|
||||||
struct scan_bss *bss,
|
const struct scan_bss *bss,
|
||||||
|
enum security security,
|
||||||
|
const struct ie_rsn_info *info,
|
||||||
bool fils_capable_hint);
|
bool fils_capable_hint);
|
||||||
|
|
||||||
struct wiphy *wiphy_find(int wiphy_id);
|
struct wiphy *wiphy_find(int wiphy_id);
|
||||||
@ -78,8 +82,6 @@ const char *wiphy_get_path(struct wiphy *wiphy);
|
|||||||
uint32_t wiphy_get_supported_bands(struct wiphy *wiphy);
|
uint32_t wiphy_get_supported_bands(struct wiphy *wiphy);
|
||||||
const struct scan_freq_set *wiphy_get_supported_freqs(
|
const struct scan_freq_set *wiphy_get_supported_freqs(
|
||||||
const struct wiphy *wiphy);
|
const struct wiphy *wiphy);
|
||||||
bool wiphy_can_connect(struct wiphy *wiphy, struct scan_bss *bss,
|
|
||||||
bool fils_hint);
|
|
||||||
bool wiphy_can_transition_disable(struct wiphy *wiphy);
|
bool wiphy_can_transition_disable(struct wiphy *wiphy);
|
||||||
bool wiphy_supports_cmds_auth_assoc(struct wiphy *wiphy);
|
bool wiphy_supports_cmds_auth_assoc(struct wiphy *wiphy);
|
||||||
bool wiphy_can_randomize_mac_addr(struct wiphy *wiphy);
|
bool wiphy_can_randomize_mac_addr(struct wiphy *wiphy);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user