[tor-commits] [tor/master] Record username/password data in socks_request_t

nickm at torproject.org nickm at torproject.org
Wed Jul 13 16:13:22 UTC 2011


commit 2e6604f42ee614156ceeb29bdcab5c78cc1d84ba
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Jun 29 12:31:17 2011 -0400

    Record username/password data in socks_request_t
    
    This change also requires us to add and use a pair of
    allocator/deallocator functions for socks_request_t, instead of
    using tor_malloc_zero/tor_free directly.
---
 src/or/buffers.c    |   43 +++++++++++++++++++++++++++++++++++++++----
 src/or/buffers.h    |    2 ++
 src/or/connection.c |    8 +++-----
 src/or/or.h         |   12 ++++++++++++
 src/test/test.c     |   20 ++++++++++----------
 5 files changed, 66 insertions(+), 19 deletions(-)

diff --git a/src/or/buffers.c b/src/or/buffers.c
index 7b212a7..0e2dbbe 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -1475,6 +1475,25 @@ log_unsafe_socks_warning(int socks_protocol, const char *address,
                               socks_protocol, address, (int)port);
 }
 
+/** Return a new socks_request_t. */
+socks_request_t *
+socks_request_new(void)
+{
+  return tor_malloc_zero(sizeof(socks_request_t));
+}
+
+/** Free all storage held in the socks_request_t <b>req</b>. */
+void
+socks_request_free(socks_request_t *req)
+{
+  if (!req)
+    return;
+  tor_free(req->username);
+  tor_free(req->password);
+  memset(req, 0xCC, sizeof(socks_request_t));
+  tor_free(req);
+}
+
 /** There is a (possibly incomplete) socks handshake on <b>buf</b>, of one
  * of the forms
  *  - socks4: "socksheader username\\0"
@@ -1631,7 +1650,6 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
   tor_addr_t destaddr;
   uint32_t destip;
   uint8_t socksver;
-  enum {socks4, socks4a} socks4_prot = socks4a;
   char *next, *startaddr;
   unsigned char usernamelen, passlen;
   struct in_addr in;
@@ -1662,6 +1680,14 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
       req->reply[1] = 0; /* authentication successful */
       log_debug(LD_APP,
                "socks5: Accepted username/password without checking.");
+      if (usernamelen) {
+        req->username = tor_memdup(data+2u, usernamelen);
+        req->usernamelen = usernamelen;
+      }
+      if (passlen) {
+        req->password = tor_memdup(data+3u+usernamelen, passlen);
+        req->passwordlen = passlen;
+      }
       *drain_out = 2u + usernamelen + 1u + passlen;
       req->got_auth = 1;
       return 0;
@@ -1813,7 +1839,9 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
           return -1;
       }
       tor_assert(0);
-    case 4: /* socks4 */
+    case 4: { /* socks4 */
+      enum {socks4, socks4a} socks4_prot = socks4a;
+      const char *authstart, *authend;
       /* http://ss5.sourceforge.net/socks4.protocol.txt */
       /* http://ss5.sourceforge.net/socks4A.protocol.txt */
 
@@ -1854,7 +1882,8 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
         socks4_prot = socks4;
       }
 
-      next = memchr(data+SOCKS4_NETWORK_LEN, 0,
+      authstart = data + SOCKS4_NETWORK_LEN;
+      next = memchr(authstart, 0,
                     datalen-SOCKS4_NETWORK_LEN);
       if (!next) {
         if (datalen >= 1024) {
@@ -1865,6 +1894,7 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
         *want_length_out = datalen+1024; /* ???? */
         return 0;
       }
+      authend = next;
       tor_assert(next < data+datalen);
 
       startaddr = NULL;
@@ -1914,10 +1944,15 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
                  req->port, escaped(req->address));
         return -1;
       }
+      if (authend != authstart) {
+        req->got_auth = 1;
+        req->usernamelen = authend - authstart;
+        req->username = tor_memdup(authstart, authend - authstart);
+      }
       /* next points to the final \0 on inbuf */
       *drain_out = next - data + 1;
       return 1;
-
+    }
     case 'G': /* get */
     case 'H': /* head */
     case 'P': /* put/post */
diff --git a/src/or/buffers.h b/src/or/buffers.h
index 35c1dd2..fad509e 100644
--- a/src/or/buffers.h
+++ b/src/or/buffers.h
@@ -41,6 +41,8 @@ int fetch_from_buf_http(buf_t *buf,
                         char **headers_out, size_t max_headerlen,
                         char **body_out, size_t *body_used, size_t max_bodylen,
                         int force_complete);
+socks_request_t *socks_request_new(void);
+void socks_request_free(socks_request_t *req);
 int fetch_from_buf_socks(buf_t *buf, socks_request_t *req,
                          int log_sockstype, int safe_socks);
 int fetch_from_buf_socks_client(buf_t *buf, int state, char **reason);
