From 36ad8d8fdc18e9006cd1316deb79b37c77cf2892 Mon Sep 17 00:00:00 2001 From: "teor (Tim Wilson-Brown)" Date: Mon, 14 Sep 2015 21:56:14 +1000 Subject: [PATCH] Warn about redundant torrc ExitPolicy lines due to accept/reject *:* Tor now warns when ExitPolicy lines occur after accept/reject *:* or variants. These lines are redundant, and were always ignored. Partial fix for ticket 16069. Patch by "teor". Patch on 2eb7eafc9d78 and a96c0affcb4c (25 Oct 2012), released in 0.2.4.7-alpha. --- changes/bug16069-exit-policy-rule6 | 2 ++ src/or/policies.c | 60 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/changes/bug16069-exit-policy-rule6 b/changes/bug16069-exit-policy-rule6 index 5b0560a2cf..5e7b894e7a 100644 --- a/changes/bug16069-exit-policy-rule6 +++ b/changes/bug16069-exit-policy-rule6 @@ -7,6 +7,8 @@ * a "private" address alias is used on an accept6 or reject6 line. The line filters both IPv4 and IPv6 private addresses, disregarding the 6 in accept6/reject6. + * any ExitPolicy lines occur after accept/reject *:* or variants. + These are redundant, and were always ignored. - When parsing torrc ExitPolicies, we now issue an info-level message: * when expanding an accept/reject * line to include both IPv4 and IPv6 wildcard addresses. diff --git a/src/or/policies.c b/src/or/policies.c index e1d7da1f5e..587245b3bd 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -1013,6 +1013,66 @@ policies_parse_exit_policy_internal(config_line_t *cfg, smartlist_t **dest, } if (parse_addr_policy(cfg, dest, -1)) return -1; + + /* Before we add the default policy and final rejects, check to see if + * there are any lines after accept *:* or reject *:*. These lines have no + * effect, and are most likely an error. */ + int found_final_effective_entry = 0; + int first_redundant_entry = 0; + for (int i = 0; i < smartlist_len(*dest); ++i) { + sa_family_t family; + addr_policy_t *p; + int found_ipv4_wildcard = 0, found_ipv6_wildcard = 0; + + p = smartlist_get(*dest, i); + + /* Look for accept/reject *[4|6|]:* entires */ + if (p->prt_min <= 1 && p->prt_max == 65535 && p->maskbits == 0) { + family = tor_addr_family(&p->addr); + /* accept/reject *:* may have already been expanded into + * accept/reject *4:*,accept/reject *6:* + * But handle both forms. + */ + if (family == AF_INET || family == AF_UNSPEC) { + found_ipv4_wildcard = 1; + } + if (family == AF_INET6 || family == AF_UNSPEC) { + found_ipv6_wildcard = 1; + } + } + + /* We also find accept *4:*,reject *6:* ; and + * accept *4:*,,accept *6:* ; and similar. + * That's ok, because they make any subsequent entries redundant. */ + if (found_ipv4_wildcard && found_ipv6_wildcard) { + found_final_effective_entry = 1; + /* if we're not on the final entry in the list */ + if (i < smartlist_len(*dest) - 1) { + first_redundant_entry = i + 1; + } + break; + } + } + /* Work out if there are redundant trailing entries in the policy list */ + if (found_final_effective_entry && first_redundant_entry > 0) { + addr_policy_t *p; + /* Longest possible policy is + * "accept6 ffff:ffff:..255/128:10000-65535", + * which contains a max-length IPv6 address, plus 24 characters. */ + char line[TOR_ADDR_BUF_LEN + 32]; + + tor_assert(first_redundant_entry < smartlist_len(*dest)); + p = smartlist_get(*dest, first_redundant_entry); + /* since we've already parsed the policy into an addr_policy_t struct, + * we might not log exactly what the user typed in */ + policy_write_item(line, TOR_ADDR_BUF_LEN + 32, p, 0); + log_warn(LD_DIR, "Exit policy '%s' and all following policies are " + "redundant, as it follows accept/reject *:* rules for both " + "IPv4 and IPv6. They will be removed from the exit policy. (Use " + "accept/reject *:* as the last entry in any exit policy.)", + line); + } + if (add_default_policy) { append_exit_policy_string(dest, DEFAULT_EXIT_POLICY); } else { -- 2.11.4.GIT