Browse Source

FILS: Mark connection fully authorized after FILS Association (AP)

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Jouni Malinen 9 years ago
parent
commit
07e0117d21
3 changed files with 20 additions and 3 deletions
  1. 7 3
      src/ap/ieee802_11.c
  2. 12 0
      src/ap/wpa_auth.c
  3. 1 0
      src/ap/wpa_auth_i.h

+ 7 - 3
src/ap/ieee802_11.c

@@ -3203,11 +3203,15 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
 		new_assoc = 0;
 	sta->flags |= WLAN_STA_ASSOC;
 	sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
-	if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) ||
+	if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
+	     !hapd->conf->osen) ||
+	    sta->auth_alg == WLAN_AUTH_FILS_SK ||
+	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
+	    sta->auth_alg == WLAN_AUTH_FILS_PK ||
 	    sta->auth_alg == WLAN_AUTH_FT) {
 		/*
-		 * Open, static WEP, or FT protocol; no separate authorization
-		 * step.
+		 * Open, static WEP, FT protocol, or FILS; no separate
+		 * authorization step.
 		 */
 		ap_sta_set_authorized(hapd, sta, 1);
 	}

+ 12 - 0
src/ap/wpa_auth.c

@@ -617,6 +617,16 @@ int wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
 	}
 #endif /* CONFIG_IEEE80211R */
 
+#ifdef CONFIG_FILS
+	if (sm->fils_completed) {
+		wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
+				"FILS authentication already completed - do not start 4-way handshake");
+		/* Go to PTKINITDONE state to allow GTK rekeying */
+		sm->wpa_ptk_state = WPA_PTK_PTKINITDONE;
+		return 0;
+	}
+#endif /* CONFIG_FILS */
+
 	if (sm->started) {
 		os_memset(&sm->key_replay, 0, sizeof(sm->key_replay));
 		sm->ReAuthenticationRequest = TRUE;
@@ -2380,6 +2390,8 @@ int fils_encrypt_assoc(struct wpa_state_machine *sm, u8 *buf,
 	current_len += wpabuf_len(plain) + AES_BLOCK_SIZE;
 	wpabuf_free(plain);
 
+	sm->fils_completed = 1;
+
 	return current_len;
 }
 

+ 1 - 0
src/ap/wpa_auth_i.h

@@ -143,6 +143,7 @@ struct wpa_state_machine {
 	u8 fils_key_auth_sta[FILS_MAX_KEY_AUTH_LEN];
 	u8 fils_key_auth_ap[FILS_MAX_KEY_AUTH_LEN];
 	size_t fils_key_auth_len;
+	unsigned int fils_completed:1;
 #endif /* CONFIG_FILS */
 };