Просмотр исходного кода

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 лет назад
Родитель
Сommit
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;
         *want_length_out = 2u+usernamelen;
         return 0;
         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->replylen = 2; /* 2 bytes of response */
       req->reply[0] = 5;
       req->reply[0] = 5;
       req->reply[1] = 0; /* authentication successful */
       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 */
 /** Helper: Perform SOCKS 5 authentication before method negotiated */
 static void
 static void
 test_buffers_socks5_auth_before_negotiation_helper(const char *cp, buf_t *buf,
 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);
   buf = buf_new_with_capacity(256);
   socks = tor_malloc_zero(sizeof(socks_request_t));;
   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  */
   /* A SOCKS 5 client that doesn't want authentication  */
   test_buffers_socks5_no_authenticate_helper(cp, buf, socks);
   test_buffers_socks5_no_authenticate_helper(cp, buf, socks);
   test_buffers_socks5_supported_commands_helper(cp, buf, socks);
   test_buffers_socks5_supported_commands_helper(cp, buf, socks);