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

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

Generated by: LCOV version 1.14