SAE: Centralize function for sending initial COMMIT
When performing SAE authentication in mesh, one station may initiate authentication by sending a COMMIT as soon as a peer candidate is discovered. Previously we did this in mesh_rsn.c, but this left some of the state initialization in a different part of the code from the rest of the state machine, and we may need to add other initializations here in the future, so move that to a more central function. Signed-off-by: Bob Copeland <me@bobcopeland.com>
This commit is contained in:
parent
28c91ee124
commit
a206e2a175
3 changed files with 48 additions and 74 deletions
|
@ -755,6 +755,37 @@ reply:
|
||||||
}
|
}
|
||||||
wpabuf_free(data);
|
wpabuf_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* auth_sae_init_committed - Send COMMIT and start SAE in committed state
|
||||||
|
* @hapd: BSS data for the device initiating the authentication
|
||||||
|
* @sta: the peer to which commit authentication frame is sent
|
||||||
|
*
|
||||||
|
* This function implements Init event handling (IEEE Std 802.11-2012,
|
||||||
|
* 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
|
||||||
|
* sta->sae structure should be initialized appropriately via a call to
|
||||||
|
* sae_prepare_commit().
|
||||||
|
*/
|
||||||
|
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!sta->sae || !sta->sae->tmp)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (sta->sae->state != SAE_NOTHING)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sta->sae->state = SAE_COMMITTED;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,4 +89,6 @@ int hostapd_update_time_adv(struct hostapd_data *hapd);
|
||||||
void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
|
void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
|
||||||
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
|
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
|
||||||
|
|
||||||
|
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
|
||||||
|
|
||||||
#endif /* IEEE802_11_H */
|
#endif /* IEEE802_11_H */
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "ap/hostapd.h"
|
#include "ap/hostapd.h"
|
||||||
#include "ap/wpa_auth.h"
|
#include "ap/wpa_auth.h"
|
||||||
#include "ap/sta_info.h"
|
#include "ap/sta_info.h"
|
||||||
|
#include "ap/ieee802_11.h"
|
||||||
#include "wpa_supplicant_i.h"
|
#include "wpa_supplicant_i.h"
|
||||||
#include "driver_i.h"
|
#include "driver_i.h"
|
||||||
#include "wpas_glue.h"
|
#include "wpas_glue.h"
|
||||||
|
@ -245,80 +246,23 @@ static int mesh_rsn_sae_group(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wpabuf *
|
static int mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
|
||||||
mesh_rsn_build_sae_commit(struct wpa_supplicant *wpa_s,
|
struct wpa_ssid *ssid,
|
||||||
struct wpa_ssid *ssid, struct sta_info *sta)
|
struct sta_info *sta)
|
||||||
{
|
{
|
||||||
struct wpabuf *buf;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if (ssid->passphrase == NULL) {
|
if (ssid->passphrase == NULL) {
|
||||||
wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available");
|
wpa_msg(wpa_s, MSG_DEBUG, "SAE: No password available");
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh_rsn_sae_group(wpa_s, sta->sae) < 0) {
|
if (mesh_rsn_sae_group(wpa_s, sta->sae) < 0) {
|
||||||
wpa_msg(wpa_s, MSG_DEBUG, "SAE: Failed to select group");
|
wpa_msg(wpa_s, MSG_DEBUG, "SAE: Failed to select group");
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sae_prepare_commit(wpa_s->own_addr, sta->addr,
|
return sae_prepare_commit(wpa_s->own_addr, sta->addr,
|
||||||
(u8 *) ssid->passphrase,
|
(u8 *) ssid->passphrase,
|
||||||
os_strlen(ssid->passphrase), sta->sae) < 0) {
|
os_strlen(ssid->passphrase), sta->sae);
|
||||||
wpa_msg(wpa_s, MSG_DEBUG, "SAE: Could not pick PWE");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = wpa_s->mesh_rsn->sae_token ?
|
|
||||||
wpabuf_len(wpa_s->mesh_rsn->sae_token) : 0;
|
|
||||||
buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
|
|
||||||
if (buf == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
sae_write_commit(sta->sae, buf, wpa_s->mesh_rsn->sae_token);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void mesh_rsn_send_auth(struct wpa_supplicant *wpa_s,
|
|
||||||
const u8 *dst, const u8 *src,
|
|
||||||
u16 auth_transaction, u16 resp,
|
|
||||||
struct wpabuf *data)
|
|
||||||
{
|
|
||||||
struct ieee80211_mgmt *auth;
|
|
||||||
u8 *buf;
|
|
||||||
size_t len, ielen = 0;
|
|
||||||
|
|
||||||
if (data)
|
|
||||||
ielen = wpabuf_len(data);
|
|
||||||
len = IEEE80211_HDRLEN + sizeof(auth->u.auth) + ielen;
|
|
||||||
buf = os_zalloc(len);
|
|
||||||
if (buf == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auth = (struct ieee80211_mgmt *) buf;
|
|
||||||
auth->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
|
||||||
WLAN_FC_STYPE_AUTH);
|
|
||||||
os_memcpy(auth->da, dst, ETH_ALEN);
|
|
||||||
os_memcpy(auth->sa, src, ETH_ALEN);
|
|
||||||
os_memcpy(auth->bssid, src, ETH_ALEN);
|
|
||||||
|
|
||||||
auth->u.auth.auth_alg = host_to_le16(WLAN_AUTH_SAE);
|
|
||||||
auth->u.auth.auth_transaction = host_to_le16(auth_transaction);
|
|
||||||
auth->u.auth.status_code = host_to_le16(resp);
|
|
||||||
|
|
||||||
if (data)
|
|
||||||
os_memcpy(auth->u.auth.variable, wpabuf_head(data), ielen);
|
|
||||||
|
|
||||||
wpa_msg(wpa_s, MSG_DEBUG, "authentication frame: STA=" MACSTR
|
|
||||||
" auth_transaction=%d resp=%d (IE len=%lu)",
|
|
||||||
MAC2STR(dst), auth_transaction, resp, (unsigned long) ielen);
|
|
||||||
if (wpa_drv_send_mlme(wpa_s, buf, len, 0) < 0)
|
|
||||||
wpa_printf(MSG_INFO, "send_auth_reply: send_mlme failed: %s",
|
|
||||||
strerror(errno));
|
|
||||||
|
|
||||||
os_free(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,9 +270,10 @@ static void mesh_rsn_send_auth(struct wpa_supplicant *wpa_s,
|
||||||
int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
|
int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
|
||||||
struct sta_info *sta)
|
struct sta_info *sta)
|
||||||
{
|
{
|
||||||
|
struct hostapd_data *hapd = wpa_s->ifmsh->bss[0];
|
||||||
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||||
struct wpabuf *buf;
|
|
||||||
unsigned int rnd;
|
unsigned int rnd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!ssid) {
|
if (!ssid) {
|
||||||
wpa_msg(wpa_s, MSG_DEBUG,
|
wpa_msg(wpa_s, MSG_DEBUG,
|
||||||
|
@ -342,25 +287,21 @@ int mesh_rsn_auth_sae_sta(struct wpa_supplicant *wpa_s,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = mesh_rsn_build_sae_commit(wpa_s, ssid, sta);
|
if (mesh_rsn_build_sae_commit(wpa_s, ssid, sta))
|
||||||
if (!buf)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
wpa_msg(wpa_s, MSG_DEBUG,
|
wpa_msg(wpa_s, MSG_DEBUG,
|
||||||
"AUTH: started authentication with SAE peer: " MACSTR,
|
"AUTH: started authentication with SAE peer: " MACSTR,
|
||||||
MAC2STR(sta->addr));
|
MAC2STR(sta->addr));
|
||||||
|
|
||||||
sta->sae->state = SAE_COMMITTED;
|
|
||||||
wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
|
wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
|
||||||
|
ret = auth_sae_init_committed(hapd, sta);
|
||||||
mesh_rsn_send_auth(wpa_s, sta->addr, wpa_s->own_addr,
|
if (ret)
|
||||||
1, WLAN_STATUS_SUCCESS, buf);
|
return ret;
|
||||||
|
|
||||||
rnd = rand() % MESH_AUTH_TIMEOUT;
|
rnd = rand() % MESH_AUTH_TIMEOUT;
|
||||||
eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
|
eloop_register_timeout(MESH_AUTH_TIMEOUT + rnd, 0, mesh_auth_timer,
|
||||||
wpa_s, sta);
|
wpa_s, sta);
|
||||||
wpabuf_free(buf);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue