[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r20737: {projects} Apply a couple of changes according to atagar's suggestions. (projects/archives/trunk/exonerator)
Author: kloesing
Date: 2009-10-03 18:47:59 -0400 (Sat, 03 Oct 2009)
New Revision: 20737
Modified:
projects/archives/trunk/exonerator/exonerator.py
Log:
Apply a couple of changes according to atagar's suggestions. Thanks!
Modified: projects/archives/trunk/exonerator/exonerator.py
===================================================================
--- projects/archives/trunk/exonerator/exonerator.py 2009-10-03 18:02:37 UTC (rev 20736)
+++ projects/archives/trunk/exonerator/exonerator.py 2009-10-03 22:47:59 UTC (rev 20737)
@@ -8,231 +8,134 @@
from optparse import OptionParser
from IPy import IP
-# check parameters
-usage = "usage: %prog [options] <IP address in question> " \
+USAGE = "usage: %prog [options] <IP address in question> " \
"<timestamp, in UTC, formatted as YYYY-MM-DD hh:mm:ss> " \
"[<target address>[:<target port>]]"
-parser = OptionParser(usage=usage)
-parser.add_option("-a", "--archive", dest="archive", default="data/",
- help="descriptor archive directory")
-(options, args) = parser.parse_args()
-if len(args) not in (3, 4):
- parser.error("incorrect number of arguments")
-if not os.path.isdir(options.archive):
- parser.error("descriptor archive directory %s does not exist or is " \
- "not a directory." % os.path.abspath(archiveDirectory))
-archiveDirectory = os.path.dirname(options.archive)
-try:
- relayIP = IP(args[0])
-except ValueError:
- parser.error("invalid IP address in question: '%s'" % args[0])
-timestampStr = "%s %s" % (args[1], args[2])
-os.environ['TZ'] = 'UTC'
-time.tzset()
-try:
- timestamp = time.strptime(timestampStr, "%Y-%m-%d %H:%M:%S")
-except ValueError:
- parser.error("incorrect time format: '%s'" % timestampStr)
-# if a target is given, parse address and possibly port part of it
-target = None
-targetIP = None
-targetPort = None
-if len(args) == 4:
- target = args[3]
- targetParts = target.split(":")
+DELIMITER = "-" * 75
+
+if __name__ == '__main__':
+ # check parameters
+ parser = OptionParser(usage=USAGE)
+ parser.add_option("-a", "--archive", dest="archive", default="data/",
+ help="descriptor archive directory")
+ (options, args) = parser.parse_args()
+ if len(args) not in (3, 4):
+ parser.error("incorrect number of arguments")
+ if not os.path.isdir(options.archive):
+ parser.error("descriptor archive directory %s does not exist or " \
+ "is not a directory." % \
+ os.path.abspath(options.archive))
+ archiveDirectory = os.path.dirname(options.archive)
try:
- targetIP = IP(targetParts[0])
+ relayIP = IP(args[0])
except ValueError:
- parser.error("invalid target IP address in: '%s'" % args[3])
- if len(targetParts) > 2:
- parser.error("invalid target format: '%s'" % args[3])
- if len(targetParts) > 1:
+ parser.error("invalid IP address in question: '%s'" % args[0])
+ timestampStr = "%s %s" % (args[1], args[2])
+ os.environ['TZ'] = 'UTC'
+ time.tzset()
+ try:
+ timestamp = time.strptime(timestampStr, "%Y-%m-%d %H:%M:%S")
+ except ValueError:
+ parser.error("incorrect time format: '%s'" % timestampStr)
+ # if a target is given, parse address and possibly port part of it
+ target = None
+ targetIP = None
+ targetPort = None
+ if len(args) == 4:
+ target = args[3]
+ targetParts = target.split(":")
try:
- targetPortTest = int(targetParts[1])
+ targetIP = IP(targetParts[0])
except ValueError:
- parser.error("invalid target port number in: '%s'" % args[3])
- if targetPortTest not in range(1, 65535):
- parser.error("invalid target port number in: '%s'" % args[3])
- targetPort = targetParts[1]
+ parser.error("invalid target IP address in: '%s'" % args[3])
+ if len(targetParts) > 2:
+ parser.error("invalid target format: '%s'" % args[3])
+ if len(targetParts) > 1:
+ try:
+ targetPortTest = int(targetParts[1])
+ except ValueError:
+ parser.error("invalid target port number in: '%s'" % \
+ args[3])
+ if targetPortTest not in range(1, 65535):
+ parser.error("invalid target port number in: '%s'" % \
+ args[3])
+ targetPort = targetParts[1]
-DELIMITER = "-----------------------------------------------------------" \
- "----------------"
-targetHelpStr = ""
-if target:
- targetHelpStr = " permitting exiting to %s" % target
-print "\nTrying to find out whether %s was running a Tor relay at " \
- "%s%s...\n\n%s\n" % (relayIP, timestampStr, targetHelpStr, DELIMITER)
+ targetHelpStr = ""
+ if target:
+ targetHelpStr = " permitting exiting to %s" % target
+ print "\nTrying to find out whether %s was running a Tor relay at " \
+ "%s%s...\n\n%s\n" % (relayIP, timestampStr, targetHelpStr,
+ DELIMITER)
-# check that we have the required archives
-timestampTooOld = time.gmtime(time.mktime(timestamp) - 300 * 60)
-timestampFrom = time.gmtime(time.mktime(timestamp) - 180 * 60)
-timestampTooNew = time.gmtime(time.mktime(timestamp) + 120 * 60)
-timestampTooOldStr = time.strftime("%Y-%m-%d %H:%M:%S", timestampTooOld)
-timestampFromStr = time.strftime("%Y-%m-%d %H:%M:%S", timestampFrom)
-timestampTooNewStr = time.strftime("%Y-%m-%d %H:%M:%S", timestampTooNew)
-print "\nChecking that relevant archives between %s and %s are " \
- "available..." % (timestampTooOldStr, timestampTooNewStr)
+ # check that we have the required archives
+ timestampTooOld = time.gmtime(time.mktime(timestamp) - 300 * 60)
+ timestampFrom = time.gmtime(time.mktime(timestamp) - 180 * 60)
+ timestampTooNew = time.gmtime(time.mktime(timestamp) + 120 * 60)
+ timestampTooOldStr = time.strftime("%Y-%m-%d %H:%M:%S",
+ timestampTooOld)
+ timestampFromStr = time.strftime("%Y-%m-%d %H:%M:%S", timestampFrom)
+ timestampTooNewStr = time.strftime("%Y-%m-%d %H:%M:%S",
+ timestampTooNew)
+ print "\nChecking that relevant archives between %s and %s are " \
+ "available..." % (timestampTooOldStr, timestampTooNewStr)
-requiredDirs = set()
-requiredDirs.add(time.strftime("consensuses-%Y-%m", timestampTooOld))
-requiredDirs.add(time.strftime("consensuses-%Y-%m", timestampTooNew))
-if target is not None:
- requiredDirs.add(time.strftime("server-descriptors-%Y-%m",
- timestampTooOld))
- requiredDirs.add(time.strftime("server-descriptors-%Y-%m",
- timestampTooNew))
+ requiredDirs = set()
+ requiredDirs.add(time.strftime("consensuses-%Y-%m", timestampTooOld))
+ requiredDirs.add(time.strftime("consensuses-%Y-%m", timestampTooNew))
+ if target:
+ requiredDirs.add(time.strftime("server-descriptors-%Y-%m",
+ timestampTooOld))
+ requiredDirs.add(time.strftime("server-descriptors-%Y-%m",
+ timestampTooNew))
-consensusDirs = list()
-descriptorsDirs = list()
-directoriesLeftToParse = list()
-directoriesLeftToParse.append(archiveDirectory)
+ consensusDirs = list()
+ descriptorsDirs = list()
+ directoriesLeftToParse = list()
+ directoriesLeftToParse.append(archiveDirectory)
-while len(directoriesLeftToParse) > 0:
- directoryOrFile = directoriesLeftToParse.pop()
- basename = os.path.basename(directoryOrFile)
- if basename.startswith("consensuses-"):
- if basename in requiredDirs:
- requiredDirs.remove(basename)
- consensusDirs.append(directoryOrFile)
- elif basename.startswith("server-descriptors-"):
- if basename in requiredDirs:
- requiredDirs.remove(basename)
- descriptorsDirs.append(directoryOrFile)
- else:
- for filename in os.listdir(directoryOrFile):
- entry = "%s/%s" % (directoryOrFile, filename)
- if os.path.isdir(entry):
- directoriesLeftToParse.append(entry)
+ while directoriesLeftToParse:
+ directoryOrFile = directoriesLeftToParse.pop()
+ basename = os.path.basename(directoryOrFile)
+ if basename.startswith("consensuses-"):
+ if basename in requiredDirs:
+ requiredDirs.remove(basename)
+ consensusDirs.append(directoryOrFile)
+ elif basename.startswith("server-descriptors-"):
+ if basename in requiredDirs:
+ requiredDirs.remove(basename)
+ descriptorsDirs.append(directoryOrFile)
+ else:
+ for filename in os.listdir(directoryOrFile):
+ entry = "%s/%s" % (directoryOrFile, filename)
+ if os.path.isdir(entry):
+ directoriesLeftToParse.append(entry)
-consensusDirs.sort()
-for file in consensusDirs:
- print " %s" % file
-descriptorsDirs.sort()
-for file in descriptorsDirs:
- print " %s" % file
+ consensusDirs.sort()
+ for consensusDir in consensusDirs:
+ print " %s" % consensusDir
+ descriptorsDirs.sort()
+ for descriptorsDir in descriptorsDirs:
+ print " %s" % descriptorsDir
-if len(requiredDirs) > 0:
- print "\nWe are missing consensuses and/or server descriptors. " \
- "Please download these archives and extract them to your data " \
- "directory. Be sure NOT to rename the extracted directories " \
- "or the contained files."
- missingFiles = list()
- for file in sorted(requiredDirs):
- print " %s.tar.bz2" % file
- sys.exit()
+ if requiredDirs:
+ print "\nWe are missing consensuses and/or server descriptors. " \
+ "Please download these archives and extract them to your " \
+ "data directory. Be sure NOT to rename the extracted " \
+ "directories or the contained files."
+ missingFiles = list()
+ for requiredDir in sorted(requiredDirs):
+ print " %s.tar.bz2" % requiredDir
+ sys.exit()
-# look for consensus files
-print "\nLooking for relevant consensuses between %s and %s..." % \
- (timestampFromStr, timestampStr)
-tooOldConsensuses = set()
-relevantConsensuses = set()
-tooNewConsensuses = set()
-directoriesLeftToParse = list()
-for file in consensusDirs:
- directoriesLeftToParse.append(file)
-while len(directoriesLeftToParse) > 0:
- directoryOrFile = directoriesLeftToParse.pop()
- if os.path.isdir(directoryOrFile):
- for filename in os.listdir(directoryOrFile):
- entry = "%s/%s" % (directoryOrFile, filename)
- directoriesLeftToParse.append(entry)
- else:
- basename = os.path.basename(directoryOrFile)
- if (basename.endswith("consensus")):
- consensusTime = time.strptime(basename[0:19],
- "%Y-%m-%d-%H:%M:%S")
- if consensusTime >= timestampTooOld and \
- consensusTime < timestampFrom:
- tooOldConsensuses.add(directoryOrFile)
- elif consensusTime >= timestampFrom and \
- consensusTime <= timestamp:
- relevantConsensuses.add(directoryOrFile)
- elif consensusTime > timestamp and \
- consensusTime <= timestampTooNew:
- tooNewConsensuses.add(directoryOrFile)
-allConsensuses = set()
-for file in tooOldConsensuses:
- allConsensuses.add(file)
-for file in relevantConsensuses:
- allConsensuses.add(file)
-for file in tooNewConsensuses:
- allConsensuses.add(file)
-if len(allConsensuses) == 0:
- print " None found!\n\n%s\n\nResult is INDECISIVE!\n\nWe cannot " \
- "make any statement about IP address %s being a relay at %s " \
- "or not! We did not find any relevant consensuses preceding " \
- "the given time. This either means that you did not download " \
- "and extract the consensus archives preceding the hours " \
- "before the given time, or (in rare cases) that the directory " \
- "archives are missing the hours before the timestamp. Please " \
- "check that your directory archives contain consensus files " \
- "of the interval 5:00 hours before and 2:00 hours after the " \
- "time you are looking for.\n" % \
- (DELIMITER, relayIP, timestampStr)
- sys.exit()
-for file in sorted(relevantConsensuses):
- print " %s" % file
-
-# parse consensuses to find descriptors belonging to the IP address
-print "\nLooking for descriptor identifiers referenced in \"r \" lines " \
- "in these consensuses containing IP address %s..." % relayIP
-positiveConsensusesNoTarget = set()
-addressesInSameNetwork = set()
-relevantDescriptors = dict()
-for consensus in allConsensuses:
- if consensus in relevantConsensuses:
- print " %s" % consensus
- file = open(consensus, "r")
- line = file.readline()
- while line:
- if line.startswith("r "):
- address = IP(line.split(" ")[6])
- if address == relayIP:
- hexDesc = binascii.b2a_hex(binascii.a2b_base64(
- line.split(" ")[3] + "=="))
- if hexDesc not in relevantDescriptors.keys():
- relevantDescriptors[hexDesc] = set()
- relevantDescriptors[hexDesc].add(consensus)
- positiveConsensusesNoTarget.add(consensus)
- if consensus in relevantConsensuses:
- print " \"%s\" references descriptor %s" % \
- (line.rstrip(), hexDesc)
- elif relayIP.overlaps(IP("%s/24" % address, make_net=True)):
- addressesInSameNetwork.add(address)
- line = file.readline()
- file.close()
-if len(relevantDescriptors) == 0:
- print " None found!\n\n%s\n\nResult is NEGATIVE with moderate " \
- "certainty!\n\nWe did not find IP address %s in any of the " \
- "consensuses that were published between %s and %s.\n\nA " \
- "possible reason for false negatives is that the relay is " \
- "using a different IP address when generating a descriptor " \
- "than for exiting to the Internet. We hope to provide better " \
- "checks for this case in the future." % \
- (DELIMITER, relayIP, timestampTooOldStr, timestampTooNewStr)
- if len(addressesInSameNetwork) > 0:
- print "\nThe following other IP addresses of Tor relays were " \
- "found in the mentioned consensus files that are in the " \
- "same /24 network and that could be related to IP address " \
- "%s:" % relayIP
- for addr in addressesInSameNetwork:
- print " %s" % addr
- print ""
- sys.exit()
-
-# parse router descriptors to check exit policies
-positiveConsensuses = set()
-missingDescriptors = set()
-if target is not None:
- print "\nChecking if referenced descriptors permit exiting to " \
- "%s..." % target
- descriptors = relevantDescriptors.keys()
- for desc in descriptors:
- missingDescriptors.add(desc)
- directoriesLeftToParse = list()
- for descriptorsDir in descriptorsDirs:
- directoriesLeftToParse.append(descriptorsDir)
- while len (directoriesLeftToParse) > 0:
+ # look for consensus files
+ print "\nLooking for relevant consensuses between %s and %s..." % \
+ (timestampFromStr, timestampStr)
+ tooOldConsensuses = set()
+ relevantConsensuses = set()
+ tooNewConsensuses = set()
+ directoriesLeftToParse = list(consensusDirs)
+ while directoriesLeftToParse:
directoryOrFile = directoriesLeftToParse.pop()
if os.path.isdir(directoryOrFile):
for filename in os.listdir(directoryOrFile):
@@ -240,127 +143,233 @@
directoriesLeftToParse.append(entry)
else:
basename = os.path.basename(directoryOrFile)
- for descriptor in descriptors:
- if basename == descriptor:
- missingDescriptors.remove(descriptor)
- file = open(directoryOrFile, "r")
- line = file.readline()
- while line:
- if line.startswith("reject ") or \
- line.startswith("accept "):
- ruleAccept = line.split()[0] == "accept"
- ruleAddress = line.split()[1].split(":")[0]
- if ruleAddress != "*" and not \
- IP(ruleAddress).overlaps(targetIP):
- # IP address does not match
- line = file.readline()
- continue
- rulePort = line.split()[1].split(":")[1]
- if targetPort is None and not ruleAccept and \
- rulePort != "*":
- # with no port given, we only consider
- # reject :* rules as matching
- line = file.readline()
- continue
- if targetPort and rulePort != "*" and \
- targetPort != rulePort:
- # ports do not match
- line = file.readline()
- continue
- relevantMatch = False
- for f in relevantDescriptors.get(descriptor):
- if f in relevantConsensuses:
- relevantMatch = True
- if relevantMatch:
+ if (basename.endswith("consensus")):
+ consensusTime = time.strptime(basename[0:19],
+ "%Y-%m-%d-%H:%M:%S")
+ if consensusTime >= timestampTooOld and \
+ consensusTime < timestampFrom:
+ tooOldConsensuses.add(directoryOrFile)
+ elif consensusTime >= timestampFrom and \
+ consensusTime <= timestamp:
+ relevantConsensuses.add(directoryOrFile)
+ elif consensusTime > timestamp and \
+ consensusTime <= timestampTooNew:
+ tooNewConsensuses.add(directoryOrFile)
+ allConsensuses = set()
+ for consensus in tooOldConsensuses:
+ allConsensuses.add(consensus)
+ for consensus in relevantConsensuses:
+ allConsensuses.add(consensus)
+ for consensus in tooNewConsensuses:
+ allConsensuses.add(consensus)
+ if not allConsensuses:
+ print " None found!\n\n%s\n\nResult is INDECISIVE!\n\nWe " \
+ "cannot make any statement about IP address %s being a " \
+ "relay at %s or not! We did not find any relevant " \
+ "consensuses preceding the given time. This either means " \
+ "that you did not download and extract the consensus " \
+ "archives preceding the hours before the given time, or " \
+ "(in rare cases) that the directory archives are missing " \
+ "the hours before the timestamp. Please check that your " \
+ "directory archives contain consensus files of the " \
+ "interval 5:00 hours before and 2:00 hours after the time " \
+ "you are looking for.\n" % (DELIMITER, relayIP, timestampStr)
+ sys.exit()
+ for consensus in sorted(relevantConsensuses):
+ print " %s" % consensus
+
+ # parse consensuses to find descriptors belonging to the IP address
+ print "\nLooking for descriptor identifiers referenced in \"r \" " \
+ "lines in these consensuses containing IP address %s..." % \
+ relayIP
+ positiveConsensusesNoTarget = set()
+ addressesInSameNetwork = set()
+ relevantDescriptors = dict()
+ for consensus in allConsensuses:
+ if consensus in relevantConsensuses:
+ print " %s" % consensus
+ consensusFile = open(consensus, "r")
+ line = consensusFile.readline()
+ while line:
+ if line.startswith("r "):
+ address = IP(line.split(" ")[6])
+ if address == relayIP:
+ hexDesc = binascii.b2a_hex(binascii.a2b_base64(
+ line.split(" ")[3] + "=="))
+ if hexDesc not in relevantDescriptors.keys():
+ relevantDescriptors[hexDesc] = set()
+ relevantDescriptors[hexDesc].add(consensus)
+ positiveConsensusesNoTarget.add(consensus)
+ if consensus in relevantConsensuses:
+ print " \"%s\" references descriptor %s" % \
+ (line.rstrip(), hexDesc)
+ elif relayIP.overlaps(IP("%s/24" % address,
+ make_net=True)):
+ addressesInSameNetwork.add(address)
+ line = consensusFile.readline()
+ consensusFile.close()
+ if not relevantDescriptors:
+ print " None found!\n\n%s\n\nResult is NEGATIVE with moderate " \
+ "certainty!\n\nWe did not find IP address %s in any of " \
+ "the consensuses that were published between %s and " \
+ "%s.\n\nA possible reason for false negatives is that the " \
+ "relay is using a different IP address when generating a " \
+ "descriptor than for exiting to the Internet. We hope to " \
+ "provide better checks for this case in the future." % \
+ (DELIMITER, relayIP, timestampTooOldStr, timestampTooNewStr)
+ if addressesInSameNetwork:
+ print "\nThe following other IP addresses of Tor relays " \
+ "were found in the mentioned consensus files that are " \
+ "in the same /24 network and that could be related to " \
+ "IP address %s:" % relayIP
+ for addr in addressesInSameNetwork:
+ print " %s" % addr
+ print ""
+ sys.exit()
+
+ # parse router descriptors to check exit policies
+ positiveConsensuses = set()
+ missingDescriptors = set()
+ if target:
+ print "\nChecking if referenced descriptors permit exiting to " \
+ "%s..." % target
+ descriptors = relevantDescriptors.keys()
+ for desc in descriptors:
+ missingDescriptors.add(desc)
+ directoriesLeftToParse = list(descriptorsDirs)
+ while directoriesLeftToParse:
+ directoryOrFile = directoriesLeftToParse.pop()
+ if os.path.isdir(directoryOrFile):
+ for filename in os.listdir(directoryOrFile):
+ entry = "%s/%s" % (directoryOrFile, filename)
+ directoriesLeftToParse.append(entry)
+ else:
+ basename = os.path.basename(directoryOrFile)
+ for descriptor in descriptors:
+ if basename == descriptor:
+ missingDescriptors.remove(descriptor)
+ descriptorFile = open(directoryOrFile, "r")
+ line = descriptorFile.readline()
+ while line:
+ if line.startswith("reject ") or \
+ line.startswith("accept "):
+ ruleAccept = line.split()[0] == "accept"
+ ruleAddress = line.split()[1].split(":")[0]
+ if ruleAddress != "*" and not \
+ IP(ruleAddress).overlaps(targetIP):
+ # IP address does not match
+ line = descriptorFile.readline()
+ continue
+ rulePort = line.split()[1].split(":")[1]
+ if not targetPort and not ruleAccept and \
+ rulePort != "*":
+ # with no port given, we only consider
+ # reject :* rules as matching
+ line = descriptorFile.readline()
+ continue
+ if targetPort and rulePort != "*" and \
+ targetPort != rulePort:
+ # ports do not match
+ line = descriptorFile.readline()
+ continue
+ relevantMatch = False
+ for f in relevantDescriptors.get(
+ descriptor):
+ if f in relevantConsensuses:
+ relevantMatch = True
+ if relevantMatch:
+ if ruleAccept:
+ print " %s permits exiting to " \
+ "%s according to rule " \
+ "\"%s\"" % (directoryOrFile,
+ target, line.rstrip())
+ else:
+ print " %s does not permit " \
+ "exiting to %s according " \
+ "to rule \"%s\"" % \
+ (directoryOrFile,
+ target, line.rstrip())
if ruleAccept:
- print " %s permits exiting to %s " \
- "according to rule \"%s\"" % \
- (directoryOrFile, target,
- line.rstrip())
- else:
- print " %s does not permit exiting " \
- "to %s according to rule " \
- "\"%s\"" % (directoryOrFile,
- target, line.rstrip())
- if ruleAccept:
- for consensus in \
- relevantDescriptors.get(descriptor):
- positiveConsensuses.add(consensus)
- break;
- line = file.readline()
- file.close()
+ for consensus in \
+ relevantDescriptors.get(
+ descriptor):
+ positiveConsensuses.add(consensus)
+ break
+ line = descriptorFile.readline()
+ descriptorFile.close()
-# print out result
-matches = None
-if target:
- matches = positiveConsensuses
-else:
- matches = positiveConsensusesNoTarget
-lastConsensus = sorted(relevantConsensuses)[len(relevantConsensuses) - 1]
-if lastConsensus in matches:
- print "\n%s\n\nResult is POSITIVE with high certainty!\n\nWe found " \
- "one or more relays on IP address %s%s in the most recent " \
- "consensus preceding %s that clients were likely to know.\n" % \
- (DELIMITER, relayIP, targetHelpStr, timestampStr)
- sys.exit()
-resultIndecisive = target and len(missingDescriptors) > 0
-if resultIndecisive:
- print "\n%s\n\nResult is INDECISIVE!\n\nAt least one referenced " \
- "descriptor could not be found. This is a rare case, but one " \
- "that (apparently) happens. We cannot make any good statement " \
- "about exit relays without these descriptors. The following " \
- "descriptors are missing:" % DELIMITER
- for desc in missingDescriptors:
- print " %s" % desc
-inOtherRelevantConsensus = False
-inTooOldConsensuses = False
-inTooNewConsensuses = False
-for f in matches:
- if f in relevantConsensuses:
- inOtherRelevantConsensus = True
- elif f in tooOldConsensuses:
- inTooOldConsensuses = True
- elif f in tooNewConsensuses:
- inTooNewConsensuses = True
-if inOtherRelevantConsensus:
- if not resultIndecisive:
- print "\n%s\n\nResult is POSITIVE with moderate certainty!" % \
+ # print out result
+ matches = None
+ if target:
+ matches = positiveConsensuses
+ else:
+ matches = positiveConsensusesNoTarget
+ lastConsensus = sorted(relevantConsensuses)[len(relevantConsensuses)-1]
+ if lastConsensus in matches:
+ print "\n%s\n\nResult is POSITIVE with high certainty!\n\nWe " \
+ "found one or more relays on IP address %s%s in the most " \
+ "recent consensus preceding %s that clients were likely " \
+ "to know.\n" % (DELIMITER, relayIP, targetHelpStr,
+ timestampStr)
+ sys.exit()
+ resultIndecisive = target and len(missingDescriptors) > 0
+ if resultIndecisive:
+ print "\n%s\n\nResult is INDECISIVE!\n\nAt least one " \
+ "referenced descriptor could not be found. This is a rare " \
+ "case, but one that (apparently) happens. We cannot make " \
+ "any good statement about exit relays without these " \
+ "descriptors. The following descriptors are missing:" % \
DELIMITER
- print "\nWe found one or more relays on IP address %s%s, but not in " \
- "the consensus immediately preceding %s. A possible reason " \
- "for the relay being missing in the last consensus preceding " \
- "the given time might be that some of the directory " \
- "authorities had difficulties connecting to the relay. " \
- "However, clients might still have used the relay." % (relayIP,
- targetHelpStr, timestampStr)
-else:
- if not resultIndecisive:
- print "\n%s\n\nResult is NEGATIVE with high certainty!" % \
- DELIMITER
- print "\nWe did not find any relay on IP address %s%s in the " \
- "consensuses 3:00 hours preceding %s." % (relayIP, targetHelpStr,
- timestampStr)
- if inTooOldConsensuses or inTooNewConsensuses:
- if inTooOldConsensuses and not inTooNewConsensuses:
- print "\nNote that we found a matching relay in consensuses " \
- "that were published between 5:00 and 3:00 hours " \
- "before %s." % timestampStr
- elif not inTooOldConsensuses and inTooNewConsensuses:
- print "\nNote that we found a matching relay in consensuses " \
- "that were published up to 2:00 hours after %s." % \
- timestampStr
- else:
- print "\nNote that we found a matching relay in consensuses " \
- "that were published between 5:00 and 3:00 hours " \
- "before and in consensuses that were published up to " \
- "2:00 hours after %s." % timestampStr
- print "Make sure that the timestamp you provided is in the " \
- "correct timezone: UTC (or GMT)."
-if target:
- if len(positiveConsensuses) == 0 and \
- len(positiveConsensusesNoTarget) > 0:
- print "\nNote that although the found relay(s) did not permit " \
- "exiting to %s there have been one or more relays running " \
- "at the given time." % target
-print ""
-
+ for desc in missingDescriptors:
+ print " %s" % desc
+ inOtherRelevantConsensus = False
+ inTooOldConsensuses = False
+ inTooNewConsensuses = False
+ for f in matches:
+ if f in relevantConsensuses:
+ inOtherRelevantConsensus = True
+ elif f in tooOldConsensuses:
+ inTooOldConsensuses = True
+ elif f in tooNewConsensuses:
+ inTooNewConsensuses = True
+ if inOtherRelevantConsensus:
+ if not resultIndecisive:
+ print "\n%s\n\nResult is POSITIVE with moderate certainty!" % \
+ DELIMITER
+ print "\nWe found one or more relays on IP address %s%s, but " \
+ "not in the consensus immediately preceding %s. A " \
+ "possible reason for the relay being missing in the last " \
+ "consensus preceding the given time might be that some of " \
+ "the directory authorities had difficulties connecting to " \
+ "the relay. However, clients might still have used the " \
+ "relay." % (relayIP, targetHelpStr, timestampStr)
+ else:
+ if not resultIndecisive:
+ print "\n%s\n\nResult is NEGATIVE with high certainty!" % \
+ DELIMITER
+ print "\nWe did not find any relay on IP address %s%s in the " \
+ "consensuses 3:00 hours preceding %s." % (relayIP,
+ targetHelpStr, timestampStr)
+ if inTooOldConsensuses or inTooNewConsensuses:
+ if inTooOldConsensuses and not inTooNewConsensuses:
+ print "\nNote that we found a matching relay in " \
+ "consensuses that were published between 5:00 and " \
+ "3:00 hours before %s." % timestampStr
+ elif not inTooOldConsensuses and inTooNewConsensuses:
+ print "\nNote that we found a matching relay in " \
+ "consensuses that were published up to 2:00 hours " \
+ "after %s." % timestampStr
+ else:
+ print "\nNote that we found a matching relay in " \
+ "consensuses that were published between 5:00 and " \
+ "3:00 hours before and in consensuses that were " \
+ "published up to 2:00 hours after %s." % timestampStr
+ print "Make sure that the timestamp you provided is in the " \
+ "correct timezone: UTC (or GMT)."
+ if target:
+ if not positiveConsensuses and positiveConsensusesNoTarget:
+ print "\nNote that although the found relay(s) did not " \
+ "permit exiting to %s there have been one or more " \
+ "relays running at the given time." % target
+ print ""
+