X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=blobdiff_plain;f=wpa_supplicant%2Fconfig_file.c;h=e72f8441fc784974fe99a5b5c3da1cfe805093b4;hp=bd59a8073f0cfa1644a6dc56e348615f2cdfc0f0;hb=6013bbe04f138f7d5d750a3e1939732cbde0426a;hpb=d42bc5e1786dd5131ca46ab7c0d3662d31f73b67 diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index bd59a80..e72f844 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -11,12 +11,17 @@ */ #include "includes.h" +#ifdef ANDROID +#include +#endif /* ANDROID */ #include "common.h" #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) @@ -141,6 +146,15 @@ static int wpa_config_validate_network(struct wpa_ssid *ssid, int line) ssid->group_cipher &= ~WPA_CIPHER_CCMP; } + if (ssid->mode == WPAS_MODE_MESH && + (ssid->key_mgmt != WPA_KEY_MGMT_NONE && + ssid->key_mgmt != WPA_KEY_MGMT_SAE)) { + wpa_printf(MSG_ERROR, + "Line %d: key_mgmt for mesh network should be open or SAE", + line); + errors++; + } + return errors; } @@ -156,6 +170,7 @@ static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id) ssid = os_zalloc(sizeof(*ssid)); if (ssid == NULL) return NULL; + dl_list_init(&ssid->psk_list); ssid->id = id; wpa_config_set_network_defaults(ssid); @@ -216,6 +231,7 @@ static struct wpa_cred * wpa_config_read_cred(FILE *f, int *line, int id) 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) { @@ -343,23 +359,34 @@ static int wpa_config_process_blob(struct wpa_config *config, FILE *f, #endif /* CONFIG_NO_CONFIG_BLOBS */ -struct wpa_config * wpa_config_read(const char *name) +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 = NULL, *head = NULL; - struct wpa_cred *cred, *cred_tail = NULL, *cred_head = NULL; + 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; - config = wpa_config_alloc_empty(NULL, NULL); + 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"); @@ -474,7 +501,12 @@ static void write_bssid(FILE *f, struct wpa_ssid *ssid) static void write_psk(FILE *f, struct wpa_ssid *ssid) { - char *value = wpa_config_get(ssid, "psk"); + char *value; + + if (ssid->mem_only_psk) + return; + + value = wpa_config_get(ssid, "psk"); if (value == NULL) return; fprintf(f, "\tpsk=%s\n", value); @@ -584,7 +616,7 @@ static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid) int res; res = os_snprintf(field, sizeof(field), "wep_key%d", idx); - if (res < 0 || (size_t) res >= sizeof(field)) + if (os_snprintf_error(sizeof(field), res)) return; value = wpa_config_get(ssid, field); if (value) { @@ -595,6 +627,16 @@ static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid) #ifdef CONFIG_P2P + +static void write_go_p2p_dev_addr(FILE *f, struct wpa_ssid *ssid) +{ + char *value = wpa_config_get(ssid, "go_p2p_dev_addr"); + if (value == NULL) + return; + fprintf(f, "\tgo_p2p_dev_addr=%s\n", value); + os_free(value); +} + static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid) { char *value = wpa_config_get(ssid, "p2p_client_list"); @@ -603,6 +645,20 @@ static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid) fprintf(f, "\tp2p_client_list=%s\n", value); os_free(value); } + + +static void write_psk_list(FILE *f, struct wpa_ssid *ssid) +{ + struct psk_list_entry *psk; + char hex[32 * 2 + 1]; + + dl_list_for_each(psk, &ssid->psk_list, struct psk_list_entry, list) { + wpa_snprintf_hex(hex, sizeof(hex), psk->psk, sizeof(psk->psk)); + fprintf(f, "\tpsk_list=%s" MACSTR "-%s\n", + psk->p2p ? "P2P-" : "", MAC2STR(psk->addr), hex); + } +} + #endif /* CONFIG_P2P */ @@ -619,7 +675,10 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) STR(ssid); INT(scan_ssid); write_bssid(f, ssid); + write_str(f, "bssid_blacklist", ssid); + write_str(f, "bssid_whitelist", ssid); write_psk(f, ssid); + INT(mem_only_psk); write_proto(f, ssid); write_key_mgmt(f, ssid); INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD); @@ -628,6 +687,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) write_auth_alg(f, ssid); STR(bgscan); STR(autoscan); + STR(scan_freq); #ifdef IEEE8021X_EAPOL write_eap(f, ssid); STR(identity); @@ -641,6 +701,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) STR(dh_file); STR(subject_match); STR(altsubject_match); + STR(domain_suffix_match); + STR(domain_match); STR(ca_cert2); STR(ca_path2); STR(client_cert2); @@ -649,6 +711,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) STR(dh_file2); STR(subject_match2); STR(altsubject_match2); + STR(domain_suffix_match2); + STR(domain_match2); STR(phase1); STR(phase2); STR(pcsc); @@ -665,6 +729,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INTe(engine); INTe(engine2); INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS); + STR(openssl_ciphers); + INTe(erp); #endif /* IEEE8021X_EAPOL */ for (i = 0; i < 4; i++) write_wep_key(f, i, ssid); @@ -674,18 +740,84 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND); STR(pac_file); INT_DEFe(fragment_size, DEFAULT_FRAGMENT_SIZE); + INTe(ocsp); + INT_DEFe(sim_num, DEFAULT_USER_SELECTED_SIM); #endif /* IEEE8021X_EAPOL */ INT(mode); - INT(proactive_key_caching); + INT(no_auto_peer); + INT(frequency); + INT(fixed_freq); +#ifdef CONFIG_ACS + INT(acs); +#endif /* CONFIG_ACS */ + write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1); INT(disabled); INT(peerkey); + INT(mixed_cell); + INT(max_oper_chwidth); + INT(pbss); + INT(wps_disabled); #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_go_p2p_dev_addr(f, ssid); write_p2p_client_list(f, ssid); + write_psk_list(f, ssid); #endif /* CONFIG_P2P */ + INT(ap_max_inactivity); + INT(dtim_period); + INT(beacon_int); +#ifdef CONFIG_MACSEC + INT(macsec_policy); +#endif /* CONFIG_MACSEC */ +#ifdef CONFIG_HS20 + INT(update_identifier); +#endif /* CONFIG_HS20 */ + write_int(f, "mac_addr", ssid->mac_addr, -1); +#ifdef CONFIG_MESH + STR(mesh_basic_rates); + INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES); + INT_DEF(dot11MeshRetryTimeout, DEFAULT_MESH_RETRY_TIMEOUT); + INT_DEF(dot11MeshConfirmTimeout, DEFAULT_MESH_CONFIRM_TIMEOUT); + INT_DEF(dot11MeshHoldingTimeout, DEFAULT_MESH_HOLDING_TIMEOUT); +#endif /* CONFIG_MESH */ + INT(wpa_ptk_rekey); + INT(ignore_broadcast_ssid); +#ifdef CONFIG_HT_OVERRIDES + INT_DEF(disable_ht, DEFAULT_DISABLE_HT); + INT_DEF(disable_ht40, DEFAULT_DISABLE_HT40); + INT_DEF(disable_sgi, DEFAULT_DISABLE_SGI); + INT_DEF(disable_ldpc, DEFAULT_DISABLE_LDPC); + INT(ht40_intolerant); + INT_DEF(disable_max_amsdu, DEFAULT_DISABLE_MAX_AMSDU); + INT_DEF(ampdu_factor, DEFAULT_AMPDU_FACTOR); + INT_DEF(ampdu_density, DEFAULT_AMPDU_DENSITY); + STR(ht_mcs); +#endif /* CONFIG_HT_OVERRIDES */ +#ifdef CONFIG_VHT_OVERRIDES + INT(disable_vht); + INT(vht_capa); + INT(vht_capa_mask); + INT_DEF(vht_rx_mcs_nss_1, -1); + INT_DEF(vht_rx_mcs_nss_2, -1); + INT_DEF(vht_rx_mcs_nss_3, -1); + INT_DEF(vht_rx_mcs_nss_4, -1); + INT_DEF(vht_rx_mcs_nss_5, -1); + INT_DEF(vht_rx_mcs_nss_6, -1); + INT_DEF(vht_rx_mcs_nss_7, -1); + INT_DEF(vht_rx_mcs_nss_8, -1); + INT_DEF(vht_tx_mcs_nss_1, -1); + INT_DEF(vht_tx_mcs_nss_2, -1); + INT_DEF(vht_tx_mcs_nss_3, -1); + INT_DEF(vht_tx_mcs_nss_4, -1); + INT_DEF(vht_tx_mcs_nss_5, -1); + INT_DEF(vht_tx_mcs_nss_6, -1); + INT_DEF(vht_tx_mcs_nss_7, -1); + INT_DEF(vht_tx_mcs_nss_8, -1); +#endif /* CONFIG_VHT_OVERRIDES */ #undef STR #undef INT @@ -695,6 +827,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred) { + size_t i; + if (cred->priority) fprintf(f, "\tpriority=%d\n", cred->priority); if (cred->pcsc) @@ -703,16 +837,119 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred) fprintf(f, "\trealm=\"%s\"\n", cred->realm); if (cred->username) fprintf(f, "\tusername=\"%s\"\n", cred->username); - if (cred->password) + 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); + for (i = 0; i < cred->num_domain; i++) + fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]); + if (cred->domain_suffix_match) + fprintf(f, "\tdomain_suffix_match=\"%s\"\n", + cred->domain_suffix_match); + if (cred->roaming_consortium_len) { + 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); + if (name) + 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 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"); + } + } + if (cred->roaming_partner) { + for (i = 0; i < cred->num_roaming_partner; i++) { + struct roaming_partner *p = &cred->roaming_partner[i]; + fprintf(f, "\troaming_partner=\"%s,%d,%u,%s\"\n", + p->fqdn, p->exact_match, p->priority, + p->country); + } + } + if (cred->update_identifier) + fprintf(f, "\tupdate_identifier=%d\n", cred->update_identifier); + + if (cred->provisioning_sp) + fprintf(f, "\tprovisioning_sp=\"%s\"\n", cred->provisioning_sp); + if (cred->sp_priority) + fprintf(f, "\tsp_priority=%d\n", cred->sp_priority); + + if (cred->min_dl_bandwidth_home) + fprintf(f, "\tmin_dl_bandwidth_home=%u\n", + cred->min_dl_bandwidth_home); + if (cred->min_ul_bandwidth_home) + fprintf(f, "\tmin_ul_bandwidth_home=%u\n", + cred->min_ul_bandwidth_home); + if (cred->min_dl_bandwidth_roaming) + fprintf(f, "\tmin_dl_bandwidth_roaming=%u\n", + cred->min_dl_bandwidth_roaming); + if (cred->min_ul_bandwidth_roaming) + fprintf(f, "\tmin_ul_bandwidth_roaming=%u\n", + cred->min_ul_bandwidth_roaming); + + if (cred->max_bss_load) + fprintf(f, "\tmax_bss_load=%u\n", + cred->max_bss_load); + + if (cred->ocsp) + fprintf(f, "\tocsp=%d\n", cred->ocsp); + + if (cred->num_req_conn_capab) { + for (i = 0; i < cred->num_req_conn_capab; i++) { + int *ports; + + fprintf(f, "\treq_conn_capab=%u", + cred->req_conn_capab_proto[i]); + ports = cred->req_conn_capab_port[i]; + if (ports) { + int j; + for (j = 0; ports[j] != -1; j++) { + fprintf(f, "%s%d", j > 0 ? "," : ":", + ports[j]); + } + } + fprintf(f, "\n"); + } + } + + if (cred->required_roaming_consortium_len) { + fprintf(f, "\trequired_roaming_consortium="); + for (i = 0; i < cred->required_roaming_consortium_len; i++) + fprintf(f, "%02x", + cred->required_roaming_consortium[i]); + fprintf(f, "\n"); + } + + if (cred->sim_num != DEFAULT_USER_SELECTED_SIM) + fprintf(f, "\tsim_num=%d\n", cred->sim_num); } @@ -776,6 +1013,8 @@ 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->openssl_ciphers) + fprintf(f, "openssl_ciphers=%s\n", config->openssl_ciphers); if (config->pcsc_reader) fprintf(f, "pcsc_reader=%s\n", config->pcsc_reader); if (config->pcsc_pin) @@ -783,13 +1022,13 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->driver_param) fprintf(f, "driver_param=%s\n", config->driver_param); if (config->dot11RSNAConfigPMKLifetime) - fprintf(f, "dot11RSNAConfigPMKLifetime=%d\n", + fprintf(f, "dot11RSNAConfigPMKLifetime=%u\n", config->dot11RSNAConfigPMKLifetime); if (config->dot11RSNAConfigPMKReauthThreshold) - fprintf(f, "dot11RSNAConfigPMKReauthThreshold=%d\n", + fprintf(f, "dot11RSNAConfigPMKReauthThreshold=%u\n", config->dot11RSNAConfigPMKReauthThreshold); if (config->dot11RSNAConfigSATimeout) - fprintf(f, "dot11RSNAConfigSATimeout=%d\n", + fprintf(f, "dot11RSNAConfigSATimeout=%u\n", config->dot11RSNAConfigSATimeout); if (config->update_config) fprintf(f, "update_config=%d\n", config->update_config); @@ -837,27 +1076,30 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P if (config->p2p_listen_reg_class) - fprintf(f, "p2p_listen_reg_class=%u\n", + fprintf(f, "p2p_listen_reg_class=%d\n", config->p2p_listen_reg_class); if (config->p2p_listen_channel) - fprintf(f, "p2p_listen_channel=%u\n", + fprintf(f, "p2p_listen_channel=%d\n", config->p2p_listen_channel); if (config->p2p_oper_reg_class) - fprintf(f, "p2p_oper_reg_class=%u\n", + fprintf(f, "p2p_oper_reg_class=%d\n", config->p2p_oper_reg_class); if (config->p2p_oper_channel) - fprintf(f, "p2p_oper_channel=%u\n", config->p2p_oper_channel); + fprintf(f, "p2p_oper_channel=%d\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); + fprintf(f, "p2p_go_intent=%d\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", + fprintf(f, "persistent_reconnect=%d\n", config->persistent_reconnect); if (config->p2p_intra_bss != DEFAULT_P2P_INTRA_BSS) - fprintf(f, "p2p_intra_bss=%u\n", config->p2p_intra_bss); + fprintf(f, "p2p_intra_bss=%d\n", config->p2p_intra_bss); if (config->p2p_group_idle) - fprintf(f, "p2p_group_idle=%u\n", config->p2p_group_idle); + fprintf(f, "p2p_group_idle=%d\n", config->p2p_group_idle); + if (config->p2p_passphrase_len) + fprintf(f, "p2p_passphrase_len=%u\n", + config->p2p_passphrase_len); if (config->p2p_pref_chan) { unsigned int i; fprintf(f, "p2p_pref_chan="); @@ -868,6 +1110,54 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) } fprintf(f, "\n"); } + if (config->p2p_no_go_freq.num) { + char *val = freq_range_list_str(&config->p2p_no_go_freq); + if (val) { + fprintf(f, "p2p_no_go_freq=%s\n", val); + os_free(val); + } + } + if (config->p2p_add_cli_chan) + fprintf(f, "p2p_add_cli_chan=%d\n", config->p2p_add_cli_chan); + if (config->p2p_optimize_listen_chan != + DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN) + fprintf(f, "p2p_optimize_listen_chan=%d\n", + config->p2p_optimize_listen_chan); + if (config->p2p_go_ht40) + fprintf(f, "p2p_go_ht40=%d\n", config->p2p_go_ht40); + if (config->p2p_go_vht) + fprintf(f, "p2p_go_vht=%d\n", config->p2p_go_vht); + if (config->p2p_go_ctwindow != DEFAULT_P2P_GO_CTWINDOW) + fprintf(f, "p2p_go_ctwindow=%d\n", config->p2p_go_ctwindow); + if (config->p2p_disabled) + fprintf(f, "p2p_disabled=%d\n", config->p2p_disabled); + if (config->p2p_no_group_iface) + fprintf(f, "p2p_no_group_iface=%d\n", + config->p2p_no_group_iface); + if (config->p2p_ignore_shared_freq) + fprintf(f, "p2p_ignore_shared_freq=%d\n", + config->p2p_ignore_shared_freq); + if (config->p2p_cli_probe) + fprintf(f, "p2p_cli_probe=%d\n", config->p2p_cli_probe); + if (config->p2p_go_freq_change_policy != DEFAULT_P2P_GO_FREQ_MOVE) + fprintf(f, "p2p_go_freq_change_policy=%u\n", + config->p2p_go_freq_change_policy); + if (WPA_GET_BE32(config->ip_addr_go)) + fprintf(f, "ip_addr_go=%u.%u.%u.%u\n", + config->ip_addr_go[0], config->ip_addr_go[1], + config->ip_addr_go[2], config->ip_addr_go[3]); + if (WPA_GET_BE32(config->ip_addr_mask)) + fprintf(f, "ip_addr_mask=%u.%u.%u.%u\n", + config->ip_addr_mask[0], config->ip_addr_mask[1], + config->ip_addr_mask[2], config->ip_addr_mask[3]); + if (WPA_GET_BE32(config->ip_addr_start)) + fprintf(f, "ip_addr_start=%u.%u.%u.%u\n", + config->ip_addr_start[0], config->ip_addr_start[1], + config->ip_addr_start[2], config->ip_addr_start[3]); + if (WPA_GET_BE32(config->ip_addr_end)) + fprintf(f, "ip_addr_end=%u.%u.%u.%u\n", + config->ip_addr_end[0], config->ip_addr_end[1], + config->ip_addr_end[2], config->ip_addr_end[3]); #endif /* CONFIG_P2P */ if (config->country[0] && config->country[1]) { fprintf(f, "country=%c%c\n", @@ -887,14 +1177,14 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) 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); + fprintf(f, "disassoc_low_ack=%d\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); + fprintf(f, "interworking=%d\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) @@ -902,13 +1192,17 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) 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); + fprintf(f, "pbc_in_m1=%d\n", config->pbc_in_m1); + if (config->wps_nfc_pw_from_config) { + 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", @@ -916,6 +1210,134 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) 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); + if (config->dtim_period) + fprintf(f, "dtim_period=%d\n", config->dtim_period); + if (config->beacon_int) + fprintf(f, "beacon_int=%d\n", config->beacon_int); + + if (config->sae_groups) { + int i; + fprintf(f, "sae_groups="); + for (i = 0; config->sae_groups[i] >= 0; i++) { + fprintf(f, "%s%d", i > 0 ? " " : "", + config->sae_groups[i]); + } + fprintf(f, "\n"); + } + + if (config->ap_vendor_elements) { + int i, len = wpabuf_len(config->ap_vendor_elements); + const u8 *p = wpabuf_head_u8(config->ap_vendor_elements); + if (len > 0) { + fprintf(f, "ap_vendor_elements="); + for (i = 0; i < len; i++) + fprintf(f, "%02x", *p++); + fprintf(f, "\n"); + } + } + + if (config->ignore_old_scan_res) + fprintf(f, "ignore_old_scan_res=%d\n", + config->ignore_old_scan_res); + + if (config->freq_list && config->freq_list[0]) { + int i; + fprintf(f, "freq_list="); + for (i = 0; config->freq_list[i]; i++) { + fprintf(f, "%s%d", i > 0 ? " " : "", + config->freq_list[i]); + } + fprintf(f, "\n"); + } + if (config->scan_cur_freq != DEFAULT_SCAN_CUR_FREQ) + fprintf(f, "scan_cur_freq=%d\n", config->scan_cur_freq); + + if (config->sched_scan_interval) + fprintf(f, "sched_scan_interval=%u\n", + config->sched_scan_interval); + + if (config->external_sim) + fprintf(f, "external_sim=%d\n", config->external_sim); + + if (config->tdls_external_control) + fprintf(f, "tdls_external_control=%d\n", + config->tdls_external_control); + + if (config->wowlan_triggers) + fprintf(f, "wowlan_triggers=%s\n", + config->wowlan_triggers); + + if (config->bgscan) + fprintf(f, "bgscan=\"%s\"\n", config->bgscan); + + if (config->p2p_search_delay != DEFAULT_P2P_SEARCH_DELAY) + fprintf(f, "p2p_search_delay=%u\n", + config->p2p_search_delay); + + if (config->mac_addr) + fprintf(f, "mac_addr=%d\n", config->mac_addr); + + if (config->rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME) + fprintf(f, "rand_addr_lifetime=%u\n", + config->rand_addr_lifetime); + + if (config->preassoc_mac_addr) + fprintf(f, "preassoc_mac_addr=%d\n", config->preassoc_mac_addr); + + if (config->key_mgmt_offload != DEFAULT_KEY_MGMT_OFFLOAD) + fprintf(f, "key_mgmt_offload=%d\n", config->key_mgmt_offload); + + if (config->user_mpm != DEFAULT_USER_MPM) + fprintf(f, "user_mpm=%d\n", config->user_mpm); + + if (config->max_peer_links != DEFAULT_MAX_PEER_LINKS) + fprintf(f, "max_peer_links=%d\n", config->max_peer_links); + + if (config->cert_in_cb != DEFAULT_CERT_IN_CB) + fprintf(f, "cert_in_cb=%d\n", config->cert_in_cb); + + if (config->mesh_max_inactivity != DEFAULT_MESH_MAX_INACTIVITY) + fprintf(f, "mesh_max_inactivity=%d\n", + config->mesh_max_inactivity); + + if (config->dot11RSNASAERetransPeriod != + DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD) + fprintf(f, "dot11RSNASAERetransPeriod=%d\n", + config->dot11RSNASAERetransPeriod); + + if (config->passive_scan) + fprintf(f, "passive_scan=%d\n", config->passive_scan); + + if (config->reassoc_same_bss_optim) + fprintf(f, "reassoc_same_bss_optim=%d\n", + config->reassoc_same_bss_optim); + + if (config->wps_priority) + fprintf(f, "wps_priority=%d\n", config->wps_priority); + + if (config->wpa_rsc_relaxation != DEFAULT_WPA_RSC_RELAXATION) + fprintf(f, "wpa_rsc_relaxation=%d\n", + config->wpa_rsc_relaxation); + + if (config->sched_scan_plans) + fprintf(f, "sched_scan_plans=%s\n", config->sched_scan_plans); + +#ifdef CONFIG_MBO + if (config->non_pref_chan) + fprintf(f, "non_pref_chan=%s\n", config->non_pref_chan); + if (config->mbo_cell_capa != DEFAULT_MBO_CELL_CAPA) + fprintf(f, "mbo_cell_capa=%u\n", config->mbo_cell_capa); +#endif /* CONFIG_MBO */ + + if (config->gas_address3) + fprintf(f, "gas_address3=%d\n", config->gas_address3); } #endif /* CONFIG_NO_CONFIG_WRITE */ @@ -931,18 +1353,29 @@ int wpa_config_write(const char *name, struct wpa_config *config) struct wpa_config_blob *blob; #endif /* CONFIG_NO_CONFIG_BLOBS */ int ret = 0; + const char *orig_name = name; + int tmp_len = os_strlen(name) + 5; /* allow space for .tmp suffix */ + char *tmp_name = os_malloc(tmp_len); + + if (tmp_name) { + os_snprintf(tmp_name, tmp_len, "%s.tmp", name); + name = tmp_name; + } wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name); f = fopen(name, "w"); if (f == NULL) { wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name); + os_free(tmp_name); return -1; } wpa_config_write_global(f, config); for (cred = config->cred; cred; cred = cred->next) { + if (cred->temporary) + continue; fprintf(f, "\ncred={\n"); wpa_config_write_cred(f, cred); fprintf(f, "}\n"); @@ -967,10 +1400,25 @@ int wpa_config_write(const char *name, struct wpa_config *config) } #endif /* CONFIG_NO_CONFIG_BLOBS */ + os_fdatasync(f); + fclose(f); + if (tmp_name) { + int chmod_ret = 0; + +#ifdef ANDROID + chmod_ret = chmod(tmp_name, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +#endif /* ANDROID */ + if (chmod_ret != 0 || rename(tmp_name, orig_name) != 0) + ret = -1; + + os_free(tmp_name); + } + wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully", - name, ret ? "un" : ""); + orig_name, ret ? "un" : ""); return ret; #else /* CONFIG_NO_CONFIG_WRITE */ return -1;