LCOV - code coverage report
Current view: top level - test - test_socks.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 571 571 100.0 %
Date: 2021-11-24 03:28:48 Functions: 23 23 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2001-2004, Roger Dingledine.
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : #include "core/or/or.h"
       7             : #include "lib/buf/buffers.h"
       8             : #include "app/config/config.h"
       9             : #include "core/mainloop/connection.h"
      10             : #include "core/proto/proto_socks.h"
      11             : #include "test/test.h"
      12             : #include "test/log_test_helpers.h"
      13             : #include "core/or/socks_request_st.h"
      14             : #include "lib/net/socks5_status.h"
      15             : 
      16             : typedef struct socks_test_data_t {
      17             :   socks_request_t *req;
      18             :   buf_t *buf;
      19             : } socks_test_data_t;
      20             : 
      21             : static void *
      22          16 : socks_test_setup(const struct testcase_t *testcase)
      23             : {
      24          16 :   socks_test_data_t *data = tor_malloc(sizeof(socks_test_data_t));
      25          16 :   (void)testcase;
      26          16 :   data->buf = buf_new_with_capacity(256);
      27          16 :   data->req = socks_request_new();
      28          16 :   config_register_addressmaps(get_options());
      29          16 :   return data;
      30             : }
      31             : static int
      32          16 : socks_test_cleanup(const struct testcase_t *testcase, void *ptr)
      33             : {
      34          16 :   socks_test_data_t *data = ptr;
      35          16 :   (void)testcase;
      36          16 :   buf_free(data->buf);
      37          16 :   socks_request_free(data->req);
      38          16 :   tor_free(data);
      39          16 :   return 1;
      40             : }
      41             : 
      42             : static const struct testcase_setup_t socks_setup = {
      43             :   socks_test_setup, socks_test_cleanup
      44             : };
      45             : 
      46             : #define SOCKS_TEST_INIT()                       \
      47             :   socks_test_data_t *testdata = ptr;            \
      48             :   buf_t *buf = testdata->buf;                   \
      49             :   socks_request_t *socks = testdata->req;
      50             : #define ADD_DATA(buf, s)                                        \
      51             :   buf_add(buf, s, sizeof(s)-1)
      52             : 
      53             : static void
      54          17 : socks_request_clear(socks_request_t *socks)
      55             : {
      56          17 :   tor_free(socks->username);
      57          17 :   tor_free(socks->password);
      58          17 :   memset(socks, 0, sizeof(socks_request_t));
      59             : }
      60             : 
      61             : /** Perform unsupported SOCKS 4 commands */
      62             : static void
      63           1 : test_socks_4_unsupported_commands(void *ptr)
      64             : {
      65           1 :   SOCKS_TEST_INIT();
      66             : 
      67             :   /* SOCKS 4 Send BIND [02] to IP address 2.2.2.2:4369 */
      68           1 :   ADD_DATA(buf, "\x04\x02\x11\x11\x02\x02\x02\x02\x00");
      69           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
      70             :                                  get_options()->SafeSocks),
      71             :             OP_EQ, -1);
      72           1 :   tt_int_op(4,OP_EQ, socks->socks_version);
      73           1 :   tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
      74             : 
      75           1 :  done:
      76           1 :   ;
      77           1 : }
      78             : 
      79             : /** Perform supported SOCKS 4 commands */
      80             : static void
      81           1 : test_socks_4_supported_commands(void *ptr)
      82             : {
      83           1 :   SOCKS_TEST_INIT();
      84             : 
      85           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
      86             : 
      87             :   /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.3:4370 */
      88           1 :   ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00");
      89           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
      90             :                                  get_options()->SafeSocks),
      91             :             OP_EQ, 1);
      92           1 :   tt_int_op(4,OP_EQ, socks->socks_version);
      93           1 :   tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
      94           1 :   tt_int_op(SOCKS_COMMAND_CONNECT,OP_EQ, socks->command);
      95           1 :   tt_str_op("2.2.2.3",OP_EQ, socks->address);
      96           1 :   tt_int_op(4370,OP_EQ, socks->port);
      97           1 :   tt_assert(socks->got_auth == 0);
      98           1 :   tt_assert(! socks->username);
      99             : 
     100           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     101           1 :   socks_request_clear(socks);
     102             : 
     103             :   /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.4:4369 with userid*/
     104           1 :   ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00");
     105           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
     106             :             OP_EQ, 1);
     107           1 :   tt_int_op(4,OP_EQ, socks->socks_version);
     108           1 :   tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
     109           1 :   tt_int_op(SOCKS_COMMAND_CONNECT,OP_EQ, socks->command);
     110           1 :   tt_str_op("2.2.2.4",OP_EQ, socks->address);
     111           1 :   tt_int_op(4370,OP_EQ, socks->port);
     112           1 :   tt_assert(socks->got_auth == 1);
     113           1 :   tt_assert(socks->username);
     114           1 :   tt_int_op(2,OP_EQ, socks->usernamelen);
     115           1 :   tt_mem_op("me",OP_EQ, socks->username, 2);
     116             : 
     117           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     118           1 :   socks_request_clear(socks);
     119             : 
     120             :   /* SOCKS 4a Send RESOLVE [F0] request for torproject.org */
     121           1 :   ADD_DATA(buf, "\x04\xF0\x01\x01\x00\x00\x00\x02me\x00torproject.org\x00");
     122           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1,
     123             :                                  get_options()->SafeSocks),
     124             :             OP_EQ, 1);
     125           1 :   tt_int_op(4,OP_EQ, socks->socks_version);
     126           1 :   tt_int_op(0,OP_EQ, socks->replylen); /* XXX: shouldn't tor reply? */
     127           1 :   tt_str_op("torproject.org",OP_EQ, socks->address);
     128             : 
     129           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     130             : 
     131           1 :  done:
     132           1 :   ;
     133           1 : }
     134             : 
     135             : static void
     136           1 : test_socks_4_bad_arguments(void *ptr)
     137             : {
     138           1 :   SOCKS_TEST_INIT();
     139           1 :   setup_capture_of_logs(LOG_DEBUG);
     140             : 
     141             :   /* Try with 0 IPv4 address */
     142           1 :   ADD_DATA(buf, "\x04\x01\x00\x50\x00\x00\x00\x00\x00");
     143           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     144             :                                  get_options()->SafeSocks),
     145             :             OP_EQ, -1);
     146           1 :   buf_clear(buf);
     147           1 :   expect_log_msg_containing("Port or DestIP is zero.");
     148           1 :   mock_clean_saved_logs();
     149             : 
     150             :   /* Try with 0 port */
     151           1 :   ADD_DATA(buf, "\x04\x01\x00\x00\x01\x02\x03\x04\x00");
     152           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     153             :                                  get_options()->SafeSocks),
     154             :             OP_EQ, -1);
     155           1 :   buf_clear(buf);
     156           1 :   expect_log_msg_containing("Port or DestIP is zero.");
     157           1 :   mock_clean_saved_logs();
     158             : 
     159             :   /* Try with 2000-byte username (!) */
     160           1 :   ADD_DATA(buf, "\x04\x01\x00\x50\x01\x02\x03\x04");
     161           1 :   int i;
     162         202 :   for (i = 0; i < 200; ++i) {
     163         200 :     ADD_DATA(buf, "1234567890");
     164             :   }
     165           1 :   ADD_DATA(buf, "\x00");
     166           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
     167             :             OP_EQ, -1);
     168           1 :   buf_clear(buf);
     169           1 :   expect_log_msg_containing("socks4: parsing failed - invalid request.");
     170           1 :   mock_clean_saved_logs();
     171             : 
     172             :   /* Try with 2000-byte hostname */
     173           1 :   ADD_DATA(buf, "\x04\x01\x00\x50\x00\x00\x00\x01\x00");
     174         202 :   for (i = 0; i < 200; ++i) {
     175         200 :     ADD_DATA(buf, "1234567890");
     176             :   }
     177           1 :   ADD_DATA(buf, "\x00");
     178             :   {
     179           1 :     const char *p;
     180           1 :     size_t s;
     181           1 :     buf_pullup(buf, 9999, &p, &s);
     182             :   }
     183           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
     184             :             OP_EQ, -1);
     185           1 :   buf_clear(buf);
     186           1 :   expect_log_msg_containing("Destaddr too long. Rejecting.");
     187           1 :   mock_clean_saved_logs();
     188             : 
     189             :   /* Try with 2000-byte hostname, not terminated. */
     190           1 :   ADD_DATA(buf, "\x04\x01\x00\x50\x00\x00\x00\x01\x00");
     191         202 :   for (i = 0; i < 200; ++i) {
     192         200 :     ADD_DATA(buf, "1234567890");
     193             :   }
     194           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
     195             :             OP_EQ, -1);
     196           1 :   buf_clear(buf);
     197           1 :   expect_log_msg_containing("parsing failed - invalid request.");
     198           1 :   mock_clean_saved_logs();
     199             : 
     200             :   /* Socks4, bogus hostname */
     201           1 :   ADD_DATA(buf, "\x04\x01\x00\x50\x00\x00\x00\x01\x00" "---\x00" );
     202           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0), OP_EQ, -1);
     203           1 :   buf_clear(buf);
     204           1 :   expect_log_msg_containing("Your application (using socks4 to port 80) "
     205           1 :                             "gave Tor a malformed hostname: ");
     206           1 :   mock_clean_saved_logs();
     207             : 
     208           1 :  done:
     209           1 :   teardown_capture_of_logs();
     210           1 : }
     211             : 
     212             : /**  Perform unsupported SOCKS 5 commands */
     213             : static void
     214           1 : test_socks_5_unsupported_commands(void *ptr)
     215             : {
     216           1 :   SOCKS_TEST_INIT();
     217             : 
     218             :   /* SOCKS 5 Send unsupported BIND [02] command */
     219           1 :   ADD_DATA(buf, "\x05\x02\x00\x01");
     220             : 
     221           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     222             :                                get_options()->SafeSocks),OP_EQ, 0);
     223           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     224           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     225           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     226           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     227           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     228           1 :   ADD_DATA(buf, "\x05\x02\x00\x01\x02\x02\x02\x01\x01\x01");
     229           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     230             :                                get_options()->SafeSocks),OP_EQ, -1);
     231             : 
     232           1 :   tt_int_op(5,OP_EQ,socks->socks_version);
     233           1 :   tt_int_op(10,OP_EQ,socks->replylen);
     234           1 :   tt_int_op(5,OP_EQ,socks->reply[0]);
     235           1 :   tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
     236           1 :   tt_int_op(1,OP_EQ,socks->reply[3]);
     237             : 
     238           1 :   buf_clear(buf);
     239           1 :   socks_request_clear(socks);
     240             : 
     241             :   /* SOCKS 5 Send unsupported UDP_ASSOCIATE [03] command */
     242           1 :   ADD_DATA(buf, "\x05\x02\x00\x01");
     243           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     244             :                                get_options()->SafeSocks),OP_EQ, 0);
     245           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     246           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     247           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     248           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     249           1 :   ADD_DATA(buf, "\x05\x03\x00\x01\x02\x02\x02\x01\x01\x01");
     250           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     251             :                                get_options()->SafeSocks),OP_EQ, -1);
     252             : 
     253           1 :   tt_int_op(5,OP_EQ,socks->socks_version);
     254           1 :   tt_int_op(10,OP_EQ,socks->replylen);
     255           1 :   tt_int_op(5,OP_EQ,socks->reply[0]);
     256           1 :   tt_int_op(SOCKS5_COMMAND_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
     257           1 :   tt_int_op(1,OP_EQ,socks->reply[3]);
     258             : 
     259           1 :  done:
     260           1 :   ;
     261           1 : }
     262             : 
     263             : /** Perform supported SOCKS 5 commands */
     264             : static void
     265           1 : test_socks_5_supported_commands(void *ptr)
     266             : {
     267           1 :   SOCKS_TEST_INIT();
     268             : 
     269             :   /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
     270           1 :   ADD_DATA(buf, "\x05\x01\x00");
     271           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     272             :                                    get_options()->SafeSocks),OP_EQ, 0);
     273           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     274           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     275           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     276           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     277             : 
     278           1 :   ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
     279           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     280             :                                    get_options()->SafeSocks),OP_EQ, 1);
     281           1 :   tt_str_op("2.2.2.2",OP_EQ, socks->address);
     282           1 :   tt_int_op(4369,OP_EQ, socks->port);
     283             : 
     284           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     285           1 :   socks_request_clear(socks);
     286             : 
     287             :   /* SOCKS 5 Send CONNECT [01] to one of the ipv6 addresses for
     288             :      torproject.org:80 */
     289           1 :   ADD_DATA(buf, "\x05\x01\x00");
     290           1 :   ADD_DATA(buf, "\x05\x01\x00\x04"
     291             :            "\x20\x02\x41\xb8\x02\x02\x0d\xeb\x02\x13\x21\xff\xfe\x20\x14\x26"
     292             :            "\x00\x50");
     293           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     294             :                                    get_options()->SafeSocks),OP_EQ, 1);
     295           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     296           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     297           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     298           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     299           1 :   tt_str_op("[2002:41b8:202:deb:213:21ff:fe20:1426]",OP_EQ, socks->address);
     300           1 :   tt_int_op(80,OP_EQ, socks->port);
     301             : 
     302           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     303           1 :   socks_request_clear(socks);
     304             : 
     305             :   /* SOCKS 5 Send CONNECT [01] to FQDN torproject.org:4369 */
     306           1 :   ADD_DATA(buf, "\x05\x01\x00");
     307           1 :   ADD_DATA(buf, "\x05\x01\x00\x03\x0Etorproject.org\x11\x11");
     308           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1,
     309             :                                    get_options()->SafeSocks),OP_EQ, 1);
     310             : 
     311           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     312           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     313           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     314           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     315           1 :   tt_str_op("torproject.org",OP_EQ, socks->address);
     316           1 :   tt_int_op(4369,OP_EQ, socks->port);
     317             : 
     318           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     319           1 :   socks_request_clear(socks);
     320             : 
     321             :   /* SOCKS 5 Send RESOLVE [F0] request for torproject.org:4369 */
     322           1 :   ADD_DATA(buf, "\x05\x01\x00");
     323           1 :   ADD_DATA(buf, "\x05\xF0\x00\x03\x0Etorproject.org\x01\x02");
     324           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     325             :                                  get_options()->SafeSocks),
     326             :             OP_EQ, 1);
     327           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     328           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     329           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     330           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     331           1 :   tt_str_op("torproject.org",OP_EQ, socks->address);
     332             : 
     333           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     334           1 :   socks_request_clear(socks);
     335             : 
     336             :   /* SOCKS 5 Should NOT reject RESOLVE [F0] request for IPv4 address
     337             :    * string if SafeSocks is enabled. */
     338             : 
     339           1 :   ADD_DATA(buf, "\x05\x01\x00");
     340           1 :   ADD_DATA(buf, "\x05\xF0\x00\x03\x07");
     341           1 :   ADD_DATA(buf, "8.8.8.8");
     342           1 :   ADD_DATA(buf, "\x11\x11");
     343           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
     344             :             OP_EQ, 1);
     345             : 
     346           1 :   tt_str_op("8.8.8.8", OP_EQ, socks->address);
     347           1 :   tt_int_op(4369, OP_EQ, socks->port);
     348             : 
     349           1 :   tt_int_op(0, OP_EQ, buf_datalen(buf));
     350             : 
     351           1 :   socks_request_clear(socks);
     352             : 
     353             :   /* SOCKS 5 should NOT reject RESOLVE [F0] request for IPv6 address
     354             :    * string if SafeSocks is enabled. */
     355             : 
     356           1 :   ADD_DATA(buf, "\x05\x01\x00");
     357           1 :   ADD_DATA(buf, "\x05\xF0\x00\x03\x29");
     358           1 :   ADD_DATA(buf, "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]");
     359           1 :   ADD_DATA(buf, "\x01\x02");
     360           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
     361             :             OP_EQ, 1);
     362             : 
     363           1 :   tt_str_op("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", OP_EQ,
     364             :     socks->address);
     365           1 :   tt_int_op(258, OP_EQ, socks->port);
     366             : 
     367           1 :   tt_int_op(0, OP_EQ, buf_datalen(buf));
     368             : 
     369           1 :   socks_request_clear(socks);
     370             : 
     371             :   /* Also allow bracket-less form. */
     372             : 
     373           1 :   ADD_DATA(buf, "\x05\x01\x00");
     374           1 :   ADD_DATA(buf, "\x05\xF0\x00\x03\x27");
     375           1 :   ADD_DATA(buf, "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
     376           1 :   ADD_DATA(buf, "\x01\x02");
     377           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
     378             :             OP_EQ, 1);
     379             : 
     380           1 :   tt_str_op("2001:0db8:85a3:0000:0000:8a2e:0370:7334", OP_EQ,
     381             :     socks->address);
     382           1 :   tt_int_op(258, OP_EQ, socks->port);
     383             : 
     384           1 :   tt_int_op(0, OP_EQ, buf_datalen(buf));
     385             : 
     386           1 :   socks_request_clear(socks);
     387             : 
     388             :   /* SOCKS 5 Send RESOLVE_PTR [F1] for IP address 2.2.2.5 */
     389           1 :   ADD_DATA(buf, "\x05\x01\x00");
     390           1 :   ADD_DATA(buf, "\x05\xF1\x00\x01\x02\x02\x02\x05\x01\x03");
     391           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     392             :                                  get_options()->SafeSocks),
     393             :             OP_EQ, 1);
     394           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     395           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     396           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     397           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     398           1 :   tt_str_op("2.2.2.5",OP_EQ, socks->address);
     399             : 
     400           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     401             : 
     402           1 :   socks_request_clear(socks);
     403             : 
     404             :   /* SOCKS 5 Send RESOLVE_PTR [F1] for an IPv6 address */
     405           1 :   ADD_DATA(buf, "\x05\x01\x00");
     406           1 :   ADD_DATA(buf, "\x05\xF1\x00\x04"
     407             :            "\x20\x01\x0d\xb8\x85\xa3\x00\x00\x00\x00\x8a\x2e\x03\x70\x73\x34"
     408             :            "\x12\x34");
     409           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     410             :                                  get_options()->SafeSocks),
     411             :             OP_EQ, 1);
     412           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     413           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     414           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     415           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     416           1 :   tt_str_op("[2001:db8:85a3::8a2e:370:7334]",OP_EQ, socks->address);
     417             : 
     418           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     419             : 
     420           1 :   socks_request_clear(socks);
     421             : 
     422             :   /* SOCKS 5 Send RESOLVE_PTR [F1] for a an IPv6 address written as a
     423             :    * string with brackets */
     424           1 :   ADD_DATA(buf, "\x05\x01\x00");
     425           1 :   ADD_DATA(buf, "\x05\xF1\x00\x03\x1e");
     426           1 :   ADD_DATA(buf, "[2001:db8:85a3::8a2e:370:7334]");
     427           1 :   ADD_DATA(buf, "\x12\x34");
     428           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     429             :                                  get_options()->SafeSocks),
     430             :             OP_EQ, 1);
     431           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     432           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     433           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     434           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     435           1 :   tt_str_op("[2001:db8:85a3::8a2e:370:7334]",OP_EQ, socks->address);
     436             : 
     437           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     438             : 
     439           1 :  done:
     440           1 :   ;
     441           1 : }
     442             : 
     443             : /**  Perform SOCKS 5 authentication */
     444             : static void
     445           1 : test_socks_5_no_authenticate(void *ptr)
     446             : {
     447           1 :   SOCKS_TEST_INIT();
     448             : 
     449             :   /*SOCKS 5 No Authentication */
     450           1 :   ADD_DATA(buf,"\x05\x01\x00");
     451           1 :   tt_assert(!fetch_from_buf_socks(buf, socks,
     452             :                                     get_options()->TestSocks,
     453             :                                     get_options()->SafeSocks));
     454           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     455           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     456           1 :   tt_int_op(SOCKS_NO_AUTH,OP_EQ, socks->reply[1]);
     457             : 
     458           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     459             : 
     460             :   /*SOCKS 5 Send username/password anyway - pretend to be broken */
     461           1 :   ADD_DATA(buf,"\x01\x02\x01\x01\x02\x01\x01");
     462           1 :   tt_assert(!fetch_from_buf_socks(buf, socks,
     463             :                                     get_options()->TestSocks,
     464             :                                     get_options()->SafeSocks));
     465           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     466           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     467           1 :   tt_int_op(1,OP_EQ, socks->reply[0]);
     468           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     469             : 
     470           1 :   tt_int_op(2,OP_EQ, socks->usernamelen);
     471           1 :   tt_int_op(2,OP_EQ, socks->passwordlen);
     472             : 
     473           1 :   tt_mem_op("\x01\x01",OP_EQ, socks->username, 2);
     474           1 :   tt_mem_op("\x01\x01",OP_EQ, socks->password, 2);
     475             : 
     476           1 :  done:
     477           1 :   ;
     478           1 : }
     479             : 
     480             : /** Perform SOCKS 5 authentication */
     481             : static void
     482           1 : test_socks_5_authenticate(void *ptr)
     483             : {
     484           1 :   SOCKS_TEST_INIT();
     485             : 
     486             :   /* SOCKS 5 Negotiate username/password authentication */
     487           1 :   ADD_DATA(buf, "\x05\x01\x02");
     488             : 
     489           1 :   tt_assert(!fetch_from_buf_socks(buf, socks,
     490             :                                    get_options()->TestSocks,
     491             :                                    get_options()->SafeSocks));
     492           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     493           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     494           1 :   tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]);
     495           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     496             : 
     497           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     498             : 
     499             :   /* SOCKS 5 Send username/password */
     500           1 :   ADD_DATA(buf, "\x01\x02me\x08mypasswd");
     501           1 :   tt_assert(!fetch_from_buf_socks(buf, socks,
     502             :                                    get_options()->TestSocks,
     503             :                                    get_options()->SafeSocks));
     504           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     505           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     506           1 :   tt_int_op(1,OP_EQ, socks->reply[0]);
     507           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     508             : 
     509           1 :   tt_int_op(2,OP_EQ, socks->usernamelen);
     510           1 :   tt_int_op(8,OP_EQ, socks->passwordlen);
     511             : 
     512           1 :   tt_mem_op("me",OP_EQ, socks->username, 2);
     513           1 :   tt_mem_op("mypasswd",OP_EQ, socks->password, 8);
     514             : 
     515           1 :  done:
     516           1 :   ;
     517           1 : }
     518             : 
     519             : /** Perform SOCKS 5 authentication with empty username/password fields.
     520             :  * Technically this violates RfC 1929, but some client software will send
     521             :  * this kind of message to Tor.
     522             :  * */
     523             : static void
     524           1 : test_socks_5_authenticate_empty_user_pass(void *ptr)
     525             : {
     526           1 :   SOCKS_TEST_INIT();
     527             : 
     528             :   /* SOCKS 5 Negotiate username/password authentication */
     529           1 :   ADD_DATA(buf, "\x05\x01\x02");
     530             : 
     531           1 :   tt_assert(!fetch_from_buf_socks(buf, socks,
     532             :                                    get_options()->TestSocks,
     533             :                                    get_options()->SafeSocks));
     534           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     535           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     536           1 :   tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]);
     537           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     538             : 
     539           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     540             : 
     541             :   /* SOCKS 5 Send username/password auth message with empty user/pass fields */
     542           1 :   ADD_DATA(buf, "\x01\x00\x00");
     543           1 :   tt_assert(!fetch_from_buf_socks(buf, socks,
     544             :                                    get_options()->TestSocks,
     545             :                                    get_options()->SafeSocks));
     546           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     547           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     548           1 :   tt_int_op(1,OP_EQ, socks->reply[0]);
     549           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     550             : 
     551           1 :   tt_int_op(0,OP_EQ, socks->usernamelen);
     552           1 :   tt_int_op(0,OP_EQ, socks->passwordlen);
     553             : 
     554           1 :  done:
     555           1 :   ;
     556           1 : }
     557             : /** Perform SOCKS 5 authentication and send data all in one go */
     558             : static void
     559           1 : test_socks_5_authenticate_with_data(void *ptr)
     560             : {
     561           1 :   SOCKS_TEST_INIT();
     562             : 
     563             :   /* SOCKS 5 Negotiate username/password authentication */
     564           1 :   ADD_DATA(buf, "\x05\x01\x02");
     565             : 
     566           1 :   tt_assert(!fetch_from_buf_socks(buf, socks,
     567             :                                    get_options()->TestSocks,
     568             :                                    get_options()->SafeSocks));
     569           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     570           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     571           1 :   tt_int_op(SOCKS_USER_PASS,OP_EQ, socks->reply[1]);
     572           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     573             : 
     574           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf));
     575             : 
     576             :   /* SOCKS 5 Send username/password */
     577             :   /* SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369 */
     578           1 :   ADD_DATA(buf, "\x01\x02me\x03you\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
     579           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     580             :                                  get_options()->SafeSocks),
     581             :             OP_EQ, 1);
     582           1 :   tt_int_op(5,OP_EQ, socks->socks_version);
     583           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     584           1 :   tt_int_op(1,OP_EQ, socks->reply[0]);
     585           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     586             : 
     587           1 :   tt_str_op("2.2.2.2",OP_EQ, socks->address);
     588           1 :   tt_int_op(4369,OP_EQ, socks->port);
     589             : 
     590           1 :   tt_int_op(2,OP_EQ, socks->usernamelen);
     591           1 :   tt_int_op(3,OP_EQ, socks->passwordlen);
     592           1 :   tt_mem_op("me",OP_EQ, socks->username, 2);
     593           1 :   tt_mem_op("you",OP_EQ, socks->password, 3);
     594             : 
     595           1 :  done:
     596           1 :   ;
     597           1 : }
     598             : 
     599             : /** Try to negotiate an unsupported authentication type */
     600             : static void
     601           1 : test_socks_5_auth_unsupported_type(void *ptr)
     602             : {
     603           1 :   SOCKS_TEST_INIT();
     604             : 
     605             :   /* None of these authentication types are recognized. */
     606           1 :   ADD_DATA(buf, "\x05\x03\x99\x21\x10");
     607           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     608             :                                  get_options()->SafeSocks),
     609             :             OP_EQ, -1);
     610           1 :   tt_int_op(0,OP_EQ, socks->socks_version);
     611           1 :   tt_int_op(2,OP_EQ, socks->replylen);
     612           1 :   tt_int_op(5,OP_EQ, socks->reply[0]);
     613           1 :   tt_int_op(0xff,OP_EQ, socks->reply[1]);
     614             : 
     615           1 :  done:
     616           1 :   ;
     617           1 : }
     618             : 
     619             : /** Try to negotiate an unsupported version of username/password auth. */
     620             : static void
     621           1 : test_socks_5_auth_unsupported_version(void *ptr)
     622             : {
     623           1 :   SOCKS_TEST_INIT();
     624             : 
     625             :   /* Negotiate username/password */
     626           1 :   ADD_DATA(buf, "\x05\x01\x02");
     627           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     628             :                                  get_options()->SafeSocks),
     629             :             OP_EQ, 0);
     630           1 :   tt_int_op(0,OP_EQ, buf_datalen(buf)); /* buf should be drained */
     631             :   /* Now, suggest an unrecognized username/password version */
     632           1 :   ADD_DATA(buf, "\x02\x05" "hello" "\x05" "world");
     633           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     634             :                                  get_options()->SafeSocks),
     635             :             OP_EQ, -1);
     636             : 
     637           1 :  done:
     638           1 :   ;
     639           1 : }
     640             : 
     641             : /** Perform SOCKS 5 authentication before method negotiated */
     642             : static void
     643           1 : test_socks_5_auth_before_negotiation(void *ptr)
     644             : {
     645           1 :   SOCKS_TEST_INIT();
     646             : 
     647             :   /* SOCKS 5 Send username/password */
     648           1 :   ADD_DATA(buf, "\x01\x02me\x02me");
     649           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     650             :                                  get_options()->SafeSocks),
     651             :             OP_EQ, -1);
     652           1 :   tt_int_op(0,OP_EQ, socks->socks_version);
     653           1 :   tt_int_op(0,OP_EQ, socks->replylen);
     654           1 :   tt_int_op(0,OP_EQ, socks->reply[0]);
     655           1 :   tt_int_op(0,OP_EQ, socks->reply[1]);
     656             : 
     657           1 :  done:
     658           1 :   ;
     659           1 : }
     660             : 
     661             : /** Perform malformed SOCKS 5 commands */
     662             : static void
     663           1 : test_socks_5_malformed_commands(void *ptr)
     664             : {
     665           1 :   SOCKS_TEST_INIT();
     666             : 
     667             :   /* XXX: Stringified address length > MAX_SOCKS_ADDR_LEN will never happen */
     668             : 
     669             :   /** SOCKS 5 Send CONNECT [01] to IP address 2.2.2.2:4369, with SafeSocks set
     670             :    */
     671           1 :   ADD_DATA(buf, "\x05\x01\x00");
     672           1 :   ADD_DATA(buf, "\x05\x01\x00\x01\x02\x02\x02\x02\x11\x11");
     673           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks, 1),
     674             :             OP_EQ, -1);
     675             : 
     676           1 :   tt_int_op(5,OP_EQ,socks->socks_version);
     677           1 :   tt_int_op(10,OP_EQ,socks->replylen);
     678           1 :   tt_int_op(5,OP_EQ,socks->reply[0]);
     679           1 :   tt_int_op(SOCKS5_NOT_ALLOWED,OP_EQ,socks->reply[1]);
     680           1 :   tt_int_op(1,OP_EQ,socks->reply[3]);
     681             : 
     682           1 :   buf_clear(buf);
     683           1 :   socks_request_clear(socks);
     684             : 
     685             :   /* SOCKS 5 Send RESOLVE_PTR [F1] for FQDN torproject.org */
     686           1 :   ADD_DATA(buf, "\x05\x01\x00");
     687           1 :   ADD_DATA(buf, "\x05\xF1\x00\x03\x0Etorproject.org\x11\x11");
     688           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     689             :                                    get_options()->SafeSocks),OP_EQ, -1);
     690             : 
     691           1 :   tt_int_op(5,OP_EQ,socks->socks_version);
     692           1 :   tt_int_op(10,OP_EQ,socks->replylen);
     693           1 :   tt_int_op(5,OP_EQ,socks->reply[0]);
     694           1 :   tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
     695           1 :   tt_int_op(1,OP_EQ,socks->reply[3]);
     696             : 
     697           1 :   buf_clear(buf);
     698           1 :   socks_request_clear(socks);
     699             : 
     700             :   /* XXX: len + 1 > MAX_SOCKS_ADDR_LEN (FQDN request) will never happen */
     701             : 
     702             :   /* SOCKS 5 Send CONNECT [01] to FQDN """"".com */
     703           1 :   ADD_DATA(buf, "\x05\x01\x00");
     704           1 :   ADD_DATA(buf, "\x05\x01\x00\x03\x09\"\"\"\"\".com\x11\x11");
     705           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     706             :                                    get_options()->SafeSocks),OP_EQ, -1);
     707             : 
     708           1 :   tt_int_op(5,OP_EQ,socks->socks_version);
     709           1 :   tt_int_op(10,OP_EQ,socks->replylen);
     710           1 :   tt_int_op(5,OP_EQ,socks->reply[0]);
     711           1 :   tt_int_op(SOCKS5_GENERAL_ERROR,OP_EQ,socks->reply[1]);
     712           1 :   tt_int_op(1,OP_EQ,socks->reply[3]);
     713             : 
     714           1 :   buf_clear(buf);
     715           1 :   socks_request_clear(socks);
     716             : 
     717             :   /* SOCKS 5 Send CONNECT [01] to address type 0x23 */
     718           1 :   ADD_DATA(buf, "\x05\x01\x00");
     719           1 :   ADD_DATA(buf, "\x05\x01\x00\x23\x02\x02\x02\x02\x11\x11");
     720           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
     721             :                                    get_options()->SafeSocks),OP_EQ, -1);
     722             : 
     723           1 :   tt_int_op(5,OP_EQ,socks->socks_version);
     724           1 :   tt_int_op(10,OP_EQ,socks->replylen);
     725           1 :   tt_int_op(5,OP_EQ,socks->reply[0]);
     726             :   /* trunnel parsing will fail with -1 */
     727           1 :   tt_int_op(SOCKS5_GENERAL_ERROR,OP_EQ,socks->reply[1]);
     728           1 :   tt_int_op(1,OP_EQ,socks->reply[3]);
     729             : 
     730           1 :  done:
     731           1 :   ;
     732           1 : }
     733             : 
     734             : static void
     735           1 : test_socks_5_bad_arguments(void *ptr)
     736             : {
     737           1 :   SOCKS_TEST_INIT();
     738           1 :   setup_capture_of_logs(LOG_DEBUG);
     739             : 
     740             :   /* Socks5, bogus hostname */
     741           1 :   ADD_DATA(buf, "\x05\x01\x00" "\x05\x01\x00\x03\x03" "---" "\x00\x50" );
     742           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0), OP_EQ, -1);
     743           1 :   buf_clear(buf);
     744           1 :   expect_log_msg_containing("Your application (using socks5 to port 80) "
     745           1 :                             "gave Tor a malformed hostname: ");
     746           1 :   mock_clean_saved_logs();
     747           1 :   socks_request_clear(socks);
     748             : 
     749           1 :  done:
     750           1 :   teardown_capture_of_logs();
     751           1 : }
     752             : 
     753             : /** check for correct behavior when the socks command has not arrived. */
     754             : static void
     755           1 : test_socks_truncated(void *ptr)
     756             : {
     757           1 :   const struct {
     758             :     enum { NONE, AUTH, ALL } setup;
     759             :     const char *body;
     760             :     size_t len;
     761           1 :   } commands[] = {
     762             :     /* SOCKS4 */
     763             :     /* Connect, to an IP. */
     764             :     { NONE, "\x04\x01\x05\x05\x01\x02\x03\x04\x00", 9},
     765             :     /* Connect, to an IP, with authentication. */
     766             :     { NONE, "\x04\x01\x05\x05\x01\x02\x03\x04hello\x00", 14},
     767             :     /* SOCKS4A */
     768             :     /* Connect, to a hostname */
     769             :     { NONE, "\x04\x01\x09\x09\x00\x00\x00\x01\x00www.example.com\x00", 25},
     770             :     /* Connect, to a hostname, with authentication */
     771             :     { NONE, "\x04\x01\x09\x09\x00\x00\x00\x01hi\x00www.example.com\x00", 27},
     772             :     /* SOCKS5 */
     773             :     /* initial handshake */
     774             :     { NONE, "\x05\x00", 2 },
     775             :     /* no-auth handshake */
     776             :     { NONE, "\x05\x03\x99\x21\x10", 5 },
     777             :     /* SOCSK5, username-password, all empty. */
     778             :     { AUTH, "\x01\x00\x00", 3 },
     779             :     /* SOCSK5, username-password, 1 char each. */
     780             :     { AUTH, "\x01\x01x\x01y", 5 },
     781             :     /* SOCSK5, username-password, max length. */
     782             :     { AUTH, "\x01\xff"
     783             :       "Ogni tempo ha il suo fascismo: se ne notano i segni premonitori "
     784             :       "dovunque la concentrazione di potere nega al cittadino la "
     785             :       "possibilit\xc3\xa0 e la capacit\xc3\xa0 di esprimere ed attuare la "
     786             :       "sua volont\xc3\xa0. A questo si arriva in molti modi, non "
     787             :       "necessariamente col terror"
     788             :       "\xff"
     789             :       "e dell'intimidazione poliziesca, ma anche negando o distorcendo "
     790             :       "l'informazione, inquinando la giustizia, paralizzando la scuola, "
     791             :       "diffondendo in molti modi sottili la nostalgia per un mondo in cui "
     792             :       "regnava sovrano l'ordine, ed in cui la sicurezza dei pochi "
     793             :       /* privilegiati riposava sul lavoro forzato e sul silenzio forzato dei
     794             :          molti. -- Primo Levi */ , 513 },
     795             :     /* Socks5, IPv4 address */
     796             :     { ALL, "\x05\x01\x00\x01\x01\x02\x03\x04\x20\x20", 10 },
     797             :     /* Socks5, IPv6 address */
     798             :     { ALL, "\x05\x01\x00\x04"
     799             :       "\x49\x20\x48\x41\x5a\x20\x45\x41\x53\x54\x45\x52\x20\x45\x47\x47"
     800             :       "\x20\x20", 22 },
     801             :     /* Socks5, hostname, empty. */
     802             :     { ALL, "\x05\x01\x00\x03" "\x00" "\x00\x50", 7 },
     803             :     /* Socks5, hostname, moderate. */
     804             :     { ALL, "\x05\x01\x00\x03" "\x11" "onion.example.com" "\x00\x50", 24 },
     805             :     /* Socks5, hostname, maximum. */
     806             :     { ALL, "\x05\x01\x00\x03" "\xff"
     807             :       "whatsoever.I.shall.see.or.hear.in.the.course.of.my.profession.as.well."
     808             :       "as.outside.my.profession.in.my.intercourse.with.men.if.it.be.what."
     809             :       "should.not.be.published.abroad.I.will.never.divulge.holding.such."
     810             :       "things.to.be.holy.secrets.x.hippocratic.oath.wikipedia"
     811             :       "\x00\x50", 262 },
     812             :   };
     813           1 :   unsigned i, j;
     814           1 :   SOCKS_TEST_INIT();
     815          15 :   for (i = 0; i < ARRAY_LENGTH(commands); ++i) {
     816         942 :     for (j = 0; j < commands[i].len; ++j) {
     817         928 :       switch (commands[i].setup) {
     818             :         default: FALLTHROUGH;
     819             :         case NONE:
     820             :           /* This test calls for no setup on the socks state. */
     821             :           break;
     822         521 :         case AUTH:
     823             :           /* This test calls for the socks state to be waiting for
     824             :            * username/password authentication */
     825         521 :           ADD_DATA(buf, "\x05\x01\x02");
     826         521 :           tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0));
     827         521 :           tt_int_op(0, OP_EQ, buf_datalen(buf));
     828             :           break;
     829         325 :         case ALL:
     830             :           /* This test calls for the socks state to be waiting for
     831             :            * the connection request */
     832         325 :           ADD_DATA(buf, "\x05\x01\x00");
     833         325 :           tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0));
     834         325 :           tt_int_op(0, OP_EQ, buf_datalen(buf));
     835             :       }
     836             : 
     837         928 :       TT_BLATHER(("Checking command %u, length %u, omitting char %u", i, j,
     838             :                   (unsigned)commands[i].body[j]));
     839         928 :       buf_add(buf, commands[i].body, j);
     840             :       /* This should return 0 meaning "not done yet" */
     841         928 :       tt_int_op(0, OP_EQ, fetch_from_buf_socks(buf, socks, 0, 0));
     842         928 :       tt_uint_op(j, OP_EQ, buf_datalen(buf)); /* Nothing was drained */
     843         928 :       buf_clear(buf);
     844         928 :       socks_request_free(testdata->req);
     845         928 :       socks = testdata->req = socks_request_new();
     846             :     }
     847             :   }
     848           1 :   done:
     849           1 :   ;
     850           1 : }
     851             : 
     852             : static void
     853           1 : test_socks_wrong_protocol(void *ptr)
     854             : {
     855           1 :   SOCKS_TEST_INIT();
     856           1 :   setup_capture_of_logs(LOG_DEBUG);
     857             : 
     858             :   /* HTTP request. */
     859           1 :   ADD_DATA(buf, "GET /index.html HTTP/1.0" );
     860           1 :   tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0), OP_EQ, -1);
     861           1 :   buf_clear(buf);
     862           1 :   expect_log_msg_containing("Socks version 71 not recognized. "
     863           1 :                             "(This port is not an HTTP proxy;");
     864           1 :   mock_clean_saved_logs();
     865           1 :   socks_request_clear(socks);
     866             : 
     867           1 :  done:
     868           1 :   teardown_capture_of_logs();
     869           1 : }
     870             : 
     871             : /* Check our client-side socks4 parsing (that is to say, our parsing of
     872             :  * server responses).
     873             :  */
     874             : static void
     875           1 : test_socks_client_v4(void *arg)
     876             : {
     877           1 :   (void)arg;
     878           1 :   buf_t *buf = buf_new();
     879           1 :   char *reason = NULL;
     880             : 
     881             :   /* Legit socks4 response, success */
     882           1 :   ADD_DATA(buf, "\x04\x5a\x20\x25\x01\x02\x03\x04");
     883           1 :   tt_int_op(1, OP_EQ,
     884             :             fetch_from_buf_socks_client(buf, PROXY_SOCKS4_WANT_CONNECT_OK,
     885             :                                         &reason));
     886           1 :   tt_ptr_op(reason, OP_EQ, NULL);
     887           1 :   tt_int_op(buf_datalen(buf), OP_EQ, 0);
     888             : 
     889             :   /* Legit socks4 response, failure. */
     890           1 :   ADD_DATA(buf, "\x04\x5b\x20\x25\x01\x02\x03\x04");
     891           1 :   tt_int_op(-1, OP_EQ,
     892             :             fetch_from_buf_socks_client(buf, PROXY_SOCKS4_WANT_CONNECT_OK,
     893             :                                         &reason));
     894           1 :   tt_ptr_op(reason, OP_NE, NULL);
     895           1 :   tt_str_op(reason, OP_EQ, "server rejected connection");
     896             : 
     897           1 :  done:
     898           1 :   buf_free(buf);
     899           1 :   tor_free(reason);
     900           1 : }
     901             : 
     902             : /* Check our client-side socks5 authentication-negotiation parsing (that is to
     903             :  * say, our parsing of server responses).
     904             :  */
     905             : static void
     906           1 : test_socks_client_v5_auth(void *arg)
     907             : {
     908           1 :   (void)arg;
     909           1 :   buf_t *buf = buf_new();
     910           1 :   char *reason = NULL;
     911             : 
     912             :   /* Legit socks5 responses, got a method we like. */
     913           1 :   ADD_DATA(buf, "\x05\x00");
     914           1 :   tt_int_op(1, OP_EQ,
     915             :             fetch_from_buf_socks_client(buf,
     916             :                                         PROXY_SOCKS5_WANT_AUTH_METHOD_NONE,
     917             :                                         &reason));
     918           1 :   tt_ptr_op(reason, OP_EQ, NULL);
     919           1 :   tt_int_op(buf_datalen(buf), OP_EQ, 0);
     920             : 
     921             :   /* Same, but we wanted something else. */
     922           1 :   ADD_DATA(buf, "\x05\x00");
     923           1 :   tt_int_op(1, OP_EQ,
     924             :             fetch_from_buf_socks_client(buf,
     925             :                                         PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929,
     926             :                                         &reason));
     927           1 :   tt_ptr_op(reason, OP_EQ, NULL);
     928           1 :   tt_int_op(buf_datalen(buf), OP_EQ, 0);
     929             : 
     930             :   /* Same, and they offered a password. */
     931           1 :   ADD_DATA(buf, "\x05\x02");
     932           1 :   tt_int_op(2, OP_EQ,
     933             :             fetch_from_buf_socks_client(buf,
     934             :                                         PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929,
     935             :                                         &reason));
     936           1 :   tt_ptr_op(reason, OP_EQ, NULL);
     937           1 :   tt_int_op(buf_datalen(buf), OP_EQ, 0);
     938             : 
     939             :   /* They rejected our method, or selected something we don't know. */
     940           1 :   ADD_DATA(buf, "\x05\xff");
     941           1 :   tt_int_op(-1, OP_EQ,
     942             :             fetch_from_buf_socks_client(buf,
     943             :                                         PROXY_SOCKS5_WANT_AUTH_METHOD_NONE,
     944             :                                         &reason));
     945           1 :   tt_str_op(reason, OP_EQ, "server doesn't support any of our available "
     946             :             "authentication methods");
     947           1 :   buf_clear(buf);
     948           1 :   tor_free(reason);
     949           1 :   ADD_DATA(buf, "\x05\xff");
     950           1 :   tt_int_op(-1, OP_EQ,
     951             :             fetch_from_buf_socks_client(buf,
     952             :                                         PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929,
     953             :                                         &reason));
     954           1 :   tt_str_op(reason, OP_EQ, "server doesn't support any of our available "
     955             :             "authentication methods");
     956           1 :   tor_free(reason);
     957           1 :   buf_clear(buf);
     958             : 
     959             :   /* Now check for authentication responses: check success and failure. */
     960           1 :   ADD_DATA(buf, "\x01\x00");
     961           1 :   tt_int_op(1, OP_EQ,
     962             :             fetch_from_buf_socks_client(buf,
     963             :                                         PROXY_SOCKS5_WANT_AUTH_RFC1929_OK,
     964             :                                         &reason));
     965           1 :   tt_ptr_op(reason, OP_EQ, NULL);
     966           1 :   tt_int_op(buf_datalen(buf), OP_EQ, 0);
     967             : 
     968           1 :   ADD_DATA(buf, "\x01\xf0");
     969           1 :   tt_int_op(-1, OP_EQ,
     970             :             fetch_from_buf_socks_client(buf,
     971             :                                         PROXY_SOCKS5_WANT_AUTH_RFC1929_OK,
     972             :                                         &reason));
     973           1 :   tt_ptr_op(reason, OP_NE, NULL);
     974           1 :   tt_str_op(reason, OP_EQ, "authentication failed");
     975             : 
     976           1 :  done:
     977           1 :   buf_free(buf);
     978           1 :   tor_free(reason);
     979           1 : }
     980             : 
     981             : /* Check our client-side socks5 connect parsing (that is to say, our parsing
     982             :  * of server responses).
     983             :  */
     984             : static void
     985           1 : test_socks_client_v5_connect(void *arg)
     986             : {
     987           1 :   (void)arg;
     988           1 :   buf_t *buf = buf_new();
     989           1 :   char *reason = NULL;
     990             : 
     991             :   /* Legit socks5 responses, success, ipv4. */
     992           1 :   ADD_DATA(buf, "\x05\x00\x00\x01\x01\x02\x03\x04\x00\x05");
     993           1 :   tt_int_op(1, OP_EQ,
     994             :             fetch_from_buf_socks_client(buf,
     995             :                                         PROXY_SOCKS5_WANT_CONNECT_OK,
     996             :                                         &reason));
     997           1 :   tt_ptr_op(reason, OP_EQ, NULL);
     998           1 :   tt_int_op(buf_datalen(buf), OP_EQ, 0);
     999             : 
    1000             :   /* Legit socks5 responses, success, ipv6. */
    1001           1 :   ADD_DATA(buf, "\x05\x00\x00\x04"
    1002             :            "abcdefghijklmnop"
    1003             :            "\x00\x05");
    1004           1 :   tt_int_op(1, OP_EQ,
    1005             :             fetch_from_buf_socks_client(buf,
    1006             :                                         PROXY_SOCKS5_WANT_CONNECT_OK,
    1007             :                                         &reason));
    1008           1 :   tt_ptr_op(reason, OP_EQ, NULL);
    1009           1 :   tt_int_op(buf_datalen(buf), OP_EQ, 0);
    1010             : 
    1011             :   /* Legit socks5 responses, success, hostname. */
    1012           1 :   ADD_DATA(buf, "\x05\x00\x00\x03\x12"
    1013             :            "gopher.example.com"
    1014             :            "\x00\x05");
    1015           1 :   tt_int_op(1, OP_EQ,
    1016             :             fetch_from_buf_socks_client(buf,
    1017             :                                         PROXY_SOCKS5_WANT_CONNECT_OK,
    1018             :                                         &reason));
    1019           1 :   tt_ptr_op(reason, OP_EQ, NULL);
    1020           1 :   tt_int_op(buf_datalen(buf), OP_EQ, 0);
    1021             : 
    1022             :   /* Legit socks5 responses, failure, hostname. */
    1023           1 :   ADD_DATA(buf, "\x05\x03\x00\x03\x12"
    1024             :            "gopher.example.com"
    1025             :            "\x00\x05");
    1026           1 :   tt_int_op(-1, OP_EQ,
    1027             :             fetch_from_buf_socks_client(buf,
    1028             :                                         PROXY_SOCKS5_WANT_CONNECT_OK,
    1029             :                                         &reason));
    1030           1 :   tt_ptr_op(reason, OP_NE, NULL);
    1031           1 :   tt_str_op(reason, OP_EQ, "Network unreachable");
    1032           1 :   tor_free(reason);
    1033           1 :   buf_clear(buf);
    1034             : 
    1035             :   /* Bogus socks5 responses: what is address type 0x17? */
    1036           1 :   ADD_DATA(buf, "\x05\x03\x00\x17\x12 blah blah");
    1037           1 :   tt_int_op(-1, OP_EQ,
    1038             :             fetch_from_buf_socks_client(buf,
    1039             :                                         PROXY_SOCKS5_WANT_CONNECT_OK,
    1040             :                                         &reason));
    1041           1 :   tt_ptr_op(reason, OP_NE, NULL);
    1042           1 :   tt_str_op(reason, OP_EQ, "invalid response to connect request");
    1043           1 :   buf_clear(buf);
    1044             : 
    1045           1 :  done:
    1046           1 :   buf_free(buf);
    1047           1 :   tor_free(reason);
    1048           1 : }
    1049             : 
    1050             : static void
    1051           1 : test_socks_client_truncated(void *arg)
    1052             : {
    1053           1 :   (void)arg;
    1054           1 :   buf_t *buf = buf_new();
    1055           1 :   char *reason = NULL;
    1056             : 
    1057             : #define S(str) str, (sizeof(str)-1)
    1058           1 :   const struct {
    1059             :     int state;
    1060             :     const char *body;
    1061             :     size_t len;
    1062           1 :   } replies[] = {
    1063             :     { PROXY_SOCKS4_WANT_CONNECT_OK, S("\x04\x5a\x20\x25\x01\x02\x03\x04") },
    1064             :     { PROXY_SOCKS4_WANT_CONNECT_OK, S("\x04\x5b\x20\x25\x01\x02\x03\x04") },
    1065             :     { PROXY_SOCKS5_WANT_AUTH_METHOD_NONE, S("\x05\x00") },
    1066             :     { PROXY_SOCKS5_WANT_AUTH_METHOD_RFC1929, S("\x05\x00") },
    1067             :     { PROXY_SOCKS5_WANT_AUTH_RFC1929_OK, S("\x01\x00") },
    1068             :     { PROXY_SOCKS5_WANT_CONNECT_OK,
    1069             :       S("\x05\x00\x00\x01\x01\x02\x03\x04\x00\x05") },
    1070             :     { PROXY_SOCKS5_WANT_CONNECT_OK,
    1071             :       S("\x05\x00\x00\x04" "abcdefghijklmnop" "\x00\x05") },
    1072             :     { PROXY_SOCKS5_WANT_CONNECT_OK,
    1073             :       S("\x05\x00\x00\x03\x12" "gopher.example.com" "\x00\x05") },
    1074             :     { PROXY_SOCKS5_WANT_CONNECT_OK,
    1075             :       S("\x05\x03\x00\x03\x12" "gopher.example.com""\x00\x05") },
    1076             :     { PROXY_SOCKS5_WANT_CONNECT_OK,
    1077             :       S("\x05\x03\x00\x17") },
    1078             :   };
    1079           1 :   unsigned i, j;
    1080          11 :   for (i = 0; i < ARRAY_LENGTH(replies); ++i) {
    1081         118 :     for (j = 0; j < replies[i].len; ++j) {
    1082         108 :       TT_BLATHER(("Checking command %u, length %u", i, j));
    1083         108 :       buf_add(buf, replies[i].body, j);
    1084             :       /* This should return 0 meaning "not done yet" */
    1085         108 :       tt_int_op(0, OP_EQ,
    1086             :                 fetch_from_buf_socks_client(buf, replies[i].state, &reason));
    1087         108 :       tt_uint_op(j, OP_EQ, buf_datalen(buf)); /* Nothing was drained */
    1088         108 :       buf_clear(buf);
    1089         108 :       tt_ptr_op(reason, OP_EQ, NULL);
    1090             :     }
    1091             :   }
    1092             : 
    1093           1 :  done:
    1094           1 :   tor_free(reason);
    1095           1 :   buf_free(buf);
    1096           1 : }
    1097             : 
    1098             : #define SOCKSENT(name)                                  \
    1099             :   { #name, test_socks_##name, TT_FORK, &socks_setup, NULL }
    1100             : 
    1101             : struct testcase_t socks_tests[] = {
    1102             :   SOCKSENT(4_unsupported_commands),
    1103             :   SOCKSENT(4_supported_commands),
    1104             :   SOCKSENT(4_bad_arguments),
    1105             : 
    1106             :   SOCKSENT(5_unsupported_commands),
    1107             :   SOCKSENT(5_supported_commands),
    1108             :   SOCKSENT(5_no_authenticate),
    1109             :   SOCKSENT(5_auth_unsupported_type),
    1110             :   SOCKSENT(5_auth_unsupported_version),
    1111             :   SOCKSENT(5_auth_before_negotiation),
    1112             :   SOCKSENT(5_authenticate),
    1113             :   SOCKSENT(5_authenticate_empty_user_pass),
    1114             :   SOCKSENT(5_authenticate_with_data),
    1115             :   SOCKSENT(5_malformed_commands),
    1116             :   SOCKSENT(5_bad_arguments),
    1117             : 
    1118             :   SOCKSENT(truncated),
    1119             : 
    1120             :   SOCKSENT(wrong_protocol),
    1121             : 
    1122             :   { "client/v4", test_socks_client_v4, TT_FORK, NULL, NULL },
    1123             :   { "client/v5_auth", test_socks_client_v5_auth, TT_FORK, NULL, NULL },
    1124             :   { "client/v5_connect", test_socks_client_v5_connect, TT_FORK, NULL, NULL },
    1125             :   { "client/truncated", test_socks_client_truncated, TT_FORK, NULL, NULL },
    1126             : 
    1127             :   END_OF_TESTCASES
    1128             : };

Generated by: LCOV version 1.14