mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 14:51:11 +01:00
Merge remote-tracking branch 'public/bug6887'
This commit is contained in:
commit
025dc19b63
6 changed files with 12 additions and 268 deletions
3
changes/bug6887
Normal file
3
changes/bug6887
Normal file
|
@ -0,0 +1,3 @@
|
|||
o Removed code:
|
||||
- Removed unused code to parse v1 directories and "running routers"
|
||||
documents. Fixes bug 6887.
|
|
@ -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,21 +1449,12 @@ 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);
|
||||
}
|
||||
}
|
||||
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
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue