|
@@ -893,6 +893,20 @@ addr_policy_append_reject_addr(smartlist_t **dest, const tor_addr_t *addr)
|
|
|
if (!*dest)
|
|
|
*dest = smartlist_new();
|
|
|
smartlist_add(*dest, add);
|
|
|
+ log_debug(LD_CONFIG, "Adding a reject ExitPolicy 'reject %s:*'",
|
|
|
+ fmt_addr(addr));
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/** Add "reject addr:*" to <b>dest</b>, for each addr in addrs, creating the
|
|
|
+ * list as needed. */
|
|
|
+void
|
|
|
+addr_policy_append_reject_addr_list(smartlist_t **dest,
|
|
|
+ const smartlist_t *addrs)
|
|
|
+{
|
|
|
+ SMARTLIST_FOREACH_BEGIN(addrs, tor_addr_t *, addr) {
|
|
|
+ addr_policy_append_reject_addr(dest, addr);
|
|
|
+ } SMARTLIST_FOREACH_END(addr);
|
|
|
}
|
|
|
|
|
|
/** Detect and excise "dead code" from the policy *<b>dest</b>. */
|
|
@@ -979,6 +993,76 @@ exit_policy_remove_redundancies(smartlist_t *dest)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/** Reject private helper for policies_parse_exit_policy_internal: rejects
|
|
|
+ * publicly routable addresses on this exit relay.
|
|
|
+ *
|
|
|
+ * Add reject entries to the linked list *dest:
|
|
|
+ * - if local_address is non-zero, treat it as a host-order IPv4 address,
|
|
|
+ * and prepend an entry that rejects it as a destination.
|
|
|
+ * - if ipv6_local_address is non-NULL, prepend an entry that rejects it as
|
|
|
+ * a destination.
|
|
|
+ * - if reject_interface_addresses is true, prepend entries that reject each
|
|
|
+ * public IPv4 and IPv6 address of each interface on this machine.
|
|
|
+ *
|
|
|
+ * IPv6 entries are only added if ipv6_exit is true. (All IPv6 addresses are
|
|
|
+ * already blocked by policies_parse_exit_policy_internal if ipv6_exit is
|
|
|
+ * false.)
|
|
|
+ *
|
|
|
+ * The list *dest is created as needed.
|
|
|
+ */
|
|
|
+void
|
|
|
+policies_parse_exit_policy_reject_private(smartlist_t **dest,
|
|
|
+ int ipv6_exit,
|
|
|
+ uint32_t local_address,
|
|
|
+ tor_addr_t *ipv6_local_address,
|
|
|
+ int reject_interface_addresses)
|
|
|
+{
|
|
|
+ tor_assert(dest);
|
|
|
+
|
|
|
+ /* Reject our local IPv4 address */
|
|
|
+ if (local_address) {
|
|
|
+ tor_addr_t v4_local;
|
|
|
+ tor_addr_from_ipv4h(&v4_local, local_address);
|
|
|
+ addr_policy_append_reject_addr(dest, &v4_local);
|
|
|
+ log_info(LD_CONFIG, "Adding a reject ExitPolicy 'reject %s:*' for our "
|
|
|
+ "published IPv4 address", fmt_addr32(local_address));
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Reject our local IPv6 address */
|
|
|
+ if (ipv6_exit && ipv6_local_address != NULL) {
|
|
|
+ if (tor_addr_is_v4(ipv6_local_address)) {
|
|
|
+ log_warn(LD_CONFIG, "IPv4 address '%s' provided as our IPv6 local "
|
|
|
+ "address", fmt_addr(ipv6_local_address));
|
|
|
+ } else {
|
|
|
+ addr_policy_append_reject_addr(dest, ipv6_local_address);
|
|
|
+ log_info(LD_CONFIG, "Adding a reject ExitPolicy 'reject [%s]:*' for "
|
|
|
+ "our published IPv6 address", fmt_addr(ipv6_local_address));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Reject local addresses from public netblocks on any interface. */
|
|
|
+ if (reject_interface_addresses) {
|
|
|
+ smartlist_t *public_addresses = NULL;
|
|
|
+
|
|
|
+ /* Reject public IPv4 addresses on any interface */
|
|
|
+ public_addresses = get_interface_address6_list(LOG_INFO, AF_INET, 0);
|
|
|
+ addr_policy_append_reject_addr_list(dest, public_addresses);
|
|
|
+ free_interface_address6_list(public_addresses);
|
|
|
+
|
|
|
+ if (ipv6_exit) {
|
|
|
+ /* Reject public IPv6 addresses on any interface */
|
|
|
+ public_addresses = get_interface_address6_list(LOG_INFO, AF_INET6, 0);
|
|
|
+ addr_policy_append_reject_addr_list(dest, public_addresses);
|
|
|
+ free_interface_address6_list(public_addresses);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If addresses were added multiple times, remove all but one of them. */
|
|
|
+ if (*dest) {
|
|
|
+ exit_policy_remove_redundancies(*dest);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
#define DEFAULT_EXIT_POLICY \
|
|
|
"reject *:25,reject *:119,reject *:135-139,reject *:445," \
|
|
|
"reject *:563,reject *:1214,reject *:4661-4666," \
|
|
@@ -986,16 +1070,12 @@ exit_policy_remove_redundancies(smartlist_t *dest)
|
|
|
|
|
|
/** Parse the exit policy <b>cfg</b> into the linked list *<b>dest</b>.
|
|
|
*
|
|
|
- * If <b>ipv6_exit</b> is true, prepend "reject *6:*" to the policy.
|
|
|
+ * If <b>ipv6_exit</b> is false, prepend "reject *6:*" to the policy.
|
|
|
*
|
|
|
* If <b>rejectprivate</b> is true:
|
|
|
* - prepend "reject private:*" to the policy.
|
|
|
- * - if local_address is non-zero, treat it as a host-order IPv4 address,
|
|
|
- * and prepend an entry that rejects it as a destination.
|
|
|
- * - if ipv6_local_address is non-NULL, prepend an entry that rejects it as
|
|
|
- * a destination.
|
|
|
- * - if reject_interface_addresses is true, prepend entries that reject each
|
|
|
- * public IPv4 and IPv6 address of each interface on this machine.
|
|
|
+ * - call policies_parse_exit_policy_reject_private to reject publicly
|
|
|
+ * routable addresses on this exit relay
|
|
|
*
|
|
|
* If cfg doesn't end in an absolute accept or reject and if
|
|
|
* <b>add_default_policy</b> is true, add the default exit
|
|
@@ -1022,69 +1102,10 @@ policies_parse_exit_policy_internal(config_line_t *cfg, smartlist_t **dest,
|
|
|
if (rejectprivate) {
|
|
|
/* Reject IPv4 and IPv6 reserved private netblocks */
|
|
|
append_exit_policy_string(dest, "reject private:*");
|
|
|
- /* Reject our local IPv4 address */
|
|
|
- if (local_address) {
|
|
|
- char buf[POLICY_BUF_LEN];
|
|
|
- tor_snprintf(buf, sizeof(buf), "reject %s:*", fmt_addr32(local_address));
|
|
|
- append_exit_policy_string(dest, buf);
|
|
|
- log_info(LD_CONFIG, "Adding a reject ExitPolicy '%s' for our published "
|
|
|
- "IPv4 address", buf);
|
|
|
- }
|
|
|
- /* Reject our local IPv6 address */
|
|
|
- if (ipv6_exit && ipv6_local_address != NULL) {
|
|
|
- if (tor_addr_is_v4(ipv6_local_address)) {
|
|
|
- log_warn(LD_CONFIG, "IPv4 address '%s' provided as our IPv6 local "
|
|
|
- "address", fmt_addr(ipv6_local_address));
|
|
|
- } else {
|
|
|
- char buf6[POLICY_BUF_LEN];
|
|
|
- tor_snprintf(buf6, sizeof(buf6), "reject [%s]:*",
|
|
|
- fmt_addr(ipv6_local_address));
|
|
|
- append_exit_policy_string(dest, buf6);
|
|
|
- log_info(LD_CONFIG, "Adding a reject ExitPolicy '%s' for our "
|
|
|
- "published IPv6 address", buf6);
|
|
|
- }
|
|
|
- }
|
|
|
- /* Reject local addresses from public netblocks on any interface,
|
|
|
- * but don't reject our published addresses twice */
|
|
|
- if (reject_interface_addresses) {
|
|
|
- smartlist_t *public_addresses = NULL;
|
|
|
- char bufif[POLICY_BUF_LEN];
|
|
|
-
|
|
|
- /* Reject public IPv4 addresses on any interface,
|
|
|
- * but don't reject our published IPv4 address twice */
|
|
|
- public_addresses = get_interface_address6_list(LOG_INFO, AF_INET, 0);
|
|
|
- SMARTLIST_FOREACH_BEGIN(public_addresses, tor_addr_t *, a) {
|
|
|
- if (!tor_addr_eq_ipv4h(a, local_address)) {
|
|
|
- tor_snprintf(bufif, sizeof(bufif), "reject %s:*",
|
|
|
- fmt_addr(a));
|
|
|
- append_exit_policy_string(dest, bufif);
|
|
|
- log_info(LD_CONFIG, "Adding a reject ExitPolicy '%s' for a local "
|
|
|
- "interface's public IPv4 address", bufif);
|
|
|
- }
|
|
|
- } SMARTLIST_FOREACH_END(a);
|
|
|
- free_interface_address6_list(public_addresses);
|
|
|
-
|
|
|
- if (ipv6_exit) {
|
|
|
- /* Reject public IPv6 addresses on any interface,
|
|
|
- * but don't reject our published IPv6 address (if any) twice */
|
|
|
- public_addresses = get_interface_address6_list(LOG_INFO, AF_INET6, 0);
|
|
|
- SMARTLIST_FOREACH_BEGIN(public_addresses, tor_addr_t *, a) {
|
|
|
- /* if we don't have an IPv6 local address, we won't have rejected
|
|
|
- * it above. This could happen if a future release does IPv6
|
|
|
- * autodiscovery, and we are waiting to discover our external IPv6
|
|
|
- * address */
|
|
|
- if (ipv6_local_address == NULL
|
|
|
- || !tor_addr_eq(ipv6_local_address, a)) {
|
|
|
- tor_snprintf(bufif, sizeof(bufif), "reject6 [%s]:*",
|
|
|
- fmt_addr(a));
|
|
|
- append_exit_policy_string(dest, bufif);
|
|
|
- log_info(LD_CONFIG, "Adding a reject ExitPolicy '%s' for a local "
|
|
|
- "interface's public IPv6 address", bufif);
|
|
|
- }
|
|
|
- } SMARTLIST_FOREACH_END(a);
|
|
|
- free_interface_address6_list(public_addresses);
|
|
|
- }
|
|
|
- }
|
|
|
+ /* Reject IPv4 and IPv6 publicly routable addresses on this exit relay */
|
|
|
+ policies_parse_exit_policy_reject_private(dest, ipv6_exit, local_address,
|
|
|
+ ipv6_local_address,
|
|
|
+ reject_interface_addresses);
|
|
|
}
|
|
|
if (parse_addr_policy(cfg, dest, -1))
|
|
|
return -1;
|