summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorteor (Tim Wilson-Brown) <teor2345@gmail.com>2016-07-01 15:37:13 +1000
committerteor (Tim Wilson-Brown) <teor2345@gmail.com>2016-07-01 15:37:13 +1000
commit514f0041d190b9e142cc246e3ec7ac65342547bd (patch)
tree4476a6dbcb443e380267cc120b21ed230137b812 /src
parent64ee7bcd0c8e154269145b626a7cd56b9d6264a1 (diff)
downloadtor-514f0041d190b9e142cc246e3ec7ac65342547bd.tar.gz
tor-514f0041d190b9e142cc246e3ec7ac65342547bd.zip
Avoid disclosing exit IP addresses in exit policies by default
From 0.2.7.2-alpha onwards, Exits would reject all the IP addresses they knew about in their exit policy. But this may have disclosed addresses that were otherwise unlisted. Now, only advertised addresses are rejected by default by ExitPolicyRejectPrivate. All known addresses are only rejected when ExitPolicyRejectLocalInterfaces is explicitly set to 1.
Diffstat (limited to 'src')
-rw-r--r--src/or/config.c3
-rw-r--r--src/or/control.c2
-rw-r--r--src/or/main.c8
-rw-r--r--src/or/or.h8
-rw-r--r--src/or/policies.c78
-rw-r--r--src/or/policies.h7
-rw-r--r--src/test/test_policy.c34
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);