diff --git a/src/or/connection.c b/src/or/connection.c
index 6f9ae20..2a4a6f7 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -246,7 +246,7 @@ edge_connection_new(int type, int socket_family)
   tor_assert(type == CONN_TYPE_EXIT || type == CONN_TYPE_AP);
   connection_init(time(NULL), TO_CONN(edge_conn), type, socket_family);
   if (type == CONN_TYPE_AP)
-    edge_conn->socks_request = tor_malloc_zero(sizeof(socks_request_t));
+    edge_conn->socks_request = socks_request_new();
   return edge_conn;
 }
 
@@ -440,10 +440,8 @@ _connection_free(connection_t *conn)
   if (CONN_IS_EDGE(conn)) {
     edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
     tor_free(edge_conn->chosen_exit_name);
-    if (edge_conn->socks_request) {
-      memset(edge_conn->socks_request, 0xcc, sizeof(socks_request_t));
-      tor_free(edge_conn->socks_request);
-    }
+    if (edge_conn->socks_request)
+      socks_request_free(edge_conn->socks_request);
 
     rend_data_free(edge_conn->rend_data);
   }
diff --git a/src/or/or.h b/src/or/or.h
index bc80e39..3c76444 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3109,6 +3109,18 @@ struct socks_request_t {
                               * make sure we send back a socks reply for
                               * every connection. */
   unsigned int got_auth : 1; /**< Have we received any authentication data? */
+
+  /** Number of bytes in username; 0 if username is NULL */
+  uint8_t usernamelen;
+  /** Number of bytes in password; 0 if password is NULL */
+  uint8_t passwordlen;
+  /** The negotiated username value if any (for socks5), or the entire
+   * authentication string (for socks4).  This value is NOT nul-terminated;
+   * see usernamelen for its length. */
+  char *username;
+  /** The negotiated password value if any (for socks5). This value is NOT
+   * nul-terminated; see usernamelen for its length. */
+  char *password;
 };
 
 /********************************* circuitbuild.c **********************/
diff --git a/src/test/test.c b/src/test/test.c
index d0e24d1..38729cf 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -627,54 +627,54 @@ test_buffers(void)
 
   /* Test fetch_from_buf_socks() */
   buf = buf_new_with_capacity(256);
-  socks = tor_malloc_zero(sizeof(socks_request_t));;
+  socks = socks_request_new();
   config_register_addressmaps(get_options());
 
   /* Sending auth credentials before we've negotiated a method */
   test_buffers_socks5_auth_before_negotiation_helper(cp, buf, socks);
 
-  tor_free(socks);
+  socks_request_free(socks);
   buf_free(buf);
   buf = NULL;
   buf = buf_new_with_capacity(256);
-  socks = tor_malloc_zero(sizeof(socks_request_t));;
+  socks = socks_request_new();
 
   /* A SOCKS 5 client that only supports authentication  */
   test_buffers_socks5_authenticate_helper(cp, buf, socks);
   test_buffers_socks5_supported_commands_helper(cp, buf, socks);
   test_buffers_socks5_unsupported_commands_helper(cp, buf, socks);
 
-  tor_free(socks);
+  socks_request_free(socks);
   buf_free(buf);
   buf = NULL;
   buf = buf_new_with_capacity(256);
-  socks = tor_malloc_zero(sizeof(socks_request_t));;
+  socks = socks_request_new();
 
   /* A SOCKS 5 client that sends credentials and data in one go  */
   test_buffers_socks5_authenticate_with_data_helper(cp, buf, socks);
 
-  tor_free(socks);
+  socks_request_free(socks);
   buf_free(buf);
   buf = NULL;
   buf = buf_new_with_capacity(256);
-  socks = tor_malloc_zero(sizeof(socks_request_t));;
+  socks = socks_request_new();
 
   /* A SOCKS 5 client that doesn't want authentication  */
   test_buffers_socks5_no_authenticate_helper(cp, buf, socks);
   test_buffers_socks5_supported_commands_helper(cp, buf, socks);
   test_buffers_socks5_unsupported_commands_helper(cp, buf, socks);
 
-  tor_free(socks);
+  socks_request_free(socks);
   buf_free(buf);
   buf = NULL;
   buf = buf_new_with_capacity(256);
-  socks = tor_malloc_zero(sizeof(socks_request_t));;
+  socks = socks_request_new();
 
   /* A SOCKS 4(a) client  */
   test_buffers_socks4_supported_commands_helper(cp, buf, socks);
   test_buffers_socks4_unsupported_commands_helper(cp, buf, socks);
 
-  tor_free(socks);
+  socks_request_free(socks);
   buf_free(buf);
   buf = NULL;
 





More information about the tor-commits mailing list