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

[or-cvs] r19232: {torflow} Turns out humans don't remember and recognize hex strings ve (torflow/trunk/NetworkScanners)



Author: mikeperry
Date: 2009-04-06 23:44:43 -0400 (Mon, 06 Apr 2009)
New Revision: 19232

Modified:
   torflow/trunk/NetworkScanners/libsoat.py
   torflow/trunk/NetworkScanners/snakeinspector.py
   torflow/trunk/NetworkScanners/soat.py
Log:

Turns out humans don't remember and recognize hex strings
very well. Give them a hint with the node name in the
results.



Modified: torflow/trunk/NetworkScanners/libsoat.py
===================================================================
--- torflow/trunk/NetworkScanners/libsoat.py	2009-04-07 03:11:55 UTC (rev 19231)
+++ torflow/trunk/NetworkScanners/libsoat.py	2009-04-07 03:44:43 UTC (rev 19232)
@@ -87,8 +87,9 @@
 
 class TestResult(object):
   ''' Parent class for all test result classes '''
-  def __init__(self, exit_node, site, status, reason=None):
+  def __init__(self, exit_node, exit_name, site, status, reason=None):
     self.exit_node = exit_node
+    self.exit_name = exit_name
     self.site = site
     self.timestamp = time.time()
     self.status = status
@@ -99,13 +100,16 @@
     self.verbose=0
     self.from_rescan = False
     self.filename=None
-    self._pickle_revision = 1    
+    self._pickle_revision = 2
 
   def depickle_upgrade(self):
     if not "_pickle_revision" in self.__dict__: # upgrade to v0
       self._pickle_revision = 0
     if self._pickle_revision < 1:
       self._pickle_revision = 1
+    if self._pickle_revision < 2:
+      self._pickle_revision = 2
+      self.exit_name = "NameNotStored!"
 
   def _rebase(self, filename, new_data_root):
     if not filename: return filename
@@ -137,7 +141,7 @@
   def __str__(self):
     ret = self.__class__.__name__+" for "+self.site+"\n"
     ret += " Time: "+time.ctime(self.timestamp)+"\n"
-    ret += " Exit: "+self.exit_node+"\n"
+    ret += " Exit: "+self.exit_node+" ("+self.exit_name+")\n"
     ret += " "+str(RESULT_STRINGS[self.status])
     if self.reason:
       ret += " Reason: "+self.reason
@@ -152,9 +156,9 @@
 
 class SSLTestResult(TestResult):
   ''' Represents the result of an openssl test '''
-  def __init__(self, exit_node, ssl_site, ssl_file, status, reason=None, 
-               exit_ip=None, exit_cert_pem=None):
-    super(SSLTestResult, self).__init__(exit_node, ssl_site, status, reason)
+  def __init__(self, exit_node, exit_name, ssl_site, ssl_file, status, 
+               reason=None, exit_ip=None, exit_cert_pem=None):
+    super(SSLTestResult, self).__init__(exit_node, exit_name, ssl_site, status, reason)
     self.ssl_file = ssl_file
     self.exit_cert = exit_cert_pem # Meh, not that much space
     self.exit_ip = exit_ip
@@ -228,10 +232,10 @@
 
 class HttpTestResult(TestResult):
   ''' Represents the result of a http test '''
