diff options
Diffstat (limited to 'contrib/wpa/wpa_supplicant/config_file.c')
-rw-r--r-- | contrib/wpa/wpa_supplicant/config_file.c | 601 |
1 files changed, 343 insertions, 258 deletions
diff --git a/contrib/wpa/wpa_supplicant/config_file.c b/contrib/wpa/wpa_supplicant/config_file.c index 5f07045..8f32cc8 100644 --- a/contrib/wpa/wpa_supplicant/config_file.c +++ b/contrib/wpa/wpa_supplicant/config_file.c @@ -1,15 +1,9 @@ /* * WPA Supplicant / Configuration backend: text file - * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> + * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. * * This file implements a configuration backend for text files. All the * configuration information is stored in a text file that uses a format @@ -22,7 +16,32 @@ #include "config.h" #include "base64.h" #include "uuid.h" +#include "p2p/p2p.h" #include "eap_peer/eap_methods.h" +#include "eap_peer/eap.h" + + +static int newline_terminated(const char *buf, size_t buflen) +{ + size_t len = os_strlen(buf); + if (len == 0) + return 0; + if (len == buflen - 1 && buf[buflen - 1] != '\r' && + buf[len - 1] != '\n') + return 0; + return 1; +} + + +static void skip_line_end(FILE *stream) +{ + char buf[100]; + while (fgets(buf, sizeof(buf), stream)) { + buf[sizeof(buf) - 1] = '\0'; + if (newline_terminated(buf, sizeof(buf))) + return; + } +} /** @@ -47,6 +66,15 @@ static char * wpa_config_get_line(char *s, int size, FILE *stream, int *line, while (fgets(s, size, stream)) { (*line)++; s[size - 1] = '\0'; + if (!newline_terminated(s, size)) { + /* + * The line was truncated - skip rest of it to avoid + * confusing error messages. + */ + wpa_printf(MSG_INFO, "Long line in configuration file " + "truncated"); + skip_line_end(stream); + } pos = s; /* Skip white space from the beginning of line. */ @@ -105,14 +133,6 @@ static int wpa_config_validate_network(struct wpa_ssid *ssid, int line) wpa_config_update_psk(ssid); } - if ((ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK | - WPA_KEY_MGMT_PSK_SHA256)) && - !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) && !(ssid->pairwise_cipher & WPA_CIPHER_NONE)) { @@ -131,7 +151,7 @@ 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; + char buf[2000], *pos, *pos2; wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new network block", *line); @@ -187,6 +207,61 @@ static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id) } +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; + + 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; +} + + #ifndef CONFIG_NO_CONFIG_BLOBS static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line, const char *name) @@ -270,253 +345,29 @@ static int wpa_config_process_blob(struct wpa_config *config, FILE *f, #endif /* CONFIG_NO_CONFIG_BLOBS */ -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; - } - - 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; - } - - return 0; -} - - -static int wpa_config_parse_str(const struct global_parse_data *data, - struct wpa_config *config, int line, - const char *pos) -{ - size_t len; - char **dst, *tmp; - - 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; - } - - 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); - - return 0; -} - - -static int wpa_config_process_country(const struct global_parse_data *data, - struct wpa_config *config, int line, - const char *pos) -{ - 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; -} - - -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); - 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); - return -1; - } - - return 0; -} - - -#ifdef CONFIG_WPS - -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)) { - wpa_printf(MSG_ERROR, "Line %d: invalid UUID", line); - return -1; - } - uuid_bin2str(config->uuid, buf, sizeof(buf)); - wpa_printf(MSG_DEBUG, "uuid=%s", buf); - return 0; -} - - -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); - return -1; - } - wpa_printf(MSG_DEBUG, "os_version=%08x", - WPA_GET_BE32(config->os_version)); - return 0; -} - -#endif /* CONFIG_WPS */ - - -#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) - -#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) }, - { STR(opensc_engine_path) }, - { STR(pkcs11_engine_path) }, - { STR(pkcs11_module_path) }, - { STR(driver_param) }, - { INT(dot11RSNAConfigPMKLifetime) }, - { INT(dot11RSNAConfigPMKReauthThreshold) }, - { INT(dot11RSNAConfigSATimeout) }, -#ifndef CONFIG_NO_CONFIG_WRITE - { INT(update_config) }, -#endif /* CONFIG_NO_CONFIG_WRITE */ - { FUNC_NO_VAR(load_dynamic_eap) }, -#ifdef CONFIG_WPS - { 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) }, - { STR(config_methods) }, - { INT_RANGE(wps_cred_processing, 0, 2) }, -#endif /* CONFIG_WPS */ - { FUNC(country) }, - { INT(bss_max_count) }, - { INT_RANGE(filter_ssids, 0, 1) } -}; - -#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])) - - -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; -} - - struct wpa_config * wpa_config_read(const char *name) { FILE *f; - char buf[256], *pos; + 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) + if (config == NULL) { + wpa_printf(MSG_ERROR, "Failed to allocate config file " + "structure"); return NULL; + } + 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; } @@ -543,10 +394,26 @@ struct wpa_config * wpa_config_read(const char *name) 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; } @@ -563,12 +430,15 @@ struct wpa_config * wpa_config_read(const char *name) 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; } @@ -726,6 +596,18 @@ static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid) } +#ifdef CONFIG_P2P +static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid) +{ + char *value = wpa_config_get(ssid, "p2p_client_list"); + if (value == NULL) + return; + fprintf(f, "\tp2p_client_list=%s\n", value); + os_free(value); +} +#endif /* CONFIG_P2P */ + + static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) { int i; @@ -742,9 +624,12 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) write_psk(f, ssid); write_proto(f, ssid); write_key_mgmt(f, ssid); + INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD); write_pairwise(f, ssid); write_group(f, ssid); write_auth_alg(f, ssid); + STR(bgscan); + STR(autoscan); #ifdef IEEE8021X_EAPOL write_eap(f, ssid); STR(identity); @@ -793,13 +678,18 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE); #endif /* IEEE8021X_EAPOL */ INT(mode); - INT(proactive_key_caching); + INT(frequency); + write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1); INT(disabled); INT(peerkey); #ifdef CONFIG_IEEE80211W - INT(ieee80211w); + write_int(f, "ieee80211w", ssid->ieee80211w, + MGMT_FRAME_PROTECTION_DEFAULT); #endif /* CONFIG_IEEE80211W */ STR(id_str); +#ifdef CONFIG_P2P + write_p2p_client_list(f, ssid); +#endif /* CONFIG_P2P */ #undef STR #undef INT @@ -807,6 +697,65 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) } +static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred) +{ + if (cred->priority) + fprintf(f, "\tpriority=%d\n", cred->priority); + if (cred->pcsc) + fprintf(f, "\tpcsc=%d\n", cred->pcsc); + if (cred->realm) + fprintf(f, "\trealm=\"%s\"\n", cred->realm); + if (cred->username) + fprintf(f, "\tusername=\"%s\"\n", cred->username); + if (cred->password && cred->ext_password) + fprintf(f, "\tpassword=ext:%s\n", cred->password); + else if (cred->password) + fprintf(f, "\tpassword=\"%s\"\n", cred->password); + if (cred->ca_cert) + fprintf(f, "\tca_cert=\"%s\"\n", cred->ca_cert); + if (cred->client_cert) + fprintf(f, "\tclient_cert=\"%s\"\n", cred->client_cert); + if (cred->private_key) + fprintf(f, "\tprivate_key=\"%s\"\n", cred->private_key); + if (cred->private_key_passwd) + fprintf(f, "\tprivate_key_passwd=\"%s\"\n", + cred->private_key_passwd); + if (cred->imsi) + fprintf(f, "\timsi=\"%s\"\n", cred->imsi); + if (cred->milenage) + fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage); + if (cred->domain) + fprintf(f, "\tdomain=\"%s\"\n", cred->domain); + if (cred->roaming_consortium_len) { + size_t i; + fprintf(f, "\troaming_consortium="); + for (i = 0; i < cred->roaming_consortium_len; i++) + fprintf(f, "%02x", cred->roaming_consortium[i]); + fprintf(f, "\n"); + } + if (cred->eap_method) { + const char *name; + name = eap_get_name(cred->eap_method[0].vendor, + cred->eap_method[0].method); + fprintf(f, "\teap=%s\n", name); + } + if (cred->phase1) + fprintf(f, "\tphase1=\"%s\"\n", cred->phase1); + if (cred->phase2) + fprintf(f, "\tphase2=\"%s\"\n", cred->phase2); + if (cred->excluded_ssid) { + size_t i, j; + for (i = 0; i < cred->num_excluded_ssid; i++) { + struct excluded_ssid *e = &cred->excluded_ssid[i]; + fprintf(f, "\texcluded_ssid="); + for (j = 0; j < e->ssid_len; j++) + fprintf(f, "%02x", e->ssid[j]); + fprintf(f, "\n"); + } + } +} + + #ifndef CONFIG_NO_CONFIG_BLOBS static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob) { @@ -823,6 +772,23 @@ static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob) #endif /* CONFIG_NO_CONFIG_BLOBS */ +static void write_global_bin(FILE *f, const char *field, + const struct wpabuf *val) +{ + size_t i; + const u8 *pos; + + if (val == NULL) + return; + + fprintf(f, "%s=", field); + pos = wpabuf_head(val); + for (i = 0; i < wpabuf_len(val); i++) + fprintf(f, "%02X", *pos++); + fprintf(f, "\n"); +} + + static void wpa_config_write_global(FILE *f, struct wpa_config *config) { #ifdef CONFIG_CTRL_IFACE @@ -836,6 +802,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "eapol_version=%d\n", config->eapol_version); if (config->ap_scan != DEFAULT_AP_SCAN) fprintf(f, "ap_scan=%d\n", config->ap_scan); + if (config->disable_scan_offload) + fprintf(f, "disable_scan_offload=%d\n", + config->disable_scan_offload); if (config->fast_reauth != DEFAULT_FAST_REAUTH) fprintf(f, "fast_reauth=%d\n", config->fast_reauth); if (config->opensc_engine_path) @@ -847,6 +816,10 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->pkcs11_module_path) fprintf(f, "pkcs11_module_path=%s\n", config->pkcs11_module_path); + if (config->pcsc_reader) + fprintf(f, "pcsc_reader=%s\n", config->pcsc_reader); + if (config->pcsc_pin) + fprintf(f, "pcsc_pin=%s\n", config->pcsc_pin); if (config->driver_param) fprintf(f, "driver_param=%s\n", config->driver_param); if (config->dot11RSNAConfigPMKLifetime) @@ -876,8 +849,13 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "model_number=%s\n", config->model_number); if (config->serial_number) fprintf(f, "serial_number=%s\n", config->serial_number); - if (config->device_type) - fprintf(f, "device_type=%s\n", config->device_type); + { + char _buf[WPS_DEV_TYPE_BUFSIZE], *buf; + buf = wps_dev_type_bin2str(config->device_type, + _buf, sizeof(_buf)); + if (os_strcmp(buf, "0-00000000-0") != 0) + fprintf(f, "device_type=%s\n", buf); + } if (WPA_GET_BE32(config->os_version)) fprintf(f, "os_version=%08x\n", WPA_GET_BE32(config->os_version)); @@ -886,15 +864,112 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->wps_cred_processing) fprintf(f, "wps_cred_processing=%d\n", config->wps_cred_processing); + if (config->wps_vendor_ext_m1) { + int i, len = wpabuf_len(config->wps_vendor_ext_m1); + const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1); + if (len > 0) { + fprintf(f, "wps_vendor_ext_m1="); + for (i = 0; i < len; i++) + fprintf(f, "%02x", *p++); + fprintf(f, "\n"); + } + } #endif /* CONFIG_WPS */ +#ifdef CONFIG_P2P + if (config->p2p_listen_reg_class) + fprintf(f, "p2p_listen_reg_class=%u\n", + config->p2p_listen_reg_class); + if (config->p2p_listen_channel) + fprintf(f, "p2p_listen_channel=%u\n", + config->p2p_listen_channel); + if (config->p2p_oper_reg_class) + fprintf(f, "p2p_oper_reg_class=%u\n", + config->p2p_oper_reg_class); + if (config->p2p_oper_channel) + fprintf(f, "p2p_oper_channel=%u\n", config->p2p_oper_channel); + if (config->p2p_go_intent != DEFAULT_P2P_GO_INTENT) + fprintf(f, "p2p_go_intent=%u\n", config->p2p_go_intent); + if (config->p2p_ssid_postfix) + fprintf(f, "p2p_ssid_postfix=%s\n", config->p2p_ssid_postfix); + if (config->persistent_reconnect) + fprintf(f, "persistent_reconnect=%u\n", + config->persistent_reconnect); + if (config->p2p_intra_bss != DEFAULT_P2P_INTRA_BSS) + fprintf(f, "p2p_intra_bss=%u\n", config->p2p_intra_bss); + if (config->p2p_group_idle) + fprintf(f, "p2p_group_idle=%u\n", config->p2p_group_idle); + if (config->p2p_pref_chan) { + unsigned int i; + fprintf(f, "p2p_pref_chan="); + for (i = 0; i < config->num_p2p_pref_chan; i++) { + fprintf(f, "%s%u:%u", i > 0 ? "," : "", + config->p2p_pref_chan[i].op_class, + config->p2p_pref_chan[i].chan); + } + fprintf(f, "\n"); + } + if (config->p2p_go_ht40) + fprintf(f, "p2p_go_ht40=%u\n", config->p2p_go_ht40); + if (config->p2p_disabled) + fprintf(f, "p2p_disabled=%u\n", config->p2p_disabled); + if (config->p2p_no_group_iface) + fprintf(f, "p2p_no_group_iface=%u\n", + config->p2p_no_group_iface); +#endif /* CONFIG_P2P */ if (config->country[0] && config->country[1]) { fprintf(f, "country=%c%c\n", config->country[0], config->country[1]); } if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT) fprintf(f, "bss_max_count=%u\n", config->bss_max_count); + if (config->bss_expiration_age != DEFAULT_BSS_EXPIRATION_AGE) + fprintf(f, "bss_expiration_age=%u\n", + config->bss_expiration_age); + if (config->bss_expiration_scan_count != + DEFAULT_BSS_EXPIRATION_SCAN_COUNT) + fprintf(f, "bss_expiration_scan_count=%u\n", + config->bss_expiration_scan_count); if (config->filter_ssids) fprintf(f, "filter_ssids=%d\n", config->filter_ssids); + if (config->max_num_sta != DEFAULT_MAX_NUM_STA) + fprintf(f, "max_num_sta=%u\n", config->max_num_sta); + if (config->disassoc_low_ack) + fprintf(f, "disassoc_low_ack=%u\n", config->disassoc_low_ack); +#ifdef CONFIG_HS20 + if (config->hs20) + fprintf(f, "hs20=1\n"); +#endif /* CONFIG_HS20 */ +#ifdef CONFIG_INTERWORKING + if (config->interworking) + fprintf(f, "interworking=%u\n", config->interworking); + if (!is_zero_ether_addr(config->hessid)) + fprintf(f, "hessid=" MACSTR "\n", MAC2STR(config->hessid)); + if (config->access_network_type != DEFAULT_ACCESS_NETWORK_TYPE) + fprintf(f, "access_network_type=%d\n", + config->access_network_type); +#endif /* CONFIG_INTERWORKING */ + if (config->pbc_in_m1) + fprintf(f, "pbc_in_m1=%u\n", config->pbc_in_m1); + if (config->wps_nfc_dev_pw_id) + fprintf(f, "wps_nfc_dev_pw_id=%d\n", + config->wps_nfc_dev_pw_id); + write_global_bin(f, "wps_nfc_dh_pubkey", config->wps_nfc_dh_pubkey); + write_global_bin(f, "wps_nfc_dh_privkey", config->wps_nfc_dh_privkey); + write_global_bin(f, "wps_nfc_dev_pw", config->wps_nfc_dev_pw); + + if (config->ext_password_backend) + fprintf(f, "ext_password_backend=%s\n", + config->ext_password_backend); + if (config->p2p_go_max_inactivity != DEFAULT_P2P_GO_MAX_INACTIVITY) + fprintf(f, "p2p_go_max_inactivity=%d\n", + config->p2p_go_max_inactivity); + if (config->auto_interworking) + fprintf(f, "auto_interworking=%d\n", + config->auto_interworking); + if (config->okc) + fprintf(f, "okc=%d\n", config->okc); + if (config->pmf) + fprintf(f, "pmf=%d\n", config->pmf); } #endif /* CONFIG_NO_CONFIG_WRITE */ @@ -905,6 +980,7 @@ int wpa_config_write(const char *name, struct wpa_config *config) #ifndef CONFIG_NO_CONFIG_WRITE FILE *f; struct wpa_ssid *ssid; + struct wpa_cred *cred; #ifndef CONFIG_NO_CONFIG_BLOBS struct wpa_config_blob *blob; #endif /* CONFIG_NO_CONFIG_BLOBS */ @@ -920,9 +996,18 @@ int wpa_config_write(const char *name, struct wpa_config *config) wpa_config_write_global(f, config); + for (cred = config->cred; cred; cred = cred->next) { + fprintf(f, "\ncred={\n"); + wpa_config_write_cred(f, cred); + fprintf(f, "}\n"); + } + for (ssid = config->ssid; ssid; ssid = ssid->next) { - if (ssid->key_mgmt == WPA_KEY_MGMT_WPS) - continue; /* do not save temporary WPS networks */ + if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary) + continue; /* do not save temporary networks */ + if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && + !ssid->passphrase) + continue; /* do not save invalid network */ fprintf(f, "\nnetwork={\n"); wpa_config_write_network(f, ssid); fprintf(f, "}\n"); |