mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Bugfixes in directory code:
Improve debugging output on fingerprint checking. Make sure to add our own fingerprint to the fingerprint list _before_ adding our own descriptor, or else we'll reject ourself. Don't call a directory invalid just because we have a newer descriptor for some router. Use router_get_dir_hash to generate hashes for signed directories. Make sure we add our own descriptor successfully. Don't fall-through on failed base64-endode. svn:r514
This commit is contained in:
parent
d0273ee135
commit
01786266ca
@ -20,6 +20,34 @@ typedef struct fingerprint_entry_t {
|
||||
static fingerprint_entry_t fingerprint_list[MAX_ROUTERS_IN_DIR];
|
||||
static int n_fingerprints = 0;
|
||||
|
||||
static void
|
||||
add_fingerprint_to_dir(const char *nickname, const char *fp)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_fingerprints; ++i) {
|
||||
if (!strcasecmp(fingerprint_list[i].nickname,nickname)) {
|
||||
free(fingerprint_list[i].fingerprint);
|
||||
fingerprint_list[i].fingerprint = strdup(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fingerprint_list[n_fingerprints].nickname = strdup(nickname);
|
||||
fingerprint_list[n_fingerprints].fingerprint = strdup(fp);
|
||||
++n_fingerprints;
|
||||
}
|
||||
|
||||
int
|
||||
dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
|
||||
{
|
||||
char fp[FINGERPRINT_LEN+1];
|
||||
if (crypto_pk_get_fingerprint(pk, fp)<0) {
|
||||
log_fn(LOG_ERR, "Error computing fingerprint");
|
||||
return -1;
|
||||
}
|
||||
add_fingerprint_to_dir(nickname, fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return 0 on success, -1 on failure */
|
||||
int
|
||||
dirserv_parse_fingerprint_file(const char *fname)
|
||||
@ -83,7 +111,9 @@ dirserv_router_fingerprint_is_known(const routerinfo_t *router)
|
||||
fingerprint_entry_t *ent =NULL;
|
||||
char fp[FINGERPRINT_LEN+1];
|
||||
|
||||
log_fn(LOG_DEBUG, "%d fingerprints known.", n_fingerprints);
|
||||
for (i=0;i<n_fingerprints;++i) {
|
||||
log_fn(LOG_DEBUG,"%s vs %s", router->nickname, fingerprint_list[i].nickname);
|
||||
if (!strcasecmp(router->nickname,fingerprint_list[i].nickname)) {
|
||||
ent = &fingerprint_list[i];
|
||||
break;
|
||||
@ -91,6 +121,7 @@ dirserv_router_fingerprint_is_known(const routerinfo_t *router)
|
||||
}
|
||||
|
||||
if (!ent) { /* No such server known */
|
||||
log_fn(LOG_WARNING,"no fingerprint found for %s",router->nickname);
|
||||
return 0;
|
||||
}
|
||||
if (crypto_pk_get_fingerprint(router->identity_pkey, fp)) {
|
||||
@ -98,8 +129,10 @@ dirserv_router_fingerprint_is_known(const routerinfo_t *router)
|
||||
return 0;
|
||||
}
|
||||
if (0==strcasecmp(ent->fingerprint, fp)) {
|
||||
log_fn(LOG_DEBUG,"good fingerprint for %s",router->nickname);
|
||||
return 1; /* Right fingerprint. */
|
||||
} else {
|
||||
log_fn(LOG_WARNING,"mismatched fingerprint for %s",router->nickname);
|
||||
return 0; /* Wrong fingerprint. */
|
||||
}
|
||||
}
|
||||
@ -201,7 +234,11 @@ dirserv_add_descriptor(const char **desc)
|
||||
if ((*desc_ent_ptr)->published > ri->published_on) {
|
||||
/* We already have a newer descriptor */
|
||||
log_fn(LOG_INFO,"We already have a newer desc for nickname %s. Not adding.",ri->nickname);
|
||||
goto err;
|
||||
/* This isn't really an error; return. */
|
||||
if (desc_tmp) free(desc_tmp);
|
||||
if (ri) routerinfo_free(ri);
|
||||
*desc = end;
|
||||
return 0;
|
||||
}
|
||||
/* We don't have a newer one; we'll update this one. */
|
||||
free_descriptor_entry(*desc_ent_ptr);
|
||||
@ -291,7 +328,7 @@ dirserv_dump_directory_to_string(char *s, int maxlen,
|
||||
i = strlen(s);
|
||||
cp = s + i;
|
||||
|
||||
if (crypto_SHA_digest(s, i, digest)) {
|
||||
if (router_get_dir_hash(s,digest)) {
|
||||
log_fn(LOG_WARNING,"couldn't compute digest");
|
||||
return -1;
|
||||
}
|
||||
|
@ -472,8 +472,16 @@ static int init_keys(void)
|
||||
log_fn(LOG_ERR, "Error initializing descriptor.");
|
||||
return -1;
|
||||
}
|
||||
/* We need to add our own fingerprint so it gets recognized. */
|
||||
if (dirserv_add_own_fingerprint(options.Nickname, get_identity_key())) {
|
||||
log_fn(LOG_ERR, "Error adding own fingerprint to approved set");
|
||||
return -1;
|
||||
}
|
||||
tmp = mydesc = router_get_my_descriptor();
|
||||
dirserv_add_descriptor(&tmp);
|
||||
if (dirserv_add_descriptor(&tmp)) {
|
||||
log(LOG_ERR, "Unable to add own descriptor to directory.");
|
||||
return -1;
|
||||
}
|
||||
sprintf(keydir,"%s/router.desc", options.DataDirectory);
|
||||
log_fn(LOG_INFO,"Dumping descriptor to %s...",keydir);
|
||||
if (write_str_to_file(keydir, mydesc)) {
|
||||
@ -744,7 +752,7 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router,
|
||||
written += strlen(s+written);
|
||||
if (base64_encode(s+written, maxlen-written, signature, 128) < 0) {
|
||||
log_fn(LOG_WARNING, "Couldn't base64-encode signature");
|
||||
/* XXX Nick: do we really mean to fall through here? */
|
||||
return -1;
|
||||
}
|
||||
written += strlen(s+written);
|
||||
strcat(s+written, "-----END SIGNATURE-----\n");
|
||||
|
@ -620,6 +620,8 @@ int connection_add(connection_t *conn);
|
||||
int connection_remove(connection_t *conn);
|
||||
void connection_set_poll_socket(connection_t *conn);
|
||||
|
||||
void get_connection_array(connection_t ***array, int *n);
|
||||
|
||||
void connection_watch_events(connection_t *conn, short events);
|
||||
int connection_is_reading(connection_t *conn);
|
||||
void connection_stop_reading(connection_t *conn);
|
||||
@ -677,6 +679,7 @@ int router_is_me(uint32_t addr, uint16_t port);
|
||||
void router_forget_router(uint32_t addr, uint16_t port);
|
||||
int router_get_list_from_file(char *routerfile);
|
||||
int router_get_router_hash(char *s, char *digest);
|
||||
int router_get_dir_hash(char *s, char *digest);
|
||||
|
||||
/* Reads a list of known routers, unsigned. */
|
||||
int router_get_list_from_string(char *s);
|
||||
@ -692,6 +695,7 @@ int router_compare_to_exit_policy(connection_t *conn);
|
||||
void routerinfo_free(routerinfo_t *router);
|
||||
|
||||
/********************************* dirserv.c ***************************/
|
||||
int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
|
||||
int dirserv_parse_fingerprint_file(const char *fname);
|
||||
int dirserv_router_fingerprint_is_known(const routerinfo_t *router);
|
||||
void dirserv_free_fingerprint_list();
|
||||
|
@ -570,7 +570,7 @@ static int router_get_hash_impl(char *s, char *digest, const char *start_str,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int router_get_dir_hash(char *s, char *digest)
|
||||
int router_get_dir_hash(char *s, char *digest)
|
||||
{
|
||||
return router_get_hash_impl(s,digest,
|
||||
"signed-directory","directory-signature");
|
||||
|
Loading…
Reference in New Issue
Block a user