-  def __init__(self, exit_node, website, status, reason=None, 
+  def __init__(self, exit_node, exit_name, website, status, reason=None, 
                sha1sum=None, exit_sha1sum=None, content=None, 
                content_exit=None, content_old=None, sha1sum_old=None):
-    super(HttpTestResult, self).__init__(exit_node, website, status, reason)
+    super(HttpTestResult, self).__init__(exit_node, exit_name, website, status, reason)
     self.proto = "http"
     self.sha1sum = sha1sum
     self.sha1sum_old = sha1sum_old
@@ -270,9 +274,9 @@
     return ret
 
 class CookieTestResult(TestResult):
-  def __init__(self, exit_node, status, reason, plain_cookies, 
+  def __init__(self, exit_node, exit_name, status, reason, plain_cookies, 
                tor_cookies):
-    super(CookieTestResult, self).__init__(exit_node, "cookies", status)
+    super(CookieTestResult, self).__init__(exit_node, exit_name, "cookies", status)
     self.proto = "http"
     self.reason = reason
     self.tor_cookies = tor_cookies
@@ -286,10 +290,10 @@
 
 class JsTestResult(TestResult):
   ''' Represents the result of a JS test '''
-  def __init__(self, exit_node, website, status, reason=None, 
+  def __init__(self, exit_node, exit_name, website, status, reason=None, 
                content=None, content_exit=None, content_old=None,
                jsdiffer=None):
-    super(JsTestResult, self).__init__(exit_node, website, status, reason)
+    super(JsTestResult, self).__init__(exit_node, exit_name, website, status, reason)
     self.proto = "http"
     self.content = content
     self.content_exit = content_exit
@@ -350,10 +354,10 @@
 
 class HtmlTestResult(TestResult):
   ''' Represents the result of a http test '''
-  def __init__(self, exit_node, website, status, reason=None, 
+  def __init__(self, exit_node, exit_name, website, status, reason=None, 
                content=None, content_exit=None, content_old=None, 
                soupdiffer=None, jsdiffer=None):
-    super(HtmlTestResult, self).__init__(exit_node, website, status, reason)
+    super(HtmlTestResult, self).__init__(exit_node, exit_name, website, status, reason)
     self.proto = "http"
     self.content = content
     self.content_exit = content_exit
@@ -465,38 +469,38 @@
 
 class SSHTestResult(TestResult):
   ''' Represents the result of an ssh test '''
-  def __init__(self, exit_node, ssh_site, status):
-    super(SSHTestResult, self).__init__(exit_node, ssh_site, status)
+  def __init__(self, exit_node, exit_name, ssh_site, status):
+    super(SSHTestResult, self).__init__(exit_node, exit_name, ssh_site, status)
     self.proto = "ssh"
 
 class DNSTestResult(TestResult):
   ''' Represents the result of a dns test '''
-  def __init__(self, exit_node, dns_site, status):
-    super(DNSTestResult, self).__init__(exit_node, dns_site, status)
+  def __init__(self, exit_node, exit_name, dns_site, status):
+    super(DNSTestResult, self).__init__(exit_node, exit_name, dns_site, status)
     self.proto = "dns"
 
 class DNSRebindTestResult(TestResult):
   ''' Represents the result of a dns rebind test '''
-  def __init__(self, exit_node, dns_rebind_site, status):
-    super(DNSRebindTestResult, self).__init__(exit_node, dns_rebind_site, status)
+  def __init__(self, exit_node, exit_name, dns_rebind_site, status):
+    super(DNSRebindTestResult, self).__init__(exit_node, exit_name, dns_rebind_site, status)
     self.proto = "dns"
 
 class SMTPTestResult(TestResult):
   ''' Represents the result of an smtp test '''
-  def __init__(self, exit_node, smtp_site, status):
-    super(SMTPTestResult, self).__init__(exit_node, smtp_site, status)
+  def __init__(self, exit_node, exit_name, smtp_site, status):
+    super(SMTPTestResult, self).__init__(exit_node, exit_name, smtp_site, status)
     self.proto = "smtp"
 
 class IMAPTestResult(TestResult):
   ''' Represents the result of an imap test '''
-  def __init__(self, exit_node, imap_site, status):
-    super(IMAPTestResult, self).__init__(exit_node, imap_site, status)
+  def __init__(self, exit_node, exit_name, imap_site, status):
+    super(IMAPTestResult, self).__init__(exit_node, exit_name, imap_site, status)
     self.proto = "imap"
 
 class POPTestResult(TestResult):
   ''' Represents the result of a pop test '''
-  def __init__(self, exit_node, pop_site, status):
-    super(POPTestResult, self).__init__(exit_node, pop_site, status)
+  def __init__(self, exit_node, exit_name, pop_site, status):
+    super(POPTestResult, self).__init__(exit_node, exit_name, pop_site, status)
     self.proto = "pop"
 
 class DataHandler:

Modified: torflow/trunk/NetworkScanners/snakeinspector.py
===================================================================
--- torflow/trunk/NetworkScanners/snakeinspector.py	2009-04-07 03:11:55 UTC (rev 19231)
+++ torflow/trunk/NetworkScanners/snakeinspector.py	2009-04-07 03:44:43 UTC (rev 19232)
@@ -27,8 +27,8 @@
   print "  --dir <datadir>"
   print "  --file <.result file>"
   print "  --exit <idhex>"
-  print "  --reason <soat failure reason>"
-  print "  --noreason <soat failure reason>"
+  print "  --reason <soat failure reason>    # may be repeated"
+  print "  --noreason <soat failure reason>  # may be repeated"
   print "  --proto <protocol>"
   print "  --resultfilter <TestResult class name>"
   print "  --statuscode <'Failure' or 'Inconclusive'>"
@@ -44,6 +44,7 @@
   except getopt.GetoptError,err:
     print str(err)
     usage(argv)
+  # FIXME: make all these repeatable
   use_dir="./data/"
   use_file=None
   node=None
@@ -90,7 +91,7 @@
   if use_file:
     results = [dh.getResult(use_file)]
   elif node:
-    results = dh.filterByNode(dh.getAll(), node)
+    results = dh.filterByNode(dh.getAll(), "$"+node)
   else:
     results = dh.getAll()
 

Modified: torflow/trunk/NetworkScanners/soat.py
===================================================================
--- torflow/trunk/NetworkScanners/soat.py	2009-04-07 03:11:55 UTC (rev 19231)
+++ torflow/trunk/NetworkScanners/soat.py	2009-04-07 03:44:43 UTC (rev 19232)
@@ -566,9 +566,9 @@
     if tor_cookies != plain_cookies:
       exit_node = metacon.get_exit_node()
       plog("ERROR", "Cookie mismatch at "+exit_node+":\nTor Cookies:"+tor_cookies+"\nPlain Cookies:\n"+plain_cookies)
-      result = CookieTestResult(exit_node, TEST_FAILURE, 
-                            FAILURE_COOKIEMISMATCH, plain_cookies, 
-                            tor_cookies)
+      result = CookieTestResult(exit_node,self.node_map[exit_node[1:]].nickname,
+                          TEST_FAILURE, FAILURE_COOKIEMISMATCH, plain_cookies, 
+                          tor_cookies)
       if self.rescan_nodes: result.from_rescan = True
       self.results.append(result)
       datahandler.saveResult(result)
@@ -751,8 +751,8 @@
     exit_node = metacon.get_exit_node()
     if exit_node == 0 or exit_node == '0' or not exit_node:
       plog('NOTICE', 'We had no exit node to test, skipping to the next test.')
-      result = HttpTestResult(exit_node, address, TEST_INCONCLUSIVE,
-                              INCONCLUSIVE_NOEXIT)
+      result = HttpTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_INCONCLUSIVE, INCONCLUSIVE_NOEXIT)
       if self.rescan_nodes: result.from_rescan = True
       self.results.append(result)
       datahandler.saveResult(result)
@@ -789,8 +789,9 @@
           fail_reason = FAILURE_CONNREFUSED
         elif pcode == -6: # timeout
           fail_reason = FAILURE_TIMEOUT
-          result = HttpTestResult(exit_node, address, TEST_FAILURE,
-                                fail_reason)
+          result = HttpTestResult(exit_node, 
+                                 self.node_map[exit_node[1:]].nickname,
+                                 address, TEST_FAILURE, fail_reason)
           return self.register_timeout_failure(result)
         elif pcode == -23: 
           fail_reason = FAILURE_URLERROR
@@ -798,16 +799,16 @@
           fail_reason = FAILURE_MISCEXCEPTION
       else: 
         fail_reason = FAILURE_BADHTTPCODE+str(pcode)
-      result = HttpTestResult(exit_node, address, TEST_FAILURE,
-                            fail_reason)
+      result = HttpTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                            address, TEST_FAILURE, fail_reason)
       result.extra_info = str(pcontent)
       self.register_http_failure(result)
       return TEST_FAILURE
 
     # if we have no content, we had a connection error
     if pcontent == "":
-      result = HttpTestResult(exit_node, address, TEST_FAILURE,
-                              FAILURE_NOEXITCONTENT)
+      result = HttpTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_FAILURE, FAILURE_NOEXITCONTENT)
       self.register_exit_failure(result)
       # Restore cookie jars
       self.cookie_jar = orig_cookie_jar
@@ -817,7 +818,8 @@
     # compare the content
     # if content matches, everything is ok
     if psha1sum.hexdigest() == sha1sum.hexdigest():
-      result = HttpTestResult(exit_node, address, TEST_SUCCESS)
+      result = HttpTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_SUCCESS)
       self.register_success(result)
       return TEST_SUCCESS
 
