RSN IBSS: Restart IBSS state machines for each new IBSS
Change the old design of running a single long living RSN IBSS instance to keep a separate instance for each IBSS connection. This fixes number of issues in getting keys set properly for new connections and is in general quite a bit more correct design.
This commit is contained in:
parent
21bdbe38be
commit
78177a000e
4 changed files with 32 additions and 47 deletions
|
@ -113,6 +113,11 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
int bssid_changed;
|
int bssid_changed;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IBSS_RSN
|
||||||
|
ibss_rsn_deinit(wpa_s->ibss_rsn);
|
||||||
|
wpa_s->ibss_rsn = NULL;
|
||||||
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
|
|
||||||
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
|
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1344,8 +1349,18 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
|
||||||
if (wpa_s->current_ssid &&
|
if (wpa_s->current_ssid &&
|
||||||
wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
|
wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
|
||||||
wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
|
wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
|
||||||
wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE)
|
wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE &&
|
||||||
ibss_rsn_connected(wpa_s->ibss_rsn);
|
wpa_s->ibss_rsn == NULL) {
|
||||||
|
wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
|
||||||
|
if (!wpa_s->ibss_rsn) {
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, "Failed to init IBSS RSN");
|
||||||
|
wpa_supplicant_deauthenticate(
|
||||||
|
wpa_s, WLAN_REASON_DEAUTH_LEAVING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ibss_rsn_set_psk(wpa_s->ibss_rsn, wpa_s->current_ssid->psk);
|
||||||
|
}
|
||||||
#endif /* CONFIG_IBSS_RSN */
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1554,7 +1569,8 @@ wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
|
||||||
l2_packet_deinit(wpa_s->l2);
|
l2_packet_deinit(wpa_s->l2);
|
||||||
wpa_s->l2 = NULL;
|
wpa_s->l2 = NULL;
|
||||||
#ifdef CONFIG_IBSS_RSN
|
#ifdef CONFIG_IBSS_RSN
|
||||||
ibss_rsn_stop(wpa_s->ibss_rsn, NULL);
|
ibss_rsn_deinit(wpa_s->ibss_rsn);
|
||||||
|
wpa_s->ibss_rsn = NULL;
|
||||||
#endif /* CONFIG_IBSS_RSN */
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
#ifdef CONFIG_TERMINATE_ONLASTIF
|
#ifdef CONFIG_TERMINATE_ONLASTIF
|
||||||
/* check if last interface */
|
/* check if last interface */
|
||||||
|
|
|
@ -285,15 +285,6 @@ static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibss_rsn->init_in_progress && key_len <=
|
|
||||||
sizeof(ibss_rsn->init_gtk)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "AUTH: Delay setting of initial TX GTK "
|
|
||||||
"until RSN IBSS is connected");
|
|
||||||
ibss_rsn->init_gtk_idx = idx;
|
|
||||||
os_memcpy(ibss_rsn->init_gtk, key, key_len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
|
return wpa_drv_set_key(ibss_rsn->wpa_s, alg, addr, idx,
|
||||||
1, seq, 6, key, key_len);
|
1, seq, 6, key, key_len);
|
||||||
}
|
}
|
||||||
|
@ -342,9 +333,7 @@ static int ibss_rsn_auth_init_group(struct ibss_rsn *ibss_rsn,
|
||||||
cb.set_key = auth_set_key;
|
cb.set_key = auth_set_key;
|
||||||
cb.for_each_sta = auth_for_each_sta;
|
cb.for_each_sta = auth_for_each_sta;
|
||||||
|
|
||||||
ibss_rsn->init_in_progress = 1;
|
|
||||||
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
|
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
|
||||||
ibss_rsn->init_in_progress = 0;
|
|
||||||
if (ibss_rsn->auth_group == NULL) {
|
if (ibss_rsn->auth_group == NULL) {
|
||||||
wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
|
wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -389,6 +378,9 @@ int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
|
||||||
{
|
{
|
||||||
struct ibss_rsn_peer *peer;
|
struct ibss_rsn_peer *peer;
|
||||||
|
|
||||||
|
if (ibss_rsn == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
for (peer = ibss_rsn->peers; peer; peer = peer->next) {
|
for (peer = ibss_rsn->peers; peer; peer = peer->next) {
|
||||||
if (os_memcmp(addr, peer->addr, ETH_ALEN) == 0) {
|
if (os_memcmp(addr, peer->addr, ETH_ALEN) == 0) {
|
||||||
wpa_printf(MSG_DEBUG, "RSN: IBSS Authenticator and "
|
wpa_printf(MSG_DEBUG, "RSN: IBSS Authenticator and "
|
||||||
|
@ -580,6 +572,9 @@ int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
|
||||||
{
|
{
|
||||||
struct ibss_rsn_peer *peer;
|
struct ibss_rsn_peer *peer;
|
||||||
|
|
||||||
|
if (ibss_rsn == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
for (peer = ibss_rsn->peers; peer; peer = peer->next) {
|
for (peer = ibss_rsn->peers; peer; peer = peer->next) {
|
||||||
if (os_memcmp(src_addr, peer->addr, ETH_ALEN) == 0)
|
if (os_memcmp(src_addr, peer->addr, ETH_ALEN) == 0)
|
||||||
return ibss_rsn_process_rx_eapol(ibss_rsn, peer,
|
return ibss_rsn_process_rx_eapol(ibss_rsn, peer,
|
||||||
|
@ -603,24 +598,7 @@ int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
|
||||||
|
|
||||||
void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk)
|
void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk)
|
||||||
{
|
{
|
||||||
|
if (ibss_rsn == NULL)
|
||||||
|
return;
|
||||||
os_memcpy(ibss_rsn->psk, psk, PMK_LEN);
|
os_memcpy(ibss_rsn->psk, psk, PMK_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ibss_rsn_connected(struct ibss_rsn *ibss_rsn)
|
|
||||||
{
|
|
||||||
u8 seq[6];
|
|
||||||
wpa_printf(MSG_DEBUG, "RSN: IBSS connected notification");
|
|
||||||
if (ibss_rsn->init_gtk_idx) {
|
|
||||||
wpa_printf(MSG_DEBUG, "RSN: Set initial IBSS TX GTK");
|
|
||||||
os_memset(seq, 0, sizeof(seq));
|
|
||||||
if (wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_CCMP,
|
|
||||||
broadcast_ether_addr,
|
|
||||||
ibss_rsn->init_gtk_idx,
|
|
||||||
1, seq, sizeof(seq), ibss_rsn->init_gtk,
|
|
||||||
16) < 0)
|
|
||||||
wpa_printf(MSG_INFO, "RSN: Failed to set IBSS TX GTK");
|
|
||||||
ibss_rsn->init_gtk_idx = 0;
|
|
||||||
os_memset(ibss_rsn->init_gtk, 0, sizeof(ibss_rsn->init_gtk));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -36,10 +36,6 @@ struct ibss_rsn {
|
||||||
struct wpa_authenticator *auth_group;
|
struct wpa_authenticator *auth_group;
|
||||||
struct ibss_rsn_peer *peers;
|
struct ibss_rsn_peer *peers;
|
||||||
u8 psk[PMK_LEN];
|
u8 psk[PMK_LEN];
|
||||||
|
|
||||||
int init_in_progress;
|
|
||||||
int init_gtk_idx;
|
|
||||||
u8 init_gtk[16];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,6 +46,5 @@ void ibss_rsn_stop(struct ibss_rsn *ibss_rsn, const u8 *peermac);
|
||||||
int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
|
int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr,
|
||||||
const u8 *buf, size_t len);
|
const u8 *buf, size_t len);
|
||||||
void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk);
|
void ibss_rsn_set_psk(struct ibss_rsn *ibss_rsn, const u8 *psk);
|
||||||
void ibss_rsn_connected(struct ibss_rsn *ibss_rsn);
|
|
||||||
|
|
||||||
#endif /* IBSS_RSN_H */
|
#endif /* IBSS_RSN_H */
|
||||||
|
|
|
@ -1077,6 +1077,11 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
|
||||||
int assoc_failed = 0;
|
int assoc_failed = 0;
|
||||||
struct wpa_ssid *old_ssid;
|
struct wpa_ssid *old_ssid;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IBSS_RSN
|
||||||
|
ibss_rsn_deinit(wpa_s->ibss_rsn);
|
||||||
|
wpa_s->ibss_rsn = NULL;
|
||||||
|
#endif /* CONFIG_IBSS_RSN */
|
||||||
|
|
||||||
if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
|
if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
|
||||||
ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
|
ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
|
||||||
#ifdef CONFIG_AP
|
#ifdef CONFIG_AP
|
||||||
|
@ -1387,7 +1392,6 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
|
||||||
} else if (ssid->mode == WPAS_MODE_IBSS &&
|
} else if (ssid->mode == WPAS_MODE_IBSS &&
|
||||||
wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
|
wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
|
||||||
wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
|
wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
|
||||||
ibss_rsn_set_psk(wpa_s->ibss_rsn, ssid->psk);
|
|
||||||
/*
|
/*
|
||||||
* RSN IBSS authentication is per-STA and we can disable the
|
* RSN IBSS authentication is per-STA and we can disable the
|
||||||
* per-BSSID authentication.
|
* per-BSSID authentication.
|
||||||
|
@ -2272,14 +2276,6 @@ next_driver:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_IBSS_RSN
|
|
||||||
wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
|
|
||||||
if (!wpa_s->ibss_rsn) {
|
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "Failed to init IBSS RSN");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_IBSS_RSN */
|
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
|
if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
|
||||||
wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
|
wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
|
||||||
|
|
Loading…
Reference in a new issue