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:
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 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);
|
|
||||||
|
|
||||||
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);
|
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);
|
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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
src/scan.c
26
src/scan.c
@ -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)
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user