mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
scan: Refactor bss_get_supported_ciphers
In many cases the pairwise and group cipher information is not the only information needed from the BSS RSN/WPA elements in order to make a decision. For example, th MFPC/MFPR bits might be needed, or pre-authentication capability bits, group management ciphers, etc. This patch refactors bss_get_supported_ciphers into the more general scan_bss_get_rsn_info function
This commit is contained in:
parent
bdd676a23a
commit
318d3a2d35
56
src/device.c
56
src/device.c
@ -220,6 +220,8 @@ static void process_bss(struct device *device, struct scan_bss *bss,
|
||||
struct timespec *timestamp)
|
||||
{
|
||||
struct network *network;
|
||||
struct ie_rsn_info info;
|
||||
int r;
|
||||
enum security security;
|
||||
const char *path;
|
||||
double rankmod;
|
||||
@ -240,41 +242,20 @@ static void process_bss(struct device *device, struct scan_bss *bss,
|
||||
memcpy(ssid, bss->ssid, bss->ssid_len);
|
||||
ssid[bss->ssid_len] = '\0';
|
||||
|
||||
/*
|
||||
* If both an RSN and a WPA elements are present currently
|
||||
* RSN takes priority and the WPA IE is ignored.
|
||||
*/
|
||||
if (bss->rsne) {
|
||||
struct ie_rsn_info rsne;
|
||||
int res = ie_parse_rsne_from_data(bss->rsne, bss->rsne[1] + 2,
|
||||
&rsne);
|
||||
if (res < 0) {
|
||||
l_debug("Cannot parse RSN field (%d, %s)",
|
||||
res, strerror(-res));
|
||||
memset(&info, 0, sizeof(info));
|
||||
r = scan_bss_get_rsn_info(bss, &info);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
return;
|
||||
}
|
||||
|
||||
security = scan_get_security(bss->capability, &rsne);
|
||||
|
||||
if (security == SECURITY_PSK)
|
||||
bss->sha256 =
|
||||
rsne.akm_suites & IE_RSN_AKM_SUITE_PSK_SHA256;
|
||||
else if (security == SECURITY_8021X)
|
||||
bss->sha256 =
|
||||
rsne.akm_suites & IE_RSN_AKM_SUITE_8021X_SHA256;
|
||||
} else if (bss->wpa) {
|
||||
struct ie_rsn_info wpa;
|
||||
int res = ie_parse_wpa_from_data(bss->wpa, bss->wpa[1] + 2,
|
||||
&wpa);
|
||||
if (res < 0) {
|
||||
l_debug("Cannot parse WPA IE (%d, %s)",
|
||||
res, strerror(-res));
|
||||
return;
|
||||
}
|
||||
|
||||
security = scan_get_security(bss->capability, &wpa);
|
||||
} else
|
||||
security = scan_get_security(bss->capability, NULL);
|
||||
} else
|
||||
security = scan_get_security(bss->capability, &info);
|
||||
|
||||
if (security == SECURITY_PSK)
|
||||
bss->sha256 = info.akm_suites & IE_RSN_AKM_SUITE_PSK_SHA256;
|
||||
else if (security == SECURITY_8021X)
|
||||
bss->sha256 = info.akm_suites & IE_RSN_AKM_SUITE_8021X_SHA256;
|
||||
|
||||
path = iwd_network_get_path(device, ssid, security);
|
||||
|
||||
@ -664,7 +645,7 @@ void device_connect_network(struct device *device, struct network *network,
|
||||
struct eapol_sm *sm = NULL;
|
||||
|
||||
if (security == SECURITY_PSK || security == SECURITY_8021X) {
|
||||
uint16_t pairwise_ciphers, group_ciphers;
|
||||
struct ie_rsn_info bss_info;
|
||||
uint8_t rsne_buf[256];
|
||||
struct ie_rsn_info info;
|
||||
|
||||
@ -685,12 +666,13 @@ void device_connect_network(struct device *device, struct network *network,
|
||||
bss->sha256 ? IE_RSN_AKM_SUITE_8021X_SHA256 :
|
||||
IE_RSN_AKM_SUITE_8021X;
|
||||
|
||||
bss_get_supported_ciphers(bss,
|
||||
&pairwise_ciphers, &group_ciphers);
|
||||
memset(&bss_info, 0, sizeof(bss_info));
|
||||
scan_bss_get_rsn_info(bss, &bss_info);
|
||||
|
||||
info.pairwise_ciphers = wiphy_select_cipher(wiphy,
|
||||
pairwise_ciphers);
|
||||
info.group_cipher = wiphy_select_cipher(wiphy, group_ciphers);
|
||||
bss_info.pairwise_ciphers);
|
||||
info.group_cipher = wiphy_select_cipher(wiphy,
|
||||
bss_info.group_cipher);
|
||||
|
||||
/* RSN takes priority */
|
||||
if (bss->rsne) {
|
||||
|
@ -378,15 +378,15 @@ int network_autoconnect(struct network *network, struct scan_bss *bss)
|
||||
break;
|
||||
case SECURITY_PSK:
|
||||
{
|
||||
uint16_t pairwise_ciphers, group_ciphers;
|
||||
struct ie_rsn_info rsn;
|
||||
const char *psk;
|
||||
size_t len;
|
||||
|
||||
bss_get_supported_ciphers(bss,
|
||||
&pairwise_ciphers, &group_ciphers);
|
||||
memset(&rsn, 0, sizeof(rsn));
|
||||
scan_bss_get_rsn_info(bss, &rsn);
|
||||
|
||||
if (!wiphy_select_cipher(wiphy, pairwise_ciphers) ||
|
||||
!wiphy_select_cipher(wiphy, group_ciphers)) {
|
||||
if (!wiphy_select_cipher(wiphy, rsn.pairwise_ciphers) ||
|
||||
!wiphy_select_cipher(wiphy, rsn.group_cipher)) {
|
||||
l_debug("Cipher mis-match");
|
||||
return -ENETUNREACH;
|
||||
}
|
||||
@ -487,14 +487,14 @@ struct scan_bss *network_bss_select(struct network *network)
|
||||
for (bss_entry = l_queue_get_entries(bss_list); bss_entry;
|
||||
bss_entry = bss_entry->next) {
|
||||
struct scan_bss *bss = bss_entry->data;
|
||||
uint16_t pairwise_ciphers, group_ciphers;
|
||||
struct ie_rsn_info rsn;
|
||||
|
||||
bss_get_supported_ciphers(bss, &pairwise_ciphers,
|
||||
&group_ciphers);
|
||||
memset(&rsn, 0, sizeof(rsn));
|
||||
scan_bss_get_rsn_info(bss, &rsn);
|
||||
|
||||
if (wiphy_select_cipher(wiphy, pairwise_ciphers) &&
|
||||
if (wiphy_select_cipher(wiphy, rsn.pairwise_ciphers) &&
|
||||
wiphy_select_cipher(wiphy,
|
||||
group_ciphers))
|
||||
rsn.group_cipher))
|
||||
return bss;
|
||||
}
|
||||
|
||||
|
26
src/scan.c
26
src/scan.c
@ -794,36 +794,32 @@ void scan_bss_free(struct scan_bss *bss)
|
||||
l_free(bss);
|
||||
}
|
||||
|
||||
void bss_get_supported_ciphers(struct scan_bss *bss,
|
||||
uint16_t *pairwise_ciphers,
|
||||
uint16_t *group_ciphers)
|
||||
int scan_bss_get_rsn_info(struct scan_bss *bss, struct ie_rsn_info *info)
|
||||
{
|
||||
struct ie_rsn_info ie;
|
||||
|
||||
*pairwise_ciphers = 0;
|
||||
*group_ciphers = 0;
|
||||
|
||||
/*
|
||||
* If both an RSN and a WPA elements are present currently
|
||||
* RSN takes priority and the WPA IE is ignored.
|
||||
*/
|
||||
if (bss->rsne) {
|
||||
int res = ie_parse_rsne_from_data(bss->rsne, bss->rsne[1] + 2,
|
||||
&ie);
|
||||
info);
|
||||
if (res < 0) {
|
||||
l_debug("Cannot parse RSN field (%d, %s)",
|
||||
res, strerror(-res));
|
||||
return;
|
||||
return res;
|
||||
}
|
||||
} else if (bss->wpa) {
|
||||
int res = ie_parse_wpa_from_data(bss->wpa, bss->wpa[1] + 2,
|
||||
&ie);
|
||||
info);
|
||||
if (res < 0) {
|
||||
l_debug("Cannot parse WPA IE (%d, %s)",
|
||||
res, strerror(-res));
|
||||
return;
|
||||
return res;
|
||||
}
|
||||
} else
|
||||
return;
|
||||
return -ENOENT;
|
||||
|
||||
*pairwise_ciphers = ie.pairwise_ciphers;
|
||||
*group_ciphers = ie.group_cipher;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scan_bss_rank_compare(const void *a, const void *b, void *user_data)
|
||||
|
@ -82,9 +82,7 @@ enum security scan_get_security(enum ie_bss_capability bss_cap,
|
||||
void scan_bss_free(struct scan_bss *bss);
|
||||
int scan_bss_rank_compare(const void *a, const void *b, void *user);
|
||||
|
||||
void bss_get_supported_ciphers(struct scan_bss *bss,
|
||||
uint16_t *pairwise_ciphers,
|
||||
uint16_t *group_ciphers);
|
||||
int scan_bss_get_rsn_info(struct scan_bss *bss, struct ie_rsn_info *info);
|
||||
|
||||
uint8_t scan_freq_to_channel(uint32_t freq, enum scan_band *out_band);
|
||||
uint32_t scan_channel_to_freq(uint8_t channel, enum scan_band band);
|
||||
|
Loading…
Reference in New Issue
Block a user