diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/dirserv.c | 42 | ||||
-rw-r--r-- | src/or/main.c | 211 | ||||
-rw-r--r-- | src/or/or.h | 7 | ||||
-rw-r--r-- | src/or/routers.c | 189 |
4 files changed, 235 insertions, 214 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 73ff278e0..afe91a161 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -10,6 +10,8 @@ static int the_directory_is_dirty = 1; static char *the_directory = NULL; static int the_directory_len = -1; +static int list_running_servers(char **nicknames_out); + /************** Fingerprint handling code ************/ typedef struct fingerprint_entry_t { @@ -291,6 +293,46 @@ dirserv_init_from_directory_string(const char *dir) return 0; } +static int +list_running_servers(char **nicknames_out) +{ + char *nickname_lst[MAX_ROUTERS_IN_DIR]; + connection_t **connection_array; + int n_conns; + connection_t *conn; + char *cp; + int n = 0, i; + int length; + *nicknames_out = NULL; + nickname_lst[n++] = options.Nickname; + + get_connection_array(&connection_array, &n_conns); + for (i = 0; i<n_conns; ++i) { + 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. */ + for (i = 0; i<n; ++i) { + length += strlen(nickname_lst[i]); + } + *nicknames_out = tor_malloc(length); + cp = *nicknames_out; + memset(cp,0,length); + for (i = 0; i<n; ++i) { + if (i) + strcat(cp, " "); + strcat(cp, nickname_lst[i]); + while (*cp) + ++cp; + } + return 0; +} + + int dirserv_dump_directory_to_string(char *s, int maxlen, crypto_pk_env_t *private_key) diff --git a/src/or/main.c b/src/or/main.c index be88ae270..befcc893d 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -3,9 +3,6 @@ /* $Id$ */ #include "or.h" -#ifdef HAVE_UNAME -#include <sys/utsname.h> -#endif /********* START PROTOTYPES **********/ @@ -38,8 +35,6 @@ static crypto_pk_env_t *onionkey=NULL; static crypto_pk_env_t *linkkey=NULL; static crypto_pk_env_t *identitykey=NULL; -routerinfo_t *my_routerinfo=NULL; - /********* END VARIABLES ************/ void set_onion_key(crypto_pk_env_t *k) { @@ -279,11 +274,7 @@ static int prepare_for_poll(void) { if(time_to_fetch_directory < now.tv_sec) { /* it's time to fetch a new directory and/or post our descriptor */ if(options.OnionRouter) { - if (init_descriptor()<0) { - log_fn(LOG_WARNING, "Error initializing descriptor. Not uploading desc."); - } else { - router_upload_desc_to_dirservers(); - } + router_upload_desc_to_dirservers(); } if(!options.DirPort) { /* NOTE directory servers do not currently fetch directories. @@ -482,7 +473,7 @@ static int init_keys(void) } /* 4. Dump router descriptor to 'router.desc' */ /* Must be called after keys are initialized. */ - if (init_descriptor()<0) { + if (!(router_get_my_descriptor())) { log_fn(LOG_ERR, "Error initializing descriptor."); return -1; } @@ -681,204 +672,6 @@ static void dumpstats(void) { /* dump stats to stdout */ } } -static void get_platform_str(char *platform, int len) -{ -#ifdef HAVE_UNAME - struct utsname u; - if (!uname(&u)) { - snprintf(platform, len-1, "Tor %s on %s %s %s %s %s", - VERSION, u.sysname, u.nodename, u.release, u.version, u.machine); - platform[len-1] = '\0'; - return; - } else -#endif - { - snprintf(platform, len-1, "Tor %s", VERSION); - } -} - -int dump_router_to_string(char *s, int maxlen, routerinfo_t *router, - crypto_pk_env_t *ident_key) { - char *onion_pkey; - char *link_pkey; - char *identity_pkey; - char platform[256]; - char digest[20]; - char signature[128]; - char published[32]; - int onion_pkeylen, link_pkeylen, identity_pkeylen; - int written; - int result=0; - struct exit_policy_t *tmpe; - - get_platform_str(platform, sizeof(platform)); - - if(crypto_pk_write_public_key_to_string(router->onion_pkey, - &onion_pkey,&onion_pkeylen)<0) { - log_fn(LOG_WARNING,"write onion_pkey to string failed!"); - return -1; - } - - if(crypto_pk_write_public_key_to_string(router->identity_pkey, - &identity_pkey,&identity_pkeylen)<0) { - log_fn(LOG_WARNING,"write identity_pkey to string failed!"); - return -1; - } - - if(crypto_pk_write_public_key_to_string(router->link_pkey, - &link_pkey,&link_pkeylen)<0) { - log_fn(LOG_WARNING,"write link_pkey to string failed!"); - return -1; - } - strftime(published, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router->published_on)); - - result = snprintf(s, maxlen, - "router %s %s %d %d %d %d\n" - "platform %s\n" - "published %s\n" - "onion-key\n%s" - "link-key\n%s" - "signing-key\n%s", - router->nickname, - router->address, - router->or_port, - router->ap_port, - router->dir_port, - router->bandwidth, - platform, - published, - onion_pkey, link_pkey, identity_pkey); - - free(onion_pkey); - free(link_pkey); - free(identity_pkey); - - if(result < 0 || result >= maxlen) { - /* apparently different glibcs do different things on snprintf error.. so check both */ - return -1; - } - written = result; - - for(tmpe=router->exit_policy; tmpe; tmpe=tmpe->next) { - result = snprintf(s+written, maxlen-written, "%s %s:%s\n", - tmpe->policy_type == EXIT_POLICY_ACCEPT ? "accept" : "reject", - tmpe->address, tmpe->port); - if(result < 0 || result+written > maxlen) { - /* apparently different glibcs do different things on snprintf error.. so check both */ - return -1; - } - written += result; - } - if (written > maxlen-256) /* Not enough room for signature. */ - return -1; - - strcat(s+written, "router-signature\n"); - written += strlen(s+written); - s[written] = '\0'; - if (router_get_router_hash(s, digest) < 0) - return -1; - - if (crypto_pk_private_sign(ident_key, digest, 20, signature) < 0) { - log_fn(LOG_WARNING, "Error signing digest"); - return -1; - } - strcat(s+written, "-----BEGIN SIGNATURE-----\n"); - written += strlen(s+written); - if (base64_encode(s+written, maxlen-written, signature, 128) < 0) { - log_fn(LOG_WARNING, "Couldn't base64-encode signature"); - return -1; - } - written += strlen(s+written); - strcat(s+written, "-----END SIGNATURE-----\n"); - written += strlen(s+written); - - if (written > maxlen-2) - return -1; - /* include a last '\n' */ - s[written] = '\n'; - s[written+1] = 0; - return written+1; -} - -int -list_running_servers(char **nicknames_out) -{ - char *nickname_lst[MAX_ROUTERS_IN_DIR]; - connection_t *conn; - char *cp; - int n = 0, i; - int length; - *nicknames_out = NULL; - if (my_routerinfo) - nickname_lst[n++] = my_routerinfo->nickname; - for (i = 0; i<nfds; ++i) { - 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. */ - for (i = 0; i<n; ++i) { - length += strlen(nickname_lst[i]); - } - *nicknames_out = tor_malloc(length); - cp = *nicknames_out; - memset(cp,0,length); - for (i = 0; i<n; ++i) { - if (i) - strcat(cp, " "); - strcat(cp, nickname_lst[i]); - while (*cp) - ++cp; - } - return 0; -} - -static char descriptor[8192]; -/* XXX should this replace my_routerinfo? */ -static routerinfo_t *desc_routerinfo; -const char *router_get_my_descriptor(void) { - log_fn(LOG_DEBUG,"my desc is '%s'",descriptor); - return descriptor; -} - -static int init_descriptor(void) { - routerinfo_t *ri; - char localhostname[256]; - char *address = options.Address; - - if(!address) { /* if not specified in config, we find a default */ - if(gethostname(localhostname,sizeof(localhostname)) < 0) { - log_fn(LOG_WARNING,"Error obtaining local hostname"); - return -1; - } - address = localhostname; - } - ri = tor_malloc(sizeof(routerinfo_t)); - ri->address = strdup(address); - ri->nickname = strdup(options.Nickname); - /* No need to set addr. */ - ri->or_port = options.ORPort; - ri->ap_port = options.APPort; - ri->dir_port = options.DirPort; - ri->published_on = time(NULL); - ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); - ri->link_pkey = crypto_pk_dup_key(get_link_key()); - ri->identity_pkey = crypto_pk_dup_key(get_identity_key()); - ri->bandwidth = options.TotalBandwidth; - ri->exit_policy = NULL; /* XXX implement this. */ - if (desc_routerinfo) - routerinfo_free(desc_routerinfo); - desc_routerinfo = ri; - if (dump_router_to_string(descriptor, 8192, ri, get_identity_key())<0) { - log_fn(LOG_WARNING, "Couldn't dump router to string."); - return -1; - } - return 0; -} - void daemonize(void) { #ifndef MS_WINDOWS /* Fork; parent exits. */ diff --git a/src/or/or.h b/src/or/or.h index c44b780e4..b739eadcd 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -616,6 +616,7 @@ void set_onion_key(crypto_pk_env_t *k); crypto_pk_env_t *get_onion_key(void); void set_identity_key(crypto_pk_env_t *k); crypto_pk_env_t *get_identity_key(void); +crypto_pk_env_t *get_link_key(void); int connection_add(connection_t *conn); int connection_remove(connection_t *conn); void connection_set_poll_socket(connection_t *conn); @@ -629,8 +630,6 @@ void connection_start_reading(connection_t *conn); void connection_stop_writing(connection_t *conn); void connection_start_writing(connection_t *conn); -int list_running_servers(char **nicknames_out); - const char *router_get_my_descriptor(void); int main(int argc, char *argv[]); @@ -691,6 +690,10 @@ int router_get_dir_from_string_impl(char *s, directory_t **dest, routerinfo_t *router_get_entry_from_string(char **s); int router_compare_to_exit_policy(connection_t *conn); void routerinfo_free(routerinfo_t *router); +int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router, + crypto_pk_env_t *ident_key); +const routerinfo_t *router_get_desc_routerinfo(void); +const char *router_get_my_descriptor(void); /********************************* dirserv.c ***************************/ int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk); diff --git a/src/or/routers.c b/src/or/routers.c index 5e0d609aa..9d82e3f47 100644 --- a/src/or/routers.c +++ b/src/or/routers.c @@ -13,6 +13,9 @@ */ #include "or.h" +#ifdef HAVE_UNAME +#include <sys/utsname.h> +#endif /****************************************************************************/ @@ -20,7 +23,7 @@ static directory_t *directory = NULL; extern or_options_t options; /* command-line and config-file options */ -extern routerinfo_t *my_routerinfo; /* from main.c */ +static routerinfo_t *my_routerinfo; /****************************************************************************/ @@ -35,8 +38,8 @@ static char *find_whitespace(char *s); static void router_free_exit_policy(routerinfo_t *router); static int router_add_exit_policy(routerinfo_t *router, directory_token_t *tok); -static int -router_resolve_directory(directory_t *dir); +static int router_resolve_directory(directory_t *dir); +static int init_descriptor(void); /****************************************************************************/ @@ -113,6 +116,11 @@ void router_upload_desc_to_dirservers(void) { if(!directory) return; + if (!router_get_my_descriptor()) { + log_fn(LOG_WARNING, "No descriptor; skipping upload"); + return; + } + for(i=0;i<directory->n_routers;i++) { router = directory->routers[i]; if(router->dir_port > 0) @@ -1087,6 +1095,181 @@ int router_compare_to_exit_policy(connection_t *conn) { } +static char descriptor[8192]; +/* XXX should this replace my_routerinfo? */ +static routerinfo_t *desc_routerinfo = NULL; +const char *router_get_my_descriptor(void) { + if (!desc_routerinfo) { + if (init_descriptor()) + return NULL; + } + log_fn(LOG_DEBUG,"my desc is '%s'",descriptor); + return descriptor; +} +const routerinfo_t *router_get_desc_routerinfo(void) { + if (!desc_routerinfo) { + if (init_descriptor()) + return NULL; + } + return desc_routerinfo; +} + +static int init_descriptor(void) { + routerinfo_t *ri; + char localhostname[256]; + char *address = options.Address; + + if(!address) { /* if not specified in config, we find a default */ + if(gethostname(localhostname,sizeof(localhostname)) < 0) { + log_fn(LOG_WARNING,"Error obtaining local hostname"); + return -1; + } + address = localhostname; + } + ri = tor_malloc(sizeof(routerinfo_t)); + ri->address = strdup(address); + ri->nickname = strdup(options.Nickname); + /* No need to set addr. */ + ri->or_port = options.ORPort; + ri->ap_port = options.APPort; + ri->dir_port = options.DirPort; + ri->published_on = time(NULL); + ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); + ri->link_pkey = crypto_pk_dup_key(get_link_key()); + ri->identity_pkey = crypto_pk_dup_key(get_identity_key()); + ri->bandwidth = options.TotalBandwidth; + ri->exit_policy = NULL; /* XXX implement this. */ + if (desc_routerinfo) + routerinfo_free(desc_routerinfo); + desc_routerinfo = ri; + if (router_dump_router_to_string(descriptor, 8192, ri, get_identity_key())<0) { + log_fn(LOG_WARNING, "Couldn't dump router to string."); + return -1; + } + return 0; +} + +static void get_platform_str(char *platform, int len) +{ +#ifdef HAVE_UNAME + struct utsname u; + if (!uname(&u)) { + snprintf(platform, len-1, "Tor %s on %s %s %s %s %s", + VERSION, u.sysname, u.nodename, u.release, u.version, u.machine); + platform[len-1] = '\0'; + return; + } else +#endif + { + snprintf(platform, len-1, "Tor %s", VERSION); + } +} + +int router_dump_router_to_string(char *s, int maxlen, routerinfo_t *router, + crypto_pk_env_t *ident_key) { + char *onion_pkey; + char *link_pkey; + char *identity_pkey; + char platform[256]; + char digest[20]; + char signature[128]; + char published[32]; + int onion_pkeylen, link_pkeylen, identity_pkeylen; + int written; + int result=0; + struct exit_policy_t *tmpe; + + get_platform_str(platform, sizeof(platform)); + + if(crypto_pk_write_public_key_to_string(router->onion_pkey, + &onion_pkey,&onion_pkeylen)<0) { + log_fn(LOG_WARNING,"write onion_pkey to string failed!"); + return -1; + } + + if(crypto_pk_write_public_key_to_string(router->identity_pkey, + &identity_pkey,&identity_pkeylen)<0) { + log_fn(LOG_WARNING,"write identity_pkey to string failed!"); + return -1; + } + + if(crypto_pk_write_public_key_to_string(router->link_pkey, + &link_pkey,&link_pkeylen)<0) { + log_fn(LOG_WARNING,"write link_pkey to string failed!"); + return -1; + } + strftime(published, 32, "%Y-%m-%d %H:%M:%S", gmtime(&router->published_on)); + + result = snprintf(s, maxlen, + "router %s %s %d %d %d %d\n" + "platform %s\n" + "published %s\n" + "onion-key\n%s" + "link-key\n%s" + "signing-key\n%s", + router->nickname, + router->address, + router->or_port, + router->ap_port, + router->dir_port, + router->bandwidth, + platform, + published, + onion_pkey, link_pkey, identity_pkey); + + free(onion_pkey); + free(link_pkey); + free(identity_pkey); + + if(result < 0 || result >= maxlen) { + /* apparently different glibcs do different things on snprintf error.. so check both */ + return -1; + } + written = result; + + for(tmpe=router->exit_policy; tmpe; tmpe=tmpe->next) { + result = snprintf(s+written, maxlen-written, "%s %s:%s\n", + tmpe->policy_type == EXIT_POLICY_ACCEPT ? "accept" : "reject", + tmpe->address, tmpe->port); + if(result < 0 || result+written > maxlen) { + /* apparently different glibcs do different things on snprintf error.. so check both */ + return -1; + } + written += result; + } + if (written > maxlen-256) /* Not enough room for signature. */ + return -1; + + strcat(s+written, "router-signature\n"); + written += strlen(s+written); + s[written] = '\0'; + if (router_get_router_hash(s, digest) < 0) + return -1; + + if (crypto_pk_private_sign(ident_key, digest, 20, signature) < 0) { + log_fn(LOG_WARNING, "Error signing digest"); + return -1; + } + strcat(s+written, "-----BEGIN SIGNATURE-----\n"); + written += strlen(s+written); + if (base64_encode(s+written, maxlen-written, signature, 128) < 0) { + log_fn(LOG_WARNING, "Couldn't base64-encode signature"); + return -1; + } + written += strlen(s+written); + strcat(s+written, "-----END SIGNATURE-----\n"); + written += strlen(s+written); + + if (written > maxlen-2) + return -1; + /* include a last '\n' */ + s[written] = '\n'; + s[written+1] = 0; + return written+1; +} + + + /* Local Variables: mode:c |