wpa_supplicant: Correct IE validation when beacons don't have any
diff mbox series

Message ID 20191222224206.181415-1-alexander@wetzel-home.de
State Superseded
Headers show
Series
  • wpa_supplicant: Correct IE validation when beacons don't have any
Related show

Commit Message

Alexander Wetzel Dec. 22, 2019, 10:42 p.m. UTC
Report an IE mismatch when beacons don't have a WPA or RSN IE but the
eapol 3/4 of the handshake has.

Also fix OWE connections from accidentally cleaning the AP IE variables
- due to calling wpa_supplicant_set_suites() without the optional bss scan
result - and incorrectly triggering the stricter IE check.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
---

This is the promised alternative patch for "wpa_supplicant:
Don't incorrectly clear ie scan data".

I gave it a full test run of the hostapd unit tests on top of bf97c1a34
without any new failures. I think the checks are the correct thing to do
but the risk of breaking some connections where some AP's are exploiting
the current loophole is of course much higher than for the first patch.

 src/rsn_supp/wpa.c              | 37 ++++++++++++++++++---------------
 wpa_supplicant/wpa_supplicant.c |  2 +-
 2 files changed, 21 insertions(+), 18 deletions(-)

Patch
diff mbox series

diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 504feaf2a..b9f71de98 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -1331,12 +1331,26 @@  static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
 		}
 	}
 
-	if (ie->wpa_ie == NULL && ie->rsn_ie == NULL &&
-	    (sm->ap_wpa_ie || sm->ap_rsn_ie)) {
-		wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not match "
-				       "with IE in Beacon/ProbeResp (no IE?)",
-				       src_addr, ie->wpa_ie, ie->wpa_ie_len,
-				       ie->rsn_ie, ie->rsn_ie_len);
+	if ((ie->rsn_ie && !sm->ap_rsn_ie) || (ie->wpa_ie && !sm->ap_wpa_ie) ||
+	    (!ie->wpa_ie && !ie->rsn_ie && (sm->ap_wpa_ie || sm->ap_rsn_ie)) ||
+	    ((!sm->ap_wpa_ie && !sm->ap_rsn_ie) &&
+	     (ie->wpa_ie || ie->rsn_ie))) {
+		if (sm->proto == WPA_PROTO_WPA && sm->rsn_enabled &&
+		    ie->rsn_ie && !sm->ap_rsn_ie)
+			wpa_report_ie_mismatch(sm, "Possible downgrade attack "
+					       "detected - RSN was enabled and "
+					       "RSN IE was in msg 3/4, but not "
+					       "in Beacon/ProbeResp",
+					       src_addr, ie->wpa_ie,
+					       ie->wpa_ie_len, ie->rsn_ie,
+					       ie->rsn_ie_len);
+		else
+			wpa_report_ie_mismatch(sm, "IE in 3/4 msg does not "
+					       "match with IE in "
+					       "Beacon/ProbeResp (no IE?)",
+					       src_addr, ie->wpa_ie,
+					       ie->wpa_ie_len, ie->rsn_ie,
+					       ie->rsn_ie_len);
 		return -1;
 	}
 
@@ -1354,17 +1368,6 @@  static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
 		return -1;
 	}
 
-	if (sm->proto == WPA_PROTO_WPA &&
-	    ie->rsn_ie && sm->ap_rsn_ie == NULL && sm->rsn_enabled) {
-		wpa_report_ie_mismatch(sm, "Possible downgrade attack "
-				       "detected - RSN was enabled and RSN IE "
-				       "was in msg 3/4, but not in "
-				       "Beacon/ProbeResp",
-				       src_addr, ie->wpa_ie, ie->wpa_ie_len,
-				       ie->rsn_ie, ie->rsn_ie_len);
-		return -1;
-	}
-
 	if ((sm->ap_rsnxe && !ie->rsnxe) ||
 	    (!sm->ap_rsnxe && ie->rsnxe) ||
 	    (sm->ap_rsnxe && ie->rsnxe &&
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 195ff74b0..44aaa0ad8 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1378,7 +1378,7 @@  int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
 			 !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
 
-	if (bss || !wpa_s->ap_ies_from_associnfo) {
+	if (bss && !wpa_s->ap_ies_from_associnfo) {
 		if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
 					 bss_wpa ? 2 + bss_wpa[1] : 0) ||
 		    wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,