tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

test_socks.c (40830B)


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