/*
* WPA Supplicant / Configuration backend: text file
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*
* This file implements a configuration backend for text files. All the
* configuration information is stored in a text file that uses a format
#include "common.h"
#include "config.h"
#include "base64.h"
-#include "eap_peer/eap_methods.h"
+#include "uuid.h"
/**
wpa_config_update_psk(ssid);
}
- if ((ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK)) &&
- !ssid->psk_set) {
+ if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set) {
wpa_printf(MSG_ERROR, "Line %d: WPA-PSK accepted for key "
"management, but no PSK configured.", line);
errors++;
}
+static struct wpa_cred * wpa_config_read_cred(FILE *f, int *line, int id)
+{
+ struct wpa_cred *cred;
+ int errors = 0, end = 0;
+ char buf[256], *pos, *pos2;
+
+ wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new cred block", *line);
+ cred = os_zalloc(sizeof(*cred));
+ if (cred == NULL)
+ return NULL;
+ cred->id = id;
+
+ while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
+ if (os_strcmp(pos, "}") == 0) {
+ end = 1;
+ break;
+ }
+
+ pos2 = os_strchr(pos, '=');
+ if (pos2 == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid cred line "
+ "'%s'.", *line, pos);
+ errors++;
+ continue;
+ }
+
+ *pos2++ = '\0';
+ if (*pos2 == '"') {
+ if (os_strchr(pos2 + 1, '"') == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "quotation '%s'.", *line, pos2);
+ errors++;
+ continue;
+ }
+ }
+
+ if (wpa_config_set_cred(cred, pos, pos2, *line) < 0)
+ errors++;
+ }
+
+ if (!end) {
+ wpa_printf(MSG_ERROR, "Line %d: cred block was not "
+ "terminated properly.", *line);
+ errors++;
+ }
+
+ if (errors) {
+ wpa_config_free_cred(cred);
+ cred = NULL;
+ }
+
+ return cred;
+}
+
+
#ifndef CONFIG_NO_CONFIG_BLOBS
static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line,
const char *name)
#endif /* CONFIG_NO_CONFIG_BLOBS */
-#ifdef CONFIG_CTRL_IFACE
-static int wpa_config_process_ctrl_interface(struct wpa_config *config,
- char *pos)
-{
- os_free(config->ctrl_interface);
- config->ctrl_interface = os_strdup(pos);
- wpa_printf(MSG_DEBUG, "ctrl_interface='%s'", config->ctrl_interface);
- return 0;
-}
-
-
-static int wpa_config_process_ctrl_interface_group(struct wpa_config *config,
- char *pos)
-{
- os_free(config->ctrl_interface_group);
- config->ctrl_interface_group = os_strdup(pos);
- wpa_printf(MSG_DEBUG, "ctrl_interface_group='%s' (DEPRECATED)",
- config->ctrl_interface_group);
- return 0;
-}
-#endif /* CONFIG_CTRL_IFACE */
-
-
-static int wpa_config_process_eapol_version(struct wpa_config *config,
- int line, char *pos)
-{
- config->eapol_version = atoi(pos);
- if (config->eapol_version < 1 || config->eapol_version > 2) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid EAPOL version (%d): "
- "'%s'.", line, config->eapol_version, pos);
- return -1;
- }
- wpa_printf(MSG_DEBUG, "eapol_version=%d", config->eapol_version);
- return 0;
-}
-
-
-static int wpa_config_process_ap_scan(struct wpa_config *config, char *pos)
-{
- config->ap_scan = atoi(pos);
- wpa_printf(MSG_DEBUG, "ap_scan=%d", config->ap_scan);
- return 0;
-}
-
-
-static int wpa_config_process_fast_reauth(struct wpa_config *config, char *pos)
-{
- config->fast_reauth = atoi(pos);
- wpa_printf(MSG_DEBUG, "fast_reauth=%d", config->fast_reauth);
- return 0;
-}
-
-
-#ifdef EAP_TLS_OPENSSL
-
-static int wpa_config_process_opensc_engine_path(struct wpa_config *config,
- char *pos)
-{
- os_free(config->opensc_engine_path);
- config->opensc_engine_path = os_strdup(pos);
- wpa_printf(MSG_DEBUG, "opensc_engine_path='%s'",
- config->opensc_engine_path);
- return 0;
-}
-
-
-static int wpa_config_process_pkcs11_engine_path(struct wpa_config *config,
- char *pos)
-{
- os_free(config->pkcs11_engine_path);
- config->pkcs11_engine_path = os_strdup(pos);
- wpa_printf(MSG_DEBUG, "pkcs11_engine_path='%s'",
- config->pkcs11_engine_path);
- return 0;
-}
-
-
-static int wpa_config_process_pkcs11_module_path(struct wpa_config *config,
- char *pos)
-{
- os_free(config->pkcs11_module_path);
- config->pkcs11_module_path = os_strdup(pos);
- wpa_printf(MSG_DEBUG, "pkcs11_module_path='%s'",
- config->pkcs11_module_path);
- return 0;
-}
-
-#endif /* EAP_TLS_OPENSSL */
-
-
-static int wpa_config_process_driver_param(struct wpa_config *config,
- char *pos)
-{
- os_free(config->driver_param);
- config->driver_param = os_strdup(pos);
- wpa_printf(MSG_DEBUG, "driver_param='%s'", config->driver_param);
- return 0;
-}
-
-
-static int wpa_config_process_pmk_lifetime(struct wpa_config *config,
- char *pos)
-{
- config->dot11RSNAConfigPMKLifetime = atoi(pos);
- wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKLifetime=%d",
- config->dot11RSNAConfigPMKLifetime);
- return 0;
-}
-
-
-static int wpa_config_process_pmk_reauth_threshold(struct wpa_config *config,
- char *pos)
-{
- config->dot11RSNAConfigPMKReauthThreshold = atoi(pos);
- wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKReauthThreshold=%d",
- config->dot11RSNAConfigPMKReauthThreshold);
- return 0;
-}
-
-
-static int wpa_config_process_sa_timeout(struct wpa_config *config, char *pos)
-{
- config->dot11RSNAConfigSATimeout = atoi(pos);
- wpa_printf(MSG_DEBUG, "dot11RSNAConfigSATimeout=%d",
- config->dot11RSNAConfigSATimeout);
- return 0;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_WRITE
-static int wpa_config_process_update_config(struct wpa_config *config,
- char *pos)
-{
- config->update_config = atoi(pos);
- wpa_printf(MSG_DEBUG, "update_config=%d", config->update_config);
- return 0;
-}
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
-
-static int wpa_config_process_load_dynamic_eap(int line, char *so)
-{
- int ret;
- wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so);
- ret = eap_peer_method_load(so);
- if (ret == -2) {
- wpa_printf(MSG_DEBUG, "This EAP type was already loaded - not "
- "reloading.");
- } else if (ret) {
- wpa_printf(MSG_ERROR, "Line %d: Failed to load dynamic EAP "
- "method '%s'.", line, so);
- return -1;
- }
-
- return 0;
-}
-
-
-static int wpa_config_process_global(struct wpa_config *config, char *pos,
- int line)
-{
-#ifdef CONFIG_CTRL_IFACE
- if (os_strncmp(pos, "ctrl_interface=", 15) == 0)
- return wpa_config_process_ctrl_interface(config, pos + 15);
-
- if (os_strncmp(pos, "ctrl_interface_group=", 21) == 0)
- return wpa_config_process_ctrl_interface_group(config,
- pos + 21);
-#endif /* CONFIG_CTRL_IFACE */
-
- if (os_strncmp(pos, "eapol_version=", 14) == 0)
- return wpa_config_process_eapol_version(config, line,
- pos + 14);
-
- if (os_strncmp(pos, "ap_scan=", 8) == 0)
- return wpa_config_process_ap_scan(config, pos + 8);
-
- if (os_strncmp(pos, "fast_reauth=", 12) == 0)
- return wpa_config_process_fast_reauth(config, pos + 12);
-
-#ifdef EAP_TLS_OPENSSL
- if (os_strncmp(pos, "opensc_engine_path=", 19) == 0)
- return wpa_config_process_opensc_engine_path(config, pos + 19);
-
- if (os_strncmp(pos, "pkcs11_engine_path=", 19) == 0)
- return wpa_config_process_pkcs11_engine_path(config, pos + 19);
-
- if (os_strncmp(pos, "pkcs11_module_path=", 19) == 0)
- return wpa_config_process_pkcs11_module_path(config, pos + 19);
-#endif /* EAP_TLS_OPENSSL */
-
- if (os_strncmp(pos, "driver_param=", 13) == 0)
- return wpa_config_process_driver_param(config, pos + 13);
-
- if (os_strncmp(pos, "dot11RSNAConfigPMKLifetime=", 27) == 0)
- return wpa_config_process_pmk_lifetime(config, pos + 27);
-
- if (os_strncmp(pos, "dot11RSNAConfigPMKReauthThreshold=", 34) == 0)
- return wpa_config_process_pmk_reauth_threshold(config,
- pos + 34);
-
- if (os_strncmp(pos, "dot11RSNAConfigSATimeout=", 25) == 0)
- return wpa_config_process_sa_timeout(config, pos + 25);
-
-#ifndef CONFIG_NO_CONFIG_WRITE
- if (os_strncmp(pos, "update_config=", 14) == 0)
- return wpa_config_process_update_config(config, pos + 14);
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
- if (os_strncmp(pos, "load_dynamic_eap=", 17) == 0)
- return wpa_config_process_load_dynamic_eap(line, pos + 17);
-
- return -1;
-}
-
-
struct wpa_config * wpa_config_read(const char *name)
{
FILE *f;
char buf[256], *pos;
int errors = 0, line = 0;
struct wpa_ssid *ssid, *tail = NULL, *head = NULL;
+ struct wpa_cred *cred, *cred_tail = NULL, *cred_head = NULL;
struct wpa_config *config;
int id = 0;
+ int cred_id = 0;
config = wpa_config_alloc_empty(NULL, NULL);
if (config == NULL)
errors++;
continue;
}
+ } else if (os_strcmp(pos, "cred={") == 0) {
+ cred = wpa_config_read_cred(f, &line, cred_id++);
+ if (cred == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: failed to "
+ "parse cred block.", line);
+ errors++;
+ continue;
+ }
+ if (cred_head == NULL) {
+ cred_head = cred_tail = cred;
+ } else {
+ cred_tail->next = cred;
+ cred_tail = cred;
+ }
#ifndef CONFIG_NO_CONFIG_BLOBS
} else if (os_strncmp(pos, "blob-base64-", 12) == 0) {
if (wpa_config_process_blob(config, f, &line, pos + 12)
config->ssid = head;
wpa_config_debug_dump_networks(config);
+ config->cred = cred_head;
+#ifndef WPA_IGNORE_CONFIG_ERRORS
if (errors) {
wpa_config_free(config);
config = NULL;
head = NULL;
}
+#endif /* WPA_IGNORE_CONFIG_ERRORS */
return config;
}
}
+#ifdef CONFIG_P2P
+static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid)
+{
+ char *value = wpa_config_get(ssid, "p2p_client_list");
+ if (value == NULL)
+ return;
+ fprintf(f, "\tp2p_client_list=%s\n", value);
+ os_free(value);
+}
+#endif /* CONFIG_P2P */
+
+
static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
{
int i;
STR(pin);
STR(engine_id);
STR(key_id);
+ STR(cert_id);
+ STR(ca_cert_id);
+ STR(key2_id);
+ STR(pin2);
+ STR(engine2_id);
+ STR(cert2_id);
+ STR(ca_cert2_id);
INTe(engine);
+ INTe(engine2);
INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
#endif /* IEEE8021X_EAPOL */
for (i = 0; i < 4; i++)
INT(ieee80211w);
#endif /* CONFIG_IEEE80211W */
STR(id_str);
+#ifdef CONFIG_P2P
+ write_p2p_client_list(f, ssid);
+#endif /* CONFIG_P2P */
#undef STR
#undef INT
fprintf(f, "ap_scan=%d\n", config->ap_scan);
if (config->fast_reauth != DEFAULT_FAST_REAUTH)
fprintf(f, "fast_reauth=%d\n", config->fast_reauth);
-#ifdef EAP_TLS_OPENSSL
if (config->opensc_engine_path)
fprintf(f, "opensc_engine_path=%s\n",
config->opensc_engine_path);
if (config->pkcs11_module_path)
fprintf(f, "pkcs11_module_path=%s\n",
config->pkcs11_module_path);
-#endif /* EAP_TLS_OPENSSL */
if (config->driver_param)
fprintf(f, "driver_param=%s\n", config->driver_param);
if (config->dot11RSNAConfigPMKLifetime)
config->dot11RSNAConfigSATimeout);
if (config->update_config)
fprintf(f, "update_config=%d\n", config->update_config);
+#ifdef CONFIG_WPS
+ if (!is_nil_uuid(config->uuid)) {
+ char buf[40];
+ uuid_bin2str(config->uuid, buf, sizeof(buf));
+ fprintf(f, "uuid=%s\n", buf);
+ }
+ if (config->device_name)
+ fprintf(f, "device_name=%s\n", config->device_name);
+ if (config->manufacturer)
+ fprintf(f, "manufacturer=%s\n", config->manufacturer);
+ if (config->model_name)
+ fprintf(f, "model_name=%s\n", config->model_name);
+ if (config->model_number)
+ fprintf(f, "model_number=%s\n", config->model_number);
+ if (config->serial_number)
+ fprintf(f, "serial_number=%s\n", config->serial_number);
+ {
+ char _buf[WPS_DEV_TYPE_BUFSIZE], *buf;
+ buf = wps_dev_type_bin2str(config->device_type,
+ _buf, sizeof(_buf));
+ if (os_strcmp(buf, "0-00000000-0") != 0)
+ fprintf(f, "device_type=%s\n", buf);
+ }
+ if (WPA_GET_BE32(config->os_version))
+ fprintf(f, "os_version=%08x\n",
+ WPA_GET_BE32(config->os_version));
+ if (config->config_methods)
+ fprintf(f, "config_methods=%s\n", config->config_methods);
+ if (config->wps_cred_processing)
+ fprintf(f, "wps_cred_processing=%d\n",
+ config->wps_cred_processing);
+#endif /* CONFIG_WPS */
+#ifdef CONFIG_P2P
+ if (config->p2p_listen_reg_class)
+ fprintf(f, "p2p_listen_reg_class=%u\n",
+ config->p2p_listen_reg_class);
+ if (config->p2p_listen_channel)
+ fprintf(f, "p2p_listen_channel=%u\n",
+ config->p2p_listen_channel);
+ if (config->p2p_oper_reg_class)
+ fprintf(f, "p2p_oper_reg_class=%u\n",
+ config->p2p_oper_reg_class);
+ if (config->p2p_oper_channel)
+ fprintf(f, "p2p_oper_channel=%u\n", config->p2p_oper_channel);
+ if (config->p2p_go_intent != DEFAULT_P2P_GO_INTENT)
+ fprintf(f, "p2p_go_intent=%u\n", config->p2p_go_intent);
+ if (config->p2p_ssid_postfix)
+ fprintf(f, "p2p_ssid_postfix=%s\n", config->p2p_ssid_postfix);
+ if (config->persistent_reconnect)
+ fprintf(f, "persistent_reconnect=%u\n",
+ config->persistent_reconnect);
+ if (config->p2p_intra_bss != DEFAULT_P2P_INTRA_BSS)
+ fprintf(f, "p2p_intra_bss=%u\n", config->p2p_intra_bss);
+ if (config->p2p_group_idle)
+ fprintf(f, "p2p_group_idle=%u\n", config->p2p_group_idle);
+#endif /* CONFIG_P2P */
+ if (config->country[0] && config->country[1]) {
+ fprintf(f, "country=%c%c\n",
+ config->country[0], config->country[1]);
+ }
+ if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT)
+ fprintf(f, "bss_max_count=%u\n", config->bss_max_count);
+ if (config->bss_expiration_age != DEFAULT_BSS_EXPIRATION_AGE)
+ fprintf(f, "bss_expiration_age=%u\n",
+ config->bss_expiration_age);
+ if (config->bss_expiration_scan_count !=
+ DEFAULT_BSS_EXPIRATION_SCAN_COUNT)
+ fprintf(f, "bss_expiration_scan_count=%u\n",
+ config->bss_expiration_scan_count);
+ if (config->filter_ssids)
+ fprintf(f, "filter_ssids=%d\n", config->filter_ssids);
+ if (config->max_num_sta != DEFAULT_MAX_NUM_STA)
+ fprintf(f, "max_num_sta=%u\n", config->max_num_sta);
+ if (config->disassoc_low_ack)
+ fprintf(f, "disassoc_low_ack=%u\n", config->disassoc_low_ack);
+#ifdef CONFIG_INTERWORKING
+ if (config->interworking)
+ fprintf(f, "interworking=%u\n", config->interworking);
+ if (!is_zero_ether_addr(config->hessid))
+ fprintf(f, "hessid=" MACSTR "\n", MAC2STR(config->hessid));
+ if (config->access_network_type != DEFAULT_ACCESS_NETWORK_TYPE)
+ fprintf(f, "access_network_type=%d\n",
+ config->access_network_type);
+#endif /* CONFIG_INTERWORKING */
}
#endif /* CONFIG_NO_CONFIG_WRITE */
wpa_config_write_global(f, config);
for (ssid = config->ssid; ssid; ssid = ssid->next) {
+ if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary)
+ continue; /* do not save temporary networks */
+ if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
+ !ssid->passphrase)
+ continue; /* do not save invalid network */
fprintf(f, "\nnetwork={\n");
wpa_config_write_network(f, ssid);
fprintf(f, "}\n");