diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-05-08 20:09:42 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-05-08 20:09:42 -0400 |
commit | a0f051137de293342d692df1d2cfa1386e5e7769 (patch) | |
tree | 7dd6e5f9560a9b5dabcbdf69a54d30eb233bbddc /src/test | |
parent | 26990f3adc06d6907029d4580abdf3488153737e (diff) | |
parent | 24ba5fd748a9a27a6069312961843d5f8f662f93 (diff) | |
download | tor-a0f051137de293342d692df1d2cfa1386e5e7769.tar.gz tor-a0f051137de293342d692df1d2cfa1386e5e7769.zip |
Merge branch 'ticket25993_squashed'
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/test_addr.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/test/test_addr.c b/src/test/test_addr.c index e1a40b7e60..505e1533d4 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -8,6 +8,7 @@ #include "or.h" #include "test.h" #include "addressmap.h" +#include "log_test_helpers.h" /** Mocking replacement: only handles localhost. */ static int @@ -941,6 +942,158 @@ test_virtaddrmap(void *data) ; } +static const char *canned_data = NULL; +static size_t canned_data_len = 0; + +/* Mock replacement for crypto_rand() that returns canned data from + * canned_data above. */ +static void +crypto_canned(char *ptr, size_t n) +{ + if (canned_data_len) { + size_t to_copy = MIN(n, canned_data_len); + memcpy(ptr, canned_data, to_copy); + canned_data += to_copy; + canned_data_len -= to_copy; + n -= to_copy; + ptr += to_copy; + } + if (n) { + crypto_rand_unmocked(ptr, n); + } +} + +static void +test_virtaddrmap_persist(void *data) +{ + (void)data; + const char *a, *b, *c; + tor_addr_t addr; + char *ones = NULL; + + addressmap_init(); + + // Try a hostname. + a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME, + tor_strdup("foobar.baz")); + tt_assert(a); + tt_assert(!strcmpend(a, ".virtual")); + + // mock crypto_rand to repeat the same result twice; make sure we get + // different outcomes. (Because even though the odds for receiving the + // same 80-bit address twice is only 1/2^40, it could still happen for + // some user -- but running our test through 2^40 iterations isn't + // reasonable.) + canned_data = "1234567890" // the first call returns this. + "1234567890" // the second call returns this. + "abcdefghij"; // the third call returns this. + canned_data_len = 30; + MOCK(crypto_rand, crypto_canned); + + a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME, + tor_strdup("quuxit.baz")); + b = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME, + tor_strdup("nescio.baz")); + tt_assert(a); + tt_assert(b); + tt_str_op(a, OP_EQ, "gezdgnbvgy3tqojq.virtual"); + tt_str_op(b, OP_EQ, "mfrggzdfmztwq2lk.virtual"); + + // Now try something to get us an ipv4 address + UNMOCK(crypto_rand); + tt_int_op(0,OP_EQ, parse_virtual_addr_network("192.168.0.0/16", + AF_INET, 0, NULL)); + a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, + tor_strdup("foobar.baz")); + tt_assert(a); + tt_assert(!strcmpstart(a, "192.168.")); + tor_addr_parse(&addr, a); + tt_int_op(AF_INET, OP_EQ, tor_addr_family(&addr)); + + b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, + tor_strdup("quuxit.baz")); + tt_str_op(b, OP_NE, a); + tt_assert(!strcmpstart(b, "192.168.")); + + // Try some canned entropy and verify all the we discard duplicates, + // addresses that end with 0, and addresses that end with 255. + MOCK(crypto_rand, crypto_canned); + canned_data = "\x01\x02\x03\x04" // okay + "\x01\x02\x03\x04" // duplicate + "\x03\x04\x00\x00" // bad ending 1 + "\x05\x05\x00\xff" // bad ending 2 + "\x05\x06\x07\xf0"; // okay + canned_data_len = 20; + a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, + tor_strdup("wumble.onion")); + b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, + tor_strdup("wumpus.onion")); + tt_str_op(a, OP_EQ, "192.168.3.4"); + tt_str_op(b, OP_EQ, "192.168.7.240"); + + // Now try IPv6! + UNMOCK(crypto_rand); + tt_int_op(0,OP_EQ, parse_virtual_addr_network("1010:F000::/20", + AF_INET6, 0, NULL)); + a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, + tor_strdup("foobar.baz")); + tt_assert(a); + tt_assert(!strcmpstart(a, "[1010:f")); + tor_addr_parse(&addr, a); + tt_int_op(AF_INET6, OP_EQ, tor_addr_family(&addr)); + + b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, + tor_strdup("quuxit.baz")); + tt_str_op(b, OP_NE, a); + tt_assert(!strcmpstart(b, "[1010:f")); + + // Try IPv6 with canned entropy, to make sure we detect duplicates. + MOCK(crypto_rand, crypto_canned); + canned_data = "acanthopterygian" // okay + "cinematographist" // okay + "acanthopterygian" // duplicate + "acanthopterygian" // duplicate + "acanthopterygian" // duplicate + "cinematographist" // duplicate + "coadministration"; // okay + canned_data_len = 16 * 7; + a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, + tor_strdup("wuffle.baz")); + b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, + tor_strdup("gribble.baz")); + c = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6, + tor_strdup("surprisingly-legible.baz")); + tt_str_op(a, OP_EQ, "[1010:f16e:7468:6f70:7465:7279:6769:616e]"); + tt_str_op(b, OP_EQ, "[1010:fe65:6d61:746f:6772:6170:6869:7374]"); + tt_str_op(c, OP_EQ, "[1010:f164:6d69:6e69:7374:7261:7469:6f6e]"); + + // Try address exhaustion: make sure we can actually fail if we + // get too many already-existing addresses. + canned_data_len = 128*1024; + canned_data = ones = tor_malloc(canned_data_len); + memset(ones, 1, canned_data_len); + // There is some chance this one will fail if a previous random + // allocation gave out the address already. + a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, + tor_strdup("might-work.onion")); + if (a) { + tt_str_op(a, OP_EQ, "192.168.1.1"); + } + setup_capture_of_logs(LOG_WARN); + // This one will definitely fail, since we've set up the RNG to hand + // out "1" forever. + b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4, + tor_strdup("wont-work.onion")); + tt_assert(b == NULL); + expect_single_log_msg_containing("Ran out of virtual addresses!"); + + done: + UNMOCK(crypto_rand); + tor_free(ones); + addressmap_free_all(); + teardown_capture_of_logs(); +} + static void test_addr_localname(void *arg) { @@ -1095,6 +1248,7 @@ struct testcase_t addr_tests[] = { ADDR_LEGACY(ip6_helpers), ADDR_LEGACY(parse), { "virtaddr", test_virtaddrmap, 0, NULL, NULL }, + { "virtaddr_persist", test_virtaddrmap_persist, TT_FORK, NULL, NULL }, { "localname", test_addr_localname, 0, NULL, NULL }, { "dup_ip", test_addr_dup_ip, 0, NULL, NULL }, { "sockaddr_to_str", test_addr_sockaddr_to_str, 0, NULL, NULL }, |