From: Fabian Keil 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/?p=privoxy.git;a=commitdiff_plain;h=ef48c7439a6041aa6148ccac53da507a75a24040 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";