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
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:
Last-Modified:
Author: Geoff Goodell
Created: 13-Jul-2008
-Status: Draft
+Status: Closed
Overview
"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"
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
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.
*/
consider_exit_family = 1;
}
+ /* XXXX021 Respect ExcludeSingleHopRelays here. */
+
if (!entry_guards)
entry_guards = smartlist_create();
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),
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"),
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,
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);
* 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
* 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. */
"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,
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);
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);
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,
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 ),
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) {