2 * WPA Supplicant / Configuration backend: text file
3 * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
8 * This file implements a configuration backend for text files. All the
9 * configuration information is stored in a text file that uses a format
10 * described in the sample configuration file, wpa_supplicant.conf.
22 static int newline_terminated(const char *buf
, size_t buflen
)
24 size_t len
= os_strlen(buf
);
27 if (len
== buflen
- 1 && buf
[buflen
- 1] != '\r' &&
34 static void skip_line_end(FILE *stream
)
37 while (fgets(buf
, sizeof(buf
), stream
)) {
38 buf
[sizeof(buf
) - 1] = '\0';
39 if (newline_terminated(buf
, sizeof(buf
)))
46 * wpa_config_get_line - Read the next configuration file line
47 * @s: Buffer for the line
48 * @size: The buffer length
49 * @stream: File stream to read from
50 * @line: Pointer to a variable storing the file line number
51 * @_pos: Buffer for the pointer to the beginning of data on the text line or
52 * %NULL if not needed (returned value used instead)
53 * Returns: Pointer to the beginning of data on the text line or %NULL if no
54 * more text lines are available.
56 * This function reads the next non-empty line from the configuration file and
57 * removes comments. The returned string is guaranteed to be null-terminated.
59 static char * wpa_config_get_line(char *s
, int size
, FILE *stream
, int *line
,
62 char *pos
, *end
, *sstart
;
64 while (fgets(s
, size
, stream
)) {
67 if (!newline_terminated(s
, size
)) {
69 * The line was truncated - skip rest of it to avoid
70 * confusing error messages.
72 wpa_printf(MSG_INFO
, "Long line in configuration file "
74 skip_line_end(stream
);
78 /* Skip white space from the beginning of line. */
79 while (*pos
== ' ' || *pos
== '\t' || *pos
== '\r')
82 /* Skip comment lines and empty lines */
83 if (*pos
== '#' || *pos
== '\n' || *pos
== '\0')
87 * Remove # comments unless they are within a double quoted
90 sstart
= os_strchr(pos
, '"');
92 sstart
= os_strrchr(sstart
+ 1, '"');
95 end
= os_strchr(sstart
, '#');
99 end
= pos
+ os_strlen(pos
) - 1;
101 /* Remove trailing white space. */
103 (*end
== '\n' || *end
== ' ' || *end
== '\t' ||
121 static int wpa_config_validate_network(struct wpa_ssid
*ssid
, int line
)
125 if (ssid
->passphrase
) {
127 wpa_printf(MSG_ERROR
, "Line %d: both PSK and "
128 "passphrase configured.", line
);
131 wpa_config_update_psk(ssid
);
134 if ((ssid
->group_cipher
& WPA_CIPHER_CCMP
) &&
135 !(ssid
->pairwise_cipher
& WPA_CIPHER_CCMP
) &&
136 !(ssid
->pairwise_cipher
& WPA_CIPHER_NONE
)) {
137 /* Group cipher cannot be stronger than the pairwise cipher. */
138 wpa_printf(MSG_DEBUG
, "Line %d: removed CCMP from group cipher"
139 " list since it was not allowed for pairwise "
141 ssid
->group_cipher
&= ~WPA_CIPHER_CCMP
;
148 static struct wpa_ssid
* wpa_config_read_network(FILE *f
, int *line
, int id
)
150 struct wpa_ssid
*ssid
;
151 int errors
= 0, end
= 0;
152 char buf
[2000], *pos
, *pos2
;
154 wpa_printf(MSG_MSGDUMP
, "Line: %d - start of a new network block",
156 ssid
= os_zalloc(sizeof(*ssid
));
161 wpa_config_set_network_defaults(ssid
);
163 while (wpa_config_get_line(buf
, sizeof(buf
), f
, line
, &pos
)) {
164 if (os_strcmp(pos
, "}") == 0) {
169 pos2
= os_strchr(pos
, '=');
171 wpa_printf(MSG_ERROR
, "Line %d: Invalid SSID line "
172 "'%s'.", *line
, pos
);
179 if (os_strchr(pos2
+ 1, '"') == NULL
) {
180 wpa_printf(MSG_ERROR
, "Line %d: invalid "
181 "quotation '%s'.", *line
, pos2
);
187 if (wpa_config_set(ssid
, pos
, pos2
, *line
) < 0)
192 wpa_printf(MSG_ERROR
, "Line %d: network block was not "
193 "terminated properly.", *line
);
197 errors
+= wpa_config_validate_network(ssid
, *line
);
200 wpa_config_free_ssid(ssid
);
208 static struct wpa_cred
* wpa_config_read_cred(FILE *f
, int *line
, int id
)
210 struct wpa_cred
*cred
;
211 int errors
= 0, end
= 0;
212 char buf
[256], *pos
, *pos2
;
214 wpa_printf(MSG_MSGDUMP
, "Line: %d - start of a new cred block", *line
);
215 cred
= os_zalloc(sizeof(*cred
));
220 while (wpa_config_get_line(buf
, sizeof(buf
), f
, line
, &pos
)) {
221 if (os_strcmp(pos
, "}") == 0) {
226 pos2
= os_strchr(pos
, '=');
228 wpa_printf(MSG_ERROR
, "Line %d: Invalid cred line "
229 "'%s'.", *line
, pos
);
236 if (os_strchr(pos2
+ 1, '"') == NULL
) {
237 wpa_printf(MSG_ERROR
, "Line %d: invalid "
238 "quotation '%s'.", *line
, pos2
);
244 if (wpa_config_set_cred(cred
, pos
, pos2
, *line
) < 0)
249 wpa_printf(MSG_ERROR
, "Line %d: cred block was not "
250 "terminated properly.", *line
);
255 wpa_config_free_cred(cred
);
263 #ifndef CONFIG_NO_CONFIG_BLOBS
264 static struct wpa_config_blob
* wpa_config_read_blob(FILE *f
, int *line
,
267 struct wpa_config_blob
*blob
;
269 unsigned char *encoded
= NULL
, *nencoded
;
271 size_t encoded_len
= 0, len
;
273 wpa_printf(MSG_MSGDUMP
, "Line: %d - start of a new named blob '%s'",
276 while (wpa_config_get_line(buf
, sizeof(buf
), f
, line
, &pos
)) {
277 if (os_strcmp(pos
, "}") == 0) {
282 len
= os_strlen(pos
);
283 nencoded
= os_realloc(encoded
, encoded_len
+ len
);
284 if (nencoded
== NULL
) {
285 wpa_printf(MSG_ERROR
, "Line %d: not enough memory for "
291 os_memcpy(encoded
+ encoded_len
, pos
, len
);
296 wpa_printf(MSG_ERROR
, "Line %d: blob was not terminated "
302 blob
= os_zalloc(sizeof(*blob
));
307 blob
->name
= os_strdup(name
);
308 blob
->data
= base64_decode(encoded
, encoded_len
, &blob
->len
);
311 if (blob
->name
== NULL
|| blob
->data
== NULL
) {
312 wpa_config_free_blob(blob
);
320 static int wpa_config_process_blob(struct wpa_config
*config
, FILE *f
,
321 int *line
, char *bname
)
324 struct wpa_config_blob
*blob
;
326 name_end
= os_strchr(bname
, '=');
327 if (name_end
== NULL
) {
328 wpa_printf(MSG_ERROR
, "Line %d: no blob name terminator",
334 blob
= wpa_config_read_blob(f
, line
, bname
);
336 wpa_printf(MSG_ERROR
, "Line %d: failed to read blob %s",
340 wpa_config_set_blob(config
, blob
);
343 #endif /* CONFIG_NO_CONFIG_BLOBS */
346 struct wpa_config
* wpa_config_read(const char *name
)
350 int errors
= 0, line
= 0;
351 struct wpa_ssid
*ssid
, *tail
= NULL
, *head
= NULL
;
352 struct wpa_cred
*cred
, *cred_tail
= NULL
, *cred_head
= NULL
;
353 struct wpa_config
*config
;
357 config
= wpa_config_alloc_empty(NULL
, NULL
);
358 if (config
== NULL
) {
359 wpa_printf(MSG_ERROR
, "Failed to allocate config file "
364 wpa_printf(MSG_DEBUG
, "Reading configuration file '%s'", name
);
365 f
= fopen(name
, "r");
367 wpa_printf(MSG_ERROR
, "Failed to open config file '%s', "
368 "error: %s", name
, strerror(errno
));
373 while (wpa_config_get_line(buf
, sizeof(buf
), f
, &line
, &pos
)) {
374 if (os_strcmp(pos
, "network={") == 0) {
375 ssid
= wpa_config_read_network(f
, &line
, id
++);
377 wpa_printf(MSG_ERROR
, "Line %d: failed to "
378 "parse network block.", line
);
388 if (wpa_config_add_prio_network(config
, ssid
)) {
389 wpa_printf(MSG_ERROR
, "Line %d: failed to add "
390 "network block to priority list.",
395 } else if (os_strcmp(pos
, "cred={") == 0) {
396 cred
= wpa_config_read_cred(f
, &line
, cred_id
++);
398 wpa_printf(MSG_ERROR
, "Line %d: failed to "
399 "parse cred block.", line
);
403 if (cred_head
== NULL
) {
404 cred_head
= cred_tail
= cred
;
406 cred_tail
->next
= cred
;
409 #ifndef CONFIG_NO_CONFIG_BLOBS
410 } else if (os_strncmp(pos
, "blob-base64-", 12) == 0) {
411 if (wpa_config_process_blob(config
, f
, &line
, pos
+ 12)
413 wpa_printf(MSG_ERROR
, "Line %d: failed to "
414 "process blob.", line
);
418 #endif /* CONFIG_NO_CONFIG_BLOBS */
419 } else if (wpa_config_process_global(config
, pos
, line
) < 0) {
420 wpa_printf(MSG_ERROR
, "Line %d: Invalid configuration "
421 "line '%s'.", line
, pos
);
430 wpa_config_debug_dump_networks(config
);
431 config
->cred
= cred_head
;
433 #ifndef WPA_IGNORE_CONFIG_ERRORS
435 wpa_config_free(config
);
439 #endif /* WPA_IGNORE_CONFIG_ERRORS */
445 #ifndef CONFIG_NO_CONFIG_WRITE
447 static void write_str(FILE *f
, const char *field
, struct wpa_ssid
*ssid
)
449 char *value
= wpa_config_get(ssid
, field
);
452 fprintf(f
, "\t%s=%s\n", field
, value
);
457 static void write_int(FILE *f
, const char *field
, int value
, int def
)
461 fprintf(f
, "\t%s=%d\n", field
, value
);
465 static void write_bssid(FILE *f
, struct wpa_ssid
*ssid
)
467 char *value
= wpa_config_get(ssid
, "bssid");
470 fprintf(f
, "\tbssid=%s\n", value
);
475 static void write_psk(FILE *f
, struct wpa_ssid
*ssid
)
477 char *value
= wpa_config_get(ssid
, "psk");
480 fprintf(f
, "\tpsk=%s\n", value
);
485 static void write_proto(FILE *f
, struct wpa_ssid
*ssid
)
489 if (ssid
->proto
== DEFAULT_PROTO
)
492 value
= wpa_config_get(ssid
, "proto");
496 fprintf(f
, "\tproto=%s\n", value
);
501 static void write_key_mgmt(FILE *f
, struct wpa_ssid
*ssid
)
505 if (ssid
->key_mgmt
== DEFAULT_KEY_MGMT
)
508 value
= wpa_config_get(ssid
, "key_mgmt");
512 fprintf(f
, "\tkey_mgmt=%s\n", value
);
517 static void write_pairwise(FILE *f
, struct wpa_ssid
*ssid
)
521 if (ssid
->pairwise_cipher
== DEFAULT_PAIRWISE
)
524 value
= wpa_config_get(ssid
, "pairwise");
528 fprintf(f
, "\tpairwise=%s\n", value
);
533 static void write_group(FILE *f
, struct wpa_ssid
*ssid
)
537 if (ssid
->group_cipher
== DEFAULT_GROUP
)
540 value
= wpa_config_get(ssid
, "group");
544 fprintf(f
, "\tgroup=%s\n", value
);
549 static void write_auth_alg(FILE *f
, struct wpa_ssid
*ssid
)
553 if (ssid
->auth_alg
== 0)
556 value
= wpa_config_get(ssid
, "auth_alg");
560 fprintf(f
, "\tauth_alg=%s\n", value
);
565 #ifdef IEEE8021X_EAPOL
566 static void write_eap(FILE *f
, struct wpa_ssid
*ssid
)
570 value
= wpa_config_get(ssid
, "eap");
575 fprintf(f
, "\teap=%s\n", value
);
578 #endif /* IEEE8021X_EAPOL */
581 static void write_wep_key(FILE *f
, int idx
, struct wpa_ssid
*ssid
)
583 char field
[20], *value
;
586 res
= os_snprintf(field
, sizeof(field
), "wep_key%d", idx
);
587 if (res
< 0 || (size_t) res
>= sizeof(field
))
589 value
= wpa_config_get(ssid
, field
);
591 fprintf(f
, "\t%s=%s\n", field
, value
);
598 static void write_p2p_client_list(FILE *f
, struct wpa_ssid
*ssid
)
600 char *value
= wpa_config_get(ssid
, "p2p_client_list");
603 fprintf(f
, "\tp2p_client_list=%s\n", value
);
606 #endif /* CONFIG_P2P */
609 static void wpa_config_write_network(FILE *f
, struct wpa_ssid
*ssid
)
613 #define STR(t) write_str(f, #t, ssid)
614 #define INT(t) write_int(f, #t, ssid->t, 0)
615 #define INTe(t) write_int(f, #t, ssid->eap.t, 0)
616 #define INT_DEF(t, def) write_int(f, #t, ssid->t, def)
617 #define INT_DEFe(t, def) write_int(f, #t, ssid->eap.t, def)
621 write_bssid(f
, ssid
);
623 write_proto(f
, ssid
);
624 write_key_mgmt(f
, ssid
);
625 INT_DEF(bg_scan_period
, DEFAULT_BG_SCAN_PERIOD
);
626 write_pairwise(f
, ssid
);
627 write_group(f
, ssid
);
628 write_auth_alg(f
, ssid
);
631 #ifdef IEEE8021X_EAPOL
634 STR(anonymous_identity
);
640 STR(private_key_passwd
);
643 STR(altsubject_match
);
648 STR(private_key2_passwd
);
651 STR(altsubject_match2
);
667 INT_DEF(eapol_flags
, DEFAULT_EAPOL_FLAGS
);
668 #endif /* IEEE8021X_EAPOL */
669 for (i
= 0; i
< 4; i
++)
670 write_wep_key(f
, i
, ssid
);
673 #ifdef IEEE8021X_EAPOL
674 INT_DEF(eap_workaround
, DEFAULT_EAP_WORKAROUND
);
676 INT_DEFe(fragment_size
, DEFAULT_FRAGMENT_SIZE
);
677 #endif /* IEEE8021X_EAPOL */
679 INT(proactive_key_caching
);
682 #ifdef CONFIG_IEEE80211W
684 #endif /* CONFIG_IEEE80211W */
687 write_p2p_client_list(f
, ssid
);
688 #endif /* CONFIG_P2P */
696 static void wpa_config_write_cred(FILE *f
, struct wpa_cred
*cred
)
699 fprintf(f
, "\tpriority=%d\n", cred
->priority
);
701 fprintf(f
, "\tpcsc=%d\n", cred
->pcsc
);
703 fprintf(f
, "\trealm=\"%s\"\n", cred
->realm
);
705 fprintf(f
, "\tusername=\"%s\"\n", cred
->username
);
707 fprintf(f
, "\tpassword=\"%s\"\n", cred
->password
);
709 fprintf(f
, "\tca_cert=\"%s\"\n", cred
->ca_cert
);
711 fprintf(f
, "\timsi=\"%s\"\n", cred
->imsi
);
713 fprintf(f
, "\tmilenage=\"%s\"\n", cred
->milenage
);
715 fprintf(f
, "\tdomain=\"%s\"\n", cred
->domain
);
719 #ifndef CONFIG_NO_CONFIG_BLOBS
720 static int wpa_config_write_blob(FILE *f
, struct wpa_config_blob
*blob
)
722 unsigned char *encoded
;
724 encoded
= base64_encode(blob
->data
, blob
->len
, NULL
);
728 fprintf(f
, "\nblob-base64-%s={\n%s}\n", blob
->name
, encoded
);
732 #endif /* CONFIG_NO_CONFIG_BLOBS */
735 static void write_global_bin(FILE *f
, const char *field
,
736 const struct wpabuf
*val
)
744 fprintf(f
, "%s=", field
);
745 pos
= wpabuf_head(val
);
746 for (i
= 0; i
< wpabuf_len(val
); i
++)
747 fprintf(f
, "%02X", *pos
++);
752 static void wpa_config_write_global(FILE *f
, struct wpa_config
*config
)
754 #ifdef CONFIG_CTRL_IFACE
755 if (config
->ctrl_interface
)
756 fprintf(f
, "ctrl_interface=%s\n", config
->ctrl_interface
);
757 if (config
->ctrl_interface_group
)
758 fprintf(f
, "ctrl_interface_group=%s\n",
759 config
->ctrl_interface_group
);
760 #endif /* CONFIG_CTRL_IFACE */
761 if (config
->eapol_version
!= DEFAULT_EAPOL_VERSION
)
762 fprintf(f
, "eapol_version=%d\n", config
->eapol_version
);
763 if (config
->ap_scan
!= DEFAULT_AP_SCAN
)
764 fprintf(f
, "ap_scan=%d\n", config
->ap_scan
);
765 if (config
->disable_scan_offload
)
766 fprintf(f
, "disable_scan_offload=%d\n",
767 config
->disable_scan_offload
);
768 if (config
->fast_reauth
!= DEFAULT_FAST_REAUTH
)
769 fprintf(f
, "fast_reauth=%d\n", config
->fast_reauth
);
770 if (config
->opensc_engine_path
)
771 fprintf(f
, "opensc_engine_path=%s\n",
772 config
->opensc_engine_path
);
773 if (config
->pkcs11_engine_path
)
774 fprintf(f
, "pkcs11_engine_path=%s\n",
775 config
->pkcs11_engine_path
);
776 if (config
->pkcs11_module_path
)
777 fprintf(f
, "pkcs11_module_path=%s\n",
778 config
->pkcs11_module_path
);
779 if (config
->pcsc_reader
)
780 fprintf(f
, "pcsc_reader=%s\n", config
->pcsc_reader
);
781 if (config
->pcsc_pin
)
782 fprintf(f
, "pcsc_pin=%s\n", config
->pcsc_pin
);
783 if (config
->driver_param
)
784 fprintf(f
, "driver_param=%s\n", config
->driver_param
);
785 if (config
->dot11RSNAConfigPMKLifetime
)
786 fprintf(f
, "dot11RSNAConfigPMKLifetime=%d\n",
787 config
->dot11RSNAConfigPMKLifetime
);
788 if (config
->dot11RSNAConfigPMKReauthThreshold
)
789 fprintf(f
, "dot11RSNAConfigPMKReauthThreshold=%d\n",
790 config
->dot11RSNAConfigPMKReauthThreshold
);
791 if (config
->dot11RSNAConfigSATimeout
)
792 fprintf(f
, "dot11RSNAConfigSATimeout=%d\n",
793 config
->dot11RSNAConfigSATimeout
);
794 if (config
->update_config
)
795 fprintf(f
, "update_config=%d\n", config
->update_config
);
797 if (!is_nil_uuid(config
->uuid
)) {
799 uuid_bin2str(config
->uuid
, buf
, sizeof(buf
));
800 fprintf(f
, "uuid=%s\n", buf
);
802 if (config
->device_name
)
803 fprintf(f
, "device_name=%s\n", config
->device_name
);
804 if (config
->manufacturer
)
805 fprintf(f
, "manufacturer=%s\n", config
->manufacturer
);
806 if (config
->model_name
)
807 fprintf(f
, "model_name=%s\n", config
->model_name
);
808 if (config
->model_number
)
809 fprintf(f
, "model_number=%s\n", config
->model_number
);
810 if (config
->serial_number
)
811 fprintf(f
, "serial_number=%s\n", config
->serial_number
);
813 char _buf
[WPS_DEV_TYPE_BUFSIZE
], *buf
;
814 buf
= wps_dev_type_bin2str(config
->device_type
,
816 if (os_strcmp(buf
, "0-00000000-0") != 0)
817 fprintf(f
, "device_type=%s\n", buf
);
819 if (WPA_GET_BE32(config
->os_version
))
820 fprintf(f
, "os_version=%08x\n",
821 WPA_GET_BE32(config
->os_version
));
822 if (config
->config_methods
)
823 fprintf(f
, "config_methods=%s\n", config
->config_methods
);
824 if (config
->wps_cred_processing
)
825 fprintf(f
, "wps_cred_processing=%d\n",
826 config
->wps_cred_processing
);
827 if (config
->wps_vendor_ext_m1
) {
828 int i
, len
= wpabuf_len(config
->wps_vendor_ext_m1
);
829 const u8
*p
= wpabuf_head_u8(config
->wps_vendor_ext_m1
);
831 fprintf(f
, "wps_vendor_ext_m1=");
832 for (i
= 0; i
< len
; i
++)
833 fprintf(f
, "%02x", *p
++);
837 #endif /* CONFIG_WPS */
839 if (config
->p2p_listen_reg_class
)
840 fprintf(f
, "p2p_listen_reg_class=%u\n",
841 config
->p2p_listen_reg_class
);
842 if (config
->p2p_listen_channel
)
843 fprintf(f
, "p2p_listen_channel=%u\n",
844 config
->p2p_listen_channel
);
845 if (config
->p2p_oper_reg_class
)
846 fprintf(f
, "p2p_oper_reg_class=%u\n",
847 config
->p2p_oper_reg_class
);
848 if (config
->p2p_oper_channel
)
849 fprintf(f
, "p2p_oper_channel=%u\n", config
->p2p_oper_channel
);
850 if (config
->p2p_go_intent
!= DEFAULT_P2P_GO_INTENT
)
851 fprintf(f
, "p2p_go_intent=%u\n", config
->p2p_go_intent
);
852 if (config
->p2p_ssid_postfix
)
853 fprintf(f
, "p2p_ssid_postfix=%s\n", config
->p2p_ssid_postfix
);
854 if (config
->persistent_reconnect
)
855 fprintf(f
, "persistent_reconnect=%u\n",
856 config
->persistent_reconnect
);
857 if (config
->p2p_intra_bss
!= DEFAULT_P2P_INTRA_BSS
)
858 fprintf(f
, "p2p_intra_bss=%u\n", config
->p2p_intra_bss
);
859 if (config
->p2p_group_idle
)
860 fprintf(f
, "p2p_group_idle=%u\n", config
->p2p_group_idle
);
861 if (config
->p2p_pref_chan
) {
863 fprintf(f
, "p2p_pref_chan=");
864 for (i
= 0; i
< config
->num_p2p_pref_chan
; i
++) {
865 fprintf(f
, "%s%u:%u", i
> 0 ? "," : "",
866 config
->p2p_pref_chan
[i
].op_class
,
867 config
->p2p_pref_chan
[i
].chan
);
871 if (config
->p2p_go_ht40
)
872 fprintf(f
, "p2p_go_ht40=%u\n", config
->p2p_go_ht40
);
873 #endif /* CONFIG_P2P */
874 if (config
->country
[0] && config
->country
[1]) {
875 fprintf(f
, "country=%c%c\n",
876 config
->country
[0], config
->country
[1]);
878 if (config
->bss_max_count
!= DEFAULT_BSS_MAX_COUNT
)
879 fprintf(f
, "bss_max_count=%u\n", config
->bss_max_count
);
880 if (config
->bss_expiration_age
!= DEFAULT_BSS_EXPIRATION_AGE
)
881 fprintf(f
, "bss_expiration_age=%u\n",
882 config
->bss_expiration_age
);
883 if (config
->bss_expiration_scan_count
!=
884 DEFAULT_BSS_EXPIRATION_SCAN_COUNT
)
885 fprintf(f
, "bss_expiration_scan_count=%u\n",
886 config
->bss_expiration_scan_count
);
887 if (config
->filter_ssids
)
888 fprintf(f
, "filter_ssids=%d\n", config
->filter_ssids
);
889 if (config
->max_num_sta
!= DEFAULT_MAX_NUM_STA
)
890 fprintf(f
, "max_num_sta=%u\n", config
->max_num_sta
);
891 if (config
->disassoc_low_ack
)
892 fprintf(f
, "disassoc_low_ack=%u\n", config
->disassoc_low_ack
);
895 fprintf(f
, "hs20=1\n");
896 #endif /* CONFIG_HS20 */
897 #ifdef CONFIG_INTERWORKING
898 if (config
->interworking
)
899 fprintf(f
, "interworking=%u\n", config
->interworking
);
900 if (!is_zero_ether_addr(config
->hessid
))
901 fprintf(f
, "hessid=" MACSTR
"\n", MAC2STR(config
->hessid
));
902 if (config
->access_network_type
!= DEFAULT_ACCESS_NETWORK_TYPE
)
903 fprintf(f
, "access_network_type=%d\n",
904 config
->access_network_type
);
905 #endif /* CONFIG_INTERWORKING */
906 if (config
->pbc_in_m1
)
907 fprintf(f
, "pbc_in_m1=%u\n", config
->pbc_in_m1
);
908 if (config
->wps_nfc_dev_pw_id
)
909 fprintf(f
, "wps_nfc_dev_pw_id=%d\n",
910 config
->wps_nfc_dev_pw_id
);
911 write_global_bin(f
, "wps_nfc_dh_pubkey", config
->wps_nfc_dh_pubkey
);
912 write_global_bin(f
, "wps_nfc_dh_privkey", config
->wps_nfc_dh_privkey
);
913 write_global_bin(f
, "wps_nfc_dev_pw", config
->wps_nfc_dev_pw
);
915 if (config
->ext_password_backend
)
916 fprintf(f
, "ext_password_backend=%s\n",
917 config
->ext_password_backend
);
918 if (config
->p2p_go_max_inactivity
!= DEFAULT_P2P_GO_MAX_INACTIVITY
)
919 fprintf(f
, "p2p_go_max_inactivity=%d\n",
920 config
->p2p_go_max_inactivity
);
921 if (config
->auto_interworking
)
922 fprintf(f
, "auto_interworking=%d\n",
923 config
->auto_interworking
);
926 #endif /* CONFIG_NO_CONFIG_WRITE */
929 int wpa_config_write(const char *name
, struct wpa_config
*config
)
931 #ifndef CONFIG_NO_CONFIG_WRITE
933 struct wpa_ssid
*ssid
;
934 struct wpa_cred
*cred
;
935 #ifndef CONFIG_NO_CONFIG_BLOBS
936 struct wpa_config_blob
*blob
;
937 #endif /* CONFIG_NO_CONFIG_BLOBS */
940 wpa_printf(MSG_DEBUG
, "Writing configuration file '%s'", name
);
942 f
= fopen(name
, "w");
944 wpa_printf(MSG_DEBUG
, "Failed to open '%s' for writing", name
);
948 wpa_config_write_global(f
, config
);
950 for (cred
= config
->cred
; cred
; cred
= cred
->next
) {
951 fprintf(f
, "\ncred={\n");
952 wpa_config_write_cred(f
, cred
);
956 for (ssid
= config
->ssid
; ssid
; ssid
= ssid
->next
) {
957 if (ssid
->key_mgmt
== WPA_KEY_MGMT_WPS
|| ssid
->temporary
)
958 continue; /* do not save temporary networks */
959 if (wpa_key_mgmt_wpa_psk(ssid
->key_mgmt
) && !ssid
->psk_set
&&
961 continue; /* do not save invalid network */
962 fprintf(f
, "\nnetwork={\n");
963 wpa_config_write_network(f
, ssid
);
967 #ifndef CONFIG_NO_CONFIG_BLOBS
968 for (blob
= config
->blobs
; blob
; blob
= blob
->next
) {
969 ret
= wpa_config_write_blob(f
, blob
);
973 #endif /* CONFIG_NO_CONFIG_BLOBS */
977 wpa_printf(MSG_DEBUG
, "Configuration file '%s' written %ssuccessfully",
978 name
, ret
? "un" : "");
980 #else /* CONFIG_NO_CONFIG_WRITE */
982 #endif /* CONFIG_NO_CONFIG_WRITE */