num++;
if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
num++;
+ if (hapd->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt))
+ num++;
if (num > 8) {
/* rest of the rates are encoded in Extended supported
* rates element */
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
}
+ if (hapd->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
+ count < 8) {
+ count++;
+ *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
+ }
+
return pos;
}
num++;
if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
num++;
+ if (hapd->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt))
+ num++;
if (num <= 8)
return eid;
num -= 8;
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
}
+ if (hapd->conf->sae_pwe == 1 &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt)) {
+ count++;
+ if (count > 8)
+ *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
+ }
+
return pos;
}
#endif /* CONFIG_NO_RC4 */
-static int send_auth_reply(struct hostapd_data *hapd,
+static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *dst, const u8 *bssid,
u16 auth_alg, u16 auth_transaction, u16 resp,
const u8 *ies, size_t ies_len, const char *dbg)
" auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
MAC2STR(dst), auth_alg, auth_transaction,
resp, (unsigned long) ies_len, dbg);
- if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0)
+#ifdef CONFIG_TESTING_OPTIONS
+#ifdef CONFIG_SAE
+ if (hapd->conf->sae_confirm_immediate == 2 &&
+ auth_alg == WLAN_AUTH_SAE) {
+ if (auth_transaction == 1 &&
+ (resp == WLAN_STATUS_SUCCESS ||
+ resp == WLAN_STATUS_SAE_HASH_TO_ELEMENT)) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: Postpone SAE Commit transmission until Confirm is ready");
+ os_free(sta->sae_postponed_commit);
+ sta->sae_postponed_commit = buf;
+ sta->sae_postponed_commit_len = rlen;
+ return WLAN_STATUS_SUCCESS;
+ }
+
+ if (auth_transaction == 2 && sta && sta->sae_postponed_commit) {
+ wpa_printf(MSG_DEBUG,
+ "TESTING: Send postponed SAE Commit first, immediately followed by SAE Confirm");
+ if (hostapd_drv_send_mlme(hapd,
+ sta->sae_postponed_commit,
+ sta->sae_postponed_commit_len,
+ 0, NULL, 0, 0) < 0)
+ wpa_printf(MSG_INFO, "send_auth_reply: send failed");
+ os_free(sta->sae_postponed_commit);
+ sta->sae_postponed_commit = NULL;
+ sta->sae_postponed_commit_len = 0;
+ }
+ }
+#endif /* CONFIG_SAE */
+#endif /* CONFIG_TESTING_OPTIONS */
+ if (hostapd_drv_send_mlme(hapd, reply, rlen, 0, NULL, 0, 0) < 0)
wpa_printf(MSG_INFO, "send_auth_reply: send failed");
else
reply_res = WLAN_STATUS_SUCCESS;
struct sta_info *sta;
int reply_res;
- reply_res = send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT,
+ reply_res = send_auth_reply(hapd, NULL, dst, bssid, WLAN_AUTH_FT,
auth_transaction, status, ies, ies_len,
"auth-ft-finish");
static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
- struct sta_info *sta, int update)
+ struct sta_info *sta, int update,
+ int status_code)
{
struct wpabuf *buf;
const char *password = NULL;
struct sae_password_entry *pw;
const char *rx_id = NULL;
+ int use_pt = 0;
+ struct sae_pt *pt = NULL;
- if (sta->sae->tmp)
+ if (sta->sae->tmp) {
rx_id = sta->sae->tmp->pw_id;
+ use_pt = sta->sae->tmp->h2e;
+ }
+
+ if (status_code == WLAN_STATUS_SUCCESS)
+ use_pt = 0;
+ else if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT)
+ use_pt = 1;
for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
if (!is_broadcast_ether_addr(pw->peer_addr) &&
os_strcmp(rx_id, pw->identifier) != 0)
continue;
password = pw->password;
+ pt = pw->pt;
break;
}
- if (!password)
- password = hapd->conf->ssid.wpa_passphrase;
if (!password) {
+ password = hapd->conf->ssid.wpa_passphrase;
+ pt = hapd->conf->ssid.pt;
+ }
+ if (!password || (use_pt && !pt)) {
wpa_printf(MSG_DEBUG, "SAE: No password available");
return NULL;
}
- if (update &&
+ if (update && use_pt &&
+ sae_prepare_commit_pt(sta->sae, pt, hapd->own_addr, sta->addr,
+ NULL) < 0)
+ return NULL;
+
+ if (update && !use_pt &&
sae_prepare_commit(hapd->own_addr, sta->addr,
(u8 *) password, os_strlen(password), rx_id,
sta->sae) < 0) {
static int auth_sae_send_commit(struct hostapd_data *hapd,
struct sta_info *sta,
- const u8 *bssid, int update)
+ const u8 *bssid, int update, int status_code)
{
struct wpabuf *data;
int reply_res;
+ u16 status;
- data = auth_build_sae_commit(hapd, sta, update);
+ data = auth_build_sae_commit(hapd, sta, update, status_code);
if (!data && sta->sae->tmp && sta->sae->tmp->pw_id)
return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
if (data == NULL)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
- reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 1,
- WLAN_STATUS_SUCCESS, wpabuf_head(data),
+ status = (sta->sae->tmp && sta->sae->tmp->h2e) ?
+ WLAN_STATUS_SAE_HASH_TO_ELEMENT : WLAN_STATUS_SUCCESS;
+ reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
+ WLAN_AUTH_SAE, 1,
+ status, wpabuf_head(data),
wpabuf_len(data), "sae-send-commit");
wpabuf_free(data);
if (data == NULL)
return WLAN_STATUS_UNSPECIFIED_FAILURE;
- reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 2,
+ reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
+ WLAN_AUTH_SAE, 2,
WLAN_STATUS_SUCCESS, wpabuf_head(data),
wpabuf_len(data), "sae-send-confirm");
switch (sta->sae->state) {
case SAE_COMMITTED:
- ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
+ ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0, -1);
eloop_register_timeout(0,
hapd->dot11RSNASAERetransPeriod * 1000,
auth_sae_retransmit_timer, hapd, sta);
static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
- const u8 *bssid, u8 auth_transaction, int allow_reuse,
- int *sta_removed)
+ const u8 *bssid, u16 auth_transaction, u16 status_code,
+ int allow_reuse, int *sta_removed)
{
int ret;
switch (sta->sae->state) {
case SAE_NOTHING:
if (auth_transaction == 1) {
+ if (sta->sae->tmp)
+ sta->sae->tmp->h2e = status_code ==
+ WLAN_STATUS_SAE_HASH_TO_ELEMENT;
ret = auth_sae_send_commit(hapd, sta, bssid,
- !allow_reuse);
+ !allow_reuse, status_code);
if (ret)
return ret;
sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
return WLAN_STATUS_UNSPECIFIED_FAILURE;
/*
- * In mesh case, both Commit and Confirm can be sent
- * immediately. In infrastructure BSS, only a single
- * Authentication frame (Commit) is expected from the AP
- * here and the second one (Confirm) will be sent once
- * the STA has sent its second Authentication frame
- * (Confirm).
+ * In mesh case, both Commit and Confirm are sent
+ * immediately. In infrastructure BSS, by default, only
+ * a single Authentication frame (Commit) is expected
+ * from the AP here and the second one (Confirm) will
+ * be sent once the STA has sent its second
+ * Authentication frame (Confirm). This behavior can be
+ * overridden with explicit configuration so that the
+ * infrastructure BSS case sends both frames together.
*/
- if (hapd->conf->mesh & MESH_ENABLED) {
+ if ((hapd->conf->mesh & MESH_ENABLED) ||
+ hapd->conf->sae_confirm_immediate) {
/*
* Send both Commit and Confirm immediately
* based on SAE finite state machine
return WLAN_STATUS_SUCCESS;
sta->sae->sync++;
- ret = auth_sae_send_commit(hapd, sta, bssid, 0);
+ ret = auth_sae_send_commit(hapd, sta, bssid, 0,
+ status_code);
if (ret)
return ret;
* additional events.
*/
return sae_sm_step(hapd, sta, bssid, auth_transaction,
- 0, sta_removed);
+ WLAN_STATUS_SUCCESS, 0, sta_removed);
}
break;
case SAE_CONFIRMED:
return WLAN_STATUS_SUCCESS;
sta->sae->sync++;
- ret = auth_sae_send_commit(hapd, sta, bssid, 1);
+ ret = auth_sae_send_commit(hapd, sta, bssid, 1,
+ status_code);
if (ret)
return ret;
*sta_removed = 1;
} else if (auth_transaction == 1) {
wpa_printf(MSG_DEBUG, "SAE: Start reauthentication");
- ret = auth_sae_send_commit(hapd, sta, bssid, 1);
+ ret = auth_sae_send_commit(hapd, sta, bssid, 1,
+ status_code);
if (ret)
return ret;
sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
}
+static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
+{
+ return (hapd->conf->sae_pwe == 0 &&
+ status_code == WLAN_STATUS_SUCCESS) ||
+ (hapd->conf->sae_pwe == 1 &&
+ status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) ||
+ (hapd->conf->sae_pwe == 2 &&
+ (status_code == WLAN_STATUS_SUCCESS ||
+ status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT));
+}
+
+
+static int sae_is_group_enabled(struct hostapd_data *hapd, int group)
+{
+ int *groups = hapd->conf->sae_groups;
+ int default_groups[] = { 19, 0 };
+ int i;
+
+ if (!groups)
+ groups = default_groups;
+
+ for (i = 0; groups[i] > 0; i++) {
+ if (groups[i] == group)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int check_sae_rejected_groups(struct hostapd_data *hapd,
+ const struct wpabuf *groups)
+{
+ size_t i, count;
+ const u8 *pos;
+
+ if (!groups)
+ return 0;
+
+ pos = wpabuf_head(groups);
+ count = wpabuf_len(groups) / 2;
+ for (i = 0; i < count; i++) {
+ int enabled;
+ u16 group;
+
+ group = WPA_GET_LE16(pos);
+ pos += 2;
+ enabled = sae_is_group_enabled(hapd, group);
+ wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s",
+ group, enabled ? "enabled" : "disabled");
+ if (enabled)
+ return 1;
+ }
+
+ return 0;
+}
+
+
static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
const struct ieee80211_mgmt *mgmt, size_t len,
u16 auth_transaction, u16 status_code)
wpa_printf(MSG_DEBUG, "SAE: TESTING - reflection attack");
pos = mgmt->u.auth.variable;
end = ((const u8 *) mgmt) + len;
- send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
+ send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
auth_transaction, resp, pos, end - pos,
"auth-sae-reflection-attack");
goto remove_sta;
if (hapd->conf->sae_commit_override && auth_transaction == 1) {
wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override");
- send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
+ send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
auth_transaction, resp,
wpabuf_head(hapd->conf->sae_commit_override),
wpabuf_len(hapd->conf->sae_commit_override),
#endif /* CONFIG_TESTING_OPTIONS */
if (!sta->sae) {
if (auth_transaction != 1 ||
- status_code != WLAN_STATUS_SUCCESS) {
- resp = -1;
- goto remove_sta;
+ !sae_status_success(hapd, status_code)) {
+ wpa_printf(MSG_DEBUG, "SAE: Unexpected Status Code %u",
+ status_code);
+ resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ goto reply;
}
sta->sae = os_zalloc(sizeof(*sta->sae));
if (!sta->sae) {
* Authentication frame, and the commit-scalar and
* COMMIT-ELEMENT previously sent.
*/
- resp = auth_sae_send_commit(hapd, sta, mgmt->bssid, 0);
+ resp = auth_sae_send_commit(hapd, sta, mgmt->bssid, 0,
+ status_code);
if (resp != WLAN_STATUS_SUCCESS) {
wpa_printf(MSG_ERROR,
"SAE: Failed to send commit message");
goto remove_sta;
}
- if (status_code != WLAN_STATUS_SUCCESS)
+ if (!sae_status_success(hapd, status_code))
goto remove_sta;
if (!(hapd->conf->mesh & MESH_ENABLED) &&
resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable,
((const u8 *) mgmt) + len -
mgmt->u.auth.variable, &token,
- &token_len, groups);
+ &token_len, groups, status_code ==
+ WLAN_STATUS_SAE_HASH_TO_ELEMENT);
if (resp == SAE_SILENTLY_DISCARD) {
wpa_printf(MSG_DEBUG,
"SAE: Drop commit message from " MACSTR " due to reflection attack",
if (resp != WLAN_STATUS_SUCCESS)
goto reply;
+ if (sta->sae->tmp &&
+ check_sae_rejected_groups(
+ hapd, sta->sae->tmp->peer_rejected_groups)) {
+ resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ goto reply;
+ }
+
if (!token && use_sae_anti_clogging(hapd) && !allow_reuse) {
wpa_printf(MSG_DEBUG,
"SAE: Request anti-clogging token from "
}
resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction,
- allow_reuse, &sta_removed);
+ status_code, allow_reuse, &sta_removed);
} else if (auth_transaction == 2) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
}
sta->sae->rc = peer_send_confirm;
}
- resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction, 0,
- &sta_removed);
+ resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction,
+ status_code, 0, &sta_removed);
} else {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
data = wpabuf_alloc_copy(pos, 2);
sae_sme_send_external_auth_status(hapd, sta, resp);
- send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
+ send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
auth_transaction, resp,
data ? wpabuf_head(data) : (u8 *) "",
data ? wpabuf_len(data) : 0, "auth-sae");
if (sta->sae->state != SAE_NOTHING)
return -1;
- ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
+ ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0, -1);
if (ret)
return -1;
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
hapd->iface->freq,
elems.rsn_ie - 2, elems.rsn_ie_len + 2,
+ elems.rsnxe ? elems.rsnxe - 2 : NULL,
+ elems.rsnxe ? elems.rsnxe_len + 2 : 0,
elems.mdie, elems.mdie_len, NULL, 0);
resp = wpa_res_to_status_code(res);
if (resp != WLAN_STATUS_SUCCESS)
auth_alg = (pub ||
resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) ?
WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
- send_auth_reply(hapd, sta->addr, hapd->own_addr, auth_alg, 2, resp,
+ send_auth_reply(hapd, sta, sta->addr, hapd->own_addr, auth_alg, 2, resp,
data ? wpabuf_head(data) : (u8 *) "",
data ? wpabuf_len(data) : 0, "auth-fils-finish");
wpabuf_free(data);
#endif /* CONFIG_FILS */
-int
-ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
- const u8 *msg, size_t len, u32 *session_timeout,
- u32 *acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui, int is_probe_req)
+static int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
+ const u8 *msg, size_t len,
+ struct radius_sta *info)
{
int res;
- os_memset(vlan_id, 0, sizeof(*vlan_id));
- res = hostapd_allowed_address(hapd, addr, msg, len,
- session_timeout, acct_interim_interval,
- vlan_id, psk, identity, radius_cui,
- is_probe_req);
+ res = hostapd_allowed_address(hapd, addr, msg, len, info, 0);
if (res == HOSTAPD_ACL_REJECT) {
- if (!is_probe_req)
- wpa_printf(MSG_DEBUG,
- "Station " MACSTR
- " not allowed to authenticate",
- MAC2STR(addr));
+ wpa_printf(MSG_DEBUG, "Station " MACSTR
+ " not allowed to authenticate",
+ MAC2STR(addr));
return HOSTAPD_ACL_REJECT;
}
static int
ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
- int res, u32 session_timeout,
- u32 acct_interim_interval,
- struct vlan_description *vlan_id,
- struct hostapd_sta_wpa_psk_short **psk,
- char **identity, char **radius_cui)
+ int res, struct radius_sta *info)
{
+ u32 session_timeout = info->session_timeout;
+ u32 acct_interim_interval = info->acct_interim_interval;
+ struct vlan_description *vlan_id = &info->vlan_id;
+ struct hostapd_sta_wpa_psk_short *psk = info->psk;
+ char *identity = info->identity;
+ char *radius_cui = info->radius_cui;
+
if (vlan_id->notempty &&
!hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
hostapd_free_psk_list(sta->psk);
- if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
- sta->psk = *psk;
- *psk = NULL;
- } else {
+ if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED)
+ hostapd_copy_psk_list(&sta->psk, psk);
+ else
sta->psk = NULL;
- }
os_free(sta->identity);
- sta->identity = *identity;
- *identity = NULL;
+ if (identity)
+ sta->identity = os_strdup(identity);
+ else
+ sta->identity = NULL;
os_free(sta->radius_cui);
- sta->radius_cui = *radius_cui;
- *radius_cui = NULL;
+ if (radius_cui)
+ sta->radius_cui = os_strdup(radius_cui);
+ else
+ sta->radius_cui = NULL;
if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
sta->acct_interim_interval = acct_interim_interval;
int res, reply_res;
u16 fc;
const u8 *challenge = NULL;
- u32 session_timeout, acct_interim_interval;
- struct vlan_description vlan_id;
- struct hostapd_sta_wpa_psk_short *psk = NULL;
u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
size_t resp_ies_len = 0;
- char *identity = NULL;
- char *radius_cui = NULL;
u16 seq_ctrl;
+ struct radius_sta rad_info;
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
}
}
- res = ieee802_11_allowed_address(
- hapd, mgmt->sa, (const u8 *) mgmt, len, &session_timeout,
- &acct_interim_interval, &vlan_id, &psk, &identity, &radius_cui,
- 0);
+ res = ieee802_11_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
+ &rad_info);
if (res == HOSTAPD_ACL_REJECT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Ignore Authentication frame from " MACSTR
sta->auth_rssi = rssi;
#endif /* CONFIG_MBO */
- res = ieee802_11_set_radius_info(
- hapd, sta, res, session_timeout, acct_interim_interval,
- &vlan_id, &psk, &identity, &radius_cui);
+ res = ieee802_11_set_radius_info(hapd, sta, res, &rad_info);
if (res) {
wpa_printf(MSG_DEBUG, "ieee802_11_set_radius_info() failed");
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
}
fail:
- os_free(identity);
- os_free(radius_cui);
- hostapd_free_psk_list(psk);
-
- reply_res = send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
+ reply_res = send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, auth_alg,
auth_transaction + 1, resp, resp_ies,
resp_ies_len, "handle-auth");
rsn_ie_len += 2;
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
hapd->iface->freq, rsn_ie, rsn_ie_len,
- NULL, 0, owe_dh, owe_dh_len);
+ NULL, 0, NULL, 0, owe_dh, owe_dh_len);
status = wpa_res_to_status_code(res);
if (status != WLAN_STATUS_SUCCESS)
goto end;
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
hapd->iface->freq,
wpa_ie, wpa_ie_len,
+ elems.rsnxe ? elems.rsnxe - 2 : NULL,
+ elems.rsnxe ? elems.rsnxe_len + 2 : 0,
elems.mdie, elems.mdie_len,
elems.owe_dh, elems.owe_dh_len);
resp = wpa_res_to_status_code(res);
MAC2STR(sta->addr), sta->auth_alg);
return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
}
+
+ if (hapd->conf->sae_pwe == 2 &&
+ sta->auth_alg == WLAN_AUTH_SAE &&
+ sta->sae && sta->sae->tmp && !sta->sae->tmp->h2e &&
+ elems.rsnxe && elems.rsnxe_len >= 1 &&
+ (elems.rsnxe[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
+ wpa_printf(MSG_INFO, "SAE: " MACSTR
+ " indicates support for SAE H2E, but did not use it",
+ MAC2STR(sta->addr));
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ }
#endif /* CONFIG_SAE */
#ifdef CONFIG_OWE
send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
reply.u.deauth.reason_code = host_to_le16(reason_code);
- if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0)
+ if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0, NULL, 0, 0) < 0)
wpa_printf(MSG_INFO, "Failed to send deauth: %s",
strerror(errno));
}
#endif /* CONFIG_IEEE80211N */
#ifdef CONFIG_IEEE80211AC
- if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
+ if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
+ !is_6ghz_op_class(hapd->iconf->op_class)) {
u32 nsts = 0, sta_nsts;
if (sta && hapd->conf->use_sta_nsts && sta->vht_capabilities) {
}
#endif /* CONFIG_FST */
+ p = hostapd_eid_rsnxe(hapd, p, buf + buflen - p);
+
#ifdef CONFIG_OWE
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
sta && sta->owe_ecdh && status_code == WLAN_STATUS_SUCCESS &&
}
#endif /* CONFIG_FILS */
- if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) {
+ if (hostapd_drv_send_mlme(hapd, reply, send_len, 0, NULL, 0, 0) < 0) {
wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
strerror(errno));
res = WLAN_STATUS_UNSPECIFIED_FAILURE;
int left, i;
struct sta_info *sta;
u8 *tmp = NULL;
- struct hostapd_sta_wpa_psk_short *psk = NULL;
- char *identity = NULL;
- char *radius_cui = NULL;
#ifdef CONFIG_FILS
int delay_assoc = 0;
#endif /* CONFIG_FILS */
hapd->iface->current_mode->mode ==
HOSTAPD_MODE_IEEE80211AD) {
int acl_res;
- u32 session_timeout, acct_interim_interval;
- struct vlan_description vlan_id;
+ struct radius_sta info;
- acl_res = ieee802_11_allowed_address(
- hapd, mgmt->sa, (const u8 *) mgmt, len,
- &session_timeout, &acct_interim_interval,
- &vlan_id, &psk, &identity, &radius_cui, 0);
+ acl_res = ieee802_11_allowed_address(hapd, mgmt->sa,
+ (const u8 *) mgmt,
+ len, &info);
if (acl_res == HOSTAPD_ACL_REJECT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Ignore Association Request frame from "
}
acl_res = ieee802_11_set_radius_info(
- hapd, sta, acl_res, session_timeout,
- acct_interim_interval, &vlan_id, &psk,
- &identity, &radius_cui);
+ hapd, sta, acl_res, &info);
if (acl_res) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
#endif /* CONFIG_FILS */
fail:
- os_free(identity);
- os_free(radius_cui);
- hostapd_free_psk_list(psk);
/*
* In case of a successful response, add the station to the driver.
os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
resp->u.action.category |= 0x80;
- if (hostapd_drv_send_mlme(hapd, resp, len, 0) < 0) {
+ if (hostapd_drv_send_mlme(hapd, resp, len, 0, NULL, 0, 0) < 0) {
wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send "
"Action frame");
}
fc = le_to_host16(mgmt->frame_control);
stype = WLAN_FC_GET_STYPE(fc);
+ if (is_multicast_ether_addr(mgmt->sa) ||
+ is_zero_ether_addr(mgmt->sa) ||
+ os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
+ /* Do not process any frames with unexpected/invalid SA so that
+ * we do not add any state for unexpected STA addresses or end
+ * up sending out frames to unexpected destination. */
+ wpa_printf(MSG_DEBUG, "MGMT: Invalid SA=" MACSTR
+ " in received frame - ignore this frame silently",
+ MAC2STR(mgmt->sa));
+ return 0;
+ }
+
if (stype == WLAN_FC_STYPE_BEACON) {
handle_beacon(hapd, mgmt, len, fi);
return 1;
for (i = 0; i < 4; i++) {
if (ssid->wep.key[i] &&
hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
- i == ssid->wep.idx, NULL, 0,
- ssid->wep.key[i], ssid->wep.len[i])) {
+ 0, i == ssid->wep.idx, NULL, 0,
+ ssid->wep.key[i], ssid->wep.len[i],
+ i == ssid->wep.idx ?
+ KEY_FLAG_GROUP_RX_TX_DEFAULT :
+ KEY_FLAG_GROUP_RX_TX)) {
wpa_printf(MSG_WARNING,
"Could not set WEP keys for WDS interface; %s",
ifname_wds);
wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
MACSTR, MAC2STR(src));
- if (is_multicast_ether_addr(src)) {
- /* Broadcast bit set in SA?! Ignore the frame silently. */
+ if (is_multicast_ether_addr(src) || is_zero_ether_addr(src) ||
+ os_memcmp(src, hapd->own_addr, ETH_ALEN) == 0) {
+ /* Broadcast bit set in SA or unexpected SA?! Ignore the frame
+ * silently. */
return;
}