]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
socks: detect connection close during handshake
authorDaniel Stenberg <daniel@haxx.se>
Mon, 8 Jun 2020 12:05:22 +0000 (14:05 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 8 Jun 2020 21:19:36 +0000 (23:19 +0200)
The SOCKS4/5 state machines weren't properly terminated when the proxy
connection got closed, leading to a busy-loop.

Reported-By: zloi-user on github
Fixes #5532
Closes #5542

lib/socks.c

index 4c1af7b9de7da3297a0e23cc1b0df2e26b2ab161..b2215fef30c6860c7d23168afc84b28b9f2c2795 100644 (file)
@@ -382,6 +382,11 @@ CURLcode Curl_SOCKS4(const char *proxy_user,
             curl_easy_strerror(result));
       return CURLE_COULDNT_CONNECT;
     }
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
     else if(actualread != sx->outstanding) {
       /* remain in reading state */
       sx->outstanding -= actualread;
@@ -592,6 +597,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       failf(data, "Unable to receive initial SOCKS5 response.");
       return CURLE_COULDNT_CONNECT;
     }
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "Connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
     else if(actualread != sx->outstanding) {
       /* remain in reading state */
       sx->outstanding -= actualread;
@@ -717,15 +727,19 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
       return CURLE_COULDNT_CONNECT;
     }
-    if(actualread != sx->outstanding) {
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(actualread != sx->outstanding) {
       /* remain in state */
       sx->outstanding -= actualread;
       sx->outp += actualread;
       return CURLE_OK;
     }
-
     /* ignore the first (VER) byte */
-    if(socksreq[1] != 0) { /* status */
+    else if(socksreq[1] != 0) { /* status */
       failf(data, "User was rejected by the SOCKS5 server (%d %d).",
             socksreq[0], socksreq[1]);
       return CURLE_COULDNT_CONNECT;
@@ -890,6 +904,11 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       failf(data, "Failed to receive SOCKS5 connect request ack.");
       return CURLE_COULDNT_CONNECT;
     }
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
     else if(actualread != sx->outstanding) {
       /* remain in state */
       sx->outstanding -= actualread;
@@ -967,7 +986,12 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
       failf(data, "Failed to receive SOCKS5 connect request ack.");
       return CURLE_COULDNT_CONNECT;
     }
-    if(actualread != sx->outstanding) {
+    else if(!result && !actualread) {
+      /* connection closed */
+      failf(data, "connection to proxy closed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    else if(actualread != sx->outstanding) {
       /* remain in state */
       sx->outstanding -= actualread;
       sx->outp += actualread;