diff --git a/src/proxy/socks_proxy.c b/src/proxy/socks_proxy.c index 412a7c4f..9527b74d 100644 --- a/src/proxy/socks_proxy.c +++ b/src/proxy/socks_proxy.c @@ -130,9 +130,18 @@ static int write_to_client(struct socks_proxy_conn* c, const uint8_t* data, uint // SOCKS5 handshake // ==================================================================== static void process_socks_greeting(struct socks_proxy_conn* c) { - if (c->buf_len < 3) return; + if (c->buf_len < 2) return; uint8_t ver = c->buf[0], nmethods = c->buf[1]; - if (ver != 5 || c->buf_len < (uint16_t)(2 + nmethods)) return; + if (ver != 5 || !nmethods) { + DEBUG_WARN(DEBUG_CATEGORY_PROXY, "socks_proxy: invalid greeting sid=%08x ver=%u methods=%u", c->stream_id, ver, nmethods); + c->rem_closed = 1; tcp_conn_push_close(c->tc); return; + } + if (c->buf_len < (uint16_t)(2 + nmethods)) return; + if (!memchr(c->buf + 2, 0, nmethods)) { + uint8_t reject[] = {5, 255}; + DEBUG_WARN(DEBUG_CATEGORY_PROXY, "socks_proxy: no supported authentication sid=%08x", c->stream_id); + write_to_client(c, reject, sizeof(reject)); c->rem_closed = 1; tcp_conn_push_close(c->tc); return; + } DEBUG_DEBUG(DEBUG_CATEGORY_PROXY, "socks_proxy: greeting ver=%d nmethods=%d", ver, nmethods); uint8_t reply[] = { 0x05, 0x00 }; write_to_client(c, reply, 2); @@ -141,15 +150,16 @@ static void process_socks_greeting(struct socks_proxy_conn* c) { } static void process_socks_request(struct socks_proxy_conn* c) { - if (c->buf_len < 10) return; + if (c->buf_len < 4) return; uint8_t ver = c->buf[0], cmd = c->buf[1], atyp = c->buf[3]; - if (ver != 5) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "socks_proxy: bad ver=%d", ver); goto error; } + if (ver != 5 || c->buf[2] != 0) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "socks_proxy: bad ver=%d", ver); goto error; } if (cmd != 1) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "socks_proxy: unsupported cmd=%d (only CONNECT supported)", cmd); goto error; } uint16_t need; if (atyp == 1) need = 10; // IPv4: 4+2=6 more bytes else if (atyp == 3) { // domain: 1+len+2 if (c->buf_len < 5) return; + if (!c->buf[4]) { DEBUG_WARN(DEBUG_CATEGORY_PROXY, "socks_proxy: empty domain"); goto error; } need = (uint16_t)(5 + c->buf[4] + 2); } else if (atyp == 4) need = 22; // IPv6: 16+2=18 more @@ -164,14 +174,9 @@ static void process_socks_request(struct socks_proxy_conn* c) { socks_finalize(c); return; } else if (atyp == 4) { - // Извлекаем первые 4 байта IPv6 в dest_ip (для упрощения: IPv6 mapped IPv4 или реальный IPv6) - memcpy(c->dest_ip, c->buf + 12, 4); - memcpy(&c->dest_port, c->buf + 20, 2); - // TODO: proper IPv6 support - DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "socks_proxy: IPv6 unsupported, using last 4 bytes of addr"); - c->buf_len = 0; - socks_finalize(c); - return; + uint8_t reply[] = {5, 8, 0, 1, 0, 0, 0, 0, 0, 0}; + DEBUG_WARN(DEBUG_CATEGORY_PROXY, "socks_proxy: IPv6 destination unsupported sid=%08x", c->stream_id); + write_to_client(c, reply, sizeof(reply)); c->rem_closed = 1; tcp_conn_push_close(c->tc); return; } // atyp == 3 (domain)