diff --git a/src/or/or.h b/src/or/or.h index f6e84242b3..dcb09631f9 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1369,6 +1369,7 @@ routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port); routerinfo_t *router_get_by_nickname(const char *nickname); routerinfo_t *router_get_by_hexdigest(const char *hexdigest); routerinfo_t *router_get_by_digest(const char *digest); +int router_digest_is_trusted_dir(const char *digest); void router_get_routerlist(routerlist_t **prouterlist); void routerlist_free(routerlist_t *routerlist); void routerlist_clear_trusted_directories(void); diff --git a/src/or/router.c b/src/or/router.c index 1ff60d2d0e..35562eff73 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -516,12 +516,8 @@ int router_rebuild_descriptor(void) { log_fn(LOG_WARN, "Couldn't dump router to string."); return -1; } - /* XXX008 NM: no, we shouldn't just blindly assume we're an - * authdirserver just because our dir_port is set. We should - * take these next two lines out, and then set our is_trusted_dir - * variable if we find ourselves in the dirservers file. Yes/no? */ - if (ri->dir_port) - ri->is_trusted_dir = 1; + ri->is_trusted_dir = ri->dir_port && + router_digest_is_trusted_dir(ri->identity_digest); return 0; } diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 2ecb1aaabc..250e7d2a87 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -26,6 +26,9 @@ static int router_resolve_routerlist(routerlist_t *dir); /****************************************************************************/ +/** List of digests of keys for servers that are trusted directories. */ +static smartlist_t *trusted_dir_digests = NULL; + /**** * Functions to manage and access our list of known routers. (Note: * dirservers maintain a separate, independent list of known router @@ -306,6 +309,16 @@ routerinfo_t *router_get_by_nickname(const char *nickname) return NULL; } +/** Return true iff digest is the digest of the identity key of + * a trusted directory. */ +int router_digest_is_trusted_dir(const char *digest) { + if (!trusted_dir_digests) + return 0; + SMARTLIST_FOREACH(trusted_dir_digests, char *, cp, + if (!memcmp(digest, cp, DIGEST_LEN)) return 1); + return 0; +} + /** Return the router in our routerlist whose hexadecimal key digest * is hexdigest. Return NULL if no such router is known. */ routerinfo_t *router_get_by_hexdigest(const char *hexdigest) { @@ -527,9 +540,14 @@ int router_load_routerlist_from_file(char *routerfile, int trusted) /** Mark all directories in the routerlist as nontrusted. */ void routerlist_clear_trusted_directories(void) { - if (!routerlist) return; - SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, r, - r->is_trusted_dir = 0); + if (routerlist) { + SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, r, + r->is_trusted_dir = 0); + } + if (trusted_dir_digests) { + SMARTLIST_FOREACH(trusted_dir_digests, char *, cp, tor_free(cp)); + smartlist_clear(trusted_dir_digests); + } } /** Helper function: read routerinfo elements from s, and throw out the @@ -546,8 +564,19 @@ int router_load_routerlist_from_string(const char *s, int trusted) return -1; } if (trusted) { - SMARTLIST_FOREACH(new_list->routers, routerinfo_t *, r, - if (r->dir_port) r->is_trusted_dir = 1); + int i; + if (!trusted_dir_digests) + trusted_dir_digests = smartlist_create(); + for (i=0;irouters);++i) { + routerinfo_t *r = smartlist_get(new_list->routers, i); + if (r->dir_port) { + char *b; + r->is_trusted_dir = 1; + b = tor_malloc(DIGEST_LEN); + memcpy(b, r->identity_digest, DIGEST_LEN); + smartlist_add(trusted_dir_digests, b); + } + } } if (routerlist) { SMARTLIST_FOREACH(new_list->routers, routerinfo_t *, r,