From 8226148bf191462fca4fad862116ee34aa5bab6d Mon Sep 17 00:00:00 2001 From: trinity-1686a Date: Sun, 23 Jul 2023 20:57:32 +0200 Subject: [PATCH 1/4] reapply exit policy on reload --- src/app/config/config.c | 1 + src/core/or/connection_edge.c | 68 +++++++++++++++++++++++++++++++++++ src/core/or/connection_edge.h | 2 ++ src/core/or/policies.c | 2 +- 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/app/config/config.c b/src/app/config/config.c index a10329c552..60565d15c4 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -996,6 +996,7 @@ set_options(or_options_t *new_val, char **msg) config_line_t *changes = config_get_changes(get_options_mgr(), old_options, new_val); control_event_conf_changed(changes); + connection_reapply_exit_policy(changes); config_free_lines(changes); } diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index f21779a80c..f7cc1d7a98 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -105,6 +105,7 @@ #include "lib/buf/buffers.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" +#include "lib/encoding/confline.h" #include "core/or/cell_st.h" #include "core/or/cpath_build_state_st.h" @@ -4237,6 +4238,73 @@ my_exit_policy_rejects(const tor_addr_t *addr, return 0; } +/* Reapply exit policy to existing connections, possibly terminating + * connections + * no longer allowed by the policy. + */ +void +connection_reapply_exit_policy(config_line_t *changes) +{ + int marked_for_close = 0; + smartlist_t *conn_list = NULL; + smartlist_t *policy = NULL; + int config_change_relevant = 0; + + /* TODO if (get_options()->ReevaluateExitPolicy == 1) {*/ + if (false) { + return; + } + + for (const config_line_t *line = changes; + line && !config_change_relevant; + line = line->next) { + const char* exit_policy_options[] = { + "ExitRelay", + "ExitPolicy", + "ReducedExitPolicy", + "IPv6Exit", + NULL + }; + for (unsigned int i = 0; exit_policy_options[i] != NULL; ++i) { + if (strcmp(line->key, exit_policy_options[i]) == 0) { + config_change_relevant = 1; + break; + } + } + } + + if (!config_change_relevant) { + /* Policy did not change: no need to iterate over connections */ + return; + } + + // we can't use router_compare_to_my_exit_policy as it depend on the + // descriptor, which is regenerated asynchronously, so we have to parse the + // policy ourselves. + // We don't verify for our own IP, it's not part of the configuration. + policies_parse_exit_policy_from_options(get_options(), NULL, NULL, &policy); + + conn_list = connection_list_by_type_purpose(CONN_TYPE_EXIT, + EXIT_PURPOSE_CONNECT); + + SMARTLIST_FOREACH_BEGIN(conn_list, connection_t *, conn) { + addr_policy_result_t verdict = compare_tor_addr_to_addr_policy(&conn->addr, + conn->port, + policy); + if (verdict != ADDR_POLICY_ACCEPTED) { + connection_edge_end(TO_EDGE_CONN(conn), END_STREAM_REASON_EXITPOLICY); + connection_mark_for_close(conn); + ++marked_for_close; + } + } SMARTLIST_FOREACH_END(conn); + + smartlist_free(conn_list); + smartlist_free(policy); + + log_info(LD_GENERAL, "Marked %d connections to be closed as no longer " + "allowed per ExitPolicy", marked_for_close); +} + /** Return true iff the consensus allows network reentry. The default value is * false if the parameter is not found. */ static bool diff --git a/src/core/or/connection_edge.h b/src/core/or/connection_edge.h index 59fc17dea5..1bb0e6d368 100644 --- a/src/core/or/connection_edge.h +++ b/src/core/or/connection_edge.h @@ -13,6 +13,7 @@ #define TOR_CONNECTION_EDGE_H #include "lib/testsupport/testsupport.h" +#include "lib/encoding/confline.h" #include "feature/hs/hs_service.h" @@ -101,6 +102,7 @@ void connection_entry_set_controller_wait(entry_connection_t *conn); void connection_ap_about_to_close(entry_connection_t *edge_conn); void connection_exit_about_to_close(edge_connection_t *edge_conn); +void connection_reapply_exit_policy(config_line_t *changes); MOCK_DECL(int, connection_ap_handshake_send_begin,(entry_connection_t *ap_conn)); diff --git a/src/core/or/policies.c b/src/core/or/policies.c index 1864b84d5e..4641632b60 100644 --- a/src/core/or/policies.c +++ b/src/core/or/policies.c @@ -1066,7 +1066,7 @@ socks_policy_permits_address(const tor_addr_t *addr) } /** Return 1 if addr is permitted to connect to our metrics port, - * based on socks_policy. Else return 0. + * based on metrics_policy. Else return 0. */ int metrics_policy_permits_address(const tor_addr_t *addr) From 9de1d14c1c14d79d8d3cfa79ac60ff813e90c8e8 Mon Sep 17 00:00:00 2001 From: trinity-1686a Date: Sat, 29 Jul 2023 22:37:18 +0200 Subject: [PATCH 2/4] add config ReevaluateExitPolicy --- doc/man/tor.1.txt | 10 ++++++++++ src/app/config/config.c | 1 + src/app/config/or_options_st.h | 2 ++ src/config/torrc.sample.in | 4 ++++ src/core/or/connection_edge.c | 4 ++-- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/doc/man/tor.1.txt b/doc/man/tor.1.txt index 1589809b1a..248c0b7896 100644 --- a/doc/man/tor.1.txt +++ b/doc/man/tor.1.txt @@ -2385,6 +2385,16 @@ is non-zero): policy options are set, Tor behaves as if ExitRelay were set to 0. (Default: auto) +[[ReevaluateExitPolicy]] **ReevaluateExitPolicy** **0**|**1**:: + If set, reevaluate the exit policy on existing connections when reloading + configuration. + + + + When the exit policy of an exit node change while reloading configuration, + connections made prior to this change could violate the new policy. By + setting this to 1, Tor will check if such connections exist, and mark them + for termination. + (Default: 0) + [[ExtendAllowPrivateAddresses]] **ExtendAllowPrivateAddresses** **0**|**1**:: When this option is enabled, Tor will connect to relays on localhost, RFC1918 addresses, and so on. In particular, Tor will make direct OR diff --git a/src/app/config/config.c b/src/app/config/config.c index 60565d15c4..ae7f6203ce 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -637,6 +637,7 @@ static const config_var_t option_vars_[] = { V(RephistTrackTime, INTERVAL, "24 hours"), V_IMMUTABLE(RunAsDaemon, BOOL, "0"), V(ReducedExitPolicy, BOOL, "0"), + V(ReevaluateExitPolicy, BOOL, "0"), OBSOLETE("RunTesting"), // currently unused V_IMMUTABLE(Sandbox, BOOL, "0"), V(SafeLogging, STRING, "1"), diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h index 36b00662b5..624dc61bc5 100644 --- a/src/app/config/or_options_st.h +++ b/src/app/config/or_options_st.h @@ -141,6 +141,8 @@ struct or_options_t { * Includes OutboundBindAddresses and * configured ports. */ int ReducedExitPolicy; /**ReevaluateExitPolicy == 1) {*/ - if (false) { + if (get_options()->ReevaluateExitPolicy == 0) { return; } @@ -4262,6 +4261,7 @@ connection_reapply_exit_policy(config_line_t *changes) "ExitRelay", "ExitPolicy", "ReducedExitPolicy", + "ReevaluateExitPolicy", "IPv6Exit", NULL }; From 083fbd5dd810d7022fe1d65e4aa72425a8d5da6c Mon Sep 17 00:00:00 2001 From: trinity-1686a Date: Sat, 5 Aug 2023 13:56:57 +0200 Subject: [PATCH 3/4] handle invalid exitpolicy when reapplying it --- src/core/or/connection_edge.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index 9466446ab1..900d639959 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -4282,7 +4282,10 @@ connection_reapply_exit_policy(config_line_t *changes) // descriptor, which is regenerated asynchronously, so we have to parse the // policy ourselves. // We don't verify for our own IP, it's not part of the configuration. - policies_parse_exit_policy_from_options(get_options(), NULL, NULL, &policy); + if (BUG(policies_parse_exit_policy_from_options(get_options(), NULL, NULL, + &policy) != 0)) { + return; + } conn_list = connection_list_by_type_purpose(CONN_TYPE_EXIT, EXIT_PURPOSE_CONNECT); From bb16c1b02075f523e1aa7589c549786f071b1573 Mon Sep 17 00:00:00 2001 From: trinity-1686a Date: Mon, 14 Aug 2023 17:12:38 +0200 Subject: [PATCH 4/4] add changes entry for reevaluate exit policy --- changes/ticket40676 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changes/ticket40676 diff --git a/changes/ticket40676 b/changes/ticket40676 new file mode 100644 index 0000000000..5a025d79b6 --- /dev/null +++ b/changes/ticket40676 @@ -0,0 +1,4 @@ + o Minor feature (exit policies): + - Implement reevaluating new exit policy against existing connections. This + is controlled by new config option ReevaluateExitPolicy, defaulting to 0. + Closes ticket 40676.