summaryrefslogtreecommitdiff
path: root/lib/socks.c
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2022-11-14 03:30:30 -0500
committerJay Satiro <raysatiro@yahoo.com>2022-11-18 03:04:13 -0500
commit12e1def51a75392df62e65490416007d7e68dab9 (patch)
tree842c59a11b447d53f3e2d810d61e77bbe5d76fa2 /lib/socks.c
parent856b133f5d62475d4cc12624c4cccb4170134712 (diff)
downloadcurl-12e1def51a75392df62e65490416007d7e68dab9.tar.gz
sendf: change Curl_read_plain to wrap Curl_recv_plain
Prior to this change Curl_read_plain would attempt to read the socket directly. On Windows that's a problem because recv data may be cached by libcurl and that data is only drained using Curl_recv_plain. Rather than rewrite Curl_read_plain to handle cached recv data, I changed it to wrap Curl_recv_plain, in much the same way that Curl_write_plain already wraps Curl_send_plain. Curl_read_plain -> Curl_recv_plain Curl_write_plain -> Curl_send_plain This fixes a bug in the schannel backend where decryption of arbitrary TLS records fails because cached recv data is never drained. We send data (TLS records formed by Schannel) using Curl_write_plain, which calls Curl_send_plain, and that may do a recv-before-send ("pre-receive") to cache received data. The code calls Curl_read_plain to read data (TLS records from the server), which prior to this change did not call Curl_recv_plain and therefore cached recv data wasn't retrieved, resulting in malformed TLS records and decryption failure (SEC_E_DECRYPT_FAILURE). The bug has only been observed during Schannel TLS 1.3 handshakes. Refer to the issue and PR for more information. Ref: https://github.com/curl/curl/issues/9431#issuecomment-1312420361 Assisted-by: Joel Depooter Reported-by: Egor Pugin Fixes https://github.com/curl/curl/issues/9431 Closes https://github.com/curl/curl/pull/9904
Diffstat (limited to 'lib/socks.c')
-rw-r--r--lib/socks.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/lib/socks.c b/lib/socks.c
index 40cd13e0a..e1f6dbbb2 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -112,7 +112,7 @@ int Curl_blockread_all(struct Curl_easy *data, /* transfer */
result = ~CURLE_OK;
break;
}
- result = Curl_read_plain(sockfd, buf, buffersize, &nread);
+ result = Curl_read_plain(data, sockfd, buf, buffersize, &nread);
if(CURLE_AGAIN == result)
continue;
if(result)
@@ -396,7 +396,7 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf,
/* FALLTHROUGH */
case CONNECT_SOCKS_READ:
/* Receive response */
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "SOCKS4: Failed receiving connect request ack: %s",
@@ -599,7 +599,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
sx->outp = socksreq; /* store it here */
/* FALLTHROUGH */
case CONNECT_SOCKS_READ:
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive initial SOCKS5 response.");
@@ -729,7 +729,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
sxstate(sx, data, CONNECT_AUTH_READ);
/* FALLTHROUGH */
case CONNECT_AUTH_READ:
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
@@ -931,7 +931,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
sxstate(sx, data, CONNECT_REQ_READ);
/* FALLTHROUGH */
case CONNECT_REQ_READ:
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to receive SOCKS5 connect request ack.");
@@ -1030,7 +1030,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf,
#endif
/* FALLTHROUGH */
case CONNECT_REQ_READ_MORE:
- result = Curl_read_plain(sockfd, (char *)sx->outp,
+ result = Curl_read_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &actualread);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to receive SOCKS5 connect request ack.");