Proposal 152 implementation from Josh Albrecht, with tweaks.

svn:r16983
This commit is contained in:
Nick Mathewson
2008-09-26 18:58:45 +00:00
parent 87eb230c01
commit e147e867be
12 changed files with 88 additions and 8 deletions
+4
View File
@@ -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
+10
View File
@@ -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
+14
View File
@@ -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
+4
View File
@@ -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();
+3
View File
@@ -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"),
+4 -2
View File
@@ -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,
+18 -3
View File
@@ -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);
+12
View File
@@ -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. */
+3 -2
View File
@@ -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);
+10
View File
@@ -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);
+5
View File
@@ -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) {