Merge remote-tracking branch 'public/bug6887'

This commit is contained in:
Nick Mathewson 2012-12-07 11:02:27 -05:00
commit 025dc19b63
6 changed files with 12 additions and 268 deletions

3
changes/bug6887 Normal file
View file

@ -0,0 +1,3 @@
o Removed code:
- Removed unused code to parse v1 directories and "running routers"
documents. Fixes bug 6887.

View file

@ -1147,6 +1147,8 @@ int
dirserv_dump_directory_to_string(char **dir_out,
crypto_pk_t *private_key)
{
/* XXXX 024 Get rid of this function if we can confirm that nobody's
* fetching these any longer */
char *cp;
char *identity_pkey; /* Identity key, DER64-encoded. */
char *recommended_versions;
@ -1447,22 +1449,13 @@ free_cached_dir_(void *_d)
* If <b>is_running_routers</b>, this is really a v1 running_routers
* document rather than a v1 directory.
*/
void
dirserv_set_cached_directory(const char *directory, time_t published,
int is_running_routers)
static void
dirserv_set_cached_directory(const char *directory, time_t published)
{
time_t now = time(NULL);
if (is_running_routers) {
if (published >= now - MAX_V1_RR_AGE)
set_cached_dir(&cached_runningrouters, tor_strdup(directory), published);
} else {
if (published >= now - MAX_V1_DIRECTORY_AGE) {
cached_dir_decref(cached_directory);
cached_directory = new_cached_dir(tor_strdup(directory), published);
}
}
}
/** If <b>networkstatus</b> is non-NULL, we've just received a v2
* network-status for an authoritative directory with identity digest
@ -1643,6 +1636,8 @@ dirserv_get_directory(void)
static cached_dir_t *
dirserv_regenerate_directory(void)
{
/* XXXX 024 Get rid of this function if we can confirm that nobody's
* fetching these any longer */
char *new_directory=NULL;
if (dirserv_dump_directory_to_string(&new_directory,
@ -1662,7 +1657,7 @@ dirserv_regenerate_directory(void)
/* Save the directory to disk so we re-load it quickly on startup.
*/
dirserv_set_cached_directory(the_directory->dir, time(NULL), 0);
dirserv_set_cached_directory(the_directory->dir, time(NULL));
return the_directory;
}

View file

@ -87,8 +87,6 @@ void directory_set_dirty(void);
cached_dir_t *dirserv_get_directory(void);
cached_dir_t *dirserv_get_runningrouters(void);
cached_dir_t *dirserv_get_consensus(const char *flavor_name);
void dirserv_set_cached_directory(const char *directory, time_t when,
int is_running_routers);
void dirserv_set_cached_networkstatus_v2(const char *directory,
const char *identity,
time_t published);

View file

@ -376,25 +376,6 @@ static token_rule_t dir_footer_token_table[] = {
END_OF_TABLE
};
/** List of tokens recognized in v1 directory headers/footers. */
static token_rule_t dir_token_table[] = {
/* don't enforce counts; this is obsolete. */
T( "network-status", K_NETWORK_STATUS, NO_ARGS, NO_OBJ ),
T( "directory-signature", K_DIRECTORY_SIGNATURE, ARGS, NEED_OBJ ),
T( "recommended-software",K_RECOMMENDED_SOFTWARE,CONCAT_ARGS, NO_OBJ ),
T( "signed-directory", K_SIGNED_DIRECTORY, NO_ARGS, NO_OBJ ),
T( "running-routers", K_RUNNING_ROUTERS, ARGS, NO_OBJ ),
T( "router-status", K_ROUTER_STATUS, ARGS, NO_OBJ ),
T( "published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ ),
T( "opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
T( "contact", K_CONTACT, CONCAT_ARGS, NO_OBJ ),
T( "dir-signing-key", K_DIR_SIGNING_KEY, ARGS, OBJ_OK ),
T( "fingerprint", K_FINGERPRINT, CONCAT_ARGS, NO_OBJ ),
END_OF_TABLE
};
/** List of tokens common to V3 authority certificates and V3 consensuses. */
#define CERTIFICATE_MEMBERS \
T1("dir-key-certificate-version", K_DIR_KEY_CERTIFICATE_VERSION, \
@ -581,7 +562,6 @@ static int check_signature_token(const char *digest,
crypto_pk_t *pkey,
int flags,
const char *doctype);
static crypto_pk_t *find_dir_signing_key(const char *str, const char *eos);
#undef DEBUG_AREA_ALLOC
@ -824,218 +804,6 @@ tor_version_is_obsolete(const char *myversion, const char *versionlist)
return ret;
}
/** Read a signed directory from <b>str</b>. If it's well-formed, return 0.
* Otherwise, return -1. If we're a directory cache, cache it.
*/
int
router_parse_directory(const char *str)
{
directory_token_t *tok;
char digest[DIGEST_LEN];
time_t published_on;
int r;
const char *end, *cp, *str_dup = str;
smartlist_t *tokens = NULL;
crypto_pk_t *declared_key = NULL;
memarea_t *area = memarea_new();
/* XXXX This could be simplified a lot, but it will all go away
* once pre-0.1.1.8 is obsolete, and for now it's better not to
* touch it. */
if (router_get_dir_hash(str, digest)) {
log_warn(LD_DIR, "Unable to compute digest of directory");
goto err;
}
log_debug(LD_DIR,"Received directory hashes to %s",hex_str(digest,4));
/* Check signature first, before we try to tokenize. */
cp = str;
while (cp && (end = strstr(cp+1, "\ndirectory-signature")))
cp = end;
if (cp == str || !cp) {
log_warn(LD_DIR, "No signature found on directory."); goto err;
}
++cp;
tokens = smartlist_new();
if (tokenize_string(area,cp,strchr(cp,'\0'),tokens,dir_token_table,0)) {
log_warn(LD_DIR, "Error tokenizing directory signature"); goto err;
}
if (smartlist_len(tokens) != 1) {
log_warn(LD_DIR, "Unexpected number of tokens in signature"); goto err;
}
tok=smartlist_get(tokens,0);
if (tok->tp != K_DIRECTORY_SIGNATURE) {
log_warn(LD_DIR,"Expected a single directory signature"); goto err;
}
declared_key = find_dir_signing_key(str, str+strlen(str));
note_crypto_pk_op(VERIFY_DIR);
if (check_signature_token(digest, DIGEST_LEN, tok, declared_key,
CST_CHECK_AUTHORITY, "directory")<0)
goto err;
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_clear(tokens);
memarea_clear(area);
/* Now try to parse the first part of the directory. */
if ((end = strstr(str,"\nrouter "))) {
++end;
} else if ((end = strstr(str, "\ndirectory-signature"))) {
++end;
} else {
end = str + strlen(str);
}
if (tokenize_string(area,str,end,tokens,dir_token_table,0)) {
log_warn(LD_DIR, "Error tokenizing directory"); goto err;
}
tok = find_by_keyword(tokens, K_PUBLISHED);
tor_assert(tok->n_args == 1);
if (parse_iso_time(tok->args[0], &published_on) < 0) {
goto err;
}
/* Now that we know the signature is okay, and we have a
* publication time, cache the directory. */
if (directory_caches_v1_dir_info(get_options()) &&
!authdir_mode_v1(get_options()))
dirserv_set_cached_directory(str, published_on, 0);
r = 0;
goto done;
err:
dump_desc(str_dup, "v1 directory");
r = -1;
done:
if (declared_key) crypto_pk_free(declared_key);
if (tokens) {
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
}
if (area) {
DUMP_AREA(area, "v1 directory");
memarea_drop_all(area);
}
return r;
}
/** Read a signed router status statement from <b>str</b>. If it's
* well-formed, return 0. Otherwise, return -1. If we're a directory cache,
* cache it.*/
int
router_parse_runningrouters(const char *str)
{
char digest[DIGEST_LEN];
directory_token_t *tok;
time_t published_on;
int r = -1;
crypto_pk_t *declared_key = NULL;
smartlist_t *tokens = NULL;
const char *eos = str + strlen(str), *str_dup = str;
memarea_t *area = NULL;
if (router_get_runningrouters_hash(str, digest)) {
log_warn(LD_DIR, "Unable to compute digest of running-routers");
goto err;
}
area = memarea_new();
tokens = smartlist_new();
if (tokenize_string(area,str,eos,tokens,dir_token_table,0)) {
log_warn(LD_DIR, "Error tokenizing running-routers"); goto err;
}
tok = smartlist_get(tokens,0);
if (tok->tp != K_NETWORK_STATUS) {
log_warn(LD_DIR, "Network-status starts with wrong token");
goto err;
}
tok = find_by_keyword(tokens, K_PUBLISHED);
tor_assert(tok->n_args == 1);
if (parse_iso_time(tok->args[0], &published_on) < 0) {
goto err;
}
if (!(tok = find_opt_by_keyword(tokens, K_DIRECTORY_SIGNATURE))) {
log_warn(LD_DIR, "Missing signature on running-routers");
goto err;
}
declared_key = find_dir_signing_key(str, eos);
note_crypto_pk_op(VERIFY_DIR);
if (check_signature_token(digest, DIGEST_LEN, tok, declared_key,
CST_CHECK_AUTHORITY, "running-routers")
< 0)
goto err;
/* Now that we know the signature is okay, and we have a
* publication time, cache the list. */
if (get_options()->DirPort_set && !authdir_mode_v1(get_options()))
dirserv_set_cached_directory(str, published_on, 1);
r = 0;
err:
dump_desc(str_dup, "v1 running-routers");
if (declared_key) crypto_pk_free(declared_key);
if (tokens) {
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t));
smartlist_free(tokens);
}
if (area) {
DUMP_AREA(area, "v1 running-routers");
memarea_drop_all(area);
}
return r;
}
/** Given a directory or running-routers string in <b>str</b>, try to
* find the its dir-signing-key token (if any). If this token is
* present, extract and return the key. Return NULL on failure. */
static crypto_pk_t *
find_dir_signing_key(const char *str, const char *eos)
{
const char *cp;
directory_token_t *tok;
crypto_pk_t *key = NULL;
memarea_t *area = NULL;
tor_assert(str);
tor_assert(eos);
/* Is there a dir-signing-key in the directory? */
cp = tor_memstr(str, eos-str, "\nopt dir-signing-key");
if (!cp)
cp = tor_memstr(str, eos-str, "\ndir-signing-key");
if (!cp)
return NULL;
++cp; /* Now cp points to the start of the token. */
area = memarea_new();
tok = get_next_token(area, &cp, eos, dir_token_table);
if (!tok) {
log_warn(LD_DIR, "Unparseable dir-signing-key token");
goto done;
}
if (tok->tp != K_DIR_SIGNING_KEY) {
log_warn(LD_DIR, "Dir-signing-key token did not parse as expected");
goto done;
}
if (tok->key) {
key = tok->key;
tok->key = NULL; /* steal reference. */
} else {
log_warn(LD_DIR, "Dir-signing-key token contained no key");
}
done:
if (tok) token_clear(tok);
if (area) {
DUMP_AREA(area, "dir-signing-key token");
memarea_drop_all(area);
}
return key;
}
/** Return true iff <b>key</b> is allowed to sign directories.
*/
static int

View file

@ -31,8 +31,6 @@ int router_parse_list_from_string(const char **s, const char *eos,
int is_extrainfo,
int allow_annotations,
const char *prepend_annotations);
int router_parse_runningrouters(const char *str);
int router_parse_directory(const char *str);
routerinfo_t *router_parse_entry_from_string(const char *s, const char *end,
int cache_copy,

View file

@ -223,24 +223,6 @@ test_dir_formats(void)
add_fingerprint_to_dir("Fred", buf, fingerprint_list);
}
{
char d[DIGEST_LEN];
const char *m;
/* XXXX NM re-enable. */
/* Make sure routers aren't too far in the past any more. */
r1->cache_info.published_on = time(NULL);
r2->cache_info.published_on = time(NULL)-3*60*60;
test_assert(router_dump_router_to_string(buf, 2048, r1, pk2)>0);
test_eq(dirserv_add_descriptor(buf,&m,""), ROUTER_ADDED_NOTIFY_GENERATOR);
test_assert(router_dump_router_to_string(buf, 2048, r2, pk1)>0);
test_eq(dirserv_add_descriptor(buf,&m,""), ROUTER_ADDED_NOTIFY_GENERATOR);
get_options()->Nickname = tor_strdup("DirServer");
test_assert(!dirserv_dump_directory_to_string(&cp,pk3, 0));
crypto_pk_get_digest(pk3, d);
test_assert(!router_parse_directory(cp));
test_eq(2, smartlist_len(dir1->routers));
tor_free(cp);
}
#endif
dirserv_free_fingerprint_list();