Loading doc/TODO +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ ARMA . add log convention to the HACKING file keydir under that with fixed names ARMA - tor faq list all other systems, why we're different. NICK - Move (most of) the router/directory code out of main.c o Move (most of) the router/directory code out of main.c Mid-term: . Redo scheduler Loading src/or/dirserv.c +42 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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) Loading src/or/main.c +2 −209 Original line number Diff line number Diff line Loading @@ -3,9 +3,6 @@ /* $Id$ */ #include "or.h" #ifdef HAVE_UNAME #include <sys/utsname.h> #endif /********* START PROTOTYPES **********/ Loading Loading @@ -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) { Loading Loading @@ -279,12 +274,8 @@ 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(); } } if(!options.DirPort) { /* NOTE directory servers do not currently fetch directories. * Hope this doesn't bite us later. */ Loading Loading @@ -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; } Loading Loading @@ -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. */ Loading src/or/or.h +5 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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[]); Loading Loading @@ -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); Loading src/or/routers.c +186 −3 Original line number Diff line number Diff line Loading @@ -13,6 +13,9 @@ */ #include "or.h" #ifdef HAVE_UNAME #include <sys/utsname.h> #endif /****************************************************************************/ Loading @@ -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; /****************************************************************************/ Loading @@ -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); /****************************************************************************/ Loading Loading @@ -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) Loading Loading @@ -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 Loading Loading
doc/TODO +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ ARMA . add log convention to the HACKING file keydir under that with fixed names ARMA - tor faq list all other systems, why we're different. NICK - Move (most of) the router/directory code out of main.c o Move (most of) the router/directory code out of main.c Mid-term: . Redo scheduler Loading
src/or/dirserv.c +42 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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) Loading
src/or/main.c +2 −209 Original line number Diff line number Diff line Loading @@ -3,9 +3,6 @@ /* $Id$ */ #include "or.h" #ifdef HAVE_UNAME #include <sys/utsname.h> #endif /********* START PROTOTYPES **********/ Loading Loading @@ -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) { Loading Loading @@ -279,12 +274,8 @@ 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(); } } if(!options.DirPort) { /* NOTE directory servers do not currently fetch directories. * Hope this doesn't bite us later. */ Loading Loading @@ -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; } Loading Loading @@ -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. */ Loading
src/or/or.h +5 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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[]); Loading Loading @@ -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); Loading
src/or/routers.c +186 −3 Original line number Diff line number Diff line Loading @@ -13,6 +13,9 @@ */ #include "or.h" #ifdef HAVE_UNAME #include <sys/utsname.h> #endif /****************************************************************************/ Loading @@ -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; /****************************************************************************/ Loading @@ -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); /****************************************************************************/ Loading Loading @@ -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) Loading Loading @@ -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 Loading