};
-static char * wpa_config_parse_string(const char *value, size_t *len)
-{
- if (*value == '"') {
- const char *pos;
- char *str;
- value++;
- pos = os_strrchr(value, '"');
- if (pos == NULL || pos[1] != '\0')
- return NULL;
- *len = pos - value;
- str = os_malloc(*len + 1);
- if (str == NULL)
- return NULL;
- os_memcpy(str, value, *len);
- str[*len] = '\0';
- return str;
- } else if (*value == 'P' && value[1] == '"') {
- const char *pos;
- char *tstr, *str;
- size_t tlen;
- value += 2;
- pos = os_strrchr(value, '"');
- if (pos == NULL || pos[1] != '\0')
- return NULL;
- tlen = pos - value;
- tstr = os_malloc(tlen + 1);
- if (tstr == NULL)
- return NULL;
- os_memcpy(tstr, value, tlen);
- tstr[tlen] = '\0';
-
- str = os_malloc(tlen + 1);
- if (str == NULL) {
- os_free(tstr);
- return NULL;
- }
-
- *len = printf_decode((u8 *) str, tlen + 1, tstr);
- os_free(tstr);
-
- return str;
- } else {
- u8 *str;
- size_t tlen, hlen = os_strlen(value);
- if (hlen & 1)
- return NULL;
- tlen = hlen / 2;
- str = os_malloc(tlen + 1);
- if (str == NULL)
- return NULL;
- if (hexstr2bin(value, str, tlen)) {
- os_free(str);
- return NULL;
- }
- str[tlen] = '\0';
- *len = tlen;
- return (char *) str;
- }
-}
-
-
static int wpa_config_parse_str(const struct parse_data *data,
struct wpa_ssid *ssid,
int line, const char *value)
#ifndef NO_CONFIG_WRITE
-static int is_hex(const u8 *data, size_t len)
-{
- size_t i;
-
- for (i = 0; i < len; i++) {
- if (data[i] < 32 || data[i] >= 127)
- return 1;
- }
- return 0;
-}
-
-
static char * wpa_config_write_string_ascii(const u8 *value, size_t len)
{
char *buf;
else if (os_strcmp(start, "WPS") == 0)
val |= WPA_KEY_MGMT_WPS;
#endif /* CONFIG_WPS */
+#ifdef CONFIG_SAE
+ else if (os_strcmp(start, "SAE") == 0)
+ val |= WPA_KEY_MGMT_SAE;
+ else if (os_strcmp(start, "FT-SAE") == 0)
+ val |= WPA_KEY_MGMT_FT_SAE;
+#endif /* CONFIG_SAE */
else {
wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
line, start);
*end = '\0';
if (os_strcmp(start, "CCMP") == 0)
val |= WPA_CIPHER_CCMP;
+ else if (os_strcmp(start, "GCMP") == 0)
+ val |= WPA_CIPHER_GCMP;
else if (os_strcmp(start, "TKIP") == 0)
val |= WPA_CIPHER_TKIP;
else if (os_strcmp(start, "WEP104") == 0)
pos += ret;
}
+ if (cipher & WPA_CIPHER_GCMP) {
+ ret = os_snprintf(pos, end - pos, "%sGCMP",
+ pos == buf ? "" : " ");
+ if (ret < 0 || ret >= end - pos) {
+ end[-1] = '\0';
+ return buf;
+ }
+ pos += ret;
+ }
+
if (cipher & WPA_CIPHER_TKIP) {
ret = os_snprintf(pos, end - pos, "%sTKIP",
pos == buf ? "" : " ");
val = wpa_config_parse_cipher(line, value);
if (val == -1)
return -1;
- if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_NONE)) {
+ if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP |
+ WPA_CIPHER_NONE)) {
wpa_printf(MSG_ERROR, "Line %d: not allowed pairwise cipher "
"(0x%x).", line, val);
return -1;
val = wpa_config_parse_cipher(line, value);
if (val == -1)
return -1;
- if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_TKIP | WPA_CIPHER_WEP104 |
- WPA_CIPHER_WEP40)) {
+ if (val & ~(WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | WPA_CIPHER_TKIP |
+ WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40)) {
wpa_printf(MSG_ERROR, "Line %d: not allowed group cipher "
"(0x%x).", line, val);
return -1;
#endif /* NO_CONFIG_WRITE */
-static int * wpa_config_parse_freqs(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
+static int * wpa_config_parse_int_array(const char *value)
{
int *freqs;
size_t used, len;
used = 0;
len = 10;
- freqs = os_zalloc((len + 1) * sizeof(int));
+ freqs = os_calloc(len + 1, sizeof(int));
if (freqs == NULL)
return NULL;
if (used == len) {
int *n;
size_t i;
- n = os_realloc(freqs, (len * 2 + 1) * sizeof(int));
+ n = os_realloc_array(freqs, len * 2 + 1, sizeof(int));
if (n == NULL) {
os_free(freqs);
return NULL;
{
int *freqs;
- freqs = wpa_config_parse_freqs(data, ssid, line, value);
+ freqs = wpa_config_parse_int_array(value);
if (freqs == NULL)
return -1;
os_free(ssid->scan_freq);
{
int *freqs;
- freqs = wpa_config_parse_freqs(data, ssid, line, value);
+ freqs = wpa_config_parse_int_array(value);
if (freqs == NULL)
return -1;
os_free(ssid->freq_list);
last = *end == '\0';
*end = '\0';
tmp = methods;
- methods = os_realloc(methods,
- (num_methods + 1) * sizeof(*methods));
+ methods = os_realloc_array(methods, num_methods + 1,
+ sizeof(*methods));
if (methods == NULL) {
os_free(tmp);
os_free(buf);
os_free(buf);
tmp = methods;
- methods = os_realloc(methods, (num_methods + 1) * sizeof(*methods));
+ methods = os_realloc_array(methods, num_methods + 1, sizeof(*methods));
if (methods == NULL) {
os_free(tmp);
return -1;
pos++;
if (hwaddr_aton(pos, addr)) {
- wpa_printf(MSG_ERROR, "Line %d: Invalid "
- "p2p_client_list address '%s'.",
- line, value);
- /* continue anyway */
+ if (count == 0) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid "
+ "p2p_client_list address '%s'.",
+ line, value);
+ os_free(buf);
+ return -1;
+ }
+ /* continue anyway since this could have been from a
+ * truncated configuration file line */
+ wpa_printf(MSG_INFO, "Line %d: Ignore likely "
+ "truncated p2p_client_list address '%s'",
+ line, pos);
} else {
- n = os_realloc(buf, (count + 1) * ETH_ALEN);
+ n = os_realloc_array(buf, count + 1, ETH_ALEN);
if (n == NULL) {
os_free(buf);
return -1;
}
buf = n;
- os_memcpy(buf + count * ETH_ALEN, addr, ETH_ALEN);
+ os_memmove(buf + ETH_ALEN, buf, count * ETH_ALEN);
+ os_memcpy(buf, addr, ETH_ALEN);
count++;
wpa_hexdump(MSG_MSGDUMP, "p2p_client_list",
addr, ETH_ALEN);
pos = value;
end = value + 20 * ssid->num_p2p_clients;
- for (i = 0; i < ssid->num_p2p_clients; i++) {
+ for (i = ssid->num_p2p_clients; i > 0; i--) {
res = os_snprintf(pos, end - pos, MACSTR " ",
MAC2STR(ssid->p2p_client_list +
- i * ETH_ALEN));
+ (i - 1) * ETH_ALEN));
if (res < 0 || res >= end - pos) {
os_free(value);
return NULL;
#endif /* CONFIG_IEEE80211W */
{ INT_RANGE(peerkey, 0, 1) },
{ INT_RANGE(mixed_cell, 0, 1) },
- { INT_RANGE(frequency, 0, 10000) },
+ { INT_RANGE(frequency, 0, 65000) },
{ INT(wpa_ptk_rekey) },
{ STR(bgscan) },
{ INT_RANGE(ignore_broadcast_ssid, 0, 2) },
#ifdef CONFIG_HT_OVERRIDES
{ INT_RANGE(disable_ht, 0, 1) },
{ INT_RANGE(disable_ht40, -1, 1) },
+ { INT_RANGE(disable_sgi, 0, 1) },
{ INT_RANGE(disable_max_amsdu, -1, 1) },
{ INT_RANGE(ampdu_factor, -1, 3) },
{ INT_RANGE(ampdu_density, -1, 7) },
}
/* First network for this priority - add a new priority list */
- nlist = os_realloc(config->pssid,
- (config->num_prio + 1) * sizeof(struct wpa_ssid *));
+ nlist = os_realloc_array(config->pssid, config->num_prio + 1,
+ sizeof(struct wpa_ssid *));
if (nlist == NULL)
return -1;
os_free(cred->eap_method);
os_free(cred->phase1);
os_free(cred->phase2);
+ os_free(cred->excluded_ssid);
os_free(cred);
}
wpabuf_free(config->wps_nfc_dh_privkey);
wpabuf_free(config->wps_nfc_dev_pw);
os_free(config->ext_password_backend);
+ os_free(config->sae_groups);
os_free(config);
}
#ifdef CONFIG_HT_OVERRIDES
ssid->disable_ht = DEFAULT_DISABLE_HT;
ssid->disable_ht40 = DEFAULT_DISABLE_HT40;
+ ssid->disable_sgi = DEFAULT_DISABLE_SGI;
ssid->disable_max_amsdu = DEFAULT_DISABLE_MAX_AMSDU;
ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR;
ssid->ampdu_density = DEFAULT_AMPDU_DENSITY;
#endif /* CONFIG_HT_OVERRIDES */
+ ssid->proactive_key_caching = -1;
+#ifdef CONFIG_IEEE80211W
+ ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;
+#endif /* CONFIG_IEEE80211W */
}
get_keys = get_keys && ssid->export_keys;
- props = os_zalloc(sizeof(char *) * ((2 * NUM_SSID_FIELDS) + 1));
+ props = os_calloc(2 * NUM_SSID_FIELDS + 1, sizeof(char *));
if (!props)
return NULL;
return 0;
}
+ if (os_strcmp(var, "excluded_ssid") == 0) {
+ struct excluded_ssid *e;
+
+ if (len > MAX_SSID_LEN) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid "
+ "excluded_ssid length %d", line, (int) len);
+ os_free(val);
+ return -1;
+ }
+
+ e = os_realloc_array(cred->excluded_ssid,
+ cred->num_excluded_ssid + 1,
+ sizeof(struct excluded_ssid));
+ if (e == NULL) {
+ os_free(val);
+ return -1;
+ }
+ cred->excluded_ssid = e;
+
+ e = &cred->excluded_ssid[cred->num_excluded_ssid++];
+ os_memcpy(e->ssid, val, len);
+ e->ssid_len = len;
+
+ os_free(val);
+
+ return 0;
+ }
+
if (line) {
wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
line, var);
const char *driver_param)
{
struct wpa_config *config;
+ const int aCWmin = 4, aCWmax = 10;
+ const struct hostapd_wmm_ac_params ac_bk =
+ { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */
+ const struct hostapd_wmm_ac_params ac_be =
+ { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
+ const struct hostapd_wmm_ac_params ac_vi = /* video traffic */
+ { aCWmin - 1, aCWmin, 2, 3000 / 32, 0 };
+ const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */
+ { aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 0 };
config = os_zalloc(sizeof(*config));
if (config == NULL)
config->fast_reauth = DEFAULT_FAST_REAUTH;
config->p2p_go_intent = DEFAULT_P2P_GO_INTENT;
config->p2p_intra_bss = DEFAULT_P2P_INTRA_BSS;
+ config->p2p_go_max_inactivity = DEFAULT_P2P_GO_MAX_INACTIVITY;
config->bss_max_count = DEFAULT_BSS_MAX_COUNT;
config->bss_expiration_age = DEFAULT_BSS_EXPIRATION_AGE;
config->bss_expiration_scan_count = DEFAULT_BSS_EXPIRATION_SCAN_COUNT;
config->max_num_sta = DEFAULT_MAX_NUM_STA;
config->access_network_type = DEFAULT_ACCESS_NETWORK_TYPE;
+ config->wmm_ac_params[0] = ac_be;
+ config->wmm_ac_params[1] = ac_bk;
+ config->wmm_ac_params[2] = ac_vi;
+ config->wmm_ac_params[3] = ac_vo;
if (ctrl_interface)
config->ctrl_interface = os_strdup(ctrl_interface);
pos2++;
chan = atoi(pos2);
- n = os_realloc(pref, (num + 1) * sizeof(struct p2p_channel));
+ n = os_realloc_array(pref, num + 1,
+ sizeof(struct p2p_channel));
if (n == NULL)
goto fail;
pref = n;
}
+static int wpa_config_process_sae_groups(
+ const struct global_parse_data *data,
+ struct wpa_config *config, int line, const char *pos)
+{
+ int *groups = wpa_config_parse_int_array(pos);
+ if (groups == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid sae_groups '%s'",
+ line, pos);
+ return -1;
+ }
+
+ os_free(config->sae_groups);
+ config->sae_groups = groups;
+
+ return 0;
+}
+
+
#ifdef OFFSET
#undef OFFSET
#endif /* OFFSET */
{ INT_RANGE(p2p_intra_bss, 0, 1), CFG_CHANGED_P2P_INTRA_BSS },
{ INT(p2p_group_idle), 0 },
{ FUNC(p2p_pref_chan), CFG_CHANGED_P2P_PREF_CHAN },
+ { INT(p2p_go_ht40), 0 },
+ { INT(p2p_disabled), 0 },
+ { INT(p2p_no_group_iface), 0 },
#endif /* CONFIG_P2P */
{ FUNC(country), CFG_CHANGED_COUNTRY },
{ INT(bss_max_count), 0 },
{ BIN(wps_nfc_dh_pubkey), 0 },
{ BIN(wps_nfc_dh_privkey), 0 },
{ BIN(wps_nfc_dev_pw), 0 },
- { STR(ext_password_backend), CFG_CHANGED_EXT_PW_BACKEND }
+ { STR(ext_password_backend), CFG_CHANGED_EXT_PW_BACKEND },
+ { INT(p2p_go_max_inactivity), 0 },
+ { INT_RANGE(auto_interworking, 0, 1), 0 },
+ { INT(okc), 0 },
+ { INT(pmf), 0 },
+ { FUNC(sae_groups), 0 },
};
#undef FUNC
break;
}
if (i == NUM_GLOBAL_FIELDS) {
+#ifdef CONFIG_AP
+ if (os_strncmp(pos, "wmm_ac_", 7) == 0) {
+ char *tmp = os_strchr(pos, '=');
+ if (tmp == NULL) {
+ if (line < 0)
+ return -1;
+ wpa_printf(MSG_ERROR, "Line %d: invalid line "
+ "'%s'", line, pos);
+ return -1;
+ }
+ *tmp++ = '\0';
+ if (hostapd_config_wmm_ac(config->wmm_ac_params, pos,
+ tmp)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid WMM "
+ "AC item", line);
+ return -1;
+ }
+ }
+#endif /* CONFIG_AP */
if (line < 0)
return -1;
wpa_printf(MSG_ERROR, "Line %d: unknown global field '%s'.",