diff options
-rw-r--r-- | changes/feature17327 | 5 | ||||
-rw-r--r-- | src/or/config.c | 13 | ||||
-rw-r--r-- | src/or/config.h | 8 | ||||
-rw-r--r-- | src/test/test_config.c | 175 | ||||
-rw-r--r-- | src/test/test_dir_handle_get.c | 28 |
5 files changed, 205 insertions, 24 deletions
diff --git a/changes/feature17327 b/changes/feature17327 new file mode 100644 index 0000000000..2fab09990b --- /dev/null +++ b/changes/feature17327 @@ -0,0 +1,5 @@ + o Minor feature (IPv6): + - Add a flag ipv6=address:orport to the DirAuthority and FallbackDir torrc + options. Add hard-coded ipv6 addresses for directory authorities with + ipv6 lines in their descriptors. + Closes ticket 17327; patch from Nick Mathewson / "teor". diff --git a/src/or/config.c b/src/or/config.c index 894bd893d9..3092a47c02 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -560,9 +560,6 @@ static int options_transition_affects_descriptor( static int check_nickname_list(char **lst, const char *name, char **msg); static char *get_bindaddr_from_transport_listen_line(const char *line, const char *transport); -static int parse_dir_authority_line(const char *line, - dirinfo_type_t required_type, - int validate_only); static int parse_ports(or_options_t *options, int validate_only, char **msg_out, int *n_ports_out, int *world_writable_control_socket); @@ -897,7 +894,7 @@ static const char *default_authorities[] = { * but only add them insofar as they share bits with <b>type</b>. * Each authority's bits are restricted to the bits shared with <b>type</b>. * If <b>type</b> is ALL_DIRINFO or NO_DIRINFO (zero), add all authorities. */ -static void +STATIC void add_default_trusted_dir_authorities(dirinfo_type_t type) { int i; @@ -5531,7 +5528,7 @@ get_options_for_server_transport(const char *transport) * (minus whatever bits it's missing) as a valid authority. * Return 0 on success or filtering out by type, * or -1 if the line isn't well-formed or if we can't add it. */ -static int +STATIC int parse_dir_authority_line(const char *line, dirinfo_type_t required_type, int validate_only) { @@ -5600,7 +5597,8 @@ parse_dir_authority_line(const char *line, dirinfo_type_t required_type, log_warn(LD_CONFIG, "Redundant ipv6 addr/port on DirAuthority line"); } else { if (tor_addr_port_parse(LOG_WARN, flag+strlen("ipv6="), - &ipv6_addrport.addr, &ipv6_addrport.port) < 0 + &ipv6_addrport.addr, &ipv6_addrport.port, + -1) < 0 || tor_addr_family(&ipv6_addrport.addr) != AF_INET6) { log_warn(LD_CONFIG, "Bad ipv6 addr/port %s on DirAuthority line", escaped(flag)); @@ -5712,7 +5710,8 @@ parse_dir_fallback_line(const char *line, log_warn(LD_CONFIG, "Redundant ipv6 addr/port on FallbackDir line"); } else { if (tor_addr_port_parse(LOG_WARN, cp+strlen("ipv6="), - &ipv6_addrport.addr, &ipv6_addrport.port) < 0 + &ipv6_addrport.addr, &ipv6_addrport.port, + -1) < 0 || tor_addr_family(&ipv6_addrport.addr) != AF_INET6) { log_warn(LD_CONFIG, "Bad ipv6 addr/port %s on FallbackDir line", escaped(cp)); diff --git a/src/or/config.h b/src/or/config.h index 7e8868804e..bfdd1694eb 100644 --- a/src/or/config.h +++ b/src/or/config.h @@ -152,10 +152,12 @@ STATIC int parse_transport_line(const or_options_t *options, int server); STATIC int consider_adding_dir_servers(const or_options_t *options, const or_options_t *old_options); +STATIC void add_default_trusted_dir_authorities(dirinfo_type_t type); MOCK_DECL(STATIC void, add_default_fallback_dir_servers, (void)); -STATIC int -parse_dir_fallback_line(const char *line, - int validate_only); +STATIC int parse_dir_authority_line(const char *line, + dirinfo_type_t required_type, + int validate_only); +STATIC int parse_dir_fallback_line(const char *line, int validate_only); #endif #endif diff --git a/src/test/test_config.c b/src/test/test_config.c index 28e9fa0f32..580dae4167 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1444,6 +1444,176 @@ test_config_resolve_my_address(void *arg) UNMOCK(tor_gethostname); } +static void +test_config_adding_trusted_dir_server(void *arg) +{ + (void)arg; + + const char digest[DIGEST_LEN] = ""; + dir_server_t *ds = NULL; + tor_addr_port_t ipv6; + int rv = -1; + + clear_dir_servers(); + routerlist_free_all(); + + /* create a trusted ds without an IPv6 address and port */ + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); + tt_assert(ds); + dir_server_add(ds); + tt_assert(get_n_authorities(V3_DIRINFO) == 1); + tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 1); + + /* create a trusted ds with an IPv6 address and port */ + rv = tor_addr_port_parse(LOG_WARN, "[::1]:9061", &ipv6.addr, &ipv6.port, -1); + tt_assert(rv == 0); + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, &ipv6, digest, + NULL, V3_DIRINFO, 1.0); + tt_assert(ds); + dir_server_add(ds); + tt_assert(get_n_authorities(V3_DIRINFO) == 2); + tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 2); + + done: + clear_dir_servers(); + routerlist_free_all(); +} + +static void +test_config_adding_fallback_dir_server(void *arg) +{ + (void)arg; + + const char digest[DIGEST_LEN] = ""; + dir_server_t *ds = NULL; + tor_addr_t ipv4; + tor_addr_port_t ipv6; + int rv = -1; + + clear_dir_servers(); + routerlist_free_all(); + + rv = tor_addr_parse(&ipv4, "127.0.0.1"); + tt_assert(rv == AF_INET); + + /* create a trusted ds without an IPv6 address and port */ + ds = fallback_dir_server_new(&ipv4, 9059, 9060, NULL, digest, 1.0); + tt_assert(ds); + dir_server_add(ds); + tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 1); + + /* create a trusted ds with an IPv6 address and port */ + rv = tor_addr_port_parse(LOG_WARN, "[::1]:9061", &ipv6.addr, &ipv6.port, -1); + tt_assert(rv == 0); + ds = fallback_dir_server_new(&ipv4, 9059, 9060, &ipv6, digest, 1.0); + tt_assert(ds); + dir_server_add(ds); + tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 2); + + done: + clear_dir_servers(); + routerlist_free_all(); +} + +/* No secrets here: + * v3ident is `echo "onion" | shasum | cut -d" " -f1 | tr "a-f" "A-F"` + * fingerprint is `echo "unionem" | shasum | cut -d" " -f1 | tr "a-f" "A-F"` + * with added spaces + */ +#define TEST_DIR_AUTH_LINE_START \ + "foobar orport=12345 " \ + "v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 " +#define TEST_DIR_AUTH_LINE_END \ + "1.2.3.4:54321 " \ + "FDB2 FBD2 AAA5 25FA 2999 E617 5091 5A32 C777 3B17" +#define TEST_DIR_AUTH_IPV6_FLAG \ + "ipv6=[feed::beef]:9 " + +static void +test_config_parsing_trusted_dir_server(void *arg) +{ + (void)arg; + int rv = -1; + + /* parse a trusted dir server without an IPv6 address and port */ + rv = parse_dir_authority_line(TEST_DIR_AUTH_LINE_START + TEST_DIR_AUTH_LINE_END, + V3_DIRINFO, 1); + tt_assert(rv == 0); + + /* parse a trusted dir server with an IPv6 address and port */ + rv = parse_dir_authority_line(TEST_DIR_AUTH_LINE_START + TEST_DIR_AUTH_IPV6_FLAG + TEST_DIR_AUTH_LINE_END, + V3_DIRINFO, 1); + tt_assert(rv == 0); + + /* Since we are only validating, there is no cleanup. */ + done: + ; +} + +#undef TEST_DIR_AUTH_LINE_START +#undef TEST_DIR_AUTH_LINE_END +#undef TEST_DIR_AUTH_IPV6_FLAG + +/* No secrets here: + * id is `echo "syn-propanethial-S-oxide" | shasum | cut -d" " -f1` + */ +#define TEST_DIR_FALLBACK_LINE \ + "1.2.3.4:54321 orport=12345 " \ + "id=50e643986f31ea1235bcc1af17a1c5c5cfc0ee54 " +#define TEST_DIR_FALLBACK_IPV6_FLAG \ + "ipv6=[2015:c0de::deed]:9" + +static void +test_config_parsing_fallback_dir_server(void *arg) +{ + (void)arg; + int rv = -1; + + /* parse a trusted dir server without an IPv6 address and port */ + rv = parse_dir_fallback_line(TEST_DIR_FALLBACK_LINE, 1); + tt_assert(rv == 0); + + /* parse a trusted dir server with an IPv6 address and port */ + rv = parse_dir_fallback_line(TEST_DIR_FALLBACK_LINE + TEST_DIR_FALLBACK_IPV6_FLAG, + 1); + tt_assert(rv == 0); + + /* Since we are only validating, there is no cleanup. */ + done: + ; +} + +#undef TEST_DIR_FALLBACK_LINE +#undef TEST_DIR_FALLBACK_IPV6_FLAG + +static void +test_config_adding_default_trusted_dir_servers(void *arg) +{ + (void)arg; + + clear_dir_servers(); + routerlist_free_all(); + + /* Assume we only have one bridge authority */ + add_default_trusted_dir_authorities(BRIDGE_DIRINFO); + tt_assert(get_n_authorities(BRIDGE_DIRINFO) == 1); + tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 1); + + /* Assume we have nine V3 authorities */ + add_default_trusted_dir_authorities(V3_DIRINFO); + tt_assert(get_n_authorities(V3_DIRINFO) == 9); + tt_assert(smartlist_len(router_get_fallback_dir_servers()) == 10); + + done: + clear_dir_servers(); + routerlist_free_all(); +} + static int n_add_default_fallback_dir_servers_known_default = 0; /** @@ -3213,6 +3383,11 @@ test_config_adding_dir_servers(void *arg) { #name, test_config_ ## name, flags, NULL, NULL } struct testcase_t config_tests[] = { + CONFIG_TEST(adding_trusted_dir_server, TT_FORK), + CONFIG_TEST(adding_fallback_dir_server, TT_FORK), + CONFIG_TEST(parsing_trusted_dir_server, 0), + CONFIG_TEST(parsing_fallback_dir_server, 0), + CONFIG_TEST(adding_default_trusted_dir_servers, TT_FORK), CONFIG_TEST(adding_dir_servers, TT_FORK), CONFIG_TEST(resolve_my_address, TT_FORK), CONFIG_TEST(addressmap, 0), diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index be003df2c0..e1ac50e66e 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -1242,8 +1242,8 @@ test_dir_handle_get_server_keys_all(void* data) routerlist_free_all(); /* create a trusted ds */ - ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL, - V3_DIRINFO, 1.0); + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); tt_assert(ds); dir_server_add(ds); @@ -1400,8 +1400,8 @@ test_dir_handle_get_server_keys_fp(void* data) routerlist_free_all(); /* create a trusted ds */ - ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL, - V3_DIRINFO, 1.0); + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); tt_assert(ds); dir_server_add(ds); @@ -1554,8 +1554,8 @@ test_dir_handle_get_server_keys_fpsk(void* data) routerlist_free_all(); /* create a trusted ds */ - ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL, - V3_DIRINFO, 1.0); + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); tt_assert(ds); /* ds v3_identity_digest is the certificate's identity_key */ @@ -1610,8 +1610,8 @@ test_dir_handle_get_server_keys_busy(void* data) routerlist_free_all(); /* create a trusted ds */ - ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL, - V3_DIRINFO, 1.0); + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); tt_assert(ds); /* ds v3_identity_digest is the certificate's identity_key */ @@ -2005,8 +2005,8 @@ test_dir_handle_get_status_vote_d(void* data) dirvote_free_all(); /* create a trusted ds */ - ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL, - V3_DIRINFO, 1.0); + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); tt_assert(ds); dir_server_add(ds); @@ -2353,8 +2353,8 @@ test_dir_handle_get_status_vote_next_authority(void* data) mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE, NULL); /* create a trusted ds */ - ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL, - V3_DIRINFO, 1.0); + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); tt_assert(ds); dir_server_add(ds); @@ -2431,8 +2431,8 @@ test_dir_handle_get_status_vote_current_authority(void* data) mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE, NULL); /* create a trusted ds */ - ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, digest, NULL, - V3_DIRINFO, 1.0); + ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest, + NULL, V3_DIRINFO, 1.0); tt_assert(ds); dir_server_add(ds); |