|
@@ -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. */
|