Browse Source

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.
Jouni Malinen 14 years ago
parent
commit
78177a000e
4 changed files with 32 additions and 47 deletions
  1. 19 3
      wpa_supplicant/events.c
  2. 8 30
      wpa_supplicant/ibss_rsn.c
  3. 0 5
      wpa_supplicant/ibss_rsn.h
  4. 5 9
      wpa_supplicant/wpa_supplicant.c

+ 19 - 3
wpa_supplicant/events.c

@@ -113,6 +113,11 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 {
 	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)
 		return;
 
@@ -1344,8 +1349,18 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 	if (wpa_s->current_ssid &&
 	    wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
 	    wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
-	    wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE)
-		ibss_rsn_connected(wpa_s->ibss_rsn);
+	    wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE &&
+	    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 */
 }
 
@@ -1554,7 +1569,8 @@ wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
 		l2_packet_deinit(wpa_s->l2);
 		wpa_s->l2 = NULL;
 #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 */
 #ifdef CONFIG_TERMINATE_ONLASTIF
 		/* check if last interface */

+ 8 - 30
wpa_supplicant/ibss_rsn.c

@@ -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,
 			       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.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->init_in_progress = 0;
 	if (ibss_rsn->auth_group == NULL) {
 		wpa_printf(MSG_DEBUG, "AUTH: wpa_init() failed");
 		return -1;
@@ -389,6 +378,9 @@ int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr)
 {
 	struct ibss_rsn_peer *peer;
 
+	if (ibss_rsn == NULL)
+		return -1;
+
 	for (peer = ibss_rsn->peers; peer; peer = peer->next) {
 		if (os_memcmp(addr, peer->addr, ETH_ALEN) == 0) {
 			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;
 
+	if (ibss_rsn == NULL)
+		return -1;
+
 	for (peer = ibss_rsn->peers; peer; peer = peer->next) {
 		if (os_memcmp(src_addr, peer->addr, ETH_ALEN) == 0)
 			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)
 {
+	if (ibss_rsn == NULL)
+		return;
 	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));
-	}
-}

+ 0 - 5
wpa_supplicant/ibss_rsn.h

@@ -36,10 +36,6 @@ struct ibss_rsn {
 	struct wpa_authenticator *auth_group;
 	struct ibss_rsn_peer *peers;
 	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,
 		      const u8 *buf, size_t len);
 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 */

+ 5 - 9
wpa_supplicant/wpa_supplicant.c

@@ -1077,6 +1077,11 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 	int assoc_failed = 0;
 	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 ||
 	    ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
 #ifdef CONFIG_AP
@@ -1387,7 +1392,6 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 	} else if (ssid->mode == WPAS_MODE_IBSS &&
 		   wpa_s->key_mgmt != WPA_KEY_MGMT_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
 		 * per-BSSID authentication.
@@ -2272,14 +2276,6 @@ next_driver:
 		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
 	if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
 		wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");