Преглед на файлове

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 години
родител
ревизия
02c2d9a4aa
променени са 2 файла, в които са добавени 49 реда и са изтрити 5 реда
  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);