]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Allow PMKSA cache entries to be added through hostapd ctrl_iface
authorJouni Malinen <jouni@qca.qualcomm.com>
Sun, 18 Jun 2017 11:14:18 +0000 (14:14 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 19 Jun 2017 18:13:17 +0000 (21:13 +0300)
This allows external programs to generate and add PMKSA cache entries
into hostapd. The main use for this is to run external DPP processing
(network introduction) and testing.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
hostapd/ctrl_iface.c
src/ap/ctrl_iface_ap.c
src/ap/ctrl_iface_ap.h
src/ap/wpa_auth.c
src/ap/wpa_auth.h

index 4f49b5c4f2b219ce85a5d55dcfc8b0399ef3d8d8..42c6500c1fc06365a37a9ac23cd085cf99f43751 100644 (file)
@@ -2629,6 +2629,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
                                                          reply_size);
        } else if (os_strcmp(buf, "PMKSA_FLUSH") == 0) {
                hostapd_ctrl_iface_pmksa_flush(hapd);
+       } else if (os_strncmp(buf, "PMKSA_ADD ", 10) == 0) {
+               if (hostapd_ctrl_iface_pmksa_add(hapd, buf + 10) < 0)
+                       reply_len = -1;
        } else if (os_strncmp(buf, "SET_NEIGHBOR ", 13) == 0) {
                if (hostapd_ctrl_iface_set_neighbor(hapd, buf + 13))
                        reply_len = -1;
index a760e3a009278a163af37f0c48e8e57400f15f3f..6356e17c38998423b454c06aef6969af2fda8dfe 100644 (file)
@@ -641,6 +641,54 @@ void hostapd_ctrl_iface_pmksa_flush(struct hostapd_data *hapd)
 }
 
 
+int hostapd_ctrl_iface_pmksa_add(struct hostapd_data *hapd, char *cmd)
+{
+       u8 spa[ETH_ALEN];
+       u8 pmkid[PMKID_LEN];
+       u8 pmk[PMK_LEN_MAX];
+       size_t pmk_len;
+       char *pos, *pos2;
+       int akmp = 0, expiration = 0;
+
+       /*
+        * Entry format:
+        * <STA addr> <PMKID> <PMK> <expiration in seconds> <akmp>
+        */
+
+       if (hwaddr_aton(cmd, spa))
+               return -1;
+
+       pos = os_strchr(cmd, ' ');
+       if (!pos)
+               return -1;
+       pos++;
+
+       if (hexstr2bin(pos, pmkid, PMKID_LEN) < 0)
+               return -1;
+
+       pos = os_strchr(pos, ' ');
+       if (!pos)
+               return -1;
+       pos++;
+
+       pos2 = os_strchr(pos, ' ');
+       if (!pos2)
+               return -1;
+       pmk_len = (pos2 - pos) / 2;
+       if (pmk_len < PMK_LEN || pmk_len > PMK_LEN_MAX ||
+           hexstr2bin(pos, pmk, pmk_len) < 0)
+               return -1;
+
+       pos = pos2 + 1;
+
+       if (sscanf(pos, "%d %d", &expiration, &akmp) != 2)
+               return -1;
+
+       return wpa_auth_pmksa_add2(hapd->wpa_auth, spa, pmk, pmk_len,
+                                  pmkid, expiration, akmp);
+}
+
+
 #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
 #ifdef CONFIG_MESH
 
index 3b61cac35c3de526b7c1dc684e533b705c158987..d1dcebfb957df1e839030d2fc1aadbbf749d19e9 100644 (file)
@@ -32,6 +32,7 @@ int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd);
 int hostapd_ctrl_iface_pmksa_list(struct hostapd_data *hapd, char *buf,
                                  size_t len);
 void hostapd_ctrl_iface_pmksa_flush(struct hostapd_data *hapd);
+int hostapd_ctrl_iface_pmksa_add(struct hostapd_data *hapd, char *cmd);
 int hostapd_ctrl_iface_pmksa_list_mesh(struct hostapd_data *hapd,
                                       const u8 *addr, char *buf, size_t len);
 void * hostapd_ctrl_iface_pmksa_create_entry(const u8 *aa, char *cmd);
index 07da33ffc2287583350f5959ce81d98afcb3d8b4..bb86a92c4ce9673c604ee1b305629e4065b8d50c 100644 (file)
@@ -4010,6 +4010,22 @@ int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr,
 }
 
 
+int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr,
+                       const u8 *pmk, size_t pmk_len, const u8 *pmkid,
+                       int session_timeout, int akmp)
+{
+       if (wpa_auth->conf.disable_pmksa_caching)
+               return -1;
+
+       if (pmksa_cache_auth_add(wpa_auth->pmksa, pmk, pmk_len, pmkid,
+                                NULL, 0, wpa_auth->addr, addr, session_timeout,
+                                NULL, akmp))
+               return 0;
+
+       return -1;
+}
+
+
 void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth,
                           const u8 *sta_addr)
 {
index 7d6e015942d2cdec1d4d20cd9bcfb73e730b0d05..3b69789a1ea1a9933b8dd88b415e4dddd31cda7d 100644 (file)
@@ -329,6 +329,9 @@ int wpa_auth_pmksa_add_preauth(struct wpa_authenticator *wpa_auth,
                               struct eapol_state_machine *eapol);
 int wpa_auth_pmksa_add_sae(struct wpa_authenticator *wpa_auth, const u8 *addr,
                           const u8 *pmk, const u8 *pmkid);
+int wpa_auth_pmksa_add2(struct wpa_authenticator *wpa_auth, const u8 *addr,
+                       const u8 *pmk, size_t pmk_len, const u8 *pmkid,
+                       int session_timeout, int akmp);
 void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth,
                           const u8 *sta_addr);
 int wpa_auth_pmksa_list(struct wpa_authenticator *wpa_auth, char *buf,