hostapd: Fix internal crypto build without TLS
[wpasupplicant] / wpa_supplicant / config_file.c
index 11f2e3a..29e494c 100644 (file)
@@ -270,161 +270,97 @@ static int wpa_config_process_blob(struct wpa_config *config, FILE *f,
 #endif /* CONFIG_NO_CONFIG_BLOBS */
 
 
-static int wpa_config_process_country(struct wpa_config *config, char *pos)
-{
-       if (!pos[0] || !pos[1]) {
-               wpa_printf(MSG_DEBUG, "Invalid country set");
+struct global_parse_data {
+       char *name;
+       int (*parser)(const struct global_parse_data *data,
+                     struct wpa_config *config, int line, const char *value);
+       void *param1, *param2, *param3;
+};
+
+
+static int wpa_config_parse_int(const struct global_parse_data *data,
+                               struct wpa_config *config, int line,
+                               const char *pos)
+{
+       int *dst;
+       dst = (int *) (((u8 *) config) + (long) data->param1);
+       *dst = atoi(pos);
+       wpa_printf(MSG_DEBUG, "%s=%d", data->name, *dst);
+
+       if (data->param2 && *dst < (long) data->param2) {
+               wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
+                          "min_value=%ld)", line, data->name, *dst,
+                          (long) data->param2);
+               *dst = (long) data->param2;
                return -1;
        }
-       config->country[0] = pos[0];
-       config->country[1] = pos[1];
-       wpa_printf(MSG_DEBUG, "country='%c%c'",
-                  config->country[0], config->country[1]);
-       return 0;
-}
-
 
-#ifdef CONFIG_CTRL_IFACE
-static int wpa_config_process_ctrl_interface(struct wpa_config *config,
-                                            char *pos)
-{
-       os_free(config->ctrl_interface);
-       config->ctrl_interface = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "ctrl_interface='%s'", config->ctrl_interface);
-       return 0;
-}
-
-
-static int wpa_config_process_ctrl_interface_group(struct wpa_config *config,
-                                                  char *pos)
-{
-       os_free(config->ctrl_interface_group);
-       config->ctrl_interface_group = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "ctrl_interface_group='%s' (DEPRECATED)",
-                  config->ctrl_interface_group);
-       return 0;
-}
-#endif /* CONFIG_CTRL_IFACE */
-
-
-static int wpa_config_process_eapol_version(struct wpa_config *config,
-                                           int line, char *pos)
-{
-       config->eapol_version = atoi(pos);
-       if (config->eapol_version < 1 || config->eapol_version > 2) {
-               wpa_printf(MSG_ERROR, "Line %d: Invalid EAPOL version (%d): "
-                          "'%s'.", line, config->eapol_version, pos);
+       if (data->param3 && *dst > (long) data->param3) {
+               wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
+                          "max_value=%ld)", line, data->name, *dst,
+                          (long) data->param3);
+               *dst = (long) data->param3;
                return -1;
        }
-       wpa_printf(MSG_DEBUG, "eapol_version=%d", config->eapol_version);
-       return 0;
-}
-
-
-static int wpa_config_process_ap_scan(struct wpa_config *config, char *pos)
-{
-       config->ap_scan = atoi(pos);
-       wpa_printf(MSG_DEBUG, "ap_scan=%d", config->ap_scan);
-       return 0;
-}
-
 
-static int wpa_config_process_fast_reauth(struct wpa_config *config, char *pos)
-{
-       config->fast_reauth = atoi(pos);
-       wpa_printf(MSG_DEBUG, "fast_reauth=%d", config->fast_reauth);
        return 0;
 }
 
 
-#ifdef EAP_TLS_OPENSSL
-
-static int wpa_config_process_opensc_engine_path(struct wpa_config *config,
-                                                char *pos)
+static int wpa_config_parse_str(const struct global_parse_data *data,
+                               struct wpa_config *config, int line,
+                               const char *pos)
 {
-       os_free(config->opensc_engine_path);
-       config->opensc_engine_path = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "opensc_engine_path='%s'",
-                  config->opensc_engine_path);
-       return 0;
-}
-
+       size_t len;
+       char **dst, *tmp;
 
