Loading src/or/addressmap.c +4 −0 Changes for src/or/addressmap.c: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -455,6 +455,8 @@ addressmap_rewrite_reverse(char *address, size_t maxlen, unsigned flags, return 0; else if (f == AF_INET6 && !(flags & AMR_FLAG_USE_IPV6_DNS)) return 0; /* FFFF we should reverse-map virtual addresses even if we haven't * enabled DNS cacheing. */ } tor_asprintf(&s, "REVERSE[%s]", address); Loading Loading @@ -975,6 +977,8 @@ addressmap_register_virtual_address(int type, char *new_address) strmap_set(virtaddress_reversemap, new_address, vent); addressmap_register(*addrp, new_address, 2, ADDRMAPSRC_AUTOMAP, 0, 0); /* FFFF register corresponding reverse mapping. */ #if 0 { /* Try to catch possible bugs */ Loading src/test/test_entryconn.c +416 −10 Changes for src/test/test_entryconn.c: 416 added lines, 10 removed lines. Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ #include "addressmap.h" #include "config.h" #include "confparse.h" #include "connection.h" #include "connection_edge.h" Loading Loading @@ -162,12 +163,13 @@ test_entryconn_rewrite_automap_ipv4(void *arg) static void test_entryconn_rewrite_automap_ipv6(void *arg) { entry_connection_t *ec = arg; (void)arg; entry_connection_t *ec =NULL; entry_connection_t *ec2=NULL, *ec3=NULL; rewrite_result_t rr; char *msg = NULL; connection_free_(ENTRY_TO_CONN(ec)); ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6); ec = entry_connection_new(CONN_TYPE_AP, AF_INET6); ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6); ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET6); Loading @@ -190,8 +192,7 @@ test_entryconn_rewrite_automap_ipv6(void *arg) tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu"); tt_str_op(ec->original_dest_address, OP_EQ, "www.mit.edu"); printf("<%s>\n", ec->socks_request->address); /* XXXX Should this [ be here? */ /* Yes, this [ should be here. */ tt_assert(!strcmpstart(ec->socks_request->address,"[fe80:")); /* Connect to it and make sure we get the original address back. */ Loading Loading @@ -228,29 +229,425 @@ test_entryconn_rewrite_automap_ipv6(void *arg) ec->socks_request->address); done: connection_free_(ENTRY_TO_CONN(ec)); connection_free_(ENTRY_TO_CONN(ec2)); connection_free_(ENTRY_TO_CONN(ec3)); } #if 0 /* FFFF not actually supported. */ /* automap on resolve, reverse lookup. */ static void test_entryconn_rewrite_automap_reverse(void *arg) { entry_connection_t *ec = arg; entry_connection_t *ec2=NULL; rewrite_result_t rr; char *msg = NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); get_options_mutable()->AutomapHostsOnResolve = 1; get_options_mutable()->AutomapHostsSuffixes = smartlist_new(); get_options_mutable()->SafeLogging_ = SAFELOG_SCRUB_NONE; smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup(".bloom")); parse_virtual_addr_network("127.80.0.0/16", AF_INET, 0, &msg); /* Automap this on resolve. */ strlcpy(ec->socks_request->address, "www.poldy.BLOOM", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 1); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.poldy.bloom"); tt_str_op(ec->original_dest_address, OP_EQ, "www.poldy.bloom"); tt_assert(!strcmpstart(ec->socks_request->address,"127.80.")); strlcpy(ec2->socks_request->address, ec->socks_request->address, sizeof(ec2->socks_request->address)); ec2->use_cached_ipv4_answers = 1; // XXXX REMOVE. This is only there to hide a bug. ec2->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 1); tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_DONE|END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); done: connection_free_(ENTRY_TO_CONN(ec2)); } #endif /* Rewrite because of cached DNS entry. */ static void test_entryconn_rewrite_cached_dns_ipv4(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; time_t expires = time(NULL) + 3600; entry_connection_t *ec2=NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); addressmap_register("www.friendly.example.com", tor_strdup("240.240.241.241"), expires, ADDRMAPSRC_DNS, 0, 0); strlcpy(ec->socks_request->address, "www.friendly.example.com", sizeof(ec->socks_request->address)); strlcpy(ec2->socks_request->address, "www.friendly.example.com", sizeof(ec2->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; ec2->socks_request->command = SOCKS_COMMAND_CONNECT; ec2->use_cached_ipv4_answers = 1; /* only ec2 gets this flag */ connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com"); tt_str_op(ec->socks_request->address, OP_EQ, "www.friendly.example.com"); connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, expires); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com"); tt_str_op(ec2->socks_request->address, OP_EQ, "240.240.241.241"); done: connection_free_(ENTRY_TO_CONN(ec2)); } /* Rewrite because of cached DNS entry. */ static void test_entryconn_rewrite_cached_dns_ipv6(void *arg) { entry_connection_t *ec = NULL; rewrite_result_t rr; time_t expires = time(NULL) + 3600; entry_connection_t *ec2=NULL; (void)arg; ec = entry_connection_new(CONN_TYPE_AP, AF_INET6); ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6); /* Rewrite because of AddrmapRewrite option */ addressmap_register("www.friendly.example.com", tor_strdup("[::f00f]"), expires, ADDRMAPSRC_DNS, 0, 0); /* Rewrite because of control port */ strlcpy(ec->socks_request->address, "www.friendly.example.com", sizeof(ec->socks_request->address)); strlcpy(ec2->socks_request->address, "www.friendly.example.com", sizeof(ec2->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; ec2->socks_request->command = SOCKS_COMMAND_CONNECT; ec2->use_cached_ipv6_answers = 1; /* only ec2 gets this flag */ connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com"); tt_str_op(ec->socks_request->address, OP_EQ, "www.friendly.example.com"); connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, expires); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com"); tt_str_op(ec2->socks_request->address, OP_EQ, "[::f00f]"); done: connection_free_(ENTRY_TO_CONN(ec)); connection_free_(ENTRY_TO_CONN(ec2)); } /* Fail to connect to unmapped address in virtual range. */ static void test_entryconn_rewrite_unmapped_virtual(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; entry_connection_t *ec2 = NULL; char *msg = NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6); parse_virtual_addr_network("18.202.0.0/16", AF_INET, 0, &msg); parse_virtual_addr_network("[ABCD::]/16", AF_INET6, 0, &msg); strlcpy(ec->socks_request->address, "18.202.5.5", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.should_close, OP_EQ, 1); tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_INTERNAL); tt_int_op(rr.automap, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); strlcpy(ec2->socks_request->address, "[ABCD:9::5314:9543]", sizeof(ec2->socks_request->address)); ec2->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.should_close, OP_EQ, 1); tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_INTERNAL); tt_int_op(rr.automap, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); done: connection_free_(ENTRY_TO_CONN(ec2)); } /* Rewrite because of mapaddress option */ static void test_entryconn_rewrite_mapaddress(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; config_line_append(&get_options_mutable()->AddressMap, "MapAddress", "meta metaobjects.example"); config_register_addressmaps(get_options()); strlcpy(ec->socks_request->address, "meta", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_int_op(rr.automap, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(ec->socks_request->address, OP_EQ, "metaobjects.example"); done: ; } /* Reject reverse lookups of internal address. */ static void test_entryconn_rewrite_reject_internal_reverse(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; strlcpy(ec->socks_request->address, "10.0.0.1", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.should_close, OP_EQ, 1); tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_SOCKSPROTOCOL | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); tt_int_op(rr.automap, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); done: ; } /* Rewrite into .exit because of virtual address mapping */ static void test_entryconn_rewrite_automap_exit(void *arg) { entry_connection_t *ec = arg; entry_connection_t *ec2=NULL; rewrite_result_t rr; char *msg = NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); get_options_mutable()->AutomapHostsOnResolve = 1; get_options_mutable()->AutomapHostsSuffixes = smartlist_new(); get_options_mutable()->AllowDotExit = 1; smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup(".EXIT")); parse_virtual_addr_network("127.1.0.0/16", AF_INET, 0, &msg); /* Automap this on resolve. */ strlcpy(ec->socks_request->address, "website.example.exit", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 1); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "website.example.exit"); tt_str_op(ec->original_dest_address, OP_EQ, "website.example.exit"); tt_assert(!strcmpstart(ec->socks_request->address,"127.1.")); /* Connect to it and make sure we get the original address back. */ strlcpy(ec2->socks_request->address, ec->socks_request->address, sizeof(ec2->socks_request->address)); ec2->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_AUTOMAP); tt_str_op(rr.orig_address, OP_EQ, ec->socks_request->address); tt_str_op(ec2->original_dest_address, OP_EQ, ec->socks_request->address); tt_str_op(ec2->socks_request->address, OP_EQ, "website.example.exit"); done: connection_free_(ENTRY_TO_CONN(ec2)); } /* Rewrite into .exit because of mapaddress */ static void test_entryconn_rewrite_mapaddress_exit(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; /* Fail to connect to unmapped address in virtual range. */ config_line_append(&get_options_mutable()->AddressMap, "MapAddress", "*.example.com *.example.com.abc.exit"); config_register_addressmaps(get_options()); /* Automap this on resolve. */ strlcpy(ec->socks_request->address, "abc.example.com", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_TORRC); tt_str_op(rr.orig_address, OP_EQ, "abc.example.com"); tt_str_op(ec->socks_request->address, OP_EQ, "abc.example.com.abc.exit"); done: ; } /* Map foo.onion to longthing.onion, and also automap. */ static void test_entryconn_rewrite_mapaddress_automap_onion(void *arg) { entry_connection_t *ec = arg; entry_connection_t *ec2 = NULL; entry_connection_t *ec3 = NULL; entry_connection_t *ec4 = NULL; rewrite_result_t rr; char *msg = NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET); ec4 = entry_connection_new(CONN_TYPE_AP, AF_INET); get_options_mutable()->AutomapHostsOnResolve = 1; get_options_mutable()->AutomapHostsSuffixes = smartlist_new(); get_options_mutable()->AllowDotExit = 1; smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup(".onion")); parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg); config_line_append(&get_options_mutable()->AddressMap, "MapAddress", "foo.onion abcdefghijklmnop.onion"); config_register_addressmaps(get_options()); /* Connect to foo.onion. */ strlcpy(ec->socks_request->address, "foo.onion", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "foo.onion"); tt_str_op(ec->socks_request->address, OP_EQ, "abcdefghijklmnop.onion"); /* Okay, resolve foo.onion */ strlcpy(ec2->socks_request->address, "foo.onion", sizeof(ec2->socks_request->address)); ec2->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 1); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "foo.onion"); tt_assert(!strcmpstart(ec2->socks_request->address, "192.168.")); /* Rewrite plus automap */ /* Now connect */ strlcpy(ec3->socks_request->address, ec2->socks_request->address, sizeof(ec3->socks_request->address)); ec3->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec3, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_assert(!strcmpstart(ec3->socks_request->address, "abcdefghijklmnop.onion")); /* Map foo.onion to longthing.onion */ /* Now resolve abcefghijklmnop.onion. */ strlcpy(ec4->socks_request->address, "abcdefghijklmnop.onion", sizeof(ec4->socks_request->address)); ec4->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec4, &rr); tt_int_op(rr.automap, OP_EQ, 1); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "abcdefghijklmnop.onion"); tt_assert(!strcmpstart(ec4->socks_request->address, "192.168.")); /* XXXX doesn't work tt_str_op(ec4->socks_request->address, OP_EQ, ec2->socks_request->address); */ done: connection_free_(ENTRY_TO_CONN(ec2)); connection_free_(ENTRY_TO_CONN(ec3)); connection_free_(ENTRY_TO_CONN(ec4)); } #define REWRITE(name) \ { #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL } Loading @@ -260,6 +657,15 @@ struct testcase_t entryconn_tests[] = { REWRITE(rewrite_bad_dotexit), REWRITE(rewrite_automap_ipv4), REWRITE(rewrite_automap_ipv6), // REWRITE(rewrite_automap_reverse), REWRITE(rewrite_cached_dns_ipv4), REWRITE(rewrite_cached_dns_ipv6), REWRITE(rewrite_unmapped_virtual), REWRITE(rewrite_mapaddress), REWRITE(rewrite_reject_internal_reverse), REWRITE(rewrite_automap_exit), REWRITE(rewrite_mapaddress_exit), REWRITE(rewrite_mapaddress_automap_onion), END_OF_TESTCASES }; Loading
src/or/addressmap.c +4 −0 Changes for src/or/addressmap.c: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -455,6 +455,8 @@ addressmap_rewrite_reverse(char *address, size_t maxlen, unsigned flags, return 0; else if (f == AF_INET6 && !(flags & AMR_FLAG_USE_IPV6_DNS)) return 0; /* FFFF we should reverse-map virtual addresses even if we haven't * enabled DNS cacheing. */ } tor_asprintf(&s, "REVERSE[%s]", address); Loading Loading @@ -975,6 +977,8 @@ addressmap_register_virtual_address(int type, char *new_address) strmap_set(virtaddress_reversemap, new_address, vent); addressmap_register(*addrp, new_address, 2, ADDRMAPSRC_AUTOMAP, 0, 0); /* FFFF register corresponding reverse mapping. */ #if 0 { /* Try to catch possible bugs */ Loading
src/test/test_entryconn.c +416 −10 Changes for src/test/test_entryconn.c: 416 added lines, 10 removed lines. Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ #include "addressmap.h" #include "config.h" #include "confparse.h" #include "connection.h" #include "connection_edge.h" Loading Loading @@ -162,12 +163,13 @@ test_entryconn_rewrite_automap_ipv4(void *arg) static void test_entryconn_rewrite_automap_ipv6(void *arg) { entry_connection_t *ec = arg; (void)arg; entry_connection_t *ec =NULL; entry_connection_t *ec2=NULL, *ec3=NULL; rewrite_result_t rr; char *msg = NULL; connection_free_(ENTRY_TO_CONN(ec)); ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6); ec = entry_connection_new(CONN_TYPE_AP, AF_INET6); ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6); ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET6); Loading @@ -190,8 +192,7 @@ test_entryconn_rewrite_automap_ipv6(void *arg) tt_str_op(rr.orig_address, OP_EQ, "www.mit.edu"); tt_str_op(ec->original_dest_address, OP_EQ, "www.mit.edu"); printf("<%s>\n", ec->socks_request->address); /* XXXX Should this [ be here? */ /* Yes, this [ should be here. */ tt_assert(!strcmpstart(ec->socks_request->address,"[fe80:")); /* Connect to it and make sure we get the original address back. */ Loading Loading @@ -228,29 +229,425 @@ test_entryconn_rewrite_automap_ipv6(void *arg) ec->socks_request->address); done: connection_free_(ENTRY_TO_CONN(ec)); connection_free_(ENTRY_TO_CONN(ec2)); connection_free_(ENTRY_TO_CONN(ec3)); } #if 0 /* FFFF not actually supported. */ /* automap on resolve, reverse lookup. */ static void test_entryconn_rewrite_automap_reverse(void *arg) { entry_connection_t *ec = arg; entry_connection_t *ec2=NULL; rewrite_result_t rr; char *msg = NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); get_options_mutable()->AutomapHostsOnResolve = 1; get_options_mutable()->AutomapHostsSuffixes = smartlist_new(); get_options_mutable()->SafeLogging_ = SAFELOG_SCRUB_NONE; smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup(".bloom")); parse_virtual_addr_network("127.80.0.0/16", AF_INET, 0, &msg); /* Automap this on resolve. */ strlcpy(ec->socks_request->address, "www.poldy.BLOOM", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 1); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.poldy.bloom"); tt_str_op(ec->original_dest_address, OP_EQ, "www.poldy.bloom"); tt_assert(!strcmpstart(ec->socks_request->address,"127.80.")); strlcpy(ec2->socks_request->address, ec->socks_request->address, sizeof(ec2->socks_request->address)); ec2->use_cached_ipv4_answers = 1; // XXXX REMOVE. This is only there to hide a bug. ec2->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 1); tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_DONE|END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); done: connection_free_(ENTRY_TO_CONN(ec2)); } #endif /* Rewrite because of cached DNS entry. */ static void test_entryconn_rewrite_cached_dns_ipv4(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; time_t expires = time(NULL) + 3600; entry_connection_t *ec2=NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); addressmap_register("www.friendly.example.com", tor_strdup("240.240.241.241"), expires, ADDRMAPSRC_DNS, 0, 0); strlcpy(ec->socks_request->address, "www.friendly.example.com", sizeof(ec->socks_request->address)); strlcpy(ec2->socks_request->address, "www.friendly.example.com", sizeof(ec2->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; ec2->socks_request->command = SOCKS_COMMAND_CONNECT; ec2->use_cached_ipv4_answers = 1; /* only ec2 gets this flag */ connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com"); tt_str_op(ec->socks_request->address, OP_EQ, "www.friendly.example.com"); connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, expires); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com"); tt_str_op(ec2->socks_request->address, OP_EQ, "240.240.241.241"); done: connection_free_(ENTRY_TO_CONN(ec2)); } /* Rewrite because of cached DNS entry. */ static void test_entryconn_rewrite_cached_dns_ipv6(void *arg) { entry_connection_t *ec = NULL; rewrite_result_t rr; time_t expires = time(NULL) + 3600; entry_connection_t *ec2=NULL; (void)arg; ec = entry_connection_new(CONN_TYPE_AP, AF_INET6); ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6); /* Rewrite because of AddrmapRewrite option */ addressmap_register("www.friendly.example.com", tor_strdup("[::f00f]"), expires, ADDRMAPSRC_DNS, 0, 0); /* Rewrite because of control port */ strlcpy(ec->socks_request->address, "www.friendly.example.com", sizeof(ec->socks_request->address)); strlcpy(ec2->socks_request->address, "www.friendly.example.com", sizeof(ec2->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; ec2->socks_request->command = SOCKS_COMMAND_CONNECT; ec2->use_cached_ipv6_answers = 1; /* only ec2 gets this flag */ connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com"); tt_str_op(ec->socks_request->address, OP_EQ, "www.friendly.example.com"); connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, expires); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "www.friendly.example.com"); tt_str_op(ec2->socks_request->address, OP_EQ, "[::f00f]"); done: connection_free_(ENTRY_TO_CONN(ec)); connection_free_(ENTRY_TO_CONN(ec2)); } /* Fail to connect to unmapped address in virtual range. */ static void test_entryconn_rewrite_unmapped_virtual(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; entry_connection_t *ec2 = NULL; char *msg = NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6); parse_virtual_addr_network("18.202.0.0/16", AF_INET, 0, &msg); parse_virtual_addr_network("[ABCD::]/16", AF_INET6, 0, &msg); strlcpy(ec->socks_request->address, "18.202.5.5", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.should_close, OP_EQ, 1); tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_INTERNAL); tt_int_op(rr.automap, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); strlcpy(ec2->socks_request->address, "[ABCD:9::5314:9543]", sizeof(ec2->socks_request->address)); ec2->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.should_close, OP_EQ, 1); tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_INTERNAL); tt_int_op(rr.automap, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); done: connection_free_(ENTRY_TO_CONN(ec2)); } /* Rewrite because of mapaddress option */ static void test_entryconn_rewrite_mapaddress(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; config_line_append(&get_options_mutable()->AddressMap, "MapAddress", "meta metaobjects.example"); config_register_addressmaps(get_options()); strlcpy(ec->socks_request->address, "meta", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_int_op(rr.automap, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(ec->socks_request->address, OP_EQ, "metaobjects.example"); done: ; } /* Reject reverse lookups of internal address. */ static void test_entryconn_rewrite_reject_internal_reverse(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; strlcpy(ec->socks_request->address, "10.0.0.1", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.should_close, OP_EQ, 1); tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_SOCKSPROTOCOL | END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED); tt_int_op(rr.automap, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); done: ; } /* Rewrite into .exit because of virtual address mapping */ static void test_entryconn_rewrite_automap_exit(void *arg) { entry_connection_t *ec = arg; entry_connection_t *ec2=NULL; rewrite_result_t rr; char *msg = NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); get_options_mutable()->AutomapHostsOnResolve = 1; get_options_mutable()->AutomapHostsSuffixes = smartlist_new(); get_options_mutable()->AllowDotExit = 1; smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup(".EXIT")); parse_virtual_addr_network("127.1.0.0/16", AF_INET, 0, &msg); /* Automap this on resolve. */ strlcpy(ec->socks_request->address, "website.example.exit", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 1); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "website.example.exit"); tt_str_op(ec->original_dest_address, OP_EQ, "website.example.exit"); tt_assert(!strcmpstart(ec->socks_request->address,"127.1.")); /* Connect to it and make sure we get the original address back. */ strlcpy(ec2->socks_request->address, ec->socks_request->address, sizeof(ec2->socks_request->address)); ec2->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_AUTOMAP); tt_str_op(rr.orig_address, OP_EQ, ec->socks_request->address); tt_str_op(ec2->original_dest_address, OP_EQ, ec->socks_request->address); tt_str_op(ec2->socks_request->address, OP_EQ, "website.example.exit"); done: connection_free_(ENTRY_TO_CONN(ec2)); } /* Rewrite into .exit because of mapaddress */ static void test_entryconn_rewrite_mapaddress_exit(void *arg) { entry_connection_t *ec = arg; rewrite_result_t rr; /* Fail to connect to unmapped address in virtual range. */ config_line_append(&get_options_mutable()->AddressMap, "MapAddress", "*.example.com *.example.com.abc.exit"); config_register_addressmaps(get_options()); /* Automap this on resolve. */ strlcpy(ec->socks_request->address, "abc.example.com", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_TORRC); tt_str_op(rr.orig_address, OP_EQ, "abc.example.com"); tt_str_op(ec->socks_request->address, OP_EQ, "abc.example.com.abc.exit"); done: ; } /* Map foo.onion to longthing.onion, and also automap. */ static void test_entryconn_rewrite_mapaddress_automap_onion(void *arg) { entry_connection_t *ec = arg; entry_connection_t *ec2 = NULL; entry_connection_t *ec3 = NULL; entry_connection_t *ec4 = NULL; rewrite_result_t rr; char *msg = NULL; ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET); ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET); ec4 = entry_connection_new(CONN_TYPE_AP, AF_INET); get_options_mutable()->AutomapHostsOnResolve = 1; get_options_mutable()->AutomapHostsSuffixes = smartlist_new(); get_options_mutable()->AllowDotExit = 1; smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup(".onion")); parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg); config_line_append(&get_options_mutable()->AddressMap, "MapAddress", "foo.onion abcdefghijklmnop.onion"); config_register_addressmaps(get_options()); /* Connect to foo.onion. */ strlcpy(ec->socks_request->address, "foo.onion", sizeof(ec->socks_request->address)); ec->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "foo.onion"); tt_str_op(ec->socks_request->address, OP_EQ, "abcdefghijklmnop.onion"); /* Okay, resolve foo.onion */ strlcpy(ec2->socks_request->address, "foo.onion", sizeof(ec2->socks_request->address)); ec2->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec2, &rr); tt_int_op(rr.automap, OP_EQ, 1); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "foo.onion"); tt_assert(!strcmpstart(ec2->socks_request->address, "192.168.")); /* Rewrite plus automap */ /* Now connect */ strlcpy(ec3->socks_request->address, ec2->socks_request->address, sizeof(ec3->socks_request->address)); ec3->socks_request->command = SOCKS_COMMAND_CONNECT; connection_ap_handshake_rewrite(ec3, &rr); tt_int_op(rr.automap, OP_EQ, 0); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_assert(!strcmpstart(ec3->socks_request->address, "abcdefghijklmnop.onion")); /* Map foo.onion to longthing.onion */ /* Now resolve abcefghijklmnop.onion. */ strlcpy(ec4->socks_request->address, "abcdefghijklmnop.onion", sizeof(ec4->socks_request->address)); ec4->socks_request->command = SOCKS_COMMAND_RESOLVE; connection_ap_handshake_rewrite(ec4, &rr); tt_int_op(rr.automap, OP_EQ, 1); tt_int_op(rr.should_close, OP_EQ, 0); tt_int_op(rr.end_reason, OP_EQ, 0); tt_i64_op(rr.map_expires, OP_EQ, TIME_MAX); tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE); tt_str_op(rr.orig_address, OP_EQ, "abcdefghijklmnop.onion"); tt_assert(!strcmpstart(ec4->socks_request->address, "192.168.")); /* XXXX doesn't work tt_str_op(ec4->socks_request->address, OP_EQ, ec2->socks_request->address); */ done: connection_free_(ENTRY_TO_CONN(ec2)); connection_free_(ENTRY_TO_CONN(ec3)); connection_free_(ENTRY_TO_CONN(ec4)); } #define REWRITE(name) \ { #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL } Loading @@ -260,6 +657,15 @@ struct testcase_t entryconn_tests[] = { REWRITE(rewrite_bad_dotexit), REWRITE(rewrite_automap_ipv4), REWRITE(rewrite_automap_ipv6), // REWRITE(rewrite_automap_reverse), REWRITE(rewrite_cached_dns_ipv4), REWRITE(rewrite_cached_dns_ipv6), REWRITE(rewrite_unmapped_virtual), REWRITE(rewrite_mapaddress), REWRITE(rewrite_reject_internal_reverse), REWRITE(rewrite_automap_exit), REWRITE(rewrite_mapaddress_exit), REWRITE(rewrite_mapaddress_automap_onion), END_OF_TESTCASES };