Commit e147e867 authored by Nick Mathewson's avatar Nick Mathewson 🎨
Browse files

Proposal 152 implementation from Josh Albrecht, with tweaks.

svn:r16983
parent 87eb230c
......@@ -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
......
......@@ -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:
......
......@@ -4,7 +4,7 @@ Version:
Last-Modified:
Author: Geoff Goodell
Created: 13-Jul-2008
Status: Draft
Status: Closed
Overview
......
......@@ -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
......
......@@ -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();
......
......@@ -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"),
......
......@@ -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,
......
......@@ -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);
......
......@@ -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. */
......
......@@ -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);
......
......@@ -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);
......
......@@ -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) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment