]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Work around an interop connection issue in FT-PSK + WPA-PSK
authorJanusz Dziedzic <janusz@plumewifi.com>
Mon, 5 Mar 2018 14:37:10 +0000 (15:37 +0100)
committerJouni Malinen <j@w1.fi>
Sun, 6 Jan 2019 19:10:08 +0000 (21:10 +0200)
While the AP is configured to enable both FT-PSK and WPA-PSK, an HP
printer request both AKMs (copied from AP?) in Association Request
frame, but don't add MDIE and don't use FT. This results in the
connection failing.

Next in logs we see:

RSN: Trying to use FT, but MDIE not included
IE - hexdump(len=26): 30 18 01 00 00 0f ac 04 01 00 00 0f ac 04
                      02 00 00 0f ac 02 00 0f ac 04 00 00

This is seen with some HP and Epson printers. Work around this by
stripping FT AKM(s) when MDE is not present and there is still a non-FT
AKM available.

Signed-off-by: Janusz Dziedzic <janusz@plumewifi.com>
src/ap/wpa_auth_ie.c
src/common/defs.h

index 92c70da817945f000bda4cd1e8d65f40ca77ccc4..3bcbef793ce41f5999d9642cbdee70ab766b4f4e 100644 (file)
@@ -561,6 +561,19 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
        if (version == WPA_PROTO_RSN) {
                res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);
 
+               if (wpa_key_mgmt_ft(data.key_mgmt) && !mdie &&
+                   !wpa_key_mgmt_only_ft(data.key_mgmt)) {
+                       /* Workaround for some HP and Epson printers that seem
+                        * to incorrectly copy the FT-PSK + WPA-PSK AKMs from AP
+                        * advertised RSNE to Association Request frame. */
+                       wpa_printf(MSG_DEBUG,
+                                  "RSN: FT set in RSNE AKM but MDE is missing from "
+                                  MACSTR
+                                  " - ignore FT AKM(s) because there's also a non-FT AKM",
+                                  MAC2STR(sm->addr));
+                       data.key_mgmt &= ~WPA_KEY_MGMT_FT;
+               }
+
                selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
                if (0) {
                }
index c968cd6cb82a5e46e20356821eb364714022e1d7..c54f57005ccb03d84a54310ce5a369a5bb9680be 100644 (file)
@@ -59,6 +59,13 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
 #define WPA_KEY_MGMT_DPP BIT(23)
 #define WPA_KEY_MGMT_FT_IEEE8021X_SHA384 BIT(24)
 
+#define WPA_KEY_MGMT_FT (WPA_KEY_MGMT_FT_PSK | \
+                        WPA_KEY_MGMT_FT_IEEE8021X | \
+                        WPA_KEY_MGMT_FT_IEEE8021X_SHA384 | \
+                        WPA_KEY_MGMT_FT_SAE | \
+                        WPA_KEY_MGMT_FT_FILS_SHA256 | \
+                        WPA_KEY_MGMT_FT_FILS_SHA384)
+
 static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
 {
        return !!(akm & (WPA_KEY_MGMT_IEEE8021X |
@@ -86,12 +93,14 @@ static inline int wpa_key_mgmt_wpa_psk(int akm)
 
 static inline int wpa_key_mgmt_ft(int akm)
 {
-       return !!(akm & (WPA_KEY_MGMT_FT_PSK |
-                        WPA_KEY_MGMT_FT_IEEE8021X |
-                        WPA_KEY_MGMT_FT_IEEE8021X_SHA384 |
-                        WPA_KEY_MGMT_FT_SAE |
-                        WPA_KEY_MGMT_FT_FILS_SHA256 |
-                        WPA_KEY_MGMT_FT_FILS_SHA384));
+       return !!(akm & WPA_KEY_MGMT_FT);
+}
+
+static inline int wpa_key_mgmt_only_ft(int akm)
+{
+       int ft = wpa_key_mgmt_ft(akm);
+       akm &= ~WPA_KEY_MGMT_FT;
+       return ft && !akm;
 }
 
 static inline int wpa_key_mgmt_ft_psk(int akm)