3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-26 02:19:26 +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:
Denis Kenzior 2016-10-24 22:12:25 -05:00
parent bdd676a23a
commit 318d3a2d35
4 changed files with 41 additions and 65 deletions

View File

@ -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) {

View File

@ -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;
}

View File

@ -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)

View File

@ -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);