
commit 091551f78899de8cc2e5b1d656df27e31e383a14 Author: Karsten Loesing <karsten.loesing@gmx.net> Date: Mon Feb 11 17:38:21 2013 +0100 Check that authorities run recommended versions. Implements #7725. --- .gitignore | 2 + src/org/torproject/doctor/Checker.java | 51 ++++++++++++++++++++++- src/org/torproject/doctor/StatusFileReport.java | 7 +++- src/org/torproject/doctor/Warning.java | 5 ++- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 14a8cb2..db27b77 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.classpath +.project classes/ lib/ out/ diff --git a/src/org/torproject/doctor/Checker.java b/src/org/torproject/doctor/Checker.java index 2fbdcaf..3adc678 100644 --- a/src/org/torproject/doctor/Checker.java +++ b/src/org/torproject/doctor/Checker.java @@ -2,7 +2,6 @@ * See LICENSE for licensing information */ package org.torproject.doctor; -import java.io.*; import java.text.*; import java.util.*; import org.torproject.descriptor.*; @@ -45,6 +44,7 @@ public class Checker { this.checkBandwidthScanners(); this.checkMissingAuthorities(); this.checkAuthorityRelayIdentityKeys(); + this.checkAuthorityVersions(); } } else { this.warnings.put(Warning.NoConsensusKnown, new TreeSet<String>()); @@ -364,7 +364,6 @@ public class Checker { private void warnAboutExpiringCertificates(Warning warningType, SortedMap<String, String> expiringCertificates) { SortedSet<String> details = new TreeSet<String>(); - StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> e : expiringCertificates.entrySet()) { String dir = e.getKey(); @@ -472,5 +471,53 @@ public class Checker { unexpectedFingerprints); } } + + private void checkAuthorityVersions() { + if (downloadedConsensus.getRecommendedServerVersions() == null) { + return; + } + Set<String> recommendedVersions = new HashSet<String>(); + for (String version : + downloadedConsensus.getRecommendedServerVersions()) { + recommendedVersions.add(version.split("-", 2)[0]); + } + SortedMap<String, String> authorities = new TreeMap<String, String>(); + authorities.put("f2044413dac2e02e3d6bcf4735a19bca1de97281", + "gabelmoo"); + authorities.put("847b1f850344d7876491a54892f904934e4eb85d", "tor26"); + authorities.put("f397038adc51336135e7b80bd99ca3844360292b", + "turtles"); + authorities.put("bd6a829255cb08e66fbe7d3748363586e46b3810", + "maatuska"); + authorities.put("7be683e65d48141321c5ed92f075c55364ac7123", + "dannenberg"); + authorities.put("0ad3fa884d18f89eea2d89c019379e0e7fd94417", "urras"); + authorities.put("9695dfc35ffeb861329b9f1ab04c46397020ce31", "moria1"); + authorities.put("7ea6ead6fd83083c538f44038bbfa077587dd755", "dizum"); + authorities.put("cf6d0aafb385be71b8e111fc5cff4b47923733bc", + "Faravahar"); + authorities.put("4a0ccd2ddc7995083d73f5d667100c8a5831f16d", "Tonga"); + SortedSet<String> unrecommendedVersions = new TreeSet<String>(); + for (Map.Entry<String, String> e : authorities.entrySet()) { + String fingerprint = e.getKey().toUpperCase(); + String nickname = e.getValue(); + if (this.downloadedConsensus.getStatusEntries().containsKey( + fingerprint)) { + String authorityVersion = this.downloadedConsensus.getStatusEntry( + fingerprint).getVersion(); + if (authorityVersion.startsWith("Tor ")) { + authorityVersion = authorityVersion.substring("Tor ".length()); + } + if (!recommendedVersions.contains( + authorityVersion.split("-", 2)[0])) { + unrecommendedVersions.add(nickname + "=" + authorityVersion); + } + } + } + if (!unrecommendedVersions.isEmpty()) { + this.warnings.put(Warning.UnrecommendedVersions, + unrecommendedVersions); + } + } } diff --git a/src/org/torproject/doctor/StatusFileReport.java b/src/org/torproject/doctor/StatusFileReport.java index 7ea29bb..1e23639 100644 --- a/src/org/torproject/doctor/StatusFileReport.java +++ b/src/org/torproject/doctor/StatusFileReport.java @@ -42,7 +42,6 @@ public class StatusFileReport { /* Read when we last emitted a warning to rate-limit some of them. */ private File lastWarnedFile = new File("out/state/last-warned"); private void readLastWarned() { - long now = System.currentTimeMillis(); try { if (this.lastWarnedFile.exists()) { BufferedReader br = new BufferedReader(new FileReader( @@ -60,6 +59,7 @@ public class StatusFileReport { String message = line.substring(line.indexOf(": ") + 2); lastWarned.put(message, warnedMillis); } + br.close(); } } catch (IOException e) { System.err.println("Could not read file '" @@ -174,6 +174,11 @@ public class StatusFileReport { + "different relay identity keys than expected: " + detailsString, 150L * 60L * 1000L); break; + case UnrecommendedVersions: + warningStrings.put("WARNING: The following authorities are " + + "running unrecommended Tor versions: " + + detailsString, 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 2fe87f0..fc7de0e 100644 --- a/src/org/torproject/doctor/Warning.java +++ b/src/org/torproject/doctor/Warning.java @@ -70,6 +70,9 @@ public enum Warning { /* One or more relays running on the IP addresses and dir ports of the * authorities are using a different relay identity key than * expected. */ - UnexpectedFingerprints + UnexpectedFingerprints, + + /* One or more authorities are running an unrecommended Tor version. */ + UnrecommendedVersions }