|
@@ -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) {
|