mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-20 10:12:15 +01:00
bugfixes and features: closer to making dirserv work
fix a variety of seg faults don't try to list OPs in running-routers write cached-directory to disk when rebuilding the dir on boot, dirservers load approved-routers file on boot, dirservers load cached directory file svn:r508
This commit is contained in:
parent
467d278b8b
commit
3ed7aedc11
@ -93,6 +93,7 @@ logv(int severity, const char *funcname, const char *format, va_list ap)
|
||||
formatted = 1;
|
||||
}
|
||||
fputs(buf, lf->file);
|
||||
/* XXX check for EOF */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,7 +405,7 @@ char *read_file_to_str(const char *filename) {
|
||||
}
|
||||
|
||||
if(stat(filename, &statbuf) < 0) {
|
||||
log_fn(LOG_WARNING,"Could not stat %s.",filename);
|
||||
log_fn(LOG_INFO,"Could not stat %s.",filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ static void command_process_created_cell(cell_t *cell, connection_t *conn) {
|
||||
circ = circuit_get_by_aci_conn(cell->aci, conn);
|
||||
|
||||
if(!circ) {
|
||||
log_fn(LOG_WARNING,"received CREATED cell (aci %d) for unknown circ. Dropping.", cell->aci);
|
||||
log_fn(LOG_INFO,"(aci %d) unknown circ (probably got a destroy earlier). Dropping.", cell->aci);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -186,6 +186,7 @@ static int directory_handle_command(connection_t *conn) {
|
||||
log_fn(LOG_DEBUG,"headers '%s', body '%s'.",headers,body);
|
||||
if(!strncasecmp(headers,"GET",3)) {
|
||||
/* XXX should check url and http version */
|
||||
log_fn(LOG_DEBUG,"Received GET command.");
|
||||
|
||||
dlen = dirserv_get_directory(&cp);
|
||||
|
||||
@ -206,7 +207,7 @@ static int directory_handle_command(connection_t *conn) {
|
||||
|
||||
if(!strncasecmp(headers,"POST",4)) {
|
||||
/* XXX should check url and http version */
|
||||
log_fn(LOG_DEBUG,"Received POST command, body '%s'", body);
|
||||
log_fn(LOG_DEBUG,"Received POST command.");
|
||||
cp = body;
|
||||
if(dirserv_add_descriptor(&cp) < 0) {
|
||||
log_fn(LOG_WARNING,"dirserv_add_descriptor() failed. Dropping.");
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "or.h"
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
|
||||
static int the_directory_is_dirty = 1;
|
||||
static char *the_directory = NULL;
|
||||
static int the_directory_len = -1;
|
||||
@ -155,7 +157,7 @@ dirserv_add_descriptor(const char **desc)
|
||||
routerinfo_t *ri = NULL;
|
||||
int i;
|
||||
char *start, *end;
|
||||
char *desc_tmp = NULL;
|
||||
char *desc_tmp = NULL, *cp;
|
||||
size_t desc_len;
|
||||
|
||||
start = strstr(*desc, "router ");
|
||||
@ -170,12 +172,12 @@ dirserv_add_descriptor(const char **desc)
|
||||
end = start+strlen(start);
|
||||
}
|
||||
desc_len = end-start;
|
||||
desc_tmp = tor_malloc(desc_len+1);
|
||||
cp = desc_tmp = tor_malloc(desc_len+1);
|
||||
strncpy(desc_tmp, start, desc_len);
|
||||
desc_tmp[desc_len]='\0';
|
||||
|
||||
/* Check: is the descriptor syntactically valid? */
|
||||
ri = router_get_entry_from_string(&desc_tmp);
|
||||
ri = router_get_entry_from_string(&cp);
|
||||
if (!ri) {
|
||||
log(LOG_WARNING, "Couldn't parse descriptor");
|
||||
goto err;
|
||||
@ -198,6 +200,7 @@ dirserv_add_descriptor(const char **desc)
|
||||
/* if so, decide whether to update it. */
|
||||
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. Ignoring.",ri->nickname);
|
||||
goto err;
|
||||
}
|
||||
/* We don't have a newer one; we'll update this one. */
|
||||
@ -278,7 +281,7 @@ dirserv_dump_directory_to_string(char *s, int maxlen,
|
||||
for (i = 0; i < n_descriptors; ++i) {
|
||||
strncat(cp, descriptor_list[i]->descriptor, descriptor_list[i]->desc_len);
|
||||
cp += descriptor_list[i]->desc_len;
|
||||
assert(!cp);
|
||||
assert(!*cp);
|
||||
}
|
||||
/* These multiple strlen calls are inefficient, but dwarfed by the RSA
|
||||
signature.
|
||||
@ -322,6 +325,7 @@ dirserv_dump_directory_to_string(char *s, int maxlen,
|
||||
size_t dirserv_get_directory(const char **directory)
|
||||
{
|
||||
char *new_directory;
|
||||
char filename[512];
|
||||
if (the_directory_is_dirty) {
|
||||
new_directory = tor_malloc(MAX_DIR_SIZE);
|
||||
if (dirserv_dump_directory_to_string(new_directory, MAX_DIR_SIZE,
|
||||
@ -341,11 +345,16 @@ size_t dirserv_get_directory(const char **directory)
|
||||
* router lists. This does more signature checking than is strictly
|
||||
* necessary, but safe is better than sorry. */
|
||||
new_directory = strdup(the_directory);
|
||||
/* use a new copy of the dir, since get_dir_from_string scribbles on it */
|
||||
if (router_get_dir_from_string(new_directory, get_identity_key())) {
|
||||
log_fn(LOG_ERR, "We just generated a directory we can't parse. Dying.");
|
||||
exit(0);
|
||||
}
|
||||
free(new_directory);
|
||||
sprintf(filename,"%s/cached-directory", options.DataDirectory);
|
||||
if(write_str_to_file(filename,the_directory) < 0) {
|
||||
log_fn(LOG_WARNING, "Couldn't write cached directory to disk. Ignoring.");
|
||||
}
|
||||
} else {
|
||||
log(LOG_INFO,"Directory still clean, reusing.");
|
||||
}
|
||||
|
@ -502,7 +502,8 @@ static int init_keys(void)
|
||||
crypto_pk_env_t *prkey;
|
||||
|
||||
/* OP's don't need keys. Just initialize the TLS context.*/
|
||||
if (!options.OnionRouter && !options.DirPort) {
|
||||
if (!options.OnionRouter) {
|
||||
assert(!options.DirPort);
|
||||
if (tor_tls_context_new(NULL, 0, NULL)<0) {
|
||||
log_fn(LOG_ERR, "Error creating TLS context for OP.");
|
||||
return -1;
|
||||
@ -514,32 +515,31 @@ static int init_keys(void)
|
||||
log_fn(LOG_ERR, "DataDirectory is too long.");
|
||||
return -1;
|
||||
}
|
||||
strcpy(keydir, options.DataDirectory);
|
||||
if (check_private_dir(keydir, 1)) {
|
||||
if (check_private_dir(options.DataDirectory, 1)) {
|
||||
return -1;
|
||||
}
|
||||
strcat(keydir, "/keys");
|
||||
sprintf(keydir,"%s/keys",options.DataDirectory);
|
||||
if (check_private_dir(keydir, 1)) {
|
||||
return -1;
|
||||
}
|
||||
cp = keydir + strlen(keydir); /* End of string. */
|
||||
assert(!*cp);
|
||||
|
||||
/* 1. Read identity key. Make it if none is found. */
|
||||
strcat(keydir, "/identity.key");
|
||||
strcpy(cp, "/identity.key");
|
||||
log_fn(LOG_INFO,"Reading/making identity key %s...",keydir);
|
||||
prkey = init_key_from_file(keydir);
|
||||
if (!prkey) return -1;
|
||||
set_identity_key(prkey);
|
||||
/* 2. Read onion key. Make it if none is found. */
|
||||
*cp = '\0';
|
||||
strcat(keydir, "/onion.key");
|
||||
strcpy(cp, "/onion.key");
|
||||
log_fn(LOG_INFO,"Reading/making onion key %s...",keydir);
|
||||
prkey = init_key_from_file(keydir);
|
||||
if (!prkey) return -1;
|
||||
set_onion_key(prkey);
|
||||
|
||||
/* 3. Initialize link key and TLS context. */
|
||||
*cp = '\0';
|
||||
strcat(keydir, "/link.key");
|
||||
strcpy(cp, "/link.key");
|
||||
log_fn(LOG_INFO,"Reading/making link key %s...",keydir);
|
||||
prkey = init_key_from_file(keydir);
|
||||
if (!prkey) return -1;
|
||||
set_link_key(prkey);
|
||||
@ -553,14 +553,14 @@ static int init_keys(void)
|
||||
log_fn(LOG_ERR, "Error initializing descriptor.");
|
||||
return -1;
|
||||
}
|
||||
strcpy(keydir, options.DataDirectory);
|
||||
strcat(keydir, "/router.desc");
|
||||
sprintf(keydir,"%s/router.desc", options.DataDirectory);
|
||||
log_fn(LOG_INFO,"Dumping descriptor to %s...",keydir);
|
||||
if (write_str_to_file(keydir, router_get_my_descriptor())) {
|
||||
return -1;
|
||||
}
|
||||
/* 5. Dump fingerprint to 'fingerprint' */
|
||||
strcpy(keydir, options.DataDirectory);
|
||||
strcat(keydir, "/fingerprint");
|
||||
sprintf(keydir,"%s/fingerprint", options.DataDirectory);
|
||||
log_fn(LOG_INFO,"Dumping fingerprint to %s...",keydir);
|
||||
assert(strlen(options.Nickname) <= MAX_NICKNAME_LEN);
|
||||
strcpy(fingerprint, options.Nickname);
|
||||
strcat(fingerprint, " ");
|
||||
@ -572,6 +572,30 @@ static int init_keys(void)
|
||||
strcat(fingerprint, "\n");
|
||||
if (write_str_to_file(keydir, fingerprint))
|
||||
return -1;
|
||||
if(!options.DirPort)
|
||||
return 0;
|
||||
/* 6. [dirserver only] load approved-routers file */
|
||||
sprintf(keydir,"%s/approved-routers", options.DataDirectory);
|
||||
log_fn(LOG_INFO,"Loading approved fingerprints from %s...",keydir);
|
||||
if(dirserv_parse_fingerprint_file(keydir) < 0) {
|
||||
log_fn(LOG_ERR, "Error loading fingerprints");
|
||||
return -1;
|
||||
}
|
||||
/* 7. [dirserver only] load old directory, if it's there */
|
||||
sprintf(keydir,"%s/cached-directory", options.DataDirectory);
|
||||
log_fn(LOG_INFO,"Loading cached directory from %s...",keydir);
|
||||
cp = read_file_to_str(keydir);
|
||||
if(!cp) {
|
||||
log_fn(LOG_INFO,"Cached directory %s not present. Ok.",keydir);
|
||||
} else {
|
||||
if(dirserv_init_from_directory_string(cp) < 0) {
|
||||
log_fn(LOG_ERR, "Cached directory %s is corrupt", keydir);
|
||||
free(cp);
|
||||
return -1;
|
||||
}
|
||||
free(cp);
|
||||
}
|
||||
/* success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -829,6 +853,8 @@ list_running_servers(char **nicknames_out)
|
||||
conn = connection_array[i];
|
||||
if (conn->type != CONN_TYPE_OR || conn->state != OR_CONN_STATE_OPEN)
|
||||
continue; /* only list successfully handshaked OR's. */
|
||||
if(!conn->nickname) /* it's an OP, don't list it */
|
||||
continue;
|
||||
nickname_lst[n++] = conn->nickname;
|
||||
}
|
||||
length = n + 1; /* spaces + EOS + 1. */
|
||||
|
@ -669,7 +669,7 @@ int router_get_dir_from_string_impl(char *s, directory_t **dest,
|
||||
NEXT_TOK();
|
||||
TOK_IS(K_RECOMMENDED_SOFTWARE, "recommended-software");
|
||||
if (tok.val.cmd.n_args != 1) {
|
||||
log_fn(LOG_WARNING, "Invalid recommded-software line");
|
||||
log_fn(LOG_WARNING, "Invalid recommended-software line");
|
||||
goto err;
|
||||
}
|
||||
versions = strdup(tok.val.cmd.args[0]);
|
||||
@ -677,7 +677,7 @@ int router_get_dir_from_string_impl(char *s, directory_t **dest,
|
||||
NEXT_TOK();
|
||||
TOK_IS(K_RUNNING_ROUTERS, "running-routers");
|
||||
n_good_nicknames = tok.val.cmd.n_args;
|
||||
memcpy(good_nickname_lst, tok.val.cmd.args, n_good_nicknames);
|
||||
memcpy(good_nickname_lst, tok.val.cmd.args, n_good_nicknames*sizeof(char *));
|
||||
|
||||
if (router_get_list_from_string_impl(&s, &new_dir,
|
||||
n_good_nicknames, good_nickname_lst)) {
|
||||
|
Loading…
Reference in New Issue
Block a user