From ef5925237d4712c40fb6d69b8de882ab39e6798f Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 21 Sep 2010 01:03:29 -0400 Subject: First cut of code to enable RefuseUnknownExits The RefuseUnknownExits config option is now a tristate, with "1" meaning "enable it no matter what the consensus says", "0" meaning "disable it no matter what the consensus says", and "auto" meaning "do what the consensus says". If the consensus is silent, we enable RefuseUnknownExits. This patch also changes the dirserv logic so that refuseunknownexits won't make us cache unless we're an exit. --- src/or/config.c | 21 ++++++++++++++++++++- src/or/connection_edge.c | 4 +--- src/or/dirserv.c | 12 +++++++++--- src/or/or.h | 10 ++++++---- src/or/router.c | 30 ++++++++++++++++++++++++++++++ src/or/router.h | 2 ++ 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/or/config.c b/src/or/config.c index 6b3bcf6da..30a4d0f29 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -327,7 +327,7 @@ static config_var_t _option_vars[] = { V(RecommendedClientVersions, LINELIST, NULL), V(RecommendedServerVersions, LINELIST, NULL), OBSOLETE("RedirectExit"), - V(RefuseUnknownExits, BOOL, "0"), + V(RefuseUnknownExits, STRING, "auto"), V(RejectPlaintextPorts, CSV, ""), V(RelayBandwidthBurst, MEMUNIT, "0"), V(RelayBandwidthRate, MEMUNIT, "0"), @@ -1228,6 +1228,19 @@ options_act(or_options_t *old_options) if (accounting_is_enabled(options)) configure_accounting(time(NULL)); + /* parse RefuseUnknownExits tristate */ + if (!strcmp(options->RefuseUnknownExits, "0")) + options->RefuseUnknownExits_ = 0; + else if (!strcmp(options->RefuseUnknownExits, "1")) + options->RefuseUnknownExits_ = 1; + else if (!strcmp(options->RefuseUnknownExits, "auto")) + options->RefuseUnknownExits_ = -1; + else { + /* Should have caught this in options_validate */ + return -1; + } + + /* Change the cell EWMA settings */ cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus()); @@ -2994,6 +3007,12 @@ options_validate(or_options_t *old_options, or_options_t *options, REJECT("Failed to resolve/guess local address. See logs for details."); } + if (strcmp(options->RefuseUnknownExits, "0") && + strcmp(options->RefuseUnknownExits, "1") && + strcmp(options->RefuseUnknownExits, "auto")) { + REJECT("RefuseUnknownExits must be 0, 1, or auto"); + } + #ifndef MS_WINDOWS if (options->RunAsDaemon && torrc_fname && path_is_relative(torrc_fname)) REJECT("Can't use a relative path to torrc when RunAsDaemon is set."); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 6a3a5ef0a..63595151d 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -2537,9 +2537,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) (or_circ->is_first_hop || (!connection_or_digest_is_known_relay( or_circ->p_conn->identity_digest) && -// XXX022 commented out so we can test it first in 0.2.2.11 -RD -// networkstatus_get_param(NULL, "refuseunknownexits", 1)))) { - get_options()->RefuseUnknownExits))) { + should_refuse_unknown_exits(get_options())))) { /* Don't let clients use us as a single-hop proxy, unless the user * has explicitly allowed that in the config. It attracts attackers * and users who'd be better off with, well, single-hop proxies. diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 3fcf1783d..6dca0d100 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1153,18 +1153,21 @@ directory_fetches_from_authorities(or_options_t *options) { routerinfo_t *me; uint32_t addr; + int refuseunknown; if (options->FetchDirInfoEarly) return 1; if (options->BridgeRelay == 1) return 0; if (server_mode(options) && router_pick_published_address(options, &addr)<0) return 1; /* we don't know our IP address; ask an authority. */ - if (options->DirPort == 0 && !options->RefuseUnknownExits) + refuseunknown = router_my_exit_policy_is_reject_star() && + should_refuse_unknown_exits(options); + if (options->DirPort == 0 && !refuseunknown) return 0; if (!server_mode(options) || !advertised_server_mode()) return 0; me = router_get_my_routerinfo(); - if (!me || (!me->dir_port && !options->RefuseUnknownExits)) + if (!me || (!me->dir_port && !refuseunknown)) return 0; /* if dirport not advertised, return 0 too */ return 1; } @@ -1208,7 +1211,10 @@ directory_caches_dir_info(or_options_t *options) return 1; if (!server_mode(options) || !advertised_server_mode()) return 0; - return options->RefuseUnknownExits; + /* We need an up-to-date view of network info if we're going to try to + * block unknown exits. */ + return router_my_exit_policy_is_reject_star() && + should_refuse_unknown_exits(options); } /** Return 1 if we want to allow remote people to ask us directory diff --git a/src/or/or.h b/src/or/or.h index 3c109738d..6c1c8efb8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2468,10 +2468,12 @@ typedef struct { int ConstrainedSockets; /**< Shrink xmit and recv socket buffers. */ uint64_t ConstrainedSockSize; /**< Size of constrained buffers. */ - /** Whether we should drop exit streams from Tors that we don't know - * are relays. XXX022 In here for 0.2.2.11 as a temporary test before - * we switch over to putting it in consensusparams. -RD */ - int RefuseUnknownExits; + /** Whether we should drop exit streams from Tors that we don't know are + * relays. One of "0" (never refuse), "1" (always refuse), or "auto" (do + * what the consensus says). -RD */ + const char *RefuseUnknownExits; + /** Parsed version of RefuseUnknownExits. -1 for auto. */ + int RefuseUnknownExits_; /** Application ports that require all nodes in circ to have sufficient * uptime. */ diff --git a/src/or/router.c b/src/or/router.c index 978078bf7..6ae2ed0db 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -18,6 +18,7 @@ #include "geoip.h" #include "hibernate.h" #include "main.h" +#include "networkstatus.h" #include "policies.h" #include "relay.h" #include "rephist.h" @@ -975,6 +976,22 @@ server_mode(or_options_t *options) return (options->ORPort != 0 || options->ORListenAddress); } +/** Return true iff the combination of options in options and parameters + * in consensus mean that we don't want to allow exits from circuits + * we got from addresses not known to be servers. */ +int +should_refuse_unknown_exits(or_options_t *options) +{ + networkstatus_t *consensus; + if (options->RefuseUnknownExits_ != -1) { + return options->RefuseUnknownExits_; + } else if ((consensus = networkstatus_get_latest_consensus()) != NULL) { + return networkstatus_get_param(consensus, "refuseunknownexits", 1); + } else { + return 1; + } +} + /** Remember if we've advertised ourselves to the dirservers. */ static int server_is_advertised=0; @@ -1137,6 +1154,17 @@ router_compare_to_my_exit_policy(edge_connection_t *conn) desc_routerinfo->exit_policy) != ADDR_POLICY_ACCEPTED; } +/** Return true iff my exit policy is reject *:*. Return -1 if we don't + * have a descriptor */ +int +router_my_exit_policy_is_reject_star(void) +{ + if (!router_get_my_routerinfo()) /* make sure desc_routerinfo exists */ + return -1; + + return desc_routerinfo->policy_is_reject_star; +} + /** Return true iff I'm a server and digest is equal to * my identity digest. */ int @@ -1300,6 +1328,8 @@ router_rebuild_descriptor(int force) policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy, options->ExitPolicyRejectPrivate, ri->address, !options->BridgeRelay); + ri->policy_is_reject_star = + policy_is_reject_star(ri->exit_policy); if (desc_routerinfo) { /* inherit values */ ri->is_valid = desc_routerinfo->is_valid; diff --git a/src/or/router.h b/src/or/router.h index d90a7cff9..c17fc78bd 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -51,6 +51,7 @@ int server_mode(or_options_t *options); int advertised_server_mode(void); int proxy_mode(or_options_t *options); void consider_publishable_server(int force); +int should_refuse_unknown_exits(or_options_t *options); void router_upload_dir_desc_to_dirservers(int force); void mark_my_descriptor_dirty_if_older_than(time_t when); @@ -60,6 +61,7 @@ void check_descriptor_ipaddress_changed(time_t now); void router_new_address_suggestion(const char *suggestion, const dir_connection_t *d_conn); int router_compare_to_my_exit_policy(edge_connection_t *conn); +int router_my_exit_policy_is_reject_star(void); routerinfo_t *router_get_my_routerinfo(void); extrainfo_t *router_get_my_extrainfo(void); const char *router_get_my_descriptor(void); -- cgit v1.2.3 From 6c5b9ba6258c8e79be9f96a3ec377600d0066356 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 27 Sep 2010 17:07:22 -0400 Subject: Change bug1751 enabling code based on comments from arma --- src/or/config.c | 1 - src/or/connection_edge.c | 9 +++++---- src/or/dirserv.c | 2 +- src/or/or.h | 5 +++-- src/or/router.c | 5 +---- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/or/config.c b/src/or/config.c index 30a4d0f29..b509fb862 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1240,7 +1240,6 @@ options_act(or_options_t *old_options) return -1; } - /* Change the cell EWMA settings */ cell_ewma_set_scale_factor(options, networkstatus_get_latest_consensus()); diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 63595151d..361f91017 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -2488,6 +2488,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) char *address=NULL; uint16_t port; or_circuit_t *or_circ = NULL; + or_options_t *options = get_options(); assert_circuit_ok(circ); if (!CIRCUIT_IS_ORIGIN(circ)) @@ -2500,7 +2501,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) * that we have a stream connected to a circuit, and we don't connect to a * circuit until we have a pending/successful resolve. */ - if (!server_mode(get_options()) && + if (!server_mode(options) && circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, "Relay begin cell at non-server. Closing."); @@ -2533,11 +2534,11 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) tor_free(address); return 0; } - if (or_circ && or_circ->p_conn && !get_options()->AllowSingleHopExits && + if (or_circ && or_circ->p_conn && !options->AllowSingleHopExits && (or_circ->is_first_hop || (!connection_or_digest_is_known_relay( or_circ->p_conn->identity_digest) && - should_refuse_unknown_exits(get_options())))) { + should_refuse_unknown_exits(options)))) { /* Don't let clients use us as a single-hop proxy, unless the user * has explicitly allowed that in the config. It attracts attackers * and users who'd be better off with, well, single-hop proxies. @@ -2557,7 +2558,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) return 0; } } else if (rh.command == RELAY_COMMAND_BEGIN_DIR) { - if (!directory_permits_begindir_requests(get_options()) || + if (!directory_permits_begindir_requests(options) || circ->purpose != CIRCUIT_PURPOSE_OR) { relay_send_end_cell_from_edge(rh.stream_id, circ, END_STREAM_REASON_NOTDIRECTORY, NULL); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 6dca0d100..8ae03424a 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1212,7 +1212,7 @@ directory_caches_dir_info(or_options_t *options) if (!server_mode(options) || !advertised_server_mode()) return 0; /* We need an up-to-date view of network info if we're going to try to - * block unknown exits. */ + * block exit attempts from unknown relays. */ return router_my_exit_policy_is_reject_star() && should_refuse_unknown_exits(options); } diff --git a/src/or/or.h b/src/or/or.h index 6c1c8efb8..2e532c9ef 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2470,8 +2470,9 @@ typedef struct { /** Whether we should drop exit streams from Tors that we don't know are * relays. One of "0" (never refuse), "1" (always refuse), or "auto" (do - * what the consensus says). -RD */ - const char *RefuseUnknownExits; + * what the consensus says, defaulting to 'refuse' if the consensus says + * nothing). */ + char *RefuseUnknownExits; /** Parsed version of RefuseUnknownExits. -1 for auto. */ int RefuseUnknownExits_; diff --git a/src/or/router.c b/src/or/router.c index 6ae2ed0db..d30eb1bfa 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -982,13 +982,10 @@ server_mode(or_options_t *options) int should_refuse_unknown_exits(or_options_t *options) { - networkstatus_t *consensus; if (options->RefuseUnknownExits_ != -1) { return options->RefuseUnknownExits_; - } else if ((consensus = networkstatus_get_latest_consensus()) != NULL) { - return networkstatus_get_param(consensus, "refuseunknownexits", 1); } else { - return 1; + return networkstatus_get_param(NULL, "refuseunknownexits", 1); } } -- cgit v1.2.3 From 8ac2de5ab98522abaa3289d6db155567e6126b50 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Sat, 18 Sep 2010 14:48:21 +0200 Subject: Add RefuseUnknownExits to the manpage --- doc/tor.1.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 3b7e30bdf..c42aae0e0 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -905,6 +905,12 @@ is non-zero): the next day. All times are local, and given in 24-hour time. (Defaults to "month 1 0:00".) +**RefuseUnknownExits** **0**|**1**|**auto**:: + Prevent nodes that don't appear in the consensus from exiting using this + relay. If the option is 1, we always block exit attempts from such + nodes; if it's 0, we never do, and if the option is "auto", then we do + whatever the authorities suggest in the consensus. (Defaults to auto.) + **ServerDNSResolvConfFile** __filename__:: Overrides the default DNS configuration with the configuration in __filename__. The file format is the same as the standard Unix -- cgit v1.2.3 From c951830002706719fd98f87dabd82437f3f392ac Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Mon, 27 Sep 2010 23:15:43 +0200 Subject: Fix a bridge segfault When we enabled support to change statistic options without restarting Tor we forgot to initialize geoip_countries. Fix that. --- changes/bug1964 | 3 +++ src/or/geoip.c | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 changes/bug1964 diff --git a/changes/bug1964 b/changes/bug1964 new file mode 100644 index 000000000..d100094eb --- /dev/null +++ b/changes/bug1964 @@ -0,0 +1,3 @@ + o Major bugfixes: + - Fix a segfault that can happen when using bridges. Fixes bug 1964; + bugfix on 0.2.2.15-alpha. diff --git a/src/or/geoip.c b/src/or/geoip.c index 7f1052e98..ee8d72ee1 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -254,6 +254,8 @@ geoip_get_country_by_ip(uint32_t ipaddr) int geoip_get_n_countries(void) { + if (!geoip_countries) + init_geoip_countries(); return (int) smartlist_len(geoip_countries); } -- cgit v1.2.3 From 9d7f0badb5f6b27deb64968329390b785cf24103 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Mon, 27 Sep 2010 17:44:00 -0400 Subject: changelog entry for bug1751 --- src/or/router.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/or/router.c b/src/or/router.c index d30eb1bfa..621cbaace 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -977,7 +977,7 @@ server_mode(or_options_t *options) } /** Return true iff the combination of options in options and parameters - * in consensus mean that we don't want to allow exits from circuits + * in the consensus mean that we don't want to allow exits from circuits * we got from addresses not known to be servers. */ int should_refuse_unknown_exits(or_options_t *options) -- cgit v1.2.3 From 8df3a909466217d6738d6fe4f7555f569b2a4cb7 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Mon, 27 Sep 2010 17:44:51 -0400 Subject: the actual changelog entry this time --- changes/bug1751 | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changes/bug1751 diff --git a/changes/bug1751 b/changes/bug1751 new file mode 100644 index 000000000..58ea9a225 --- /dev/null +++ b/changes/bug1751 @@ -0,0 +1,5 @@ + o Major features: + - Exit relays now try harder to block exit attempts from unknown + relays, to make it harder for people to use them as one-hop proxies. + Controlled by the refuseunknownexits consensus parameter, or you + can override it with the RefuseUnknownExits torrc option. -- cgit v1.2.3