Quellcode durchsuchen

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.
teor (Tim Wilson-Brown) vor 8 Jahren
Ursprung
Commit
36ad8d8fdc
2 geänderte Dateien mit 62 neuen und 0 gelöschten Zeilen
  1. 2 0
      changes/bug16069-exit-policy-rule6
  2. 60 0
      src/or/policies.c

+ 2 - 0
changes/bug16069-exit-policy-rule6

@@ -7,6 +7,8 @@
       * a "private" address alias is used on an accept6 or reject6 line.
       * a "private" address alias is used on an accept6 or reject6 line.
         The line filters both IPv4 and IPv6 private addresses, disregarding
         The line filters both IPv4 and IPv6 private addresses, disregarding
         the 6 in accept6/reject6.
         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 parsing torrc ExitPolicies, we now issue an info-level message:
       * when expanding an accept/reject * line to include both IPv4 and IPv6
       * when expanding an accept/reject * line to include both IPv4 and IPv6
         wildcard addresses.
         wildcard addresses.

+ 60 - 0
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))
   if (parse_addr_policy(cfg, dest, -1))
     return -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:*,<other policies>,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) {
   if (add_default_policy) {
     append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);
     append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);
   } else {
   } else {