]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Clean up configuration parsing
authorJouni Malinen <jouni@codeaurora.org>
Sat, 16 Mar 2019 10:19:10 +0000 (12:19 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 16 Mar 2019 15:29:59 +0000 (17:29 +0200)
Share a single parsing implementation for both hostapd and
wpa_supplicant to avoid code duplication. In addition, clean up the
implementation to be more easily extensible.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/dpp_hostapd.c
src/common/dpp.c
src/common/dpp.h
wpa_supplicant/dpp_supplicant.c

index 7184f7204c5281e816c3b81958a40891fb9a140d..0305283b6982627ada3aa4e354cc3145875e0e10 100644 (file)
@@ -519,171 +519,31 @@ static int hostapd_dpp_set_configurator(struct hostapd_data *hapd,
                                        struct dpp_authentication *auth,
                                        const char *cmd)
 {
-       const char *pos, *end;
-       struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
-       struct dpp_configurator *conf = NULL;
-       u8 ssid[32] = { "test" };
-       size_t ssid_len = 4;
-       char pass[64] = { };
-       size_t pass_len = 0;
-       u8 psk[PMK_LEN];
-       int psk_set = 0;
-       char *group_id = NULL;
+       const char *pos;
 
        if (!cmd)
                return 0;
 
        wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd);
-       pos = os_strstr(cmd, " ssid=");
-       if (pos) {
-               pos += 6;
-               end = os_strchr(pos, ' ');
-               ssid_len = end ? (size_t) (end - pos) : os_strlen(pos);
-               ssid_len /= 2;
-               if (ssid_len > sizeof(ssid) ||
-                   hexstr2bin(pos, ssid, ssid_len) < 0)
-                       goto fail;
-       }
-
-       pos = os_strstr(cmd, " pass=");
-       if (pos) {
-               pos += 6;
-               end = os_strchr(pos, ' ');
-               pass_len = end ? (size_t) (end - pos) : os_strlen(pos);
-               pass_len /= 2;
-               if (pass_len > sizeof(pass) - 1 || pass_len < 8 ||
-                   hexstr2bin(pos, (u8 *) pass, pass_len) < 0)
-                       goto fail;
-       }
-
-       pos = os_strstr(cmd, " psk=");
-       if (pos) {
-               pos += 5;
-               if (hexstr2bin(pos, psk, PMK_LEN) < 0)
-                       goto fail;
-               psk_set = 1;
-       }
-
-       pos = os_strstr(cmd, " group_id=");
-       if (pos) {
-               size_t group_id_len;
-
-               pos += 10;
-               end = os_strchr(pos, ' ');
-               group_id_len = end ? (size_t) (end - pos) : os_strlen(pos);
-               group_id = os_malloc(group_id_len + 1);
-               if (!group_id)
-                       goto fail;
-               os_memcpy(group_id, pos, group_id_len);
-               group_id[group_id_len] = '\0';
-       }
-
-       if (os_strstr(cmd, " conf=sta-")) {
-               conf_sta = os_zalloc(sizeof(struct dpp_configuration));
-               if (!conf_sta)
-                       goto fail;
-               os_memcpy(conf_sta->ssid, ssid, ssid_len);
-               conf_sta->ssid_len = ssid_len;
-               if (os_strstr(cmd, " conf=sta-psk") ||
-                   os_strstr(cmd, " conf=sta-sae") ||
-                   os_strstr(cmd, " conf=sta-psk-sae")) {
-                       if (os_strstr(cmd, " conf=sta-psk-sae"))
-                               conf_sta->akm = DPP_AKM_PSK_SAE;
-                       else if (os_strstr(cmd, " conf=sta-sae"))
-                               conf_sta->akm = DPP_AKM_SAE;
-                       else
-                               conf_sta->akm = DPP_AKM_PSK;
-                       if (psk_set) {
-                               os_memcpy(conf_sta->psk, psk, PMK_LEN);
-                       } else {
-                               conf_sta->passphrase = os_strdup(pass);
-                               if (!conf_sta->passphrase)
-                                       goto fail;
-                       }
-               } else if (os_strstr(cmd, " conf=sta-dpp")) {
-                       conf_sta->akm = DPP_AKM_DPP;
-               } else {
-                       goto fail;
-               }
-               if (os_strstr(cmd, " group_id=")) {
-                       conf_sta->group_id = group_id;
-                       group_id = NULL;
-               }
-       }
-
-       if (os_strstr(cmd, " conf=ap-")) {
-               conf_ap = os_zalloc(sizeof(struct dpp_configuration));
-               if (!conf_ap)
-                       goto fail;
-               os_memcpy(conf_ap->ssid, ssid, ssid_len);
-               conf_ap->ssid_len = ssid_len;
-               if (os_strstr(cmd, " conf=ap-psk") ||
-                   os_strstr(cmd, " conf=ap-sae") ||
-                   os_strstr(cmd, " conf=ap-psk-sae")) {
-                       if (os_strstr(cmd, " conf=ap-psk-sae"))
-                               conf_ap->akm = DPP_AKM_PSK_SAE;
-                       else if (os_strstr(cmd, " conf=ap-sae"))
-                               conf_ap->akm = DPP_AKM_SAE;
-                       else
-                               conf_ap->akm = DPP_AKM_PSK;
-                       if (psk_set) {
-                               os_memcpy(conf_ap->psk, psk, PMK_LEN);
-                       } else if (pass_len > 0) {
-                               conf_ap->passphrase = os_strdup(pass);
-                               if (!conf_ap->passphrase)
-                                       goto fail;
-                       } else {
-                               goto fail;
-                       }
-               } else if (os_strstr(cmd, " conf=ap-dpp")) {
-                       conf_ap->akm = DPP_AKM_DPP;
-               } else {
-                       goto fail;
-               }
-               if (os_strstr(cmd, " group_id=")) {
-                       conf_ap->group_id = group_id;
-                       group_id = NULL;
-               }
-       }
-
-       pos = os_strstr(cmd, " expiry=");
-       if (pos) {
-               long int val;
-
-               pos += 8;
-               val = strtol(pos, NULL, 0);
-               if (val <= 0)
-                       goto fail;
-               if (conf_sta)
-                       conf_sta->netaccesskey_expiry = val;
-               if (conf_ap)
-                       conf_ap->netaccesskey_expiry = val;
-       }
 
        pos = os_strstr(cmd, " configurator=");
        if (pos) {
                auth->configurator = 1;
                pos += 14;
-               conf = hostapd_dpp_configurator_get_id(hapd, atoi(pos));
-               if (!conf) {
+               auth->conf = hostapd_dpp_configurator_get_id(hapd, atoi(pos));
+               if (!auth->conf) {
                        wpa_printf(MSG_INFO,
                                   "DPP: Could not find the specified configurator");
-                       goto fail;
+                       return -1;
                }
        }
-       auth->conf_sta = conf_sta;
-       auth->conf_ap = conf_ap;
-       auth->conf = conf;
-       os_free(group_id);
-       return 0;
 
-fail:
-       wpa_msg(hapd->msg_ctx, MSG_INFO,
-               "DPP: Failed to set configurator parameters");
-       dpp_configuration_free(conf_sta);
-       dpp_configuration_free(conf_ap);
-       os_free(group_id);
-       return -1;
+       if (dpp_configuration_parse(auth, cmd) < 0) {
+               wpa_msg(hapd->msg_ctx, MSG_INFO,
+                       "DPP: Failed to set configurator parameters");
+               return -1;
+       }
+       return 0;
 }
 
 
index c7a200780395f8b5a096488b6eb1693497b33b77..fe097c5c4cc8eb891e27672bccc8254024740216 100644 (file)
@@ -4048,6 +4048,70 @@ fail:
 }
 
 
