[or-cvs] Get directories working.

Nick Mathewson nickm at seul.org
Thu May 8 21:35:14 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv10997/src/or

Modified Files:
	directory.c main.c routers.c 
Log Message:
Get directories working.

Or at least, directories get generated, signed, download, and checked, with
nobody seeming to crash.

In config/*, added 'signing-key' blocks to dirservers and routers.or, so
that everyone will know about the directories' signing keys.

In or/directory.c, refrained from using a dirserver's signing key when
no such key is known; added more debugging output.

In or/main.c, added debugging output and fixed a few logic errors.

In or/routers.c, added debugging output and prevented a segfault on
routers_resolve_directory.  The interleaving of arrays and lists on
routerinfo_t is still messy, but at least it seems to work again.



Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- directory.c	8 May 2003 03:36:53 -0000	1.11
+++ directory.c	8 May 2003 21:35:11 -0000	1.12
@@ -43,7 +43,12 @@
   conn->address = strdup(router->address);
   conn->receiver_bucket = -1; /* edge connections don't do receiver buckets */
   conn->bandwidth = -1;
-  conn->pkey = crypto_pk_dup_key(router->signing_pkey);
+  if (router->signing_pkey)
+    conn->pkey = crypto_pk_dup_key(router->signing_pkey);
+  else {
+    log(LOG_ERR, "No signing key known for directory %s; signature won\'t be checked", conn->address);
+    conn->pkey = NULL;
+  }
 
   s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
   if(s < 0) { 
@@ -148,7 +153,11 @@
     }
     if(router_get_dir_from_string(the_directory, conn->pkey) < 0) {
       log(LOG_DEBUG,"connection_dir_process_inbuf(): ...but parsing failed. Ignoring.");
+    } else {
+      log(LOG_DEBUG,"connection_dir_process_inbuf(): and got a %s directory; updated routers.", 
+          conn->pkey ? "authenticated" : "unauthenticated");
     }
+    
     if(options.ORPort) { /* connect to them all */
       router_retry_connections();
     }

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- main.c	8 May 2003 03:36:53 -0000	1.58
+++ main.c	8 May 2003 21:35:11 -0000	1.59
@@ -654,7 +654,7 @@
 
   routers = (routerinfo_t**) malloc(sizeof(routerinfo_t*) * (nfds+1));
   if (!routers) {
-    /* freak out XXX */
+    log(LOG_ERR, "build_directory(): couldn\'t allocate space for routerinfo");
     return -1;
   }
   if (my_routerinfo) {
@@ -669,7 +669,8 @@
       continue; /* we only want to list ones that successfully handshaked */
     router = router_get_by_addr_port(conn->addr,conn->port);
     if(!router) {
-      log(LOG_ERR,"dump_directory_to_string(): couldn't find router %d:%d!",conn->addr,conn->port);
+      log(LOG_ERR,"dump_directory_to_string(): couldn\'t find router %d:%d!",
+          conn->addr,conn->port);
       continue;
     }
     routers[n++] = router;
@@ -684,9 +685,11 @@
                                 crypto_pk_env_t *private_key)
 {
   directory_t dir;
-  if (!build_directory(&dir))
+  if (build_directory(&dir)) {
+    log(LOG_ERR,"dump_signed_directory_to_string(): build_directory failed.");
     return -1;
-  return dump_signed_directory_to_string_impl(s, maxlen, &dir, private_key);  
+  }
+  return dump_signed_directory_to_string_impl(s, maxlen, &dir, private_key);
 }
 
 int
@@ -703,21 +706,22 @@
           "client-software x y z\n" /* XXX make this real */
           "server-software a b c\n\n" /* XXX make this real */
           , maxlen);
+  
+  i = strlen(s);
+  cp = s+i;
   for (i = 0; i < dir->n_routers; ++i) {
     router = dir->routers[i];
-    written = dump_router_to_string(s, maxlen, router);
+    written = dump_router_to_string(cp, maxlen-i, router);
 
     if(written < 0) { 
-      log(LOG_ERR,"dump_directory_to_string(): tried to exceed string length.");
-      s[maxlen-1] = 0; /* make sure it's null terminated */
+      log(LOG_ERR,"dump_signed_directory_to_string(): tried to exceed string length.");
+      cp[maxlen-1] = 0; /* make sure it's null terminated */
       return -1;
     }
-    
-    maxlen -= written;
-    s += written;
+    i += written;
+    cp += written;
   }
 
-
   /* These multiple strlen calls are inefficient, but dwarfed by the RSA
      signature.
   */
@@ -726,22 +730,33 @@
   i = strlen(s);
   cp = s + i;
   
-  if (crypto_SHA_digest(s, i, digest))
+  if (crypto_SHA_digest(s, i, digest)) {
+    log(LOG_ERR,"dump_signed_directory_to_string(): couldn\'t compute digest");
     return -1;
-  if (crypto_pk_private_sign(get_signing_privatekey(), digest, 20, signature) < 0)
+  }
+  if (crypto_pk_private_sign(private_key, digest, 20, signature) < 0) {
+    log(LOG_ERR,"dump_signed_directory_to_string(): couldn\'t sign digest");
     return -1;
+  }
   
   strncpy(cp, 
           "-----BEGIN SIGNATURE-----\n", maxlen-i);
           
   i = strlen(s);
   cp = s+i;
-  if (base64_encode(cp, maxlen-i, signature, 128) < 0)
+  if (base64_encode(cp, maxlen-i, signature, 128) < 0) {
+    log(LOG_ERR,"dump_signed_directory_to_string(): couldn\'t base64-encode signature %d/%d");
     return -1;
+  }
 
   i = strlen(s);
   cp = s+i;
-  strcat(cp, "-----END SIGNATURE-----\n");
+  strncat(cp, "-----END SIGNATURE-----\n", maxlen-i);
+  i = strlen(s);
+  if (i == maxlen) {
+    log(LOG_ERR,"dump_signed_directory_to_string(): tried to exceed string length.");
+    return -1;
+  }
 
   return 0;
 }

Index: routers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routers.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- routers.c	8 May 2003 12:32:30 -0000	1.27
+++ routers.c	8 May 2003 21:35:11 -0000	1.28
@@ -518,15 +518,21 @@
 
 int router_get_list_from_string(char *s) 
 {
-  int i;
-  i = router_get_list_from_string_impl(s, &directory);
-  router_resolve_directory(directory);
-  return i;
+  if (router_get_list_from_string_impl(s, &directory)) {
+    log(LOG_ERR, "Error parsing router file");
+    return -1;
+  }
+  if (router_resolve_directory(directory)) {
+    log(LOG_ERR, "Error resolving directory");
+    return -1;
+  }
+  return 0;
 }
 
 int router_get_list_from_string_impl(char *s, directory_t **dest) {
   directory_token_t tok;
   if (router_get_next_token(&s, &tok)) {
+    log(LOG_ERR, "Error reading routers: %s", tok.val.error); 
     return -1;
   }
   return router_get_list_from_string_tok(&s, dest, &tok);
@@ -536,25 +542,41 @@
 {
   char *start, *end;
   start = strstr(s, "signed-directory");
-  if (!start) return -1;
+  if (!start) {
+    log(LOG_ERR,"router_get_dir_hash(): couldn't find \"signed-directory\"");
+    return -1;
+  }
   end = strstr(start, "directory-signature");
-  if (!end) return -1;
+  if (!end) {
+    log(LOG_ERR,"router_get_dir_hash(): couldn't find \"directory-signature\"");
+    return -1;
+  }
   end = strchr(end, '\n');
-  if (!end) return -1;
+  if (!end) {
+    log(LOG_ERR,"router_get_dir_hash(): couldn't find EOL");
+    return -1;
+  }
   ++end;
   
-  if (crypto_SHA_digest(start, end-start, digest))
+  if (crypto_SHA_digest(start, end-start, digest)) {
+    log(LOG_ERR,"router_get_dir_hash(): couldn't compute digest");
     return -1;
+  }
 
   return 0;
 }
 
 int router_get_dir_from_string(char *s, crypto_pk_env_t *pkey)
 {
-  int i;
-  i = router_get_dir_from_string_impl(s, &directory, pkey);
-  router_resolve_directory(directory);
-  return i;
+  if (router_get_dir_from_string_impl(s, &directory, pkey)) {
+    log(LOG_ERR, "router_get_dir_from_string: Couldn\'t parse directory.");
+    return -1;
+  }
+  if (router_resolve_directory(directory)) {
+    log(LOG_ERR, "Error resolving directory");
+    return -1;
+  }
+  return 0;
 }
 
 int router_get_dir_from_string_impl(char *s, directory_t **dest,
@@ -578,8 +600,10 @@
       return -1;                                                        \
     } } while(0)
   
-  if (router_get_dir_hash(s, digest))
+  if (router_get_dir_hash(s, digest)) {
+    log(LOG_ERR, "Unable to compute digest of directory");
     return -1;
+  }
 
   NEXT_TOK();
   TOK_IS(K_SIGNED_DIRECTORY, "signed-directory");
@@ -591,8 +615,10 @@
   TOK_IS(K_SERVER_SOFTWARE, "server-software");
   
   NEXT_TOK();
-  if (router_get_list_from_string_tok(&s, &new_dir, &tok))
+  if (router_get_list_from_string_tok(&s, &new_dir, &tok)) {
+    log(LOG_ERR, "Error reading routers from directory");
     return -1;
+  }
   
   TOK_IS(K_DIRECTORY_SIGNATURE, "directory-signature");
   NEXT_TOK();
@@ -637,6 +663,10 @@
 
   while (tok->tp == K_ROUTER) {
     router = router_get_entry_from_string_tok(s, tok);
+    if (!router) {
+      log(LOG_ERR, "Error reading router");
+      return -1;
+    }
     switch(router_is_me(router->addr, router->or_port)) {
       case 0: /* it's not me */
         router->next = routerlist;
@@ -694,7 +724,8 @@
   max = dir->n_routers;
   for (i = 0; i < max; ++i) {
     if (router_resolve(dir->routers[i])) {
-      /* ARMA: Is this the right way to remove a router from the directory? */
+      log(LOG_INFO, "Couldn\'t resolve router %s; removing",
+          dir->routers[i]->address);
       dir->routers[i]->next = NULL;
       routerlist_free(dir->routers[i]);
       dir->routers[i] = dir->routers[--max];
@@ -702,6 +733,11 @@
       --dir->n_routers;
     }
   }
+  /* This is quick-and-dirty, but it keeps stuff consistant. */
+  for (i = 0; i < dir->n_routers-1; ++i) {
+    dir->routers[i]->next = dir->routers[i+1];
+  }
+  dir->routers[dir->n_routers-1]->next=NULL;
   
   return 0;
 }



More information about the tor-commits mailing list