@@ -835,9 +837,11 @@
         exit_content_file = open(DataHandler.uniqueFilename(failed_prefix+'.'+exit_node[1:]+'.content'), 'w')
         exit_content_file.write(pcontent)
         exit_content_file.close()
-        result = HttpTestResult(exit_node, address, TEST_FAILURE, 
-                                FAILURE_EXITTRUNCATION, sha1sum.hexdigest(), 
-                                psha1sum.hexdigest(), content_prefix+".content",
+        result = HttpTestResult(exit_node,
+                                self.node_map[exit_node[1:]].nickname, 
+                                address, TEST_FAILURE, FAILURE_EXITTRUNCATION, 
+                                sha1sum.hexdigest(), psha1sum.hexdigest(), 
+                                content_prefix+".content",
                                 exit_content_file.name)
         self.register_exit_failure(result)
         # Restore cookie jars
@@ -856,7 +860,8 @@
     
     if not content_new:
       plog("WARN", "Failed to re-frech "+address+" outside of Tor. Did our network fail?")
-      result = HttpTestResult(exit_node, address, TEST_INCONCLUSIVE, 
+      result = HttpTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_INCONCLUSIVE, 
                               INCONCLUSIVE_NOLOCALCONTENT)
       if self.rescan_nodes: result.from_rescan = True
       self.results.append(result)
@@ -890,7 +895,8 @@
     # compare the node content and the new content
     # if it matches, everything is ok
     if psha1sum.hexdigest() == sha1sum_new.hexdigest():
-      result = HttpTestResult(exit_node, address, TEST_SUCCESS)
+      result = HttpTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_SUCCESS)
       self.register_success(result)
       return TEST_SUCCESS
  
