diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/address.c | 36 | ||||
-rw-r--r-- | src/common/address.h | 11 | ||||
-rw-r--r-- | src/config/torrc.minimal.in-staging | 9 | ||||
-rw-r--r-- | src/config/torrc.sample.in | 9 | ||||
-rw-r--r-- | src/or/routerparse.c | 11 | ||||
-rw-r--r-- | src/test/test_policy.c | 44 |
6 files changed, 101 insertions, 19 deletions
diff --git a/src/common/address.c b/src/common/address.c index 597f6990d3..066355373a 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -620,13 +620,20 @@ tor_addr_to_PTR_name(char *out, size_t outlen, * yield an IPv4 wildcard. * * If 'flags & TAPMP_EXTENDED_STAR' is true, then the wildcard address '*' - * yields an AF_UNSPEC wildcard address, and the following change is made + * yields an AF_UNSPEC wildcard address, which expands to corresponding + * wildcard IPv4 and IPv6 rules, and the following change is made * in the grammar above: * Address ::= IPv4Address / "[" IPv6Address "]" / "*" / "*4" / "*6" * with the new "*4" and "*6" productions creating a wildcard to match * IPv4 or IPv6 addresses. * - */ + * If 'flags & TAPMP_EXTENDED_STAR' and 'flags & TAPMP_STAR_IPV4_ONLY' are + * both true, then the wildcard address '*' yields an IPv4 wildcard. + * + * If 'flags & TAPMP_EXTENDED_STAR' and 'flags & TAPMP_STAR_IPV6_ONLY' are + * both true, then the wildcard address '*' yields an IPv6 wildcard. + * + * TAPMP_STAR_IPV4_ONLY and TAPMP_STAR_IPV6_ONLY are mutually exclusive. */ int tor_addr_parse_mask_ports(const char *s, unsigned flags, @@ -643,6 +650,10 @@ tor_addr_parse_mask_ports(const char *s, tor_assert(s); tor_assert(addr_out); + /* We can either only want an IPv4 address or only want an IPv6 address, + * but we can't only want IPv4 & IPv6 at the same time. */ + tor_assert(!((flags & TAPMP_STAR_IPV4_ONLY) + && (flags & TAPMP_STAR_IPV6_ONLY))); /** Longest possible length for an address, mask, and port-range combination. * Includes IP, [], /mask, :, ports */ @@ -688,12 +699,21 @@ tor_addr_parse_mask_ports(const char *s, if (!strcmp(address, "*")) { if (flags & TAPMP_EXTENDED_STAR) { - family = AF_UNSPEC; - tor_addr_make_unspec(addr_out); - log_info(LD_GENERAL, - "'%s' expands into rules which apply to all IPv4 and IPv6 " - "addresses. (Use accept/reject *4:* for IPv4 or " - "accept[6]/reject[6] *6:* for IPv6.)", s); + if (flags & TAPMP_STAR_IPV4_ONLY) { + family = AF_INET; + tor_addr_from_ipv4h(addr_out, 0); + } else if (flags & TAPMP_STAR_IPV6_ONLY) { + static char nil_bytes[16] = { [0]=0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }; + family = AF_INET6; + tor_addr_from_ipv6_bytes(addr_out, nil_bytes); + } else { + family = AF_UNSPEC; + tor_addr_make_unspec(addr_out); + log_info(LD_GENERAL, + "'%s' expands into rules which apply to all IPv4 and IPv6 " + "addresses. (Use accept/reject *4:* for IPv4 or " + "accept[6]/reject[6] *6:* for IPv6.)", s); + } } else { family = AF_INET; tor_addr_from_ipv4h(addr_out, 0); diff --git a/src/common/address.h b/src/common/address.h index 48a34cee31..90207c3338 100644 --- a/src/common/address.h +++ b/src/common/address.h @@ -227,10 +227,19 @@ int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address, int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out); -/* Does the address * yield an AF_UNSPEC wildcard address (1) and do we + +/* Does the address * yield an AF_UNSPEC wildcard address (1), + * which expands to corresponding wildcard IPv4 and IPv6 rules, and do we * allow *4 and *6 for IPv4 and IPv6 wildcards, respectively; * or does the address * yield IPv4 wildcard address (0). */ #define TAPMP_EXTENDED_STAR 1 +/* Does the address * yield an IPv4 wildcard address rule (1); + * or does it yield wildcard IPv4 and IPv6 rules (0) */ +#define TAPMP_STAR_IPV4_ONLY (1 << 1) +/* Does the address * yield an IPv6 wildcard address rule (1); + * or does it yield wildcard IPv4 and IPv6 rules (0) */ +#define TAPMP_STAR_IPV6_ONLY (1 << 2) +/* TAPMP_STAR_IPV4_ONLY and TAPMP_STAR_IPV6_ONLY are mutually exclusive. */ int tor_addr_parse_mask_ports(const char *s, unsigned flags, tor_addr_t *addr_out, maskbits_t *mask_out, uint16_t *port_min_out, uint16_t *port_max_out); diff --git a/src/config/torrc.minimal.in-staging b/src/config/torrc.minimal.in-staging index d54a5599cd..c17f7eb87e 100644 --- a/src/config/torrc.minimal.in-staging +++ b/src/config/torrc.minimal.in-staging @@ -1,5 +1,5 @@ ## Configuration file for a typical Tor user -## Last updated 2 September 2014 for Tor 0.2.6.1-alpha. +## Last updated 11 September 2015 for Tor 0.2.7.3-alpha. ## (may or may not work for much older or much newer versions of Tor.) ## ## Lines that begin with "## " try to explain what's going on. Lines @@ -24,6 +24,7 @@ ## can access your SocksPort may be able to learn about the connections ## you make. #SocksPolicy accept 192.168.0.0/16 +#SocksPolicy accept6 FC00::/7 #SocksPolicy reject * ## Logs go to stdout at level "notice" unless redirected by something @@ -174,8 +175,10 @@ ## networks, including to your public IP address. See the man page entry ## for ExitPolicyRejectPrivate if you want to allow "exit enclaving". ## -#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more -#ExitPolicy accept *:119 # accept nntp as well as default exit policy +#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports on IPv4 and IPv6 but no more +#ExitPolicy accept *:119 # accept nntp ports on IPv4 and IPv6 as well as default exit policy +#ExitPolicy accept *4:119 # accept nntp ports on IPv4 only as well as default exit policy +#ExitPolicy accept6 *6:119 # accept nntp ports on IPv6 only as well as default exit policy #ExitPolicy reject *:* # no exits allowed ## Bridge relays (or "bridges") are Tor relays that aren't listed in the diff --git a/src/config/torrc.sample.in b/src/config/torrc.sample.in index d54a5599cd..c17f7eb87e 100644 --- a/src/config/torrc.sample.in +++ b/src/config/torrc.sample.in @@ -1,5 +1,5 @@ ## Configuration file for a typical Tor user -## Last updated 2 September 2014 for Tor 0.2.6.1-alpha. +## Last updated 11 September 2015 for Tor 0.2.7.3-alpha. ## (may or may not work for much older or much newer versions of Tor.) ## ## Lines that begin with "## " try to explain what's going on. Lines @@ -24,6 +24,7 @@ ## can access your SocksPort may be able to learn about the connections ## you make. #SocksPolicy accept 192.168.0.0/16 +#SocksPolicy accept6 FC00::/7 #SocksPolicy reject * ## Logs go to stdout at level "notice" unless redirected by something @@ -174,8 +175,10 @@ ## networks, including to your public IP address. See the man page entry ## for ExitPolicyRejectPrivate if you want to allow "exit enclaving". ## -#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more -#ExitPolicy accept *:119 # accept nntp as well as default exit policy +#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports on IPv4 and IPv6 but no more +#ExitPolicy accept *:119 # accept nntp ports on IPv4 and IPv6 as well as default exit policy +#ExitPolicy accept *4:119 # accept nntp ports on IPv4 only as well as default exit policy +#ExitPolicy accept6 *6:119 # accept nntp ports on IPv6 only as well as default exit policy #ExitPolicy reject *:* # no exits allowed ## Bridge relays (or "bridges") are Tor relays that aren't listed in the diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 2f7e50e60a..7bb18ecc30 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -3820,6 +3820,12 @@ router_parse_addr_policy(directory_token_t *tok, unsigned fmt_flags) else newe.policy_type = ADDR_POLICY_ACCEPT; + /* accept6/reject6 * produces an IPv6 wildcard address only. + * (accept/reject * produces rules for IPv4 and IPv6 wildcard addresses.) */ + if (tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) { + fmt_flags |= TAPMP_STAR_IPV6_ONLY; + } + if (tor_addr_parse_mask_ports(arg, fmt_flags, &newe.addr, &newe.maskbits, &newe.prt_min, &newe.prt_max) < 0) { log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg)); @@ -3829,9 +3835,12 @@ router_parse_addr_policy(directory_token_t *tok, unsigned fmt_flags) return addr_policy_get_canonical_entry(&newe); } -/** Parse an exit policy line of the format "accept/reject private:...". +/** Parse an exit policy line of the format "accept[6]/reject[6] private:...". * This didn't exist until Tor 0.1.1.15, so nobody should generate it in * router descriptors until earlier versions are obsolete. + * + * accept/reject and accept6/reject6 private all produce rules for both + * IPv4 and IPv6 addresses. */ static addr_policy_t * router_parse_addr_policy_private(directory_token_t *tok) diff --git a/src/test/test_policy.c b/src/test/test_policy.c index 5e91468e8c..4150b97468 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -77,7 +77,8 @@ test_policies_general(void *arg) int i; smartlist_t *policy = NULL, *policy2 = NULL, *policy3 = NULL, *policy4 = NULL, *policy5 = NULL, *policy6 = NULL, - *policy7 = NULL; + *policy7 = NULL, *policy8 = NULL, *policy9 = NULL, + *policy10 = NULL, *policy11 = NULL; addr_policy_t *p; tor_addr_t tar; config_line_t line; @@ -192,6 +193,30 @@ test_policies_general(void *arg) tt_assert(p != NULL); smartlist_add(policy7, p); + tt_int_op(0, OP_EQ, policies_parse_exit_policy(NULL, &policy8, + EXIT_POLICY_IPV6_ENABLED | + EXIT_POLICY_REJECT_PRIVATE | + EXIT_POLICY_ADD_DEFAULT, 0)); + + tt_assert(policy8); + + tt_int_op(0, OP_EQ, policies_parse_exit_policy(NULL, &policy9, + EXIT_POLICY_REJECT_PRIVATE | + EXIT_POLICY_ADD_DEFAULT, 0)); + + tt_assert(policy9); + + /* accept6 * and reject6 * produce IPv6 wildcards only */ + policy10 = smartlist_new(); + p = router_parse_addr_policy_item_from_string("accept6 *:*",-1); + tt_assert(p != NULL); + smartlist_add(policy10, p); + + policy11 = smartlist_new(); + p = router_parse_addr_policy_item_from_string("reject6 *:*",-1); + tt_assert(p != NULL); + smartlist_add(policy11, p); + tt_assert(!exit_policy_is_general_exit(policy)); tt_assert(exit_policy_is_general_exit(policy2)); tt_assert(!exit_policy_is_general_exit(NULL)); @@ -200,6 +225,10 @@ test_policies_general(void *arg) tt_assert(!exit_policy_is_general_exit(policy5)); tt_assert(!exit_policy_is_general_exit(policy6)); tt_assert(!exit_policy_is_general_exit(policy7)); + tt_assert(exit_policy_is_general_exit(policy8)); + tt_assert(exit_policy_is_general_exit(policy9)); + tt_assert(!exit_policy_is_general_exit(policy10)); + tt_assert(!exit_policy_is_general_exit(policy11)); tt_assert(cmp_addr_policies(policy, policy2)); tt_assert(cmp_addr_policies(policy, NULL)); @@ -208,7 +237,12 @@ test_policies_general(void *arg) tt_assert(!policy_is_reject_star(policy2, AF_INET)); tt_assert(policy_is_reject_star(policy, AF_INET)); + tt_assert(policy_is_reject_star(policy10, AF_INET)); + tt_assert(!policy_is_reject_star(policy10, AF_INET6)); + tt_assert(policy_is_reject_star(policy11, AF_INET)); + tt_assert(policy_is_reject_star(policy11, AF_INET6)); tt_assert(policy_is_reject_star(NULL, AF_INET)); + tt_assert(policy_is_reject_star(NULL, AF_INET6)); addr_policy_list_free(policy); policy = NULL; @@ -219,13 +253,13 @@ test_policies_general(void *arg) line.value = (char*)"accept *:80,reject private:*,reject *:*"; line.next = NULL; tt_int_op(0, OP_EQ, policies_parse_exit_policy(&line,&policy, - EXIT_POLICY_IPV6_ENABLED | + ~EXIT_POLICY_IPV6_ENABLED | EXIT_POLICY_ADD_DEFAULT,0)); tt_assert(policy); //test_streq(policy->string, "accept *:80"); //test_streq(policy->next->string, "reject *:*"); - tt_int_op(smartlist_len(policy),OP_EQ, 4); + tt_int_op(smartlist_len(policy),OP_EQ, 9); /* test policy summaries */ /* check if we properly ignore private IP addresses */ @@ -427,6 +461,10 @@ test_policies_general(void *arg) addr_policy_list_free(policy5); addr_policy_list_free(policy6); addr_policy_list_free(policy7); + addr_policy_list_free(policy8); + addr_policy_list_free(policy9); + addr_policy_list_free(policy10); + addr_policy_list_free(policy11); tor_free(policy_str); if (sm) { SMARTLIST_FOREACH(sm, char *, s, tor_free(s)); |