+static int bin_str_eq(const char *val, size_t len, const char *cmp)
+{
+       return os_strlen(cmp) == len && os_memcmp(val, cmp, len) == 0;
+}
+
+
+struct dpp_configuration * dpp_configuration_alloc(const char *type)
+{
+       struct dpp_configuration *conf;
+       const char *end;
+       size_t len;
+
+       conf = os_zalloc(sizeof(*conf));
+       if (!conf)
+               goto fail;
+
+       end = os_strchr(type, ' ');
+       if (end)
+               len = end - type;
+       else
+               len = os_strlen(type);
+
+       if (bin_str_eq(type, len, "psk"))
+               conf->akm = DPP_AKM_PSK;
+       else if (bin_str_eq(type, len, "sae"))
+               conf->akm = DPP_AKM_SAE;
+       else if (bin_str_eq(type, len, "psk-sae"))
+               conf->akm = DPP_AKM_PSK_SAE;
+       else if (bin_str_eq(type, len, "dpp"))
+               conf->akm = DPP_AKM_DPP;
+       else
+               goto fail;
+
+       return conf;
+fail:
+       dpp_configuration_free(conf);
+       return NULL;
+}
+
+
+static int dpp_akm_psk(enum dpp_akm akm)
+{
+       return akm == DPP_AKM_PSK || akm == DPP_AKM_PSK_SAE;
+}
+
+
+static int dpp_akm_sae(enum dpp_akm akm)
+{
+       return akm == DPP_AKM_SAE || akm == DPP_AKM_PSK_SAE;
+}
+
+
+int dpp_configuration_valid(const struct dpp_configuration *conf)
+{
+       if (conf->ssid_len == 0)
+               return 0;
+       if (dpp_akm_psk(conf->akm) && !conf->passphrase && !conf->psk_set)
+               return 0;
+       if (dpp_akm_sae(conf->akm) && !conf->passphrase)
+               return 0;
+       return 1;
+}
+
+
 void dpp_configuration_free(struct dpp_configuration *conf)
 {
        if (!conf)
@@ -4058,6 +4122,113 @@ void dpp_configuration_free(struct dpp_configuration *conf)
 }
 
 
