aboutsummaryrefslogtreecommitdiff
path: root/wpa_supplicant/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant/config.c')
-rw-r--r--wpa_supplicant/config.c294
1 files changed, 244 insertions, 50 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index c8844bbb..a5d4d815 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -804,8 +804,12 @@ static int wpa_config_parse_key_mgmt(const struct parse_data *data,
#ifdef CONFIG_SAE
else if (os_strcmp(start, "SAE") == 0)
val |= WPA_KEY_MGMT_SAE;
+ else if (os_strcmp(start, "SAE-EXT-KEY") == 0)
+ val |= WPA_KEY_MGMT_SAE_EXT_KEY;
else if (os_strcmp(start, "FT-SAE") == 0)
val |= WPA_KEY_MGMT_FT_SAE;
+ else if (os_strcmp(start, "FT-SAE-EXT-KEY") == 0)
+ val |= WPA_KEY_MGMT_FT_SAE_EXT_KEY;
#endif /* CONFIG_SAE */
#ifdef CONFIG_HS20
else if (os_strcmp(start, "OSEN") == 0)
@@ -1004,6 +1008,16 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data,
pos += ret;
}
+ if (ssid->key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) {
+ ret = os_snprintf(pos, end - pos, "%sSAE-EXT-KEY",
+ pos == buf ? "" : " ");
+ if (os_snprintf_error(end - pos, ret)) {
+ end[-1] = '\0';
+ return buf;
+ }
+ pos += ret;
+ }
+
if (ssid->key_mgmt & WPA_KEY_MGMT_FT_SAE) {
ret = os_snprintf(pos, end - pos, "%sFT-SAE",
pos == buf ? "" : " ");
@@ -1013,6 +1027,16 @@ static char * wpa_config_write_key_mgmt(const struct parse_data *data,
}
pos += ret;
}
+
+ if (ssid->key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
+ ret = os_snprintf(pos, end - pos, "%sFT-SAE-EXT-KEY",
+ pos == buf ? "" : " ");
+ if (os_snprintf_error(end - pos, ret)) {
+ end[-1] = '\0';
+ return buf;
+ }
+ pos += ret;
+ }
#endif /* CONFIG_SAE */
#ifdef CONFIG_HS20
@@ -2321,6 +2345,50 @@ static char * wpa_config_write_peerkey(const struct parse_data *data,
#endif /* NO_CONFIG_WRITE */
+static int wpa_config_parse_mac_value(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ u8 mac_value[ETH_ALEN];
+
+ if (hwaddr_aton(value, mac_value) == 0) {
+ if (os_memcmp(mac_value, ssid->mac_value, ETH_ALEN) == 0)
+ return 1;
+ os_memcpy(ssid->mac_value, mac_value, ETH_ALEN);
+ return 0;
+ }
+
+ wpa_printf(MSG_ERROR, "Line %d: Invalid MAC address '%s'",
+ line, value);
+ return -1;
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_mac_value(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ const size_t size = 3 * ETH_ALEN;
+ char *value;
+ int res;
+
+ if (ssid->mac_addr != WPAS_MAC_ADDR_STYLE_DEDICATED_PER_ESS)
+ return NULL;
+
+ value = os_malloc(size);
+ if (!value)
+ return NULL;
+ res = os_snprintf(value, size, MACSTR, MAC2STR(ssid->mac_value));
+ if (os_snprintf_error(size, res)) {
+ os_free(value);
+ return NULL;
+ }
+ value[size - 1] = '\0';
+ return value;
+}
+#endif /* NO_CONFIG_WRITE */
+
+
/* Helper macros for network block parser */
#ifdef OFFSET
@@ -2434,8 +2502,8 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(ht, 0, 1) },
{ INT_RANGE(vht, 0, 1) },
{ INT_RANGE(ht40, -1, 1) },
- { INT_RANGE(max_oper_chwidth, CHANWIDTH_USE_HT,
- CHANWIDTH_80P80MHZ) },
+ { INT_RANGE(max_oper_chwidth, CONF_OPER_CHWIDTH_USE_HT,
+ CONF_OPER_CHWIDTH_80P80MHZ) },
{ INT(vht_center_freq1) },
{ INT(vht_center_freq2) },
#ifdef IEEE8021X_EAPOL
@@ -2503,7 +2571,9 @@ static const struct parse_data ssid_fields[] = {
{ INTe(machine_ocsp, machine_cert.ocsp) },
{ INT(eapol_flags) },
{ INTe(sim_num, sim_num) },
- { STRe(imsi_privacy_key, imsi_privacy_key) },
+ { STRe(imsi_privacy_cert, imsi_privacy_cert) },
+ { STRe(imsi_privacy_attr, imsi_privacy_attr) },
+ { INTe(strict_conservative_peer_mode, strict_conservative_peer_mode) },
{ STRe(openssl_ciphers, openssl_ciphers) },
{ INTe(erp, erp) },
#endif /* IEEE8021X_EAPOL */
@@ -2608,6 +2678,7 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(macsec_integ_only, 0, 1) },
{ INT_RANGE(macsec_replay_protect, 0, 1) },
{ INT(macsec_replay_window) },
+ { INT_RANGE(macsec_offload, 0, 2) },
{ INT_RANGE(macsec_port, 1, 65534) },
{ INT_RANGE(mka_priority, 0, 255) },
{ INT_RANGE(macsec_csindex, 0, 1) },
@@ -2618,7 +2689,8 @@ static const struct parse_data ssid_fields[] = {
{ INT(update_identifier) },
{ STR_RANGE(roaming_consortium_selection, 0, MAX_ROAMING_CONS_OI_LEN) },
#endif /* CONFIG_HS20 */
- { INT_RANGE(mac_addr, 0, 2) },
+ { INT_RANGE(mac_addr, 0, 3) },
+ { FUNC_KEY(mac_value) },
{ INT_RANGE(pbss, 0, 2) },
{ INT_RANGE(wps_disabled, 0, 1) },
{ INT_RANGE(fils_dh_group, 0, 65535) },
@@ -2629,6 +2701,7 @@ static const struct parse_data ssid_fields[] = {
{ STR_LEN(dpp_csign) },
{ STR_LEN(dpp_pp_key) },
{ INT_RANGE(dpp_pfs, 0, 2) },
+ { INT_RANGE(dpp_connector_privacy, 0, 1) },
#endif /* CONFIG_DPP */
{ INT_RANGE(owe_group, 0, 65535) },
{ INT_RANGE(owe_only, 0, 1) },
@@ -2638,6 +2711,8 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(beacon_prot, 0, 1) },
{ INT_RANGE(transition_disable, 0, 255) },
{ INT_RANGE(sae_pk, 0, 2) },
+ { INT_RANGE(disable_eht, 0, 1)},
+ { INT_RANGE(enable_4addr_mode, 0, 1)},
};
#undef OFFSET
@@ -2771,7 +2846,8 @@ static void eap_peer_config_free(struct eap_peer_config *eap)
bin_clear_free(eap->identity, eap->identity_len);
os_free(eap->anonymous_identity);
os_free(eap->imsi_identity);
- os_free(eap->imsi_privacy_key);
+ os_free(eap->imsi_privacy_cert);
+ os_free(eap->imsi_privacy_attr);
os_free(eap->machine_identity);
bin_clear_free(eap->password, eap->password_len);
bin_clear_free(eap->machine_password, eap->machine_password_len);
@@ -2875,7 +2951,8 @@ void wpa_config_free_cred(struct wpa_cred *cred)
os_free(cred->req_conn_capab_port[i]);
os_free(cred->req_conn_capab_port);
os_free(cred->req_conn_capab_proto);
- os_free(cred->imsi_privacy_key);
+ os_free(cred->imsi_privacy_cert);
+ os_free(cred->imsi_privacy_attr);
os_free(cred);
}
@@ -2967,6 +3044,8 @@ void wpa_config_free(struct wpa_config *config)
#endif /* CONFIG_MBO */
os_free(config->dpp_name);
os_free(config->dpp_mud_url);
+ os_free(config->dpp_extra_conf_req_name);
+ os_free(config->dpp_extra_conf_req_value);
os_free(config);
}
@@ -3150,7 +3229,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
#ifdef CONFIG_MACSEC
ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
#endif /* CONFIG_MACSEC */
- ssid->mac_addr = -1;
+ ssid->mac_addr = WPAS_MAC_ADDR_STYLE_NOT_SET;
ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH;
}
@@ -3501,53 +3580,62 @@ static int wpa_config_set_cred_req_conn_capab(struct wpa_cred *cred,
}
-static int wpa_config_set_cred_roaming_consortiums(struct wpa_cred *cred,
- const char *value)
-{
- u8 roaming_consortiums[MAX_ROAMING_CONS][MAX_ROAMING_CONS_OI_LEN];
- size_t roaming_consortiums_len[MAX_ROAMING_CONS];
- unsigned int num_roaming_consortiums = 0;
+static int
+wpa_config_set_cred_ois(u8 cred_ois[MAX_ROAMING_CONS][MAX_ROAMING_CONS_OI_LEN],
+ size_t cred_ois_len[MAX_ROAMING_CONS],
+ unsigned int *cred_num_ois,
+ const char *value)
+{
+ u8 ois[MAX_ROAMING_CONS][MAX_ROAMING_CONS_OI_LEN];
+ size_t ois_len[MAX_ROAMING_CONS];
+ unsigned int num_ois = 0;
const char *pos, *end;
size_t len;
- os_memset(roaming_consortiums, 0, sizeof(roaming_consortiums));
- os_memset(roaming_consortiums_len, 0, sizeof(roaming_consortiums_len));
+ len = os_strlen(value);
+ if (len / 2 < 3) {
+ wpa_printf(MSG_ERROR,
+ "Invalid organisation identifier (OI) list: %s",
+ value);
+ return -1;
+ }
+
+ os_memset(ois, 0, sizeof(ois));
+ os_memset(ois_len, 0, sizeof(ois_len));
for (pos = value;;) {
end = os_strchr(pos, ',');
len = end ? (size_t) (end - pos) : os_strlen(pos);
if (!end && len == 0)
break;
- if (len == 0 || (len & 1) != 0 ||
+ if (len / 2 < 3 || (len & 1) != 0 ||
len / 2 > MAX_ROAMING_CONS_OI_LEN ||
hexstr2bin(pos,
- roaming_consortiums[num_roaming_consortiums],
+ ois[num_ois],
len / 2) < 0) {
wpa_printf(MSG_INFO,
- "Invalid roaming_consortiums entry: %s",
+ "Invalid organisation identifier (OI) entry: %s",
pos);
return -1;
}
- roaming_consortiums_len[num_roaming_consortiums] = len / 2;
- num_roaming_consortiums++;
+ ois_len[num_ois] = len / 2;
+ num_ois++;
if (!end)
break;
- if (num_roaming_consortiums >= MAX_ROAMING_CONS) {
+ if (num_ois >= MAX_ROAMING_CONS) {
wpa_printf(MSG_INFO,
- "Too many roaming_consortiums OIs");
+ "Too many OIs");
return -1;
}
pos = end + 1;
}
- os_memcpy(cred->roaming_consortiums, roaming_consortiums,
- sizeof(roaming_consortiums));
- os_memcpy(cred->roaming_consortiums_len, roaming_consortiums_len,
- sizeof(roaming_consortiums_len));
- cred->num_roaming_consortiums = num_roaming_consortiums;
+ os_memcpy(cred_ois, ois, sizeof(ois));
+ os_memcpy(cred_ois_len, ois_len, sizeof(ois_len));
+ *cred_num_ois = num_ois;
return 0;
}
@@ -3782,36 +3870,70 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
}
if (os_strcmp(var, "roaming_consortium") == 0) {
- if (len < 3 || len > sizeof(cred->roaming_consortium)) {
+ if (len < 3 || len > sizeof(cred->home_ois[0])) {
wpa_printf(MSG_ERROR, "Line %d: invalid "
"roaming_consortium length %d (3..15 "
"expected)", line, (int) len);
os_free(val);
return -1;
}
- os_memcpy(cred->roaming_consortium, val, len);
- cred->roaming_consortium_len = len;
+ wpa_printf(MSG_WARNING,
+ "Line %d: option roaming_consortium is deprecated and will be removed in the future",
+ line);
+ os_memcpy(cred->home_ois[0], val, len);
+ cred->home_ois_len[0] = len;
+ cred->num_home_ois = 1;
os_free(val);
return 0;
}
if (os_strcmp(var, "required_roaming_consortium") == 0) {
- if (len < 3 || len > sizeof(cred->required_roaming_consortium))
- {
+ if (len < 3 || len > sizeof(cred->required_home_ois[0])) {
wpa_printf(MSG_ERROR, "Line %d: invalid "
"required_roaming_consortium length %d "
"(3..15 expected)", line, (int) len);
os_free(val);
return -1;
}
- os_memcpy(cred->required_roaming_consortium, val, len);
- cred->required_roaming_consortium_len = len;
+ wpa_printf(MSG_WARNING,
+ "Line %d: option required_roaming_consortium is deprecated and will be removed in the future",
+ line);
+ os_memcpy(cred->required_home_ois[0], val, len);
+ cred->required_home_ois_len[0] = len;
+ cred->num_required_home_ois = 1;
os_free(val);
return 0;
}
+ if (os_strcmp(var, "home_ois") == 0) {
+ res = wpa_config_set_cred_ois(cred->home_ois,
+ cred->home_ois_len,
+ &cred->num_home_ois,
+ val);
+ if (res < 0)
+ wpa_printf(MSG_ERROR, "Line %d: invalid home_ois",
+ line);
+ os_free(val);
+ return res;
+ }
+
+ if (os_strcmp(var, "required_home_ois") == 0) {
+ res = wpa_config_set_cred_ois(cred->required_home_ois,
+ cred->required_home_ois_len,
+ &cred->num_required_home_ois,
+ val);
+ if (res < 0)
+ wpa_printf(MSG_ERROR,
+ "Line %d: invalid required_home_ois", line);
+ os_free(val);
+ return res;
+ }
+
if (os_strcmp(var, "roaming_consortiums") == 0) {
- res = wpa_config_set_cred_roaming_consortiums(cred, val);
+ res = wpa_config_set_cred_ois(cred->roaming_consortiums,
+ cred->roaming_consortiums_len,
+ &cred->num_roaming_consortiums,
+ val);
if (res < 0)
wpa_printf(MSG_ERROR,
"Line %d: invalid roaming_consortiums",
@@ -3911,9 +4033,20 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
return 0;
}
- if (os_strcmp(var, "imsi_privacy_key") == 0) {
- os_free(cred->imsi_privacy_key);
- cred->imsi_privacy_key = val;
+ if (os_strcmp(var, "imsi_privacy_cert") == 0) {
+ os_free(cred->imsi_privacy_cert);
+ cred->imsi_privacy_cert = val;
+ return 0;
+ }
+
+ if (os_strcmp(var, "imsi_privacy_attr") == 0) {
+ os_free(cred->imsi_privacy_attr);
+ cred->imsi_privacy_attr = val;
+ return 0;
+ }
+
+ if (os_strcmp(var, "strict_conservative_peer_mode") == 0) {
+ cred->strict_conservative_peer_mode = atoi(val);
return 0;
}
@@ -4067,8 +4200,14 @@ char * wpa_config_get_cred_no_key(struct wpa_cred *cred, const char *var)
if (os_strcmp(var, "imsi") == 0)
return alloc_strdup(cred->imsi);
- if (os_strcmp(var, "imsi_privacy_key") == 0)
- return alloc_strdup(cred->imsi_privacy_key);
+ if (os_strcmp(var, "imsi_privacy_cert") == 0)
+ return alloc_strdup(cred->imsi_privacy_cert);
+
+ if (os_strcmp(var, "imsi_privacy_attr") == 0)
+ return alloc_strdup(cred->imsi_privacy_attr);
+
+ if (os_strcmp(var, "strict_conservative_peer_mode") == 0)
+ return alloc_int_str(cred->strict_conservative_peer_mode);
if (os_strcmp(var, "milenage") == 0) {
if (!(cred->milenage))
@@ -4114,14 +4253,14 @@ char * wpa_config_get_cred_no_key(struct wpa_cred *cred, const char *var)
size_t buflen;
char *buf;
- if (!cred->roaming_consortium_len)
+ if (!cred->num_home_ois || !cred->home_ois_len[0])
return NULL;
- buflen = cred->roaming_consortium_len * 2 + 1;
+ buflen = cred->home_ois_len[0] * 2 + 1;
buf = os_malloc(buflen);
if (buf == NULL)
return NULL;
- wpa_snprintf_hex(buf, buflen, cred->roaming_consortium,
- cred->roaming_consortium_len);
+ wpa_snprintf_hex(buf, buflen, cred->home_ois[0],
+ cred->home_ois_len[0]);
return buf;
}
@@ -4129,14 +4268,64 @@ char * wpa_config_get_cred_no_key(struct wpa_cred *cred, const char *var)
size_t buflen;
char *buf;
- if (!cred->required_roaming_consortium_len)
+ if (!cred->num_required_home_ois ||
+ !cred->required_home_ois_len[0])
return NULL;
- buflen = cred->required_roaming_consortium_len * 2 + 1;
+ buflen = cred->required_home_ois_len[0] * 2 + 1;
buf = os_malloc(buflen);
if (buf == NULL)
return NULL;
- wpa_snprintf_hex(buf, buflen, cred->required_roaming_consortium,
- cred->required_roaming_consortium_len);
+ wpa_snprintf_hex(buf, buflen, cred->required_home_ois[0],
+ cred->required_home_ois_len[0]);
+ return buf;
+ }
+
+ if (os_strcmp(var, "home_ois") == 0) {
+ size_t buflen;
+ char *buf, *pos;
+ size_t i;
+
+ if (!cred->num_home_ois)
+ return NULL;
+ buflen = cred->num_home_ois * MAX_ROAMING_CONS_OI_LEN * 2 + 1;
+ buf = os_malloc(buflen);
+ if (!buf)
+ return NULL;
+ pos = buf;
+ for (i = 0; i < cred->num_home_ois; i++) {
+ if (i > 0)
+ *pos++ = ',';
+ pos += wpa_snprintf_hex(
+ pos, buf + buflen - pos,
+ cred->home_ois[i],
+ cred->home_ois_len[i]);
+ }
+ *pos = '\0';
+ return buf;
+ }
+
+ if (os_strcmp(var, "required_home_ois") == 0) {
+ size_t buflen;
+ char *buf, *pos;
+ size_t i;
+
+ if (!cred->num_required_home_ois)
+ return NULL;
+ buflen = cred->num_required_home_ois *
+ MAX_ROAMING_CONS_OI_LEN * 2 + 1;
+ buf = os_malloc(buflen);
+ if (!buf)
+ return NULL;
+ pos = buf;
+ for (i = 0; i < cred->num_required_home_ois; i++) {
+ if (i > 0)
+ *pos++ = ',';
+ pos += wpa_snprintf_hex(
+ pos, buf + buflen - pos,
+ cred->required_home_ois[i],
+ cred->required_home_ois_len[i]);
+ }
+ *pos = '\0';
return buf;
}
@@ -5207,6 +5396,7 @@ static const struct global_parse_data global_fields[] = {
{ FUNC(p2p_device_persistent_mac_addr), 0 },
{ INT(p2p_interface_random_mac_addr), 0 },
{ INT(p2p_6ghz_disable), 0 },
+ { INT(p2p_dfs_chan_enable), 0 },
#endif /* CONFIG_P2P */
{ FUNC(country), CFG_CHANGED_COUNTRY },
{ INT(bss_max_count), 0 },
@@ -5240,6 +5430,7 @@ static const struct global_parse_data global_fields[] = {
{ INT_RANGE(auto_interworking, 0, 1), 0 },
{ INT(okc), 0 },
{ INT(pmf), 0 },
+ { INT_RANGE(sae_check_mfp, 0, 1), 0 },
{ FUNC(sae_groups), 0 },
{ INT_RANGE(sae_pwe, 0, 3), 0 },
{ INT_RANGE(sae_pmkid_in_assoc, 0, 1), 0 },
@@ -5258,9 +5449,9 @@ static const struct global_parse_data global_fields[] = {
{ STR(osu_dir), 0 },
{ STR(wowlan_triggers), CFG_CHANGED_WOWLAN_TRIGGERS },
{ INT(p2p_search_delay), 0},
- { INT(mac_addr), 0 },
+ { INT_RANGE(mac_addr, 0, 2), 0 },
{ INT(rand_addr_lifetime), 0 },
- { INT(preassoc_mac_addr), 0 },
+ { INT_RANGE(preassoc_mac_addr, 0, 2), 0 },
{ INT(key_mgmt_offload), 0},
{ INT(passive_scan), 0 },
{ INT(reassoc_same_bss_optim), 0 },
@@ -5290,6 +5481,9 @@ static const struct global_parse_data global_fields[] = {
{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
{ STR(dpp_name), 0 },
{ STR(dpp_mud_url), 0 },
+ { STR(dpp_extra_conf_req_name), 0 },
+ { STR(dpp_extra_conf_req_value), 0 },
+ { INT_RANGE(dpp_connector_privacy_default, 0, 1), 0 },
#endif /* CONFIG_DPP */
{ INT_RANGE(coloc_intf_reporting, 0, 1), 0 },
{ INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },