From: Fabian Keil <fk@fabiankeil.de>
Date: Tue, 9 Mar 2021 17:50:13 +0000 (+0100)
Subject: socks5_connect(): Deal with domain names in the socks reply
X-Git-Tag: v_3_0_34~137
X-Git-Url: http://www.privoxy.org/gitweb/%22https:/faq/user-manual/static/gitweb.js?a=commitdiff_plain;h=ef48c7439a6041aa6148ccac53da507a75a24040;p=privoxy.git

socks5_connect(): Deal with domain names in the socks reply
---

diff --git a/gateway.c b/gateway.c
index 20f111fa..683048ac 100644
--- a/gateway.c
+++ b/gateway.c
@@ -1102,10 +1102,11 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
 {
 #define SIZE_SOCKS5_REPLY_IPV4 10
 #define SIZE_SOCKS5_REPLY_IPV6 22
+#define SIZE_SOCKS5_REPLY_DOMAIN 300
 #define SOCKS5_REPLY_DIFFERENCE (SIZE_SOCKS5_REPLY_IPV6 - SIZE_SOCKS5_REPLY_IPV4)
    int err = 0;
    char cbuf[300];
-   char sbuf[SIZE_SOCKS5_REPLY_IPV6];
+   char sbuf[SIZE_SOCKS5_REPLY_DOMAIN];
    size_t client_pos = 0;
    int server_size = 0;
    size_t hostlen = 0;
@@ -1425,6 +1426,29 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
                errstr = "SOCKS5 negotiation read failed (IPv6 address)";
             }
          }
+         else if (sbuf[3] == '\x03')
+         {
+            /*
+             * The address field contains a domain name
+             * which means we didn't get the whole reply
+             * yet. Read and discard the rest of it to make
+             * sure it isn't treated as HTTP data later on.
+             */
+            unsigned domain_length = (unsigned)sbuf[4];
+            int bytes_left_to_read = 5 + (int)domain_length + 2 - SIZE_SOCKS5_REPLY_IPV4;
+            if (bytes_left_to_read <= 0 || sizeof(sbuf) < bytes_left_to_read)
+            {
+               errstr = "SOCKS5 negotiation read failed (Invalid domain length)";
+            }
+            else
+            {
+               server_size = read_socket(sfd, sbuf, bytes_left_to_read);
+               if (server_size != bytes_left_to_read)
+               {
+                  errstr = "SOCKS5 negotiation read failed (Domain name)";
+               }
+            }
+         }
          else if (sbuf[3] != '\x01')
          {
             errstr = "SOCKS5 reply contains unsupported address type";