-static int wpa_config_process_pkcs11_engine_path(struct wpa_config *config,
-                                                char *pos)
-{
-       os_free(config->pkcs11_engine_path);
-       config->pkcs11_engine_path = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "pkcs11_engine_path='%s'",
-                  config->pkcs11_engine_path);
-       return 0;
-}
-
-
-static int wpa_config_process_pkcs11_module_path(struct wpa_config *config,
-                                                char *pos)
-{
-       os_free(config->pkcs11_module_path);
-       config->pkcs11_module_path = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "pkcs11_module_path='%s'",
-                  config->pkcs11_module_path);
-       return 0;
-}
-
-#endif /* EAP_TLS_OPENSSL */
-
-
-static int wpa_config_process_driver_param(struct wpa_config *config,
-                                          char *pos)
-{
-       os_free(config->driver_param);
-       config->driver_param = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "driver_param='%s'", config->driver_param);
-       return 0;
-}
-
-
-static int wpa_config_process_pmk_lifetime(struct wpa_config *config,
-                                          char *pos)
-{
-       config->dot11RSNAConfigPMKLifetime = atoi(pos);
-       wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKLifetime=%d",
-                  config->dot11RSNAConfigPMKLifetime);
-       return 0;
-}
+       len = os_strlen(pos);
+       if (data->param2 && len < (size_t) data->param2) {
+               wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
+                          "min_len=%ld)", line, data->name,
+                          (unsigned long) len, (long) data->param2);
+               return -1;
+       }
 
+       if (data->param3 && len > (size_t) data->param3) {
+               wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
+                          "max_len=%ld)", line, data->name,
+                          (unsigned long) len, (long) data->param3);
+               return -1;
+       }
 
-static int wpa_config_process_pmk_reauth_threshold(struct wpa_config *config,
-                                                  char *pos)
-{
-       config->dot11RSNAConfigPMKReauthThreshold = atoi(pos);
-       wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKReauthThreshold=%d",
-                  config->dot11RSNAConfigPMKReauthThreshold);
-       return 0;
-}
+       tmp = os_strdup(pos);
+       if (tmp == NULL)
+               return -1;
 
+       dst = (char **) (((u8 *) config) + (long) data->param1);
+       os_free(*dst);
+       *dst = tmp;
+       wpa_printf(MSG_DEBUG, "%s='%s'", data->name, *dst);
 
-static int wpa_config_process_sa_timeout(struct wpa_config *config, char *pos)
-{
-       config->dot11RSNAConfigSATimeout = atoi(pos);
-       wpa_printf(MSG_DEBUG, "dot11RSNAConfigSATimeout=%d",
-                  config->dot11RSNAConfigSATimeout);
        return 0;
 }
 
 
-#ifndef CONFIG_NO_CONFIG_WRITE
-static int wpa_config_process_update_config(struct wpa_config *config,
-                                           char *pos)
+static int wpa_config_process_country(const struct global_parse_data *data,
+                                     struct wpa_config *config, int line,
+                                     const char *pos)
 {
-       config->update_config = atoi(pos);
-       wpa_printf(MSG_DEBUG, "update_config=%d", config->update_config);
+       if (!pos[0] || !pos[1]) {
+               wpa_printf(MSG_DEBUG, "Invalid country set");
+               return -1;
+       }
+       config->country[0] = pos[0];
+       config->country[1] = pos[1];
+       wpa_printf(MSG_DEBUG, "country='%c%c'",
+                  config->country[0], config->country[1]);
        return 0;
 }
-#endif /* CONFIG_NO_CONFIG_WRITE */
 
 
-static int wpa_config_process_load_dynamic_eap(int line, char *so)
+static int wpa_config_process_load_dynamic_eap(
+       const struct global_parse_data *data, struct wpa_config *config,
+       int line, const char *so)
 {
        int ret;
        wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so);
@@ -444,8 +380,9 @@ static int wpa_config_process_load_dynamic_eap(int line, char *so)
 
 #ifdef CONFIG_WPS
 
