commit 72039624bb190dfec3e758b7389410a987adc8a3
Author: David Goulet <[email protected]>
Date:   Wed May 27 13:20:03 2015 -0400

    Fix: socks5 resolve wasn't sending data correctly
    
    The resolve function was sending uninitialized data to tor and sometimes
    too much data than needed. Furthermore, a valid SOCKS5 request for that
    needs a port so add one in both resolve and resolve_ptr.
    
    Reported-by: Yawning Angel <[email protected]>
    Signed-off-by: David Goulet <[email protected]>
---
 src/common/socks5.c |   43 +++++++++++++++++++++++++++++++------------
 src/common/socks5.h |    2 ++
 2 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/src/common/socks5.c b/src/common/socks5.c
index 3c9544a..3f284ca 100644
--- a/src/common/socks5.c
+++ b/src/common/socks5.c
@@ -564,20 +564,19 @@ ATTR_HIDDEN
 int socks5_send_resolve_request(const char *hostname, struct connection *conn)
 {
        int ret, ret_send;
-       /*
-        * Can't go bigger than that. 4 bytes for the header, 1 for the name len
-        * and 255 for the name.
-        */
-       unsigned char buffer[260];
        size_t name_len, msg_len, data_len;
        struct socks5_request msg;
        struct socks5_request_resolve req;
+       /* Can't go bigger than that. 4 bytes for the header, 1 for the name 
len,
+        * 255 for the name and 2 bytes for the port. */
+       unsigned char buffer[sizeof(msg) + sizeof(req)];
 
        assert(hostname);
        assert(conn);
        assert(conn->fd >= 0);
 
        memset(buffer, 0, sizeof(buffer));
+       memset(&req, 0, sizeof(req));
        msg_len = sizeof(msg);
 
        msg.ver = SOCKS5_VERSION;
@@ -596,11 +595,21 @@ int socks5_send_resolve_request(const char *hostname, 
struct connection *conn)
        /* Setup resolve request. */
        req.len = name_len;
        memcpy(req.name, hostname, name_len);
+       /* Dummy port, tor doesn't need it. */
+       req.port = htons(42);
 
        /* Copy final buffer. */
        memcpy(buffer, &msg, msg_len);
-       memcpy(buffer + msg_len, &req, sizeof(req));
-       data_len = msg_len + sizeof(req);
+       data_len = msg_len;
+       /* Add the length of hostname. */
+       memcpy(buffer + data_len, &req.len, sizeof(req.len));
+       data_len += sizeof(req.len);
+       /* Add hostname without NULL terminated byte. */
+       memcpy(buffer + data_len, req.name, req.len);
+       data_len += req.len;
+       /* Add the dummy port at the end. */
+       memcpy(buffer + data_len, &req.port, sizeof(req.port));
+       data_len += sizeof(req.port);
 
        ret_send = send_data(conn->fd, &buffer, data_len);
        if (ret_send < 0) {
@@ -703,10 +712,11 @@ ATTR_HIDDEN
 int socks5_send_resolve_ptr_request(struct connection *conn, const void *ip, 
int af)
 {
        int ret, ret_send;
-       unsigned char buffer[20];       /* Can't go higher than that (with 
IPv6). */
        size_t msg_len, data_len;
        struct socks5_request msg;
        struct socks5_request_resolve_ptr req;
+       /* Can't go higher than that (with IPv6). */
+       unsigned char buffer[sizeof(msg) + sizeof(req)];
 
        assert(conn);
        assert(conn->fd >= 0);
@@ -724,11 +734,17 @@ int socks5_send_resolve_ptr_request(struct connection 
*conn, const void *ip, int
        switch (af) {
        case AF_INET:
                msg.atyp = SOCKS5_ATYP_IPV4;
-               memcpy(req.addr.ipv4, ip, 4);
+               memcpy(req.addr.ipv4, ip, sizeof(req.addr.ipv4));
+               /* Copy right away the IP since we know the family type. */
+               memcpy(buffer + msg_len, &req.addr, sizeof(req.addr.ipv4));
+               data_len = msg_len + sizeof(req.addr.ipv4);
                break;
        case AF_INET6:
                msg.atyp = SOCKS5_ATYP_IPV6;
-               memcpy(req.addr.ipv6, ip, 16);
+               memcpy(req.addr.ipv6, ip, sizeof(req.addr.ipv6));
+               /* Copy right away the IP since we know the family type. */
+               memcpy(buffer + msg_len, &req.addr, sizeof(req.addr.ipv6));
+               data_len = msg_len + sizeof(req.addr.ipv6);
                break;
        default:
                ERR("Unknown address domain of %d", ip);
@@ -736,10 +752,13 @@ int socks5_send_resolve_ptr_request(struct connection 
*conn, const void *ip, int
                goto error;
        }
 
+       /* Dummy port, tor doesn't need it. */
+       req.port = htons(42);
+
        /* Copy final buffer. */
        memcpy(buffer, &msg, msg_len);
-       memcpy(buffer + msg_len, &req, sizeof(req));
-       data_len = msg_len + sizeof(req);
+       memcpy(buffer + data_len, &req.port, sizeof(req.port));
+       data_len += sizeof(req.port);
 
        ret_send = send_data(conn->fd, &buffer, data_len);
        if (ret_send < 0) {
diff --git a/src/common/socks5.h b/src/common/socks5.h
index 35c7d2b..41da679 100644
--- a/src/common/socks5.h
+++ b/src/common/socks5.h
@@ -108,6 +108,7 @@ struct socks5_request_domain {
 struct socks5_request_resolve {
        uint8_t len;
        unsigned char name[UINT8_MAX];
+       uint16_t port;
 };
 
 /* Use for the Tor resolve ptr command. */
@@ -116,6 +117,7 @@ struct socks5_request_resolve_ptr {
                uint8_t ipv4[4];
                uint8_t ipv6[16];
        } addr;
+       uint16_t port;
 };
 
 /* Non variable part of a reply. */

_______________________________________________
tor-commits mailing list
[email protected]
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to