]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SAE: Default password binding through control interface
authorJouni Malinen <jouni.malinen@oss.qualcomm.com>
Tue, 26 Aug 2025 09:37:12 +0000 (12:37 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 26 Aug 2025 09:39:32 +0000 (12:39 +0300)
Allow sae_track_password information to be configured through the
hostapd control interface to enable synchronization across BSSs.

Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
hostapd/ctrl_iface.c
src/ap/ieee802_11.c
src/ap/ieee802_11.h

index 45c498a349ea8f2adc71c4e22fca62fc5690814c..e6ea1dc3a6d295dc695c026ff0bed7a56b5a9e6f 100644 (file)
@@ -4070,6 +4070,25 @@ fail:
 #endif /* CONFIG_NAN_USD */
 
 
+#ifdef CONFIG_SAE
+static int hostapd_ctrl_iface_sae_password_bind(struct hostapd_data *hapd,
+                                               const char *cmd)
+{
+       u8 addr[ETH_ALEN];
+       const char *password;
+
+       if (hwaddr_aton(cmd, addr))
+               return -1;
+       password = os_strchr(cmd, ' ');
+       if (!password)
+               return -1;
+       password++;
+
+       return sae_password_bind(hapd, addr, password);
+}
+#endif /* CONFIG_SAE */
+
+
 static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                                              char *buf, char *reply,
                                              int reply_size,
@@ -4673,6 +4692,11 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                        reply_len = -1;
 #endif /* CONFIG_TESTING_OPTIONS */
 #endif /* CONFIG_IEEE80211BE */
+#ifdef CONFIG_SAE
+       } else if (os_strncmp(buf, "SAE_PASSWORD_BIND ", 18) == 0) {
+               if (hostapd_ctrl_iface_sae_password_bind(hapd, buf + 18))
+                       reply_len = -1;
+#endif /* CONFIG_SAE */
        } else {
                os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
                reply_len = 16;
index 9f27ba87c3f12e3c90caf4579d98a1c222f57695..f157c949291ca39be9054c3f666a583647ca0084 100644 (file)
@@ -560,6 +560,28 @@ static bool has_sae_success_seen(struct hostapd_data *hapd,
 }
 
 
+static int sae_password_mark_success(struct hostapd_data *hapd,
+                                     struct sae_password_entry *pw,
+                                     const u8 *addr)
+{
+       if (in_mac_addr_list(pw->success_mac, pw->num_success_mac, addr))
+               return 0;
+
+       if (!pw->success_mac) {
+               pw->success_mac = os_zalloc(hapd->conf->sae_track_password *
+                                           ETH_ALEN);
+               if (!pw->success_mac)
+                       return -1;
+               pw->num_success_mac = hapd->conf->sae_track_password;
+       }
+
+       os_memcpy(&pw->success_mac[pw->next_success_mac * ETH_ALEN], addr,
+                 ETH_ALEN);
+       pw->next_success_mac = (pw->next_success_mac + 1) % pw->num_success_mac;
+       return 0;
+}
+
+
 static void sae_password_track_success(struct hostapd_data *hapd,
                                       struct sta_info *sta)
 {
@@ -572,22 +594,7 @@ static void sae_password_track_success(struct hostapd_data *hapd,
        if (!pw)
                return;
 
-       if (in_mac_addr_list(pw->success_mac,
-                            pw->num_success_mac,
-                            sta->addr))
-               return;
-
-       if (!pw->success_mac) {
-               pw->success_mac = os_zalloc(hapd->conf->sae_track_password *
-                                           ETH_ALEN);
-               if (!pw->success_mac)
-                       return;
-               pw->num_success_mac = hapd->conf->sae_track_password;
-       }
-
-       os_memcpy(&pw->success_mac[pw->next_success_mac * ETH_ALEN], sta->addr,
-                 ETH_ALEN);
-       pw->next_success_mac = (pw->next_success_mac + 1) % pw->num_success_mac;
+       sae_password_mark_success(hapd, pw, sta->addr);
 }
 
 
@@ -624,6 +631,27 @@ static bool sae_password_track_fail(struct hostapd_data *hapd,
 }
 
 
+int sae_password_bind(struct hostapd_data *hapd, const u8 *addr,
+                     const char *password)
+{
+       struct sae_password_entry *pw;
+
+       if (!hapd->conf->sae_track_password)
+               return -1;
+
+       for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
+               if (pw->identifier ||
+                   !is_broadcast_ether_addr(pw->peer_addr) ||
+                   os_strcmp(password, pw->password) != 0)
+                       continue;
+
+               return sae_password_mark_success(hapd, pw, addr);
+       }
+
+       return -1;
+}
+
+
 const char * sae_get_password(struct hostapd_data *hapd,
                              struct sta_info *sta,
                              const char *rx_id,
index 31bc0249bffa3634477006a511bd066b55b1c24c..a2bd583beda335592e2406427cd930bba91a885e 100644 (file)
@@ -290,6 +290,8 @@ u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
                        const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid,
                        u8 *rnr_count, u8 **rnr_offset, size_t rnr_len);
 bool hostapd_is_multiple_link_mld(struct hostapd_data *hapd);
+int sae_password_bind(struct hostapd_data *hapd, const u8 *addr,
+                     const char *password);
 const char * sae_get_password(struct hostapd_data *hapd,
                              struct sta_info *sta, const char *rx_id,
                              struct sae_password_entry **pw_entry,