[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r12071: More fixes for bad behavior when downloading extrainfos: do (in tor/trunk: . src/or)



Author: nickm
Date: 2007-10-21 00:41:00 -0400 (Sun, 21 Oct 2007)
New Revision: 12071

Modified:
   tor/trunk/
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerlist.c
Log:
 r15995@catbus:  nickm | 2007-10-21 00:40:46 -0400
 More fixes for bad behavior when downloading extrainfos: do not download an ei if we lack the key to verify it, and do not download it if we already got it and found (weirdly) that it didn't match the corresponding server descriptor.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r15995] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-10-21 04:15:28 UTC (rev 12070)
+++ tor/trunk/src/or/or.h	2007-10-21 04:41:00 UTC (rev 12071)
@@ -1109,6 +1109,9 @@
   unsigned int do_not_cache : 1;
   /* If true, this item is meant to represent an extrainfo. */
   unsigned int is_extrainfo : 1;
+  /* If true, we got an extrainfo for this item, and the digest was right,
+   * but it was incompatible. */
+  unsigned int extrainfo_is_bogus : 1;
 } signed_descriptor_t;
 
 /** Information about another onion router in the network. */

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-10-21 04:15:28 UTC (rev 12070)
+++ tor/trunk/src/or/routerlist.c	2007-10-21 04:41:00 UTC (rev 12071)
@@ -3817,6 +3817,10 @@
         sd = &((routerinfo_t*)smartlist_get(lst, i))->cache_info;
       if (sd->is_extrainfo)
         continue; /* This should never happen. */
+      if (old_routers && !router_get_by_digest(sd->identity_digest))
+        continue; /* Couldn't check the signature if we got it. */
+      if (sd->extrainfo_is_bogus)
+        continue;
       d = sd->extra_info_digest;
       if (tor_digest_is_zero(d)) {
         ++n_no_ei;
@@ -4042,13 +4046,14 @@
  * <b>msg</b> is present, set *<b>msg</b> to a description of the
  * incompatibility (if any)
  *
- * DOCDOC sd.
+ * DOCDOC sd.  DOCDOC extrainfo_is_bogus.
  **/
 int
 routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
                                        signed_descriptor_t *sd,
                                        const char **msg)
 {
+  int digest_matches, r=1;
   tor_assert(ri);
   tor_assert(ei);
   if (!sd)
@@ -4059,13 +4064,15 @@
     return 1;
   }
 
-  /* The nickname must match exactly to have been generated at the same time
+  digest_matches = !memcmp(ei->cache_info.signed_descriptor_digest,
+                           sd->extra_info_digest, DIGEST_LEN);
+
+  /* The identity must match exactly to have been generated at the same time
    * by the same router. */
-  if (strcmp(ri->nickname, ei->nickname) ||
-      memcmp(ri->cache_info.identity_digest, ei->cache_info.identity_digest,
+  if (memcmp(ri->cache_info.identity_digest, ei->cache_info.identity_digest,
              DIGEST_LEN)) {
     if (msg) *msg = "Extrainfo nickname or identity did not match routerinfo";
-    return 1; /* different servers */
+    goto err; /* different servers */
   }
 
   if (ei->pending_sig) {
@@ -4077,7 +4084,7 @@
       ei->bad_sig = 1;
       tor_free(ei->pending_sig);
       if (msg) *msg = "Extrainfo signature bad, or signed with wrong key";
-      return 1; /* Bad signature, or no match. */
+      goto err; /* Bad signature, or no match. */
     }
 
     tor_free(ei->pending_sig);
@@ -4085,19 +4092,28 @@
 
   if (ei->cache_info.published_on < sd->published_on) {
     if (msg) *msg = "Extrainfo published time did not match routerdesc";
-    return 1;
+    goto err;
   } else if (ei->cache_info.published_on > sd->published_on) {
     if (msg) *msg = "Extrainfo published time did not match routerdesc";
-    return -1;
+    r = -1;
+    goto err;
   }
 
-  if (memcmp(ei->cache_info.signed_descriptor_digest,
-             sd->extra_info_digest, DIGEST_LEN)) {
+  if (!digest_matches) {
     if (msg) *msg = "Extrainfo digest did not match value from routerdesc";
-    return 1; /* Digest doesn't match declared value. */
+    goto err; /* Digest doesn't match declared value. */
   }
 
   return 0;
+ err:
+  if (digest_matches) {
+    /* This signature was okay, and the digest was right: This is indeed the
+     * corresponding extrainfo.  But insanely, it doesn't match the routerinfo
+     * that lists it.  Don't try to fetch this one again. */
+    sd->extrainfo_is_bogus = 1;
+  }
+
+  return r;
 }
 
 /** Assert that the internal representation of <b>rl</b> is