mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 13:02:44 +01:00
ap: add profile settings PairwiseCiphers/GroupCipher
These can now be optionally provided in an AP profile and provide a way to limit what ciphers can be chosen. This still is dependent on what the hardware supports.
This commit is contained in:
parent
5f84a78638
commit
262685e818
89
src/ap.c
89
src/ap.c
@ -3132,12 +3132,38 @@ static bool ap_load_psk(struct ap_state *ap, const struct l_settings *config)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: only PTK/GTK ciphers are supported here since this is all these are
|
||||||
|
* used for.
|
||||||
|
*/
|
||||||
|
static enum ie_rsn_cipher_suite ap_string_to_cipher(const char *str)
|
||||||
|
{
|
||||||
|
if (!strcmp(str, "UseGroupCipher"))
|
||||||
|
return IE_RSN_CIPHER_SUITE_USE_GROUP_CIPHER;
|
||||||
|
else if (!strcmp(str, "TKIP"))
|
||||||
|
return IE_RSN_CIPHER_SUITE_TKIP;
|
||||||
|
else if (!strcmp(str, "CCMP-128") || !strcmp(str, "CCMP"))
|
||||||
|
return IE_RSN_CIPHER_SUITE_CCMP;
|
||||||
|
else if (!strcmp(str, "GCMP-128") || !strcmp(str, "GCMP"))
|
||||||
|
return IE_RSN_CIPHER_SUITE_GCMP;
|
||||||
|
else if (!strcmp(str, "GCMP-256"))
|
||||||
|
return IE_RSN_CIPHER_SUITE_GCMP_256;
|
||||||
|
else if (!strcmp(str, "CCMP-256"))
|
||||||
|
return IE_RSN_CIPHER_SUITE_CCMP_256;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
|
static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
|
||||||
bool *out_cck_rates)
|
bool *out_cck_rates)
|
||||||
{
|
{
|
||||||
|
struct wiphy *wiphy = netdev_get_wiphy(ap->netdev);
|
||||||
size_t len;
|
size_t len;
|
||||||
L_AUTO_FREE_VAR(char *, strval) = NULL;
|
L_AUTO_FREE_VAR(char *, strval) = NULL;
|
||||||
|
_auto_(l_strv_free) char **ciphers_str = NULL;
|
||||||
|
uint16_t cipher_mask;
|
||||||
int err;
|
int err;
|
||||||
|
int i;
|
||||||
|
|
||||||
strval = l_settings_get_string(config, "General", "SSID");
|
strval = l_settings_get_string(config, "General", "SSID");
|
||||||
if (L_WARN_ON(!strval))
|
if (L_WARN_ON(!strval))
|
||||||
@ -3212,6 +3238,8 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
|
|||||||
l_error("AP [WSC].PrimaryDeviceType format unknown");
|
l_error("AP [WSC].PrimaryDeviceType format unknown");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l_free(l_steal_ptr(strval));
|
||||||
} else {
|
} else {
|
||||||
/* Make ourselves a WFA standard PC by default */
|
/* Make ourselves a WFA standard PC by default */
|
||||||
ap->wsc_primary_device_type.category = 1;
|
ap->wsc_primary_device_type.category = 1;
|
||||||
@ -3260,6 +3288,61 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
|
|||||||
} else
|
} else
|
||||||
*out_cck_rates = true;
|
*out_cck_rates = true;
|
||||||
|
|
||||||
|
cipher_mask = wiphy_get_supported_ciphers(wiphy, IE_GROUP_CIPHERS);
|
||||||
|
|
||||||
|
/* If the config sets a group cipher use that directly */
|
||||||
|
strval = l_settings_get_string(config, "Security", "GroupCipher");
|
||||||
|
if (strval) {
|
||||||
|
enum ie_rsn_cipher_suite cipher = ap_string_to_cipher(strval);
|
||||||
|
|
||||||
|
if (!cipher || !(cipher & cipher_mask)) {
|
||||||
|
l_error("Unsupported or unknown group cipher %s",
|
||||||
|
strval);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
ap->group_cipher = cipher;
|
||||||
|
l_free(l_steal_ptr(strval));
|
||||||
|
} else {
|
||||||
|
/* No config override, use CCMP (or TKIP if not supported) */
|
||||||
|
if (cipher_mask & IE_RSN_CIPHER_SUITE_CCMP)
|
||||||
|
ap->group_cipher = IE_RSN_CIPHER_SUITE_CCMP;
|
||||||
|
else
|
||||||
|
ap->group_cipher = IE_RSN_CIPHER_SUITE_TKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
cipher_mask = wiphy_get_supported_ciphers(wiphy, IE_PAIRWISE_CIPHERS);
|
||||||
|
|
||||||
|
ciphers_str = l_settings_get_string_list(config, "Security",
|
||||||
|
"PairwiseCiphers", ',');
|
||||||
|
for (i = 0; ciphers_str && ciphers_str[i]; i++) {
|
||||||
|
enum ie_rsn_cipher_suite cipher =
|
||||||
|
ap_string_to_cipher(ciphers_str[i]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constrain list to only values in both supported ciphers and
|
||||||
|
* the cipher list provided.
|
||||||
|
*/
|
||||||
|
if (!cipher || !(cipher & cipher_mask)) {
|
||||||
|
l_error("Unsupported or unknown pairwise cipher %s",
|
||||||
|
ciphers_str[i]);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
ap->ciphers |= cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ap->ciphers) {
|
||||||
|
/*
|
||||||
|
* Default behavior if no ciphers are specified, disable TKIP
|
||||||
|
* for security if CCMP is available
|
||||||
|
*/
|
||||||
|
if (cipher_mask & IE_RSN_CIPHER_SUITE_CCMP)
|
||||||
|
cipher_mask &= ~IE_RSN_CIPHER_SUITE_TKIP;
|
||||||
|
|
||||||
|
ap->ciphers = cipher_mask;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3302,12 +3385,6 @@ struct ap_state *ap_start(struct netdev *netdev, struct l_settings *config,
|
|||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
|
||||||
/* TODO: Add all ciphers supported by wiphy */
|
|
||||||
ap->ciphers = wiphy_select_cipher(wiphy, IE_RSN_CIPHER_SUITE_TKIP |
|
|
||||||
IE_RSN_CIPHER_SUITE_CCMP);
|
|
||||||
ap->group_cipher = wiphy_select_cipher(wiphy,
|
|
||||||
IE_RSN_CIPHER_SUITE_TKIP |
|
|
||||||
IE_RSN_CIPHER_SUITE_CCMP);
|
|
||||||
ap->beacon_interval = 100;
|
ap->beacon_interval = 100;
|
||||||
ap->networks = l_queue_new();
|
ap->networks = l_queue_new();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user