@@ -934,10 +940,10 @@
       exit_content_file.write(pcontent)
       exit_content_file.close()
 
-      result = HttpTestResult(exit_node, address, TEST_FAILURE, 
-                              FAILURE_EXITONLY, sha1sum.hexdigest(), 
-                              psha1sum.hexdigest(), content_prefix+".content",
-                              exit_content_file.name)
+      result = HttpTestResult(exit_node, self.node_map[exit_node[1:]].nickname,
+                              address, TEST_FAILURE, FAILURE_EXITONLY, 
+                              sha1sum.hexdigest(), psha1sum.hexdigest(), 
+                              content_prefix+".content", exit_content_file.name)
       self.register_exit_failure(result)
       return TEST_FAILURE
 
@@ -945,10 +951,10 @@
     exit_content_file.write(pcontent)
     exit_content_file.close()
 
-    result = HttpTestResult(exit_node, address, TEST_FAILURE, 
-                            FAILURE_DYNAMIC, sha1sum_new.hexdigest(), 
-                            psha1sum.hexdigest(), content_prefix+".content",
-                            exit_content_file.name, 
+    result = HttpTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                            address, TEST_FAILURE, FAILURE_DYNAMIC, 
+                            sha1sum_new.hexdigest(), psha1sum.hexdigest(), 
+                            content_prefix+".content", exit_content_file.name, 
                             content_prefix+'.content-old',
                             sha1sum.hexdigest())
     if self.rescan_nodes: result.from_rescan = True