+int dpp_configuration_parse(struct dpp_authentication *auth, const char *cmd)
+{
+       const char *pos, *end;
+       struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
+       struct dpp_configuration *conf = NULL;
+
+       pos = os_strstr(cmd, " conf=sta-");
+       if (pos) {
+               conf_sta = dpp_configuration_alloc(pos + 10);
+               if (!conf_sta)
+                       goto fail;
+               conf = conf_sta;
+       }
+
+       pos = os_strstr(cmd, " conf=ap-");
+       if (pos) {
+               conf_ap = dpp_configuration_alloc(pos + 9);
+               if (!conf_ap)
+                       goto fail;
+               conf = conf_ap;
+       }
+
+       if (!conf)
+               return 0;
+
+       pos = os_strstr(cmd, " ssid=");
+       if (pos) {
+               pos += 6;
+               end = os_strchr(pos, ' ');
+               conf->ssid_len = end ? (size_t) (end - pos) : os_strlen(pos);
+               conf->ssid_len /= 2;
+               if (conf->ssid_len > sizeof(conf->ssid) ||
+                   hexstr2bin(pos, conf->ssid, conf->ssid_len) < 0)
+                       goto fail;
+       } else {
+#ifdef CONFIG_TESTING_OPTIONS
+               /* use a default SSID for legacy testing reasons */
+               os_memcpy(conf->ssid, "test", 4);
+               conf->ssid_len = 4;
+#else /* CONFIG_TESTING_OPTIONS */
+               goto fail;
+#endif /* CONFIG_TESTING_OPTIONS */
+       }
+
+       pos = os_strstr(cmd, " pass=");
+       if (pos) {
+               size_t pass_len;
+
+               pos += 6;
+               end = os_strchr(pos, ' ');
+               pass_len = end ? (size_t) (end - pos) : os_strlen(pos);
+               pass_len /= 2;
+               if (pass_len > 63 || pass_len < 8)
+                       goto fail;
+               conf->passphrase = os_zalloc(pass_len + 1);
+               if (!conf->passphrase ||
+                   hexstr2bin(pos, (u8 *) conf->passphrase, pass_len) < 0)
+                       goto fail;
+       }
+
+       pos = os_strstr(cmd, " psk=");
+       if (pos) {
+               pos += 5;
+               if (hexstr2bin(pos, conf->psk, PMK_LEN) < 0)
+                       goto fail;
+               conf->psk_set = 1;
+       }
+
+       pos = os_strstr(cmd, " group_id=");
+       if (pos) {
+               size_t group_id_len;
+
+               pos += 10;
+               end = os_strchr(pos, ' ');
+               group_id_len = end ? (size_t) (end - pos) : os_strlen(pos);
+               conf->group_id = os_malloc(group_id_len + 1);
+               if (!conf->group_id)
+                       goto fail;
+               os_memcpy(conf->group_id, pos, group_id_len);
+               conf->group_id[group_id_len] = '\0';
+       }
+
+       pos = os_strstr(cmd, " expiry=");
+       if (pos) {
+               long int val;
+
+               pos += 8;
+               val = strtol(pos, NULL, 0);
+               if (val <= 0)
+                       goto fail;
+               conf->netaccesskey_expiry = val;
+       }
+
+       if (!dpp_configuration_valid(conf))
+               goto fail;
+
+       auth->conf_sta = conf_sta;
+       auth->conf_ap = conf_ap;
+       return 0;
+
+fail:
+       dpp_configuration_free(conf_sta);
+       dpp_configuration_free(conf_ap);
+       return -1;
+}
+
+
 void dpp_auth_deinit(struct dpp_authentication *auth)
 {
        if (!auth)
index fe4b7f3a29803bcb8a964a4931b69cc49c463c94..03eabef43c85263ed13780886e94d22ac02aef01 100644 (file)
@@ -163,6 +163,7 @@ struct dpp_configuration {
        /* For legacy configuration */
        char *passphrase;
        u8 psk[32];
+       int psk_set;
 };
 
 struct dpp_authentication {
@@ -392,7 +393,10 @@ int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
                     const u8 *attr_start, size_t attr_len);
 int dpp_notify_new_qr_code(struct dpp_authentication *auth,
                           struct dpp_bootstrap_info *peer_bi);
+struct dpp_configuration * dpp_configuration_alloc(const char *type);
+int dpp_configuration_valid(const struct dpp_configuration *conf);
 void dpp_configuration_free(struct dpp_configuration *conf);
+int dpp_configuration_parse(struct dpp_authentication *auth, const char *cmd);
 void dpp_auth_deinit(struct dpp_authentication *auth);
 struct wpabuf *
 dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
index 411bfff831d2eaa49e494a16fcf8424611b4f1bc..71ba667ad07ee1ff62700cf4d7b2af97acfe9850 100644 (file)
@@ -554,169 +554,30 @@ static int wpas_dpp_set_configurator(struct wpa_supplicant *wpa_s,
                                     struct dpp_authentication *auth,
                                     const char *cmd)
 {
-       const char *pos, *end;
-       struct dpp_configuration *conf_sta = NULL, *conf_ap = NULL;
-       struct dpp_configurator *conf = NULL;
-       u8 ssid[32] = { "test" };
-       size_t ssid_len = 4;
-       char pass[64] = { };
-       size_t pass_len = 0;
-       u8 psk[PMK_LEN];
-       int psk_set = 0;
-       char *group_id = NULL;
+       const char *pos;
 
        if (!cmd)
                return 0;
 
        wpa_printf(MSG_DEBUG, "DPP: Set configurator parameters: %s", cmd);
-       pos = os_strstr(cmd, " ssid=");
-       if (pos) {
-               pos += 6;
-               end = os_strchr(pos, ' ');
-               ssid_len = end ? (size_t) (end - pos) : os_strlen(pos);
-               ssid_len /= 2;
-               if (ssid_len > sizeof(ssid) ||
-                   hexstr2bin(pos, ssid, ssid_len) < 0)
-                       goto fail;
-       }
-
-       pos = os_strstr(cmd, " pass=");
-       if (pos) {
-               pos += 6;
-               end = os_strchr(pos, ' ');
-               pass_len = end ? (size_t) (end - pos) : os_strlen(pos);
-               pass_len /= 2;
-               if (pass_len > sizeof(pass) - 1 || pass_len < 8 ||
-                   hexstr2bin(pos, (u8 *) pass, pass_len) < 0)
-                       goto fail;
-       }
-
-       pos = os_strstr(cmd, " psk=");
-       if (pos) {
-               pos += 5;
-               if (hexstr2bin(pos, psk, PMK_LEN) < 0)
-                       goto fail;
-               psk_set = 1;
-       }
-
-       pos = os_strstr(cmd, " group_id=");
-       if (pos) {
-               size_t group_id_len;
-
-               pos += 10;
-               end = os_strchr(pos, ' ');
-               group_id_len = end ? (size_t) (end - pos) : os_strlen(pos);
-               group_id = os_malloc(group_id_len + 1);
-               if (!group_id)
-                       goto fail;
-               os_memcpy(group_id, pos, group_id_len);
-               group_id[group_id_len] = '\0';
-       }
-
-       if (os_strstr(cmd, " conf=sta-")) {
-               conf_sta = os_zalloc(sizeof(struct dpp_configuration));
-               if (!conf_sta)
-                       goto fail;
-               os_memcpy(conf_sta->ssid, ssid, ssid_len);
-               conf_sta->ssid_len = ssid_len;
-               if (os_strstr(cmd, " conf=sta-psk") ||
-                   os_strstr(cmd, " conf=sta-sae") ||
-                   os_strstr(cmd, " conf=sta-psk-sae")) {
-                       if (os_strstr(cmd, " conf=sta-psk-sae"))
-                               conf_sta->akm = DPP_AKM_PSK_SAE;
-                       else if (os_strstr(cmd, " conf=sta-sae"))
-                               conf_sta->akm = DPP_AKM_SAE;
-                       else
-                               conf_sta->akm = DPP_AKM_PSK;
-                       if (psk_set) {
-                               os_memcpy(conf_sta->psk, psk, PMK_LEN);
-                       } else if (pass_len > 0) {
-                               conf_sta->passphrase = os_strdup(pass);
-                               if (!conf_sta->passphrase)
-                                       goto fail;
-                       } else {
-                               goto fail;
-                       }
-               } else if (os_strstr(cmd, " conf=sta-dpp")) {
-                       conf_sta->akm = DPP_AKM_DPP;
-               } else {
-                       goto fail;
-               }
-               if (os_strstr(cmd, " group_id=")) {
-                       conf_sta->group_id = group_id;
-                       group_id = NULL;
-               }
-       }
-
-       if (os_strstr(cmd, " conf=ap-")) {
-               conf_ap = os_zalloc(sizeof(struct dpp_configuration));
-               if (!conf_ap)
-                       goto fail;
-               os_memcpy(conf_ap->ssid, ssid, ssid_len);
-               conf_ap->ssid_len = ssid_len;
-               if (os_strstr(cmd, " conf=ap-psk") ||
-                   os_strstr(cmd, " conf=ap-sae") ||
-                   os_strstr(cmd, " conf=ap-psk-sae")) {
-                       if (os_strstr(cmd, " conf=ap-psk-sae"))
-                               conf_ap->akm = DPP_AKM_PSK_SAE;
-                       else if (os_strstr(cmd, " conf=ap-sae"))
-                               conf_ap->akm = DPP_AKM_SAE;
-                       else
-                               conf_ap->akm = DPP_AKM_PSK;
-                       if (psk_set) {
-                               os_memcpy(conf_ap->psk, psk, PMK_LEN);
-                       } else {
-                               conf_ap->passphrase = os_strdup(pass);
-                               if (!conf_ap->passphrase)
-                                       goto fail;
-                       }
-               } else if (os_strstr(cmd, " conf=ap-dpp")) {
-                       conf_ap->akm = DPP_AKM_DPP;
-               } else {
-                       goto fail;
-               }
-               if (os_strstr(cmd, " group_id=")) {
-                       conf_ap->group_id = group_id;
-                       group_id = NULL;
-               }
-       }
-
-       pos = os_strstr(cmd, " expiry=");
-       if (pos) {
-               long int val;
-
-               pos += 8;
-               val = strtol(pos, NULL, 0);
-               if (val <= 0)
-                       goto fail;
-               if (conf_sta)
-                       conf_sta->netaccesskey_expiry = val;
-               if (conf_ap)
-                       conf_ap->netaccesskey_expiry = val;
-       }
 
        pos = os_strstr(cmd, " configurator=");
        if (pos) {
                pos += 14;
-               conf = dpp_configurator_get_id(wpa_s, atoi(pos));
-               if (!conf) {
+               auth->conf = dpp_configurator_get_id(wpa_s, atoi(pos));
+               if (!auth->conf) {
                        wpa_printf(MSG_INFO,
                                   "DPP: Could not find the specified configurator");
-                       goto fail;
+                       return -1;
                }
        }
-       auth->conf_sta = conf_sta;
-       auth->conf_ap = conf_ap;
-       auth->conf = conf;
-       os_free(group_id);
-       return 0;
 
-fail:
-       wpa_msg(wpa_s, MSG_INFO, "DPP: Failed to set configurator parameters");
-       dpp_configuration_free(conf_sta);
-       dpp_configuration_free(conf_ap);
-       os_free(group_id);
-       return -1;
+       if (dpp_configuration_parse(auth, cmd) < 0) {
+               wpa_msg(wpa_s, MSG_INFO,
+                       "DPP: Failed to set configurator parameters");
+               return -1;
+       }
+       return 0;
 }