[or-cvs] When we connect and finish TLS negotiation with address:por...

Nick Mathewson nickm at seul.org
Wed Apr 6 21:09:50 UTC 2005


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

Modified Files:
	connection_or.c dirserv.c or.h 
Log Message:
When we connect and finish TLS negotiation with address:port, it is obvious that any other key or nickname we might know about (as an authdirserver) does not actually exist at address:port.

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_or.c,v
retrieving revision 1.167
retrieving revision 1.168
diff -u -d -r1.167 -r1.168
--- connection_or.c	6 Apr 2005 18:55:14 -0000	1.167
+++ connection_or.c	6 Apr 2005 21:09:47 -0000	1.168
@@ -498,7 +498,13 @@
 #endif
 
   if (connection_or_nonopen_was_started_here(conn)) {
-    /* I initiated this connection. */
+    if (authdir_mode(options)) {
+      /* We initiated this connection to address:port.  Drop all routers
+       * with the same address:port and a different key or nickname.
+       */
+      dirserv_orconn_tls_done(conn->address, conn->port,
+                              digest_rcvd, nickname);
+    }
     if (conn->nickname[0] == '$') {
       /* I was aiming for a particular digest. Did I get it? */
       char d[HEX_DIGEST_LEN+1];
@@ -508,7 +514,6 @@
                "Identity key not as expected for router at %s:%d: wanted %s but got %s",
                conn->address, conn->port, conn->nickname, d);
         control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
-        // XXX if we're an authdir_mode, forget about nickname's descriptor
         return -1;
       }
     } else if (strcasecmp(conn->nickname, nickname)) {
@@ -517,14 +522,8 @@
              "Other side (%s:%d) is '%s', but we tried to connect to '%s'",
              conn->address, conn->port, nickname, conn->nickname);
       control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED);
-      // XXX if we're an authdir_mode, forget about nickname's descriptor
       return -1;
     }
-    if (authdir_mode(options)) {
-      /* I got exactly the guy I wanted. Now go through and blow away
-       * descriptors for exactly this Address:ORPort that aren't this guy. */
-      //XXX
-    }
   } else {
     if ((c=connection_get_by_identity_digest(digest_rcvd, CONN_TYPE_OR))) {
       log_fn(LOG_INFO,"Router '%s' is already connected on fd %d. Dropping fd %d.", nickname, c->s, conn->s);

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.154
retrieving revision 1.155
diff -u -d -r1.154 -r1.155
--- dirserv.c	6 Apr 2005 03:20:06 -0000	1.154
+++ dirserv.c	6 Apr 2005 21:09:47 -0000	1.155
@@ -993,6 +993,53 @@
   return compress ? the_runningrouters_z_len : the_runningrouters_len;
 }
 
+/** Called when a TLS handshake has completed successfully with a
+ * router listening at <b>address</b>:<b>or_port</b>, and has yielded
+ * a certificate with digest <b>digest_rcvd</b> and nickname
+ * <b>nickname_rcvd</b>.  When this happens, it's clear that any other
+ * descriptors for that address/port combination must be unusable:
+ * delete them if they are not verified.
+ */
+void
+dirserv_orconn_tls_done(const char *address,
+                        uint16_t or_port,
+                        const char *digest_rcvd,
+                        const char *nickname_rcvd)
+{
+  int i;
+  tor_assert(address);
+  tor_assert(digest_rcvd);
+  tor_assert(nickname_rcvd);
+
+  if (!descriptor_list)
+    return;
+
+  for (i = 0; i < smartlist_len(descriptor_list); ++i) {
+    routerinfo_t *ri = smartlist_get(descriptor_list, i);
+    int drop = 0;
+    if (ri->is_verified)
+      continue;
+    if (!strcasecmp(address, ri->address) &&
+        or_port == ri->or_port) {
+      /* We have a router at the same address! */
+      if (strcasecmp(ri->nickname, nickname_rcvd)) {
+        log_fn(LOG_WARN, "Dropping descriptor: nickname '%s' does not match nickname '%s' in cert from %s:%d",
+               ri->nickname, nickname_rcvd, address, or_port);
+        drop = 1;
+      } else if (memcmp(ri->identity_digest, digest_rcvd, DIGEST_LEN)) {
+        log_fn(LOG_WARN, "Dropping descriptor: identity key does not match key in cert from %s:%d",
+               address, or_port);
+        drop = 1;
+      }
+      if (drop) {
+        routerinfo_free(ri);
+        smartlist_del(descriptor_list, i--);
+        directory_set_dirty();
+      }
+    }
+  }
+}
+
 void
 dirserv_free_all(void)
 {

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.588
retrieving revision 1.589
diff -u -d -r1.588 -r1.589
--- or.h	6 Apr 2005 15:19:32 -0000	1.588
+++ or.h	6 Apr 2005 21:09:47 -0000	1.589
@@ -1480,6 +1480,10 @@
 size_t dirserv_get_runningrouters(const char **rr, int compress);
 void dirserv_set_cached_directory(const char *directory, time_t when,
                                   int is_running_routers);
+void dirserv_orconn_tls_done(const char *address,
+                             uint16_t or_port,
+                             const char *digest_rcvd,
+                             const char *nickname);
 void dirserv_free_all(void);
 
 /********************************* dns.c ***************************/



More information about the tor-commits mailing list