diff options
Diffstat (limited to 'src/test/test_config.c')
-rw-r--r-- | src/test/test_config.c | 317 |
1 files changed, 291 insertions, 26 deletions
diff --git a/src/test/test_config.c b/src/test/test_config.c index 6a91453e8c..dcb4e92c56 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2013, The Tor Project, Inc. */ + * Copyright (c) 2007-2014, The Tor Project, Inc. */ /* See LICENSE for licensing information */ #include "orconfig.h" @@ -14,6 +14,8 @@ #include "test.h" #include "util.h" #include "address.h" +#include "entrynodes.h" +#include "transports.h" static void test_config_addressmap(void *arg) @@ -63,22 +65,22 @@ test_config_addressmap(void *arg) /* MapAddress .google.com .torserver.exit */ strlcpy(address, "reader.google.com", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "reader.torserver.exit"); + tt_str_op(address,OP_EQ, "reader.torserver.exit"); /* MapAddress *.yahoo.com *.google.com.torserver.exit */ strlcpy(address, "reader.yahoo.com", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "reader.google.com.torserver.exit"); + tt_str_op(address,OP_EQ, "reader.google.com.torserver.exit"); /*MapAddress *.cnn.com www.cnn.com */ strlcpy(address, "cnn.com", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "www.cnn.com"); + tt_str_op(address,OP_EQ, "www.cnn.com"); /* MapAddress .cn.com www.cnn.com */ strlcpy(address, "www.cn.com", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "www.cnn.com"); + tt_str_op(address,OP_EQ, "www.cnn.com"); /* MapAddress ex.com www.cnn.com - no match */ strlcpy(address, "www.ex.com", sizeof(address)); @@ -91,19 +93,19 @@ test_config_addressmap(void *arg) /* Where mapping for FQDN match on FQDN */ strlcpy(address, "www.google.com", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "3.3.3.3"); + tt_str_op(address,OP_EQ, "3.3.3.3"); strlcpy(address, "www.torproject.org", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "1.1.1.1"); + tt_str_op(address,OP_EQ, "1.1.1.1"); strlcpy(address, "other.torproject.org", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "this.torproject.org.otherserver.exit"); + tt_str_op(address,OP_EQ, "this.torproject.org.otherserver.exit"); strlcpy(address, "test.torproject.org", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "2.2.2.2"); + tt_str_op(address,OP_EQ, "2.2.2.2"); /* Test a chain of address mappings and the order in which they were added: "MapAddress www.example.org 4.4.4.4" @@ -112,12 +114,12 @@ test_config_addressmap(void *arg) */ strlcpy(address, "www.example.org", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "5.5.5.5"); + tt_str_op(address,OP_EQ, "5.5.5.5"); /* Test infinite address mapping results in no change */ strlcpy(address, "www.infiniteloop.org", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "www.infiniteloop.org"); + tt_str_op(address,OP_EQ, "www.infiniteloop.org"); /* Test we don't find false positives */ strlcpy(address, "www.example.com", sizeof(address)); @@ -135,23 +137,23 @@ test_config_addressmap(void *arg) strlcpy(address, "www.abc.com", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "www.abc.torserver.exit"); + tt_str_op(address,OP_EQ, "www.abc.torserver.exit"); strlcpy(address, "www.def.com", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "www.def.torserver.exit"); + tt_str_op(address,OP_EQ, "www.def.torserver.exit"); strlcpy(address, "www.torproject.org", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "1.1.1.1"); + tt_str_op(address,OP_EQ, "1.1.1.1"); strlcpy(address, "test.torproject.org", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "1.1.1.1"); + tt_str_op(address,OP_EQ, "1.1.1.1"); strlcpy(address, "torproject.net", sizeof(address)); tt_assert(addressmap_rewrite(address, sizeof(address), &expires, NULL)); - tt_str_op(address,==, "2.2.2.2"); + tt_str_op(address,OP_EQ, "2.2.2.2"); /* We don't support '*' as a mapping directive */ config_free_lines(get_options_mutable()->AddressMap); @@ -211,9 +213,9 @@ test_config_check_or_create_data_subdir(void *arg) subpath = get_datadir_fname(subdir); #if defined (_WIN32) - tt_int_op(mkdir(options->DataDirectory), ==, 0); + tt_int_op(mkdir(options->DataDirectory), OP_EQ, 0); #else - tt_int_op(mkdir(options->DataDirectory, 0700), ==, 0); + tt_int_op(mkdir(options->DataDirectory, 0700), OP_EQ, 0); #endif r = stat(subpath, &st); @@ -285,9 +287,9 @@ test_config_write_to_data_subdir(void *arg) filepath = get_datadir_fname2(subdir, fname); #if defined (_WIN32) - tt_int_op(mkdir(options->DataDirectory), ==, 0); + tt_int_op(mkdir(options->DataDirectory), OP_EQ, 0); #else - tt_int_op(mkdir(options->DataDirectory, 0700), ==, 0); + tt_int_op(mkdir(options->DataDirectory, 0700), OP_EQ, 0); #endif // Write attempt shoudl fail, if subdirectory doesn't exist. @@ -298,13 +300,13 @@ test_config_write_to_data_subdir(void *arg) // equal to the original string. tt_assert(!write_to_data_subdir(subdir, fname, str, NULL)); cp = read_file_to_str(filepath, 0, NULL); - tt_str_op(cp,==, str); + tt_str_op(cp,OP_EQ, str); tor_free(cp); // A second write operation should overwrite the old content. tt_assert(!write_to_data_subdir(subdir, fname, str, NULL)); cp = read_file_to_str(filepath, 0, NULL); - tt_str_op(cp,==, str); + tt_str_op(cp,OP_EQ, str); tor_free(cp); done: @@ -329,7 +331,7 @@ good_bridge_line_test(const char *string, const char *test_addrport, /* test addrport */ tmp = tor_strdup(fmt_addrport(&bridge_line->addr, bridge_line->port)); - tt_str_op(test_addrport,==, tmp); + tt_str_op(test_addrport,OP_EQ, tmp); tor_free(tmp); /* If we were asked to validate a digest, but we did not get a @@ -347,7 +349,7 @@ good_bridge_line_test(const char *string, const char *test_addrport, if (test_digest) { tmp = tor_strdup(hex_str(bridge_line->digest, DIGEST_LEN)); tor_strlower(tmp); - tt_str_op(test_digest,==, tmp); + tt_str_op(test_digest,OP_EQ, tmp); tor_free(tmp); } @@ -358,7 +360,7 @@ good_bridge_line_test(const char *string, const char *test_addrport, if (!test_transport && bridge_line->transport_name) tt_assert(0); if (test_transport) - tt_str_op(test_transport,==, bridge_line->transport_name); + tt_str_op(test_transport,OP_EQ, bridge_line->transport_name); /* Validate the SOCKS argument smartlist. */ if (test_socks_args && !bridge_line->socks_args) @@ -552,6 +554,267 @@ test_config_parse_transport_options_line(void *arg) } } +/* Mocks needed for the transport plugin line test */ + +static void pt_kickstart_proxy_mock(const smartlist_t *transport_list, + char **proxy_argv, int is_server); +static int transport_add_from_config_mock(const tor_addr_t *addr, + uint16_t port, const char *name, + int socks_ver); +static int transport_is_needed_mock(const char *transport_name); + +static int pt_kickstart_proxy_mock_call_count = 0; +static int transport_add_from_config_mock_call_count = 0; +static int transport_is_needed_mock_call_count = 0; +static int transport_is_needed_mock_return = 0; + +static void +pt_kickstart_proxy_mock(const smartlist_t *transport_list, + char **proxy_argv, int is_server) +{ + (void) transport_list; + (void) proxy_argv; + (void) is_server; + /* XXXX check that args are as expected. */ + + ++pt_kickstart_proxy_mock_call_count; +} + +static int +transport_add_from_config_mock(const tor_addr_t *addr, + uint16_t port, const char *name, + int socks_ver) +{ + (void) addr; + (void) port; + (void) name; + (void) socks_ver; + /* XXXX check that args are as expected. */ + + ++transport_add_from_config_mock_call_count; + + return 0; +} + +static int +transport_is_needed_mock(const char *transport_name) +{ + (void) transport_name; + /* XXXX check that arg is as expected. */ + + ++transport_is_needed_mock_call_count; + + return transport_is_needed_mock_return; +} + +/** + * Test parsing for the ClientTransportPlugin and ServerTransportPlugin config + * options. + */ + +static void +test_config_parse_transport_plugin_line(void *arg) +{ + (void)arg; + + or_options_t *options = get_options_mutable(); + int r, tmp; + int old_pt_kickstart_proxy_mock_call_count; + int old_transport_add_from_config_mock_call_count; + int old_transport_is_needed_mock_call_count; + + /* Bad transport lines - too short */ + r = parse_transport_line(options, "bad", 1, 0); + tt_assert(r < 0); + r = parse_transport_line(options, "bad", 1, 1); + tt_assert(r < 0); + r = parse_transport_line(options, "bad bad", 1, 0); + tt_assert(r < 0); + r = parse_transport_line(options, "bad bad", 1, 1); + tt_assert(r < 0); + + /* Test transport list parsing */ + r = parse_transport_line(options, + "transport_1 exec /usr/bin/fake-transport", 1, 0); + tt_assert(r == 0); + r = parse_transport_line(options, + "transport_1 exec /usr/bin/fake-transport", 1, 1); + tt_assert(r == 0); + r = parse_transport_line(options, + "transport_1,transport_2 exec /usr/bin/fake-transport", 1, 0); + tt_assert(r == 0); + r = parse_transport_line(options, + "transport_1,transport_2 exec /usr/bin/fake-transport", 1, 1); + tt_assert(r == 0); + /* Bad transport identifiers */ + r = parse_transport_line(options, + "transport_* exec /usr/bin/fake-transport", 1, 0); + tt_assert(r < 0); + r = parse_transport_line(options, + "transport_* exec /usr/bin/fake-transport", 1, 1); + tt_assert(r < 0); + + /* Check SOCKS cases for client transport */ + r = parse_transport_line(options, + "transport_1 socks4 1.2.3.4:567", 1, 0); + tt_assert(r == 0); + r = parse_transport_line(options, + "transport_1 socks5 1.2.3.4:567", 1, 0); + tt_assert(r == 0); + /* Proxy case for server transport */ + r = parse_transport_line(options, + "transport_1 proxy 1.2.3.4:567", 1, 1); + tt_assert(r == 0); + /* Multiple-transport error exit */ + r = parse_transport_line(options, + "transport_1,transport_2 socks5 1.2.3.4:567", 1, 0); + tt_assert(r < 0); + r = parse_transport_line(options, + "transport_1,transport_2 proxy 1.2.3.4:567", 1, 1); + /* No port error exit */ + r = parse_transport_line(options, + "transport_1 socks5 1.2.3.4", 1, 0); + tt_assert(r < 0); + r = parse_transport_line(options, + "transport_1 proxy 1.2.3.4", 1, 1); + tt_assert(r < 0); + /* Unparsable address error exit */ + r = parse_transport_line(options, + "transport_1 socks5 1.2.3:6x7", 1, 0); + tt_assert(r < 0); + r = parse_transport_line(options, + "transport_1 proxy 1.2.3:6x7", 1, 1); + tt_assert(r < 0); + + /* "Strange {Client|Server}TransportPlugin field" error exit */ + r = parse_transport_line(options, + "transport_1 foo bar", 1, 0); + tt_assert(r < 0); + r = parse_transport_line(options, + "transport_1 foo bar", 1, 1); + tt_assert(r < 0); + + /* No sandbox mode error exit */ + tmp = options->Sandbox; + options->Sandbox = 1; + r = parse_transport_line(options, + "transport_1 exec /usr/bin/fake-transport", 1, 0); + tt_assert(r < 0); + r = parse_transport_line(options, + "transport_1 exec /usr/bin/fake-transport", 1, 1); + tt_assert(r < 0); + options->Sandbox = tmp; + + /* + * These final test cases cover code paths that only activate without + * validate_only, so they need mocks in place. + */ + MOCK(pt_kickstart_proxy, pt_kickstart_proxy_mock); + old_pt_kickstart_proxy_mock_call_count = + pt_kickstart_proxy_mock_call_count; + r = parse_transport_line(options, + "transport_1 exec /usr/bin/fake-transport", 0, 1); + tt_assert(r == 0); + tt_assert(pt_kickstart_proxy_mock_call_count == + old_pt_kickstart_proxy_mock_call_count + 1); + UNMOCK(pt_kickstart_proxy); + + /* This one hits a log line in the !validate_only case only */ + r = parse_transport_line(options, + "transport_1 proxy 1.2.3.4:567", 0, 1); + tt_assert(r == 0); + + /* Check mocked client transport cases */ + MOCK(pt_kickstart_proxy, pt_kickstart_proxy_mock); + MOCK(transport_add_from_config, transport_add_from_config_mock); + MOCK(transport_is_needed, transport_is_needed_mock); + + /* Unnecessary transport case */ + transport_is_needed_mock_return = 0; + old_pt_kickstart_proxy_mock_call_count = + pt_kickstart_proxy_mock_call_count; + old_transport_add_from_config_mock_call_count = + transport_add_from_config_mock_call_count; + old_transport_is_needed_mock_call_count = + transport_is_needed_mock_call_count; + r = parse_transport_line(options, + "transport_1 exec /usr/bin/fake-transport", 0, 0); + /* Should have succeeded */ + tt_assert(r == 0); + /* transport_is_needed() should have been called */ + tt_assert(transport_is_needed_mock_call_count == + old_transport_is_needed_mock_call_count + 1); + /* + * pt_kickstart_proxy() and transport_add_from_config() should + * not have been called. + */ + tt_assert(pt_kickstart_proxy_mock_call_count == + old_pt_kickstart_proxy_mock_call_count); + tt_assert(transport_add_from_config_mock_call_count == + old_transport_add_from_config_mock_call_count); + + /* Necessary transport case */ + transport_is_needed_mock_return = 1; + old_pt_kickstart_proxy_mock_call_count = + pt_kickstart_proxy_mock_call_count; + old_transport_add_from_config_mock_call_count = + transport_add_from_config_mock_call_count; + old_transport_is_needed_mock_call_count = + transport_is_needed_mock_call_count; + r = parse_transport_line(options, + "transport_1 exec /usr/bin/fake-transport", 0, 0); + /* Should have succeeded */ + tt_assert(r == 0); + /* + * transport_is_needed() and pt_kickstart_proxy() should have been + * called. + */ + tt_assert(pt_kickstart_proxy_mock_call_count == + old_pt_kickstart_proxy_mock_call_count + 1); + tt_assert(transport_is_needed_mock_call_count == + old_transport_is_needed_mock_call_count + 1); + /* transport_add_from_config() should not have been called. */ + tt_assert(transport_add_from_config_mock_call_count == + old_transport_add_from_config_mock_call_count); + + /* proxy case */ + transport_is_needed_mock_return = 1; + old_pt_kickstart_proxy_mock_call_count = + pt_kickstart_proxy_mock_call_count; + old_transport_add_from_config_mock_call_count = + transport_add_from_config_mock_call_count; + old_transport_is_needed_mock_call_count = + transport_is_needed_mock_call_count; + r = parse_transport_line(options, + "transport_1 socks5 1.2.3.4:567", 0, 0); + /* Should have succeeded */ + tt_assert(r == 0); + /* + * transport_is_needed() and transport_add_from_config() should have + * been called. + */ + tt_assert(transport_add_from_config_mock_call_count == + old_transport_add_from_config_mock_call_count + 1); + tt_assert(transport_is_needed_mock_call_count == + old_transport_is_needed_mock_call_count + 1); + /* pt_kickstart_proxy() should not have been called. */ + tt_assert(pt_kickstart_proxy_mock_call_count == + old_pt_kickstart_proxy_mock_call_count); + + /* Done with mocked client transport cases */ + UNMOCK(transport_is_needed); + UNMOCK(transport_add_from_config); + UNMOCK(pt_kickstart_proxy); + + done: + /* Make sure we undo all mocks */ + UNMOCK(pt_kickstart_proxy); + UNMOCK(transport_add_from_config); + UNMOCK(transport_is_needed); + + return; +} + // Tests if an options with MyFamily fingerprints missing '$' normalises // them correctly and also ensure it also works with multiple fingerprints static void @@ -576,7 +839,8 @@ test_config_fix_my_family(void *arg) TT_FAIL(("options_validate failed: %s", err)); } - tt_str_op(options->MyFamily,==, "$1111111111111111111111111111111111111111, " + tt_str_op(options->MyFamily,OP_EQ, + "$1111111111111111111111111111111111111111, " "$1111111111111111111111111111111111111112, " "$1111111111111111111111111111111111111113"); @@ -596,6 +860,7 @@ struct testcase_t config_tests[] = { CONFIG_TEST(addressmap, 0), CONFIG_TEST(parse_bridge_line, 0), CONFIG_TEST(parse_transport_options_line, 0), + CONFIG_TEST(parse_transport_plugin_line, TT_FORK), CONFIG_TEST(check_or_create_data_subdir, TT_FORK), CONFIG_TEST(write_to_data_subdir, TT_FORK), CONFIG_TEST(fix_my_family, 0), |