diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2015-05-04 10:34:12 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2015-05-07 11:28:37 -0700 |
commit | cc00d5dc8483e32158b2ba61ea44b0c38d790ed7 (patch) | |
tree | 533da635c6af5654dd5673b5b0449d1d9567091f | |
parent | d1c753ef9cb780f24f7b8000c3540ab1452bc7a9 (diff) | |
download | wpa_supplicant_8-cc00d5dc8483e32158b2ba61ea44b0c38d790ed7.tar.gz |
Cumulative security patch from commit 58606fd98722e92aaa4c2c7b8cb99cc92bd4308c
58606fd EAP-pwd server: Make sure in_frag_pos is cleared to zero on allocation
6aa5d95 EAP-pwd peer: Make sure in_frag_pos is cleared to zero on allocation
28a069a EAP-pwd peer: Fix asymmetric fragmentation behavior
3035cc2 EAP-pwd server: Fix Total-Length parsing for fragment reassembly
477c743 EAP-pwd peer: Fix Total-Length parsing for fragment reassembly
e28a58b EAP-pwd server: Fix payload length validation for Commit and Confirm
dd2f043 EAP-pwd peer: Fix payload length validation for Commit and Confirm
ef566a4 AP WMM: Fix integer underflow in WMM Action frame parser
8640cf7 WPS: Add more debug prints to httpread
1bd0d57 WPS: Replace the httpread_debug design with standard debug prints
7da4f4b WPS: Check maximum HTTP body length earlier in the process
af185d0 WPS: Extra validation step for HTTP reader
5acd23f WPS: Fix HTTP chunked transfer encoding parser
a5da657 dbus: Stop ongoing scheduled scan when scan is requested
0c28071 Fix sending ANQP request to an unknown BSS while associated
74197e0 wpa_cli: Fix memory leak when tracking networks
4504621 TDLS: Add TDLS_LINK_STATUS command to the control interface
01e87ef IBSS: Check ibss_rsn init before starting new IBSS authentication
74d912f libtommath: Fix check mp_init_multi() result
fd66aa6 Check Public Action length explicitly before reading Action Code
ff4a6d4 EAP-SIM/AKA: Explicitly check for header to include Reserved field
f5ed400 EAP-SAKE: Make attribute parser more readable
0dfb7be EAP-SAKE: Pass EAP identifier instead of full request
354e3f7 TLS: Fix debug dump of X.509 certificate
87fcb5a EAP-PAX: Fix PAX_STD-1 and PAX_STD-3 payload length validation
c3c5615 EAP-GPSK: Pass EAP identifier instead of full request
d36c803 EAP-TLS/PEAP/TTLS/FAST: Move more towards using struct wpabuf
8d9f3b8 EAP-FAST: Do not use type cast to remove const specification
07f9034 EAP-FAST: Pass EAP identifier instead of full request
f153e41 EAP-EKE: Do not pass full request to eap_eke_build_fail()
53f376c Fix a typo in function documentation
5aeebc4 D-Bus Fix network_is_persistent_group() for P2P operations
5441da2 Fix wpas_notify_network_removed()
e8181e2 dbus: Add a debug print on fill_dict_with_properties() getter failures
8a78e22 D-Bus: Fix operations when P2P management interface is used
dea0d8e RADIUS: Fix a copy-paste error in variable name
Change-Id: Ib70bf513c1f6c17974ef135806e44e120a5d5709
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
36 files changed, 561 insertions, 311 deletions
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 9e7d70de..8d2a0663 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2098,7 +2098,8 @@ static int handle_action(struct hostapd_data *hapd, case WLAN_ACTION_PUBLIC: case WLAN_ACTION_PROTECTED_DUAL: #ifdef CONFIG_IEEE80211N - if (mgmt->u.action.u.public_action.action == + if (len >= IEEE80211_HDRLEN + 2 && + mgmt->u.action.u.public_action.action == WLAN_PA_20_40_BSS_COEX) { wpa_printf(MSG_DEBUG, "HT20/40 coex mgmt frame received from STA " diff --git a/src/ap/wmm.c b/src/ap/wmm.c index 6d4177c2..314e244b 100644 --- a/src/ap/wmm.c +++ b/src/ap/wmm.c @@ -274,6 +274,9 @@ void hostapd_wmm_action(struct hostapd_data *hapd, return; } + if (left < 0) + return; /* not a valid WMM Action frame */ + /* extract the tspec info element */ if (ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) { hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, diff --git a/src/eap_common/eap_common.c b/src/eap_common/eap_common.c index 1de13281..51a15d75 100644 --- a/src/eap_common/eap_common.c +++ b/src/eap_common/eap_common.c @@ -192,7 +192,7 @@ u8 eap_get_id(const struct wpabuf *msg) /** - * eap_get_id - Get EAP Type from wpabuf + * eap_get_type - Get EAP Type from wpabuf * @msg: Buffer starting with an EAP header * Returns: The EAP Type after the EAP header */ diff --git a/src/eap_common/eap_sake_common.c b/src/eap_common/eap_sake_common.c index a76253d0..c22e43ed 100644 --- a/src/eap_common/eap_sake_common.c +++ b/src/eap_common/eap_sake_common.c @@ -16,99 +16,99 @@ static int eap_sake_parse_add_attr(struct eap_sake_parse_attr *attr, - const u8 *pos) + u8 attr_id, u8 len, const u8 *data) { size_t i; - switch (pos[0]) { + switch (attr_id) { case EAP_SAKE_AT_RAND_S: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_RAND_S"); - if (pos[1] != 2 + EAP_SAKE_RAND_LEN) { + if (len != EAP_SAKE_RAND_LEN) { wpa_printf(MSG_DEBUG, "EAP-SAKE: AT_RAND_S with " - "invalid length %d", pos[1]); + "invalid payload length %d", len); return -1; } - attr->rand_s = pos + 2; + attr->rand_s = data; break; case EAP_SAKE_AT_RAND_P: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_RAND_P"); - if (pos[1] != 2 + EAP_SAKE_RAND_LEN) { + if (len != EAP_SAKE_RAND_LEN) { wpa_printf(MSG_DEBUG, "EAP-SAKE: AT_RAND_P with " - "invalid length %d", pos[1]); + "invalid payload length %d", len); return -1; } - attr->rand_p = pos + 2; + attr->rand_p = data; break; case EAP_SAKE_AT_MIC_S: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_MIC_S"); - if (pos[1] != 2 + EAP_SAKE_MIC_LEN) { + if (len != EAP_SAKE_MIC_LEN) { wpa_printf(MSG_DEBUG, "EAP-SAKE: AT_MIC_S with " - "invalid length %d", pos[1]); + "invalid payload length %d", len); return -1; } - attr->mic_s = pos + 2; + attr->mic_s = data; break; case EAP_SAKE_AT_MIC_P: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_MIC_P"); - if (pos[1] != 2 + EAP_SAKE_MIC_LEN) { + if (len != EAP_SAKE_MIC_LEN) { wpa_printf(MSG_DEBUG, "EAP-SAKE: AT_MIC_P with " - "invalid length %d", pos[1]); + "invalid payload length %d", len); return -1; } - attr->mic_p = pos + 2; + attr->mic_p = data; break; case EAP_SAKE_AT_SERVERID: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_SERVERID"); - attr->serverid = pos + 2; - attr->serverid_len = pos[1] - 2; + attr->serverid = data; + attr->serverid_len = len; break; case EAP_SAKE_AT_PEERID: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_PEERID"); - attr->peerid = pos + 2; - attr->peerid_len = pos[1] - 2; + attr->peerid = data; + attr->peerid_len = len; break; case EAP_SAKE_AT_SPI_S: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_SPI_S"); - attr->spi_s = pos + 2; - attr->spi_s_len = pos[1] - 2; + attr->spi_s = data; + attr->spi_s_len = len; break; case EAP_SAKE_AT_SPI_P: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_SPI_P"); - attr->spi_p = pos + 2; - attr->spi_p_len = pos[1] - 2; + attr->spi_p = data; + attr->spi_p_len = len; break; case EAP_SAKE_AT_ANY_ID_REQ: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_ANY_ID_REQ"); - if (pos[1] != 4) { + if (len != 2) { wpa_printf(MSG_DEBUG, "EAP-SAKE: Invalid AT_ANY_ID_REQ" - " length %d", pos[1]); + " payload length %d", len); return -1; } - attr->any_id_req = pos + 2; + attr->any_id_req = data; break; case EAP_SAKE_AT_PERM_ID_REQ: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_PERM_ID_REQ"); - if (pos[1] != 4) { + if (len != 2) { wpa_printf(MSG_DEBUG, "EAP-SAKE: Invalid " - "AT_PERM_ID_REQ length %d", pos[1]); + "AT_PERM_ID_REQ payload length %d", len); return -1; } - attr->perm_id_req = pos + 2; + attr->perm_id_req = data; break; case EAP_SAKE_AT_ENCR_DATA: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_ENCR_DATA"); - attr->encr_data = pos + 2; - attr->encr_data_len = pos[1] - 2; + attr->encr_data = data; + attr->encr_data_len = len; break; case EAP_SAKE_AT_IV: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_IV"); - attr->iv = pos + 2; - attr->iv_len = pos[1] - 2; + attr->iv = data; + attr->iv_len = len; break; case EAP_SAKE_AT_PADDING: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_PADDING"); - for (i = 2; i < pos[1]; i++) { - if (pos[i]) { + for (i = 0; i < len; i++) { + if (data[i]) { wpa_printf(MSG_DEBUG, "EAP-SAKE: AT_PADDING " "with non-zero pad byte"); return -1; @@ -117,26 +117,26 @@ static int eap_sake_parse_add_attr(struct eap_sake_parse_attr *attr, break; case EAP_SAKE_AT_NEXT_TMPID: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_NEXT_TMPID"); - attr->next_tmpid = pos + 2; - attr->next_tmpid_len = pos[1] - 2; + attr->next_tmpid = data; + attr->next_tmpid_len = len; break; case EAP_SAKE_AT_MSK_LIFE: wpa_printf(MSG_DEBUG, "EAP-SAKE: Parse: AT_IV"); - if (pos[1] != 6) { + if (len != 4) { wpa_printf(MSG_DEBUG, "EAP-SAKE: Invalid " - "AT_MSK_LIFE length %d", pos[1]); + "AT_MSK_LIFE payload length %d", len); return -1; } - attr->msk_life = pos + 2; + attr->msk_life = data; break; default: - if (pos[0] < 128) { + if (attr_id < 128) { wpa_printf(MSG_DEBUG, "EAP-SAKE: Unknown non-skippable" - " attribute %d", pos[0]); + " attribute %d", attr_id); return -1; } wpa_printf(MSG_DEBUG, "EAP-SAKE: Ignoring unknown skippable " - "attribute %d", pos[0]); + "attribute %d", attr_id); break; } @@ -180,7 +180,7 @@ int eap_sake_parse_attributes(const u8 *buf, size_t len, return -1; } - if (eap_sake_parse_add_attr(attr, pos)) + if (eap_sake_parse_add_attr(attr, pos[0], pos[1] - 2, pos + 2)) return -1; pos += pos[1]; diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c index 0662ae73..dc9e8cc3 100644 --- a/src/eap_peer/eap_aka.c +++ b/src/eap_peer/eap_aka.c @@ -1296,7 +1296,7 @@ static struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv, pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData, &len); - if (pos == NULL || len < 1) { + if (pos == NULL || len < 3) { ret->ignore = TRUE; return NULL; } diff --git a/src/eap_peer/eap_eke.c b/src/eap_peer/eap_eke.c index 9fec66c0..987af83f 100644 --- a/src/eap_peer/eap_eke.c +++ b/src/eap_peer/eap_eke.c @@ -195,15 +195,14 @@ static int eap_eke_supp_mac(u8 mac) static struct wpabuf * eap_eke_build_fail(struct eap_eke_data *data, struct eap_method_ret *ret, - const struct wpabuf *reqData, - u32 failure_code) + u8 id, u32 failure_code) { struct wpabuf *resp; wpa_printf(MSG_DEBUG, "EAP-EKE: Sending EAP-EKE-Failure/Response - code=0x%x", failure_code); - resp = eap_eke_build_msg(data, eap_get_id(reqData), 4, EAP_EKE_FAILURE); + resp = eap_eke_build_msg(data, id, 4, EAP_EKE_FAILURE); if (resp) wpabuf_put_be32(resp, failure_code); @@ -230,9 +229,10 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data, const u8 *pos, *end; const u8 *prop = NULL; u8 idtype; + u8 id = eap_get_id(reqData); if (data->state != IDENTITY) { - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PROTO_ERROR); } @@ -240,7 +240,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data, if (payload_len < 2 + 4) { wpa_printf(MSG_DEBUG, "EAP-EKE: Too short ID/Request Data"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PROTO_ERROR); } @@ -253,7 +253,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data, if (pos + num_prop * 4 > end) { wpa_printf(MSG_DEBUG, "EAP-EKE: Too short ID/Request Data (num_prop=%u)", num_prop); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PROTO_ERROR); } @@ -293,7 +293,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data, if (prop == NULL) { wpa_printf(MSG_DEBUG, "EAP-EKE: No acceptable proposal found"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_NO_PROPOSAL_CHOSEN); } @@ -301,7 +301,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data, if (pos == end) { wpa_printf(MSG_DEBUG, "EAP-EKE: Too short ID/Request Data to include IDType/Identity"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PROTO_ERROR); } @@ -312,7 +312,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data, os_free(data->serverid); data->serverid = os_malloc(end - pos); if (data->serverid == NULL) { - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } os_memcpy(data->serverid, pos, end - pos); @@ -320,11 +320,11 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data, wpa_printf(MSG_DEBUG, "EAP-EKE: Sending EAP-EKE-ID/Response"); - resp = eap_eke_build_msg(data, eap_get_id(reqData), + resp = eap_eke_build_msg(data, id, 2 + 4 + 1 + data->peerid_len, EAP_EKE_ID); if (resp == NULL) { - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -339,7 +339,7 @@ static struct wpabuf * eap_eke_process_id(struct eap_eke_data *data, data->msgs = wpabuf_alloc(wpabuf_len(reqData) + wpabuf_len(resp)); if (data->msgs == NULL) { wpabuf_free(resp); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpabuf_put_buf(data->msgs, reqData); @@ -366,10 +366,11 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, u8 pub[EAP_EKE_MAX_DH_LEN]; const u8 *password; size_t password_len; + u8 id = eap_get_id(reqData); if (data->state != COMMIT) { wpa_printf(MSG_DEBUG, "EAP-EKE: EAP-EKE-Commit/Request received in unexpected state (%d)", data->state); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PROTO_ERROR); } @@ -378,7 +379,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, password = eap_get_config_password(sm, &password_len); if (password == NULL) { wpa_printf(MSG_INFO, "EAP-EKE: No password configured!"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PASSWD_NOT_FOUND); } @@ -387,7 +388,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, if (pos + data->sess.dhcomp_len > end) { wpa_printf(MSG_DEBUG, "EAP-EKE: Too short EAP-EKE-Commit"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PROTO_ERROR); } @@ -405,7 +406,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, data->serverid, data->serverid_len, data->peerid, data->peerid_len, key) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive key"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -416,7 +417,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, if (eap_eke_dh_init(data->sess.dhgroup, data->dh_priv, pub) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to initialize DH"); os_memset(key, 0, sizeof(key)); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -424,7 +425,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, { wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive shared secret"); os_memset(key, 0, sizeof(key)); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -433,18 +434,18 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, data->peerid, data->peerid_len) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive Ke/Ki"); os_memset(key, 0, sizeof(key)); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpa_printf(MSG_DEBUG, "EAP-EKE: Sending EAP-EKE-Commit/Response"); - resp = eap_eke_build_msg(data, eap_get_id(reqData), + resp = eap_eke_build_msg(data, id, data->sess.dhcomp_len + data->sess.pnonce_len, EAP_EKE_COMMIT); if (resp == NULL) { os_memset(key, 0, sizeof(key)); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -453,7 +454,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, if (eap_eke_dhcomp(&data->sess, key, pub, rpos) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to build DHComponent_P"); os_memset(key, 0, sizeof(key)); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } os_memset(key, 0, sizeof(key)); @@ -463,7 +464,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, if (random_get_bytes(data->nonce_p, data->sess.nonce_len)) { wpabuf_free(resp); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Nonce_P", @@ -472,7 +473,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, if (eap_eke_prot(&data->sess, data->nonce_p, data->sess.nonce_len, wpabuf_put(resp, 0), &prot_len) < 0) { wpabuf_free(resp); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpa_hexdump(MSG_DEBUG, "EAP-EKE: PNonce_P", @@ -484,7 +485,7 @@ static struct wpabuf * eap_eke_process_commit(struct eap_sm *sm, if (wpabuf_resize(&data->msgs, wpabuf_len(reqData) + wpabuf_len(resp)) < 0) { wpabuf_free(resp); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpabuf_put_buf(data->msgs, reqData); @@ -509,11 +510,12 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data, u8 auth_s[EAP_EKE_MAX_HASH_LEN]; size_t decrypt_len; u8 *auth; + u8 id = eap_get_id(reqData); if (data->state != CONFIRM) { wpa_printf(MSG_DEBUG, "EAP-EKE: EAP-EKE-Confirm/Request received in unexpected state (%d)", data->state); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PROTO_ERROR); } @@ -524,7 +526,7 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data, if (pos + data->sess.pnonce_ps_len + data->sess.prf_len > end) { wpa_printf(MSG_DEBUG, "EAP-EKE: Too short EAP-EKE-Confirm"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PROTO_ERROR); } @@ -532,19 +534,19 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data, if (eap_eke_decrypt_prot(&data->sess, pos, data->sess.pnonce_ps_len, nonces, &decrypt_len) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to decrypt PNonce_PS"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_AUTHENTICATION_FAIL); } if (decrypt_len != (size_t) 2 * data->sess.nonce_len) { wpa_printf(MSG_INFO, "EAP-EKE: PNonce_PS protected data length does not match length of Nonce_P and Nonce_S"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_AUTHENTICATION_FAIL); } wpa_hexdump_key(MSG_DEBUG, "EAP-EKE: Received Nonce_P | Nonce_S", nonces, 2 * data->sess.nonce_len); if (os_memcmp(data->nonce_p, nonces, data->sess.nonce_len) != 0) { wpa_printf(MSG_INFO, "EAP-EKE: Received Nonce_P does not match transmitted Nonce_P"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_AUTHENTICATION_FAIL); } @@ -556,30 +558,30 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data, if (eap_eke_derive_ka(&data->sess, data->serverid, data->serverid_len, data->peerid, data->peerid_len, data->nonce_p, data->nonce_s) < 0) { - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } if (eap_eke_auth(&data->sess, "EAP-EKE server", data->msgs, auth_s) < 0) { - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_S", auth_s, data->sess.prf_len); if (os_memcmp_const(auth_s, pos + data->sess.pnonce_ps_len, data->sess.prf_len) != 0) { wpa_printf(MSG_INFO, "EAP-EKE: Auth_S does not match"); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_AUTHENTICATION_FAIL); } wpa_printf(MSG_DEBUG, "EAP-EKE: Sending EAP-EKE-Confirm/Response"); - resp = eap_eke_build_msg(data, eap_get_id(reqData), + resp = eap_eke_build_msg(data, id, data->sess.pnonce_len + data->sess.prf_len, EAP_EKE_CONFIRM); if (resp == NULL) { - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -587,7 +589,7 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data, if (eap_eke_prot(&data->sess, data->nonce_s, data->sess.nonce_len, wpabuf_put(resp, 0), &prot_len) < 0) { wpabuf_free(resp); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpabuf_put(resp, prot_len); @@ -595,7 +597,7 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data, auth = wpabuf_put(resp, data->sess.prf_len); if (eap_eke_auth(&data->sess, "EAP-EKE peer", data->msgs, auth) < 0) { wpabuf_free(resp); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } wpa_hexdump(MSG_DEBUG, "EAP-EKE: Auth_P", auth, data->sess.prf_len); @@ -606,7 +608,7 @@ static struct wpabuf * eap_eke_process_confirm(struct eap_eke_data *data, data->msk, data->emsk) < 0) { wpa_printf(MSG_INFO, "EAP-EKE: Failed to derive MSK/EMSK"); wpabuf_free(resp); - return eap_eke_build_fail(data, ret, reqData, + return eap_eke_build_fail(data, ret, id, EAP_EKE_FAIL_PRIVATE_INTERNAL_ERROR); } @@ -638,7 +640,8 @@ static struct wpabuf * eap_eke_process_failure(struct eap_eke_data *data, wpa_printf(MSG_INFO, "EAP-EKE: Failure-Code 0x%x", code); } - return eap_eke_build_fail(data, ret, reqData, EAP_EKE_FAIL_NO_ERROR); + return eap_eke_build_fail(data, ret, eap_get_id(reqData), + EAP_EKE_FAIL_NO_ERROR); } diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c index 68d7fba8..248b57b2 100644 --- a/src/eap_peer/eap_fast.c +++ b/src/eap_peer/eap_fast.c @@ -1172,7 +1172,7 @@ static struct wpabuf * eap_fast_pac_request(void) static int eap_fast_process_decrypted(struct eap_sm *sm, struct eap_fast_data *data, struct eap_method_ret *ret, - const struct eap_hdr *req, + u8 identifier, struct wpabuf *decrypted, struct wpabuf **out_data) { @@ -1184,18 +1184,18 @@ static int eap_fast_process_decrypted(struct eap_sm *sm, return 0; if (resp) return eap_fast_encrypt_response(sm, data, resp, - req->identifier, out_data); + identifier, out_data); if (tlv.result == EAP_TLV_RESULT_FAILURE) { resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0); return eap_fast_encrypt_response(sm, data, resp, - req->identifier, out_data); + identifier, out_data); } if (tlv.iresult == EAP_TLV_RESULT_FAILURE) { resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1); return eap_fast_encrypt_response(sm, data, resp, - req->identifier, out_data); + identifier, out_data); } if (tlv.crypto_binding) { @@ -1277,14 +1277,13 @@ static int eap_fast_process_decrypted(struct eap_sm *sm, resp = wpabuf_alloc(1); } - return eap_fast_encrypt_response(sm, data, resp, req->identifier, + return eap_fast_encrypt_response(sm, data, resp, identifier, out_data); } static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data, - struct eap_method_ret *ret, - const struct eap_hdr *req, + struct eap_method_ret *ret, u8 identifier, const struct wpabuf *in_data, struct wpabuf **out_data) { @@ -1309,7 +1308,7 @@ static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data, /* Received TLS ACK - requesting more fragments */ return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST, data->fast_version, - req->identifier, NULL, out_data); + identifier, NULL, out_data); } res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted); @@ -1328,7 +1327,7 @@ continue_req: return -1; } - res = eap_fast_process_decrypted(sm, data, ret, req, + res = eap_fast_process_decrypted(sm, data, ret, identifier, in_decrypted, out_data); wpabuf_free(in_decrypted); @@ -1340,7 +1339,7 @@ continue_req: static const u8 * eap_fast_get_a_id(const u8 *buf, size_t len, size_t *id_len) { const u8 *a_id; - struct pac_tlv_hdr *hdr; + const struct pac_tlv_hdr *hdr; /* * Parse authority identity (A-ID) from the EAP-FAST/Start. This @@ -1350,13 +1349,13 @@ static const u8 * eap_fast_get_a_id(const u8 *buf, size_t len, size_t *id_len) *id_len = len; if (len > sizeof(*hdr)) { int tlen; - hdr = (struct pac_tlv_hdr *) buf; + hdr = (const struct pac_tlv_hdr *) buf; tlen = be_to_host16(hdr->len); if (be_to_host16(hdr->type) == PAC_TYPE_A_ID && sizeof(*hdr) + tlen <= len) { wpa_printf(MSG_DEBUG, "EAP-FAST: A-ID was in TLV " "(Start)"); - a_id = (u8 *) (hdr + 1); + a_id = (const u8 *) (hdr + 1); *id_len = tlen; } } @@ -1529,6 +1528,7 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv, struct wpabuf *resp; const u8 *pos; struct eap_fast_data *data = priv; + struct wpabuf msg; pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret, reqData, &left, &flags); @@ -1545,13 +1545,13 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv, left = 0; /* A-ID is not used in further packet processing */ } + wpabuf_set(&msg, pos, left); + resp = NULL; if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) && !data->resuming) { /* Process tunneled (encrypted) phase 2 data. */ - struct wpabuf msg; - wpabuf_set(&msg, pos, left); - res = eap_fast_decrypt(sm, data, ret, req, &msg, &resp); + res = eap_fast_decrypt(sm, data, ret, id, &msg, &resp); if (res < 0) { ret->methodState = METHOD_DONE; ret->decision = DECISION_FAIL; @@ -1565,8 +1565,8 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv, /* Continue processing TLS handshake (phase 1). */ res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_FAST, - data->fast_version, id, pos, - left, &resp); + data->fast_version, id, &msg, + &resp); if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { char cipher[80]; @@ -1590,16 +1590,13 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv, } if (res == 2) { - struct wpabuf msg; /* * Application data included in the handshake message. */ wpabuf_free(data->pending_phase2_req); data->pending_phase2_req = resp; resp = NULL; - wpabuf_set(&msg, pos, left); - res = eap_fast_decrypt(sm, data, ret, req, &msg, - &resp); + res = eap_fast_decrypt(sm, data, ret, id, &msg, &resp); } } diff --git a/src/eap_peer/eap_gpsk.c b/src/eap_peer/eap_gpsk.c index c54bf116..902b4ba2 100644 --- a/src/eap_peer/eap_gpsk.c +++ b/src/eap_peer/eap_gpsk.c @@ -274,7 +274,7 @@ static const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm, static struct wpabuf * eap_gpsk_process_gpsk_1(struct eap_sm *sm, struct eap_gpsk_data *data, struct eap_method_ret *ret, - const struct wpabuf *reqData, + u8 identifier, const u8 *payload, size_t payload_len) { @@ -301,7 +301,7 @@ static struct wpabuf * eap_gpsk_process_gpsk_1(struct eap_sm *sm, return NULL; } - resp = eap_gpsk_send_gpsk_2(data, eap_get_id(reqData), + resp = eap_gpsk_send_gpsk_2(data, identifier, csuite_list, csuite_list_len); if (resp == NULL) return NULL; @@ -583,7 +583,7 @@ static const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data, static struct wpabuf * eap_gpsk_process_gpsk_3(struct eap_sm *sm, struct eap_gpsk_data *data, struct eap_method_ret *ret, - const struct wpabuf *reqData, + u8 identifier, const u8 *payload, size_t payload_len) { @@ -615,7 +615,7 @@ static struct wpabuf * eap_gpsk_process_gpsk_3(struct eap_sm *sm, (unsigned long) (end - pos)); } - resp = eap_gpsk_send_gpsk_4(data, eap_get_id(reqData)); + resp = eap_gpsk_send_gpsk_4(data, identifier); if (resp == NULL) return NULL; @@ -670,6 +670,7 @@ static struct wpabuf * eap_gpsk_process(struct eap_sm *sm, void *priv, struct wpabuf *resp; const u8 *pos; size_t len; + u8 opcode, id; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, reqData, &len); if (pos == NULL || len < 1) { @@ -677,25 +678,27 @@ static struct wpabuf * eap_gpsk_process(struct eap_sm *sm, void *priv, return NULL; } - wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode %d", *pos); + id = eap_get_id(reqData); + opcode = *pos++; + len--; + wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode %d", opcode); ret->ignore = FALSE; ret->methodState = METHOD_MAY_CONT; ret->decision = DECISION_FAIL; ret->allowNotifications = FALSE; - switch (*pos) { + switch (opcode) { case EAP_GPSK_OPCODE_GPSK_1: - resp = eap_gpsk_process_gpsk_1(sm, data, ret, reqData, - pos + 1, len - 1); + resp = eap_gpsk_process_gpsk_1(sm, data, ret, id, pos, len); break; case EAP_GPSK_OPCODE_GPSK_3: - resp = eap_gpsk_process_gpsk_3(sm, data, ret, reqData, - pos + 1, len - 1); + resp = eap_gpsk_process_gpsk_3(sm, data, ret, id, pos, len); break; default: - wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignoring message with " - "unknown opcode %d", *pos); + wpa_printf(MSG_DEBUG, + "EAP-GPSK: Ignoring message with unknown opcode %d", + opcode); ret->ignore = TRUE; return NULL; } diff --git a/src/eap_peer/eap_pax.c b/src/eap_peer/eap_pax.c index 6d1ff208..c920bcd3 100644 --- a/src/eap_peer/eap_pax.c +++ b/src/eap_peer/eap_pax.c @@ -333,7 +333,7 @@ static struct wpabuf * eap_pax_process(struct eap_sm *sm, void *priv, u16 flen, mlen; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PAX, reqData, &len); - if (pos == NULL || len < EAP_PAX_ICV_LEN) { + if (pos == NULL || len < sizeof(*req) + EAP_PAX_ICV_LEN) { ret->ignore = TRUE; return NULL; } diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c index 86a18bb8..4f68fcea 100644 --- a/src/eap_peer/eap_peap.c +++ b/src/eap_peer/eap_peap.c @@ -968,6 +968,7 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, struct wpabuf *resp; const u8 *pos; struct eap_peap_data *data = priv; + struct wpabuf msg; pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_PEAP, ret, reqData, &left, &flags); @@ -998,17 +999,17 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, * should always be, anyway */ } + wpabuf_set(&msg, pos, left); + resp = NULL; if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) && !data->resuming) { - struct wpabuf msg; - wpabuf_set(&msg, pos, left); res = eap_peap_decrypt(sm, data, ret, req, &msg, &resp); } else { res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_PEAP, - data->peap_version, id, pos, - left, &resp); + data->peap_version, id, &msg, + &resp); if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { char *label; @@ -1077,14 +1078,12 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, } if (res == 2) { - struct wpabuf msg; /* * Application data included in the handshake message. */ wpabuf_free(data->pending_phase2_req); data->pending_phase2_req = resp; resp = NULL; - wpabuf_set(&msg, pos, left); res = eap_peap_decrypt(sm, data, ret, req, &msg, &resp); } diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c index f2b09266..5a60b3f7 100644 --- a/src/eap_peer/eap_pwd.c +++ b/src/eap_peer/eap_pwd.c @@ -355,6 +355,23 @@ eap_pwd_perform_commit_exchange(struct eap_sm *sm, struct eap_pwd_data *data, BIGNUM *mask = NULL, *x = NULL, *y = NULL, *cofactor = NULL; u16 offset; u8 *ptr, *scalar = NULL, *element = NULL; + size_t prime_len, order_len; + + if (data->state != PWD_Commit_Req) { + ret->ignore = TRUE; + goto fin; + } + + prime_len = BN_num_bytes(data->grp->prime); + order_len = BN_num_bytes(data->grp->order); + + if (payload_len != 2 * prime_len + order_len) { + wpa_printf(MSG_INFO, + "EAP-pwd: Unexpected Commit payload length %u (expected %u)", + (unsigned int) payload_len, + (unsigned int) (2 * prime_len + order_len)); + goto fin; + } if (((data->private_value = BN_new()) == NULL) || ((data->my_element = EC_POINT_new(data->grp->group)) == NULL) || @@ -554,6 +571,18 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data, u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr; int offset; + if (data->state != PWD_Confirm_Req) { + ret->ignore = TRUE; + goto fin; + } + + if (payload_len != SHA256_MAC_LEN) { + wpa_printf(MSG_INFO, + "EAP-pwd: Unexpected Confirm payload length %u (expected %u)", + (unsigned int) payload_len, SHA256_MAC_LEN); + goto fin; + } + /* * first build up the ciphersuite which is group | random_function | * prf @@ -837,17 +866,30 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, * if it's the first fragment there'll be a length field */ if (EAP_PWD_GET_LENGTH_BIT(lm_exch)) { + if (len < 2) { + wpa_printf(MSG_DEBUG, + "EAP-pwd: Frame too short to contain Total-Length field"); + ret->ignore = TRUE; + return NULL; + } tot_len = WPA_GET_BE16(pos); wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments whose " "total length = %d", tot_len); if (tot_len > 15000) return NULL; + if (data->inbuf) { + wpa_printf(MSG_DEBUG, + "EAP-pwd: Unexpected new fragment start when previous fragment is still in use"); + ret->ignore = TRUE; + return NULL; + } data->inbuf = wpabuf_alloc(tot_len); if (data->inbuf == NULL) { wpa_printf(MSG_INFO, "Out of memory to buffer " "fragments!"); return NULL; } + data->in_frag_pos = 0; pos += sizeof(u16); len -= sizeof(u16); } @@ -927,6 +969,7 @@ eap_pwd_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, /* * we have output! Do we need to fragment it? */ + lm_exch = EAP_PWD_GET_EXCHANGE(lm_exch); len = wpabuf_len(data->outbuf); if ((len + EAP_PWD_HDR_SIZE) > data->mtu) { resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, data->mtu, diff --git a/src/eap_peer/eap_sake.c b/src/eap_peer/eap_sake.c index 7d149074..c4f9843f 100644 --- a/src/eap_peer/eap_sake.c +++ b/src/eap_peer/eap_sake.c @@ -141,7 +141,7 @@ static struct wpabuf * eap_sake_build_msg(struct eap_sake_data *data, static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm, struct eap_sake_data *data, struct eap_method_ret *ret, - const struct wpabuf *reqData, + u8 id, const u8 *payload, size_t payload_len) { @@ -166,8 +166,7 @@ static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm, wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Identity"); - resp = eap_sake_build_msg(data, eap_get_id(reqData), - 2 + data->peerid_len, + resp = eap_sake_build_msg(data, id, 2 + data->peerid_len, EAP_SAKE_SUBTYPE_IDENTITY); if (resp == NULL) return NULL; @@ -185,7 +184,7 @@ static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm, static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm, struct eap_sake_data *data, struct eap_method_ret *ret, - const struct wpabuf *reqData, + u8 id, const u8 *payload, size_t payload_len) { @@ -247,8 +246,7 @@ static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm, rlen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN; if (data->peerid) rlen += 2 + data->peerid_len; - resp = eap_sake_build_msg(data, eap_get_id(reqData), rlen, - EAP_SAKE_SUBTYPE_CHALLENGE); + resp = eap_sake_build_msg(data, id, rlen, EAP_SAKE_SUBTYPE_CHALLENGE); if (resp == NULL) return NULL; @@ -285,6 +283,7 @@ static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm, static struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm, struct eap_sake_data *data, struct eap_method_ret *ret, + u8 id, const struct wpabuf *reqData, const u8 *payload, size_t payload_len) @@ -323,14 +322,13 @@ static struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm, ret->allowNotifications = FALSE; wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending " "Response/Auth-Reject"); - return eap_sake_build_msg(data, eap_get_id(reqData), 0, + return eap_sake_build_msg(data, id, 0, EAP_SAKE_SUBTYPE_AUTH_REJECT); } wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Confirm"); - resp = eap_sake_build_msg(data, eap_get_id(reqData), - 2 + EAP_SAKE_MIC_LEN, + resp = eap_sake_build_msg(data, id, 2 + EAP_SAKE_MIC_LEN, EAP_SAKE_SUBTYPE_CONFIRM); if (resp == NULL) return NULL; @@ -367,7 +365,7 @@ static struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv, struct wpabuf *resp; const u8 *pos, *end; size_t len; - u8 subtype, session_id; + u8 subtype, session_id, id; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, reqData, &len); if (pos == NULL || len < sizeof(struct eap_sake_hdr)) { @@ -377,6 +375,7 @@ static struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv, req = (const struct eap_sake_hdr *) pos; end = pos + len; + id = eap_get_id(reqData); subtype = req->subtype; session_id = req->session_id; pos = (const u8 *) (req + 1); @@ -402,15 +401,15 @@ static struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv, switch (subtype) { case EAP_SAKE_SUBTYPE_IDENTITY: - resp = eap_sake_process_identity(sm, data, ret, reqData, + resp = eap_sake_process_identity(sm, data, ret, id, pos, end - pos); break; case EAP_SAKE_SUBTYPE_CHALLENGE: - resp = eap_sake_process_challenge(sm, data, ret, reqData, + resp = eap_sake_process_challenge(sm, data, ret, id, pos, end - pos); break; case EAP_SAKE_SUBTYPE_CONFIRM: - resp = eap_sake_process_confirm(sm, data, ret, reqData, + resp = eap_sake_process_confirm(sm, data, ret, id, reqData, pos, end - pos); break; default: diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c index bd06df78..99a2816c 100644 --- a/src/eap_peer/eap_sim.c +++ b/src/eap_peer/eap_sim.c @@ -1042,7 +1042,7 @@ static struct wpabuf * eap_sim_process(struct eap_sm *sm, void *priv, } pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, reqData, &len); - if (pos == NULL || len < 1) { + if (pos == NULL || len < 3) { ret->ignore = TRUE; return NULL; } diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c index 5aa3fd59..d81b1cf1 100644 --- a/src/eap_peer/eap_tls.c +++ b/src/eap_peer/eap_tls.c @@ -228,6 +228,7 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, u8 flags, id; const u8 *pos; struct eap_tls_data *data = priv; + struct wpabuf msg; pos = eap_peer_tls_process_init(sm, &data->ssl, data->eap_type, ret, reqData, &left, &flags); @@ -242,8 +243,9 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, } resp = NULL; + wpabuf_set(&msg, pos, left); res = eap_peer_tls_process_helper(sm, &data->ssl, data->eap_type, 0, - id, pos, left, &resp); + id, &msg, &resp); if (res < 0) { return eap_tls_failure(sm, data, ret, res, resp, id); diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c index b4a5b1f3..fef7fdb8 100644 --- a/src/eap_peer/eap_tls_common.c +++ b/src/eap_peer/eap_tls_common.c @@ -477,22 +477,19 @@ static const struct wpabuf * eap_peer_tls_data_reassemble( * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * @data: Data for TLS processing * @in_data: Message received from the server - * @in_len: Length of in_data * @out_data: Buffer for returning a pointer to application data (if available) * Returns: 0 on success, 1 if more input data is needed, 2 if application data * is available, -1 on failure */ static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data, - const u8 *in_data, size_t in_len, + const struct wpabuf *in_data, struct wpabuf **out_data) { const struct wpabuf *msg; int need_more_input; struct wpabuf *appl_data; - struct wpabuf buf; - wpabuf_set(&buf, in_data, in_len); - msg = eap_peer_tls_data_reassemble(data, &buf, &need_more_input); + msg = eap_peer_tls_data_reassemble(data, in_data, &need_more_input); if (msg == NULL) return need_more_input ? 1 : -1; @@ -612,7 +609,6 @@ static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type, * @peap_version: Version number for EAP-PEAP/TTLS * @id: EAP identifier for the response * @in_data: Message received from the server - * @in_len: Length of in_data * @out_data: Buffer for returning a pointer to the response message * Returns: 0 on success, 1 if more input data is needed, 2 if application data * is available, or -1 on failure @@ -635,14 +631,15 @@ static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type, */ int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data, EapType eap_type, int peap_version, - u8 id, const u8 *in_data, size_t in_len, + u8 id, const struct wpabuf *in_data, struct wpabuf **out_data) { int ret = 0; *out_data = NULL; - if (data->tls_out && wpabuf_len(data->tls_out) > 0 && in_len > 0) { + if (data->tls_out && wpabuf_len(data->tls_out) > 0 && + wpabuf_len(in_data) > 0) { wpa_printf(MSG_DEBUG, "SSL: Received non-ACK when output " "fragments are waiting to be sent out"); return -1; @@ -653,8 +650,7 @@ int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data, * No more data to send out - expect to receive more data from * the AS. */ - int res = eap_tls_process_input(sm, data, in_data, in_len, - out_data); + int res = eap_tls_process_input(sm, data, in_data, out_data); if (res) { /* * Input processing failed (res = -1) or more data is diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h index 390c2165..acd2b783 100644 --- a/src/eap_peer/eap_tls_common.h +++ b/src/eap_peer/eap_tls_common.h @@ -100,7 +100,7 @@ u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm, size_t *len); int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data, EapType eap_type, int peap_version, - u8 id, const u8 *in_data, size_t in_len, + u8 id, const struct wpabuf *in_data, struct wpabuf **out_data); struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type, int peap_version); diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c index b5c028b5..25e3cbab 100644 --- a/src/eap_peer/eap_ttls.c +++ b/src/eap_peer/eap_ttls.c @@ -1385,14 +1385,14 @@ static int eap_ttls_process_handshake(struct eap_sm *sm, struct eap_ttls_data *data, struct eap_method_ret *ret, u8 identifier, - const u8 *in_data, size_t in_len, + const struct wpabuf *in_data, struct wpabuf **out_data) { int res; res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS, data->ttls_version, identifier, - in_data, in_len, out_data); + in_data, out_data); if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to " @@ -1419,15 +1419,13 @@ static int eap_ttls_process_handshake(struct eap_sm *sm, } if (res == 2) { - struct wpabuf msg; /* * Application data included in the handshake message. */ wpabuf_free(data->pending_phase2_req); data->pending_phase2_req = *out_data; *out_data = NULL; - wpabuf_set(&msg, in_data, in_len); - res = eap_ttls_decrypt(sm, data, ret, identifier, &msg, + res = eap_ttls_decrypt(sm, data, ret, identifier, in_data, out_data); } @@ -1477,6 +1475,7 @@ static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv, struct wpabuf *resp; const u8 *pos; struct eap_ttls_data *data = priv; + struct wpabuf msg; pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret, reqData, &left, &flags); @@ -1497,15 +1496,15 @@ static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv, left = 0; } + wpabuf_set(&msg, pos, left); + resp = NULL; if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) && !data->resuming) { - struct wpabuf msg; - wpabuf_set(&msg, pos, left); res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp); } else { res = eap_ttls_process_handshake(sm, data, ret, id, - pos, left, &resp); + &msg, &resp); } eap_ttls_check_auth_status(sm, data, ret); diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c index 66bd5d2e..cb83ff73 100644 --- a/src/eap_server/eap_server_pwd.c +++ b/src/eap_server/eap_server_pwd.c @@ -656,9 +656,21 @@ eap_pwd_process_commit_resp(struct eap_sm *sm, struct eap_pwd_data *data, BIGNUM *x = NULL, *y = NULL, *cofactor = NULL; EC_POINT *K = NULL, *point = NULL; int res = 0; + size_t prime_len, order_len; wpa_printf(MSG_DEBUG, "EAP-pwd: Received commit response"); + prime_len = BN_num_bytes(data->grp->prime); + order_len = BN_num_bytes(data->grp->order); + + if (payload_len != 2 * prime_len + order_len) { + wpa_printf(MSG_INFO, + "EAP-pwd: Unexpected Commit payload length %u (expected %u)", + (unsigned int) payload_len, + (unsigned int) (2 * prime_len + order_len)); + goto fin; + } + if (((data->peer_scalar = BN_new()) == NULL) || ((data->k = BN_new()) == NULL) || ((cofactor = BN_new()) == NULL) || @@ -774,6 +786,13 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data, u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr; int offset; + if (payload_len != SHA256_MAC_LEN) { + wpa_printf(MSG_INFO, + "EAP-pwd: Unexpected Confirm payload length %u (expected %u)", + (unsigned int) payload_len, SHA256_MAC_LEN); + goto fin; + } + /* build up the ciphersuite: group | random_function | prf */ grp = htons(data->group_num); ptr = (u8 *) &cs; @@ -923,17 +942,28 @@ static void eap_pwd_process(struct eap_sm *sm, void *priv, * the first fragment has a total length */ if (EAP_PWD_GET_LENGTH_BIT(lm_exch)) { + if (len < 2) { + wpa_printf(MSG_DEBUG, + "EAP-pwd: Frame too short to contain Total-Length field"); + return; + } tot_len = WPA_GET_BE16(pos); wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments, total " "length = %d", tot_len); if (tot_len > 15000) return; + if (data->inbuf) { + wpa_printf(MSG_DEBUG, + "EAP-pwd: Unexpected new fragment start when previous fragment is still in use"); + return; + } data->inbuf = wpabuf_alloc(tot_len); if (data->inbuf == NULL) { wpa_printf(MSG_INFO, "EAP-pwd: Out of memory to " "buffer fragments!"); return; } + data->in_frag_pos = 0; pos += sizeof(u16); len -= sizeof(u16); } diff --git a/src/radius/radius.c b/src/radius/radius.c index 906d8c81..1ebfd11f 100644 --- a/src/radius/radius.c +++ b/src/radius/radius.c @@ -1225,7 +1225,7 @@ int radius_msg_add_mppe_keys(struct radius_msg *msg, } /* MS-MPPE-Recv-Key */ - buf = os_malloc(hlen + send_key_len + 16); + buf = os_malloc(hlen + recv_key_len + 16); if (buf == NULL) { return 0; } diff --git a/src/tls/libtommath.c b/src/tls/libtommath.c index 3fb8fbed..251133e7 100644 --- a/src/tls/libtommath.c +++ b/src/tls/libtommath.c @@ -1631,7 +1631,7 @@ static int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) } /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { return res; } diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c index 742af328..b51dfcd4 100644 --- a/src/tls/x509v3.c +++ b/src/tls/x509v3.c @@ -1511,7 +1511,7 @@ struct x509_certificate * x509_certificate_parse(const u8 *buf, size_t len) if (pos + hdr.length < end) { wpa_hexdump(MSG_MSGDUMP, "X509: Ignoring extra data after DER " "encoded certificate", - pos + hdr.length, end - pos + hdr.length); + pos + hdr.length, end - (pos + hdr.length)); end = pos + hdr.length; } diff --git a/src/wps/httpread.c b/src/wps/httpread.c index 2f08f372..180b572c 100644 --- a/src/wps/httpread.c +++ b/src/wps/httpread.c @@ -44,16 +44,6 @@ #define HTTPREAD_HEADER_MAX_SIZE 4096 /* max allowed for headers */ #define HTTPREAD_BODYBUF_DELTA 4096 /* increase allocation by this */ -#if 0 -/* httpread_debug -- set this global variable > 0 e.g. from debugger - * to enable debugs (larger numbers for more debugs) - * Make this a #define of 0 to eliminate the debugging code. - */ -int httpread_debug = 99; -#else -#define httpread_debug 0 /* eliminates even the debugging code */ -#endif - /* control instance -- actual definition (opaque to application) */ @@ -136,8 +126,7 @@ static void httpread_timeout_handler(void *eloop_data, void *user_ctx); */ void httpread_destroy(struct httpread *h) { - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, "ENTER httpread_destroy(%p)", h); + wpa_printf(MSG_DEBUG, "httpread_destroy(%p)", h); if (!h) return; @@ -177,6 +166,12 @@ static int httpread_hdr_option_analyze( if (!isdigit(*hbp)) return -1; h->content_length = atol(hbp); + if (h->content_length < 0 || h->content_length > h->max_bytes) { + wpa_printf(MSG_DEBUG, + "httpread: Unacceptable Content-Length %d", + h->content_length); + return -1; + } h->got_content_length = 1; return 0; } @@ -380,15 +375,16 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) char *bbp; /* pointer into body buffer */ char readbuf[HTTPREAD_READBUF_SIZE]; /* temp use to read into */ - if (httpread_debug >= 20) - wpa_printf(MSG_DEBUG, "ENTER httpread_read_handler(%p)", h); - /* read some at a time, then search for the interal * boundaries between header and data and etc. */ + wpa_printf(MSG_DEBUG, "httpread: Trying to read more data(%p)", h); nread = read(h->sd, readbuf, sizeof(readbuf)); - if (nread < 0) + if (nread < 0) { + wpa_printf(MSG_DEBUG, "httpread failed: %s", strerror(errno)); goto bad; + } + wpa_hexdump_ascii(MSG_MSGDUMP, "httpread - read", readbuf, nread); if (nread == 0) { /* end of transmission... this may be normal * or may be an error... in some cases we can't @@ -411,8 +407,7 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) * although dropped connections can cause false * end */ - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, "httpread ok eof(%p)", h); + wpa_printf(MSG_DEBUG, "httpread ok eof(%p)", h); h->got_body = 1; goto got_file; } @@ -432,6 +427,8 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) if (nread == 0) goto get_more; if (h->hdr_nbytes == HTTPREAD_HEADER_MAX_SIZE) { + wpa_printf(MSG_DEBUG, + "httpread: Too long header"); goto bad; } *hbp++ = *rbp++; @@ -453,16 +450,13 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) goto bad; } if (h->max_bytes == 0) { - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, - "httpread no body hdr end(%p)", h); + wpa_printf(MSG_DEBUG, "httpread no body hdr end(%p)", + h); goto got_file; } if (h->got_content_length && h->content_length == 0) { - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, - "httpread zero content length(%p)", - h); + wpa_printf(MSG_DEBUG, + "httpread zero content length(%p)", h); goto got_file; } } @@ -475,9 +469,7 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) !os_strncasecmp(h->hdr, "HEAD", 4) || !os_strncasecmp(h->hdr, "GET", 3)) { if (!h->got_body) { - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, - "httpread NO BODY for sp. type"); + wpa_printf(MSG_DEBUG, "httpread NO BODY for sp. type"); } h->got_body = 1; goto got_file; @@ -498,8 +490,12 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) char *new_body; int new_alloc_nbytes; - if (h->body_nbytes >= h->max_bytes) + if (h->body_nbytes >= h->max_bytes) { + wpa_printf(MSG_DEBUG, + "httpread: body_nbytes=%d >= max_bytes=%d", + h->body_nbytes, h->max_bytes); goto bad; + } new_alloc_nbytes = h->body_alloc_nbytes + HTTPREAD_BODYBUF_DELTA; /* For content-length case, the first time @@ -509,9 +505,20 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) if (h->got_content_length && new_alloc_nbytes < (h->content_length + 1)) new_alloc_nbytes = h->content_length + 1; + if (new_alloc_nbytes < h->body_alloc_nbytes || + new_alloc_nbytes > h->max_bytes) { + wpa_printf(MSG_DEBUG, + "httpread: Unacceptable body length %d", + new_alloc_nbytes); + goto bad; + } if ((new_body = os_realloc(h->body, new_alloc_nbytes)) - == NULL) + == NULL) { + wpa_printf(MSG_DEBUG, + "httpread: Failed to reallocate buffer (len=%d)", + new_alloc_nbytes); goto bad; + } h->body = new_body; h->body_alloc_nbytes = new_alloc_nbytes; @@ -530,9 +537,19 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) /* hdr line consists solely * of a hex numeral and CFLF */ - if (!isxdigit(*cbp)) + if (!isxdigit(*cbp)) { + wpa_printf(MSG_DEBUG, + "httpread: Unexpected chunk header value (not a hex digit)"); goto bad; + } h->chunk_size = strtoul(cbp, NULL, 16); + if (h->chunk_size < 0 || + h->chunk_size > h->max_bytes) { + wpa_printf(MSG_DEBUG, + "httpread: Invalid chunk size %d", + h->chunk_size); + goto bad; + } /* throw away chunk header * so we have only real data */ @@ -542,10 +559,9 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) /* end of chunking */ /* trailer follows */ h->in_trailer = 1; - if (httpread_debug >= 20) - wpa_printf( - MSG_DEBUG, - "httpread end chunks(%p)", h); + wpa_printf(MSG_DEBUG, + "httpread end chunks(%p)", + h); break; } h->in_chunk_data = 1; @@ -563,8 +579,11 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) */ if (bbp[-1] == '\n' && bbp[-2] == '\r') { - } else + } else { + wpa_printf(MSG_DEBUG, + "httpread: Invalid chunk end"); goto bad; + } h->body_nbytes -= 2; bbp -= 2; h->chunk_start = h->body_nbytes; @@ -574,10 +593,8 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) } else if (h->got_content_length && h->body_nbytes >= h->content_length) { h->got_body = 1; - if (httpread_debug >= 10) - wpa_printf( - MSG_DEBUG, - "httpread got content(%p)", h); + wpa_printf(MSG_DEBUG, + "httpread got content(%p)", h); goto got_file; } if (nread <= 0) @@ -601,6 +618,11 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) ncopy = nread; } /* Note: should never be 0 */ + if (ncopy < 0) { + wpa_printf(MSG_DEBUG, + "httpread: Invalid ncopy=%d", ncopy); + goto bad; + } if (ncopy > nread) ncopy = nread; os_memcpy(bbp, rbp, ncopy); @@ -635,10 +657,9 @@ static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx) if (c == '\n') { h->trailer_state = trailer_line_begin; h->in_trailer = 0; - if (httpread_debug >= 10) - wpa_printf( - MSG_DEBUG, - "httpread got content(%p)", h); + wpa_printf(MSG_DEBUG, + "httpread got content(%p)", + h); h->got_body = 1; goto got_file; } @@ -666,13 +687,14 @@ bad: return; get_more: + wpa_printf(MSG_DEBUG, "httpread: get more (%p)", h); return; got_file: - if (httpread_debug >= 10) - wpa_printf(MSG_DEBUG, - "httpread got file %d bytes type %d", - h->body_nbytes, h->hdr_type); + wpa_printf(MSG_DEBUG, "httpread got file %d bytes type %d", + h->body_nbytes, h->hdr_type); + wpa_hexdump_ascii(MSG_MSGDUMP, "httpread: body", + h->body, h->body_nbytes); /* Null terminate for convenience of some applications */ if (h->body) h->body[h->body_nbytes] = 0; /* null terminate */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 91617fb2..4aa602d6 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -760,6 +760,33 @@ static int wpa_supplicant_ctrl_iface_tdls_cancel_chan_switch( return wpa_tdls_disable_chan_switch(wpa_s->wpa, peer); } + +static int wpa_supplicant_ctrl_iface_tdls_link_status( + struct wpa_supplicant *wpa_s, const char *addr, + char *buf, size_t buflen) +{ + u8 peer[ETH_ALEN]; + const char *tdls_status; + int ret; + + if (hwaddr_aton(addr, peer)) { + wpa_printf(MSG_DEBUG, + "CTRL_IFACE TDLS_LINK_STATUS: Invalid address '%s'", + addr); + return -1; + } + wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_LINK_STATUS " MACSTR, + MAC2STR(peer)); + + tdls_status = wpa_tdls_get_link_status(wpa_s->wpa, peer); + wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_LINK_STATUS: %s", tdls_status); + ret = os_snprintf(buf, buflen, "TDLS link status: %s\n", tdls_status); + if (os_snprintf_error(buflen, ret)) + return -1; + + return ret; +} + #endif /* CONFIG_TDLS */ @@ -8415,6 +8442,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (wpa_supplicant_ctrl_iface_tdls_cancel_chan_switch(wpa_s, buf + 24)) reply_len = -1; + } else if (os_strncmp(buf, "TDLS_LINK_STATUS ", 17) == 0) { + reply_len = wpa_supplicant_ctrl_iface_tdls_link_status( + wpa_s, buf + 17, reply, reply_size); #endif /* CONFIG_TDLS */ } else if (os_strcmp(buf, "WMM_AC_STATUS") == 0) { reply_len = wpas_wmm_ac_status(wpa_s, reply, reply_size); diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 30ef03a7..89a562c1 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -137,7 +137,7 @@ static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH, @@ -200,7 +200,7 @@ void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success) iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -239,7 +239,7 @@ static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -307,7 +307,7 @@ static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -374,7 +374,7 @@ static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, @@ -467,7 +467,7 @@ void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt); @@ -511,6 +511,8 @@ void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s, char path[WPAS_DBUS_OBJECT_PATH_MAX]; + if (!wpa_s->dbus_new_path) + return; os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d", wpa_s->dbus_new_path, ssid->id); @@ -539,7 +541,7 @@ void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s) iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -579,7 +581,7 @@ void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -620,7 +622,7 @@ void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -686,7 +688,7 @@ void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -760,7 +762,7 @@ void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -801,7 +803,7 @@ void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -844,7 +846,7 @@ static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, @@ -916,7 +918,8 @@ void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s, if (parent->p2p_mgmt) parent = parent->parent; - if (!wpa_s->dbus_groupobj_path) + if (!wpa_s->dbus_groupobj_path || !wpa_s->dbus_new_path || + !parent->dbus_new_path) return; msg = dbus_message_new_signal(parent->dbus_new_path, @@ -984,6 +987,8 @@ void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s, if (wpa_s->p2p_mgmt) wpa_s = wpa_s->parent; + if (!wpa_s->dbus_new_path) + return; if (request || !status) { if (config_methods & WPS_CONFIG_DISPLAY) @@ -1073,6 +1078,8 @@ void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s, if (wpa_s->p2p_mgmt) wpa_s = wpa_s->parent; + if (!wpa_s->dbus_new_path) + return; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, @@ -1105,7 +1112,8 @@ static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s, { char group_name[3]; - if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)) + if (!wpa_s->dbus_new_path || + os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN)) return -1; os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2); @@ -1209,7 +1217,7 @@ void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s, iface = parent->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !parent->dbus_new_path || !wpa_s->dbus_new_path) return; if (wpa_s->dbus_groupobj_path == NULL) @@ -1272,7 +1280,7 @@ void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, os_memset(freqs, 0, sizeof(freqs)); /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, @@ -1386,6 +1394,8 @@ void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s, if (wpa_s->p2p_mgmt) wpa_s = wpa_s->parent; + if (!wpa_s->dbus_new_path) + return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, WPAS_DBUS_NEW_IFACE_P2PDEVICE, @@ -1439,6 +1449,8 @@ void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s, parent = wpa_s->parent; if (parent->p2p_mgmt) parent = parent->parent; + if (!parent->dbus_new_path) + return; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" @@ -1494,6 +1506,8 @@ void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s, parent = wpa_s->parent; if (parent->p2p_mgmt) parent = parent->parent; + if (!parent->dbus_new_path) + return; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" @@ -1551,6 +1565,8 @@ void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s, if (wpa_s->p2p_mgmt) wpa_s = wpa_s->parent; + if (!wpa_s->dbus_new_path) + return; /* Check if this is a known peer */ if (!p2p_peer_known(wpa_s->global->p2p, sa)) @@ -1617,6 +1633,8 @@ void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s, if (wpa_s->p2p_mgmt) wpa_s = wpa_s->parent; + if (!wpa_s->dbus_new_path) + return; /* Check if this is a known peer */ if (!p2p_peer_known(wpa_s->global->p2p, sa)) @@ -1678,6 +1696,8 @@ static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s, if (wpa_s->p2p_mgmt) wpa_s = wpa_s->parent; + if (!wpa_s->dbus_new_path) + return; os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u", @@ -1762,6 +1782,8 @@ void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s, if (wpa_s->p2p_mgmt) wpa_s = wpa_s->parent; + if (!wpa_s->dbus_new_path) + return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, WPAS_DBUS_NEW_IFACE_P2PDEVICE, "WpsFailed"); @@ -1862,6 +1884,9 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s, char path[WPAS_DBUS_OBJECT_PATH_MAX]; char *prop; + if (!wpa_s->dbus_new_path) + return; + switch (property) { case WPAS_DBUS_BSS_PROP_SIGNAL: prop = "Signal"; @@ -2177,7 +2202,7 @@ int wpas_dbus_register_network(struct wpa_supplicant *wpa_s, #endif /* CONFIG_P2P */ /* Do nothing if the control interface is not turned on */ - if (wpa_s == NULL || wpa_s->global == NULL) + if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path) return 0; ctrl_iface = wpa_s->global->dbus; if (ctrl_iface == NULL) @@ -2351,7 +2376,7 @@ int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s, char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX]; /* Do nothing if the control interface is not turned on */ - if (wpa_s == NULL || wpa_s->global == NULL) + if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path) return 0; ctrl_iface = wpa_s->global->dbus; if (ctrl_iface == NULL) @@ -2394,7 +2419,7 @@ int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s, struct bss_handler_args *arg; /* Do nothing if the control interface is not turned on */ - if (wpa_s == NULL || wpa_s->global == NULL) + if (wpa_s == NULL || wpa_s->global == NULL || !wpa_s->dbus_new_path) return 0; ctrl_iface = wpa_s->global->dbus; if (ctrl_iface == NULL) @@ -3345,7 +3370,7 @@ static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s, iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_new_path) return; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, @@ -3422,8 +3447,9 @@ int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr) if (ctrl_iface == NULL) return 0; - if (wpa_s->p2p_mgmt) - wpa_s = wpa_s->parent; + wpa_s = wpa_s->parent->parent; + if (!wpa_s->dbus_new_path) + return 0; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, @@ -3481,12 +3507,12 @@ int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s, int ret; /* Do nothing if the control interface is not turned on */ - if (wpa_s == NULL || wpa_s->global == NULL || - wpa_s->dbus_new_path == NULL) + if (wpa_s == NULL || wpa_s->global == NULL) return 0; - if (wpa_s->p2p_mgmt) - wpa_s = wpa_s->parent; + wpa_s = wpa_s->parent->parent; + if (!wpa_s->dbus_new_path) + return 0; ctrl_iface = wpa_s->global->dbus; if (ctrl_iface == NULL) @@ -3512,6 +3538,8 @@ void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s, if (wpa_s->p2p_mgmt) wpa_s = wpa_s->parent; + if (!wpa_s->dbus_new_path) + return; os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(dev_addr)); @@ -3713,6 +3741,9 @@ int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s, /* Do nothing if the control interface is not turned on */ if (wpa_s == NULL || wpa_s->global == NULL) return 0; + wpa_s = wpa_s->parent->parent; + if (!wpa_s->dbus_new_path) + return 0; /* Make sure ssid is a persistent group */ if (ssid->disabled != 2 && !ssid->p2p_persistent_group) @@ -3797,15 +3828,13 @@ int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s, int ret; /* Do nothing if the control interface is not turned on */ - if (wpa_s == NULL || wpa_s->global == NULL || - wpa_s->dbus_new_path == NULL) + if (wpa_s == NULL || wpa_s->global == NULL) return 0; - if (wpa_s->p2p_mgmt) - wpa_s = wpa_s->parent; + wpa_s = wpa_s->parent->parent; ctrl_iface = wpa_s->global->dbus; - if (ctrl_iface == NULL) + if (ctrl_iface == NULL || !wpa_s->dbus_new_path) return 0; os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index d695d1bc..97db9a87 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -157,7 +157,8 @@ static struct wpa_supplicant * get_iface_by_dbus_path( struct wpa_supplicant *wpa_s; for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { - if (os_strcmp(wpa_s->dbus_new_path, path) == 0) + if (wpa_s->dbus_new_path && + os_strcmp(wpa_s->dbus_new_path, path) == 0) return wpa_s; } return NULL; @@ -600,7 +601,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, iface.bridge_ifname = bridge_ifname; /* Otherwise, have wpa_supplicant attach to it. */ wpa_s = wpa_supplicant_add_iface(global, &iface, NULL); - if (wpa_s) { + if (wpa_s && wpa_s->dbus_new_path) { const char *path = wpa_s->dbus_new_path; reply = dbus_message_new_method_return(message); @@ -684,7 +685,7 @@ DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message, DBUS_TYPE_INVALID); wpa_s = wpa_supplicant_get_iface(global, ifname); - if (wpa_s == NULL) + if (wpa_s == NULL || wpa_s->dbus_new_path == NULL) return wpas_dbus_error_iface_unknown(message); path = wpa_s->dbus_new_path; @@ -876,8 +877,10 @@ dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, unsigned int i = 0, num = 0; dbus_bool_t success; - for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) - num++; + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { + if (wpa_s->dbus_new_path) + num++; + } paths = os_calloc(num, sizeof(char *)); if (!paths) { @@ -885,8 +888,10 @@ dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter, return FALSE; } - for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) - paths[i++] = wpa_s->dbus_new_path; + for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { + if (wpa_s->dbus_new_path) + paths[i++] = wpa_s->dbus_new_path; + } success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_OBJECT_PATH, @@ -1327,14 +1332,25 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, message, "You can specify only Channels in passive scan"); goto out; - } else if (params.freqs && params.freqs[0]) { - if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) { - reply = wpas_dbus_error_scan_error( - message, "Scan request rejected"); - } } else { - wpa_s->scan_req = MANUAL_SCAN_REQ; - wpa_supplicant_req_scan(wpa_s, 0, 0); + if (wpa_s->sched_scanning) { + wpa_printf(MSG_DEBUG, + "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed", + __func__); + wpa_supplicant_cancel_sched_scan(wpa_s); + } + + if (params.freqs && params.freqs[0]) { + if (wpa_supplicant_trigger_scan(wpa_s, + ¶ms)) { + reply = wpas_dbus_error_scan_error( + message, + "Scan request rejected"); + } + } else { + wpa_s->scan_req = MANUAL_SCAN_REQ; + wpa_supplicant_req_scan(wpa_s, 0, 0); + } } } else if (os_strcmp(type, "active") == 0) { if (!params.num_ssids) { @@ -1344,6 +1360,13 @@ DBusMessage * wpas_dbus_handler_scan(DBusMessage *message, #ifdef CONFIG_AUTOSCAN autoscan_deinit(wpa_s); #endif /* CONFIG_AUTOSCAN */ + if (wpa_s->sched_scanning) { + wpa_printf(MSG_DEBUG, + "%s[dbus]: Stop ongoing sched_scan to allow requested scan to proceed", + __func__); + wpa_supplicant_cancel_sched_scan(wpa_s); + } + if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) { reply = wpas_dbus_error_scan_error( message, "Scan request rejected"); @@ -1478,7 +1501,8 @@ DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message, dbus_message_iter_init(message, &iter); - ssid = wpa_config_add_network(wpa_s->conf); + if (wpa_s->dbus_new_path) + ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) { wpa_printf(MSG_ERROR, "%s[dbus]: can't add new interface.", __func__); @@ -1602,7 +1626,7 @@ DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message, iface = wpas_dbus_new_decompose_object_path(op, WPAS_DBUS_NEW_NETWORKS_PART, &net_id); - if (iface == NULL || net_id == NULL || + if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, op); goto out; @@ -1715,7 +1739,7 @@ DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message, iface = wpas_dbus_new_decompose_object_path(op, WPAS_DBUS_NEW_NETWORKS_PART, &net_id); - if (iface == NULL || net_id == NULL || + if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, op); goto out; @@ -1773,7 +1797,7 @@ DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message, iface = wpas_dbus_new_decompose_object_path(op, WPAS_DBUS_NEW_NETWORKS_PART, &net_id); - if (iface == NULL || net_id == NULL || + if (iface == NULL || net_id == NULL || !wpa_s->dbus_new_path || os_strcmp(iface, wpa_s->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, op); goto out; @@ -2266,12 +2290,14 @@ DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path( message, DBUS_ERROR_FAILED, "Reinit of the EAPOL state machine with the new PKCS #11 engine and module path failed."); - wpa_dbus_mark_property_changed( - wpa_s->global->dbus, wpa_s->dbus_new_path, - WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11EnginePath"); - wpa_dbus_mark_property_changed( - wpa_s->global->dbus, wpa_s->dbus_new_path, - WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11ModulePath"); + if (wpa_s->dbus_new_path) { + wpa_dbus_mark_property_changed( + wpa_s->global->dbus, wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11EnginePath"); + wpa_dbus_mark_property_changed( + wpa_s->global->dbus, wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11ModulePath"); + } return NULL; } @@ -3024,7 +3050,7 @@ dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter, struct wpa_supplicant *wpa_s = user_data; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf; - if (wpa_s->current_bss) + if (wpa_s->current_bss && wpa_s->dbus_new_path) os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u", wpa_s->dbus_new_path, wpa_s->current_bss->id); @@ -3052,7 +3078,7 @@ dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter, struct wpa_supplicant *wpa_s = user_data; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf; - if (wpa_s->current_ssid) + if (wpa_s->current_ssid && wpa_s->dbus_new_path) os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", wpa_s->dbus_new_path, wpa_s->current_ssid->id); @@ -3140,6 +3166,12 @@ dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error, unsigned int i = 0; dbus_bool_t success = FALSE; + if (!wpa_s->dbus_new_path) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: no D-Bus interface", __func__); + return FALSE; + } + paths = os_calloc(wpa_s->num_bss, sizeof(char *)); if (!paths) { dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory"); @@ -3191,6 +3223,12 @@ dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error, unsigned int i = 0, num = 0; dbus_bool_t success = FALSE; + if (!wpa_s->dbus_new_path) { + dbus_set_error(error, DBUS_ERROR_FAILED, + "%s: no D-Bus interface", __func__); + return FALSE; + } + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) if (!network_is_persistent_group(ssid)) num++; @@ -4104,7 +4142,7 @@ void wpas_dbus_signal_preq(struct wpa_supplicant *wpa_s, struct wpas_dbus_priv *priv = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ - if (priv == NULL) + if (priv == NULL || !wpa_s->dbus_new_path) return; if (wpa_s->preq_notify_peer == NULL) diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index 0eff7638..32f0a353 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -354,7 +354,8 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, pg_object_path, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART, &net_id_str); if (iface == NULL || net_id_str == NULL || - os_strcmp(iface, wpa_s->dbus_new_path) != 0) { + !wpa_s->parent->dbus_new_path || + os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, pg_object_path); @@ -649,7 +650,8 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART, &net_id_str); if (iface == NULL || net_id_str == NULL || - os_strcmp(iface, wpa_s->dbus_new_path) != 0) { + !wpa_s->parent->dbus_new_path || + os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, pg_object_path); goto out; @@ -1043,7 +1045,8 @@ dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error, char **peer_obj_paths = NULL; - if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error)) + if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error) || + !wpa_s->parent->parent->dbus_new_path) return FALSE; dl_list_init(&peer_objpath_list); @@ -1064,7 +1067,8 @@ dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error, os_snprintf(node->path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, - wpa_s->dbus_new_path, MAC2STR(addr)); + wpa_s->parent->parent->dbus_new_path, + MAC2STR(addr)); dl_list_add_tail(&peer_objpath_list, &node->list); num++; @@ -1184,13 +1188,17 @@ dbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter, struct wpa_supplicant *wpa_s = user_data; char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path; + if (!wpa_s->parent->parent->dbus_new_path) + return FALSE; + if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT) os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/"); else os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, - wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr)); + wpa_s->parent->parent->dbus_new_path, + MAC2STR(wpa_s->go_dev_addr)); path = go_peer_obj_path; return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH, @@ -1636,6 +1644,11 @@ dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter, unsigned int i = 0, num = 0; dbus_bool_t success = FALSE; + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + if (!wpa_s->parent->dbus_new_path) + return FALSE; + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) if (network_is_persistent_group(ssid)) num++; @@ -1659,7 +1672,7 @@ dbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter, /* Construct the object path for this network. */ os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d", - wpa_s->dbus_new_path, ssid->id); + wpa_s->parent->dbus_new_path, ssid->id); } success = wpas_dbus_simple_array_property_getter(iter, @@ -1746,7 +1759,10 @@ DBusMessage * wpas_dbus_handler_add_persistent_group( dbus_message_iter_init(message, &iter); - ssid = wpa_config_add_network(wpa_s->conf); + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + if (wpa_s->parent->dbus_new_path) + ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) { wpa_printf(MSG_ERROR, "dbus: %s: Cannot add new persistent group", @@ -1779,7 +1795,7 @@ DBusMessage * wpas_dbus_handler_add_persistent_group( /* Construct the object path for this network. */ os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d", - wpa_s->dbus_new_path, ssid->id); + wpa_s->parent->dbus_new_path, ssid->id); reply = dbus_message_new_method_return(message); if (reply == NULL) { @@ -1826,6 +1842,9 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group( dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op, DBUS_TYPE_INVALID); + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; + /* * Extract the network ID and ensure the network is actually a child of * this interface. @@ -1834,7 +1853,8 @@ DBusMessage * wpas_dbus_handler_remove_persistent_group( op, WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART, &persistent_group_id); if (iface == NULL || persistent_group_id == NULL || - os_strcmp(iface, wpa_s->dbus_new_path) != 0) { + !wpa_s->parent->dbus_new_path || + os_strcmp(iface, wpa_s->parent->dbus_new_path) != 0) { reply = wpas_dbus_error_invalid_args(message, op); goto out; } @@ -1899,6 +1919,8 @@ DBusMessage * wpas_dbus_handler_remove_all_persistent_groups( struct wpa_ssid *ssid, *next; struct wpa_config *config; + if (wpa_s->p2p_dev) + wpa_s = wpa_s->p2p_dev; config = wpa_s->conf; ssid = config->ssid; while (ssid) { @@ -1928,6 +1950,9 @@ dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter, const u8 *addr; dbus_bool_t success = FALSE; + if (!wpa_s->parent->parent->dbus_new_path) + return FALSE; + /* Verify correct role for this property */ if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_GO) { return wpas_dbus_simple_array_property_getter( @@ -1955,7 +1980,8 @@ dbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter, os_snprintf(paths[i], WPAS_DBUS_OBJECT_PATH_MAX, "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR, - wpa_s->parent->dbus_new_path, MAC2STR(addr)); + wpa_s->parent->parent->dbus_new_path, + MAC2STR(addr)); i++; } diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c index a94a0e51..734ac4a1 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c @@ -358,6 +358,8 @@ dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter, struct wpa_supplicant *wpa_s = user_data; dbus_bool_t process_credentials, old_pc; + if (!wpa_s->dbus_new_path) + return FALSE; if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN, &process_credentials)) return FALSE; diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c index 15b09014..45623f34 100644 --- a/wpa_supplicant/dbus/dbus_new_helpers.c +++ b/wpa_supplicant/dbus/dbus_new_helpers.c @@ -46,8 +46,13 @@ static dbus_bool_t fill_dict_with_properties( goto error; /* An error getting a property fails the request entirely */ - if (!dsc->getter(&entry_iter, error, user_data)) + if (!dsc->getter(&entry_iter, error, user_data)) { + wpa_printf(MSG_INFO, + "dbus: %s dbus_interface=%s dbus_property=%s getter failed", + __func__, dsc->dbus_interface, + dsc->dbus_property); return FALSE; + } if (!dbus_message_iter_close_container(dict_iter, &entry_iter)) goto error; diff --git a/wpa_supplicant/dbus/dbus_old.c b/wpa_supplicant/dbus/dbus_old.c index 45bb4022..88227af7 100644 --- a/wpa_supplicant/dbus/dbus_old.c +++ b/wpa_supplicant/dbus/dbus_old.c @@ -383,7 +383,7 @@ void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s) DBusMessage *_signal; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_path) return; _signal = dbus_message_new_signal(wpa_s->dbus_path, @@ -474,7 +474,7 @@ void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s) dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; /* Do nothing if the control interface is not turned on */ - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_path) return; _signal = dbus_message_new_signal(wpa_s->dbus_path, @@ -509,7 +509,7 @@ void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, if (wpa_s->global == NULL) return; iface = wpa_s->global->dbus; - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_path) return; _signal = dbus_message_new_signal(wpa_s->dbus_path, @@ -559,7 +559,7 @@ void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s, if (wpa_s->global == NULL) return; iface = wpa_s->global->dbus; - if (iface == NULL) + if (iface == NULL || !wpa_s->dbus_path) return; _signal = dbus_message_new_signal(wpa_s->dbus_path, @@ -738,7 +738,7 @@ struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path( struct wpa_supplicant *wpa_s; for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { - if (strcmp(wpa_s->dbus_path, path) == 0) + if (wpa_s->dbus_path && strcmp(wpa_s->dbus_path, path) == 0) return wpa_s; } return NULL; diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c index 773ee8b4..0ffa1bef 100644 --- a/wpa_supplicant/dbus/dbus_old_handlers.c +++ b/wpa_supplicant/dbus/dbus_old_handlers.c @@ -166,7 +166,7 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, iface.bridge_ifname = bridge_ifname; /* Otherwise, have wpa_supplicant attach to it. */ wpa_s = wpa_supplicant_add_iface(global, &iface, NULL); - if (wpa_s) { + if (wpa_s && wpa_s->dbus_path) { const char *path = wpa_s->dbus_path; reply = dbus_message_new_method_return(message); @@ -262,7 +262,7 @@ DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message, } wpa_s = wpa_supplicant_get_iface(global, ifname); - if (wpa_s == NULL) { + if (wpa_s == NULL || !wpa_s->dbus_path) { reply = wpas_dbus_new_invalid_iface_error(message); goto out; } @@ -354,6 +354,11 @@ DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message, DBusMessageIter sub_iter; struct wpa_bss *bss; + if (!wpa_s->dbus_path) + return dbus_message_new_error(message, + WPAS_ERROR_INTERNAL_ERROR, + "no D-Bus interface available"); + /* Create and initialize the return message */ reply = dbus_message_new_method_return(message); dbus_message_iter_init_append(reply, &iter); @@ -708,10 +713,11 @@ DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; - struct wpa_ssid *ssid; + struct wpa_ssid *ssid = NULL; char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; - ssid = wpa_config_add_network(wpa_s->conf); + if (wpa_s->dbus_path) + ssid = wpa_config_add_network(wpa_s->conf); if (ssid == NULL) { reply = dbus_message_new_error( message, WPAS_ERROR_ADD_NETWORK_ERROR, @@ -769,7 +775,7 @@ DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message, } /* Ensure the network is actually a child of this interface */ - if (os_strcmp(iface, wpa_s->dbus_path) != 0) { + if (!wpa_s->dbus_path || os_strcmp(iface, wpa_s->dbus_path) != 0) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } @@ -1020,7 +1026,7 @@ DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, goto out; } /* Ensure the object path really points to this interface */ - if (network == NULL || + if (network == NULL || !wpa_s->dbus_path || os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) { reply = wpas_dbus_new_invalid_network_error(message); goto out; diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index 98af5305..a1afc85f 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -188,14 +188,16 @@ int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes, struct wpa_bss *bss; int res; - freq = wpa_s->assoc_freq; bss = wpa_bss_get_bssid(wpa_s, dst); - if (bss) { - wpa_bss_anqp_unshare_alloc(bss); - freq = bss->freq; - } - if (freq <= 0) + if (!bss) { + wpa_printf(MSG_WARNING, + "ANQP: Cannot send query to unknown BSS " + MACSTR, MAC2STR(dst)); return -1; + } + + wpa_bss_anqp_unshare_alloc(bss); + freq = bss->freq; wpa_printf(MSG_DEBUG, "HS20: ANQP Query Request to " MACSTR " for " "subtypes 0x%x", MAC2STR(dst), stypes); diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index d0ae135b..6299191d 100644 --- a/wpa_supplicant/ibss_rsn.c +++ b/wpa_supplicant/ibss_rsn.c @@ -571,6 +571,9 @@ int ibss_rsn_start(struct ibss_rsn *ibss_rsn, const u8 *addr) struct ibss_rsn_peer *peer; int res; + if (!ibss_rsn) + return -1; + /* if the peer already exists, exit immediately */ peer = ibss_rsn_get_peer(ibss_rsn, addr); if (peer) diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 35885ee2..fd47c179 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -2673,14 +2673,16 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, struct wpa_bss *bss; int res; - freq = wpa_s->assoc_freq; bss = wpa_bss_get_bssid(wpa_s, dst); - if (bss) { - wpa_bss_anqp_unshare_alloc(bss); - freq = bss->freq; - } - if (freq <= 0) + if (!bss) { + wpa_printf(MSG_WARNING, + "ANQP: Cannot send query to unknown BSS " + MACSTR, MAC2STR(dst)); return -1; + } + + wpa_bss_anqp_unshare_alloc(bss); + freq = bss->freq; wpa_msg(wpa_s, MSG_DEBUG, "ANQP: Query Request to " MACSTR " for %u id(s)", diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index ea7dbdb1..184a95c8 100644 --- a/wpa_supplicant/notify.c +++ b/wpa_supplicant/notify.c @@ -307,14 +307,12 @@ void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s, void wpas_notify_network_removed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { - if (wpa_s->p2p_mgmt) - return; - if (wpa_s->next_ssid == ssid) wpa_s->next_ssid = NULL; if (wpa_s->wpa) wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); - if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s) + if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s && + !wpa_s->p2p_mgmt) wpas_dbus_unregister_network(wpa_s, ssid->id); if (network_is_persistent_group(ssid)) wpas_notify_persistent_group_removed(wpa_s, ssid); diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index bf0a03f2..bd5846bf 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1456,7 +1456,8 @@ static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc, char *argv[]) { int res = wpa_ctrl_command(ctrl, "ADD_NETWORK"); - update_networks(ctrl); + if (interactive) + update_networks(ctrl); return res; } @@ -1465,7 +1466,8 @@ static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc, char *argv[]) { int res = wpa_cli_cmd(ctrl, "REMOVE_NETWORK", 1, argc, argv); - update_networks(ctrl); + if (interactive) + update_networks(ctrl); return res; } @@ -2653,6 +2655,13 @@ static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_tdls_link_status(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "TDLS_LINK_STATUS", 1, argc, argv); +} + + static int wpa_cli_cmd_wmm_ac_addts(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -3280,6 +3289,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL, cli_cmd_flag_none, "<addr> = tear down TDLS with <addr>" }, + { "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL, + cli_cmd_flag_none, + "<addr> = TDLS link status with <addr>" }, { "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL, cli_cmd_flag_none, "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] " diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 8ed8b725..364ba194 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1118,13 +1118,13 @@ struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, int eap_register_methods(void); /** - * Utility method to tell if a given network is a persistent group + * Utility method to tell if a given network is for persistent group storage * @ssid: Network object * Returns: 1 if network is a persistent group, 0 otherwise */ static inline int network_is_persistent_group(struct wpa_ssid *ssid) { - return ((ssid->disabled == 2) || ssid->p2p_persistent_group); + return ssid->disabled == 2 && ssid->p2p_persistent_group; } int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); |