diff options
author | Nick Mathewson <nickm@torproject.org> | 2003-05-07 02:13:23 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2003-05-07 02:13:23 +0000 |
commit | d0ff485e1b36e07d1edecdc6c454d636dea99061 (patch) | |
tree | 58542df3aabc3430143d1b22320885df116c137d /src/or | |
parent | 3416a106273b419eda949febe70aa23b15af4ac5 (diff) | |
download | tor-d0ff485e1b36e07d1edecdc6c454d636dea99061.tar.gz tor-d0ff485e1b36e07d1edecdc6c454d636dea99061.zip |
More work on directories. Signed directories not yet tested. No support for checking sigs yet
svn:r268
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/main.c | 103 | ||||
-rw-r--r-- | src/or/or.h | 3 | ||||
-rw-r--r-- | src/or/routers.c | 44 | ||||
-rw-r--r-- | src/or/test.c | 24 |
4 files changed, 146 insertions, 28 deletions
diff --git a/src/or/main.c b/src/or/main.c index 234030e1ef..d645d4731c 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -555,7 +555,8 @@ void dumpstats(void) { /* dump stats to stdout */ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router) { char *pkey; - int pkeylen; + char *signing_pkey, *signing_pkey_tag; + int pkeylen, signing_pkeylen; int written; int result=0; struct exit_policy_t *tmpe; @@ -565,16 +566,30 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router) { return 0; } - result = snprintf(s, maxlen, "router %s %d %d %d %d %d\n%s", + signing_pkey = ""; + signing_pkey_tag = ""; + if (router->signing_pkey) { + if(crypto_pk_write_public_key_to_string(router->signing_pkey, + &signing_pkey,&signing_pkeylen)<0) { + log(LOG_ERR,"dump_router_to_string(): write signing_pkey to string failed!"); + return 0; + } + signing_pkey_tag = "signing-key\n"; + } + + result = snprintf(s, maxlen, "router %s %d %d %d %d %d\n%s%s%s", router->address, router->or_port, router->op_port, router->ap_port, router->dir_port, router->bandwidth, - pkey); + pkey, + signing_pkey_tag, signing_pkey); free(pkey); + if (*signing_pkey) + free(signing_pkey); if(result < 0 || result > maxlen) { /* apparently different glibcs do different things on snprintf error.. so check both */ @@ -607,21 +622,23 @@ int dump_router_to_string(char *s, int maxlen, routerinfo_t *router) { } -void dump_directory_to_string(char *s, int maxlen) { - int i; +void dump_directory_to_string(char *s, int maxlen) +{ + directory_t dir; + routerinfo_t **routers = NULL;; connection_t *conn; routerinfo_t *router; - int written; + int i, n = 0; - /* first write my own info */ - if(my_routerinfo) { - written = dump_router_to_string(s, maxlen, my_routerinfo); - maxlen -= written; - s += written; + routers = (routerinfo_t**) malloc(sizeof(routerinfo_t*) * (nfds+1)); + if (!routers) { + /* freak out XXX */ + return; } - - /* now write info for other routers */ - for(i=0;i<nfds;i++) { + if (my_routerinfo) { + routers[n++] = my_routerinfo; + } + for(i = 0; i<nfds; ++i) { conn = connection_array[i]; if(conn->type != CONN_TYPE_OR) @@ -633,7 +650,64 @@ void dump_directory_to_string(char *s, int maxlen) { log(LOG_ERR,"dump_directory_to_string(): couldn't find router %d:%d!",conn->addr,conn->port); continue; } + routers[n++] = router; + } + dir.routers = routers; + dir.n_routers = n; + + dump_directory_to_string_impl(s, maxlen, &dir); +} + +int +dump_signed_directory_to_string_impl(char *s, int maxlen, directory_t *dir, + crypto_pk_env_t *private_key) +{ + char *cp; + char digest[20]; + char signature[128]; + int i; + strncpy(s, + "signed-directory\n" + "client-software x y z\n" /* XXX make this real */ + "server-software a b c\n\n" /* XXX make this real */ + , maxlen); + /* These multiple strlen calls are inefficient, but dwarfed by the RSA + signature. + */ + i = strlen(s); + + dump_directory_to_string_impl(s+i, maxlen-i, dir); + i = strlen(s); + cp = s + i; + + if (crypto_SHA_digest(s, i, digest)) + return -1; + if (crypto_pk_private_sign(private_key, digest, 20, signature)) + return -1; + + + strncpy(cp, + "directory-signature\n-----BEGIN SIGNATURE-----\n", maxlen-i); + + i = strlen(s); + cp = s+i; + if (base64_encode(cp, maxlen-i, signature, 128) < 0) + return -1; + i = strlen(s); + cp = s+i; + strcat(cp, "-----END SIGNATURE-----\n"); + + return 0; +} + +void dump_directory_to_string_impl(char *s, int maxlen, directory_t *directory) { + int i; + routerinfo_t *router; + int written; + + for (i = 0; i < directory->n_routers; ++i) { + router = directory->routers[i]; written = dump_router_to_string(s, maxlen, router); if(written < 0) { @@ -645,7 +719,6 @@ void dump_directory_to_string(char *s, int maxlen) { maxlen -= written; s += written; } - } void daemonize(void) { diff --git a/src/or/or.h b/src/or/or.h index 65db958954..fd289c3b77 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -320,6 +320,7 @@ typedef struct { uint16_t dir_port; crypto_pk_env_t *pkey; /* public RSA key */ + crypto_pk_env_t *signing_pkey; /* May be null */ /* link info */ uint32_t bandwidth; @@ -737,6 +738,7 @@ int do_main_loop(void); void dumpstats(void); void dump_directory_to_string(char *s, int maxlen); +void dump_directory_to_string_impl(char *s, int maxlen, directory_t *directory); int main(int argc, char *argv[]); @@ -793,6 +795,7 @@ int router_get_list_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 routerlist_free(routerinfo_t *list); #endif diff --git a/src/or/routers.c b/src/or/routers.c index 49a66cbeb2..f0b5205454 100644 --- a/src/or/routers.c +++ b/src/or/routers.c @@ -17,7 +17,7 @@ extern routerinfo_t *my_routerinfo; /* from main.c */ /****************************************************************************/ /* static function prototypes */ -static void routerlist_free(routerinfo_t *list); +void routerlist_free(routerinfo_t *list); static routerinfo_t **make_rarray(routerinfo_t* list, int *len); static char *eat_whitespace(char *s); static char *find_whitespace(char *s); @@ -124,7 +124,7 @@ int router_is_me(uint32_t addr, uint16_t port) } /* delete a list of routers from memory */ -static void routerlist_free(routerinfo_t *list) +void routerlist_free(routerinfo_t *list) { routerinfo_t *tmp = NULL; struct exit_policy_t *e = NULL, *etmp = NULL; @@ -402,7 +402,6 @@ routerinfo_t *router_get_entry_from_string(char **s) { log(LOG_ERR,"router_get_entry_from_string(): Entry does not start with \"router\""); return NULL; } - puts("X"); router = malloc(sizeof(routerinfo_t)); if (!router) { @@ -477,7 +476,7 @@ routerinfo_t *router_get_entry_from_string(char **s) { goto router_read_failed; } - /* now advance *s so it's at the end of this router entry */ + /* now advance *s so it's at the end of this public key */ next = strchr(next, '\n'); assert(next); /* can't fail, we just checked it was here */ *next = 0; @@ -494,10 +493,40 @@ routerinfo_t *router_get_entry_from_string(char **s) { goto router_read_failed; } -// test_write_pkey(router->pkey); - *s = next+1; - while(**s != '\n') { + *s = eat_whitespace(*s); + if (!strncasecmp(*s, "signing-key", 11)) { + /* We have a signing key */ + *s = strchr(*s, '\n'); + *s = eat_whitespace(*s); + next = strstr(*s,OR_PUBLICKEY_END_TAG); + router->signing_pkey = crypto_new_pk_env(CRYPTO_PK_RSA); + if (!next || !router->signing_pkey) { + log(LOG_ERR,"router_get_entry_from_string(): Couldn't find signing_pk in string"); + goto router_read_failed; + } + next = strchr(next, '\n'); + assert(next); + *next = 0; + if ((crypto_pk_read_public_key_from_string(router->signing_pkey, *s, + strlen(*s)))<0) { + log(LOG_ERR,"router_get_entry_from_string(): Couldn't read signing pk from string"); + goto router_read_failed; + } + + log(LOG_DEBUG,"router_get_entry_from_string(): Signing key size = %u.", crypto_pk_keysize(router->signing_pkey)); + + if (crypto_pk_keysize(router->signing_pkey) != 128) { /* keys MUST be 1024 bits in size */ + log(LOG_ERR,"Signing key for router %s:%u is 1024 bits. All keys must be exactly 1024 bits long.", + router->address,router->or_port); + goto router_read_failed; + } + *s = next+1; + } + + // test_write_pkey(router->pkey); + + while(**s && **s != '\n') { /* pull in a line of exit policy */ next = strchr(*s, '\n'); if(!next) @@ -509,7 +538,6 @@ routerinfo_t *router_get_entry_from_string(char **s) { return router; - router_read_failed: if(router->address) free(router->address); diff --git a/src/or/test.c b/src/or/test.c index ae1a94b65d..c288f2b718 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -506,8 +506,8 @@ void test_dir_format() { - char buf[2048], buf2[512]; - char *pk1_str, *pk2_str, *cp; + char buf[2048], buf2[2048]; + char *pk1_str = NULL, *pk2_str = NULL, *cp; int pk1_str_len, pk2_str_len; routerinfo_t r1, r2; crypto_pk_env_t *pk1 = NULL, *pk2 = NULL; @@ -528,6 +528,7 @@ test_dir_format() r1.ap_port = 9002; r1.dir_port = 9003; r1.pkey = pk1; + r1.signing_pkey = NULL; r1.bandwidth = 1000; r1.exit_policy = NULL; r1.next = &r2; @@ -548,6 +549,7 @@ test_dir_format() r2.ap_port = 0; r2.dir_port = 0; r2.pkey = pk2; + r2.signing_pkey = pk1; r2.bandwidth = 3000; r2.exit_policy = &ex1; r2.next = NULL; @@ -574,10 +576,13 @@ test_dir_format() test_eq(rp1->dir_port, r1.dir_port); test_eq(rp1->bandwidth, r1.bandwidth); test_assert(crypto_pk_cmp_keys(rp1->pkey, pk1) == 0); + test_assert(rp1->signing_pkey == NULL); test_assert(rp1->exit_policy == NULL); strcpy(buf2, "router tor.tor.tor 9005 0 0 0 3000\n"); strcat(buf2, pk2_str); + strcat(buf2, "signing-key\n"); + strcat(buf2, pk1_str); strcat(buf2, "accept *:80\nreject 18.*:24\n\n"); test_assert(dump_router_to_string(buf, 2048, &r2)>0); test_streq(buf, buf2); @@ -592,6 +597,7 @@ test_dir_format() test_eq(rp2->dir_port, r2.dir_port); test_eq(rp2->bandwidth, r2.bandwidth); test_assert(crypto_pk_cmp_keys(rp2->pkey, pk2) == 0); + test_assert(crypto_pk_cmp_keys(rp2->signing_pkey, pk1) == 0); test_eq(rp2->exit_policy->policy_type, EXIT_POLICY_ACCEPT); test_streq(rp2->exit_policy->string, "accept *:80"); test_streq(rp2->exit_policy->address, "*"); @@ -601,9 +607,17 @@ test_dir_format() test_streq(rp2->exit_policy->next->address, "18.*"); test_streq(rp2->exit_policy->next->port, "24"); test_assert(rp2->exit_policy->next->next == NULL); + + /* Okay, now for the directories. */ - - /* XXXX free everything*/ + + + if (pk1_str) free(pk1_str); + if (pk2_str) free(pk2_str); + if (pk1) crypto_free_pk_env(pk1); + if (pk2) crypto_free_pk_env(pk2); + if (rp1) routerlist_free(rp1); + if (rp2) routerlist_free(rp2); } int @@ -617,7 +631,7 @@ main(int c, char**v) { log(LOG_ERR,NULL); /* make logging quieter */ setup_directory(); -#if 1 +#if 0 puts("========================== Buffers ========================="); test_buffers(); puts("========================== Crypto =========================="); |