static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line, const char *name) { struct wpa_config_blob *blob; char buf[256], *pos; unsigned char *encoded = NULL, *nencoded; int end = 0; size_t encoded_len = 0, len; wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new named blob '%s'", *line, name); while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) { if (os_strcmp(pos, "}") == 0) { end = 1; break; } len = os_strlen(pos); nencoded = os_realloc(encoded, encoded_len + len); if (nencoded == NULL) { wpa_printf(MSG_ERROR, "Line %d: not enough memory for " "blob", *line); os_free(encoded); return NULL; } encoded = nencoded; os_memcpy(encoded + encoded_len, pos, len); encoded_len += len; } if (!end) { wpa_printf(MSG_ERROR, "Line %d: blob was not terminated " "properly", *line); os_free(encoded); return NULL; } blob = os_zalloc(sizeof(*blob)); if (blob == NULL) { os_free(encoded); return NULL; } blob->name = os_strdup(name); blob->data = base64_decode(encoded, encoded_len, &blob->len); os_free(encoded); if (blob->name == NULL || blob->data == NULL) { wpa_config_free_blob(blob); return NULL; } return blob; }
static struct wpa_cred * wpa_config_read_cred(FILE *f, int *line, int id) { struct wpa_cred *cred; int errors = 0, end = 0; char buf[256], *pos, *pos2; wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new cred block", *line); cred = os_zalloc(sizeof(*cred)); if (cred == NULL) return NULL; cred->id = id; cred->sim_num = DEFAULT_USER_SELECTED_SIM; while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) { if (os_strcmp(pos, "}") == 0) { end = 1; break; } pos2 = os_strchr(pos, '='); if (pos2 == NULL) { wpa_printf(MSG_ERROR, "Line %d: Invalid cred line " "'%s'.", *line, pos); errors++; continue; } *pos2++ = '\0'; if (*pos2 == '"') { if (os_strchr(pos2 + 1, '"') == NULL) { wpa_printf(MSG_ERROR, "Line %d: invalid " "quotation '%s'.", *line, pos2); errors++; continue; } } if (wpa_config_set_cred(cred, pos, pos2, *line) < 0) errors++; } if (!end) { wpa_printf(MSG_ERROR, "Line %d: cred block was not " "terminated properly.", *line); errors++; } if (errors) { wpa_config_free_cred(cred); cred = NULL; } return cred; }
static struct wps_config * wpa_config_read_wps_property(FILE *f, int *line) { struct wps_config *wps; int errors = 0, end = 0; char buf[256], *pos, *pos2; wpa_printf(MSG_MSGDUMP, "Line: %d - start of a wps_property block", *line); wps = wpa_zalloc(sizeof(*wps)); if (wps == NULL) return NULL; while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) { if (strcmp(pos, "}") == 0) { end = 1; break; } pos2 = os_strchr(pos, '='); if (pos2 == NULL) { wpa_printf(MSG_ERROR, "Line %d: Invalid property line " "'%s'.", *line, pos); errors++; continue; } *pos2++ = '\0'; if (*pos2 == '"') { if (os_strchr(pos2 + 1, '"') == NULL) { wpa_printf(MSG_ERROR, "Line %d: invalid " "quotation '%s'.", *line, pos2); errors++; continue; } } if (wps_config_set(wps, pos, pos2, *line) < 0) errors++; } if (!end) { wpa_printf(MSG_ERROR, "Line %d: wps_property block was not " "terminated properly.", *line); errors++; } if (errors) { wpa_config_free_wps_config(wps); wps = NULL; } return wps; }
struct wpa_config * wpa_config_read(const char *name) { FILE *f; char buf[256], *pos; int errors = 0, line = 0; struct wpa_ssid *ssid, *tail = NULL, *head = NULL; struct wpa_config *config; int id = 0; config = wpa_config_alloc_empty(NULL, NULL); if (config == NULL) return NULL; wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); f = fopen(name, "r"); if (f == NULL) { os_free(config); return NULL; } while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) { if (os_strcmp(pos, "network={") == 0) { ssid = wpa_config_read_network(f, &line, id++); if (ssid == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse network block.", line); #ifndef WPA_IGNORE_CONFIG_ERRORS errors++; #endif continue; } if (head == NULL) { head = tail = ssid; } else { tail->next = ssid; tail = ssid; } if (wpa_config_add_prio_network(config, ssid)) { wpa_printf(MSG_ERROR, "Line %d: failed to add " "network block to priority list.", line); errors++; continue; } #ifndef CONFIG_NO_CONFIG_BLOBS } else if (os_strncmp(pos, "blob-base64-", 12) == 0) { if (wpa_config_process_blob(config, f, &line, pos + 12) < 0) { errors++; continue; } #endif /* CONFIG_NO_CONFIG_BLOBS */ } else if (wpa_config_process_global(config, pos, line) < 0) { wpa_printf(MSG_ERROR, "Line %d: Invalid configuration " "line '%s'.", line, pos); errors++; continue; } } fclose(f); config->ssid = head; wpa_config_debug_dump_networks(config); #ifndef WPA_IGNORE_CONFIG_ERRORS if (errors) { wpa_config_free(config); config = NULL; head = NULL; } #endif return config; }
struct wpa_config * wpa_config_read(const char *name) { FILE *f; char buf[256], *pos; int errors = 0, line = 0; struct wpa_ssid *ssid, *tail = NULL, *head = NULL; struct wpa_config *config; int id = 0; long lSize; config = wpa_config_alloc_empty(NULL, NULL); if (config == NULL) return NULL; wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); f = fopen(name, "r"); if (f == NULL) { os_free(config); return NULL; } #if 1 /* Check the config file, if file size is too small, delete it and use default config file at next start */ fseek (f , 0 , SEEK_END); lSize = ftell (f); rewind (f); /* Make sure the file size has baisc filed */ if (lSize < 30) { fclose(f); if( remove( name ) != 0 ) wpa_printf(MSG_WARNING, "Error deleting file %s", name ); else wpa_printf(MSG_WARNING, "File successfully deleted %s", name ); os_free(config); return NULL; } #endif while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) { if (os_strcmp(pos, "network={") == 0) { ssid = wpa_config_read_network(f, &line, id++); if (ssid == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse network block.", line); errors++; continue; } if (head == NULL) { head = tail = ssid; } else { tail->next = ssid; tail = ssid; } if (wpa_config_add_prio_network(config, ssid)) { wpa_printf(MSG_ERROR, "Line %d: failed to add " "network block to priority list.", line); errors++; continue; } #ifndef CONFIG_NO_CONFIG_BLOBS } else if (os_strncmp(pos, "blob-base64-", 12) == 0) { if (wpa_config_process_blob(config, f, &line, pos + 12) < 0) { errors++; continue; } #endif /* CONFIG_NO_CONFIG_BLOBS */ } else if (wpa_config_process_global(config, pos, line) < 0) { wpa_printf(MSG_ERROR, "Line %d: Invalid configuration " "line '%s'.", line, pos); errors++; continue; } } fclose(f); config->ssid = head; wpa_config_debug_dump_networks(config); #ifndef WPA_IGNORE_CONFIG_ERRORS if (errors) { wpa_config_free(config); config = NULL; head = NULL; } #endif /* WPA_IGNORE_CONFIG_ERRORS */ return config; }
struct wpa_config * wpa_config_read(const char *name) { FILE *f; char buf[256], *pos; int errors = 0, line = 0; struct wpa_ssid *ssid, *tail = NULL, *head = NULL; struct wpa_config *config; int id = 0; #ifdef EAP_WPS #ifndef USE_INTEL_SDK struct wps_config *wps; #endif /* USE_INTEL_SDK */ #endif /* EAP_WPS */ config = wpa_config_alloc_empty(NULL, NULL); if (config == NULL) return NULL; wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); f = fopen(name, "r"); if (f == NULL) { os_free(config); return NULL; } while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) { if (os_strcmp(pos, "network={") == 0) { ssid = wpa_config_read_network(f, &line, id++); if (ssid == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse network block.", line); errors++; continue; } if (head == NULL) { head = tail = ssid; } else { tail->next = ssid; tail = ssid; } if (wpa_config_add_prio_network(config, ssid)) { wpa_printf(MSG_ERROR, "Line %d: failed to add " "network block to priority list.", line); errors++; continue; } } else if (os_strncmp(pos, "blob-base64-", 12) == 0) { char *bname = pos + 12, *name_end; struct wpa_config_blob *blob; name_end = os_strchr(bname, '='); if (name_end == NULL) { wpa_printf(MSG_ERROR, "Line %d: no blob name " "terminator", line); errors++; continue; } *name_end = '\0'; blob = wpa_config_read_blob(f, &line, bname); if (blob == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to read" " blob %s", line, bname); errors++; continue; } wpa_config_set_blob(config, blob); #ifdef CONFIG_CTRL_IFACE } else if (os_strncmp(pos, "ctrl_interface=", 15) == 0) { os_free(config->ctrl_interface); config->ctrl_interface = os_strdup(pos + 15); wpa_printf(MSG_DEBUG, "ctrl_interface='%s'", config->ctrl_interface); } else if (os_strncmp(pos, "ctrl_interface_group=", 21) == 0) { os_free(config->ctrl_interface_group); config->ctrl_interface_group = os_strdup(pos + 21); wpa_printf(MSG_DEBUG, "ctrl_interface_group='%s' " "(DEPRECATED)", config->ctrl_interface_group); #endif /* CONFIG_CTRL_IFACE */ } else if (os_strncmp(pos, "eapol_version=", 14) == 0) { config->eapol_version = atoi(pos + 14); 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); errors++; continue; } wpa_printf(MSG_DEBUG, "eapol_version=%d", config->eapol_version); } else if (os_strncmp(pos, "ap_scan=", 8) == 0) { config->ap_scan = atoi(pos + 8); wpa_printf(MSG_DEBUG, "ap_scan=%d", config->ap_scan); } else if (os_strncmp(pos, "fast_reauth=", 12) == 0) { config->fast_reauth = atoi(pos + 12); wpa_printf(MSG_DEBUG, "fast_reauth=%d", config->fast_reauth); } else if (os_strncmp(pos, "opensc_engine_path=", 19) == 0) { os_free(config->opensc_engine_path); config->opensc_engine_path = os_strdup(pos + 19); wpa_printf(MSG_DEBUG, "opensc_engine_path='%s'", config->opensc_engine_path); } else if (os_strncmp(pos, "pkcs11_engine_path=", 19) == 0) { os_free(config->pkcs11_engine_path); config->pkcs11_engine_path = os_strdup(pos + 19); wpa_printf(MSG_DEBUG, "pkcs11_engine_path='%s'", config->pkcs11_engine_path); } else if (os_strncmp(pos, "pkcs11_module_path=", 19) == 0) { os_free(config->pkcs11_module_path); config->pkcs11_module_path = os_strdup(pos + 19); wpa_printf(MSG_DEBUG, "pkcs11_module_path='%s'", config->pkcs11_module_path); } else if (os_strncmp(pos, "driver_param=", 13) == 0) { os_free(config->driver_param); config->driver_param = os_strdup(pos + 13); wpa_printf(MSG_DEBUG, "driver_param='%s'", config->driver_param); } else if (os_strncmp(pos, "dot11RSNAConfigPMKLifetime=", 27) == 0) { config->dot11RSNAConfigPMKLifetime = atoi(pos + 27); wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKLifetime=%d", config->dot11RSNAConfigPMKLifetime); } else if (os_strncmp(pos, "dot11RSNAConfigPMKReauthThreshold=", 34) == 0) { config->dot11RSNAConfigPMKReauthThreshold = atoi(pos + 34); wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKReauthThreshold=%d", config->dot11RSNAConfigPMKReauthThreshold); } else if (os_strncmp(pos, "dot11RSNAConfigSATimeout=", 25) == 0) { config->dot11RSNAConfigSATimeout = atoi(pos + 25); wpa_printf(MSG_DEBUG, "dot11RSNAConfigSATimeout=%d", config->dot11RSNAConfigSATimeout); } else if (os_strncmp(pos, "update_config=", 14) == 0) { config->update_config = atoi(pos + 14); wpa_printf(MSG_DEBUG, "update_config=%d", config->update_config); } else if (os_strncmp(pos, "load_dynamic_eap=", 17) == 0) { char *so = pos + 17; int ret; wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so); ret = eap_peer_method_load(so); if (ret == -2) { wpa_printf(MSG_DEBUG, "This EAP type was " "already loaded - not reloading."); } else if (ret) { wpa_printf(MSG_ERROR, "Line %d: Failed to " "load dynamic EAP method '%s'.", line, so); errors++; } #ifdef EAP_WPS #ifndef USE_INTEL_SDK } else if (os_strcmp(pos, "wps_property={") == 0) { wps = wpa_config_read_wps_property(f, &line); if (config->wps) { if (wps) os_free(wps); wpa_printf(MSG_ERROR, "Line %d: Failed to " "set multiple WPS properties.", line); errors++; continue; } else if (!wps) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse wps_property block.", line); errors++; continue; } config->wps = wps; #endif /* USE_INTEL_SDK */ #endif /* EAP_WPS */ } else { wpa_printf(MSG_ERROR, "Line %d: Invalid configuration " "line '%s'.", line, pos); errors++; continue; } } fclose(f); config->ssid = head; wpa_config_debug_dump_networks(config); if (errors) { wpa_config_free(config); config = NULL; head = NULL; } return config; }
struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp) { FILE *f; char buf[512], *pos; int errors = 0, line = 0; struct wpa_ssid *ssid, *tail, *head; struct wpa_cred *cred, *cred_tail, *cred_head; struct wpa_config *config; int id = 0; int cred_id = 0; if (name == NULL) return NULL; if (cfgp) config = cfgp; else config = wpa_config_alloc_empty(NULL, NULL); if (config == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate config file " "structure"); return NULL; } tail = head = config->ssid; while (tail && tail->next) tail = tail->next; cred_tail = cred_head = config->cred; while (cred_tail && cred_tail->next) cred_tail = cred_tail->next; wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); f = fopen(name, "r"); if (f == NULL) { wpa_printf(MSG_ERROR, "Failed to open config file '%s', " "error: %s", name, strerror(errno)); os_free(config); return NULL; } while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) { if (os_strcmp(pos, "network={") == 0) { ssid = wpa_config_read_network(f, &line, id++); if (ssid == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse network block.", line); errors++; continue; } if (head == NULL) { head = tail = ssid; } else { tail->next = ssid; tail = ssid; } if (wpa_config_add_prio_network(config, ssid)) { wpa_printf(MSG_ERROR, "Line %d: failed to add " "network block to priority list.", line); errors++; continue; } } else if (os_strcmp(pos, "cred={") == 0) { cred = wpa_config_read_cred(f, &line, cred_id++); if (cred == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse cred block.", line); errors++; continue; } if (cred_head == NULL) { cred_head = cred_tail = cred; } else { cred_tail->next = cred; cred_tail = cred; } #ifndef CONFIG_NO_CONFIG_BLOBS } else if (os_strncmp(pos, "blob-base64-", 12) == 0) { if (wpa_config_process_blob(config, f, &line, pos + 12) < 0) { wpa_printf(MSG_ERROR, "Line %d: failed to " "process blob.", line); errors++; continue; } #endif /* CONFIG_NO_CONFIG_BLOBS */ } else if (wpa_config_process_global(config, pos, line) < 0) { wpa_printf(MSG_ERROR, "Line %d: Invalid configuration " "line '%s'.", line, pos); errors++; continue; } } fclose(f); config->ssid = head; wpa_config_debug_dump_networks(config); config->cred = cred_head; #ifndef WPA_IGNORE_CONFIG_ERRORS if (errors) { wpa_config_free(config); config = NULL; head = NULL; } #endif /* WPA_IGNORE_CONFIG_ERRORS */ return config; }
/** * wpa_config_read - Read and parse a configuration file * @config_file: Path and file name for the configuration file * Returns: Pointer to allocated configuration data or %NULL on failure * * This function reads a configuration file, parses its contents, and allocates * data structures needed for storing configuration information. The allocated * data can be freed with wpa_config_free(). */ struct wpa_config * wpa_config_read(const char *config_file) { FILE *f; char buf[256], *pos; int errors = 0, line = 0; struct wpa_ssid *ssid, *tail = NULL, *head = NULL; struct wpa_config *config; int id = 0, prio; config = malloc(sizeof(*config)); if (config == NULL) return NULL; memset(config, 0, sizeof(*config)); config->eapol_version = 1; config->ap_scan = 1; config->fast_reauth = 1; wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", config_file); f = fopen(config_file, "r"); if (f == NULL) { free(config); return NULL; } while ((pos = wpa_config_get_line(buf, sizeof(buf), f, &line))) { if (strcmp(pos, "network={") == 0) { ssid = wpa_config_read_network(f, &line, id++); if (ssid == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse network block.", line); errors++; continue; } if (head == NULL) { head = tail = ssid; } else { tail->next = ssid; tail = ssid; } if (wpa_config_add_prio_network(config, ssid)) { wpa_printf(MSG_ERROR, "Line %d: failed to add " "network block to priority list.", line); errors++; continue; } #ifdef CONFIG_CTRL_IFACE } else if (strncmp(pos, "ctrl_interface=", 15) == 0) { free(config->ctrl_interface); config->ctrl_interface = strdup(pos + 15); wpa_printf(MSG_DEBUG, "ctrl_interface='%s'", config->ctrl_interface); #ifndef CONFIG_CTRL_IFACE_UDP } else if (strncmp(pos, "ctrl_interface_group=", 21) == 0) { struct group *grp; char *endp; const char *group = pos + 21; grp = getgrnam(group); if (grp) { config->ctrl_interface_gid = grp->gr_gid; config->ctrl_interface_gid_set = 1; wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" " (from group name '%s')", (int) config->ctrl_interface_gid, group); continue; } /* Group name not found - try to parse this as gid */ config->ctrl_interface_gid = strtol(group, &endp, 10); if (*group == '\0' || *endp != '\0') { wpa_printf(MSG_DEBUG, "Line %d: Invalid group " "'%s'", line, group); errors++; continue; } config->ctrl_interface_gid_set = 1; wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", (int) config->ctrl_interface_gid); #endif /* CONFIG_CTRL_IFACE_UDP */ #endif /* CONFIG_CTRL_IFACE */ } else if (strncmp(pos, "eapol_version=", 14) == 0) { config->eapol_version = atoi(pos + 14); 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); errors++; continue; } wpa_printf(MSG_DEBUG, "eapol_version=%d", config->eapol_version); } else if (strncmp(pos, "ap_scan=", 8) == 0) { config->ap_scan = atoi(pos + 8); wpa_printf(MSG_DEBUG, "ap_scan=%d", config->ap_scan); } else if (strncmp(pos, "fast_reauth=", 12) == 0) { config->fast_reauth = atoi(pos + 12); wpa_printf(MSG_DEBUG, "fast_reauth=%d", config->fast_reauth); } else if (strncmp(pos, "opensc_engine_path=", 19) == 0) { free(config->opensc_engine_path); config->opensc_engine_path = strdup(pos + 19); wpa_printf(MSG_DEBUG, "opensc_engine_path='%s'", config->opensc_engine_path); } else if (strncmp(pos, "pkcs11_engine_path=", 19) == 0) { free(config->pkcs11_engine_path); config->pkcs11_engine_path = strdup(pos + 19); wpa_printf(MSG_DEBUG, "pkcs11_engine_path='%s'", config->pkcs11_engine_path); } else if (strncmp(pos, "pkcs11_module_path=", 19) == 0) { free(config->pkcs11_module_path); config->pkcs11_module_path = strdup(pos + 19); wpa_printf(MSG_DEBUG, "pkcs11_module_path='%s'", config->pkcs11_module_path); } else if (strncmp(pos, "driver_param=", 13) == 0) { free(config->driver_param); config->driver_param = strdup(pos + 13); wpa_printf(MSG_DEBUG, "driver_param='%s'", config->driver_param); } else if (strncmp(pos, "dot11RSNAConfigPMKLifetime=", 27) == 0) { config->dot11RSNAConfigPMKLifetime = atoi(pos + 27); wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKLifetime=%d", config->dot11RSNAConfigPMKLifetime); } else if (strncmp(pos, "dot11RSNAConfigPMKReauthThreshold=", 34) == 0) { config->dot11RSNAConfigPMKReauthThreshold = atoi(pos + 34); wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKReauthThreshold=%d", config->dot11RSNAConfigPMKReauthThreshold); } else if (strncmp(pos, "dot11RSNAConfigSATimeout=", 25) == 0) { config->dot11RSNAConfigSATimeout = atoi(pos + 25); wpa_printf(MSG_DEBUG, "dot11RSNAConfigSATimeout=%d", config->dot11RSNAConfigSATimeout); } else { wpa_printf(MSG_ERROR, "Line %d: Invalid configuration " "line '%s'.", line, pos); errors++; continue; } } fclose(f); config->ssid = head; for (prio = 0; prio < config->num_prio; prio++) { ssid = config->pssid[prio]; wpa_printf(MSG_DEBUG, "Priority group %d", ssid->priority); while (ssid) { wpa_printf(MSG_DEBUG, " id=%d ssid='%s'", ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); ssid = ssid->pnext; } } if (errors) { wpa_config_free(config); config = NULL; head = NULL; } return config; }
static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id) { struct wpa_ssid *ssid; int errors = 0, end = 0; char buf[256], *pos, *pos2; wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new network block", *line); ssid = (struct wpa_ssid *) malloc(sizeof(*ssid)); if (ssid == NULL) return NULL; memset(ssid, 0, sizeof(*ssid)); ssid->id = id; ssid->proto = WPA_PROTO_WPA | WPA_PROTO_RSN; ssid->pairwise_cipher = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP; ssid->group_cipher = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40; ssid->key_mgmt = WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X; ssid->eapol_flags = EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST; ssid->eap_workaround = (unsigned int) -1; while ((pos = wpa_config_get_line(buf, sizeof(buf), f, line))) { if (strcmp(pos, "}") == 0) { end = 1; break; } pos2 = strchr(pos, '='); if (pos2 == NULL) { wpa_printf(MSG_ERROR, "Line %d: Invalid SSID line " "'%s'.", *line, pos); errors++; continue; } *pos2++ = '\0'; if (*pos2 == '"') { if (strchr(pos2 + 1, '"') == NULL) { wpa_printf(MSG_ERROR, "Line %d: invalid " "quotation '%s'.", *line, pos2); errors++; continue; } } if (wpa_config_set(ssid, pos, pos2, *line) < 0) errors++; } if (!end) { wpa_printf(MSG_ERROR, "Line %d: network block was not " "terminated properly.", *line); errors++; } if (ssid->passphrase) { if (ssid->psk_set) { wpa_printf(MSG_ERROR, "Line %d: both PSK and " "passphrase configured.", *line); errors++; } wpa_config_update_psk(ssid); } if ((ssid->key_mgmt & WPA_KEY_MGMT_PSK) && !ssid->psk_set) { wpa_printf(MSG_ERROR, "Line %d: WPA-PSK accepted for key " "management, but no PSK configured.", *line); errors++; } if ((ssid->group_cipher & WPA_CIPHER_CCMP) && !(ssid->pairwise_cipher & WPA_CIPHER_CCMP)) { /* Group cipher cannot be stronger than the pairwise cipher. */ wpa_printf(MSG_DEBUG, "Line %d: removed CCMP from group cipher" " list since it was not allowed for pairwise " "cipher", *line); ssid->group_cipher &= ~WPA_CIPHER_CCMP; } if (errors) { free(ssid); ssid = NULL; } return ssid; }
static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id) { struct wpa_ssid *ssid; int errors = 0, i, end = 0; char buf[256], *pos, *pos2; wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new network block", *line); ssid = (struct wpa_ssid *) malloc(sizeof(*ssid)); if (ssid == NULL) return NULL; memset(ssid, 0, sizeof(*ssid)); ssid->id = id; ssid->proto = WPA_PROTO_WPA | WPA_PROTO_RSN; ssid->pairwise_cipher = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP; ssid->group_cipher = WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40; ssid->key_mgmt = WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X; ssid->eapol_flags = EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST; ssid->eap_workaround = (unsigned int) -1; while ((pos = wpa_config_get_line(buf, sizeof(buf), f, line))) { if (strcmp(pos, "}") == 0) { end = 1; break; } pos2 = strchr(pos, '='); if (pos2 == NULL) { wpa_printf(MSG_ERROR, "Line %d: Invalid SSID line " "'%s'.", *line, pos); errors++; continue; } *pos2++ = '\0'; if (*pos2 == '"') { if (strchr(pos2 + 1, '"') == NULL) { wpa_printf(MSG_ERROR, "Line %d: invalid " "quotation '%s'.", *line, pos2); errors++; continue; } } for (i = 0; i < NUM_SSID_FIELDS; i++) { struct parse_data *field = &ssid_fields[i]; if (strcmp(pos, field->name) != 0) continue; field->ssid = ssid; if (field->parser(field, *line, pos2)) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse %s '%s'.", *line, pos, pos2); errors++; } break; } if (i == NUM_SSID_FIELDS) { wpa_printf(MSG_ERROR, "Line %d: unknown network field " "'%s'.", *line, pos); errors++; } } if (!end) { wpa_printf(MSG_ERROR, "Line %d: network block was not " "terminated properly.", *line); errors++; } if (ssid->passphrase) { if (ssid->psk_set) { wpa_printf(MSG_ERROR, "Line %d: both PSK and " "passphrase configured.", *line); errors++; } pbkdf2_sha1(ssid->passphrase, (char *) ssid->ssid, ssid->ssid_len, 4096, ssid->psk, PMK_LEN); wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)", ssid->psk, PMK_LEN); ssid->psk_set = 1; } if ((ssid->key_mgmt & WPA_KEY_MGMT_PSK) && !ssid->psk_set) { wpa_printf(MSG_ERROR, "Line %d: WPA-PSK accepted for key " "management, but no PSK configured.", *line); errors++; } if ((ssid->group_cipher & WPA_CIPHER_CCMP) && !(ssid->pairwise_cipher & WPA_CIPHER_CCMP)) { /* Group cipher cannot be stronger than the pairwise cipher. */ wpa_printf(MSG_DEBUG, "Line %d: removed CCMP from group cipher" " list since it was not allowed for pairwise " "cipher", *line); ssid->group_cipher &= ~WPA_CIPHER_CCMP; } if (errors) { free(ssid); ssid = NULL; } return ssid; }
struct wpa_config * wpa_config_read(const char *name) { FILE *f; char buf[512], *pos; int errors = 0, line = 0; struct wpa_ssid *ssid, *tail = NULL, *head = NULL; struct wpa_cred *cred, *cred_tail = NULL, *cred_head = NULL; struct wpa_config *config; int id = 0; int cred_id = 0; config = wpa_config_alloc_empty(NULL, NULL); if (config == NULL) return NULL; wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name); f = fopen(name, "r"); if (f == NULL) { os_free(config); return NULL; } while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) { if (os_strcmp(pos, "network={") == 0) { ssid = wpa_config_read_network(f, &line, id++); if (ssid == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse network block.", line); errors++; continue; } if (head == NULL) { head = tail = ssid; } else { tail->next = ssid; tail = ssid; } if (wpa_config_add_prio_network(config, ssid)) { wpa_printf(MSG_ERROR, "Line %d: failed to add " "network block to priority list.", line); errors++; continue; } } else if (os_strcmp(pos, "cred={") == 0) { cred = wpa_config_read_cred(f, &line, cred_id++); if (cred == NULL) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse cred block.", line); errors++; continue; } if (cred_head == NULL) { cred_head = cred_tail = cred; } else { cred_tail->next = cred; cred_tail = cred; } #ifndef CONFIG_NO_CONFIG_BLOBS } else if (os_strncmp(pos, "blob-base64-", 12) == 0) { if (wpa_config_process_blob(config, f, &line, pos + 12) < 0) { errors++; continue; } #endif /* CONFIG_NO_CONFIG_BLOBS */ #ifdef CONFIG_P2P } else if (os_strncmp(buf, "wme_ac_", 7) == 0 || os_strncmp(buf, "wmm_ac_", 7) == 0) { pos = os_strchr(buf, '='); if (pos == NULL) { wpa_printf(MSG_ERROR, "Line %d: invalid line '%s'", line, buf); errors++; continue; } *pos = '\0'; pos++; if (wpa_config_wmm_ac(config->wmm_ac_params, buf, pos)) { wpa_printf(MSG_ERROR, "Line %d: invalid WMM " "ac item", line); errors++; } #endif /* CONFIG_P2P */ } else if (wpa_config_process_global(config, pos, line) < 0) { wpa_printf(MSG_ERROR, "Line %d: Invalid configuration " "line '%s'.", line, pos); errors++; continue; } } fclose(f); config->ssid = head; wpa_config_debug_dump_networks(config); config->cred = cred_head; #ifndef WPA_IGNORE_CONFIG_ERRORS if (errors) { wpa_config_free(config); config = NULL; head = NULL; } #endif /* WPA_IGNORE_CONFIG_ERRORS */ return config; }