@@ -1134,7 +1140,8 @@
     has_js_changes = jsdiff.contains_differences(tor_js)
 
     if not has_js_changes:
-      result = JsTestResult(exit_node, address, TEST_SUCCESS)
+      result = JsTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                            address, TEST_SUCCESS)
       self.register_success(result)
       return TEST_SUCCESS
     else:
@@ -1142,11 +1149,11 @@
       exit_content_file.write(tor_js)
       exit_content_file.close()
 
-      result = JsTestResult(exit_node, address, TEST_FAILURE, 
-                              FAILURE_DYNAMIC, content_prefix+".content",
-                              exit_content_file.name, 
-                              content_prefix+'.content-old',
-                              self.jsdiffer_files[address])
+      result = JsTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                             address, TEST_FAILURE, FAILURE_DYNAMIC, 
+                             content_prefix+".content", exit_content_file.name, 
+                             content_prefix+'.content-old',
+                             self.jsdiffer_files[address])
       self.register_dynamic_failure(result)
       return TEST_FAILURE
 
@@ -1189,7 +1196,8 @@
     # if content matches, everything is ok
     if str(orig_soup) == str(tor_soup):
       plog("INFO", "Successful soup comparison after SHA1 fail for "+address+" via "+exit_node)
-      result = HtmlTestResult(exit_node, address, TEST_SUCCESS)
+      result = HtmlTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_SUCCESS)
       self.register_success(result)
 
       return TEST_SUCCESS
@@ -1197,7 +1205,8 @@
     content_new = new_html.decode('ascii', 'ignore')
     if not content_new:
       plog("WARN", "Failed to re-frech "+address+" outside of Tor. Did our network fail?")
-      result = HtmlTestResult(exit_node, address, TEST_INCONCLUSIVE, 
+      result = HtmlTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_INCONCLUSIVE, 
                               INCONCLUSIVE_NOLOCALCONTENT)
       if self.rescan_nodes: result.from_rescan = True
       self.results.append(result)
@@ -1213,9 +1222,9 @@
       exit_content_file.write(tor_html)
       exit_content_file.close()
 
-      result = HtmlTestResult(exit_node, address, TEST_FAILURE, 
-                              FAILURE_EXITONLY, content_prefix+".content",
-                              exit_content_file.name)
+      result = HtmlTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_FAILURE, FAILURE_EXITONLY, 
+                              content_prefix+".content", exit_content_file.name)
       self.register_exit_failure(result)
       return TEST_FAILURE
 
@@ -1274,7 +1283,8 @@
 
     if false_positive:
       plog("NOTICE", "False positive detected for dynamic change at "+address+" via "+exit_node)
-      result = HtmlTestResult(exit_node, address, TEST_SUCCESS)
+      result = HtmlTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, TEST_SUCCESS)
       self.register_success(result)
       return TEST_SUCCESS
 
@@ -1289,9 +1299,9 @@
       soupdiff_file = self.soupdiffer_files[address]
     else: soupdiff_file = None
 
-    result = HtmlTestResult(exit_node, address, TEST_FAILURE, 
-                            FAILURE_DYNAMIC, content_prefix+".content",
-                            exit_content_file.name, 
+    result = HtmlTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                            address, TEST_FAILURE, FAILURE_DYNAMIC, 
+                            content_prefix+".content", exit_content_file.name, 
                             content_prefix+'.content-old',
                             soupdiff_file, jsdiff_file)
     self.register_dynamic_failure(result)
@@ -1439,7 +1449,7 @@
       if ssl_domain.cert_changed:
         plog("NOTICE", "Fully dynamic certificate host "+address)
 