-static int wpa_config_process_uuid(struct wpa_config *config, int line,
-                                  char *pos)
+static int wpa_config_process_uuid(const struct global_parse_data *data,
+                                  struct wpa_config *config, int line,
+                                  const char *pos)
 {
        char buf[40];
        if (uuid_str2bin(pos, config->uuid)) {
@@ -458,75 +395,9 @@ static int wpa_config_process_uuid(struct wpa_config *config, int line,
 }
 
 
-static int wpa_config_process_device_name(struct wpa_config *config, char *pos)
-{
-       if (os_strlen(pos) > 32)
-               return -1;
-       os_free(config->device_name);
-       config->device_name = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "device_name='%s'", config->device_name);
-       return 0;
-}
-
-
-static int wpa_config_process_manufacturer(struct wpa_config *config,
-                                          char *pos)
-{
-       if (os_strlen(pos) > 64)
-               return -1;
-       os_free(config->manufacturer);
-       config->manufacturer = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "manufacturer='%s'", config->manufacturer);
-       return 0;
-}
-
-
-static int wpa_config_process_model_name(struct wpa_config *config, char *pos)
-{
-       if (os_strlen(pos) > 32)
-               return -1;
-       os_free(config->model_name);
-       config->model_name = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "model_name='%s'", config->model_name);
-       return 0;
-}
-
-
-static int wpa_config_process_model_number(struct wpa_config *config,
-                                          char *pos)
-{
-       if (os_strlen(pos) > 32)
-               return -1;
-       os_free(config->model_number);
-       config->model_number = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "model_number='%s'", config->model_number);
-       return 0;
-}
-
-
-static int wpa_config_process_serial_number(struct wpa_config *config,
-                                           char *pos)
-{
-       if (os_strlen(pos) > 32)
-               return -1;
-       os_free(config->serial_number);
-       config->serial_number = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "serial_number='%s'", config->serial_number);
-       return 0;
-}
-
-
-static int wpa_config_process_device_type(struct wpa_config *config, char *pos)
-{
-       os_free(config->device_type);
-       config->device_type = os_strdup(pos);
-       wpa_printf(MSG_DEBUG, "device_type='%s'", config->device_type);
-       return 0;
-}
-
-
-static int wpa_config_process_os_version(struct wpa_config *config, int line,
-                                        char *pos)
+static int wpa_config_process_os_version(const struct global_parse_data *data,
+                                        struct wpa_config *config, int line,
+                                        const char *pos)
 {
        if (hexstr2bin(pos, config->os_version, 4)) {
                wpa_printf(MSG_ERROR, "Line %d: invalid os_version", line);
@@ -540,83 +411,93 @@ static int wpa_config_process_os_version(struct wpa_config *config, int line,
 #endif /* CONFIG_WPS */
 
 
-static int wpa_config_process_global(struct wpa_config *config, char *pos,
-                                    int line)
-{
-#ifdef CONFIG_CTRL_IFACE
-       if (os_strncmp(pos, "ctrl_interface=", 15) == 0)
-               return wpa_config_process_ctrl_interface(config, pos + 15);
-
-       if (os_strncmp(pos, "ctrl_interface_group=", 21) == 0)
-               return wpa_config_process_ctrl_interface_group(config,
-                                                              pos + 21);
-#endif /* CONFIG_CTRL_IFACE */
-
-       if (os_strncmp(pos, "eapol_version=", 14) == 0)
-               return wpa_config_process_eapol_version(config, line,
-                                                       pos + 14);
-
-       if (os_strncmp(pos, "ap_scan=", 8) == 0)
-               return wpa_config_process_ap_scan(config, pos + 8);
+#ifdef OFFSET
+#undef OFFSET
+#endif /* OFFSET */
+/* OFFSET: Get offset of a variable within the wpa_config structure */
+#define OFFSET(v) ((void *) &((struct wpa_config *) 0)->v)
 
-       if (os_strncmp(pos, "fast_reauth=", 12) == 0)
-               return wpa_config_process_fast_reauth(config, pos + 12);
+#define FUNC(f) #f, wpa_config_process_ ## f, OFFSET(f), NULL, NULL
+#define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL
+#define _INT(f) #f, wpa_config_parse_int, OFFSET(f)
+#define INT(f) _INT(f), NULL, NULL
+#define INT_RANGE(f, min, max) _INT(f), (void *) min, (void *) max
+#define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
+#define STR(f) _STR(f), NULL, NULL
+#define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
 
+static const struct global_parse_data global_fields[] = {
+#ifdef CONFIG_CTRL_IFACE
+       { STR(ctrl_interface) },
+       { STR(ctrl_interface_group) } /* deprecated */,
+#endif /* CONFIG_CTRL_IFACE */
+       { INT_RANGE(eapol_version, 1, 2) },
+       { INT(ap_scan) },
+       { INT(fast_reauth) },
 #ifdef EAP_TLS_OPENSSL
-       if (os_strncmp(pos, "opensc_engine_path=", 19) == 0)
-               return wpa_config_process_opensc_engine_path(config, pos + 19);
-
-       if (os_strncmp(pos, "pkcs11_engine_path=", 19) == 0)
-               return wpa_config_process_pkcs11_engine_path(config, pos + 19);
-
-       if (os_strncmp(pos, "pkcs11_module_path=", 19) == 0)
-               return wpa_config_process_pkcs11_module_path(config, pos + 19);
+       { STR(opensc_engine_path) },
+       { STR(pkcs11_engine_path) },
+       { STR(pkcs11_module_path) },
 #endif /* EAP_TLS_OPENSSL */
-
-       if (os_strncmp(pos, "driver_param=", 13) == 0)
-               return wpa_config_process_driver_param(config, pos + 13);
-
-       if (os_strncmp(pos, "dot11RSNAConfigPMKLifetime=", 27) == 0)
-               return wpa_config_process_pmk_lifetime(config, pos + 27);
-
-       if (os_strncmp(pos, "dot11RSNAConfigPMKReauthThreshold=", 34) == 0)
-               return wpa_config_process_pmk_reauth_threshold(config,
-                                                              pos + 34);
-
-       if (os_strncmp(pos, "dot11RSNAConfigSATimeout=", 25) == 0)
-               return wpa_config_process_sa_timeout(config, pos + 25);
-
+       { STR(driver_param) },
+       { INT(dot11RSNAConfigPMKLifetime) },
+       { INT(dot11RSNAConfigPMKReauthThreshold) },
+       { INT(dot11RSNAConfigSATimeout) },
 #ifndef CONFIG_NO_CONFIG_WRITE
-       if (os_strncmp(pos, "update_config=", 14) == 0)
-               return wpa_config_process_update_config(config, pos + 14);
+       { INT(update_config) },
 #endif /* CONFIG_NO_CONFIG_WRITE */
-
-       if (os_strncmp(pos, "load_dynamic_eap=", 17) == 0)
-               return wpa_config_process_load_dynamic_eap(line, pos + 17);
-
+       { FUNC_NO_VAR(load_dynamic_eap) },
 #ifdef CONFIG_WPS
-       if (os_strncmp(pos, "uuid=", 5) == 0)
-               return wpa_config_process_uuid(config, line, pos + 5);
-       if (os_strncmp(pos, "device_name=", 12) == 0)
-               return wpa_config_process_device_name(config, pos + 12);
-       if (os_strncmp(pos, "manufacturer=", 13) == 0)
-               return wpa_config_process_manufacturer(config, pos + 13);
-       if (os_strncmp(pos, "model_name=", 11) == 0)
-               return wpa_config_process_model_name(config, pos + 11);
-       if (os_strncmp(pos, "model_number=", 13) == 0)
-               return wpa_config_process_model_number(config, pos + 13);
-       if (os_strncmp(pos, "serial_number=", 14) == 0)
-               return wpa_config_process_serial_number(config, pos + 14);
-       if (os_strncmp(pos, "device_type=", 12) == 0)
-               return wpa_config_process_device_type(config, pos + 12);
-       if (os_strncmp(pos, "os_version=", 11) == 0)
-               return wpa_config_process_os_version(config, line, pos + 11);
+       { FUNC(uuid) },
+       { STR_RANGE(device_name, 0, 32) },
+       { STR_RANGE(manufacturer, 0, 64) },
+       { STR_RANGE(model_name, 0, 32) },
+       { STR_RANGE(model_number, 0, 32) },
+       { STR_RANGE(serial_number, 0, 32) },
+       { STR(device_type) },
+       { FUNC(os_version) },
+       { INT_RANGE(wps_cred_processing, 0, 2) },
 #endif /* CONFIG_WPS */
+       { FUNC(country) }
+};
 
-       if (os_strncmp(pos, "country=", 8) == 0)
-               return wpa_config_process_country(config, pos + 8);
+#undef FUNC
+#undef _INT
+#undef INT
+#undef INT_RANGE
+#undef _STR
+#undef STR
+#undef STR_RANGE
+#define NUM_GLOBAL_FIELDS (sizeof(global_fields) / sizeof(global_fields[0]))
 
-       return -1;
+
+static int wpa_config_process_global(struct wpa_config *config, char *pos,
+                                    int line)
+{
+       size_t i;
+       int ret = 0;
+
+       for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
+               const struct global_parse_data *field = &global_fields[i];
+               size_t flen = os_strlen(field->name);
+               if (os_strncmp(pos, field->name, flen) != 0 ||
+                   pos[flen] != '=')
+                       continue;
+
+               if (field->parser(field, config, line, pos + flen + 1)) {
+                       wpa_printf(MSG_ERROR, "Line %d: failed to "
+                                  "parse '%s'.", line, pos);
+                       ret = -1;
+               }
+               break;
+       }
+       if (i == NUM_GLOBAL_FIELDS) {
+               wpa_printf(MSG_ERROR, "Line %d: unknown global field '%s'.",
+                          line, pos);
+               ret = -1;
+       }
+
+       return ret;
 }
 
 
@@ -981,7 +862,7 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
        if (config->update_config)
                fprintf(f, "update_config=%d\n", config->update_config);
 #ifdef CONFIG_WPS
-       if (is_nil_uuid(config->uuid)) {
+       if (!is_nil_uuid(config->uuid)) {
                char buf[40];
                uuid_bin2str(config->uuid, buf, sizeof(buf));
                fprintf(f, "uuid=%s\n", buf);
@@ -998,9 +879,12 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
                fprintf(f, "serial_number=%s\n", config->serial_number);
        if (config->device_type)
                fprintf(f, "device_type=%s\n", config->device_type);
-       if (config->os_version)
+       if (WPA_GET_BE32(config->os_version))
                fprintf(f, "os_version=%08x\n",
                        WPA_GET_BE32(config->os_version));
+       if (config->wps_cred_processing)
+               fprintf(f, "wps_cred_processing=%d\n",
+                       config->wps_cred_processing);
 #endif /* CONFIG_WPS */
        if (config->country[0] && config->country[1]) {
                fprintf(f, "country=%c%c\n",