139beb93cSSam Leffler /*
239beb93cSSam Leffler * WPA Supplicant / Configuration backend: text file
3c1d255d3SCy Schubert * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler *
5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license.
6f05cddf9SRui Paulo * See README for more details.
739beb93cSSam Leffler *
839beb93cSSam Leffler * This file implements a configuration backend for text files. All the
939beb93cSSam Leffler * configuration information is stored in a text file that uses a format
1039beb93cSSam Leffler * described in the sample configuration file, wpa_supplicant.conf.
1139beb93cSSam Leffler */
1239beb93cSSam Leffler
1339beb93cSSam Leffler #include "includes.h"
145b9c547cSRui Paulo #ifdef ANDROID
155b9c547cSRui Paulo #include <sys/stat.h>
165b9c547cSRui Paulo #endif /* ANDROID */
1739beb93cSSam Leffler
1839beb93cSSam Leffler #include "common.h"
1939beb93cSSam Leffler #include "config.h"
2039beb93cSSam Leffler #include "base64.h"
2139beb93cSSam Leffler #include "uuid.h"
2285732ac8SCy Schubert #include "common/ieee802_1x_defs.h"
23f05cddf9SRui Paulo #include "p2p/p2p.h"
2439beb93cSSam Leffler #include "eap_peer/eap_methods.h"
25f05cddf9SRui Paulo #include "eap_peer/eap.h"
26c1d255d3SCy Schubert #include "utils/config.h"
2739beb93cSSam Leffler
2839beb93cSSam Leffler
wpa_config_validate_network(struct wpa_ssid * ssid,int line)2939beb93cSSam Leffler static int wpa_config_validate_network(struct wpa_ssid *ssid, int line)
3039beb93cSSam Leffler {
3139beb93cSSam Leffler int errors = 0;
3239beb93cSSam Leffler
3339beb93cSSam Leffler if (ssid->passphrase) {
3439beb93cSSam Leffler if (ssid->psk_set) {
3539beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: both PSK and "
3639beb93cSSam Leffler "passphrase configured.", line);
3739beb93cSSam Leffler errors++;
3839beb93cSSam Leffler }
3939beb93cSSam Leffler wpa_config_update_psk(ssid);
4039beb93cSSam Leffler }
4139beb93cSSam Leffler
4285732ac8SCy Schubert if (ssid->disabled == 2)
4385732ac8SCy Schubert ssid->p2p_persistent_group = 1;
4485732ac8SCy Schubert
4539beb93cSSam Leffler if ((ssid->group_cipher & WPA_CIPHER_CCMP) &&
4685732ac8SCy Schubert !(ssid->pairwise_cipher & (WPA_CIPHER_CCMP | WPA_CIPHER_CCMP_256 |
4785732ac8SCy Schubert WPA_CIPHER_GCMP | WPA_CIPHER_GCMP_256 |
4885732ac8SCy Schubert WPA_CIPHER_NONE))) {
4939beb93cSSam Leffler /* Group cipher cannot be stronger than the pairwise cipher. */
5039beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Line %d: removed CCMP from group cipher"
5139beb93cSSam Leffler " list since it was not allowed for pairwise "
5239beb93cSSam Leffler "cipher", line);
5339beb93cSSam Leffler ssid->group_cipher &= ~WPA_CIPHER_CCMP;
5439beb93cSSam Leffler }
5539beb93cSSam Leffler
56*a90b9d01SCy Schubert if (is_6ghz_freq(ssid->frequency) && ssid->mode == WPAS_MODE_MESH &&
57*a90b9d01SCy Schubert ssid->key_mgmt == WPA_KEY_MGMT_NONE) {
58*a90b9d01SCy Schubert wpa_printf(MSG_ERROR,
59*a90b9d01SCy Schubert "Line %d: key_mgmt for mesh network in 6 GHz should be SAE",
60*a90b9d01SCy Schubert line);
61*a90b9d01SCy Schubert errors++;
62*a90b9d01SCy Schubert }
635b9c547cSRui Paulo if (ssid->mode == WPAS_MODE_MESH &&
645b9c547cSRui Paulo (ssid->key_mgmt != WPA_KEY_MGMT_NONE &&
655b9c547cSRui Paulo ssid->key_mgmt != WPA_KEY_MGMT_SAE)) {
665b9c547cSRui Paulo wpa_printf(MSG_ERROR,
675b9c547cSRui Paulo "Line %d: key_mgmt for mesh network should be open or SAE",
685b9c547cSRui Paulo line);
695b9c547cSRui Paulo errors++;
705b9c547cSRui Paulo }
715b9c547cSRui Paulo
724bc52338SCy Schubert #ifdef CONFIG_OCV
734bc52338SCy Schubert if (ssid->ocv && ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION) {
744bc52338SCy Schubert wpa_printf(MSG_ERROR,
754bc52338SCy Schubert "Line %d: PMF needs to be enabled whenever using OCV",
764bc52338SCy Schubert line);
774bc52338SCy Schubert errors++;
784bc52338SCy Schubert }
794bc52338SCy Schubert #endif /* CONFIG_OCV */
804bc52338SCy Schubert
8139beb93cSSam Leffler return errors;
8239beb93cSSam Leffler }
8339beb93cSSam Leffler
8439beb93cSSam Leffler
wpa_config_read_network(FILE * f,int * line,int id)8539beb93cSSam Leffler static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id)
8639beb93cSSam Leffler {
8739beb93cSSam Leffler struct wpa_ssid *ssid;
8839beb93cSSam Leffler int errors = 0, end = 0;
89f05cddf9SRui Paulo char buf[2000], *pos, *pos2;
9039beb93cSSam Leffler
9139beb93cSSam Leffler wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new network block",
9239beb93cSSam Leffler *line);
9339beb93cSSam Leffler ssid = os_zalloc(sizeof(*ssid));
9439beb93cSSam Leffler if (ssid == NULL)
9539beb93cSSam Leffler return NULL;
965b9c547cSRui Paulo dl_list_init(&ssid->psk_list);
9739beb93cSSam Leffler ssid->id = id;
9839beb93cSSam Leffler
9939beb93cSSam Leffler wpa_config_set_network_defaults(ssid);
10039beb93cSSam Leffler
10139beb93cSSam Leffler while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
10239beb93cSSam Leffler if (os_strcmp(pos, "}") == 0) {
10339beb93cSSam Leffler end = 1;
10439beb93cSSam Leffler break;
10539beb93cSSam Leffler }
10639beb93cSSam Leffler
10739beb93cSSam Leffler pos2 = os_strchr(pos, '=');
10839beb93cSSam Leffler if (pos2 == NULL) {
10939beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: Invalid SSID line "
11039beb93cSSam Leffler "'%s'.", *line, pos);
11139beb93cSSam Leffler errors++;
11239beb93cSSam Leffler continue;
11339beb93cSSam Leffler }
11439beb93cSSam Leffler
11539beb93cSSam Leffler *pos2++ = '\0';
11639beb93cSSam Leffler if (*pos2 == '"') {
11739beb93cSSam Leffler if (os_strchr(pos2 + 1, '"') == NULL) {
11839beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: invalid "
11939beb93cSSam Leffler "quotation '%s'.", *line, pos2);
12039beb93cSSam Leffler errors++;
12139beb93cSSam Leffler continue;
12239beb93cSSam Leffler }
12339beb93cSSam Leffler }
12439beb93cSSam Leffler
125c1d255d3SCy Schubert if (wpa_config_set(ssid, pos, pos2, *line) < 0) {
126c1d255d3SCy Schubert #ifndef CONFIG_WEP
127c1d255d3SCy Schubert if (os_strcmp(pos, "wep_key0") == 0 ||
128c1d255d3SCy Schubert os_strcmp(pos, "wep_key1") == 0 ||
129c1d255d3SCy Schubert os_strcmp(pos, "wep_key2") == 0 ||
130c1d255d3SCy Schubert os_strcmp(pos, "wep_key3") == 0 ||
131c1d255d3SCy Schubert os_strcmp(pos, "wep_tx_keyidx") == 0) {
132c1d255d3SCy Schubert wpa_printf(MSG_ERROR,
133c1d255d3SCy Schubert "Line %d: unsupported WEP parameter",
134c1d255d3SCy Schubert *line);
135c1d255d3SCy Schubert ssid->disabled = 1;
136c1d255d3SCy Schubert continue;
137c1d255d3SCy Schubert }
138c1d255d3SCy Schubert #endif /* CONFIG_WEP */
13939beb93cSSam Leffler errors++;
14039beb93cSSam Leffler }
141c1d255d3SCy Schubert }
14239beb93cSSam Leffler
14339beb93cSSam Leffler if (!end) {
14439beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: network block was not "
14539beb93cSSam Leffler "terminated properly.", *line);
14639beb93cSSam Leffler errors++;
14739beb93cSSam Leffler }
14839beb93cSSam Leffler
14939beb93cSSam Leffler errors += wpa_config_validate_network(ssid, *line);
15039beb93cSSam Leffler
15139beb93cSSam Leffler if (errors) {
15239beb93cSSam Leffler wpa_config_free_ssid(ssid);
15339beb93cSSam Leffler ssid = NULL;
15439beb93cSSam Leffler }
15539beb93cSSam Leffler
15639beb93cSSam Leffler return ssid;
15739beb93cSSam Leffler }
15839beb93cSSam Leffler
15939beb93cSSam Leffler
wpa_config_read_cred(FILE * f,int * line,int id)160f05cddf9SRui Paulo static struct wpa_cred * wpa_config_read_cred(FILE *f, int *line, int id)
161f05cddf9SRui Paulo {
162f05cddf9SRui Paulo struct wpa_cred *cred;
163f05cddf9SRui Paulo int errors = 0, end = 0;
164f05cddf9SRui Paulo char buf[256], *pos, *pos2;
165f05cddf9SRui Paulo
166f05cddf9SRui Paulo wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new cred block", *line);
167f05cddf9SRui Paulo cred = os_zalloc(sizeof(*cred));
168f05cddf9SRui Paulo if (cred == NULL)
169f05cddf9SRui Paulo return NULL;
170f05cddf9SRui Paulo cred->id = id;
1715b9c547cSRui Paulo cred->sim_num = DEFAULT_USER_SELECTED_SIM;
172f05cddf9SRui Paulo
173f05cddf9SRui Paulo while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
174f05cddf9SRui Paulo if (os_strcmp(pos, "}") == 0) {
175f05cddf9SRui Paulo end = 1;
176f05cddf9SRui Paulo break;
177f05cddf9SRui Paulo }
178f05cddf9SRui Paulo
179f05cddf9SRui Paulo pos2 = os_strchr(pos, '=');
180f05cddf9SRui Paulo if (pos2 == NULL) {
181f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "Line %d: Invalid cred line "
182f05cddf9SRui Paulo "'%s'.", *line, pos);
183f05cddf9SRui Paulo errors++;
184f05cddf9SRui Paulo continue;
185f05cddf9SRui Paulo }
186f05cddf9SRui Paulo
187f05cddf9SRui Paulo *pos2++ = '\0';
188f05cddf9SRui Paulo if (*pos2 == '"') {
189f05cddf9SRui Paulo if (os_strchr(pos2 + 1, '"') == NULL) {
190f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "Line %d: invalid "
191f05cddf9SRui Paulo "quotation '%s'.", *line, pos2);
192f05cddf9SRui Paulo errors++;
193f05cddf9SRui Paulo continue;
194f05cddf9SRui Paulo }
195f05cddf9SRui Paulo }
196f05cddf9SRui Paulo
197f05cddf9SRui Paulo if (wpa_config_set_cred(cred, pos, pos2, *line) < 0)
198f05cddf9SRui Paulo errors++;
199f05cddf9SRui Paulo }
200f05cddf9SRui Paulo
201f05cddf9SRui Paulo if (!end) {
202f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "Line %d: cred block was not "
203f05cddf9SRui Paulo "terminated properly.", *line);
204f05cddf9SRui Paulo errors++;
205f05cddf9SRui Paulo }
206f05cddf9SRui Paulo
207f05cddf9SRui Paulo if (errors) {
208f05cddf9SRui Paulo wpa_config_free_cred(cred);
209f05cddf9SRui Paulo cred = NULL;
210f05cddf9SRui Paulo }
211f05cddf9SRui Paulo
212f05cddf9SRui Paulo return cred;
213f05cddf9SRui Paulo }
214f05cddf9SRui Paulo
215f05cddf9SRui Paulo
21639beb93cSSam Leffler #ifndef CONFIG_NO_CONFIG_BLOBS
wpa_config_read_blob(FILE * f,int * line,const char * name)21739beb93cSSam Leffler static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line,
21839beb93cSSam Leffler const char *name)
21939beb93cSSam Leffler {
22039beb93cSSam Leffler struct wpa_config_blob *blob;
22139beb93cSSam Leffler char buf[256], *pos;
222c1d255d3SCy Schubert char *encoded = NULL, *nencoded;
22339beb93cSSam Leffler int end = 0;
22439beb93cSSam Leffler size_t encoded_len = 0, len;
22539beb93cSSam Leffler
22639beb93cSSam Leffler wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new named blob '%s'",
22739beb93cSSam Leffler *line, name);
22839beb93cSSam Leffler
22939beb93cSSam Leffler while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
23039beb93cSSam Leffler if (os_strcmp(pos, "}") == 0) {
23139beb93cSSam Leffler end = 1;
23239beb93cSSam Leffler break;
23339beb93cSSam Leffler }
23439beb93cSSam Leffler
23539beb93cSSam Leffler len = os_strlen(pos);
23639beb93cSSam Leffler nencoded = os_realloc(encoded, encoded_len + len);
23739beb93cSSam Leffler if (nencoded == NULL) {
23839beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: not enough memory for "
23939beb93cSSam Leffler "blob", *line);
24039beb93cSSam Leffler os_free(encoded);
24139beb93cSSam Leffler return NULL;
24239beb93cSSam Leffler }
24339beb93cSSam Leffler encoded = nencoded;
24439beb93cSSam Leffler os_memcpy(encoded + encoded_len, pos, len);
24539beb93cSSam Leffler encoded_len += len;
24639beb93cSSam Leffler }
24739beb93cSSam Leffler
24885732ac8SCy Schubert if (!end || !encoded) {
24939beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: blob was not terminated "
25039beb93cSSam Leffler "properly", *line);
25139beb93cSSam Leffler os_free(encoded);
25239beb93cSSam Leffler return NULL;
25339beb93cSSam Leffler }
25439beb93cSSam Leffler
25539beb93cSSam Leffler blob = os_zalloc(sizeof(*blob));
25639beb93cSSam Leffler if (blob == NULL) {
25739beb93cSSam Leffler os_free(encoded);
25839beb93cSSam Leffler return NULL;
25939beb93cSSam Leffler }
26039beb93cSSam Leffler blob->name = os_strdup(name);
26139beb93cSSam Leffler blob->data = base64_decode(encoded, encoded_len, &blob->len);
26239beb93cSSam Leffler os_free(encoded);
26339beb93cSSam Leffler
26439beb93cSSam Leffler if (blob->name == NULL || blob->data == NULL) {
26539beb93cSSam Leffler wpa_config_free_blob(blob);
26639beb93cSSam Leffler return NULL;
26739beb93cSSam Leffler }
26839beb93cSSam Leffler
26939beb93cSSam Leffler return blob;
27039beb93cSSam Leffler }
27139beb93cSSam Leffler
27239beb93cSSam Leffler
wpa_config_process_blob(struct wpa_config * config,FILE * f,int * line,char * bname)27339beb93cSSam Leffler static int wpa_config_process_blob(struct wpa_config *config, FILE *f,
27439beb93cSSam Leffler int *line, char *bname)
27539beb93cSSam Leffler {
27639beb93cSSam Leffler char *name_end;
27739beb93cSSam Leffler struct wpa_config_blob *blob;
27839beb93cSSam Leffler
27939beb93cSSam Leffler name_end = os_strchr(bname, '=');
28039beb93cSSam Leffler if (name_end == NULL) {
28139beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: no blob name terminator",
28239beb93cSSam Leffler *line);
28339beb93cSSam Leffler return -1;
28439beb93cSSam Leffler }
28539beb93cSSam Leffler *name_end = '\0';
28639beb93cSSam Leffler
28739beb93cSSam Leffler blob = wpa_config_read_blob(f, line, bname);
28839beb93cSSam Leffler if (blob == NULL) {
28939beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: failed to read blob %s",
29039beb93cSSam Leffler *line, bname);
29139beb93cSSam Leffler return -1;
29239beb93cSSam Leffler }
29339beb93cSSam Leffler wpa_config_set_blob(config, blob);
29439beb93cSSam Leffler return 0;
29539beb93cSSam Leffler }
29639beb93cSSam Leffler #endif /* CONFIG_NO_CONFIG_BLOBS */
29739beb93cSSam Leffler
29839beb93cSSam Leffler
wpa_config_read(const char * name,struct wpa_config * cfgp,bool ro)299*a90b9d01SCy Schubert struct wpa_config * wpa_config_read(const char *name, struct wpa_config *cfgp,
300*a90b9d01SCy Schubert bool ro)
30139beb93cSSam Leffler {
30239beb93cSSam Leffler FILE *f;
303f05cddf9SRui Paulo char buf[512], *pos;
30439beb93cSSam Leffler int errors = 0, line = 0;
3055b9c547cSRui Paulo struct wpa_ssid *ssid, *tail, *head;
3065b9c547cSRui Paulo struct wpa_cred *cred, *cred_tail, *cred_head;
30739beb93cSSam Leffler struct wpa_config *config;
308*a90b9d01SCy Schubert static int id = 0;
309*a90b9d01SCy Schubert static int cred_id = 0;
31039beb93cSSam Leffler
3115b9c547cSRui Paulo if (name == NULL)
3125b9c547cSRui Paulo return NULL;
3135b9c547cSRui Paulo if (cfgp)
3145b9c547cSRui Paulo config = cfgp;
3155b9c547cSRui Paulo else
31639beb93cSSam Leffler config = wpa_config_alloc_empty(NULL, NULL);
317f05cddf9SRui Paulo if (config == NULL) {
318f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "Failed to allocate config file "
319f05cddf9SRui Paulo "structure");
32039beb93cSSam Leffler return NULL;
321f05cddf9SRui Paulo }
3225b9c547cSRui Paulo tail = head = config->ssid;
3235b9c547cSRui Paulo while (tail && tail->next)
3245b9c547cSRui Paulo tail = tail->next;
3255b9c547cSRui Paulo cred_tail = cred_head = config->cred;
3265b9c547cSRui Paulo while (cred_tail && cred_tail->next)
3275b9c547cSRui Paulo cred_tail = cred_tail->next;
328f05cddf9SRui Paulo
32939beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Reading configuration file '%s'", name);
33039beb93cSSam Leffler f = fopen(name, "r");
33139beb93cSSam Leffler if (f == NULL) {
332f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "Failed to open config file '%s', "
333f05cddf9SRui Paulo "error: %s", name, strerror(errno));
33485732ac8SCy Schubert if (config != cfgp)
33539beb93cSSam Leffler os_free(config);
33639beb93cSSam Leffler return NULL;
33739beb93cSSam Leffler }
33839beb93cSSam Leffler
33939beb93cSSam Leffler while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
34039beb93cSSam Leffler if (os_strcmp(pos, "network={") == 0) {
34139beb93cSSam Leffler ssid = wpa_config_read_network(f, &line, id++);
34239beb93cSSam Leffler if (ssid == NULL) {
34339beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: failed to "
34439beb93cSSam Leffler "parse network block.", line);
34539beb93cSSam Leffler errors++;
34639beb93cSSam Leffler continue;
34739beb93cSSam Leffler }
348*a90b9d01SCy Schubert ssid->ro = ro;
34939beb93cSSam Leffler if (head == NULL) {
35039beb93cSSam Leffler head = tail = ssid;
35139beb93cSSam Leffler } else {
35239beb93cSSam Leffler tail->next = ssid;
35339beb93cSSam Leffler tail = ssid;
35439beb93cSSam Leffler }
35539beb93cSSam Leffler if (wpa_config_add_prio_network(config, ssid)) {
35639beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: failed to add "
35739beb93cSSam Leffler "network block to priority list.",
35839beb93cSSam Leffler line);
35939beb93cSSam Leffler errors++;
36039beb93cSSam Leffler continue;
36139beb93cSSam Leffler }
362f05cddf9SRui Paulo } else if (os_strcmp(pos, "cred={") == 0) {
363f05cddf9SRui Paulo cred = wpa_config_read_cred(f, &line, cred_id++);
364f05cddf9SRui Paulo if (cred == NULL) {
365f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "Line %d: failed to "
366f05cddf9SRui Paulo "parse cred block.", line);
367f05cddf9SRui Paulo errors++;
368f05cddf9SRui Paulo continue;
369f05cddf9SRui Paulo }
370f05cddf9SRui Paulo if (cred_head == NULL) {
371f05cddf9SRui Paulo cred_head = cred_tail = cred;
372f05cddf9SRui Paulo } else {
373f05cddf9SRui Paulo cred_tail->next = cred;
374f05cddf9SRui Paulo cred_tail = cred;
375f05cddf9SRui Paulo }
37639beb93cSSam Leffler #ifndef CONFIG_NO_CONFIG_BLOBS
37739beb93cSSam Leffler } else if (os_strncmp(pos, "blob-base64-", 12) == 0) {
37839beb93cSSam Leffler if (wpa_config_process_blob(config, f, &line, pos + 12)
37939beb93cSSam Leffler < 0) {
380f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "Line %d: failed to "
381f05cddf9SRui Paulo "process blob.", line);
38239beb93cSSam Leffler errors++;
38339beb93cSSam Leffler continue;
38439beb93cSSam Leffler }
38539beb93cSSam Leffler #endif /* CONFIG_NO_CONFIG_BLOBS */
38639beb93cSSam Leffler } else if (wpa_config_process_global(config, pos, line) < 0) {
38739beb93cSSam Leffler wpa_printf(MSG_ERROR, "Line %d: Invalid configuration "
38839beb93cSSam Leffler "line '%s'.", line, pos);
38939beb93cSSam Leffler errors++;
39039beb93cSSam Leffler continue;
39139beb93cSSam Leffler }
39239beb93cSSam Leffler }
39339beb93cSSam Leffler
39439beb93cSSam Leffler fclose(f);
39539beb93cSSam Leffler
39639beb93cSSam Leffler config->ssid = head;
39739beb93cSSam Leffler wpa_config_debug_dump_networks(config);
398f05cddf9SRui Paulo config->cred = cred_head;
39939beb93cSSam Leffler
400f05cddf9SRui Paulo #ifndef WPA_IGNORE_CONFIG_ERRORS
40139beb93cSSam Leffler if (errors) {
40285732ac8SCy Schubert if (config != cfgp)
40339beb93cSSam Leffler wpa_config_free(config);
40439beb93cSSam Leffler config = NULL;
40539beb93cSSam Leffler head = NULL;
40639beb93cSSam Leffler }
407f05cddf9SRui Paulo #endif /* WPA_IGNORE_CONFIG_ERRORS */
40839beb93cSSam Leffler
40939beb93cSSam Leffler return config;
41039beb93cSSam Leffler }
41139beb93cSSam Leffler
41239beb93cSSam Leffler
41339beb93cSSam Leffler #ifndef CONFIG_NO_CONFIG_WRITE
41439beb93cSSam Leffler
write_str(FILE * f,const char * field,struct wpa_ssid * ssid)41539beb93cSSam Leffler static void write_str(FILE *f, const char *field, struct wpa_ssid *ssid)
41639beb93cSSam Leffler {
41739beb93cSSam Leffler char *value = wpa_config_get(ssid, field);
41839beb93cSSam Leffler if (value == NULL)
41939beb93cSSam Leffler return;
42039beb93cSSam Leffler fprintf(f, "\t%s=%s\n", field, value);
4214bc52338SCy Schubert str_clear_free(value);
42239beb93cSSam Leffler }
42339beb93cSSam Leffler
42439beb93cSSam Leffler
write_int(FILE * f,const char * field,int value,int def)42539beb93cSSam Leffler static void write_int(FILE *f, const char *field, int value, int def)
42639beb93cSSam Leffler {
42739beb93cSSam Leffler if (value == def)
42839beb93cSSam Leffler return;
42939beb93cSSam Leffler fprintf(f, "\t%s=%d\n", field, value);
43039beb93cSSam Leffler }
43139beb93cSSam Leffler
43239beb93cSSam Leffler
write_bssid(FILE * f,struct wpa_ssid * ssid)43339beb93cSSam Leffler static void write_bssid(FILE *f, struct wpa_ssid *ssid)
43439beb93cSSam Leffler {
43539beb93cSSam Leffler char *value = wpa_config_get(ssid, "bssid");
43639beb93cSSam Leffler if (value == NULL)
43739beb93cSSam Leffler return;
43839beb93cSSam Leffler fprintf(f, "\tbssid=%s\n", value);
43939beb93cSSam Leffler os_free(value);
44039beb93cSSam Leffler }
44139beb93cSSam Leffler
44239beb93cSSam Leffler
write_bssid_hint(FILE * f,struct wpa_ssid * ssid)44385732ac8SCy Schubert static void write_bssid_hint(FILE *f, struct wpa_ssid *ssid)
44485732ac8SCy Schubert {
44585732ac8SCy Schubert char *value = wpa_config_get(ssid, "bssid_hint");
44685732ac8SCy Schubert
44785732ac8SCy Schubert if (!value)
44885732ac8SCy Schubert return;
44985732ac8SCy Schubert fprintf(f, "\tbssid_hint=%s\n", value);
45085732ac8SCy Schubert os_free(value);
45185732ac8SCy Schubert }
45285732ac8SCy Schubert
45385732ac8SCy Schubert
write_psk(FILE * f,struct wpa_ssid * ssid)45439beb93cSSam Leffler static void write_psk(FILE *f, struct wpa_ssid *ssid)
45539beb93cSSam Leffler {
456325151a3SRui Paulo char *value;
457325151a3SRui Paulo
458325151a3SRui Paulo if (ssid->mem_only_psk)
459325151a3SRui Paulo return;
460325151a3SRui Paulo
461325151a3SRui Paulo value = wpa_config_get(ssid, "psk");
46239beb93cSSam Leffler if (value == NULL)
46339beb93cSSam Leffler return;
46439beb93cSSam Leffler fprintf(f, "\tpsk=%s\n", value);
46539beb93cSSam Leffler os_free(value);
46639beb93cSSam Leffler }
46739beb93cSSam Leffler
46839beb93cSSam Leffler
write_proto(FILE * f,struct wpa_ssid * ssid)46939beb93cSSam Leffler static void write_proto(FILE *f, struct wpa_ssid *ssid)
47039beb93cSSam Leffler {
47139beb93cSSam Leffler char *value;
47239beb93cSSam Leffler
47339beb93cSSam Leffler if (ssid->proto == DEFAULT_PROTO)
47439beb93cSSam Leffler return;
47539beb93cSSam Leffler
47639beb93cSSam Leffler value = wpa_config_get(ssid, "proto");
47739beb93cSSam Leffler if (value == NULL)
47839beb93cSSam Leffler return;
47939beb93cSSam Leffler if (value[0])
48039beb93cSSam Leffler fprintf(f, "\tproto=%s\n", value);
48139beb93cSSam Leffler os_free(value);
48239beb93cSSam Leffler }
48339beb93cSSam Leffler
48439beb93cSSam Leffler
write_key_mgmt(FILE * f,struct wpa_ssid * ssid)48539beb93cSSam Leffler static void write_key_mgmt(FILE *f, struct wpa_ssid *ssid)
48639beb93cSSam Leffler {
48739beb93cSSam Leffler char *value;
48839beb93cSSam Leffler
48939beb93cSSam Leffler if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
49039beb93cSSam Leffler return;
49139beb93cSSam Leffler
49239beb93cSSam Leffler value = wpa_config_get(ssid, "key_mgmt");
49339beb93cSSam Leffler if (value == NULL)
49439beb93cSSam Leffler return;
49539beb93cSSam Leffler if (value[0])
49639beb93cSSam Leffler fprintf(f, "\tkey_mgmt=%s\n", value);
49739beb93cSSam Leffler os_free(value);
49839beb93cSSam Leffler }
49939beb93cSSam Leffler
50039beb93cSSam Leffler
write_pairwise(FILE * f,struct wpa_ssid * ssid)50139beb93cSSam Leffler static void write_pairwise(FILE *f, struct wpa_ssid *ssid)
50239beb93cSSam Leffler {
50339beb93cSSam Leffler char *value;
50439beb93cSSam Leffler
50539beb93cSSam Leffler if (ssid->pairwise_cipher == DEFAULT_PAIRWISE)
50639beb93cSSam Leffler return;
50739beb93cSSam Leffler
50839beb93cSSam Leffler value = wpa_config_get(ssid, "pairwise");
50939beb93cSSam Leffler if (value == NULL)
51039beb93cSSam Leffler return;
51139beb93cSSam Leffler if (value[0])
51239beb93cSSam Leffler fprintf(f, "\tpairwise=%s\n", value);
51339beb93cSSam Leffler os_free(value);
51439beb93cSSam Leffler }
51539beb93cSSam Leffler
51639beb93cSSam Leffler
write_group(FILE * f,struct wpa_ssid * ssid)51739beb93cSSam Leffler static void write_group(FILE *f, struct wpa_ssid *ssid)
51839beb93cSSam Leffler {
51939beb93cSSam Leffler char *value;
52039beb93cSSam Leffler
52139beb93cSSam Leffler if (ssid->group_cipher == DEFAULT_GROUP)
52239beb93cSSam Leffler return;
52339beb93cSSam Leffler
52439beb93cSSam Leffler value = wpa_config_get(ssid, "group");
52539beb93cSSam Leffler if (value == NULL)
52639beb93cSSam Leffler return;
52739beb93cSSam Leffler if (value[0])
52839beb93cSSam Leffler fprintf(f, "\tgroup=%s\n", value);
52939beb93cSSam Leffler os_free(value);
53039beb93cSSam Leffler }
53139beb93cSSam Leffler
53239beb93cSSam Leffler
write_group_mgmt(FILE * f,struct wpa_ssid * ssid)53385732ac8SCy Schubert static void write_group_mgmt(FILE *f, struct wpa_ssid *ssid)
53485732ac8SCy Schubert {
53585732ac8SCy Schubert char *value;
53685732ac8SCy Schubert
53785732ac8SCy Schubert if (!ssid->group_mgmt_cipher)
53885732ac8SCy Schubert return;
53985732ac8SCy Schubert
54085732ac8SCy Schubert value = wpa_config_get(ssid, "group_mgmt");
54185732ac8SCy Schubert if (!value)
54285732ac8SCy Schubert return;
54385732ac8SCy Schubert if (value[0])
54485732ac8SCy Schubert fprintf(f, "\tgroup_mgmt=%s\n", value);
54585732ac8SCy Schubert os_free(value);
54685732ac8SCy Schubert }
54785732ac8SCy Schubert
54885732ac8SCy Schubert
write_auth_alg(FILE * f,struct wpa_ssid * ssid)54939beb93cSSam Leffler static void write_auth_alg(FILE *f, struct wpa_ssid *ssid)
55039beb93cSSam Leffler {
55139beb93cSSam Leffler char *value;
55239beb93cSSam Leffler
55339beb93cSSam Leffler if (ssid->auth_alg == 0)
55439beb93cSSam Leffler return;
55539beb93cSSam Leffler
55639beb93cSSam Leffler value = wpa_config_get(ssid, "auth_alg");
55739beb93cSSam Leffler if (value == NULL)
55839beb93cSSam Leffler return;
55939beb93cSSam Leffler if (value[0])
56039beb93cSSam Leffler fprintf(f, "\tauth_alg=%s\n", value);
56139beb93cSSam Leffler os_free(value);
56239beb93cSSam Leffler }
56339beb93cSSam Leffler
56439beb93cSSam Leffler
56539beb93cSSam Leffler #ifdef IEEE8021X_EAPOL
write_eap(FILE * f,struct wpa_ssid * ssid)56639beb93cSSam Leffler static void write_eap(FILE *f, struct wpa_ssid *ssid)
56739beb93cSSam Leffler {
56839beb93cSSam Leffler char *value;
56939beb93cSSam Leffler
57039beb93cSSam Leffler value = wpa_config_get(ssid, "eap");
57139beb93cSSam Leffler if (value == NULL)
57239beb93cSSam Leffler return;
57339beb93cSSam Leffler
57439beb93cSSam Leffler if (value[0])
57539beb93cSSam Leffler fprintf(f, "\teap=%s\n", value);
57639beb93cSSam Leffler os_free(value);
57739beb93cSSam Leffler }
57839beb93cSSam Leffler #endif /* IEEE8021X_EAPOL */
57939beb93cSSam Leffler
58039beb93cSSam Leffler
581c1d255d3SCy Schubert #ifdef CONFIG_WEP
write_wep_key(FILE * f,int idx,struct wpa_ssid * ssid)58239beb93cSSam Leffler static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid)
58339beb93cSSam Leffler {
58439beb93cSSam Leffler char field[20], *value;
58539beb93cSSam Leffler int res;
58639beb93cSSam Leffler
58739beb93cSSam Leffler res = os_snprintf(field, sizeof(field), "wep_key%d", idx);
5885b9c547cSRui Paulo if (os_snprintf_error(sizeof(field), res))
58939beb93cSSam Leffler return;
59039beb93cSSam Leffler value = wpa_config_get(ssid, field);
59139beb93cSSam Leffler if (value) {
59239beb93cSSam Leffler fprintf(f, "\t%s=%s\n", field, value);
59339beb93cSSam Leffler os_free(value);
59439beb93cSSam Leffler }
59539beb93cSSam Leffler }
596c1d255d3SCy Schubert #endif /* CONFIG_WEP */
59739beb93cSSam Leffler
59839beb93cSSam Leffler
599f05cddf9SRui Paulo #ifdef CONFIG_P2P
6005b9c547cSRui Paulo
write_go_p2p_dev_addr(FILE * f,struct wpa_ssid * ssid)6015b9c547cSRui Paulo static void write_go_p2p_dev_addr(FILE *f, struct wpa_ssid *ssid)
6025b9c547cSRui Paulo {
6035b9c547cSRui Paulo char *value = wpa_config_get(ssid, "go_p2p_dev_addr");
6045b9c547cSRui Paulo if (value == NULL)
6055b9c547cSRui Paulo return;
6065b9c547cSRui Paulo fprintf(f, "\tgo_p2p_dev_addr=%s\n", value);
6075b9c547cSRui Paulo os_free(value);
6085b9c547cSRui Paulo }
6095b9c547cSRui Paulo
write_p2p_client_list(FILE * f,struct wpa_ssid * ssid)610f05cddf9SRui Paulo static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid)
611f05cddf9SRui Paulo {
612f05cddf9SRui Paulo char *value = wpa_config_get(ssid, "p2p_client_list");
613f05cddf9SRui Paulo if (value == NULL)
614f05cddf9SRui Paulo return;
615f05cddf9SRui Paulo fprintf(f, "\tp2p_client_list=%s\n", value);
616f05cddf9SRui Paulo os_free(value);
617f05cddf9SRui Paulo }
6185b9c547cSRui Paulo
6195b9c547cSRui Paulo
write_psk_list(FILE * f,struct wpa_ssid * ssid)6205b9c547cSRui Paulo static void write_psk_list(FILE *f, struct wpa_ssid *ssid)
6215b9c547cSRui Paulo {
6225b9c547cSRui Paulo struct psk_list_entry *psk;
6235b9c547cSRui Paulo char hex[32 * 2 + 1];
6245b9c547cSRui Paulo
6255b9c547cSRui Paulo dl_list_for_each(psk, &ssid->psk_list, struct psk_list_entry, list) {
6265b9c547cSRui Paulo wpa_snprintf_hex(hex, sizeof(hex), psk->psk, sizeof(psk->psk));
6275b9c547cSRui Paulo fprintf(f, "\tpsk_list=%s" MACSTR "-%s\n",
6285b9c547cSRui Paulo psk->p2p ? "P2P-" : "", MAC2STR(psk->addr), hex);
6295b9c547cSRui Paulo }
6305b9c547cSRui Paulo }
6315b9c547cSRui Paulo
632f05cddf9SRui Paulo #endif /* CONFIG_P2P */
633f05cddf9SRui Paulo
634f05cddf9SRui Paulo
63585732ac8SCy Schubert #ifdef CONFIG_MACSEC
63685732ac8SCy Schubert
write_mka_cak(FILE * f,struct wpa_ssid * ssid)63785732ac8SCy Schubert static void write_mka_cak(FILE *f, struct wpa_ssid *ssid)
63885732ac8SCy Schubert {
63985732ac8SCy Schubert char *value;
64085732ac8SCy Schubert
64185732ac8SCy Schubert if (!(ssid->mka_psk_set & MKA_PSK_SET_CAK))
64285732ac8SCy Schubert return;
64385732ac8SCy Schubert
64485732ac8SCy Schubert value = wpa_config_get(ssid, "mka_cak");
64585732ac8SCy Schubert if (!value)
64685732ac8SCy Schubert return;
64785732ac8SCy Schubert fprintf(f, "\tmka_cak=%s\n", value);
64885732ac8SCy Schubert os_free(value);
64985732ac8SCy Schubert }
65085732ac8SCy Schubert
65185732ac8SCy Schubert
write_mka_ckn(FILE * f,struct wpa_ssid * ssid)65285732ac8SCy Schubert static void write_mka_ckn(FILE *f, struct wpa_ssid *ssid)
65385732ac8SCy Schubert {
65485732ac8SCy Schubert char *value;
65585732ac8SCy Schubert
65685732ac8SCy Schubert if (!(ssid->mka_psk_set & MKA_PSK_SET_CKN))
65785732ac8SCy Schubert return;
65885732ac8SCy Schubert
65985732ac8SCy Schubert value = wpa_config_get(ssid, "mka_ckn");
66085732ac8SCy Schubert if (!value)
66185732ac8SCy Schubert return;
66285732ac8SCy Schubert fprintf(f, "\tmka_ckn=%s\n", value);
66385732ac8SCy Schubert os_free(value);
66485732ac8SCy Schubert }
66585732ac8SCy Schubert
66685732ac8SCy Schubert #endif /* CONFIG_MACSEC */
66785732ac8SCy Schubert
66885732ac8SCy Schubert
wpa_config_write_network(FILE * f,struct wpa_ssid * ssid)66939beb93cSSam Leffler static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
67039beb93cSSam Leffler {
67139beb93cSSam Leffler #define STR(t) write_str(f, #t, ssid)
67239beb93cSSam Leffler #define INT(t) write_int(f, #t, ssid->t, 0)
673c1d255d3SCy Schubert #define INTe(t, m) write_int(f, #t, ssid->eap.m, 0)
67439beb93cSSam Leffler #define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
675c1d255d3SCy Schubert #define INT_DEFe(t, m, def) write_int(f, #t, ssid->eap.m, def)
67639beb93cSSam Leffler
67739beb93cSSam Leffler STR(ssid);
67839beb93cSSam Leffler INT(scan_ssid);
67939beb93cSSam Leffler write_bssid(f, ssid);
68085732ac8SCy Schubert write_bssid_hint(f, ssid);
681c1d255d3SCy Schubert write_str(f, "bssid_ignore", ssid);
682c1d255d3SCy Schubert write_str(f, "bssid_accept", ssid);
68339beb93cSSam Leffler write_psk(f, ssid);
684325151a3SRui Paulo INT(mem_only_psk);
68585732ac8SCy Schubert STR(sae_password);
68685732ac8SCy Schubert STR(sae_password_id);
6874b72b91aSCy Schubert write_int(f, "sae_pwe", ssid->sae_pwe, DEFAULT_SAE_PWE);
68839beb93cSSam Leffler write_proto(f, ssid);
68939beb93cSSam Leffler write_key_mgmt(f, ssid);
690f05cddf9SRui Paulo INT_DEF(bg_scan_period, DEFAULT_BG_SCAN_PERIOD);
69139beb93cSSam Leffler write_pairwise(f, ssid);
69239beb93cSSam Leffler write_group(f, ssid);
69385732ac8SCy Schubert write_group_mgmt(f, ssid);
69439beb93cSSam Leffler write_auth_alg(f, ssid);
695f05cddf9SRui Paulo STR(bgscan);
696f05cddf9SRui Paulo STR(autoscan);
6975b9c547cSRui Paulo STR(scan_freq);
69839beb93cSSam Leffler #ifdef IEEE8021X_EAPOL
69939beb93cSSam Leffler write_eap(f, ssid);
70039beb93cSSam Leffler STR(identity);
70139beb93cSSam Leffler STR(anonymous_identity);
70285732ac8SCy Schubert STR(imsi_identity);
703c1d255d3SCy Schubert STR(machine_identity);
70439beb93cSSam Leffler STR(password);
705c1d255d3SCy Schubert STR(machine_password);
70639beb93cSSam Leffler STR(ca_cert);
70739beb93cSSam Leffler STR(ca_path);
70839beb93cSSam Leffler STR(client_cert);
70939beb93cSSam Leffler STR(private_key);
71039beb93cSSam Leffler STR(private_key_passwd);
71139beb93cSSam Leffler STR(subject_match);
7124bc52338SCy Schubert STR(check_cert_subject);
71339beb93cSSam Leffler STR(altsubject_match);
7145b9c547cSRui Paulo STR(domain_suffix_match);
7155b9c547cSRui Paulo STR(domain_match);
71639beb93cSSam Leffler STR(ca_cert2);
71739beb93cSSam Leffler STR(ca_path2);
71839beb93cSSam Leffler STR(client_cert2);
71939beb93cSSam Leffler STR(private_key2);
72039beb93cSSam Leffler STR(private_key2_passwd);
72139beb93cSSam Leffler STR(subject_match2);
7224bc52338SCy Schubert STR(check_cert_subject2);
72339beb93cSSam Leffler STR(altsubject_match2);
7245b9c547cSRui Paulo STR(domain_suffix_match2);
7255b9c547cSRui Paulo STR(domain_match2);
726c1d255d3SCy Schubert STR(machine_ca_cert);
727c1d255d3SCy Schubert STR(machine_ca_path);
728c1d255d3SCy Schubert STR(machine_client_cert);
729c1d255d3SCy Schubert STR(machine_private_key);
730c1d255d3SCy Schubert STR(machine_private_key_passwd);
731c1d255d3SCy Schubert STR(machine_subject_match);
732c1d255d3SCy Schubert STR(machine_check_cert_subject);
733c1d255d3SCy Schubert STR(machine_altsubject_match);
734c1d255d3SCy Schubert STR(machine_domain_suffix_match);
735c1d255d3SCy Schubert STR(machine_domain_match);
73639beb93cSSam Leffler STR(phase1);
73739beb93cSSam Leffler STR(phase2);
738c1d255d3SCy Schubert STR(machine_phase2);
73939beb93cSSam Leffler STR(pcsc);
74039beb93cSSam Leffler STR(pin);
74139beb93cSSam Leffler STR(engine_id);
74239beb93cSSam Leffler STR(key_id);
74339beb93cSSam Leffler STR(cert_id);
74439beb93cSSam Leffler STR(ca_cert_id);
74539beb93cSSam Leffler STR(key2_id);
74639beb93cSSam Leffler STR(pin2);
74739beb93cSSam Leffler STR(engine2_id);
74839beb93cSSam Leffler STR(cert2_id);
74939beb93cSSam Leffler STR(ca_cert2_id);
750c1d255d3SCy Schubert INTe(engine, cert.engine);
751c1d255d3SCy Schubert INTe(engine2, phase2_cert.engine);
752c1d255d3SCy Schubert INTe(machine_engine, machine_cert.engine);
75339beb93cSSam Leffler INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
7545b9c547cSRui Paulo STR(openssl_ciphers);
755c1d255d3SCy Schubert INTe(erp, erp);
75639beb93cSSam Leffler #endif /* IEEE8021X_EAPOL */
757c1d255d3SCy Schubert #ifdef CONFIG_WEP
758c1d255d3SCy Schubert {
759c1d255d3SCy Schubert int i;
760c1d255d3SCy Schubert
76139beb93cSSam Leffler for (i = 0; i < 4; i++)
76239beb93cSSam Leffler write_wep_key(f, i, ssid);
76339beb93cSSam Leffler INT(wep_tx_keyidx);
764c1d255d3SCy Schubert }
765c1d255d3SCy Schubert #endif /* CONFIG_WEP */
76639beb93cSSam Leffler INT(priority);
76739beb93cSSam Leffler #ifdef IEEE8021X_EAPOL
76839beb93cSSam Leffler INT_DEF(eap_workaround, DEFAULT_EAP_WORKAROUND);
76939beb93cSSam Leffler STR(pac_file);
770c1d255d3SCy Schubert INT_DEFe(fragment_size, fragment_size, DEFAULT_FRAGMENT_SIZE);
771c1d255d3SCy Schubert INTe(ocsp, cert.ocsp);
772c1d255d3SCy Schubert INTe(ocsp2, phase2_cert.ocsp);
773c1d255d3SCy Schubert INTe(machine_ocsp, machine_cert.ocsp);
774c1d255d3SCy Schubert INT_DEFe(sim_num, sim_num, DEFAULT_USER_SELECTED_SIM);
77539beb93cSSam Leffler #endif /* IEEE8021X_EAPOL */
77639beb93cSSam Leffler INT(mode);
7775b9c547cSRui Paulo INT(no_auto_peer);
77832a95656SCy Schubert INT(mesh_fwding);
779f05cddf9SRui Paulo INT(frequency);
780c1d255d3SCy Schubert INT(enable_edmg);
781c1d255d3SCy Schubert INT(edmg_channel);
7825b9c547cSRui Paulo INT(fixed_freq);
783780fb4a2SCy Schubert #ifdef CONFIG_ACS
784780fb4a2SCy Schubert INT(acs);
785780fb4a2SCy Schubert #endif /* CONFIG_ACS */
786f05cddf9SRui Paulo write_int(f, "proactive_key_caching", ssid->proactive_key_caching, -1);
78739beb93cSSam Leffler INT(disabled);
7885b9c547cSRui Paulo INT(mixed_cell);
789c1d255d3SCy Schubert INT_DEF(vht, 1);
79085732ac8SCy Schubert INT_DEF(ht, 1);
79185732ac8SCy Schubert INT(ht40);
792c1d255d3SCy Schubert INT_DEF(he, 1);
7934bc52338SCy Schubert INT_DEF(max_oper_chwidth, DEFAULT_MAX_OPER_CHWIDTH);
79485732ac8SCy Schubert INT(vht_center_freq1);
79585732ac8SCy Schubert INT(vht_center_freq2);
796780fb4a2SCy Schubert INT(pbss);
797780fb4a2SCy Schubert INT(wps_disabled);
79885732ac8SCy Schubert INT(fils_dh_group);
799f05cddf9SRui Paulo write_int(f, "ieee80211w", ssid->ieee80211w,
800f05cddf9SRui Paulo MGMT_FRAME_PROTECTION_DEFAULT);
80139beb93cSSam Leffler STR(id_str);
802f05cddf9SRui Paulo #ifdef CONFIG_P2P
8035b9c547cSRui Paulo write_go_p2p_dev_addr(f, ssid);
804f05cddf9SRui Paulo write_p2p_client_list(f, ssid);
8055b9c547cSRui Paulo write_psk_list(f, ssid);
806f05cddf9SRui Paulo #endif /* CONFIG_P2P */
8075b9c547cSRui Paulo INT(ap_max_inactivity);
8085b9c547cSRui Paulo INT(dtim_period);
8095b9c547cSRui Paulo INT(beacon_int);
8105b9c547cSRui Paulo #ifdef CONFIG_MACSEC
8115b9c547cSRui Paulo INT(macsec_policy);
81285732ac8SCy Schubert write_mka_cak(f, ssid);
81385732ac8SCy Schubert write_mka_ckn(f, ssid);
81485732ac8SCy Schubert INT(macsec_integ_only);
8154bc52338SCy Schubert INT(macsec_replay_protect);
8164bc52338SCy Schubert INT(macsec_replay_window);
817*a90b9d01SCy Schubert INT(macsec_offload);
81885732ac8SCy Schubert INT(macsec_port);
81985732ac8SCy Schubert INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER);
820*a90b9d01SCy Schubert INT(macsec_csindex);
8215b9c547cSRui Paulo #endif /* CONFIG_MACSEC */
8225b9c547cSRui Paulo #ifdef CONFIG_HS20
8235b9c547cSRui Paulo INT(update_identifier);
82485732ac8SCy Schubert STR(roaming_consortium_selection);
8255b9c547cSRui Paulo #endif /* CONFIG_HS20 */
8265b9c547cSRui Paulo write_int(f, "mac_addr", ssid->mac_addr, -1);
8275b9c547cSRui Paulo #ifdef CONFIG_MESH
8285b9c547cSRui Paulo STR(mesh_basic_rates);
8295b9c547cSRui Paulo INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES);
8305b9c547cSRui Paulo INT_DEF(dot11MeshRetryTimeout, DEFAULT_MESH_RETRY_TIMEOUT);
8315b9c547cSRui Paulo INT_DEF(dot11MeshConfirmTimeout, DEFAULT_MESH_CONFIRM_TIMEOUT);
8325b9c547cSRui Paulo INT_DEF(dot11MeshHoldingTimeout, DEFAULT_MESH_HOLDING_TIMEOUT);
83385732ac8SCy Schubert INT_DEF(mesh_rssi_threshold, DEFAULT_MESH_RSSI_THRESHOLD);
8345b9c547cSRui Paulo #endif /* CONFIG_MESH */
8355b9c547cSRui Paulo INT(wpa_ptk_rekey);
836c1d255d3SCy Schubert INT(wpa_deny_ptk0_rekey);
837780fb4a2SCy Schubert INT(group_rekey);
8385b9c547cSRui Paulo INT(ignore_broadcast_ssid);
83985732ac8SCy Schubert #ifdef CONFIG_DPP
84085732ac8SCy Schubert STR(dpp_connector);
84185732ac8SCy Schubert STR(dpp_netaccesskey);
84285732ac8SCy Schubert INT(dpp_netaccesskey_expiry);
84385732ac8SCy Schubert STR(dpp_csign);
844c1d255d3SCy Schubert STR(dpp_pp_key);
845c1d255d3SCy Schubert INT(dpp_pfs);
846*a90b9d01SCy Schubert INT(dpp_connector_privacy);
84785732ac8SCy Schubert #endif /* CONFIG_DPP */
84885732ac8SCy Schubert INT(owe_group);
84985732ac8SCy Schubert INT(owe_only);
850c1d255d3SCy Schubert INT(owe_ptk_workaround);
8514bc52338SCy Schubert INT(multi_ap_backhaul_sta);
852206b73d0SCy Schubert INT(ft_eap_pmksa_caching);
853*a90b9d01SCy Schubert INT(multi_ap_profile);
854c1d255d3SCy Schubert INT(beacon_prot);
855c1d255d3SCy Schubert INT(transition_disable);
856c1d255d3SCy Schubert INT(sae_pk);
8575b9c547cSRui Paulo #ifdef CONFIG_HT_OVERRIDES
8585b9c547cSRui Paulo INT_DEF(disable_ht, DEFAULT_DISABLE_HT);
8595b9c547cSRui Paulo INT_DEF(disable_ht40, DEFAULT_DISABLE_HT40);
8605b9c547cSRui Paulo INT_DEF(disable_sgi, DEFAULT_DISABLE_SGI);
8615b9c547cSRui Paulo INT_DEF(disable_ldpc, DEFAULT_DISABLE_LDPC);
8625b9c547cSRui Paulo INT(ht40_intolerant);
8634bc52338SCy Schubert INT_DEF(tx_stbc, DEFAULT_TX_STBC);
8644bc52338SCy Schubert INT_DEF(rx_stbc, DEFAULT_RX_STBC);
8655b9c547cSRui Paulo INT_DEF(disable_max_amsdu, DEFAULT_DISABLE_MAX_AMSDU);
8665b9c547cSRui Paulo INT_DEF(ampdu_factor, DEFAULT_AMPDU_FACTOR);
8675b9c547cSRui Paulo INT_DEF(ampdu_density, DEFAULT_AMPDU_DENSITY);
8685b9c547cSRui Paulo STR(ht_mcs);
8695b9c547cSRui Paulo #endif /* CONFIG_HT_OVERRIDES */
8705b9c547cSRui Paulo #ifdef CONFIG_VHT_OVERRIDES
8715b9c547cSRui Paulo INT(disable_vht);
8725b9c547cSRui Paulo INT(vht_capa);
8735b9c547cSRui Paulo INT(vht_capa_mask);
8745b9c547cSRui Paulo INT_DEF(vht_rx_mcs_nss_1, -1);
8755b9c547cSRui Paulo INT_DEF(vht_rx_mcs_nss_2, -1);
8765b9c547cSRui Paulo INT_DEF(vht_rx_mcs_nss_3, -1);
8775b9c547cSRui Paulo INT_DEF(vht_rx_mcs_nss_4, -1);
8785b9c547cSRui Paulo INT_DEF(vht_rx_mcs_nss_5, -1);
8795b9c547cSRui Paulo INT_DEF(vht_rx_mcs_nss_6, -1);
8805b9c547cSRui Paulo INT_DEF(vht_rx_mcs_nss_7, -1);
8815b9c547cSRui Paulo INT_DEF(vht_rx_mcs_nss_8, -1);
8825b9c547cSRui Paulo INT_DEF(vht_tx_mcs_nss_1, -1);
8835b9c547cSRui Paulo INT_DEF(vht_tx_mcs_nss_2, -1);
8845b9c547cSRui Paulo INT_DEF(vht_tx_mcs_nss_3, -1);
8855b9c547cSRui Paulo INT_DEF(vht_tx_mcs_nss_4, -1);
8865b9c547cSRui Paulo INT_DEF(vht_tx_mcs_nss_5, -1);
8875b9c547cSRui Paulo INT_DEF(vht_tx_mcs_nss_6, -1);
8885b9c547cSRui Paulo INT_DEF(vht_tx_mcs_nss_7, -1);
8895b9c547cSRui Paulo INT_DEF(vht_tx_mcs_nss_8, -1);
8905b9c547cSRui Paulo #endif /* CONFIG_VHT_OVERRIDES */
891c1d255d3SCy Schubert #ifdef CONFIG_HE_OVERRIDES
892c1d255d3SCy Schubert INT(disable_he);
893c1d255d3SCy Schubert #endif /* CONFIG_HE_OVERRIDES */
894*a90b9d01SCy Schubert INT(disable_eht);
895*a90b9d01SCy Schubert INT(enable_4addr_mode);
896*a90b9d01SCy Schubert INT(max_idle);
897*a90b9d01SCy Schubert INT(ssid_protection);
89839beb93cSSam Leffler
89939beb93cSSam Leffler #undef STR
90039beb93cSSam Leffler #undef INT
90139beb93cSSam Leffler #undef INT_DEF
90239beb93cSSam Leffler }
90339beb93cSSam Leffler
90439beb93cSSam Leffler
wpa_config_write_cred(FILE * f,struct wpa_cred * cred)905f05cddf9SRui Paulo static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
906f05cddf9SRui Paulo {
9075b9c547cSRui Paulo size_t i;
9085b9c547cSRui Paulo
909f05cddf9SRui Paulo if (cred->priority)
910f05cddf9SRui Paulo fprintf(f, "\tpriority=%d\n", cred->priority);
911f05cddf9SRui Paulo if (cred->pcsc)
912f05cddf9SRui Paulo fprintf(f, "\tpcsc=%d\n", cred->pcsc);
913f05cddf9SRui Paulo if (cred->realm)
914f05cddf9SRui Paulo fprintf(f, "\trealm=\"%s\"\n", cred->realm);
915f05cddf9SRui Paulo if (cred->username)
916f05cddf9SRui Paulo fprintf(f, "\tusername=\"%s\"\n", cred->username);
917f05cddf9SRui Paulo if (cred->password && cred->ext_password)
918f05cddf9SRui Paulo fprintf(f, "\tpassword=ext:%s\n", cred->password);
919f05cddf9SRui Paulo else if (cred->password)
920f05cddf9SRui Paulo fprintf(f, "\tpassword=\"%s\"\n", cred->password);
921f05cddf9SRui Paulo if (cred->ca_cert)
922f05cddf9SRui Paulo fprintf(f, "\tca_cert=\"%s\"\n", cred->ca_cert);
923f05cddf9SRui Paulo if (cred->client_cert)
924f05cddf9SRui Paulo fprintf(f, "\tclient_cert=\"%s\"\n", cred->client_cert);
925f05cddf9SRui Paulo if (cred->private_key)
926f05cddf9SRui Paulo fprintf(f, "\tprivate_key=\"%s\"\n", cred->private_key);
927f05cddf9SRui Paulo if (cred->private_key_passwd)
928f05cddf9SRui Paulo fprintf(f, "\tprivate_key_passwd=\"%s\"\n",
929f05cddf9SRui Paulo cred->private_key_passwd);
930f05cddf9SRui Paulo if (cred->imsi)
931f05cddf9SRui Paulo fprintf(f, "\timsi=\"%s\"\n", cred->imsi);
932f05cddf9SRui Paulo if (cred->milenage)
933f05cddf9SRui Paulo fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage);
9345b9c547cSRui Paulo for (i = 0; i < cred->num_domain; i++)
9355b9c547cSRui Paulo fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]);
9365b9c547cSRui Paulo if (cred->domain_suffix_match)
9375b9c547cSRui Paulo fprintf(f, "\tdomain_suffix_match=\"%s\"\n",
9385b9c547cSRui Paulo cred->domain_suffix_match);
939f05cddf9SRui Paulo if (cred->eap_method) {
940f05cddf9SRui Paulo const char *name;
941f05cddf9SRui Paulo name = eap_get_name(cred->eap_method[0].vendor,
942f05cddf9SRui Paulo cred->eap_method[0].method);
9435b9c547cSRui Paulo if (name)
944f05cddf9SRui Paulo fprintf(f, "\teap=%s\n", name);
945f05cddf9SRui Paulo }
946f05cddf9SRui Paulo if (cred->phase1)
947f05cddf9SRui Paulo fprintf(f, "\tphase1=\"%s\"\n", cred->phase1);
948f05cddf9SRui Paulo if (cred->phase2)
949f05cddf9SRui Paulo fprintf(f, "\tphase2=\"%s\"\n", cred->phase2);
950f05cddf9SRui Paulo if (cred->excluded_ssid) {
9515b9c547cSRui Paulo size_t j;
952f05cddf9SRui Paulo for (i = 0; i < cred->num_excluded_ssid; i++) {
953f05cddf9SRui Paulo struct excluded_ssid *e = &cred->excluded_ssid[i];
954f05cddf9SRui Paulo fprintf(f, "\texcluded_ssid=");
955f05cddf9SRui Paulo for (j = 0; j < e->ssid_len; j++)
956f05cddf9SRui Paulo fprintf(f, "%02x", e->ssid[j]);
957f05cddf9SRui Paulo fprintf(f, "\n");
958f05cddf9SRui Paulo }
959f05cddf9SRui Paulo }
9605b9c547cSRui Paulo if (cred->roaming_partner) {
9615b9c547cSRui Paulo for (i = 0; i < cred->num_roaming_partner; i++) {
9625b9c547cSRui Paulo struct roaming_partner *p = &cred->roaming_partner[i];
9635b9c547cSRui Paulo fprintf(f, "\troaming_partner=\"%s,%d,%u,%s\"\n",
9645b9c547cSRui Paulo p->fqdn, p->exact_match, p->priority,
9655b9c547cSRui Paulo p->country);
9665b9c547cSRui Paulo }
9675b9c547cSRui Paulo }
9685b9c547cSRui Paulo if (cred->update_identifier)
9695b9c547cSRui Paulo fprintf(f, "\tupdate_identifier=%d\n", cred->update_identifier);
9705b9c547cSRui Paulo
9715b9c547cSRui Paulo if (cred->provisioning_sp)
9725b9c547cSRui Paulo fprintf(f, "\tprovisioning_sp=\"%s\"\n", cred->provisioning_sp);
9735b9c547cSRui Paulo if (cred->sp_priority)
9745b9c547cSRui Paulo fprintf(f, "\tsp_priority=%d\n", cred->sp_priority);
9755b9c547cSRui Paulo
9765b9c547cSRui Paulo if (cred->min_dl_bandwidth_home)
9775b9c547cSRui Paulo fprintf(f, "\tmin_dl_bandwidth_home=%u\n",
9785b9c547cSRui Paulo cred->min_dl_bandwidth_home);
9795b9c547cSRui Paulo if (cred->min_ul_bandwidth_home)
9805b9c547cSRui Paulo fprintf(f, "\tmin_ul_bandwidth_home=%u\n",
9815b9c547cSRui Paulo cred->min_ul_bandwidth_home);
9825b9c547cSRui Paulo if (cred->min_dl_bandwidth_roaming)
9835b9c547cSRui Paulo fprintf(f, "\tmin_dl_bandwidth_roaming=%u\n",
9845b9c547cSRui Paulo cred->min_dl_bandwidth_roaming);
9855b9c547cSRui Paulo if (cred->min_ul_bandwidth_roaming)
9865b9c547cSRui Paulo fprintf(f, "\tmin_ul_bandwidth_roaming=%u\n",
9875b9c547cSRui Paulo cred->min_ul_bandwidth_roaming);
9885b9c547cSRui Paulo
9895b9c547cSRui Paulo if (cred->max_bss_load)
9905b9c547cSRui Paulo fprintf(f, "\tmax_bss_load=%u\n",
9915b9c547cSRui Paulo cred->max_bss_load);
9925b9c547cSRui Paulo
9935b9c547cSRui Paulo if (cred->ocsp)
9945b9c547cSRui Paulo fprintf(f, "\tocsp=%d\n", cred->ocsp);
9955b9c547cSRui Paulo
9965b9c547cSRui Paulo if (cred->num_req_conn_capab) {
9975b9c547cSRui Paulo for (i = 0; i < cred->num_req_conn_capab; i++) {
9985b9c547cSRui Paulo int *ports;
9995b9c547cSRui Paulo
10005b9c547cSRui Paulo fprintf(f, "\treq_conn_capab=%u",
10015b9c547cSRui Paulo cred->req_conn_capab_proto[i]);
10025b9c547cSRui Paulo ports = cred->req_conn_capab_port[i];
10035b9c547cSRui Paulo if (ports) {
10045b9c547cSRui Paulo int j;
10055b9c547cSRui Paulo for (j = 0; ports[j] != -1; j++) {
10065b9c547cSRui Paulo fprintf(f, "%s%d", j > 0 ? "," : ":",
10075b9c547cSRui Paulo ports[j]);
10085b9c547cSRui Paulo }
10095b9c547cSRui Paulo }
10105b9c547cSRui Paulo fprintf(f, "\n");
10115b9c547cSRui Paulo }
10125b9c547cSRui Paulo }
10135b9c547cSRui Paulo
1014*a90b9d01SCy Schubert if (cred->num_home_ois) {
1015*a90b9d01SCy Schubert size_t j;
1016*a90b9d01SCy Schubert
1017*a90b9d01SCy Schubert fprintf(f, "\thome_ois=\"");
1018*a90b9d01SCy Schubert for (i = 0; i < cred->num_home_ois; i++) {
1019*a90b9d01SCy Schubert if (i > 0)
1020*a90b9d01SCy Schubert fprintf(f, ",");
1021*a90b9d01SCy Schubert for (j = 0; j < cred->home_ois_len[i]; j++)
10225b9c547cSRui Paulo fprintf(f, "%02x",
1023*a90b9d01SCy Schubert cred->home_ois[i][j]);
1024*a90b9d01SCy Schubert }
1025*a90b9d01SCy Schubert fprintf(f, "\"\n");
1026*a90b9d01SCy Schubert }
1027*a90b9d01SCy Schubert
1028*a90b9d01SCy Schubert if (cred->num_required_home_ois) {
1029*a90b9d01SCy Schubert size_t j;
1030*a90b9d01SCy Schubert
1031*a90b9d01SCy Schubert fprintf(f, "\trequired_home_ois=\"");
1032*a90b9d01SCy Schubert for (i = 0; i < cred->num_required_home_ois; i++) {
1033*a90b9d01SCy Schubert if (i > 0)
1034*a90b9d01SCy Schubert fprintf(f, ",");
1035*a90b9d01SCy Schubert for (j = 0; j < cred->required_home_ois_len[i]; j++)
1036*a90b9d01SCy Schubert fprintf(f, "%02x",
1037*a90b9d01SCy Schubert cred->required_home_ois[i][j]);
1038*a90b9d01SCy Schubert }
1039*a90b9d01SCy Schubert fprintf(f, "\"\n");
10405b9c547cSRui Paulo }
10415b9c547cSRui Paulo
104285732ac8SCy Schubert if (cred->num_roaming_consortiums) {
104385732ac8SCy Schubert size_t j;
104485732ac8SCy Schubert
104585732ac8SCy Schubert fprintf(f, "\troaming_consortiums=\"");
104685732ac8SCy Schubert for (i = 0; i < cred->num_roaming_consortiums; i++) {
104785732ac8SCy Schubert if (i > 0)
104885732ac8SCy Schubert fprintf(f, ",");
104985732ac8SCy Schubert for (j = 0; j < cred->roaming_consortiums_len[i]; j++)
105085732ac8SCy Schubert fprintf(f, "%02x",
105185732ac8SCy Schubert cred->roaming_consortiums[i][j]);
105285732ac8SCy Schubert }
105385732ac8SCy Schubert fprintf(f, "\"\n");
105485732ac8SCy Schubert }
105585732ac8SCy Schubert
10565b9c547cSRui Paulo if (cred->sim_num != DEFAULT_USER_SELECTED_SIM)
10575b9c547cSRui Paulo fprintf(f, "\tsim_num=%d\n", cred->sim_num);
105832a95656SCy Schubert
105932a95656SCy Schubert if (cred->engine)
106032a95656SCy Schubert fprintf(f, "\tengine=%d\n", cred->engine);
106132a95656SCy Schubert if (cred->engine_id)
106232a95656SCy Schubert fprintf(f, "\tengine_id=\"%s\"\n", cred->engine_id);
106332a95656SCy Schubert if (cred->key_id)
106432a95656SCy Schubert fprintf(f, "\tkey_id=\"%s\"\n", cred->key_id);
106532a95656SCy Schubert if (cred->cert_id)
106632a95656SCy Schubert fprintf(f, "\tcert_id=\"%s\"\n", cred->cert_id);
106732a95656SCy Schubert if (cred->ca_cert_id)
106832a95656SCy Schubert fprintf(f, "\tca_cert_id=\"%s\"\n", cred->ca_cert_id);
1069*a90b9d01SCy Schubert
1070*a90b9d01SCy Schubert if (cred->imsi_privacy_cert)
1071*a90b9d01SCy Schubert fprintf(f, "\timsi_privacy_cert=\"%s\"\n",
1072*a90b9d01SCy Schubert cred->imsi_privacy_cert);
1073*a90b9d01SCy Schubert if (cred->imsi_privacy_attr)
1074*a90b9d01SCy Schubert fprintf(f, "\timsi_privacy_attr=\"%s\"\n",
1075*a90b9d01SCy Schubert cred->imsi_privacy_attr);
1076f05cddf9SRui Paulo }
1077f05cddf9SRui Paulo
1078f05cddf9SRui Paulo
107939beb93cSSam Leffler #ifndef CONFIG_NO_CONFIG_BLOBS
wpa_config_write_blob(FILE * f,struct wpa_config_blob * blob)108039beb93cSSam Leffler static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob)
108139beb93cSSam Leffler {
1082c1d255d3SCy Schubert char *encoded;
108339beb93cSSam Leffler
108439beb93cSSam Leffler encoded = base64_encode(blob->data, blob->len, NULL);
108539beb93cSSam Leffler if (encoded == NULL)
108639beb93cSSam Leffler return -1;
108739beb93cSSam Leffler
108839beb93cSSam Leffler fprintf(f, "\nblob-base64-%s={\n%s}\n", blob->name, encoded);
108939beb93cSSam Leffler os_free(encoded);
109039beb93cSSam Leffler return 0;
109139beb93cSSam Leffler }
109239beb93cSSam Leffler #endif /* CONFIG_NO_CONFIG_BLOBS */
109339beb93cSSam Leffler
109439beb93cSSam Leffler
write_global_bin(FILE * f,const char * field,const struct wpabuf * val)1095f05cddf9SRui Paulo static void write_global_bin(FILE *f, const char *field,
1096f05cddf9SRui Paulo const struct wpabuf *val)
1097f05cddf9SRui Paulo {
1098f05cddf9SRui Paulo size_t i;
1099f05cddf9SRui Paulo const u8 *pos;
1100f05cddf9SRui Paulo
1101f05cddf9SRui Paulo if (val == NULL)
1102f05cddf9SRui Paulo return;
1103f05cddf9SRui Paulo
1104f05cddf9SRui Paulo fprintf(f, "%s=", field);
1105f05cddf9SRui Paulo pos = wpabuf_head(val);
1106f05cddf9SRui Paulo for (i = 0; i < wpabuf_len(val); i++)
1107f05cddf9SRui Paulo fprintf(f, "%02X", *pos++);
1108f05cddf9SRui Paulo fprintf(f, "\n");
1109f05cddf9SRui Paulo }
1110f05cddf9SRui Paulo
1111f05cddf9SRui Paulo
wpa_config_write_global(FILE * f,struct wpa_config * config)111239beb93cSSam Leffler static void wpa_config_write_global(FILE *f, struct wpa_config *config)
111339beb93cSSam Leffler {
111439beb93cSSam Leffler #ifdef CONFIG_CTRL_IFACE
111539beb93cSSam Leffler if (config->ctrl_interface)
111639beb93cSSam Leffler fprintf(f, "ctrl_interface=%s\n", config->ctrl_interface);
111739beb93cSSam Leffler if (config->ctrl_interface_group)
111839beb93cSSam Leffler fprintf(f, "ctrl_interface_group=%s\n",
111939beb93cSSam Leffler config->ctrl_interface_group);
112039beb93cSSam Leffler #endif /* CONFIG_CTRL_IFACE */
112139beb93cSSam Leffler if (config->eapol_version != DEFAULT_EAPOL_VERSION)
112239beb93cSSam Leffler fprintf(f, "eapol_version=%d\n", config->eapol_version);
112339beb93cSSam Leffler if (config->ap_scan != DEFAULT_AP_SCAN)
112439beb93cSSam Leffler fprintf(f, "ap_scan=%d\n", config->ap_scan);
1125f05cddf9SRui Paulo if (config->disable_scan_offload)
1126f05cddf9SRui Paulo fprintf(f, "disable_scan_offload=%d\n",
1127f05cddf9SRui Paulo config->disable_scan_offload);
112839beb93cSSam Leffler if (config->fast_reauth != DEFAULT_FAST_REAUTH)
112939beb93cSSam Leffler fprintf(f, "fast_reauth=%d\n", config->fast_reauth);
1130*a90b9d01SCy Schubert #ifndef CONFIG_OPENSC_ENGINE_PATH
113139beb93cSSam Leffler if (config->opensc_engine_path)
113239beb93cSSam Leffler fprintf(f, "opensc_engine_path=%s\n",
113339beb93cSSam Leffler config->opensc_engine_path);
1134*a90b9d01SCy Schubert #endif /* CONFIG_OPENSC_ENGINE_PATH */
1135*a90b9d01SCy Schubert #ifndef CONFIG_PKCS11_ENGINE_PATH
113639beb93cSSam Leffler if (config->pkcs11_engine_path)
113739beb93cSSam Leffler fprintf(f, "pkcs11_engine_path=%s\n",
113839beb93cSSam Leffler config->pkcs11_engine_path);
1139*a90b9d01SCy Schubert #endif /* CONFIG_PKCS11_ENGINE_PATH */
1140*a90b9d01SCy Schubert #ifndef CONFIG_PKCS11_MODULE_PATH
114139beb93cSSam Leffler if (config->pkcs11_module_path)
114239beb93cSSam Leffler fprintf(f, "pkcs11_module_path=%s\n",
114339beb93cSSam Leffler config->pkcs11_module_path);
1144*a90b9d01SCy Schubert #endif /* CONFIG_PKCS11_MODULE_PATH */
11455b9c547cSRui Paulo if (config->openssl_ciphers)
11465b9c547cSRui Paulo fprintf(f, "openssl_ciphers=%s\n", config->openssl_ciphers);
1147f05cddf9SRui Paulo if (config->pcsc_reader)
1148f05cddf9SRui Paulo fprintf(f, "pcsc_reader=%s\n", config->pcsc_reader);
1149f05cddf9SRui Paulo if (config->pcsc_pin)
1150f05cddf9SRui Paulo fprintf(f, "pcsc_pin=%s\n", config->pcsc_pin);
115139beb93cSSam Leffler if (config->driver_param)
115239beb93cSSam Leffler fprintf(f, "driver_param=%s\n", config->driver_param);
115339beb93cSSam Leffler if (config->dot11RSNAConfigPMKLifetime)
1154325151a3SRui Paulo fprintf(f, "dot11RSNAConfigPMKLifetime=%u\n",
115539beb93cSSam Leffler config->dot11RSNAConfigPMKLifetime);
115639beb93cSSam Leffler if (config->dot11RSNAConfigPMKReauthThreshold)
1157325151a3SRui Paulo fprintf(f, "dot11RSNAConfigPMKReauthThreshold=%u\n",
115839beb93cSSam Leffler config->dot11RSNAConfigPMKReauthThreshold);
115939beb93cSSam Leffler if (config->dot11RSNAConfigSATimeout)
1160325151a3SRui Paulo fprintf(f, "dot11RSNAConfigSATimeout=%u\n",
116139beb93cSSam Leffler config->dot11RSNAConfigSATimeout);
116239beb93cSSam Leffler if (config->update_config)
116339beb93cSSam Leffler fprintf(f, "update_config=%d\n", config->update_config);
116439beb93cSSam Leffler #ifdef CONFIG_WPS
116539beb93cSSam Leffler if (!is_nil_uuid(config->uuid)) {
116639beb93cSSam Leffler char buf[40];
116739beb93cSSam Leffler uuid_bin2str(config->uuid, buf, sizeof(buf));
116839beb93cSSam Leffler fprintf(f, "uuid=%s\n", buf);
116939beb93cSSam Leffler }
117085732ac8SCy Schubert if (config->auto_uuid)
117185732ac8SCy Schubert fprintf(f, "auto_uuid=%d\n", config->auto_uuid);
117239beb93cSSam Leffler if (config->device_name)
117339beb93cSSam Leffler fprintf(f, "device_name=%s\n", config->device_name);
117439beb93cSSam Leffler if (config->manufacturer)
117539beb93cSSam Leffler fprintf(f, "manufacturer=%s\n", config->manufacturer);
117639beb93cSSam Leffler if (config->model_name)
117739beb93cSSam Leffler fprintf(f, "model_name=%s\n", config->model_name);
117839beb93cSSam Leffler if (config->model_number)
117939beb93cSSam Leffler fprintf(f, "model_number=%s\n", config->model_number);
118039beb93cSSam Leffler if (config->serial_number)
118139beb93cSSam Leffler fprintf(f, "serial_number=%s\n", config->serial_number);
1182f05cddf9SRui Paulo {
1183f05cddf9SRui Paulo char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
1184f05cddf9SRui Paulo buf = wps_dev_type_bin2str(config->device_type,
1185f05cddf9SRui Paulo _buf, sizeof(_buf));
1186f05cddf9SRui Paulo if (os_strcmp(buf, "0-00000000-0") != 0)
1187f05cddf9SRui Paulo fprintf(f, "device_type=%s\n", buf);
1188f05cddf9SRui Paulo }
118939beb93cSSam Leffler if (WPA_GET_BE32(config->os_version))
119039beb93cSSam Leffler fprintf(f, "os_version=%08x\n",
119139beb93cSSam Leffler WPA_GET_BE32(config->os_version));
1192e28a4053SRui Paulo if (config->config_methods)
1193e28a4053SRui Paulo fprintf(f, "config_methods=%s\n", config->config_methods);
119439beb93cSSam Leffler if (config->wps_cred_processing)
119539beb93cSSam Leffler fprintf(f, "wps_cred_processing=%d\n",
119639beb93cSSam Leffler config->wps_cred_processing);
11974bc52338SCy Schubert if (config->wps_cred_add_sae)
11984bc52338SCy Schubert fprintf(f, "wps_cred_add_sae=%d\n",
11994bc52338SCy Schubert config->wps_cred_add_sae);
1200f05cddf9SRui Paulo if (config->wps_vendor_ext_m1) {
1201f05cddf9SRui Paulo int i, len = wpabuf_len(config->wps_vendor_ext_m1);
1202f05cddf9SRui Paulo const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1);
1203f05cddf9SRui Paulo if (len > 0) {
1204f05cddf9SRui Paulo fprintf(f, "wps_vendor_ext_m1=");
1205f05cddf9SRui Paulo for (i = 0; i < len; i++)
1206f05cddf9SRui Paulo fprintf(f, "%02x", *p++);
1207f05cddf9SRui Paulo fprintf(f, "\n");
1208f05cddf9SRui Paulo }
1209f05cddf9SRui Paulo }
121039beb93cSSam Leffler #endif /* CONFIG_WPS */
1211f05cddf9SRui Paulo #ifdef CONFIG_P2P
121285732ac8SCy Schubert {
121385732ac8SCy Schubert int i;
121485732ac8SCy Schubert char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
121585732ac8SCy Schubert
121685732ac8SCy Schubert for (i = 0; i < config->num_sec_device_types; i++) {
121785732ac8SCy Schubert buf = wps_dev_type_bin2str(config->sec_device_type[i],
121885732ac8SCy Schubert _buf, sizeof(_buf));
121985732ac8SCy Schubert if (buf)
122085732ac8SCy Schubert fprintf(f, "sec_device_type=%s\n", buf);
122185732ac8SCy Schubert }
122285732ac8SCy Schubert }
1223f05cddf9SRui Paulo if (config->p2p_listen_reg_class)
1224325151a3SRui Paulo fprintf(f, "p2p_listen_reg_class=%d\n",
1225f05cddf9SRui Paulo config->p2p_listen_reg_class);
1226f05cddf9SRui Paulo if (config->p2p_listen_channel)
1227325151a3SRui Paulo fprintf(f, "p2p_listen_channel=%d\n",
1228f05cddf9SRui Paulo config->p2p_listen_channel);
1229f05cddf9SRui Paulo if (config->p2p_oper_reg_class)
1230325151a3SRui Paulo fprintf(f, "p2p_oper_reg_class=%d\n",
1231f05cddf9SRui Paulo config->p2p_oper_reg_class);
1232f05cddf9SRui Paulo if (config->p2p_oper_channel)
1233325151a3SRui Paulo fprintf(f, "p2p_oper_channel=%d\n", config->p2p_oper_channel);
1234f05cddf9SRui Paulo if (config->p2p_go_intent != DEFAULT_P2P_GO_INTENT)
1235325151a3SRui Paulo fprintf(f, "p2p_go_intent=%d\n", config->p2p_go_intent);
1236f05cddf9SRui Paulo if (config->p2p_ssid_postfix)
1237f05cddf9SRui Paulo fprintf(f, "p2p_ssid_postfix=%s\n", config->p2p_ssid_postfix);
1238f05cddf9SRui Paulo if (config->persistent_reconnect)
1239325151a3SRui Paulo fprintf(f, "persistent_reconnect=%d\n",
1240f05cddf9SRui Paulo config->persistent_reconnect);
1241f05cddf9SRui Paulo if (config->p2p_intra_bss != DEFAULT_P2P_INTRA_BSS)
1242325151a3SRui Paulo fprintf(f, "p2p_intra_bss=%d\n", config->p2p_intra_bss);
1243f05cddf9SRui Paulo if (config->p2p_group_idle)
1244325151a3SRui Paulo fprintf(f, "p2p_group_idle=%d\n", config->p2p_group_idle);
12455b9c547cSRui Paulo if (config->p2p_passphrase_len)
12465b9c547cSRui Paulo fprintf(f, "p2p_passphrase_len=%u\n",
12475b9c547cSRui Paulo config->p2p_passphrase_len);
1248f05cddf9SRui Paulo if (config->p2p_pref_chan) {
1249f05cddf9SRui Paulo unsigned int i;
1250f05cddf9SRui Paulo fprintf(f, "p2p_pref_chan=");
1251f05cddf9SRui Paulo for (i = 0; i < config->num_p2p_pref_chan; i++) {
1252f05cddf9SRui Paulo fprintf(f, "%s%u:%u", i > 0 ? "," : "",
1253f05cddf9SRui Paulo config->p2p_pref_chan[i].op_class,
1254f05cddf9SRui Paulo config->p2p_pref_chan[i].chan);
1255f05cddf9SRui Paulo }
1256f05cddf9SRui Paulo fprintf(f, "\n");
1257f05cddf9SRui Paulo }
12585b9c547cSRui Paulo if (config->p2p_no_go_freq.num) {
12595b9c547cSRui Paulo char *val = freq_range_list_str(&config->p2p_no_go_freq);
12605b9c547cSRui Paulo if (val) {
12615b9c547cSRui Paulo fprintf(f, "p2p_no_go_freq=%s\n", val);
12625b9c547cSRui Paulo os_free(val);
12635b9c547cSRui Paulo }
12645b9c547cSRui Paulo }
12655b9c547cSRui Paulo if (config->p2p_add_cli_chan)
12665b9c547cSRui Paulo fprintf(f, "p2p_add_cli_chan=%d\n", config->p2p_add_cli_chan);
12675b9c547cSRui Paulo if (config->p2p_optimize_listen_chan !=
12685b9c547cSRui Paulo DEFAULT_P2P_OPTIMIZE_LISTEN_CHAN)
12695b9c547cSRui Paulo fprintf(f, "p2p_optimize_listen_chan=%d\n",
12705b9c547cSRui Paulo config->p2p_optimize_listen_chan);
1271f05cddf9SRui Paulo if (config->p2p_go_ht40)
1272325151a3SRui Paulo fprintf(f, "p2p_go_ht40=%d\n", config->p2p_go_ht40);
12735b9c547cSRui Paulo if (config->p2p_go_vht)
1274325151a3SRui Paulo fprintf(f, "p2p_go_vht=%d\n", config->p2p_go_vht);
12754bc52338SCy Schubert if (config->p2p_go_he)
12764bc52338SCy Schubert fprintf(f, "p2p_go_he=%d\n", config->p2p_go_he);
1277c1d255d3SCy Schubert if (config->p2p_go_edmg)
1278c1d255d3SCy Schubert fprintf(f, "p2p_go_edmg=%d\n", config->p2p_go_edmg);
12795b9c547cSRui Paulo if (config->p2p_go_ctwindow != DEFAULT_P2P_GO_CTWINDOW)
1280325151a3SRui Paulo fprintf(f, "p2p_go_ctwindow=%d\n", config->p2p_go_ctwindow);
1281f05cddf9SRui Paulo if (config->p2p_disabled)
1282325151a3SRui Paulo fprintf(f, "p2p_disabled=%d\n", config->p2p_disabled);
1283f05cddf9SRui Paulo if (config->p2p_no_group_iface)
1284325151a3SRui Paulo fprintf(f, "p2p_no_group_iface=%d\n",
1285f05cddf9SRui Paulo config->p2p_no_group_iface);
12865b9c547cSRui Paulo if (config->p2p_ignore_shared_freq)
1287325151a3SRui Paulo fprintf(f, "p2p_ignore_shared_freq=%d\n",
12885b9c547cSRui Paulo config->p2p_ignore_shared_freq);
1289325151a3SRui Paulo if (config->p2p_cli_probe)
1290325151a3SRui Paulo fprintf(f, "p2p_cli_probe=%d\n", config->p2p_cli_probe);
1291325151a3SRui Paulo if (config->p2p_go_freq_change_policy != DEFAULT_P2P_GO_FREQ_MOVE)
1292325151a3SRui Paulo fprintf(f, "p2p_go_freq_change_policy=%u\n",
1293325151a3SRui Paulo config->p2p_go_freq_change_policy);
1294c1d255d3SCy Schubert
1295c1d255d3SCy Schubert if (config->p2p_6ghz_disable)
1296c1d255d3SCy Schubert fprintf(f, "p2p_6ghz_disable=%d\n", config->p2p_6ghz_disable);
1297c1d255d3SCy Schubert
1298780fb4a2SCy Schubert if (WPA_GET_BE32(config->ip_addr_go))
1299780fb4a2SCy Schubert fprintf(f, "ip_addr_go=%u.%u.%u.%u\n",
1300780fb4a2SCy Schubert config->ip_addr_go[0], config->ip_addr_go[1],
1301780fb4a2SCy Schubert config->ip_addr_go[2], config->ip_addr_go[3]);
1302780fb4a2SCy Schubert if (WPA_GET_BE32(config->ip_addr_mask))
1303780fb4a2SCy Schubert fprintf(f, "ip_addr_mask=%u.%u.%u.%u\n",
1304780fb4a2SCy Schubert config->ip_addr_mask[0], config->ip_addr_mask[1],
1305780fb4a2SCy Schubert config->ip_addr_mask[2], config->ip_addr_mask[3]);
1306780fb4a2SCy Schubert if (WPA_GET_BE32(config->ip_addr_start))
1307780fb4a2SCy Schubert fprintf(f, "ip_addr_start=%u.%u.%u.%u\n",
1308780fb4a2SCy Schubert config->ip_addr_start[0], config->ip_addr_start[1],
1309780fb4a2SCy Schubert config->ip_addr_start[2], config->ip_addr_start[3]);
1310780fb4a2SCy Schubert if (WPA_GET_BE32(config->ip_addr_end))
1311780fb4a2SCy Schubert fprintf(f, "ip_addr_end=%u.%u.%u.%u\n",
1312780fb4a2SCy Schubert config->ip_addr_end[0], config->ip_addr_end[1],
1313780fb4a2SCy Schubert config->ip_addr_end[2], config->ip_addr_end[3]);
1314f05cddf9SRui Paulo #endif /* CONFIG_P2P */
131539beb93cSSam Leffler if (config->country[0] && config->country[1]) {
131639beb93cSSam Leffler fprintf(f, "country=%c%c\n",
131739beb93cSSam Leffler config->country[0], config->country[1]);
131839beb93cSSam Leffler }
1319e28a4053SRui Paulo if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT)
1320e28a4053SRui Paulo fprintf(f, "bss_max_count=%u\n", config->bss_max_count);
1321f05cddf9SRui Paulo if (config->bss_expiration_age != DEFAULT_BSS_EXPIRATION_AGE)
1322f05cddf9SRui Paulo fprintf(f, "bss_expiration_age=%u\n",
1323f05cddf9SRui Paulo config->bss_expiration_age);
1324f05cddf9SRui Paulo if (config->bss_expiration_scan_count !=
1325f05cddf9SRui Paulo DEFAULT_BSS_EXPIRATION_SCAN_COUNT)
1326f05cddf9SRui Paulo fprintf(f, "bss_expiration_scan_count=%u\n",
1327f05cddf9SRui Paulo config->bss_expiration_scan_count);
1328e28a4053SRui Paulo if (config->filter_ssids)
1329e28a4053SRui Paulo fprintf(f, "filter_ssids=%d\n", config->filter_ssids);
133085732ac8SCy Schubert if (config->filter_rssi)
133185732ac8SCy Schubert fprintf(f, "filter_rssi=%d\n", config->filter_rssi);
1332f05cddf9SRui Paulo if (config->max_num_sta != DEFAULT_MAX_NUM_STA)
1333f05cddf9SRui Paulo fprintf(f, "max_num_sta=%u\n", config->max_num_sta);
133485732ac8SCy Schubert if (config->ap_isolate != DEFAULT_AP_ISOLATE)
133585732ac8SCy Schubert fprintf(f, "ap_isolate=%u\n", config->ap_isolate);
1336f05cddf9SRui Paulo if (config->disassoc_low_ack)
1337325151a3SRui Paulo fprintf(f, "disassoc_low_ack=%d\n", config->disassoc_low_ack);
1338f05cddf9SRui Paulo #ifdef CONFIG_HS20
1339f05cddf9SRui Paulo if (config->hs20)
1340f05cddf9SRui Paulo fprintf(f, "hs20=1\n");
1341f05cddf9SRui Paulo #endif /* CONFIG_HS20 */
1342f05cddf9SRui Paulo #ifdef CONFIG_INTERWORKING
1343f05cddf9SRui Paulo if (config->interworking)
1344325151a3SRui Paulo fprintf(f, "interworking=%d\n", config->interworking);
1345f05cddf9SRui Paulo if (!is_zero_ether_addr(config->hessid))
1346f05cddf9SRui Paulo fprintf(f, "hessid=" MACSTR "\n", MAC2STR(config->hessid));
1347f05cddf9SRui Paulo if (config->access_network_type != DEFAULT_ACCESS_NETWORK_TYPE)
1348f05cddf9SRui Paulo fprintf(f, "access_network_type=%d\n",
1349f05cddf9SRui Paulo config->access_network_type);
135085732ac8SCy Schubert if (config->go_interworking)
135185732ac8SCy Schubert fprintf(f, "go_interworking=%d\n", config->go_interworking);
135285732ac8SCy Schubert if (config->go_access_network_type)
135385732ac8SCy Schubert fprintf(f, "go_access_network_type=%d\n",
135485732ac8SCy Schubert config->go_access_network_type);
135585732ac8SCy Schubert if (config->go_internet)
135685732ac8SCy Schubert fprintf(f, "go_internet=%d\n", config->go_internet);
135785732ac8SCy Schubert if (config->go_venue_group)
135885732ac8SCy Schubert fprintf(f, "go_venue_group=%d\n", config->go_venue_group);
135985732ac8SCy Schubert if (config->go_venue_type)
136085732ac8SCy Schubert fprintf(f, "go_venue_type=%d\n", config->go_venue_type);
1361f05cddf9SRui Paulo #endif /* CONFIG_INTERWORKING */
1362f05cddf9SRui Paulo if (config->pbc_in_m1)
1363325151a3SRui Paulo fprintf(f, "pbc_in_m1=%d\n", config->pbc_in_m1);
13645b9c547cSRui Paulo if (config->wps_nfc_pw_from_config) {
1365f05cddf9SRui Paulo if (config->wps_nfc_dev_pw_id)
1366f05cddf9SRui Paulo fprintf(f, "wps_nfc_dev_pw_id=%d\n",
1367f05cddf9SRui Paulo config->wps_nfc_dev_pw_id);
13685b9c547cSRui Paulo write_global_bin(f, "wps_nfc_dh_pubkey",
13695b9c547cSRui Paulo config->wps_nfc_dh_pubkey);
13705b9c547cSRui Paulo write_global_bin(f, "wps_nfc_dh_privkey",
13715b9c547cSRui Paulo config->wps_nfc_dh_privkey);
1372f05cddf9SRui Paulo write_global_bin(f, "wps_nfc_dev_pw", config->wps_nfc_dev_pw);
13735b9c547cSRui Paulo }
1374f05cddf9SRui Paulo
1375f05cddf9SRui Paulo if (config->ext_password_backend)
1376f05cddf9SRui Paulo fprintf(f, "ext_password_backend=%s\n",
1377f05cddf9SRui Paulo config->ext_password_backend);
1378f05cddf9SRui Paulo if (config->p2p_go_max_inactivity != DEFAULT_P2P_GO_MAX_INACTIVITY)
1379f05cddf9SRui Paulo fprintf(f, "p2p_go_max_inactivity=%d\n",
1380f05cddf9SRui Paulo config->p2p_go_max_inactivity);
1381f05cddf9SRui Paulo if (config->auto_interworking)
1382f05cddf9SRui Paulo fprintf(f, "auto_interworking=%d\n",
1383f05cddf9SRui Paulo config->auto_interworking);
1384f05cddf9SRui Paulo if (config->okc)
1385f05cddf9SRui Paulo fprintf(f, "okc=%d\n", config->okc);
1386f05cddf9SRui Paulo if (config->pmf)
1387f05cddf9SRui Paulo fprintf(f, "pmf=%d\n", config->pmf);
13885b9c547cSRui Paulo if (config->dtim_period)
13895b9c547cSRui Paulo fprintf(f, "dtim_period=%d\n", config->dtim_period);
13905b9c547cSRui Paulo if (config->beacon_int)
13915b9c547cSRui Paulo fprintf(f, "beacon_int=%d\n", config->beacon_int);
13925b9c547cSRui Paulo
1393*a90b9d01SCy Schubert if (config->sae_check_mfp)
1394*a90b9d01SCy Schubert fprintf(f, "sae_check_mfp=%d\n", config->sae_check_mfp);
1395*a90b9d01SCy Schubert
13965b9c547cSRui Paulo if (config->sae_groups) {
13975b9c547cSRui Paulo int i;
13985b9c547cSRui Paulo fprintf(f, "sae_groups=");
139985732ac8SCy Schubert for (i = 0; config->sae_groups[i] > 0; i++) {
14005b9c547cSRui Paulo fprintf(f, "%s%d", i > 0 ? " " : "",
14015b9c547cSRui Paulo config->sae_groups[i]);
14025b9c547cSRui Paulo }
14035b9c547cSRui Paulo fprintf(f, "\n");
14045b9c547cSRui Paulo }
14055b9c547cSRui Paulo
1406c1d255d3SCy Schubert if (config->sae_pwe)
1407c1d255d3SCy Schubert fprintf(f, "sae_pwe=%d\n", config->sae_pwe);
1408c1d255d3SCy Schubert
1409c1d255d3SCy Schubert if (config->sae_pmkid_in_assoc)
1410c1d255d3SCy Schubert fprintf(f, "sae_pmkid_in_assoc=%d\n",
1411c1d255d3SCy Schubert config->sae_pmkid_in_assoc);
1412c1d255d3SCy Schubert
14135b9c547cSRui Paulo if (config->ap_vendor_elements) {
14145b9c547cSRui Paulo int i, len = wpabuf_len(config->ap_vendor_elements);
14155b9c547cSRui Paulo const u8 *p = wpabuf_head_u8(config->ap_vendor_elements);
14165b9c547cSRui Paulo if (len > 0) {
14175b9c547cSRui Paulo fprintf(f, "ap_vendor_elements=");
14185b9c547cSRui Paulo for (i = 0; i < len; i++)
14195b9c547cSRui Paulo fprintf(f, "%02x", *p++);
14205b9c547cSRui Paulo fprintf(f, "\n");
14215b9c547cSRui Paulo }
14225b9c547cSRui Paulo }
14235b9c547cSRui Paulo
14244b72b91aSCy Schubert if (config->ap_assocresp_elements) {
14254b72b91aSCy Schubert int i, len = wpabuf_len(config->ap_assocresp_elements);
14264b72b91aSCy Schubert const u8 *p = wpabuf_head_u8(config->ap_assocresp_elements);
14274b72b91aSCy Schubert
14284b72b91aSCy Schubert if (len > 0) {
14294b72b91aSCy Schubert fprintf(f, "ap_assocresp_elements=");
14304b72b91aSCy Schubert for (i = 0; i < len; i++)
14314b72b91aSCy Schubert fprintf(f, "%02x", *p++);
14324b72b91aSCy Schubert fprintf(f, "\n");
14334b72b91aSCy Schubert }
14344b72b91aSCy Schubert }
14354b72b91aSCy Schubert
14365b9c547cSRui Paulo if (config->ignore_old_scan_res)
14375b9c547cSRui Paulo fprintf(f, "ignore_old_scan_res=%d\n",
14385b9c547cSRui Paulo config->ignore_old_scan_res);
14395b9c547cSRui Paulo
14405b9c547cSRui Paulo if (config->freq_list && config->freq_list[0]) {
14415b9c547cSRui Paulo int i;
14425b9c547cSRui Paulo fprintf(f, "freq_list=");
14435b9c547cSRui Paulo for (i = 0; config->freq_list[i]; i++) {
1444325151a3SRui Paulo fprintf(f, "%s%d", i > 0 ? " " : "",
14455b9c547cSRui Paulo config->freq_list[i]);
14465b9c547cSRui Paulo }
14475b9c547cSRui Paulo fprintf(f, "\n");
14485b9c547cSRui Paulo }
1449c1d255d3SCy Schubert if (config->initial_freq_list && config->initial_freq_list[0]) {
1450c1d255d3SCy Schubert int i;
1451c1d255d3SCy Schubert fprintf(f, "initial_freq_list=");
1452c1d255d3SCy Schubert for (i = 0; config->initial_freq_list[i]; i++) {
1453c1d255d3SCy Schubert fprintf(f, "%s%d", i > 0 ? " " : "",
1454c1d255d3SCy Schubert config->initial_freq_list[i]);
1455c1d255d3SCy Schubert }
1456c1d255d3SCy Schubert fprintf(f, "\n");
1457c1d255d3SCy Schubert }
14585b9c547cSRui Paulo if (config->scan_cur_freq != DEFAULT_SCAN_CUR_FREQ)
14595b9c547cSRui Paulo fprintf(f, "scan_cur_freq=%d\n", config->scan_cur_freq);
14605b9c547cSRui Paulo
1461c1d255d3SCy Schubert if (config->scan_res_valid_for_connect !=
1462c1d255d3SCy Schubert DEFAULT_SCAN_RES_VALID_FOR_CONNECT)
1463c1d255d3SCy Schubert fprintf(f, "scan_res_valid_for_connect=%d\n",
1464c1d255d3SCy Schubert config->scan_res_valid_for_connect);
1465c1d255d3SCy Schubert
14665b9c547cSRui Paulo if (config->sched_scan_interval)
14675b9c547cSRui Paulo fprintf(f, "sched_scan_interval=%u\n",
14685b9c547cSRui Paulo config->sched_scan_interval);
14695b9c547cSRui Paulo
147085732ac8SCy Schubert if (config->sched_scan_start_delay)
147185732ac8SCy Schubert fprintf(f, "sched_scan_start_delay=%u\n",
147285732ac8SCy Schubert config->sched_scan_start_delay);
147385732ac8SCy Schubert
14745b9c547cSRui Paulo if (config->external_sim)
14755b9c547cSRui Paulo fprintf(f, "external_sim=%d\n", config->external_sim);
14765b9c547cSRui Paulo
14775b9c547cSRui Paulo if (config->tdls_external_control)
14785b9c547cSRui Paulo fprintf(f, "tdls_external_control=%d\n",
14795b9c547cSRui Paulo config->tdls_external_control);
14805b9c547cSRui Paulo
14815b9c547cSRui Paulo if (config->wowlan_triggers)
14825b9c547cSRui Paulo fprintf(f, "wowlan_triggers=%s\n",
14835b9c547cSRui Paulo config->wowlan_triggers);
14845b9c547cSRui Paulo
14855b9c547cSRui Paulo if (config->bgscan)
14865b9c547cSRui Paulo fprintf(f, "bgscan=\"%s\"\n", config->bgscan);
14875b9c547cSRui Paulo
148885732ac8SCy Schubert if (config->autoscan)
148985732ac8SCy Schubert fprintf(f, "autoscan=%s\n", config->autoscan);
149085732ac8SCy Schubert
14915b9c547cSRui Paulo if (config->p2p_search_delay != DEFAULT_P2P_SEARCH_DELAY)
14925b9c547cSRui Paulo fprintf(f, "p2p_search_delay=%u\n",
14935b9c547cSRui Paulo config->p2p_search_delay);
14945b9c547cSRui Paulo
14955b9c547cSRui Paulo if (config->mac_addr)
14965b9c547cSRui Paulo fprintf(f, "mac_addr=%d\n", config->mac_addr);
14975b9c547cSRui Paulo
14985b9c547cSRui Paulo if (config->rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME)
14995b9c547cSRui Paulo fprintf(f, "rand_addr_lifetime=%u\n",
15005b9c547cSRui Paulo config->rand_addr_lifetime);
15015b9c547cSRui Paulo
15025b9c547cSRui Paulo if (config->preassoc_mac_addr)
15035b9c547cSRui Paulo fprintf(f, "preassoc_mac_addr=%d\n", config->preassoc_mac_addr);
15045b9c547cSRui Paulo
15055b9c547cSRui Paulo if (config->key_mgmt_offload != DEFAULT_KEY_MGMT_OFFLOAD)
1506325151a3SRui Paulo fprintf(f, "key_mgmt_offload=%d\n", config->key_mgmt_offload);
15075b9c547cSRui Paulo
15085b9c547cSRui Paulo if (config->user_mpm != DEFAULT_USER_MPM)
15095b9c547cSRui Paulo fprintf(f, "user_mpm=%d\n", config->user_mpm);
15105b9c547cSRui Paulo
15115b9c547cSRui Paulo if (config->max_peer_links != DEFAULT_MAX_PEER_LINKS)
15125b9c547cSRui Paulo fprintf(f, "max_peer_links=%d\n", config->max_peer_links);
15135b9c547cSRui Paulo
15145b9c547cSRui Paulo if (config->cert_in_cb != DEFAULT_CERT_IN_CB)
15155b9c547cSRui Paulo fprintf(f, "cert_in_cb=%d\n", config->cert_in_cb);
15165b9c547cSRui Paulo
15175b9c547cSRui Paulo if (config->mesh_max_inactivity != DEFAULT_MESH_MAX_INACTIVITY)
15185b9c547cSRui Paulo fprintf(f, "mesh_max_inactivity=%d\n",
15195b9c547cSRui Paulo config->mesh_max_inactivity);
15205b9c547cSRui Paulo
152132a95656SCy Schubert if (config->mesh_fwding != DEFAULT_MESH_FWDING)
152232a95656SCy Schubert fprintf(f, "mesh_fwding=%d\n", config->mesh_fwding);
152332a95656SCy Schubert
1524325151a3SRui Paulo if (config->dot11RSNASAERetransPeriod !=
1525325151a3SRui Paulo DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD)
1526325151a3SRui Paulo fprintf(f, "dot11RSNASAERetransPeriod=%d\n",
1527325151a3SRui Paulo config->dot11RSNASAERetransPeriod);
1528325151a3SRui Paulo
15295b9c547cSRui Paulo if (config->passive_scan)
15305b9c547cSRui Paulo fprintf(f, "passive_scan=%d\n", config->passive_scan);
15315b9c547cSRui Paulo
15325b9c547cSRui Paulo if (config->reassoc_same_bss_optim)
15335b9c547cSRui Paulo fprintf(f, "reassoc_same_bss_optim=%d\n",
15345b9c547cSRui Paulo config->reassoc_same_bss_optim);
1535325151a3SRui Paulo
1536325151a3SRui Paulo if (config->wps_priority)
1537325151a3SRui Paulo fprintf(f, "wps_priority=%d\n", config->wps_priority);
1538780fb4a2SCy Schubert
1539780fb4a2SCy Schubert if (config->wpa_rsc_relaxation != DEFAULT_WPA_RSC_RELAXATION)
1540780fb4a2SCy Schubert fprintf(f, "wpa_rsc_relaxation=%d\n",
1541780fb4a2SCy Schubert config->wpa_rsc_relaxation);
1542780fb4a2SCy Schubert
1543780fb4a2SCy Schubert if (config->sched_scan_plans)
1544780fb4a2SCy Schubert fprintf(f, "sched_scan_plans=%s\n", config->sched_scan_plans);
1545780fb4a2SCy Schubert
1546780fb4a2SCy Schubert #ifdef CONFIG_MBO
1547780fb4a2SCy Schubert if (config->non_pref_chan)
1548780fb4a2SCy Schubert fprintf(f, "non_pref_chan=%s\n", config->non_pref_chan);
1549780fb4a2SCy Schubert if (config->mbo_cell_capa != DEFAULT_MBO_CELL_CAPA)
1550780fb4a2SCy Schubert fprintf(f, "mbo_cell_capa=%u\n", config->mbo_cell_capa);
155185732ac8SCy Schubert if (config->disassoc_imminent_rssi_threshold !=
155285732ac8SCy Schubert DEFAULT_DISASSOC_IMMINENT_RSSI_THRESHOLD)
155385732ac8SCy Schubert fprintf(f, "disassoc_imminent_rssi_threshold=%d\n",
155485732ac8SCy Schubert config->disassoc_imminent_rssi_threshold);
155585732ac8SCy Schubert if (config->oce != DEFAULT_OCE_SUPPORT)
155685732ac8SCy Schubert fprintf(f, "oce=%u\n", config->oce);
1557780fb4a2SCy Schubert #endif /* CONFIG_MBO */
1558780fb4a2SCy Schubert
1559780fb4a2SCy Schubert if (config->gas_address3)
1560780fb4a2SCy Schubert fprintf(f, "gas_address3=%d\n", config->gas_address3);
1561780fb4a2SCy Schubert
1562780fb4a2SCy Schubert if (config->ftm_responder)
1563780fb4a2SCy Schubert fprintf(f, "ftm_responder=%d\n", config->ftm_responder);
1564780fb4a2SCy Schubert if (config->ftm_initiator)
1565780fb4a2SCy Schubert fprintf(f, "ftm_initiator=%d\n", config->ftm_initiator);
156685732ac8SCy Schubert
156785732ac8SCy Schubert if (config->osu_dir)
156885732ac8SCy Schubert fprintf(f, "osu_dir=%s\n", config->osu_dir);
156985732ac8SCy Schubert
157085732ac8SCy Schubert if (config->fst_group_id)
157185732ac8SCy Schubert fprintf(f, "fst_group_id=%s\n", config->fst_group_id);
157285732ac8SCy Schubert if (config->fst_priority)
157385732ac8SCy Schubert fprintf(f, "fst_priority=%d\n", config->fst_priority);
157485732ac8SCy Schubert if (config->fst_llt)
157585732ac8SCy Schubert fprintf(f, "fst_llt=%d\n", config->fst_llt);
157685732ac8SCy Schubert
157785732ac8SCy Schubert if (config->gas_rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME)
157885732ac8SCy Schubert fprintf(f, "gas_rand_addr_lifetime=%u\n",
157985732ac8SCy Schubert config->gas_rand_addr_lifetime);
158085732ac8SCy Schubert if (config->gas_rand_mac_addr)
158185732ac8SCy Schubert fprintf(f, "gas_rand_mac_addr=%d\n", config->gas_rand_mac_addr);
158285732ac8SCy Schubert if (config->dpp_config_processing)
158385732ac8SCy Schubert fprintf(f, "dpp_config_processing=%d\n",
158485732ac8SCy Schubert config->dpp_config_processing);
1585*a90b9d01SCy Schubert if (config->dpp_name)
1586*a90b9d01SCy Schubert fprintf(f, "dpp_name=%s\n", config->dpp_name);
1587*a90b9d01SCy Schubert if (config->dpp_mud_url)
1588*a90b9d01SCy Schubert fprintf(f, "dpp_mud_url=%s\n", config->dpp_mud_url);
1589*a90b9d01SCy Schubert if (config->dpp_extra_conf_req_name)
1590*a90b9d01SCy Schubert fprintf(f, "dpp_extra_conf_req_name=%s\n",
1591*a90b9d01SCy Schubert config->dpp_extra_conf_req_name);
1592*a90b9d01SCy Schubert if (config->dpp_extra_conf_req_value)
1593*a90b9d01SCy Schubert fprintf(f, "dpp_extra_conf_req_value=%s\n",
1594*a90b9d01SCy Schubert config->dpp_extra_conf_req_value);
1595*a90b9d01SCy Schubert if (config->dpp_connector_privacy_default)
1596*a90b9d01SCy Schubert fprintf(f, "dpp_connector_privacy_default=%d\n",
1597*a90b9d01SCy Schubert config->dpp_connector_privacy_default);
159885732ac8SCy Schubert if (config->coloc_intf_reporting)
159985732ac8SCy Schubert fprintf(f, "coloc_intf_reporting=%d\n",
160085732ac8SCy Schubert config->coloc_intf_reporting);
16014bc52338SCy Schubert if (config->p2p_device_random_mac_addr)
16024bc52338SCy Schubert fprintf(f, "p2p_device_random_mac_addr=%d\n",
16034bc52338SCy Schubert config->p2p_device_random_mac_addr);
16044bc52338SCy Schubert if (!is_zero_ether_addr(config->p2p_device_persistent_mac_addr))
16054bc52338SCy Schubert fprintf(f, "p2p_device_persistent_mac_addr=" MACSTR "\n",
16064bc52338SCy Schubert MAC2STR(config->p2p_device_persistent_mac_addr));
16074bc52338SCy Schubert if (config->p2p_interface_random_mac_addr)
16084bc52338SCy Schubert fprintf(f, "p2p_interface_random_mac_addr=%d\n",
16094bc52338SCy Schubert config->p2p_interface_random_mac_addr);
1610206b73d0SCy Schubert if (config->disable_btm)
1611206b73d0SCy Schubert fprintf(f, "disable_btm=1\n");
1612c1d255d3SCy Schubert if (config->extended_key_id != DEFAULT_EXTENDED_KEY_ID)
1613c1d255d3SCy Schubert fprintf(f, "extended_key_id=%d\n",
1614c1d255d3SCy Schubert config->extended_key_id);
1615c1d255d3SCy Schubert if (config->wowlan_disconnect_on_deinit)
1616c1d255d3SCy Schubert fprintf(f, "wowlan_disconnect_on_deinit=%d\n",
1617c1d255d3SCy Schubert config->wowlan_disconnect_on_deinit);
1618*a90b9d01SCy Schubert #ifdef CONFIG_TESTING_OPTIONS
1619*a90b9d01SCy Schubert if (config->mld_force_single_link)
1620*a90b9d01SCy Schubert fprintf(f, "mld_force_single_link=1\n");
1621*a90b9d01SCy Schubert if (config->mld_connect_band_pref != MLD_CONNECT_BAND_PREF_AUTO)
1622*a90b9d01SCy Schubert fprintf(f, "mld_connect_band_pref=%d\n",
1623*a90b9d01SCy Schubert config->mld_connect_band_pref);
1624*a90b9d01SCy Schubert if (!is_zero_ether_addr(config->mld_connect_bssid_pref))
1625*a90b9d01SCy Schubert fprintf(f, "mld_connect_bssid_pref=" MACSTR "\n",
1626*a90b9d01SCy Schubert MAC2STR(config->mld_connect_bssid_pref));
1627*a90b9d01SCy Schubert #endif /* CONFIG_TESTING_OPTIONS */
1628*a90b9d01SCy Schubert if (config->ft_prepend_pmkid)
1629*a90b9d01SCy Schubert fprintf(f, "ft_prepend_pmkid=%d", config->ft_prepend_pmkid);
163039beb93cSSam Leffler }
163139beb93cSSam Leffler
163239beb93cSSam Leffler #endif /* CONFIG_NO_CONFIG_WRITE */
163339beb93cSSam Leffler
163439beb93cSSam Leffler
wpa_config_write(const char * name,struct wpa_config * config)163539beb93cSSam Leffler int wpa_config_write(const char *name, struct wpa_config *config)
163639beb93cSSam Leffler {
163739beb93cSSam Leffler #ifndef CONFIG_NO_CONFIG_WRITE
163839beb93cSSam Leffler FILE *f;
163939beb93cSSam Leffler struct wpa_ssid *ssid;
1640f05cddf9SRui Paulo struct wpa_cred *cred;
164139beb93cSSam Leffler #ifndef CONFIG_NO_CONFIG_BLOBS
164239beb93cSSam Leffler struct wpa_config_blob *blob;
164339beb93cSSam Leffler #endif /* CONFIG_NO_CONFIG_BLOBS */
164439beb93cSSam Leffler int ret = 0;
16455b9c547cSRui Paulo const char *orig_name = name;
1646c1d255d3SCy Schubert int tmp_len;
1647c1d255d3SCy Schubert char *tmp_name;
16485b9c547cSRui Paulo
1649c1d255d3SCy Schubert if (!name) {
1650c1d255d3SCy Schubert wpa_printf(MSG_ERROR, "No configuration file for writing");
1651c1d255d3SCy Schubert return -1;
1652c1d255d3SCy Schubert }
1653c1d255d3SCy Schubert
1654c1d255d3SCy Schubert tmp_len = os_strlen(name) + 5; /* allow space for .tmp suffix */
1655c1d255d3SCy Schubert tmp_name = os_malloc(tmp_len);
16565b9c547cSRui Paulo if (tmp_name) {
16575b9c547cSRui Paulo os_snprintf(tmp_name, tmp_len, "%s.tmp", name);
16585b9c547cSRui Paulo name = tmp_name;
16595b9c547cSRui Paulo }
166039beb93cSSam Leffler
166139beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
166239beb93cSSam Leffler
166339beb93cSSam Leffler f = fopen(name, "w");
166439beb93cSSam Leffler if (f == NULL) {
166539beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name);
16665b9c547cSRui Paulo os_free(tmp_name);
166739beb93cSSam Leffler return -1;
166839beb93cSSam Leffler }
166939beb93cSSam Leffler
167039beb93cSSam Leffler wpa_config_write_global(f, config);
167139beb93cSSam Leffler
1672f05cddf9SRui Paulo for (cred = config->cred; cred; cred = cred->next) {
16735b9c547cSRui Paulo if (cred->temporary)
16745b9c547cSRui Paulo continue;
1675f05cddf9SRui Paulo fprintf(f, "\ncred={\n");
1676f05cddf9SRui Paulo wpa_config_write_cred(f, cred);
1677f05cddf9SRui Paulo fprintf(f, "}\n");
1678f05cddf9SRui Paulo }
1679f05cddf9SRui Paulo
168039beb93cSSam Leffler for (ssid = config->ssid; ssid; ssid = ssid->next) {
1681*a90b9d01SCy Schubert if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary ||
1682*a90b9d01SCy Schubert ssid->ro)
1683f05cddf9SRui Paulo continue; /* do not save temporary networks */
1684c1d255d3SCy Schubert if (wpa_key_mgmt_wpa_psk_no_sae(ssid->key_mgmt) &&
1685c1d255d3SCy Schubert !ssid->psk_set && !ssid->passphrase)
1686c1d255d3SCy Schubert continue; /* do not save invalid network */
1687c1d255d3SCy Schubert if (wpa_key_mgmt_sae(ssid->key_mgmt) &&
1688c1d255d3SCy Schubert !ssid->passphrase && !ssid->sae_password)
1689f05cddf9SRui Paulo continue; /* do not save invalid network */
169039beb93cSSam Leffler fprintf(f, "\nnetwork={\n");
169139beb93cSSam Leffler wpa_config_write_network(f, ssid);
169239beb93cSSam Leffler fprintf(f, "}\n");
169339beb93cSSam Leffler }
169439beb93cSSam Leffler
169539beb93cSSam Leffler #ifndef CONFIG_NO_CONFIG_BLOBS
169639beb93cSSam Leffler for (blob = config->blobs; blob; blob = blob->next) {
169739beb93cSSam Leffler ret = wpa_config_write_blob(f, blob);
169839beb93cSSam Leffler if (ret)
169939beb93cSSam Leffler break;
170039beb93cSSam Leffler }
170139beb93cSSam Leffler #endif /* CONFIG_NO_CONFIG_BLOBS */
170239beb93cSSam Leffler
1703325151a3SRui Paulo os_fdatasync(f);
1704325151a3SRui Paulo
170539beb93cSSam Leffler fclose(f);
170639beb93cSSam Leffler
17075b9c547cSRui Paulo if (tmp_name) {
17085b9c547cSRui Paulo int chmod_ret = 0;
17095b9c547cSRui Paulo
17105b9c547cSRui Paulo #ifdef ANDROID
17115b9c547cSRui Paulo chmod_ret = chmod(tmp_name,
17125b9c547cSRui Paulo S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
17135b9c547cSRui Paulo #endif /* ANDROID */
17145b9c547cSRui Paulo if (chmod_ret != 0 || rename(tmp_name, orig_name) != 0)
17155b9c547cSRui Paulo ret = -1;
17165b9c547cSRui Paulo
17175b9c547cSRui Paulo os_free(tmp_name);
17185b9c547cSRui Paulo }
17195b9c547cSRui Paulo
172039beb93cSSam Leffler wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully",
17215b9c547cSRui Paulo orig_name, ret ? "un" : "");
172239beb93cSSam Leffler return ret;
172339beb93cSSam Leffler #else /* CONFIG_NO_CONFIG_WRITE */
172439beb93cSSam Leffler return -1;
172539beb93cSSam Leffler #endif /* CONFIG_NO_CONFIG_WRITE */
172639beb93cSSam Leffler }
1727