diff options
author | Steve Kondik <steve@cyngn.com> | 2016-08-15 02:06:33 -0700 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2016-08-15 02:06:33 -0700 |
commit | dc6ca4340a7ad6005a2e13b66bb2995e8010aa82 (patch) | |
tree | a10cfe90c813fea4f55682d918759aa5e2c54aab | |
parent | a08fd9e9b66b23ceb7f14aaba3150e2146393b37 (diff) | |
parent | dff13b397b9dc3a1bb9120c2c3fcc8793cdb97b9 (diff) | |
download | android_external_wpa_supplicant_8-dc6ca4340a7ad6005a2e13b66bb2995e8010aa82.tar.gz android_external_wpa_supplicant_8-dc6ca4340a7ad6005a2e13b66bb2995e8010aa82.tar.bz2 android_external_wpa_supplicant_8-dc6ca4340a7ad6005a2e13b66bb2995e8010aa82.zip |
Merge branch 'wlan-service.lnx.1.0-rel.1.0' of git://codeaurora.org/platform/external/wpa_supplicant_8 into cm-13.0replicant-6.0-0002replicant-6.0-0001
Change-Id: I110d3aa8efe7861b7a5b0dd570bfe5b0ec88e6be
-rw-r--r-- | hostapd/config_file.c | 30 | ||||
-rw-r--r-- | hostapd/hostapd.conf | 7 | ||||
-rw-r--r-- | src/ap/ap_config.c | 1 | ||||
-rw-r--r-- | src/ap/ap_config.h | 1 | ||||
-rw-r--r-- | src/ap/ap_drv_ops.c | 5 | ||||
-rw-r--r-- | src/ap/beacon.c | 2 | ||||
-rw-r--r-- | src/ap/drv_callbacks.c | 11 | ||||
-rw-r--r-- | src/ap/ieee802_11.c | 8 | ||||
-rw-r--r-- | src/ap/ieee802_11.h | 2 | ||||
-rw-r--r-- | src/ap/ieee802_11_vht.c | 113 | ||||
-rw-r--r-- | src/eap_peer/eap_proxy_qmi.c | 22 | ||||
-rw-r--r-- | src/p2p/p2p.c | 2 | ||||
-rw-r--r-- | src/utils/common.c | 23 | ||||
-rw-r--r-- | src/utils/common.h | 2 | ||||
-rw-r--r-- | src/wps/wps_attr_process.c | 10 | ||||
-rw-r--r-- | wpa_supplicant/config.c | 30 |
16 files changed, 255 insertions, 14 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 5540059d..14ddad7f 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -3295,6 +3295,36 @@ static int hostapd_config_fill(struct hostapd_config *conf, wpabuf_free(bss->vendor_elements); bss->vendor_elements = elems; + } else if (os_strcmp(buf, "assocresp_elements") == 0) { + struct wpabuf *elems; + size_t len = os_strlen(pos); + if (len & 0x01) { + wpa_printf(MSG_ERROR, + "Line %d: Invalid assocresp_elements '%s'", + line, pos); + return 1; + } + len /= 2; + if (len == 0) { + wpabuf_free(bss->assocresp_elements); + bss->assocresp_elements = NULL; + return 0; + } + + elems = wpabuf_alloc(len); + if (elems == NULL) + return 1; + + if (hexstr2bin(pos, wpabuf_put(elems, len), len)) { + wpabuf_free(elems); + wpa_printf(MSG_ERROR, + "Line %d: Invalid assocresp_elements '%s'", + line, pos); + return 1; + } + + wpabuf_free(bss->assocresp_elements); + bss->assocresp_elements = elems; } else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0) { bss->sae_anti_clogging_threshold = atoi(pos); } else if (os_strcmp(buf, "sae_groups") == 0) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index c9c4d7e3..9aa49f55 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -274,6 +274,13 @@ ignore_broadcast_ssid=0 # one or more elements) #vendor_elements=dd0411223301 +# Additional vendor specific elements for (Re)Association Response frames +# This parameter can be used to add additional vendor specific element(s) into +# the end of the (Re)Association Response frames. The format for these +# element(s) is a hexdump of the raw information elements (id+len+payload for +# one or more elements) +#assocresp_elements=dd0411223301 + # TX queue parameters (EDCF / bursting) # tx_queue_<queue name>_<param> # queues: data0, data1, data2, data3, after_beacon, beacon diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 455013aa..3e396945 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -554,6 +554,7 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf) #endif /* CONFIG_HS20 */ wpabuf_free(conf->vendor_elements); + wpabuf_free(conf->assocresp_elements); os_free(conf->sae_groups); diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 71fc06e4..254f4bca 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -535,6 +535,7 @@ struct hostapd_bss_config { #endif /* CONFIG_RADIUS_TEST */ struct wpabuf *vendor_elements; + struct wpabuf *assocresp_elements; unsigned int sae_anti_clogging_threshold; int *sae_groups; diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 6cafcb74..b9029bb7 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -207,6 +207,11 @@ int hostapd_build_ap_extra_ies(struct hostapd_data *hapd, if (wpabuf_resize(&proberesp, add) == 0) wpabuf_put_buf(proberesp, hapd->conf->vendor_elements); } + if (hapd->conf->assocresp_elements) { + size_t add = wpabuf_len(hapd->conf->assocresp_elements); + if (wpabuf_resize(&assocresp, add) == 0) + wpabuf_put_buf(assocresp, hapd->conf->assocresp_elements); + } *beacon_ret = beacon; *proberesp_ret = proberesp; diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 54d0d6f4..c319372b 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -466,6 +466,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) { pos = hostapd_eid_vht_capabilities(hapd, pos); pos = hostapd_eid_vht_operation(hapd, pos); + pos = hostapd_eid_txpower_envelope(hapd, pos); } if (hapd->conf->vendor_vht) pos = hostapd_eid_vendor_vht(hapd, pos); @@ -925,6 +926,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) { tailpos = hostapd_eid_vht_capabilities(hapd, tailpos); tailpos = hostapd_eid_vht_operation(hapd, tailpos); + tailpos = hostapd_eid_txpower_envelope(hapd, tailpos); } if (hapd->conf->vendor_vht) tailpos = hostapd_eid_vendor_vht(hapd, tailpos); diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index fbbfe12c..cc664d78 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -115,8 +115,15 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, } sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2); - res = hostapd_check_acl(hapd, addr, NULL); - if (res != HOSTAPD_ACL_ACCEPT) { + /* + * ACL configurations to the drivers (implementing AP SME and ACL + * offload) without hostapd's knowledge, can result in a disconnection + * though the driver accepts the connection. Skip the hostapd check for + * ACL if the driver supports ACL offload to avoid potentially + * conflicting ACL rules. + */ + if (hapd->iface->drv_max_acl_mac_addrs == 0 && + hostapd_check_acl(hapd, addr, NULL) != HOSTAPD_ACL_ACCEPT) { wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect", MAC2STR(addr)); reason = WLAN_REASON_UNSPECIFIED; diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 288852db..0176c442 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1690,6 +1690,14 @@ static void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, p = hostapd_eid_p2p_manage(hapd, p); #endif /* CONFIG_P2P_MANAGER */ + if (hapd->conf->assocresp_elements && + (size_t) (buf + sizeof(buf) - p) >= + wpabuf_len(hapd->conf->assocresp_elements)) { + os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements), + wpabuf_len(hapd->conf->assocresp_elements)); + p += wpabuf_len(hapd->conf->assocresp_elements); + } + send_len += p - reply->u.assoc_resp.variable; if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 44c1bff3..6f505409 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -52,6 +52,8 @@ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid); +u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid); + int hostapd_ht_operation_update(struct hostapd_iface *iface); void ieee802_11_send_sa_query_req(struct hostapd_data *hapd, const u8 *addr, const u8 *trans_id); diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c index 5bf1b5d7..d31ab730 100644 --- a/src/ap/ieee802_11_vht.c +++ b/src/ap/ieee802_11_vht.c @@ -17,6 +17,7 @@ #include "sta_info.h" #include "beacon.h" #include "ieee802_11.h" +#include "dfs.h" u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid) @@ -131,6 +132,118 @@ static int check_valid_vht_mcs(struct hostapd_hw_modes *mode, } +u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) +{ + struct hostapd_iface *iface = hapd->iface; + struct hostapd_config *iconf = iface->conf; + struct hostapd_hw_modes *mode = iface->current_mode; + struct hostapd_channel_data *chan; + int dfs, i; + u8 channel, tx_pwr_count, local_pwr_constraint; + int max_tx_power; + u8 tx_pwr; + + if (!mode) + return eid; + + if (ieee80211_freq_to_chan(iface->freq, &channel) == NUM_HOSTAPD_MODES) + return eid; + + for (i = 0; i < mode->num_channels; i++) { + if (mode->channels[i].freq == iface->freq) + break; + } + if (i == mode->num_channels) + return eid; + + switch (iface->conf->vht_oper_chwidth) { + case VHT_CHANWIDTH_USE_HT: + if (iconf->secondary_channel == 0) { + /* Max Transmit Power count = 0 (20 MHz) */ + tx_pwr_count = 0; + } else { + /* Max Transmit Power count = 1 (20, 40 MHz) */ + tx_pwr_count = 1; + } + break; + case VHT_CHANWIDTH_80MHZ: + /* Max Transmit Power count = 2 (20, 40, and 80 MHz) */ + tx_pwr_count = 2; + break; + case VHT_CHANWIDTH_80P80MHZ: + case VHT_CHANWIDTH_160MHZ: + /* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */ + tx_pwr_count = 3; + break; + default: + return eid; + } + + /* + * Below local_pwr_constraint logic is referred from + * hostapd_eid_pwr_constraint. + * + * Check if DFS is required by regulatory. + */ + dfs = hostapd_is_dfs_required(hapd->iface); + if (dfs < 0) + dfs = 0; + + /* + * In order to meet regulations when TPC is not implemented using + * a transmit power that is below the legal maximum (including any + * mitigation factor) should help. In this case, indicate 3 dB below + * maximum allowed transmit power. + */ + if (hapd->iconf->local_pwr_constraint == -1) + local_pwr_constraint = (dfs == 0) ? 0 : 3; + else + local_pwr_constraint = hapd->iconf->local_pwr_constraint; + + /* + * A STA that is not an AP shall use a transmit power less than or + * equal to the local maximum transmit power level for the channel. + * The local maximum transmit power can be calculated from the formula: + * local max TX pwr = max TX pwr - local pwr constraint + * Where max TX pwr is maximum transmit power level specified for + * channel in Country element and local pwr constraint is specified + * for channel in this Power Constraint element. + */ + chan = &mode->channels[i]; + max_tx_power = chan->max_tx_power - local_pwr_constraint; + + /* + * Local Maximum Transmit power is encoded as two's complement + * with a 0.5 dB step. + */ + max_tx_power *= 2; /* in 0.5 dB steps */ + if (max_tx_power > 127) { + /* 63.5 has special meaning of 63.5 dBm or higher */ + max_tx_power = 127; + } + if (max_tx_power < -128) + max_tx_power = -128; + if (max_tx_power < 0) + tx_pwr = 0x80 + max_tx_power + 128; + else + tx_pwr = max_tx_power; + + *eid++ = WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE; + *eid++ = 2 + tx_pwr_count; + + /* + * Max Transmit Power count and + * Max Transmit Power units = 0 (EIRP) + */ + *eid++ = tx_pwr_count; + + for (i = 0; i <= tx_pwr_count; i++) + *eid++ = tx_pwr; + + return eid; +} + + u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta, const u8 *vht_capab) { diff --git a/src/eap_peer/eap_proxy_qmi.c b/src/eap_peer/eap_proxy_qmi.c index 60710306..fc469e64 100644 --- a/src/eap_peer/eap_proxy_qmi.c +++ b/src/eap_peer/eap_proxy_qmi.c @@ -716,6 +716,20 @@ int eap_auth_end_eap_session(qmi_client_type qmi_auth_svc_client_ptr) return 0; } +static void eap_proxy_schedule_thread(void *eloop_ctx, void *timeout_ctx) +{ + struct eap_proxy_sm *eap_proxy = eloop_ctx; + pthread_attr_t attr; + int ret = -1; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ret = pthread_create(&eap_proxy->thread_id, &attr, eap_proxy_post_init, eap_proxy); + if(ret < 0) + wpa_printf(MSG_ERROR, "eap_proxy: starting thread is failed %d\n", ret); +} + + struct eap_proxy_sm * eap_proxy_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb, void *msg_ctx) @@ -724,8 +738,6 @@ eap_proxy_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb, int qmiRetCode; struct eap_proxy_sm *eap_proxy; qmi_idl_service_object_type qmi_client_service_obj; - pthread_attr_t attr; - int ret = -1; eap_proxy = os_malloc(sizeof(struct eap_proxy_sm)); if (NULL == eap_proxy) { @@ -751,11 +763,7 @@ eap_proxy_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb, * parent process that created the qmi client context. */ - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - ret = pthread_create(&eap_proxy->thread_id, &attr, eap_proxy_post_init, eap_proxy); - if(ret < 0) - wpa_printf(MSG_ERROR, "eap_proxy: starting thread is failed %d\n", ret); + eloop_register_timeout(0, 0, eap_proxy_schedule_thread, eap_proxy, NULL); return eap_proxy; } diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 5da8ab38..8c553024 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -3706,6 +3706,8 @@ void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, break; case P2P_PENDING_INVITATION_RESPONSE: p2p_invitation_resp_cb(p2p, success); + if (p2p->inv_status != P2P_SC_SUCCESS) + p2p_check_after_scan_tx_continuation(p2p); break; case P2P_PENDING_DEV_DISC_REQUEST: p2p_dev_disc_req_cb(p2p, success); diff --git a/src/utils/common.c b/src/utils/common.c index 5cf0d571..e77b7db5 100644 --- a/src/utils/common.c +++ b/src/utils/common.c @@ -697,6 +697,29 @@ int is_hex(const u8 *data, size_t len) } +int has_ctrl_char(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; +} + + +int has_newline(const char *str) +{ + while (*str) { + if (*str == '\n' || *str == '\r') + return 1; + str++; + } + return 0; +} + + size_t merge_byte_arrays(u8 *res, size_t res_len, const u8 *src1, size_t src1_len, const u8 *src2, size_t src2_len) diff --git a/src/utils/common.h b/src/utils/common.h index fb9b5b9a..7dbb24a6 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -503,6 +503,8 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len); char * wpa_config_parse_string(const char *value, size_t *len); int is_hex(const u8 *data, size_t len); +int has_ctrl_char(const u8 *data, size_t len); +int has_newline(const char *str); size_t merge_byte_arrays(u8 *res, size_t res_len, const u8 *src1, size_t src1_len, const u8 *src2, size_t src2_len); diff --git a/src/wps/wps_attr_process.c b/src/wps/wps_attr_process.c index eadb22fe..e8c45793 100644 --- a/src/wps/wps_attr_process.c +++ b/src/wps/wps_attr_process.c @@ -229,6 +229,16 @@ static int wps_workaround_cred_key(struct wps_credential *cred) cred->key_len--; #endif /* CONFIG_WPS_STRICT */ } + + + if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) && + (cred->key_len < 8 || has_ctrl_char(cred->key, cred->key_len))) { + wpa_printf(MSG_INFO, "WPS: Reject credential with invalid WPA/WPA2-Personal passphrase"); + wpa_hexdump_ascii_key(MSG_INFO, "WPS: Network Key", + cred->key, cred->key_len); + return -1; + } + return 0; } diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 63256740..3455fc0e 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -456,6 +456,12 @@ static int wpa_config_parse_psk(const struct parse_data *data, } wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)", (u8 *) value, len); + if (has_ctrl_char((u8 *) value, len)) { + wpa_printf(MSG_ERROR, + "Line %d: Invalid passphrase character", + line); + return -1; + } if (ssid->passphrase && os_strlen(ssid->passphrase) == len && os_memcmp(ssid->passphrase, value, len) == 0) return 0; @@ -2609,14 +2615,15 @@ char * wpa_config_get(struct wpa_ssid *ssid, const char *var) const struct parse_data *field = &ssid_fields[i]; if (os_strcmp(var, field->name) == 0) { char *ret = field->writer(field, ssid); - if (ret != NULL && (os_strchr(ret, '\r') != NULL || - os_strchr(ret, '\n') != NULL)) { + + if (ret && has_newline(ret)) { wpa_printf(MSG_ERROR, - "Found newline in value for %s; " - "not returning it", var); + "Found newline in value for %s; not returning it", + var); os_free(ret); ret = NULL; } + return ret; } } @@ -2803,6 +2810,8 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var, if (os_strcmp(var, "password") == 0 && os_strncmp(value, "ext:", 4) == 0) { + if (has_newline(value)) + return -1; str_clear_free(cred->password); cred->password = os_strdup(value); cred->ext_password = 1; @@ -2853,9 +2862,14 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var, } val = wpa_config_parse_string(value, &len); - if (val == NULL) { + if (val == NULL || + (os_strcmp(var, "excluded_ssid") != 0 && + os_strcmp(var, "roaming_consortium") != 0 && + os_strcmp(var, "required_roaming_consortium") != 0 && + has_newline(val))) { wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string " "value '%s'.", line, var, value); + os_free(val); return -1; } @@ -3656,6 +3670,12 @@ static int wpa_global_config_parse_str(const struct global_parse_data *data, return -1; } + if (has_newline(pos)) { + wpa_printf(MSG_ERROR, "Line %d: invalid %s value with newline", + line, data->name); + return -1; + } + tmp = os_strdup(pos); if (tmp == NULL) return -1; |