diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/config.c | 3 | ||||
-rw-r--r-- | src/or/control.c | 2 | ||||
-rw-r--r-- | src/or/main.c | 8 | ||||
-rw-r--r-- | src/or/or.h | 8 | ||||
-rw-r--r-- | src/or/policies.c | 78 | ||||
-rw-r--r-- | src/or/policies.h | 7 | ||||
-rw-r--r-- | src/test/test_policy.c | 34 |
7 files changed, 109 insertions, 31 deletions
diff --git a/src/or/config.c b/src/or/config.c index 45acd39980..5643c8d226 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -244,6 +244,7 @@ static config_var_t option_vars_[] = { V(ExitNodes, ROUTERSET, NULL), V(ExitPolicy, LINELIST, NULL), V(ExitPolicyRejectPrivate, BOOL, "1"), + V(ExitPolicyRejectLocalInterfaces, BOOL, "0"), V(ExitPortStatistics, BOOL, "0"), V(ExtendAllowPrivateAddresses, BOOL, "0"), V(ExitRelay, AUTOBOOL, "auto"), @@ -4320,6 +4321,8 @@ options_transition_affects_descriptor(const or_options_t *old_options, old_options->ExitRelay != new_options->ExitRelay || old_options->ExitPolicyRejectPrivate != new_options->ExitPolicyRejectPrivate || + old_options->ExitPolicyRejectLocalInterfaces != + new_options->ExitPolicyRejectLocalInterfaces || old_options->IPv6Exit != new_options->IPv6Exit || !config_lines_eq(old_options->ORPort_lines, new_options->ORPort_lines) || diff --git a/src/or/control.c b/src/or/control.c index d3613d8d4f..ea7d7b7962 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3025,7 +3025,7 @@ static const getinfo_item_t getinfo_items[] = { " ExitPolicyRejectPrivate."), ITEM("exit-policy/reject-private/relay", policies, "The relay-specific rules appended to the configured exit policy by" - " ExitPolicyRejectPrivate."), + " ExitPolicyRejectPrivate and/or ExitPolicyRejectLocalInterfaces."), ITEM("exit-policy/full", policies, "The entire exit policy of onion router"), ITEM("exit-policy/ipv4", policies, "IPv4 parts of exit policy"), ITEM("exit-policy/ipv6", policies, "IPv6 parts of exit policy"), diff --git a/src/or/main.c b/src/or/main.c index 65a67a9923..2b9b08546c 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -2220,8 +2220,8 @@ ip_address_changed(int at_interface) { const or_options_t *options = get_options(); int server = server_mode(options); - int exit_reject_private = (server && options->ExitRelay - && options->ExitPolicyRejectPrivate); + int exit_reject_interfaces = (server && options->ExitRelay + && options->ExitPolicyRejectLocalInterfaces); if (at_interface) { if (! server) { @@ -2239,8 +2239,8 @@ ip_address_changed(int at_interface) } /* Exit relays incorporate interface addresses in their exit policies when - * ExitPolicyRejectPrivate is set */ - if (exit_reject_private || (server && !at_interface)) { + * ExitPolicyRejectLocalInterfaces is set */ + if (exit_reject_interfaces || (server && !at_interface)) { mark_my_descriptor_dirty("IP address changed"); } diff --git a/src/or/or.h b/src/or/or.h index a1a0810e4b..98f5a006d8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3573,7 +3573,13 @@ typedef struct { /** Bitmask; derived from AllowInvalidNodes. */ invalid_router_usage_t AllowInvalid_; config_line_t *ExitPolicy; /**< Lists of exit policy components. */ - int ExitPolicyRejectPrivate; /**< Should we not exit to local addresses? */ + int ExitPolicyRejectPrivate; /**< Should we not exit to reserved private + * addresses, and our own published addresses? + */ + int ExitPolicyRejectLocalInterfaces; /**< Should we not exit to local + * interface addresses? + * Includes OutboundBindAddresses and + * configured ports. */ config_line_t *SocksPolicy; /**< Lists of socks policy components */ config_line_t *DirPolicy; /**< Lists of dir policy components */ /** Addresses to bind for listening for SOCKS connections. */ diff --git a/src/or/policies.c b/src/or/policies.c index 2703d7edef..544c6b7dbb 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -1843,10 +1843,18 @@ policies_log_first_redundant_entry(const smartlist_t *policy) * * If <b>ipv6_exit</b> is false, prepend "reject *6:*" to the policy. * + * If <b>configured_addresses</b> contains addresses: + * - prepend entries that reject the addresses in this list. These may be the + * advertised relay addresses and/or the outbound bind addresses, + * depending on the ExitPolicyRejectPrivate and + * ExitPolicyRejectLocalInterfaces settings. * If <b>rejectprivate</b> is true: * - prepend "reject private:*" to the policy. - * - prepend entries that reject publicly routable addresses on this exit - * relay by calling policies_parse_exit_policy_reject_private + * If <b>reject_interface_addresses</b> is true: + * - prepend entries that reject publicly routable interface addresses on + * this exit relay by calling policies_parse_exit_policy_reject_private + * If <b>reject_configured_port_addresses</b> is true: + * - prepend entries that reject all configured port addresses * * If cfg doesn't end in an absolute accept or reject and if * <b>add_default_policy</b> is true, add the default exit @@ -1874,13 +1882,16 @@ policies_parse_exit_policy_internal(config_line_t *cfg, if (rejectprivate) { /* Reject IPv4 and IPv6 reserved private netblocks */ append_exit_policy_string(dest, "reject private:*"); - /* Reject IPv4 and IPv6 publicly routable addresses on this exit relay */ - policies_parse_exit_policy_reject_private( - dest, ipv6_exit, + } + + /* Consider rejecting IPv4 and IPv6 advertised relay addresses, outbound bind + * addresses, publicly routable addresses, and configured port addresses + * on this exit relay */ + policies_parse_exit_policy_reject_private(dest, ipv6_exit, configured_addresses, reject_interface_addresses, reject_configured_port_addresses); - } + if (parse_addr_policy(cfg, dest, -1)) return -1; @@ -1908,8 +1919,14 @@ policies_parse_exit_policy_internal(config_line_t *cfg, * If <b>EXIT_POLICY_REJECT_PRIVATE</b> bit is set in <b>options</b>: * - prepend an entry that rejects all destinations in all netblocks * reserved for private use. + * - prepend entries that reject the advertised relay addresses in + * configured_addresses + * If <b>EXIT_POLICY_REJECT_LOCAL_INTERFACES</b> bit is set in <b>options</b>: * - prepend entries that reject publicly routable addresses on this exit * relay by calling policies_parse_exit_policy_internal + * - prepend entries that reject the outbound bind addresses in + * configured_addresses + * - prepend entries that reject all configured port addresses * * If <b>EXIT_POLICY_ADD_DEFAULT</b> bit is set in <b>options</b>, append * default exit policy entries to <b>result</b> smartlist. @@ -1922,12 +1939,14 @@ policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest, int ipv6_enabled = (options & EXIT_POLICY_IPV6_ENABLED) ? 1 : 0; int reject_private = (options & EXIT_POLICY_REJECT_PRIVATE) ? 1 : 0; int add_default = (options & EXIT_POLICY_ADD_DEFAULT) ? 1 : 0; + int reject_local_interfaces = (options & + EXIT_POLICY_REJECT_LOCAL_INTERFACES) ? 1 : 0; return policies_parse_exit_policy_internal(cfg,dest,ipv6_enabled, reject_private, configured_addresses, - reject_private, - reject_private, + reject_local_interfaces, + reject_local_interfaces, add_default); } @@ -1993,6 +2012,7 @@ policies_copy_outbound_addresses_to_smartlist(smartlist_t *addr_list, * add it to the list of configured addresses. * - if ipv6_local_address is non-NULL, and not the null tor_addr_t, add it * to the list of configured addresses. + * If <b>or_options->ExitPolicyRejectLocalInterfaces</b> is true: * - if or_options->OutboundBindAddressIPv4_ is not the null tor_addr_t, add * it to the list of configured addresses. * - if or_options->OutboundBindAddressIPv6_ is not the null tor_addr_t, add @@ -2036,11 +2056,20 @@ policies_parse_exit_policy_from_options(const or_options_t *or_options, parser_cfg |= EXIT_POLICY_ADD_DEFAULT; } + if (or_options->ExitPolicyRejectLocalInterfaces) { + parser_cfg |= EXIT_POLICY_REJECT_LOCAL_INTERFACES; + } + /* Copy the configured addresses into the tor_addr_t* list */ - policies_copy_ipv4h_to_smartlist(configured_addresses, local_address); - policies_copy_addr_to_smartlist(configured_addresses, ipv6_local_address); - policies_copy_outbound_addresses_to_smartlist(configured_addresses, - or_options); + if (or_options->ExitPolicyRejectPrivate) { + policies_copy_ipv4h_to_smartlist(configured_addresses, local_address); + policies_copy_addr_to_smartlist(configured_addresses, ipv6_local_address); + } + + if (or_options->ExitPolicyRejectLocalInterfaces) { + policies_copy_outbound_addresses_to_smartlist(configured_addresses, + or_options); + } rv = policies_parse_exit_policy(or_options->ExitPolicy, result, parser_cfg, configured_addresses); @@ -2820,7 +2849,8 @@ getinfo_helper_policies(control_connection_t *conn, return -1; } - if (!options->ExitPolicyRejectPrivate) { + if (!options->ExitPolicyRejectPrivate && + !options->ExitPolicyRejectLocalInterfaces) { *answer = tor_strdup(""); return 0; } @@ -2829,16 +2859,22 @@ getinfo_helper_policies(control_connection_t *conn, smartlist_t *configured_addresses = smartlist_new(); /* Copy the configured addresses into the tor_addr_t* list */ - policies_copy_ipv4h_to_smartlist(configured_addresses, me->addr); - policies_copy_addr_to_smartlist(configured_addresses, &me->ipv6_addr); - policies_copy_outbound_addresses_to_smartlist(configured_addresses, - options); + if (options->ExitPolicyRejectPrivate) { + policies_copy_ipv4h_to_smartlist(configured_addresses, me->addr); + policies_copy_addr_to_smartlist(configured_addresses, &me->ipv6_addr); + } + + if (options->ExitPolicyRejectLocalInterfaces) { + policies_copy_outbound_addresses_to_smartlist(configured_addresses, + options); + } policies_parse_exit_policy_reject_private( - &private_policy_list, - options->IPv6Exit, - configured_addresses, - 1, 1); + &private_policy_list, + options->IPv6Exit, + configured_addresses, + options->ExitPolicyRejectLocalInterfaces, + options->ExitPolicyRejectLocalInterfaces); *answer = policy_dump_to_string(private_policy_list, 1, 1); addr_policy_list_free(private_policy_list); diff --git a/src/or/policies.h b/src/or/policies.h index aaa6fa0a4e..e134e686d2 100644 --- a/src/or/policies.h +++ b/src/or/policies.h @@ -18,9 +18,10 @@ */ #define POLICY_BUF_LEN 72 -#define EXIT_POLICY_IPV6_ENABLED (1 << 0) -#define EXIT_POLICY_REJECT_PRIVATE (1 << 1) -#define EXIT_POLICY_ADD_DEFAULT (1 << 2) +#define EXIT_POLICY_IPV6_ENABLED (1 << 0) +#define EXIT_POLICY_REJECT_PRIVATE (1 << 1) +#define EXIT_POLICY_ADD_DEFAULT (1 << 2) +#define EXIT_POLICY_REJECT_LOCAL_INTERFACES (1 << 3) typedef enum firewall_connection_t { FIREWALL_OR_CONNECTION = 0, diff --git a/src/test/test_policy.c b/src/test/test_policy.c index 14182af86b..a972bd5b29 100644 --- a/src/test/test_policy.c +++ b/src/test/test_policy.c @@ -1082,10 +1082,32 @@ test_policies_getinfo_helper_policies(void *arg) append_exit_policy_string(&mock_my_routerinfo.exit_policy, "reject *6:*"); mock_options.IPv6Exit = 1; - mock_options.ExitPolicyRejectPrivate = 1; tor_addr_from_ipv4h(&mock_options.OutboundBindAddressIPv4_, TEST_IPV4_ADDR); tor_addr_parse(&mock_options.OutboundBindAddressIPv6_, TEST_IPV6_ADDR); + mock_options.ExitPolicyRejectPrivate = 1; + mock_options.ExitPolicyRejectLocalInterfaces = 1; + + rv = getinfo_helper_policies(NULL, "exit-policy/reject-private/relay", + &answer, &errmsg); + tt_assert(rv == 0); + tt_assert(answer != NULL); + tt_assert(strlen(answer) > 0); + tor_free(answer); + + mock_options.ExitPolicyRejectPrivate = 1; + mock_options.ExitPolicyRejectLocalInterfaces = 0; + + rv = getinfo_helper_policies(NULL, "exit-policy/reject-private/relay", + &answer, &errmsg); + tt_assert(rv == 0); + tt_assert(answer != NULL); + tt_assert(strlen(answer) > 0); + tor_free(answer); + + mock_options.ExitPolicyRejectPrivate = 0; + mock_options.ExitPolicyRejectLocalInterfaces = 1; + rv = getinfo_helper_policies(NULL, "exit-policy/reject-private/relay", &answer, &errmsg); tt_assert(rv == 0); @@ -1093,6 +1115,16 @@ test_policies_getinfo_helper_policies(void *arg) tt_assert(strlen(answer) > 0); tor_free(answer); + mock_options.ExitPolicyRejectPrivate = 0; + mock_options.ExitPolicyRejectLocalInterfaces = 0; + + rv = getinfo_helper_policies(NULL, "exit-policy/reject-private/relay", + &answer, &errmsg); + tt_assert(rv == 0); + tt_assert(answer != NULL); + tt_assert(strlen(answer) == 0); + tor_free(answer); + rv = getinfo_helper_policies(NULL, "exit-policy/ipv4", &answer, &errmsg); tt_assert(rv == 0); |