[tor-commits] [doctor/master] Check votes and signatures in downloaded consensuses.

karsten at torproject.org karsten at torproject.org
Fri Dec 9 14:24:35 UTC 2011


commit 4581684aa786d9966df190388b18e2b24a734ce1
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Fri Dec 9 15:22:08 2011 +0100

    Check votes and signatures in downloaded consensuses.
    
    Implements the rest of #4250.
---
 src/org/torproject/doctor/Checker.java          |   49 +++++++++++++++++++++++
 src/org/torproject/doctor/Parser.java           |   18 ++++++--
 src/org/torproject/doctor/Status.java           |   20 +++++++++
 src/org/torproject/doctor/StatusFileReport.java |   12 ++++++
 src/org/torproject/doctor/Warning.java          |   11 +++++-
 5 files changed, 104 insertions(+), 6 deletions(-)

diff --git a/src/org/torproject/doctor/Checker.java b/src/org/torproject/doctor/Checker.java
index a0f55c2..4d6493f 100755
--- a/src/org/torproject/doctor/Checker.java
+++ b/src/org/torproject/doctor/Checker.java
@@ -35,6 +35,8 @@ public class Checker {
     this.findMostRecentConsensus();
     this.checkMissingConsensuses();
     this.checkAllConsensusesFresh();
+    this.checkContainedVotes();
+    this.checkConsensusSignatures();
     if (this.downloadedConsensus != null) {
       if (this.isConsensusFresh(this.downloadedConsensus)) {
         this.checkConsensusMethods();
@@ -102,6 +104,53 @@ public class Checker {
     }
   }
 
+  /* Check if all downloaded consensuses contain the same set of votes. */
+  private void checkContainedVotes() {
+    Set<String> allVotes = new HashSet<String>();
+    for (Status consensus : downloadedConsensuses.values()) {
+      allVotes.addAll(consensus.getContainedVotes());
+    }
+    SortedSet<String> missingVotes = new TreeSet<String>();
+    for (Map.Entry<String, Status> e : downloadedConsensuses.entrySet()) {
+      String nickname = e.getKey();
+      Status downloadedConsensus = e.getValue();
+      if (!downloadedConsensus.getContainedVotes().containsAll(
+          allVotes)) {
+        missingVotes.add(nickname);
+      }
+    }
+    if (!missingVotes.isEmpty()) {
+      StringBuilder sb = new StringBuilder();
+      for (String nickname : missingVotes) {
+        sb.append(", " + nickname);
+      }
+      this.warnings.put(Warning.ConsensusMissingVotes,
+          sb.toString().substring(2));
+    }
+  }
+
+  /* Check if all downloaded consensuses contain signatures from all other
+   * authorities. */
+  private void checkConsensusSignatures() {
+    SortedSet<String> missingSignatures = new TreeSet<String>();
+    for (Map.Entry<String, Status> e : downloadedConsensuses.entrySet()) {
+      String nickname = e.getKey();
+      Status downloadedConsensus = e.getValue();
+      if (!downloadedConsensus.getContainedSignatures().containsAll(
+          downloadedConsensus.getContainedVotes())) {
+        missingSignatures.add(nickname);
+      }
+    }
+    if (!missingSignatures.isEmpty()) {
+      StringBuilder sb = new StringBuilder();
+      for (String nickname : missingSignatures) {
+        sb.append(", " + nickname);
+      }
+      this.warnings.put(Warning.ConsensusMissingSignatures,
+          sb.toString().substring(2));
+    }
+  }
+
   /* Check if the most recent consensus is older than 1 hour. */
   private boolean isConsensusFresh(Status consensus) {
     return (consensus.getValidAfterMillis() >=
diff --git a/src/org/torproject/doctor/Parser.java b/src/org/torproject/doctor/Parser.java
index 9a91033..d318f29 100755
--- a/src/org/torproject/doctor/Parser.java
+++ b/src/org/torproject/doctor/Parser.java
@@ -108,9 +108,15 @@ public class Parser {
               status.addConsensusParam(paramName, paramValue);
             }
           }
-        } else if (line.startsWith("dir-source ") && !isConsensus) {
-          status.setNickname(line.split(" ")[1]);
-          status.setFingerprint(line.split(" ")[2]);
+        } else if (line.startsWith("dir-source ")) {
+          String nickname = line.split(" ")[1];
+          String fingerprint = line.split(" ")[2];
+          if (isConsensus) {
+            status.addContainedVote(fingerprint);
+          } else {
+            status.setNickname(line.split(" ")[1]);
+            status.setFingerprint(line.split(" ")[2]);
+          }
         } else if (line.startsWith("dir-key-expires ")) {
           try {
             status.setDirKeyExpiresMillis(dateTimeFormat.parse(
@@ -140,8 +146,6 @@ public class Parser {
           }
           if (line.startsWith("r ")) {
             rLine = line;
-          } else {
-            break;
           }
         } else if (line.startsWith("s ") || line.equals("s")) {
           sLine = line;
@@ -156,6 +160,10 @@ public class Parser {
         } else if (line.startsWith("w ") && !isConsensus &&
               line.contains(" Measured")) {
           bandwidthWeights++;
+        } else if (line.startsWith("directory-signature ") &&
+            isConsensus) {
+          String fingerprint = line.split(" ")[1];
+          status.addContainedSignature(fingerprint);
         }
       }
       br.close();
diff --git a/src/org/torproject/doctor/Status.java b/src/org/torproject/doctor/Status.java
index 0573ae2..df41e47 100755
--- a/src/org/torproject/doctor/Status.java
+++ b/src/org/torproject/doctor/Status.java
@@ -136,6 +136,26 @@ public class Status implements Comparable<Status> {
     return this.knownFlags;
   }
 
+  /* Fingerprints of directory authorities of contained votes (only
+   * relevant for consensuses). */
+  private SortedSet<String> containedVotes = new TreeSet<String>();
+  public void addContainedVote(String fingerprint) {
+    this.containedVotes.add(fingerprint);
+  }
+  public SortedSet<String> getContainedVotes() {
+    return this.containedVotes;
+  }
+
+  /* Fingerprints of directory authorities of contained signatures (only
+   * relevant for consensuses). */
+  private SortedSet<String> containedSignatures = new TreeSet<String>();
+  public void addContainedSignature(String fingerprint) {
+    this.containedSignatures.add(fingerprint);
+  }
+  public SortedSet<String> getContainedSignatures() {
+    return this.containedSignatures;
+  }
+
   /* Number of status entries with the Running flag. */
   private int runningRelays;
   public void setRunningRelays(int runningRelays) {
diff --git a/src/org/torproject/doctor/StatusFileReport.java b/src/org/torproject/doctor/StatusFileReport.java
index 1fe3b87..a43a27e 100755
--- a/src/org/torproject/doctor/StatusFileReport.java
+++ b/src/org/torproject/doctor/StatusFileReport.java
@@ -138,6 +138,18 @@ public class StatusFileReport implements Report {
               + "not reporting bandwidth scanner results: " + details,
               150L * 60L * 1000L);
           break;
+        case ConsensusMissingVotes:
+          warningStrings.put("The consensuses downloaded from the "
+              + "following authorities are missing votes that are "
+              + "contained in consensuses downloaded from other "
+              + "authorities: " + details, 150L * 60L * 1000L);
+          break;
+        case ConsensusMissingSignatures:
+          warningStrings.put("The consensuses downloaded from the "
+              + "following authorities are missing signatures from "
+              + "other, previously voting authorities: " + details,
+              150L * 60L * 1000L);
+          break;
       }
     }
     long now = System.currentTimeMillis();
diff --git a/src/org/torproject/doctor/Warning.java b/src/org/torproject/doctor/Warning.java
index d592926..0cb8cd8 100755
--- a/src/org/torproject/doctor/Warning.java
+++ b/src/org/torproject/doctor/Warning.java
@@ -41,6 +41,15 @@ public enum Warning {
 
   /* One or more directory authorities are not reporting bandwidth scanner
    * results. */
-  BandwidthScannerResultsMissing
+  BandwidthScannerResultsMissing,
+
+  /* The consensuses downloaded from one or more authorities are missing
+   * votes that are contained in consensuses downloaded from other
+   * authorities. */
+  ConsensusMissingVotes,
+
+  /* The consensuses downloaded from one or more authorities are missing
+   * signatures from other, previously voting authorities. */
+  ConsensusMissingSignatures
 }
 



More information about the tor-commits mailing list