Browse Source

bug1666 - Pass-through support for SOCKS5 authentication(4)

Implement nickm's suggestion that we tolerate SOCKS5 clients
that send authentication credentials and SOCKS commands all in
one go.
Robert Hogan 15 years ago
parent
commit
02c2d9a4aa
2 changed files with 49 additions and 5 deletions
  1. 0 5
      src/or/buffers.c
  2. 49 0
      src/test/test.c

+ 0 - 5
src/or/buffers.c

@@ -1658,11 +1658,6 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
         *want_length_out = 2u+usernamelen;
         return 0;
       }
-      if (datalen > 2u + usernamelen + 1u + passlen) {
-        log_warn(LD_APP,
-                 "socks5: Malformed username/password. Rejecting.");
-        return -1;
-      }
       req->replylen = 2; /* 2 bytes of response */
       req->reply[0] = 5;
       req->reply[1] = 0; /* authentication successful */

+ 49 - 0
src/test/test.c

@@ -398,6 +398,46 @@ done:
   ;
 }
 
+/** Helper: Perform SOCKS 5 authentication and send data all in one go */
+static void
+test_buffers_socks5_authenticate_with_data_helper(const char *cp, buf_t *buf,
+                                                  socks_request_t *socks)
+{
+  /* SOCKS 5 Negotiate username/password authentication */
+  cp = "\x05\x01\x02";
+  write_to_buf(cp, 3, buf);
+  test_assert(!fetch_from_buf_socks(buf, socks,
+                                   get_options()->TestSocks,
+                                   get_options()->SafeSocks));
+  test_eq(2, socks->replylen);
+  test_eq(5, socks->reply[0]);
+  test_eq(SOCKS_USER_PASS, socks->reply[1]);
+  test_eq(5, socks->socks_version);
+
+  /* SOCKS 5 Send username/password */
+  /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
+  cp = "\x01\x02me\x02me\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11";
+  write_to_buf(cp, 17, buf);
+  test_assert(!fetch_from_buf_socks(buf, socks,
+                                   get_options()->TestSocks,
+                                   get_options()->SafeSocks));
+  test_eq(5, socks->socks_version);
+  test_eq(2, socks->replylen);
+  test_eq(5, socks->reply[0]);
+  test_eq(0, socks->reply[1]);
+
+  test_assert(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
+                                   get_options()->SafeSocks) == 1);
+  test_eq(5, socks->socks_version);
+  test_eq(2, socks->replylen);
+  test_eq(5, socks->reply[0]);
+  test_eq(0, socks->reply[1]);
+  test_streq("2.2.2.2", socks->address);
+  test_eq(4369, socks->port);
+done:
+  ;
+}
+
 /** Helper: Perform SOCKS 5 authentication before method negotiated */
 static void
 test_buffers_socks5_auth_before_negotiation_helper(const char *cp, buf_t *buf,
@@ -610,6 +650,15 @@ test_buffers(void)
   buf = buf_new_with_capacity(256);
   socks = tor_malloc_zero(sizeof(socks_request_t));;
 
+  /* 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);
+  buf_free(buf);
+  buf = NULL;
+  buf = buf_new_with_capacity(256);
+  socks = tor_malloc_zero(sizeof(socks_request_t));;
+
   /* 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);