Allow PMF to be enabled by default

Previously, PMF (protected management frames, IEEE 802.11w) could be
enabled only with a per-network parameter (ieee80211w). The new global
parameter (pmf) can now be used to change the default behavior to be PMF
enabled (pmf=1) or required (pmf=2) for network blocks that do not
override this with the ieee80211w parameter.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2012-11-24 22:21:29 +02:00
parent 368b1957a6
commit 62d4980331
10 changed files with 61 additions and 13 deletions

View file

@ -286,8 +286,9 @@ enum wpa_states {
enum mfp_options {
NO_MGMT_FRAME_PROTECTION = 0,
MGMT_FRAME_PROTECTION_OPTIONAL = 1,
MGMT_FRAME_PROTECTION_REQUIRED = 2
MGMT_FRAME_PROTECTION_REQUIRED = 2,
};
#define MGMT_FRAME_PROTECTION_DEFAULT 3
/**
* enum hostapd_hw_mode - Hardware mode

View file

@ -2042,6 +2042,9 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
ssid->ampdu_density = DEFAULT_AMPDU_DENSITY;
#endif /* CONFIG_HT_OVERRIDES */
ssid->proactive_key_caching = -1;
#ifdef CONFIG_IEEE80211W
ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;
#endif /* CONFIG_IEEE80211W */
}
@ -3035,6 +3038,7 @@ static const struct global_parse_data global_fields[] = {
{ INT(p2p_go_max_inactivity), 0 },
{ INT_RANGE(auto_interworking, 0, 1), 0 },
{ INT(okc), 0 },
{ INT(pmf), 0 },
};
#undef FUNC

View file

@ -782,6 +782,15 @@ struct wpa_config {
* default behavior.
*/
int okc;
/**
* pmf - Whether to enable/require PMF by default
*
* By default, PMF is disabled unless enabled by the per-network
* ieee80211w=1 or ieee80211w=2 parameter. pmf=1/2 can be used to change
* this default behavior.
*/
enum mfp_options pmf;
};

View file

@ -680,7 +680,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
INT(disabled);
INT(peerkey);
#ifdef CONFIG_IEEE80211W
INT(ieee80211w);
write_int(f, "ieee80211w", ssid->ieee80211w,
MGMT_FRAME_PROTECTION_DEFAULT);
#endif /* CONFIG_IEEE80211W */
STR(id_str);
#ifdef CONFIG_P2P
@ -928,6 +929,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
config->auto_interworking);
if (config->okc)
fprintf(f, "okc=%d\n", config->okc);
if (config->pmf)
fprintf(f, "pmf=%d\n", config->pmf);
}
#endif /* CONFIG_NO_CONFIG_WRITE */

View file

@ -361,6 +361,12 @@ struct wpa_ssid {
*
* This value is used to configure policy for management frame
* protection (IEEE 802.11w). 0 = disabled, 1 = optional, 2 = required.
* This is disabled by default unless the default value has been changed
* with the global pmf=1/2 parameter.
*
* Internally, special value 3 is used to indicate that the parameter
* was not specified in the configuration (i.e., default behavior is
* followed).
*/
enum mfp_options ieee80211w;
#endif /* CONFIG_IEEE80211W */

View file

@ -202,6 +202,7 @@ static int wpa_config_read_global_os_version(struct wpa_config *config,
static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
{
int errors = 0;
int val;
wpa_config_read_reg_dword(hk, TEXT("ap_scan"), &config->ap_scan);
wpa_config_read_reg_dword(hk, TEXT("fast_reauth"),
@ -272,6 +273,8 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
(int *) &config->disassoc_low_ack);
wpa_config_read_reg_dword(hk, TEXT("okc"), &config->okc);
wpa_config_read_reg_dword(hk, TEXT("pmf"), &val);
config->pmf = val;
return errors ? -1 : 0;
}
@ -612,6 +615,7 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
config->disassoc_low_ack, 0);
wpa_config_write_reg_dword(hk, TEXT("okc"), config->okc, 0);
wpa_config_write_reg_dword(hk, TEXT("pmf"), config->pmf, 0);
return 0;
}
@ -913,7 +917,8 @@ static int wpa_config_write_network(HKEY hk, struct wpa_ssid *ssid, int id)
INT(disabled);
INT(peerkey);
#ifdef CONFIG_IEEE80211W
INT(ieee80211w);
write_int(netw, "ieee80211w", ssid->ieee80211w,
MGMT_FRAME_PROTECTION_DEFAULT);
#endif /* CONFIG_IEEE80211W */
STR(id_str);

View file

@ -426,7 +426,9 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_IEEE80211W
if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
(ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
wpa_s->conf->pmf : ssid->ieee80211w) ==
MGMT_FRAME_PROTECTION_REQUIRED) {
wpa_dbg(wpa_s, MSG_DEBUG, " skip RSN IE - no mgmt "
"frame protection");
break;

View file

@ -263,8 +263,9 @@ void sme_send_authentication(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_IEEE80211W
wpa_s->sme.mfp = ssid->ieee80211w;
if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
wpa_s->sme.mfp = ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
wpa_s->conf->pmf : ssid->ieee80211w;
if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) {
const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
struct wpa_ie_data _ie;
if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 &&
@ -1190,7 +1191,9 @@ void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
if (wpa_s->wpa_state != WPA_COMPLETED)
return;
ssid = wpa_s->current_ssid;
if (ssid == NULL || ssid->ieee80211w == 0)
if (ssid == NULL ||
(ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION)
return;
if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
return;

View file

@ -930,7 +930,9 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_IEEE80211W
if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
(ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
wpa_s->conf->pmf : ssid->ieee80211w) ==
MGMT_FRAME_PROTECTION_REQUIRED) {
wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
"that does not support management frame protection - "
"reject");
@ -1126,7 +1128,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_IEEE80211W
sel = ie.mgmt_group_cipher;
if (ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION ||
if ((ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION ||
!(ie.capabilities & WPA_CAPABILITY_MFPC))
sel = 0;
if (sel & WPA_CIPHER_AES_128_CMAC) {
@ -1139,7 +1142,9 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
}
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
wpa_s->mgmt_group_cipher);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, ssid->ieee80211w);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
(ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
wpa_s->conf->pmf : ssid->ieee80211w));
#endif /* CONFIG_IEEE80211W */
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
@ -1562,8 +1567,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
params.drop_unencrypted = use_crypt;
#ifdef CONFIG_IEEE80211W
params.mgmt_frame_protection = ssid->ieee80211w;
if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION && bss) {
params.mgmt_frame_protection =
ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
wpa_s->conf->pmf : ssid->ieee80211w;
if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
struct wpa_ie_data ie;
if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&

View file

@ -273,6 +273,14 @@ fast_reauth=1
# can be disabled with per-network proactive_key_caching=0 parameter.
#okc=0
# Protected Management Frames default
# This parameter can be used to set the default behavior for the ieee80211w
# parameter. By default, PMF is disabled unless enabled with the global pmf=1/2
# parameter or with the per-network ieee80211w=1/2 parameter. With pmf=1/2, PMF
# is enabled/required by default, but can be disabled with the per-network
# ieee80211w parameter.
#pmf=0
# Interworking (IEEE 802.11u)
# Enable Interworking
@ -497,7 +505,7 @@ fast_reauth=1
# If not set, this defaults to: WPA-PSK WPA-EAP
#
# ieee80211w: whether management frame protection is enabled
# 0 = disabled (default)
# 0 = disabled (default unless changed with the global pmf parameter)
# 1 = optional
# 2 = required
# The most common configuration options for this based on the PMF (protected