diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | doc/spec/dir-spec.txt | 10 | ||||
-rw-r--r-- | doc/spec/proposals/152-single-hop-circuits.txt | 2 | ||||
-rw-r--r-- | doc/tor.1.in | 14 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 4 | ||||
-rw-r--r-- | src/or/config.c | 3 | ||||
-rw-r--r-- | src/or/connection_edge.c | 6 | ||||
-rw-r--r-- | src/or/control.c | 21 | ||||
-rw-r--r-- | src/or/or.h | 12 | ||||
-rw-r--r-- | src/or/router.c | 5 | ||||
-rw-r--r-- | src/or/routerlist.c | 10 | ||||
-rw-r--r-- | src/or/routerparse.c | 5 |
12 files changed, 88 insertions, 8 deletions
@@ -83,6 +83,10 @@ Changes in version 0.2.1.6-alpha - 2008-09-xx v2 hidden service descriptors. - Authorities now serve a /tor/dbg-stability.txt URL to help debug WFU and MTBF calculations. + - Implement most of Proposal 152: allow specialized servers to permit + single-hop circuits, and clients to use those servers to build + single-hop circuits when using a specialized controller. Patch + from Josh Albrecht. Resolves "Bug" 768. o Code simplifications and refactoring: - Revise the connection_new functions so that a more typesafe variant diff --git a/doc/spec/dir-spec.txt b/doc/spec/dir-spec.txt index 2bbc014936..a010836156 100644 --- a/doc/spec/dir-spec.txt +++ b/doc/spec/dir-spec.txt @@ -591,6 +591,16 @@ $Id$ with unrecognized items; the protocols line should be preceded with an "opt" until these Tors are obsolete.] + "allow-single-hop-exits" + + [At most one.] + + Present only if the router allows single-hop circuits to make exit + connections. Most Tor servers do not support this: this is + included for specialized controllers designed to support perspective + access and such. + + 2.2. Extra-info documents Extra-info documents consist of the following items: diff --git a/doc/spec/proposals/152-single-hop-circuits.txt b/doc/spec/proposals/152-single-hop-circuits.txt index bff5b1650b..7f3894c65a 100644 --- a/doc/spec/proposals/152-single-hop-circuits.txt +++ b/doc/spec/proposals/152-single-hop-circuits.txt @@ -4,7 +4,7 @@ Version: Last-Modified: Author: Geoff Goodell Created: 13-Jul-2008 -Status: Draft +Status: Closed Overview diff --git a/doc/tor.1.in b/doc/tor.1.in index 48f5b00b22..67eb17e2a6 100644 --- a/doc/tor.1.in +++ b/doc/tor.1.in @@ -387,6 +387,14 @@ can opt to use them in some circuit positions, though. The default is "middle,rendezvous", and other choices are not advised. .LP .TP +\fBExcludeSingleHopRelays \fR\fB0\fR|\fB1\fR\fP +This option controls whether circuits built by Tor will include relays with +the AllowSingleHopExits flag set to true. If ExcludeSingleHopRelays is set to +0, these relays will be included. Note that these relays might be at higher +risk of being seized or observed, so they are not normally included. +(Default: 1) +.LP +.TP \fBBridge \fR\fIIP:ORPort\fR [fingerprint]\fP When set along with UseBridges, instructs Tor to use the relay at "IP:ORPort" as a "bridge" relaying into the Tor network. If "fingerprint" @@ -784,6 +792,12 @@ The IP address or fqdn of this server (e.g. moria.mit.edu). You can leave this unset, and Tor will guess your IP address. .LP .TP +\fBAllowSingleHopExits \fR\fB0\fR|\fB1\fR\fP +This option controls whether clients can use this server as a single hop +proxy. If set to 1, clients can use this server as an exit even if it is +the only hop in the circuit. (Default: 0) +.LP +.TP \fBAssumeReachable \fR\fB0\fR|\fB1\fR\fP This option is used when bootstrapping a new Tor network. If set to 1, don't do self-reachability testing; just upload your server descriptor diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index c531dbe10a..42ccae71aa 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1197,6 +1197,8 @@ choose_good_exit_server_general(routerlist_t *dir, int need_uptime, connections = get_connection_array(); + /* XXXX021 Respect ExcludeSingleHopRelays here. */ + /* Count how many connections are waiting for a circuit to be built. * We use this for log messages now, but in the future we may depend on it. */ @@ -2458,6 +2460,8 @@ choose_random_entry(cpath_build_state_t *state) consider_exit_family = 1; } + /* XXXX021 Respect ExcludeSingleHopRelays here. */ + if (!entry_guards) entry_guards = smartlist_create(); diff --git a/src/or/config.c b/src/or/config.c index 219be16481..de1c6e0b3f 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -136,6 +136,8 @@ static config_var_t _option_vars[] = { V(Address, STRING, NULL), V(AllowInvalidNodes, CSV, "middle,rendezvous"), V(AllowNonRFC953Hostnames, BOOL, "0"), + V(AllowSingleHopCircuits, BOOL, "0"), + V(AllowSingleHopExits, BOOL, "0"), V(AlternateBridgeAuthority, LINELIST, NULL), V(AlternateDirAuthority, LINELIST, NULL), V(AlternateHSAuthority, LINELIST, NULL), @@ -198,6 +200,7 @@ static config_var_t _option_vars[] = { V(TestingEstimatedDescriptorPropagationTime, INTERVAL, "10 minutes"), V(ExcludeNodes, ROUTERSET, NULL), V(ExcludeExitNodes, ROUTERSET, NULL), + V(ExcludeSingleHopRelays, BOOL, "1"), V(ExitNodes, ROUTERSET, NULL), V(ExitPolicy, LINELIST, NULL), V(ExitPolicyRejectPrivate, BOOL, "1"), diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index fe05aed521..4d054a88a6 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -2498,8 +2498,10 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) tor_free(address); return 0; } - if (or_circ && or_circ->is_first_hop) { - /* Don't let clients use us as a single-hop proxy; it attracts attackers + if (or_circ && or_circ->is_first_hop && + !get_options()->AllowSingleHopExits) { + /* 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. */ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, diff --git a/src/or/control.c b/src/or/control.c index 93a946405d..8ae93e4998 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -2324,11 +2324,26 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len, conn); return 0; } + /* Is this a single hop circuit? */ if (circ && (circuit_get_cpath_len(circ)<2 || hop==1)) { - connection_write_str_to_buf( - "551 Can't attach stream to one-hop circuit.\r\n", conn); - return 0; + routerinfo_t *r = NULL; + char* exit_digest; + if (circ->build_state && + circ->build_state->chosen_exit && + circ->build_state->chosen_exit->identity_digest) { + exit_digest = circ->build_state->chosen_exit->identity_digest; + r = router_get_by_digest(exit_digest); + } + /* Do both the client and relay allow one-hop exit circuits? */ + if (!r || !r->allow_single_hop_exits || + !get_options()->AllowSingleHopCircuits) { + connection_write_str_to_buf( + "551 Can't attach stream to this one-hop circuit.\r\n", conn); + return 0; + } + ap_conn->chosen_exit_name = tor_strdup(hex_str(exit_digest, DIGEST_LEN)); } + if (circ && hop>0) { /* find this hop in the circuit, and set cpath */ cpath = circuit_get_cpath_hop(circ, hop); diff --git a/src/or/or.h b/src/or/or.h index f57dcfbd90..5820a56c4e 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1357,6 +1357,8 @@ typedef struct { * dnsworker code. */ unsigned int caches_extra_info:1; /**< Whether the router caches and serves * extrainfo documents. */ + unsigned int allow_single_hop_exits:1; /**< Whether the router allows + * single hop exits. */ /* local info */ unsigned int is_running:1; /**< As far as we know, is this OR currently @@ -2420,6 +2422,16 @@ typedef struct { * if we are a cache). For authorities, this is always true. */ int DownloadExtraInfo; + /** If true, and we are acting as a relay, allow exit circuits even when + * we are the first hop of a circuit. */ + int AllowSingleHopExits; + /** If true, don't allow relays with AllowSingleHopExits=1 to be used in + * circuits that we build. */ + int ExcludeSingleHopRelays; + /** If true, and the controller tells us to use a one-hop circuit, and the + * exit allows it, we use it. */ + int AllowSingleHopCircuits; + /** If true, do not believe anybody who tells us that a domain resolves * to an internal address, or that an internal address has a PTR mapping. * Helps avoid some cross-site attacks. */ diff --git a/src/or/router.c b/src/or/router.c index 94fa8d59de..29b930bbc0 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1687,7 +1687,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, "opt extra-info-digest %s\n%s" "onion-key\n%s" "signing-key\n%s" - "%s%s%s", + "%s%s%s%s", router->nickname, router->address, router->or_port, @@ -1704,7 +1704,8 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, onion_pkey, identity_pkey, family_line, we_are_hibernating() ? "opt hibernating 1\n" : "", - options->HidServDirectoryV2 ? "opt hidden-service-dir\n" : ""); + options->HidServDirectoryV2 ? "opt hidden-service-dir\n" : "", + options->AllowSingleHopExits ? "opt allow-single-hop-exits\n" : ""); tor_free(family_line); tor_free(onion_pkey); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 3a5c4d5998..be38cc569e 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1767,6 +1767,16 @@ router_choose_random_node(const char *preferred, excludednodes = smartlist_create(); + /* Exclude relays that allow single hop exit circuits, if the user + * wants to (such relays might be risky) */ + if (get_options()->ExcludeSingleHopRelays) { + routerlist_t *rl = router_get_routerlist(); + SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r, + if (r->allow_single_hop_exits) { + smartlist_add(excludednodes, r); + }); + } + if ((r = routerlist_find_my_routerinfo())) { smartlist_add(excludednodes, r); routerlist_add_family(excludednodes, r); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 5a8a17796a..c6b7454966 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -63,6 +63,7 @@ typedef enum { K_EXTRA_INFO_DIGEST, K_CACHES_EXTRA_INFO, K_HIDDEN_SERVICE_DIR, + K_ALLOW_SINGLE_HOP_EXITS, K_DIR_KEY_CERTIFICATE_VERSION, K_DIR_IDENTITY_KEY, @@ -239,6 +240,7 @@ static token_rule_t routerdesc_token_table[] = { T01("write-history", K_WRITE_HISTORY, ARGS, NO_OBJ ), T01("extra-info-digest", K_EXTRA_INFO_DIGEST, GE(1), NO_OBJ ), T01("hidden-service-dir", K_HIDDEN_SERVICE_DIR, NO_ARGS, NO_OBJ ), + T01("allow-single-hop-exits",K_ALLOW_SINGLE_HOP_EXITS, NO_ARGS, NO_OBJ ), T01("family", K_FAMILY, ARGS, NO_OBJ ), T01("caches-extra-info", K_CACHES_EXTRA_INFO, NO_ARGS, NO_OBJ ), @@ -1363,6 +1365,9 @@ router_parse_entry_from_string(const char *s, const char *end, if ((tok = find_first_by_keyword(tokens, K_CACHES_EXTRA_INFO))) router->caches_extra_info = 1; + if ((tok = find_first_by_keyword(tokens, K_ALLOW_SINGLE_HOP_EXITS))) + router->allow_single_hop_exits = 1; + if ((tok = find_first_by_keyword(tokens, K_EXTRA_INFO_DIGEST))) { tor_assert(tok->n_args >= 1); if (strlen(tok->args[0]) == HEX_DIGEST_LEN) { |