3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-29 13:59:24 +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 timespec *timestamp)
{ {
struct network *network; struct network *network;
struct ie_rsn_info info;
int r;
enum security security; enum security security;
const char *path; const char *path;
double rankmod; double rankmod;
@ -240,41 +242,20 @@ static void process_bss(struct device *device, struct scan_bss *bss,
memcpy(ssid, bss->ssid, bss->ssid_len); memcpy(ssid, bss->ssid, bss->ssid_len);
ssid[bss->ssid_len] = '\0'; ssid[bss->ssid_len] = '\0';
/* memset(&info, 0, sizeof(info));
* If both an RSN and a WPA elements are present currently r = scan_bss_get_rsn_info(bss, &info);
* RSN takes priority and the WPA IE is ignored. if (r < 0) {
*/ if (r != -ENOENT)
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));
return; return;
}
security = scan_get_security(bss->capability, &rsne); security = scan_get_security(bss->capability, NULL);
} else
security = scan_get_security(bss->capability, &info);
if (security == SECURITY_PSK) if (security == SECURITY_PSK)
bss->sha256 = bss->sha256 = info.akm_suites & IE_RSN_AKM_SUITE_PSK_SHA256;
rsne.akm_suites & IE_RSN_AKM_SUITE_PSK_SHA256;
else if (security == SECURITY_8021X) else if (security == SECURITY_8021X)
bss->sha256 = bss->sha256 = info.akm_suites & IE_RSN_AKM_SUITE_8021X_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);
path = iwd_network_get_path(device, ssid, security); 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; struct eapol_sm *sm = NULL;
if (security == SECURITY_PSK || security == SECURITY_8021X) { if (security == SECURITY_PSK || security == SECURITY_8021X) {
uint16_t pairwise_ciphers, group_ciphers; struct ie_rsn_info bss_info;
uint8_t rsne_buf[256]; uint8_t rsne_buf[256];
struct ie_rsn_info info; 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 : bss->sha256 ? IE_RSN_AKM_SUITE_8021X_SHA256 :
IE_RSN_AKM_SUITE_8021X; IE_RSN_AKM_SUITE_8021X;
bss_get_supported_ciphers(bss, memset(&bss_info, 0, sizeof(bss_info));
&pairwise_ciphers, &group_ciphers); scan_bss_get_rsn_info(bss, &bss_info);
info.pairwise_ciphers = wiphy_select_cipher(wiphy, info.pairwise_ciphers = wiphy_select_cipher(wiphy,
pairwise_ciphers); bss_info.pairwise_ciphers);
info.group_cipher = wiphy_select_cipher(wiphy, group_ciphers); info.group_cipher = wiphy_select_cipher(wiphy,
bss_info.group_cipher);
/* RSN takes priority */ /* RSN takes priority */
if (bss->rsne) { if (bss->rsne) {

View File

@ -378,15 +378,15 @@ int network_autoconnect(struct network *network, struct scan_bss *bss)
break; break;
case SECURITY_PSK: case SECURITY_PSK:
{ {
uint16_t pairwise_ciphers, group_ciphers; struct ie_rsn_info rsn;
const char *psk; const char *psk;
size_t len; size_t len;
bss_get_supported_ciphers(bss, memset(&rsn, 0, sizeof(rsn));
&pairwise_ciphers, &group_ciphers); 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)) { !wiphy_select_cipher(wiphy, rsn.group_cipher)) {
l_debug("Cipher mis-match"); l_debug("Cipher mis-match");
return -ENETUNREACH; 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; 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;
uint16_t pairwise_ciphers, group_ciphers; struct ie_rsn_info rsn;
bss_get_supported_ciphers(bss, &pairwise_ciphers, memset(&rsn, 0, sizeof(rsn));
&group_ciphers); 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, wiphy_select_cipher(wiphy,
group_ciphers)) rsn.group_cipher))
return bss; return bss;
} }

View File

@ -794,36 +794,32 @@ void scan_bss_free(struct scan_bss *bss)
l_free(bss); l_free(bss);
} }
void bss_get_supported_ciphers(struct scan_bss *bss, int scan_bss_get_rsn_info(struct scan_bss *bss, struct ie_rsn_info *info)
uint16_t *pairwise_ciphers,
uint16_t *group_ciphers)
{ {
struct ie_rsn_info ie; /*
* If both an RSN and a WPA elements are present currently
*pairwise_ciphers = 0; * RSN takes priority and the WPA IE is ignored.
*group_ciphers = 0; */
if (bss->rsne) { if (bss->rsne) {
int res = ie_parse_rsne_from_data(bss->rsne, bss->rsne[1] + 2, int res = ie_parse_rsne_from_data(bss->rsne, bss->rsne[1] + 2,
&ie); info);
if (res < 0) { if (res < 0) {
l_debug("Cannot parse RSN field (%d, %s)", l_debug("Cannot parse RSN field (%d, %s)",
res, strerror(-res)); res, strerror(-res));
return; return res;
} }
} else if (bss->wpa) { } else if (bss->wpa) {
int res = ie_parse_wpa_from_data(bss->wpa, bss->wpa[1] + 2, int res = ie_parse_wpa_from_data(bss->wpa, bss->wpa[1] + 2,
&ie); info);
if (res < 0) { if (res < 0) {
l_debug("Cannot parse WPA IE (%d, %s)", l_debug("Cannot parse WPA IE (%d, %s)",
res, strerror(-res)); res, strerror(-res));
return; return res;
} }
} else } else
return; return -ENOENT;
*pairwise_ciphers = ie.pairwise_ciphers; return 0;
*group_ciphers = ie.group_cipher;
} }
int scan_bss_rank_compare(const void *a, const void *b, void *user_data) 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); void scan_bss_free(struct scan_bss *bss);
int scan_bss_rank_compare(const void *a, const void *b, void *user); int scan_bss_rank_compare(const void *a, const void *b, void *user);
void bss_get_supported_ciphers(struct scan_bss *bss, int scan_bss_get_rsn_info(struct scan_bss *bss, struct ie_rsn_info *info);
uint16_t *pairwise_ciphers,
uint16_t *group_ciphers);
uint8_t scan_freq_to_channel(uint32_t freq, enum scan_band *out_band); 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); uint32_t scan_channel_to_freq(uint8_t channel, enum scan_band band);