tor

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

test_entryconn.c (27393B)


      1 /* Copyright (c) 2014-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 #include "orconfig.h"
      5 
      6 #define CONNECTION_PRIVATE
      7 #define CONNECTION_EDGE_PRIVATE
      8 
      9 #include "core/or/or.h"
     10 #include "test/test.h"
     11 
     12 #include "feature/client/addressmap.h"
     13 #include "app/config/config.h"
     14 #include "lib/confmgt/confmgt.h"
     15 #include "core/mainloop/connection.h"
     16 #include "core/or/connection_edge.h"
     17 #include "feature/nodelist/nodelist.h"
     18 
     19 #include "feature/hs/hs_cache.h"
     20 
     21 #include "core/or/entry_connection_st.h"
     22 #include "core/or/socks_request_st.h"
     23 
     24 #include "lib/encoding/confline.h"
     25 
     26 static void *
     27 entryconn_rewrite_setup(const struct testcase_t *tc)
     28 {
     29  (void)tc;
     30  entry_connection_t *ec = entry_connection_new(CONN_TYPE_AP, AF_INET);
     31  addressmap_init();
     32  return ec;
     33 }
     34 
     35 static int
     36 entryconn_rewrite_teardown(const struct testcase_t *tc, void *arg)
     37 {
     38  (void)tc;
     39  entry_connection_t *ec = arg;
     40  if (ec)
     41    connection_free_minimal(ENTRY_TO_CONN(ec));
     42  addressmap_free_all();
     43  return 1;
     44 }
     45 
     46 static struct testcase_setup_t test_rewrite_setup = {
     47  entryconn_rewrite_setup, entryconn_rewrite_teardown
     48 };
     49 
     50 /* Simple rewrite: no changes needed */
     51 static void
     52 test_entryconn_rewrite_basic(void *arg)
     53 {
     54  entry_connection_t *ec = arg;
     55  rewrite_result_t rr;
     56 
     57  tt_assert(ec->socks_request);
     58  strlcpy(ec->socks_request->address, "www.TORproject.org",
     59          sizeof(ec->socks_request->address));
     60  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
     61  connection_ap_handshake_rewrite(ec, &rr);
     62 
     63  tt_int_op(rr.should_close, OP_EQ, 0);
     64  tt_int_op(rr.end_reason, OP_EQ, 0);
     65  tt_int_op(rr.automap, OP_EQ, 0);
     66  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
     67  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
     68  tt_str_op(rr.orig_address, OP_EQ, "www.torproject.org");
     69  tt_str_op(ec->socks_request->address, OP_EQ, "www.torproject.org");
     70  tt_str_op(ec->original_dest_address, OP_EQ, "www.torproject.org");
     71 
     72 done:
     73  ;
     74 }
     75 
     76 /* Rewrite but reject because of disallowed .exit */
     77 static void
     78 test_entryconn_rewrite_bad_dotexit(void *arg)
     79 {
     80  entry_connection_t *ec = arg;
     81  rewrite_result_t rr;
     82 
     83  tt_assert(ec->socks_request);
     84  strlcpy(ec->socks_request->address, "www.TORproject.org.foo.exit",
     85          sizeof(ec->socks_request->address));
     86  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
     87  connection_ap_handshake_rewrite(ec, &rr);
     88 
     89  tt_int_op(rr.should_close, OP_EQ, 1);
     90  tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_TORPROTOCOL);
     91 
     92 done:
     93  ;
     94 }
     95 
     96 /* Automap on resolve, connect to automapped address, resolve again and get
     97 * same answer. (IPv4) */
     98 static void
     99 test_entryconn_rewrite_automap_ipv4(void *arg)
    100 {
    101  entry_connection_t *ec = arg;
    102  entry_connection_t *ec2=NULL, *ec3=NULL;
    103  rewrite_result_t rr;
    104  char *msg = NULL;
    105 
    106  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    107  ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    108 
    109  get_options_mutable()->AutomapHostsOnResolve = 1;
    110  smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes, ".");
    111  parse_virtual_addr_network("127.202.0.0/16", AF_INET, 0, &msg);
    112 
    113  /* Automap this on resolve. */
    114  strlcpy(ec->socks_request->address, "WWW.MIT.EDU",
    115          sizeof(ec->socks_request->address));
    116  ec->socks_request->command = SOCKS_COMMAND_RESOLVE;
    117  connection_ap_handshake_rewrite(ec, &rr);
    118 
    119  tt_int_op(rr.automap, OP_EQ, 1);
    120  tt_int_op(rr.should_close, OP_EQ, 0);
    121  tt_int_op(rr.end_reason, OP_EQ, 0);
    122  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    123  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    124  tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu");
    125  tt_str_op(ec->original_dest_address, OP_EQ, "www.mit.edu");
    126 
    127  tt_assert(!strcmpstart(ec->socks_request->address,"127.202."));
    128 
    129  /* Connect to it and make sure we get the original address back. */
    130  strlcpy(ec2->socks_request->address, ec->socks_request->address,
    131          sizeof(ec2->socks_request->address));
    132 
    133  ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
    134  connection_ap_handshake_rewrite(ec2, &rr);
    135 
    136  tt_int_op(rr.automap, OP_EQ, 0);
    137  tt_int_op(rr.should_close, OP_EQ, 0);
    138  tt_int_op(rr.end_reason, OP_EQ, 0);
    139  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    140  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    141  tt_str_op(rr.orig_address, OP_EQ, ec->socks_request->address);
    142  tt_str_op(ec2->original_dest_address, OP_EQ, ec->socks_request->address);
    143  tt_str_op(ec2->socks_request->address, OP_EQ, "www.mit.edu");
    144 
    145  /* Resolve it again, make sure the answer is the same. */
    146  strlcpy(ec3->socks_request->address, "www.MIT.EDU",
    147          sizeof(ec3->socks_request->address));
    148  ec3->socks_request->command = SOCKS_COMMAND_RESOLVE;
    149  connection_ap_handshake_rewrite(ec3, &rr);
    150 
    151  tt_int_op(rr.automap, OP_EQ, 1);
    152  tt_int_op(rr.should_close, OP_EQ, 0);
    153  tt_int_op(rr.end_reason, OP_EQ, 0);
    154  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    155  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    156  tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu");
    157  tt_str_op(ec3->original_dest_address, OP_EQ, "www.mit.edu");
    158 
    159  tt_str_op(ec3->socks_request->address, OP_EQ,
    160            ec->socks_request->address);
    161 
    162 done:
    163  connection_free_minimal(ENTRY_TO_CONN(ec2));
    164  connection_free_minimal(ENTRY_TO_CONN(ec3));
    165 }
    166 
    167 /* Automap on resolve, connect to automapped address, resolve again and get
    168 * same answer. (IPv6) */
    169 static void
    170 test_entryconn_rewrite_automap_ipv6(void *arg)
    171 {
    172  (void)arg;
    173  entry_connection_t *ec =NULL;
    174  entry_connection_t *ec2=NULL, *ec3=NULL;
    175  rewrite_result_t rr;
    176  char *msg = NULL;
    177 
    178  ec = entry_connection_new(CONN_TYPE_AP, AF_INET6);
    179  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
    180  ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
    181 
    182  get_options_mutable()->AutomapHostsOnResolve = 1;
    183  smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes, ".");
    184  parse_virtual_addr_network("FE80::/32", AF_INET6, 0, &msg);
    185 
    186  /* Automap this on resolve. */
    187  strlcpy(ec->socks_request->address, "WWW.MIT.EDU",
    188          sizeof(ec->socks_request->address));
    189  ec->socks_request->command = SOCKS_COMMAND_RESOLVE;
    190  connection_ap_handshake_rewrite(ec, &rr);
    191 
    192  tt_int_op(rr.automap, OP_EQ, 1);
    193  tt_int_op(rr.should_close, OP_EQ, 0);
    194  tt_int_op(rr.end_reason, OP_EQ, 0);
    195  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    196  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    197  tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu");
    198  tt_str_op(ec->original_dest_address, OP_EQ, "www.mit.edu");
    199 
    200  /* Yes, this [ should be here. */
    201  tt_assert(!strcmpstart(ec->socks_request->address,"[fe80:"));
    202 
    203  /* Connect to it and make sure we get the original address back. */
    204  strlcpy(ec2->socks_request->address, ec->socks_request->address,
    205          sizeof(ec2->socks_request->address));
    206 
    207  ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
    208  connection_ap_handshake_rewrite(ec2, &rr);
    209 
    210  tt_int_op(rr.automap, OP_EQ, 0);
    211  tt_int_op(rr.should_close, OP_EQ, 0);
    212  tt_int_op(rr.end_reason, OP_EQ, 0);
    213  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    214  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    215  tt_str_op(rr.orig_address, OP_EQ, ec->socks_request->address);
    216  tt_str_op(ec2->original_dest_address, OP_EQ, ec->socks_request->address);
    217  tt_str_op(ec2->socks_request->address, OP_EQ, "www.mit.edu");
    218 
    219  /* Resolve it again, make sure the answer is the same. */
    220  strlcpy(ec3->socks_request->address, "www.MIT.EDU",
    221          sizeof(ec3->socks_request->address));
    222  ec3->socks_request->command = SOCKS_COMMAND_RESOLVE;
    223  connection_ap_handshake_rewrite(ec3, &rr);
    224 
    225  tt_int_op(rr.automap, OP_EQ, 1);
    226  tt_int_op(rr.should_close, OP_EQ, 0);
    227  tt_int_op(rr.end_reason, OP_EQ, 0);
    228  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    229  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    230  tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu");
    231  tt_str_op(ec3->original_dest_address, OP_EQ, "www.mit.edu");
    232 
    233  tt_str_op(ec3->socks_request->address, OP_EQ,
    234            ec->socks_request->address);
    235 
    236 done:
    237  connection_free_minimal(ENTRY_TO_CONN(ec));
    238  connection_free_minimal(ENTRY_TO_CONN(ec2));
    239  connection_free_minimal(ENTRY_TO_CONN(ec3));
    240 }
    241 
    242 #if 0
    243 /* FFFF not actually supported. */
    244 /* automap on resolve, reverse lookup. */
    245 static void
    246 test_entryconn_rewrite_automap_reverse(void *arg)
    247 {
    248  entry_connection_t *ec = arg;
    249  entry_connection_t *ec2=NULL;
    250  rewrite_result_t rr;
    251  char *msg = NULL;
    252 
    253  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    254 
    255  get_options_mutable()->AutomapHostsOnResolve = 1;
    256  get_options_mutable()->SafeLogging_ = SAFELOG_SCRUB_NONE;
    257  smartlist_add(get_options_mutable()->AutomapHostsSuffixes,
    258                tor_strdup(".bloom"));
    259  parse_virtual_addr_network("127.80.0.0/16", AF_INET, 0, &msg);
    260 
    261  /* Automap this on resolve. */
    262  strlcpy(ec->socks_request->address, "www.poldy.BLOOM",
    263          sizeof(ec->socks_request->address));
    264  ec->socks_request->command = SOCKS_COMMAND_RESOLVE;
    265  connection_ap_handshake_rewrite(ec, &rr);
    266 
    267  tt_int_op(rr.automap, OP_EQ, 1);
    268  tt_int_op(rr.should_close, OP_EQ, 0);
    269  tt_int_op(rr.end_reason, OP_EQ, 0);
    270  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    271  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    272  tt_str_op(rr.orig_address, OP_EQ, "www.poldy.bloom");
    273  tt_str_op(ec->original_dest_address, OP_EQ, "www.poldy.bloom");
    274 
    275  tt_assert(!strcmpstart(ec->socks_request->address,"127.80."));
    276 
    277  strlcpy(ec2->socks_request->address, ec->socks_request->address,
    278          sizeof(ec2->socks_request->address));
    279  ec2->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
    280  connection_ap_handshake_rewrite(ec2, &rr);
    281 
    282  tt_int_op(rr.automap, OP_EQ, 0);
    283  tt_int_op(rr.should_close, OP_EQ, 1);
    284  tt_int_op(rr.end_reason, OP_EQ,
    285          END_STREAM_REASON_DONE|END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
    286  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    287  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    288 
    289 done:
    290  connection_free_minimal(ENTRY_TO_CONN(ec2));
    291 }
    292 #endif /* 0 */
    293 
    294 /* Rewrite because of cached DNS entry. */
    295 static void
    296 test_entryconn_rewrite_cached_dns_ipv4(void *arg)
    297 {
    298  entry_connection_t *ec = arg;
    299  rewrite_result_t rr;
    300  time_t expires = time(NULL) + 3600;
    301  entry_connection_t *ec2=NULL;
    302 
    303  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    304 
    305  addressmap_register("www.friendly.example.com",
    306                      tor_strdup("240.240.241.241"),
    307                      expires,
    308                      ADDRMAPSRC_DNS,
    309                      0, 0, 0);
    310 
    311  strlcpy(ec->socks_request->address, "www.friendly.example.com",
    312          sizeof(ec->socks_request->address));
    313  strlcpy(ec2->socks_request->address, "www.friendly.example.com",
    314          sizeof(ec2->socks_request->address));
    315 
    316  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
    317  ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
    318 
    319  ec2->entry_cfg.use_cached_ipv4_answers = 1; /* only ec2 gets this flag */
    320  connection_ap_handshake_rewrite(ec, &rr);
    321 
    322  tt_int_op(rr.automap, OP_EQ, 0);
    323  tt_int_op(rr.should_close, OP_EQ, 0);
    324  tt_int_op(rr.end_reason, OP_EQ, 0);
    325  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    326  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    327  tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com");
    328  tt_str_op(ec->socks_request->address, OP_EQ, "www.friendly.example.com");
    329 
    330  connection_ap_handshake_rewrite(ec2, &rr);
    331  tt_int_op(rr.automap, OP_EQ, 0);
    332  tt_int_op(rr.should_close, OP_EQ, 0);
    333  tt_int_op(rr.end_reason, OP_EQ, 0);
    334  tt_i64_op(rr.map_expires, OP_EQ, expires);
    335  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    336  tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com");
    337  tt_str_op(ec2->socks_request->address, OP_EQ, "240.240.241.241");
    338 
    339 done:
    340  connection_free_minimal(ENTRY_TO_CONN(ec2));
    341 }
    342 
    343 /* Rewrite because of cached DNS entry. */
    344 static void
    345 test_entryconn_rewrite_cached_dns_ipv6(void *arg)
    346 {
    347  entry_connection_t *ec = NULL;
    348  rewrite_result_t rr;
    349  time_t expires = time(NULL) + 3600;
    350  entry_connection_t *ec2=NULL;
    351 
    352  (void)arg;
    353 
    354  ec  = entry_connection_new(CONN_TYPE_AP, AF_INET6);
    355  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
    356 
    357  addressmap_register("www.friendly.example.com",
    358                      tor_strdup("[::f00f]"),
    359                      expires,
    360                      ADDRMAPSRC_DNS,
    361                      0, 0, 0);
    362 
    363  strlcpy(ec->socks_request->address, "www.friendly.example.com",
    364          sizeof(ec->socks_request->address));
    365  strlcpy(ec2->socks_request->address, "www.friendly.example.com",
    366          sizeof(ec2->socks_request->address));
    367 
    368  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
    369  ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
    370 
    371  ec2->entry_cfg.use_cached_ipv6_answers = 1; /* only ec2 gets this flag */
    372  connection_ap_handshake_rewrite(ec, &rr);
    373 
    374  tt_int_op(rr.automap, OP_EQ, 0);
    375  tt_int_op(rr.should_close, OP_EQ, 0);
    376  tt_int_op(rr.end_reason, OP_EQ, 0);
    377  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    378  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    379  tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com");
    380  tt_str_op(ec->socks_request->address, OP_EQ, "www.friendly.example.com");
    381 
    382  connection_ap_handshake_rewrite(ec2, &rr);
    383  tt_int_op(rr.automap, OP_EQ, 0);
    384  tt_int_op(rr.should_close, OP_EQ, 0);
    385  tt_int_op(rr.end_reason, OP_EQ, 0);
    386  tt_i64_op(rr.map_expires, OP_EQ, expires);
    387  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    388  tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com");
    389  tt_str_op(ec2->socks_request->address, OP_EQ, "[::f00f]");
    390 
    391 done:
    392  connection_free_minimal(ENTRY_TO_CONN(ec));
    393  connection_free_minimal(ENTRY_TO_CONN(ec2));
    394 }
    395 
    396 /* Fail to connect to unmapped address in virtual range. */
    397 static void
    398 test_entryconn_rewrite_unmapped_virtual(void *arg)
    399 {
    400  entry_connection_t *ec = arg;
    401  rewrite_result_t rr;
    402  entry_connection_t *ec2 = NULL;
    403  char *msg = NULL;
    404 
    405  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
    406 
    407  parse_virtual_addr_network("18.202.0.0/16", AF_INET, 0, &msg);
    408  parse_virtual_addr_network("[ABCD::]/16", AF_INET6, 0, &msg);
    409 
    410  strlcpy(ec->socks_request->address, "18.202.5.5",
    411          sizeof(ec->socks_request->address));
    412  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
    413  connection_ap_handshake_rewrite(ec, &rr);
    414 
    415  tt_int_op(rr.should_close, OP_EQ, 1);
    416  tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_INTERNAL);
    417  tt_int_op(rr.automap, OP_EQ, 0);
    418  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    419  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    420 
    421  strlcpy(ec2->socks_request->address, "[ABCD:9::5314:9543]",
    422          sizeof(ec2->socks_request->address));
    423  ec2->socks_request->command = SOCKS_COMMAND_CONNECT;
    424  connection_ap_handshake_rewrite(ec2, &rr);
    425 
    426  tt_int_op(rr.should_close, OP_EQ, 1);
    427  tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_INTERNAL);
    428  tt_int_op(rr.automap, OP_EQ, 0);
    429  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    430  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    431 
    432 done:
    433  connection_free_minimal(ENTRY_TO_CONN(ec2));
    434 }
    435 
    436 /* Rewrite because of mapaddress option */
    437 static void
    438 test_entryconn_rewrite_mapaddress(void *arg)
    439 {
    440  entry_connection_t *ec = arg;
    441  rewrite_result_t rr;
    442 
    443  config_line_append(&get_options_mutable()->AddressMap,
    444                     "MapAddress", "meta metaobjects.example");
    445  config_register_addressmaps(get_options());
    446 
    447  strlcpy(ec->socks_request->address, "meta",
    448          sizeof(ec->socks_request->address));
    449  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
    450  connection_ap_handshake_rewrite(ec, &rr);
    451 
    452  tt_int_op(rr.should_close, OP_EQ, 0);
    453  tt_int_op(rr.end_reason, OP_EQ, 0);
    454  tt_int_op(rr.automap, OP_EQ, 0);
    455  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    456  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    457  tt_str_op(ec->socks_request->address, OP_EQ, "metaobjects.example");
    458 
    459 done:
    460  ;
    461 }
    462 
    463 /* Reject reverse lookups of internal address. */
    464 static void
    465 test_entryconn_rewrite_reject_internal_reverse(void *arg)
    466 {
    467  entry_connection_t *ec = arg;
    468  rewrite_result_t rr;
    469 
    470  strlcpy(ec->socks_request->address, "10.0.0.1",
    471          sizeof(ec->socks_request->address));
    472  ec->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
    473  connection_ap_handshake_rewrite(ec, &rr);
    474 
    475  tt_int_op(rr.should_close, OP_EQ, 1);
    476  tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_SOCKSPROTOCOL |
    477            END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
    478  tt_int_op(rr.automap, OP_EQ, 0);
    479  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    480  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    481 
    482 done:
    483  ;
    484 }
    485 
    486 /* Rewrite into .exit because of virtual address mapping.  */
    487 static void
    488 test_entryconn_rewrite_automap_exit(void *arg)
    489 {
    490  entry_connection_t *ec = arg;
    491  entry_connection_t *ec2=NULL;
    492  rewrite_result_t rr;
    493  char *msg = NULL;
    494 
    495  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    496 
    497  smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
    498                ".EXIT");
    499  parse_virtual_addr_network("127.1.0.0/16", AF_INET, 0, &msg);
    500 
    501  /* Try to automap this on resolve. */
    502  strlcpy(ec->socks_request->address, "website.example.exit",
    503          sizeof(ec->socks_request->address));
    504  ec->socks_request->command = SOCKS_COMMAND_RESOLVE;
    505  connection_ap_handshake_rewrite(ec, &rr);
    506 
    507  /* Make sure it isn't allowed -- there is no longer an AllowDotExit
    508   * option. */
    509  tt_int_op(rr.automap, OP_EQ, 0);
    510  tt_int_op(rr.should_close, OP_EQ, 1);
    511  tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_TORPROTOCOL);
    512 
    513 done:
    514  connection_free_minimal(ENTRY_TO_CONN(ec2));
    515 }
    516 
    517 /* Rewrite into .exit because of mapaddress */
    518 static void
    519 test_entryconn_rewrite_mapaddress_exit(void *arg)
    520 {
    521  entry_connection_t *ec = arg;
    522  rewrite_result_t rr;
    523 
    524  config_line_append(&get_options_mutable()->AddressMap,
    525                     "MapAddress", "*.example.com  *.example.com.abc.exit");
    526  config_register_addressmaps(get_options());
    527 
    528  /* Automap this on resolve. */
    529  strlcpy(ec->socks_request->address, "abc.example.com",
    530          sizeof(ec->socks_request->address));
    531  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
    532  connection_ap_handshake_rewrite(ec, &rr);
    533 
    534  tt_int_op(rr.automap, OP_EQ, 0);
    535  tt_int_op(rr.should_close, OP_EQ, 0);
    536  tt_int_op(rr.end_reason, OP_EQ, 0);
    537  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    538  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_TORRC);
    539  tt_str_op(rr.orig_address, OP_EQ, "abc.example.com");
    540  tt_str_op(ec->socks_request->address, OP_EQ, "abc.example.com.abc.exit");
    541 done:
    542  ;
    543 }
    544 
    545 /* Map foo.onion to longthing.onion, and also automap. */
    546 static void
    547 test_entryconn_rewrite_mapaddress_automap_onion(void *arg)
    548 {
    549  entry_connection_t *ec = arg;
    550  entry_connection_t *ec2 = NULL;
    551  entry_connection_t *ec3 = NULL;
    552  entry_connection_t *ec4 = NULL;
    553  rewrite_result_t rr;
    554  char *msg = NULL;
    555 
    556  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    557  ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    558  ec4 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    559 
    560  get_options_mutable()->AutomapHostsOnResolve = 1;
    561  smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
    562                ".onion");
    563  parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
    564  config_line_append(&get_options_mutable()->AddressMap,
    565                     "MapAddress", "foo.onion abcdefghijklmnop.onion");
    566  config_register_addressmaps(get_options());
    567 
    568  /* Connect to foo.onion. */
    569  strlcpy(ec->socks_request->address, "foo.onion",
    570          sizeof(ec->socks_request->address));
    571  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
    572  connection_ap_handshake_rewrite(ec, &rr);
    573 
    574  tt_int_op(rr.automap, OP_EQ, 0);
    575  tt_int_op(rr.should_close, OP_EQ, 0);
    576  tt_int_op(rr.end_reason, OP_EQ, 0);
    577  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    578  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    579  tt_str_op(rr.orig_address, OP_EQ, "foo.onion");
    580  tt_str_op(ec->socks_request->address, OP_EQ, "abcdefghijklmnop.onion");
    581 
    582  /* Okay, resolve foo.onion */
    583  strlcpy(ec2->socks_request->address, "foo.onion",
    584          sizeof(ec2->socks_request->address));
    585  ec2->socks_request->command = SOCKS_COMMAND_RESOLVE;
    586  connection_ap_handshake_rewrite(ec2, &rr);
    587 
    588  tt_int_op(rr.automap, OP_EQ, 1);
    589  tt_int_op(rr.should_close, OP_EQ, 0);
    590  tt_int_op(rr.end_reason, OP_EQ, 0);
    591  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    592  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    593  tt_str_op(rr.orig_address, OP_EQ, "foo.onion");
    594  tt_assert(!strcmpstart(ec2->socks_request->address, "192.168."));
    595 
    596  /* Now connect */
    597  strlcpy(ec3->socks_request->address, ec2->socks_request->address,
    598          sizeof(ec3->socks_request->address));
    599  ec3->socks_request->command = SOCKS_COMMAND_CONNECT;
    600  connection_ap_handshake_rewrite(ec3, &rr);
    601  tt_int_op(rr.automap, OP_EQ, 0);
    602  tt_int_op(rr.should_close, OP_EQ, 0);
    603  tt_int_op(rr.end_reason, OP_EQ, 0);
    604  tt_assert(!strcmpstart(ec3->socks_request->address,
    605                         "abcdefghijklmnop.onion"));
    606 
    607  /* Now resolve abcefghijklmnop.onion. */
    608  strlcpy(ec4->socks_request->address, "abcdefghijklmnop.onion",
    609          sizeof(ec4->socks_request->address));
    610  ec4->socks_request->command = SOCKS_COMMAND_RESOLVE;
    611  connection_ap_handshake_rewrite(ec4, &rr);
    612 
    613  tt_int_op(rr.automap, OP_EQ, 1);
    614  tt_int_op(rr.should_close, OP_EQ, 0);
    615  tt_int_op(rr.end_reason, OP_EQ, 0);
    616  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    617  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    618  tt_str_op(rr.orig_address, OP_EQ, "abcdefghijklmnop.onion");
    619  tt_assert(!strcmpstart(ec4->socks_request->address, "192.168."));
    620  /* XXXX doesn't work
    621   tt_str_op(ec4->socks_request->address, OP_EQ, ec2->socks_request->address);
    622  */
    623 
    624 done:
    625  connection_free_minimal(ENTRY_TO_CONN(ec2));
    626  connection_free_minimal(ENTRY_TO_CONN(ec3));
    627  connection_free_minimal(ENTRY_TO_CONN(ec4));
    628 }
    629 
    630 static void
    631 test_entryconn_rewrite_mapaddress_automap_onion_common(entry_connection_t *ec,
    632                                                       int map_to_onion,
    633                                                       int map_to_address)
    634 {
    635  entry_connection_t *ec2 = NULL;
    636  entry_connection_t *ec3 = NULL;
    637  rewrite_result_t rr;
    638 
    639  ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    640  ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET);
    641 
    642  /* Connect to irc.example.com */
    643  strlcpy(ec->socks_request->address, "irc.example.com",
    644          sizeof(ec->socks_request->address));
    645  ec->socks_request->command = SOCKS_COMMAND_CONNECT;
    646  connection_ap_handshake_rewrite(ec, &rr);
    647 
    648  tt_int_op(rr.automap, OP_EQ, 0);
    649  tt_int_op(rr.should_close, OP_EQ, 0);
    650  tt_int_op(rr.end_reason, OP_EQ, 0);
    651  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    652  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    653  tt_str_op(rr.orig_address, OP_EQ, "irc.example.com");
    654  tt_str_op(ec->socks_request->address, OP_EQ,
    655            map_to_onion ? "abcdefghijklmnop.onion" : "irc.example.com");
    656 
    657  /* Okay, resolve irc.example.com */
    658  strlcpy(ec2->socks_request->address, "irc.example.com",
    659          sizeof(ec2->socks_request->address));
    660  ec2->socks_request->command = SOCKS_COMMAND_RESOLVE;
    661  connection_ap_handshake_rewrite(ec2, &rr);
    662 
    663  tt_int_op(rr.automap, OP_EQ, map_to_onion && map_to_address);
    664  tt_int_op(rr.should_close, OP_EQ, 0);
    665  tt_int_op(rr.end_reason, OP_EQ, 0);
    666  tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX);
    667  tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
    668  tt_str_op(rr.orig_address, OP_EQ, "irc.example.com");
    669  if (map_to_onion && map_to_address)
    670    tt_assert(!strcmpstart(ec2->socks_request->address, "192.168."));
    671 
    672  /* Now connect */
    673  strlcpy(ec3->socks_request->address, ec2->socks_request->address,
    674          sizeof(ec3->socks_request->address));
    675  ec3->socks_request->command = SOCKS_COMMAND_CONNECT;
    676  connection_ap_handshake_rewrite(ec3, &rr);
    677  tt_int_op(rr.automap, OP_EQ, 0);
    678  tt_int_op(rr.should_close, OP_EQ, 0);
    679  tt_int_op(rr.end_reason, OP_EQ, 0);
    680  if (map_to_onion)
    681    tt_assert(!strcmpstart(ec3->socks_request->address,
    682                           "abcdefghijklmnop.onion"));
    683 
    684 done:
    685  connection_free_minimal(ENTRY_TO_CONN(ec2));
    686  connection_free_minimal(ENTRY_TO_CONN(ec3));
    687 }
    688 
    689 /* This time is the same, but we start with a mapping from a non-onion
    690 * address. */
    691 static void
    692 test_entryconn_rewrite_mapaddress_automap_onion2(void *arg)
    693 {
    694  char *msg = NULL;
    695  get_options_mutable()->AutomapHostsOnResolve = 1;
    696  smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
    697                ".onion");
    698  parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
    699  config_line_append(&get_options_mutable()->AddressMap,
    700                     "MapAddress", "irc.example.com abcdefghijklmnop.onion");
    701  config_register_addressmaps(get_options());
    702 
    703  test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 1, 1);
    704 }
    705 
    706 /* Same as above, with automapped turned off */
    707 static void
    708 test_entryconn_rewrite_mapaddress_automap_onion3(void *arg)
    709 {
    710  config_line_append(&get_options_mutable()->AddressMap,
    711                     "MapAddress", "irc.example.com abcdefghijklmnop.onion");
    712  config_register_addressmaps(get_options());
    713 
    714  test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 1, 0);
    715 }
    716 
    717 /* As above, with no mapping. */
    718 static void
    719 test_entryconn_rewrite_mapaddress_automap_onion4(void *arg)
    720 {
    721  char *msg = NULL;
    722  get_options_mutable()->AutomapHostsOnResolve = 1;
    723  smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
    724                ".onion");
    725  parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
    726 
    727  test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 0, 1);
    728 }
    729 
    730 /** Test that rewrite functions can handle v3 onion addresses */
    731 static void
    732 test_entryconn_rewrite_onion_v3(void *arg)
    733 {
    734  int retval;
    735  entry_connection_t *conn = arg;
    736 
    737  (void) arg;
    738 
    739  hs_cache_init();
    740 
    741  /* Make a SOCKS request */
    742  conn->socks_request->command = SOCKS_COMMAND_CONNECT;
    743  strlcpy(conn->socks_request->address,
    744          "git.25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid.onion",
    745          sizeof(conn->socks_request->address));
    746 
    747  /* Make an onion connection using the SOCKS request */
    748  conn->entry_cfg.onion_traffic = 1;
    749  ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_SOCKS_WAIT;
    750  tt_assert(!ENTRY_TO_EDGE_CONN(conn)->hs_ident);
    751 
    752  /* Handle SOCKS and rewrite! */
    753  retval = connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL);
    754  tt_int_op(retval, OP_EQ, 0);
    755 
    756  /* Check connection state after rewrite. It should be in waiting for
    757   * descriptor state. */
    758  tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_RENDDESC_WAIT);
    759  /* check that the address got rewritten */
    760  tt_str_op(conn->socks_request->address, OP_EQ,
    761            "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid");
    762  /* check that HS information got attached to the connection */
    763  tt_assert(ENTRY_TO_EDGE_CONN(conn)->hs_ident);
    764 
    765 done:
    766  hs_free_all();
    767  /* 'conn' is cleaned by handler */
    768 }
    769 
    770 #define REWRITE(name)                           \
    771  { #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL }
    772 
    773 struct testcase_t entryconn_tests[] = {
    774  REWRITE(rewrite_basic),
    775  REWRITE(rewrite_bad_dotexit),
    776  REWRITE(rewrite_automap_ipv4),
    777  REWRITE(rewrite_automap_ipv6),
    778  // REWRITE(rewrite_automap_reverse),
    779  REWRITE(rewrite_cached_dns_ipv4),
    780  REWRITE(rewrite_cached_dns_ipv6),
    781  REWRITE(rewrite_unmapped_virtual),
    782  REWRITE(rewrite_mapaddress),
    783  REWRITE(rewrite_reject_internal_reverse),
    784  REWRITE(rewrite_automap_exit),
    785  REWRITE(rewrite_mapaddress_exit),
    786  REWRITE(rewrite_mapaddress_automap_onion),
    787  REWRITE(rewrite_mapaddress_automap_onion2),
    788  REWRITE(rewrite_mapaddress_automap_onion3),
    789  REWRITE(rewrite_mapaddress_automap_onion4),
    790  REWRITE(rewrite_onion_v3),
    791 
    792  END_OF_TESTCASES
    793 };