diff options
Diffstat (limited to 'wpa_supplicant/config.c')
-rw-r--r-- | wpa_supplicant/config.c | 294 |
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 }, |