-        result = SSLTestResult("NoExit", address, ssl_file_name, 
+        result = SSLTestResult("NoExit", "NotStored!", address, ssl_file_name, 
                                TEST_INCONCLUSIVE,
                                INCONCLUSIVE_DYNAMICSSL)
         if self.rescan_nodes: result.from_rescan = True
@@ -1450,7 +1460,7 @@
 
     if not ssl_domain.num_certs():
         plog("NOTICE", "No non-tor certs available for "+address)
-        result = SSLTestResult("NoExit", address, ssl_file_name, 
+        result = SSLTestResult("NoExit", "NoStored!", address, ssl_file_name, 
                                TEST_INCONCLUSIVE,
                                INCONCLUSIVE_NOLOCALCONTENT)
         if self.rescan_nodes: result.from_rescan = True
@@ -1472,8 +1482,8 @@
     exit_node = metacon.get_exit_node()
     if not exit_node or exit_node == '0':
       plog('NOTICE', 'We had no exit node to test, skipping to the next test.')
-      result = SSLTestResult(exit_node, address, ssl_file_name, 
-                              TEST_INCONCLUSIVE,
+      result = SSLTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                              address, ssl_file_name, TEST_INCONCLUSIVE,
                               INCONCLUSIVE_NOEXIT)
       if self.rescan_nodes: result.from_rescan = True
       self.results.append(result)
@@ -1492,8 +1502,9 @@
           fail_reason = FAILURE_CONNREFUSED
         elif code == -6: # timeout
           fail_reason = FAILURE_TIMEOUT
-          result = SSLTestResult(exit_node, address, ssl_file_name, 
-                                TEST_FAILURE, fail_reason)
+          result = SSLTestResult(exit_node,
+                                self.node_map[exit_node[1:]].nickname, address,
+                                ssl_file_name, TEST_FAILURE, fail_reason)
           return self.register_timeout_failure(result)
         elif code == -23: 
           fail_reason = FAILURE_CRYPTOERROR
@@ -1502,8 +1513,8 @@
       else:
           fail_reason = FAILURE_MISCEXCEPTION
 
-      result = SSLTestResult(exit_node, address, ssl_file_name, TEST_FAILURE, 
-                             fail_reason) 
+      result = SSLTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                             address, ssl_file_name, TEST_FAILURE, fail_reason) 
       result.extra_info = exc
       self.register_exit_failure(result)
       return TEST_FAILURE
@@ -1512,30 +1523,32 @@
       # get an easily comparable representation of the certs
       cert_pem = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
     except OpenSSL.crypto.Error, e:
-      # XXX
-      result = SSLTestResult(exit_node, address, ssl_file_name, TEST_FAILURE, 
-              FAILURE_CRYPTOERROR)
+      result = SSLTestResult(exit_node, self.node_map[exit_node[1:]].nickname,
+                   address, ssl_file_name, TEST_FAILURE, FAILURE_CRYPTOERROR)
       self.extra_info=e.__class__.__name__+str(e)
       self.register_exit_failure(result)
       return TEST_FAILURE
 
     # if certs match, everything is ok
     if ssl_domain.seen_cert(cert_pem):
-      result = SSLTestResult(exit_node, address, ssl_file_name, TEST_SUCCESS)
+      result = SSLTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                             address, ssl_file_name, TEST_SUCCESS)
       self.register_success(result)
       return TEST_SUCCESS
 
     # False positive case.. Can't help it if the cert rotates AND we have a
     # failure... Need to prune all results for this cert and give up.
     if ssl_domain.cert_rotates:
-      result = SSLTestResult(exit_node, address, ssl_file_name, TEST_FAILURE, 
-                             FAILURE_DYNAMIC, 
-                             self.get_resolved_ip(address), cert_pem)
+      result = SSLTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                             address, ssl_file_name, TEST_FAILURE, 
+                             FAILURE_DYNAMIC, self.get_resolved_ip(address), 
+                             cert_pem)
       self.register_dynamic_failure(result)
       return TEST_FAILURE
 
     # if certs dont match, means the exit node has been messing with the cert
