[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r8523: Make "is a v1 authority", "is a v2 authority", and "is a hid (in tor/trunk: . doc src/or)
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] r8523: Make "is a v1 authority", "is a v2 authority", and "is a hid (in tor/trunk: . doc src/or)
- From: nickm@xxxxxxxx
- Date: Thu, 28 Sep 2006 19:58:00 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Thu, 28 Sep 2006 19:58:12 -0400
- Reply-to: or-talk@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
Author: nickm
Date: 2006-09-28 19:57:59 -0400 (Thu, 28 Sep 2006)
New Revision: 8523
Modified:
tor/trunk/
tor/trunk/ChangeLog
tor/trunk/doc/TODO
tor/trunk/doc/tor.1.in
tor/trunk/src/or/config.c
tor/trunk/src/or/directory.c
tor/trunk/src/or/dirserv.c
tor/trunk/src/or/or.h
tor/trunk/src/or/router.c
tor/trunk/src/or/routerlist.c
Log:
r8977@Kushana: nickm | 2006-09-28 19:56:41 -0400
Make "is a v1 authority", "is a v2 authority", and "is a hidden service authority" into separate flags so we can eventually migrate more trust away from moria.
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/trunk [r8977] on c95137ef-5f19-0410-b913-86e773d04f59
Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/ChangeLog 2006-09-28 23:57:59 UTC (rev 8523)
@@ -27,6 +27,10 @@
directory authorities don't think it's a good guard, treat it as if it
were unlisted: stop using it as a guard, and throw it off the guards
list if it stays that way for a long time.
+ - Allow directory authorities to be marked separately as authorities for
+ the v1 directory protocol, the v2 directory protocol, and as hidden
+ service directories. This should make it easier to migrate trust away
+ from one of the two authorities currently running on Moria.
o Security Fixes, minor:
- If a client asked for a server by name, and we didn't have a
Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/doc/TODO 2006-09-28 23:57:59 UTC (rev 8523)
@@ -35,13 +35,16 @@
D The right thing here is to revamp our node selection implementation.
(Deferred until oprofile says this matters.)
o make it configurable, so people can turn it on or off.
+N - Test guard unreachable logic; make sure that we actually attempt to
+ connect to guards that we think are unreachable from time to time.
+ Make sure that we don't freak out when the network is down.
N - Clients stop dumping old descriptors if the network-statuses
claim they're still valid.
R . If we fail to connect via an exit enclave, (warn and) try again
without demanding that exit node.
- And recognize when extending to the enclave node is failing,
so we can abandon then too.
-N - We need a separate list of "hidserv authorities" if we want to
+ o We need a separate list of "hidserv authorities" if we want to
retire moria1 from the main list.
P - Figure out why dll's compiled in mingw don't work right in Winxp.
P - Figure out why openssl 0.9.8c "make test" fails at sha256t test.
@@ -58,6 +61,12 @@
N - Specify general event system
R - Specify actual events.
+N - Have (and document) a BEGIN_DIR relay cell that means "Connect to your
+ directory port."
+ - Specify
+ - Implement
+ - Use for something, so we can be sure it works.
+
x - We should ship with a list of stable dir mirrors -- they're not
trusted like the authorities, but they'll provide more robustness
and diversity for bootstrapping clients.
Modified: tor/trunk/doc/tor.1.in
===================================================================
--- tor/trunk/doc/tor.1.in 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/doc/tor.1.in 2006-09-28 23:57:59 UTC (rev 8523)
@@ -98,14 +98,19 @@
Store working data in DIR (Default: @LOCALSTATEDIR@/lib/tor)
.LP
.TP
-\fBDirServer \fR[\fInickname\fR] [\fBv1\fR] \fIaddress\fR\fB:\fIport fingerprint\fP
+\fBDirServer \fR[\fInickname\fR] [\fBflags\fR] \fIaddress\fR\fB:\fIport fingerprint\fP
Use a nonstandard authoritative directory server at the provided
address and port, with the specified key fingerprint. This option can
be repeated many times, for multiple authoritative directory
-servers. If the "v1" option is provided, Tor will use this server as an
+servers. Flags are separated by spaces, and determine what kind of an
+authority this directory is. By default, every authority is authoritative
+for current ("v2")-style directories, unless the "no-v2" flag is given. If the "v1" flags is provided, Tor will use this server as an
authority for old-style (v1) directories as well. (Only directory mirrors
-care about this.) If no \fBdirserver\fP line is given, Tor will use the default
-directory servers: moria1, moria2, and tor26. NOTE: this option is intended
+care about this.) Tor will use this server as an authority for hidden
+service information if the "hs" flag is set, or if the "v1" flag is set and
+the "no-hs" flag is \fBnot\fP set.
+If no \fBdirserver\fP line is given, Tor will use the default
+directory servers. NOTE: this option is intended
for setting up a private Tor network with its own directory authorities. If
you use it, you will be distinguishable from other users, because you won't
believe the same authorities they do.
Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/src/or/config.c 2006-09-28 23:57:59 UTC (rev 8523)
@@ -3244,7 +3244,8 @@
char *addrport=NULL, *address=NULL, *nickname=NULL, *fingerprint=NULL;
uint16_t port;
char digest[DIGEST_LEN];
- int is_v1_authority = 0;
+ int is_v1_authority = 0, is_hidserv_authority = 0,
+ is_not_hidserv_authority = 0, is_v2_authority = 1;
items = smartlist_create();
smartlist_split_string(items, line, NULL,
@@ -3260,13 +3261,29 @@
smartlist_del_keeporder(items, 0);
}
- if (!strcmp(smartlist_get(items, 0), "v1")) {
- char *v1 = smartlist_get(items, 0);
- tor_free(v1);
- is_v1_authority = 1;
+ while (smartlist_len(items)) {
+ char *flag = smartlist_get(items, 0);
+ if (TOR_ISDIGIT(flag[0]))
+ break;
+ if (!strcasecmp(flag, "v1")) {
+ is_v1_authority = is_hidserv_authority = 1;
+ } else if (!strcasecmp(flag, "hs")) {
+ is_hidserv_authority = 1;
+ } else if (!strcasecmp(flag, "no-hs")) {
+ is_not_hidserv_authority = 1;
+ } else if (!strcasecmp(flag, "no-v2")) {
+ is_v2_authority = 0;
+ } else {
+ log_warn(LD_CONFIG, "Unrecognized flag '%s' on DirServer line",
+ flag);
+ }
+ tor_free(flag);
smartlist_del_keeporder(items, 0);
}
+ if (is_not_hidserv_authority)
+ is_hidserv_authority = 0;
+
if (smartlist_len(items) < 2) {
log_warn(LD_CONFIG, "Too few arguments to DirServer line.");
goto err;
@@ -3295,7 +3312,9 @@
if (!validate_only) {
log_debug(LD_DIR, "Trusted dirserver at %s:%d (%s)", address, (int)port,
(char*)smartlist_get(items,1));
- add_trusted_dir_server(nickname, address, port, digest, is_v1_authority);
+ add_trusted_dir_server(nickname, address, port, digest, is_v1_authority,
+ is_v2_authority, is_hidserv_authority);
+
}
r = 0;
Modified: tor/trunk/src/or/directory.c
===================================================================
--- tor/trunk/src/or/directory.c 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/src/or/directory.c 2006-09-28 23:57:59 UTC (rev 8523)
@@ -90,20 +90,23 @@
{
smartlist_t *dirservers;
int post_via_tor;
- int post_to_v1_only;
+ int post_to_hidserv_only;
dirservers = router_get_trusted_dir_servers();
tor_assert(dirservers);
/* Only old dirservers handle rendezvous descriptor publishing. */
- post_to_v1_only = (purpose == DIR_PURPOSE_UPLOAD_RENDDESC);
+ post_to_hidserv_only = (purpose == DIR_PURPOSE_UPLOAD_RENDDESC);
/* This tries dirservers which we believe to be down, but ultimately, that's
* harmless, and we may as well err on the side of getting things uploaded.
*/
SMARTLIST_FOREACH(dirservers, trusted_dir_server_t *, ds,
{
routerstatus_t *rs = &(ds->fake_status);
- if (post_to_v1_only && !ds->is_v1_authority)
+ if (post_to_hidserv_only && !ds->is_hidserv_authority)
continue;
+ if (!post_to_hidserv_only &&
+ !(ds->is_v1_authority || ds->is_v2_authority))
+ continue;
post_via_tor = purpose_is_private(purpose) ||
!fascist_firewall_allows_address_dir(ds->addr, ds->dir_port);
directory_initiate_command_routerstatus(rs, purpose, post_via_tor,
@@ -124,26 +127,37 @@
or_options_t *options = get_options();
int prefer_authority = server_mode(options) && options->DirPort != 0;
int directconn = !purpose_is_private(purpose);
+ authority_type_t type;
- int need_v1_support = purpose == DIR_PURPOSE_FETCH_DIR ||
- purpose == DIR_PURPOSE_FETCH_RUNNING_LIST ||
- purpose == DIR_PURPOSE_FETCH_RENDDESC;
- int need_v2_support = purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS ||
- purpose == DIR_PURPOSE_FETCH_SERVERDESC;
+ switch (purpose) {
+ case DIR_PURPOSE_FETCH_NETWORKSTATUS:
+ case DIR_PURPOSE_FETCH_SERVERDESC:
+ type = V2_AUTHORITY;
+ break;
+ case DIR_PURPOSE_FETCH_DIR:
+ case DIR_PURPOSE_FETCH_RUNNING_LIST:
+ type = V1_AUTHORITY;
+ break;
+ case DIR_PURPOSE_FETCH_RENDDESC:
+ type = HIDSERV_AUTHORITY;
+ break;
+ default:
+ log_warn(LD_BUG, "Unexpected purpose %d", (int)purpose);
+ return;
+ }
- if (!options->FetchServerDescriptors &&
- (need_v1_support || need_v2_support))
+ if (!options->FetchServerDescriptors && type != HIDSERV_AUTHORITY)
return;
if (directconn) {
if (prefer_authority) {
/* only ask authdirservers, and don't ask myself */
- rs = router_pick_trusteddirserver(need_v1_support, 1, 1,
+ rs = router_pick_trusteddirserver(type, 1, 1,
retry_if_no_servers);
}
if (!rs) {
/* anybody with a non-zero dirport will do */
- rs = router_pick_directory_server(1, 1, need_v2_support,
+ rs = router_pick_directory_server(1, 1, type==V2_AUTHORITY,
retry_if_no_servers);
if (!rs) {
const char *which;
@@ -158,7 +172,7 @@
log_info(LD_DIR,
"No router found for %s; falling back to dirserver list",
which);
- rs = router_pick_trusteddirserver(need_v1_support, 1, 1,
+ rs = router_pick_trusteddirserver(type, 1, 1,
retry_if_no_servers);
if (!rs)
directconn = 0; /* last resort: try routing it via Tor */
@@ -169,10 +183,11 @@
/* Never use fascistfirewall; we're going via Tor. */
if (purpose == DIR_PURPOSE_FETCH_RENDDESC) {
/* only ask authdirservers, any of them will do */
- rs = router_pick_trusteddirserver(1, 0, 0, retry_if_no_servers);
+ rs = router_pick_trusteddirserver(HIDSERV_AUTHORITY, 0, 0,
+ retry_if_no_servers);
} else {
/* anybody with a non-zero dirport will do. Disregard firewalls. */
- rs = router_pick_directory_server(1, 0, need_v2_support,
+ rs = router_pick_directory_server(1, 0, type == V2_AUTHORITY,
retry_if_no_servers);
/* If we have any hope of building an indirect conn, we know some router
* descriptors. If (rs==NULL), we can't build circuits anyway, so
Modified: tor/trunk/src/or/dirserv.c
===================================================================
--- tor/trunk/src/or/dirserv.c 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/src/or/dirserv.c 2006-09-28 23:57:59 UTC (rev 8523)
@@ -1025,7 +1025,7 @@
digestmap_iter_get(iter, &ident, &val);
d = val;
if (d->published < oldest_published &&
- !router_get_trusteddirserver_by_digest(ident)) {
+ !router_digest_is_trusted_dir(ident)) {
oldest = ident;
oldest_published = d->published;
}
Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/src/or/or.h 2006-09-28 23:57:59 UTC (rev 8523)
@@ -2506,8 +2506,14 @@
char digest[DIGEST_LEN]; /**< Digest of identity key */
unsigned int is_running:1; /**< True iff we think this server is running. */
/** True iff this server is an authority for the older ("v1") directory
- * protocol. (All authorities are v2 authorities.) */
+ * protocol. */
unsigned int is_v1_authority:1;
+ /** True iff this server is an authority for the newer ("v2") directory
+ * protocol. */
+ unsigned int is_v2_authority:1;
+ /** True iff this server is an authority for hidden services */
+ unsigned int is_hidserv_authority:1;
+
int n_networkstatus_failures; /**< How many times have we asked for this
* server's network-status unsuccessfully? */
routerstatus_t fake_status; /**< Used when we need to pass this trusted
@@ -2524,7 +2530,10 @@
int fascistfirewall,
int for_v2_directory,
int retry_if_no_servers);
-routerstatus_t *router_pick_trusteddirserver(int need_v1_authority,
+typedef enum {
+ V1_AUTHORITY, V2_AUTHORITY, HIDSERV_AUTHORITY,
+} authority_type_t;
+routerstatus_t *router_pick_trusteddirserver(authority_type_t type,
int requireother,
int fascistfirewall,
int retry_if_no_servers);
@@ -2592,7 +2601,8 @@
void add_trusted_dir_server(const char *nickname,
const char *address, uint16_t port,
- const char *digest, int is_v1_authority);
+ const char *digest, int is_v1_authority,
+ int is_v2_authority, int is_hidserv_authority);
void clear_trusted_dir_servers(void);
int any_trusted_dir_is_v1_authority(void);
networkstatus_t *networkstatus_get_by_digest(const char *digest);
Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/src/or/router.c 2006-09-28 23:57:59 UTC (rev 8523)
@@ -361,8 +361,10 @@
crypto_pk_get_digest(get_identity_key(), digest);
if (!router_digest_is_trusted_dir(digest)) {
add_trusted_dir_server(options->Nickname, NULL,
- (uint16_t)options->DirPort, digest,
- options->V1AuthoritativeDir);
+ (uint16_t)options->DirPort, digest,
+ options->V1AuthoritativeDir, /* v1 authority */
+ 1, /* v2 authority */
+ options->V1AuthoritativeDir /* hidserv authority */);
}
return 0; /* success */
}
Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c 2006-09-28 23:57:56 UTC (rev 8522)
+++ tor/trunk/src/or/routerlist.c 2006-09-28 23:57:59 UTC (rev 8523)
@@ -22,7 +22,7 @@
int fascistfirewall,
int for_v2_directory);
static routerstatus_t *router_pick_trusteddirserver_impl(
- int need_v1_authority, int requireother, int fascistfirewall);
+ authority_type_t type, int requireother, int fascistfirewall);
static void mark_all_trusteddirservers_up(void);
static int router_nickname_matches(routerinfo_t *router, const char *nickname);
static void routerstatus_list_update_from_networkstatus(time_t now);
@@ -97,6 +97,19 @@
* listed by the authorities */
static int have_warned_about_new_version = 0;
+/** Return the number of v2 directory authorities */
+static INLINE int
+get_n_v2_authorities(void)
+{
+ int n = 0;
+ if (!trusted_dir_servers)
+ return 0;
+ SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
+ if (ds->is_v2_authority)
+ ++n);
+ return n;
+}
+
/** Repopulate our list of network_status_t objects from the list cached on
* disk. Return 0 on success, -1 on failure. */
int
@@ -465,14 +478,14 @@
* Other args are as in router_pick_trusteddirserver_impl().
*/
routerstatus_t *
-router_pick_trusteddirserver(int need_v1_authority,
+router_pick_trusteddirserver(authority_type_t type,
int requireother,
int fascistfirewall,
int retry_if_no_servers)
{
routerstatus_t *choice;
- choice = router_pick_trusteddirserver_impl(need_v1_authority,
+ choice = router_pick_trusteddirserver_impl(type,
requireother, fascistfirewall);
if (choice || !retry_if_no_servers)
return choice;
@@ -480,7 +493,7 @@
log_info(LD_DIR,
"No trusted dirservers are reachable. Trying them all again.");
mark_all_trusteddirservers_up();
- return router_pick_trusteddirserver_impl(need_v1_authority,
+ return router_pick_trusteddirserver_impl(type,
requireother, fascistfirewall);
}
@@ -540,7 +553,7 @@
* system.
*/
static routerstatus_t *
-router_pick_trusteddirserver_impl(int need_v1_authority,
+router_pick_trusteddirserver_impl(authority_type_t type,
int requireother, int fascistfirewall)
{
smartlist_t *sl;
@@ -555,8 +568,12 @@
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
{
if (!d->is_running) continue;
- if (need_v1_authority && !d->is_v1_authority)
+ if (type == V1_AUTHORITY && !d->is_v1_authority)
continue;
+ if (type == V2_AUTHORITY && !d->is_v2_authority)
+ continue;
+ if (type == HIDSERV_AUTHORITY && !d->is_hidserv_authority)
+ continue;
if (requireother && me && router_digest_is_me(d->digest))
continue;
if (fascistfirewall) {
@@ -1310,9 +1327,7 @@
static int
max_descriptors_per_router(void)
{
- int n_authorities = 0;
- if (trusted_dir_servers)
- n_authorities = smartlist_len(trusted_dir_servers);
+ int n_authorities = get_n_v2_authorities();
return (n_authorities < 5) ? 5 : n_authorities;
}
@@ -2219,7 +2234,8 @@
}
base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
if (!(trusted_dir =
- router_get_trusteddirserver_by_digest(ns->identity_digest))) {
+ router_get_trusteddirserver_by_digest(ns->identity_digest))
+ || !trusted_dir->is_v2_authority) {
log_info(LD_DIR, "Network status was signed, but not by an authoritative "
"directory we recognize.");
if (!get_options()->DirPort) {
@@ -2536,6 +2552,8 @@
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{
char resource[HEX_DIGEST_LEN+6]; /* fp/hexdigit.z\0 */
+ if (!ds->is_v2_authority)
+ continue;
if (router_digest_is_me(ds->digest))
continue;
if (connection_get_by_type_addr_port_purpose(
@@ -2594,17 +2612,19 @@
* *one* if the most recent one's publication time is under
* NETWORKSTATUS_CLIENT_DL_INTERVAL.
*/
- if (!trusted_dir_servers || !smartlist_len(trusted_dir_servers))
+ if (!get_n_v2_authorities())
return;
- n_dirservers = n_running_dirservers = smartlist_len(trusted_dir_servers);
+ n_dirservers = n_running_dirservers = 0;
missing = smartlist_create();
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{
networkstatus_t *ns = networkstatus_get_by_digest(ds->digest);
- if (ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES) {
- --n_running_dirservers;
+ if (!ds->is_v2_authority)
continue;
- }
+ ++n_dirservers;
+ if (ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES)
+ continue;
+ ++n_running_dirservers;
if (ns && ns->published_on > now-NETWORKSTATUS_MAX_AGE)
++n_live;
else
@@ -2649,6 +2669,8 @@
if (i >= n_dirservers)
i = 0;
ds = smartlist_get(trusted_dir_servers, i);
+ if (! ds->is_v2_authority)
+ continue;
if (n_failed < n_dirservers &&
ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES) {
++n_failed;
@@ -2726,7 +2748,8 @@
* <b>address</b> is NULL, add ourself. */
void
add_trusted_dir_server(const char *nickname, const char *address,
- uint16_t port, const char *digest, int is_v1_authority)
+ uint16_t port, const char *digest, int is_v1_authority,
+ int is_v2_authority, int is_hidserv_authority)
{
trusted_dir_server_t *ent;
uint32_t a;
@@ -2760,6 +2783,8 @@
ent->dir_port = port;
ent->is_running = 1;
ent->is_v1_authority = is_v1_authority;
+ ent->is_v2_authority = is_v2_authority;
+ ent->is_hidserv_authority = is_hidserv_authority;
memcpy(ent->digest, digest, DIGEST_LEN);
dlen = 64 + strlen(hostname) + (nickname?strlen(nickname):0);
@@ -3115,8 +3140,8 @@
if (!warned_conflicts)
warned_conflicts = smartlist_create();
- n_trusted = smartlist_len(trusted_dir_servers);
n_statuses = smartlist_len(networkstatus_list);
+ n_trusted = get_n_v2_authorities();
if (n_statuses <= n_trusted/2) {
/* Not enough statuses to adjust status. */
@@ -3620,8 +3645,8 @@
return;
}
- if (networkstatus_list && smartlist_len(networkstatus_list) <=
- smartlist_len(trusted_dir_servers)/2) {
+ if (networkstatus_list &&
+ smartlist_len(networkstatus_list) <= get_n_v2_authorities()/2) {
log_info(LD_DIR,
"Not enough networkstatus documents to launch requests.");
}
@@ -3859,7 +3884,7 @@
res = 0;
goto done;
}
- n_authorities = smartlist_len(trusted_dir_servers);
+ n_authorities = get_n_v2_authorities();
n_ns = smartlist_len(networkstatus_list);
if (n_ns<=n_authorities/2) {
log_info(LD_DIR,
@@ -3904,6 +3929,8 @@
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{
+ if (!ds->is_v2_authority)
+ continue;
/* If we don't have the status, and we haven't failed to get the status,
* we haven't tried to get the status. */
if (!networkstatus_get_by_digest(ds->digest) &&