summaryrefslogtreecommitdiff
path: root/src/or/directory.c
diff options
context:
space:
mode:
authorteor (Tim Wilson-Brown) <teor2345@gmail.com>2016-04-28 15:37:59 +1000
committerNick Mathewson <nickm@torproject.org>2016-05-05 08:16:28 -0400
commit833b5f71a72394c02ef633ba0f78d7011fef6181 (patch)
treed8e31ef40161c2dd4b0d0577062c264a7989822e /src/or/directory.c
parent01e7f42a09108e71cede46d4a038c4b1253a3d42 (diff)
downloadtor-833b5f71a72394c02ef633ba0f78d7011fef6181.tar.gz
tor-833b5f71a72394c02ef633ba0f78d7011fef6181.zip
Make clients always use begindir for directory requests
This improves client anonymity and avoids directory header tampering. The extra load on the authorities should be offset by the fallback directories feature. This also simplifies the fixes to #18809.
Diffstat (limited to 'src/or/directory.c')
-rw-r--r--src/or/directory.c61
1 files changed, 53 insertions, 8 deletions
diff --git a/src/or/directory.c b/src/or/directory.c
index ca3b3e338b..a03283e7fc 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -964,6 +964,16 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status)
update_certificate_downloads(time(NULL));
}
+/* Should this tor instance only use begindir for all its directory requests?
+ */
+int
+directory_must_use_begindir(const or_options_t *options)
+{
+ /* Clients, onion services, and bridges must use begindir,
+ * relays and authorities do not have to */
+ return !public_server_mode(options);
+}
+
/** Evaluate the situation and decide if we should use an encrypted
* "begindir-style" connection for this directory request.
* 1) If or_port is 0, or it's a direct conn and or_port is firewalled
@@ -971,23 +981,48 @@ connection_dir_download_cert_failed(dir_connection_t *conn, int status)
* 2) If we prefer to avoid begindir conns, and we're not fetching or
* publishing a bridge relay descriptor, no.
* 3) Else yes.
+ * If returning 0, return in *reason why we can't use begindir.
+ * reason must not be NULL.
*/
static int
directory_command_should_use_begindir(const or_options_t *options,
const tor_addr_t *addr,
int or_port, uint8_t router_purpose,
- dir_indirection_t indirection)
+ dir_indirection_t indirection,
+ const char **reason)
{
(void) router_purpose;
- if (!or_port)
+ tor_assert(reason);
+ *reason = NULL;
+
+ /* Reasons why we can't possibly use begindir */
+ if (!or_port) {
+ *reason = "directory with unknown ORPort";
return 0; /* We don't know an ORPort -- no chance. */
- if (indirection == DIRIND_DIRECT_CONN || indirection == DIRIND_ANON_DIRPORT)
+ }
+ if (indirection == DIRIND_DIRECT_CONN ||
+ indirection == DIRIND_ANON_DIRPORT) {
+ *reason = "DirPort connection";
return 0;
- if (indirection == DIRIND_ONEHOP)
+ }
+ if (indirection == DIRIND_ONEHOP) {
+ /* We're firewalled and want a direct OR connection */
if (!fascist_firewall_allows_address_addr(addr, or_port,
- FIREWALL_OR_CONNECTION, 0, 0) ||
- directory_fetches_from_authorities(options))
- return 0; /* We're firewalled or are acting like a relay -- also no. */
+ FIREWALL_OR_CONNECTION, 0, 0)) {
+ *reason = "ORPort not reachable";
+ return 0;
+ }
+ }
+ /* Reasons why we want to avoid using begindir */
+ if (indirection == DIRIND_ONEHOP) {
+ if (!directory_must_use_begindir(options)) {
+ *reason = "in relay mode";
+ return 0;
+ }
+ }
+ /* DIRIND_ONEHOP on a client, or DIRIND_ANONYMOUS
+ */
+ *reason = "(using begindir)";
return 1;
}
@@ -1070,11 +1105,13 @@ directory_initiate_command_rend(const tor_addr_port_t *or_addr_port,
dir_connection_t *conn;
const or_options_t *options = get_options();
int socket_error = 0;
+ const char *begindir_reason = NULL;
/* Should the connection be to a relay's OR port (and inside that we will
* send our directory request)? */
const int use_begindir = directory_command_should_use_begindir(options,
&or_addr_port->addr, or_addr_port->port,
- router_purpose, indirection);
+ router_purpose, indirection,
+ &begindir_reason);
/* Will the connection go via a three-hop Tor circuit? Note that this
* is separate from whether it will use_begindir. */
const int anonymized_connection = dirind_is_anon(indirection);
@@ -1100,6 +1137,14 @@ directory_initiate_command_rend(const tor_addr_port_t *or_addr_port,
(void)is_sensitive_dir_purpose;
#endif
+ /* use encrypted begindir connections for everything except relays
+ * this provides better protection for directory fetches */
+ if (!use_begindir && directory_must_use_begindir(options)) {
+ log_warn(LD_BUG, "Client could not use begindir connection: %s",
+ begindir_reason ? begindir_reason : "(NULL)");
+ return;
+ }
+
/* ensure that we don't make direct connections when a SOCKS server is
* configured. */
if (!anonymized_connection && !use_begindir && !options->HTTPProxy &&