-    result = SSLTestResult(exit_node, address, ssl_file_name, TEST_FAILURE,
+    result = SSLTestResult(exit_node, self.node_map[exit_node[1:]].nickname, 
+                           address, ssl_file_name, TEST_FAILURE,
                            FAILURE_EXITONLY, self.get_resolved_ip(address), 
                            cert_pem)
     self.register_exit_failure(result)
@@ -1719,11 +1732,11 @@
     # compare
     if (capabilities_ok != capabilities_ok_d or starttls_present != starttls_present_d or 
         tls_started != tls_started_d or tls_succeeded != tls_succeeded_d):
-      result = POPTestResult(exit_node, address, TEST_FAILURE)
+      result = POPTestResult(exit_node, self.node_map[exit_node[1:]].nickname, address, TEST_FAILURE)
       datahandler.saveResult(result)
       return TEST_FAILURE
     
-    result = POPTestResult(exit_node, address, TEST_SUCCESS)
+    result = POPTestResult(exit_node, self.node_map[exit_node[1:]].nickname, address, TEST_SUCCESS)
     datahandler.saveResult(result)
     return TEST_SUCCESS
 
@@ -1818,11 +1831,11 @@
 
     # compare
     if ehlo1_reply != ehlo1_reply_d or has_starttls != has_starttls_d or ehlo2_reply != ehlo2_reply_d:
-      result = SMTPTestResult(exit_node, address, TEST_FAILURE)
+      result = SMTPTestResult(exit_node, self.node_map[exit_node[1:]].nickname, address, TEST_FAILURE)
       datahandler.saveResult(result)
       return TEST_FAILURE
 
-    result = SMTPTestResult(exit_node, address, TEST_SUCCESS)
+    result = SMTPTestResult(exit_node, self.node_map[exit_node[1:]].nickname, address, TEST_SUCCESS)
     datahandler.saveResult(result)
     return TEST_SUCCESS
 
@@ -1985,11 +1998,11 @@
     # compare
     if (capabilities_ok != capabilities_ok_d or starttls_present != starttls_present_d or 
       tls_started != tls_started_d or tls_succeeded != tls_succeeded_d):
-      result = IMAPTestResult(exit_node, address, TEST_FAILURE)
+      result = IMAPTestResult(exit_node, self.node_map[exit_node[1:]].nickname, address, TEST_FAILURE)
       datahandler.saveResult(result)
       return TEST_FAILURE
 
-    result = IMAPTestResult(exit_node, address, TEST_SUCCESS)
+    result = IMAPTestResult(exit_node, self.node_map[exit_node[1:]].nickname, address, TEST_SUCCESS)
     datahandler.saveResult(result)
     return TEST_SUCCESS
 
@@ -2020,11 +2033,11 @@
       return TEST_INCONCLUSIVE
 
     if ip in ips_d:
-      result = DNSTestResult(exit_node, address, TEST_SUCCESS)
+      result = DNSTestResult(exit_node, self.node_map[exit_node[1:]].nickname, address, TEST_SUCCESS)
       return TEST_SUCCESS
     else:
       plog('ERROR', 'The basic DNS test suspects ' + exit_node + ' to be malicious.')
-      result = DNSTestResult(exit_node, address, TEST_FAILURE)
+      result = DNSTestResult(exit_node, self.node_map[exit_node[1:]].nickname, address, TEST_FAILURE)
       return TEST_FAILURE
 
 class SSHTest(Test):
@@ -2151,7 +2164,7 @@
           handler = DataHandler()
           node = self.__mt.get_exit_node()
           plog("ERROR", "DNS Rebeind failure via "+node)
-          result = DNSRebindTestResult(node, '', TEST_FAILURE)
+          result = DNSRebindTestResult(node, "NotStored!", '', TEST_FAILURE)
           handler.saveResult(result)
     # TODO: This is currently handled via socks error codes,
     # but stream events would give us more info...