Skip to content
Snippets Groups Projects
Commit bba995e6 authored by Nick Mathewson's avatar Nick Mathewson :game_die:
Browse files

Begin writing unit tests for rewrite code

parent 715fdfcb
No related branches found
No related tags found
No related merge requests found
......@@ -924,6 +924,7 @@ connection_ap_handshake_rewrite(entry_connection_t *conn,
out->map_expires = TIME_MAX;
out->end_reason = 0;
out->should_close = 0;
out->orig_address[0] = 0;
tor_strlower(socks->address); /* normalize it */
strlcpy(out->orig_address, socks->address, sizeof(out->orig_address));
......
......@@ -151,7 +151,8 @@ typedef struct {
*/
char orig_address[MAX_SOCKS_ADDR_LEN];
/** True iff the address has been automatically remapped to a local
* address in VirtualAddrNetwork */
* address in VirtualAddrNetwork. (Only set true the first time we
* do the mapping.) */
int automap;
/** If this connection has a .exit address, who put it there? */
addressmap_entry_source_t exit_source;
......
......@@ -31,6 +31,7 @@ src_test_test_SOURCES = \
src/test/test_data.c \
src/test/test_dir.c \
src/test/test_checkdir.c \
src/test/test_entryconn.c \
src/test/test_entrynodes.c \
src/test/test_extorport.c \
src/test/test_introduce.c \
......
......@@ -1313,6 +1313,7 @@ extern struct testcase_t channel_tests[];
extern struct testcase_t channeltls_tests[];
extern struct testcase_t relay_tests[];
extern struct testcase_t scheduler_tests[];
extern struct testcase_t entryconn_tests[];
static struct testgroup_t testgroups[] = {
{ "", test_array },
......@@ -1337,6 +1338,7 @@ static struct testgroup_t testgroups[] = {
{ "circuitmux/", circuitmux_tests },
{ "options/", options_tests },
{ "entrynodes/", entrynodes_tests },
{ "entryconn/", entryconn_tests },
{ "extorport/", extorport_tests },
{ "control/", controller_event_tests },
{ "hs/", hs_tests },
......
/* Copyright (c) 2014-2015, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define CONNECTION_PRIVATE
#define CONNECTION_EDGE_PRIVATE
#include "or.h"
#include "test.h"
#include "addressmap.h"
#include "config.h"
#include "connection.h"
#include "connection_edge.h"
static void *
entryconn_rewrite_setup(const struct testcase_t *tc)
{
(void)tc;
entry_connection_t *ec = entry_connection_new(CONN_TYPE_AP, AF_INET);
addressmap_init();
return ec;
}
static int
entryconn_rewrite_teardown(const struct testcase_t *tc, void *arg)
{
(void)tc;
entry_connection_t *ec = arg;
if (ec)
connection_free_(ENTRY_TO_CONN(ec));
addressmap_free_all();
return 1;
}
static struct testcase_setup_t test_rewrite_setup = {
entryconn_rewrite_setup, entryconn_rewrite_teardown
};
/* Simple rewrite: no changes needed */
static void
test_entryconn_rewrite_basic(void *arg)
{
entry_connection_t *ec = arg;
rewrite_result_t rr;
tt_assert(ec->socks_request);
strlcpy(ec->socks_request->address, "www.TORproject.org",
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(rr.orig_address, OP_EQ, "www.torproject.org");
tt_str_op(ec->socks_request->address, OP_EQ, "www.torproject.org");
tt_str_op(ec->original_dest_address, OP_EQ, "www.torproject.org");
done:
;
}
/* Rewrite but reject because of disallowed .exit */
static void
test_entryconn_rewrite_bad_dotexit(void *arg)
{
entry_connection_t *ec = arg;
rewrite_result_t rr;
get_options_mutable()->AllowDotExit = 0;
tt_assert(ec->socks_request);
strlcpy(ec->socks_request->address, "www.TORproject.org.foo.exit",
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_TORPROTOCOL);
done:
;
}
/* Automap on resolve, connect to automapped address, resolve again and get
* same answer. (IPv4) */
static void
test_entryconn_rewrite_automap_ipv4(void *arg)
{
entry_connection_t *ec = arg;
entry_connection_t *ec2=NULL, *ec3=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);
get_options_mutable()->AutomapHostsOnResolve = 1;
get_options_mutable()->AutomapHostsSuffixes = smartlist_new();
smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup("."));
parse_virtual_addr_network("127.202.0.0/16", AF_INET, 0, &msg);
/* Automap this on resolve. */
strlcpy(ec->socks_request->address, "WWW.MIT.EDU",
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.mit.edu");
tt_str_op(ec->original_dest_address, OP_EQ, "www.mit.edu");
tt_assert(!strcmpstart(ec->socks_request->address,"127.202."));
/* 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_NONE);
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, "www.mit.edu");
/* Resolve it again, make sure the answer is the same. */
strlcpy(ec3->socks_request->address, "www.MIT.EDU",
sizeof(ec3->socks_request->address));
ec3->socks_request->command = SOCKS_COMMAND_RESOLVE;
connection_ap_handshake_rewrite(ec3, &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.mit.edu");
tt_str_op(ec3->original_dest_address, OP_EQ, "www.mit.edu");
tt_str_op(ec3->socks_request->address, OP_EQ,
ec->socks_request->address);
done:
connection_free_(ENTRY_TO_CONN(ec2));
connection_free_(ENTRY_TO_CONN(ec3));
}
/* Automap on resolve, connect to automapped address, resolve again and get
* same answer. (IPv6) */
static void
test_entryconn_rewrite_automap_ipv6(void *arg)
{
entry_connection_t *ec = arg;
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);
ec2 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
get_options_mutable()->AutomapHostsOnResolve = 1;
get_options_mutable()->AutomapHostsSuffixes = smartlist_new();
smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup("."));
parse_virtual_addr_network("FE80::/32", AF_INET6, 0, &msg);
/* Automap this on resolve. */
strlcpy(ec->socks_request->address, "WWW.MIT.EDU",
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.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? */
tt_assert(!strcmpstart(ec->socks_request->address,"[fe80:"));
/* 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_NONE);
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, "www.mit.edu");
/* Resolve it again, make sure the answer is the same. */
strlcpy(ec3->socks_request->address, "www.MIT.EDU",
sizeof(ec3->socks_request->address));
ec3->socks_request->command = SOCKS_COMMAND_RESOLVE;
connection_ap_handshake_rewrite(ec3, &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.mit.edu");
tt_str_op(ec3->original_dest_address, OP_EQ, "www.mit.edu");
tt_str_op(ec3->socks_request->address, OP_EQ,
ec->socks_request->address);
done:
connection_free_(ENTRY_TO_CONN(ec2));
connection_free_(ENTRY_TO_CONN(ec3));
}
/* automap on resolve, reverse lookup. */
/* Rewrite because of cached DNS entry. */
/* Rewrite because of AddrmapRewrite option */
/* Rewrite because of control port */
/* Rewrite into .exit because of virtual address mapping */
/* Rewrite into .exit because of mapaddress */
/* Fail to connect to unmapped address in virtual range. */
/* Rewrite plus automap */
/* Map foo.onion to longthing.onion */
#define REWRITE(name) \
{ #name, test_entryconn_##name, TT_FORK, &test_rewrite_setup, NULL }
struct testcase_t entryconn_tests[] = {
REWRITE(rewrite_basic),
REWRITE(rewrite_bad_dotexit),
REWRITE(rewrite_automap_ipv4),
REWRITE(rewrite_automap_ipv6),
END_OF_TESTCASES
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment