[or-cvs] r19230: {torflow} Clean up SSL error handling and tagging. (torflow/trunk/NetworkScanners)
mikeperry at seul.org
mikeperry at seul.org
Tue Apr 7 03:04:52 UTC 2009
Author: mikeperry
Date: 2009-04-06 23:04:52 -0400 (Mon, 06 Apr 2009)
New Revision: 19230
Modified:
torflow/trunk/NetworkScanners/libsoat.py
torflow/trunk/NetworkScanners/soat.py
Log:
Clean up SSL error handling and tagging.
Modified: torflow/trunk/NetworkScanners/libsoat.py
===================================================================
--- torflow/trunk/NetworkScanners/libsoat.py 2009-04-06 23:34:15 UTC (rev 19229)
+++ torflow/trunk/NetworkScanners/libsoat.py 2009-04-07 03:04:52 UTC (rev 19230)
@@ -74,6 +74,7 @@
FAILURE_EXITPOLICY = "FailureExitPolicy"
FAILURE_CONNREFUSED = "FailureConnRefused"
FAILURE_URLERROR = "FailureURLError" # can also mean timeout...
+FAILURE_CRYPTOERROR = "FailureCryptoError"
FAILURE_TIMEOUT = "FailureTimeout"
# False positive reasons
Modified: torflow/trunk/NetworkScanners/soat.py
===================================================================
--- torflow/trunk/NetworkScanners/soat.py 2009-04-06 23:34:15 UTC (rev 19229)
+++ torflow/trunk/NetworkScanners/soat.py 2009-04-07 03:04:52 UTC (rev 19230)
@@ -289,6 +289,8 @@
self.node_results[node].append(result)
if len(self.node_results[node]) >= self.tests_per_node:
self.nodes.remove(node)
+ self.scan_nodes = len(self.nodes)
+ self.nodes_to_mark = self.scan_nodes*self.tests_per_node
plog("INFO", "Removed node "+node+". "+str(len(self.nodes))+" nodes remain")
else:
plog("DEBUG", "Keeping node "+node+". "+str(len(self.nodes))+" nodes remain. Tests: "+str(len(self.node_results[node]))+"/"+str(self.tests_per_node))
@@ -1330,29 +1332,26 @@
c.set_connect_state()
c.connect((address, 443)) # DNS OK.
c.send(crypto.dump_certificate_request(crypto.FILETYPE_PEM,request))
+ # return the cert
+ return (0, c.get_peer_certificate(), None)
except socket.timeout, e:
plog('WARN','Socket timeout for '+address+": "+str(e))
- return e
+ return (-6.0, None, e.__class__.__name__+str(e))
except socket.error, e:
plog('WARN','An error occured while opening an ssl connection to '+address+": "+str(e))
- return e
+ return (-666.0, None, e.__class__.__name__+str(e))
except socks.Socks5Error, e:
- # XXX: Improve these
- if e.value[0] == 6: # or e.value[0] == 1: # Timeout or 'general'
- plog('NOTICE', 'An error occured while negotiating socks5 for '+address+': '+str(e))
- return -1
- else:
- plog('WARN', 'An error occured while negotiating socks5 for '+address+': '+str(e))
- return e
+ plog('WARN', 'A SOCKS5 error '+str(e.value[0])+' occured for '+address+": "+str(e))
+ return (-float(e.value[0]), None, e.__class__.__name__+str(e))
except KeyboardInterrupt:
raise KeyboardInterrupt
+ except OpenSSL.crypto.Error, e:
+ traceback.print_exc()
+ return (-23.0, None, e.__class__.__name__+str(e))
except Exception, e:
plog('WARN', 'An unknown SSL error occured for '+address+': '+str(e))
traceback.print_exc()
- return e
-
- # return the cert
- return c.get_peer_certificate()
+ return (-666.0, None, e.__class__.__name__+str(e))
def get_resolved_ip(self, hostname):
mappings = metacon.control.get_address_mappings("cache")
@@ -1370,13 +1369,17 @@
#let's always check.
#if not ssl_domain.seen_ip(ip):
plog('INFO', 'Ssl connection to new ip '+ip+" for "+ssl_domain.domain)
- raw_cert = self.ssl_request(ip)
- if not raw_cert or isinstance(raw_cert, Exception):
- plog('WARN', 'Error getting the correct cert for '+ssl_domain.domain+":"+ip)
+ (code, raw_cert, exc) = self.ssl_request(ip)
+ if not raw_cert:
+ plog('WARN', 'Error getting the correct cert for '+ssl_domain.domain+":"+ip+" "+str(code)+"("+str(exc)+")")
continue
- ssl_domain.add_cert(ip,
+ try:
+ ssl_domain.add_cert(ip,
crypto.dump_certificate(crypto.FILETYPE_PEM, raw_cert))
- changed = True # Always save new copy.
+ changed = True # Always save new copy.
+ except Exception, e:
+ traceback.print_exc()
+ plog('WARN', 'Error dumping cert for '+ssl_domain.domain+":"+ip+" E:"+str(e))
return changed
def check_openssl(self, address):
@@ -1416,16 +1419,10 @@
self.remove_target(address, INCONCLUSIVE_NOLOCALCONTENT)
return TEST_INCONCLUSIVE
- try:
- if self._update_cert_list(ssl_domain, check_ips):
- ssl_file = open(ssl_file_name, 'w')
- pickle.dump(ssl_domain, ssl_file)
- ssl_file.close()
- except OpenSSL.crypto.Error:
- plog('WARN', 'Local crypto error for '+address)
- traceback.print_exc()
- self.remove_target(address, INCONCLUSIVE_NOLOCALCONTENT)
- return TEST_INCONCLUSIVE
+ if self._update_cert_list(ssl_domain, check_ips):
+ ssl_file = open(ssl_file_name, 'w')
+ pickle.dump(ssl_domain, ssl_file)
+ ssl_file.close()
if not ssl_domain.cert_map:
plog('WARN', 'Error getting the correct cert for ' + address)
@@ -1435,16 +1432,10 @@
if ssl_domain.cert_changed:
ssl_domain = SSLDomain(address)
plog('INFO', 'Fetching all new certs for '+address)
- try:
- if self._update_cert_list(ssl_domain, check_ips):
- ssl_file = open(ssl_file_name, 'w')
- pickle.dump(ssl_domain, ssl_file)
- ssl_file.close()
- except OpenSSL.crypto.Error:
- plog('WARN', 'Local crypto error for '+address)
- traceback.print_exc()
- self.remove_target(address, INCONCLUSIVE_NOLOCALCONTENT)
- return TEST_INCONCLUSIVE
+ if self._update_cert_list(ssl_domain, check_ips):
+ ssl_file = open(ssl_file_name, 'w')
+ pickle.dump(ssl_domain, ssl_file)
+ ssl_file.close()
if ssl_domain.cert_changed:
plog("NOTICE", "Fully dynamic certificate host "+address)
@@ -1473,7 +1464,7 @@
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, tor_host, tor_port)
socket.socket = socks.socksocket
- cert = self.ssl_request(address)
+ (code, cert, exc) = self.ssl_request(address)
# reset the connection method back to direct
socket.socket = defaultsocket
@@ -1489,43 +1480,41 @@
datahandler.saveResult(result)
return TEST_INCONCLUSIVE
- if cert == -1:
- plog('NOTICE', 'SSL test inconclusive for: '+address)
- result = SSLTestResult(exit_node, address, ssl_file_name,
- TEST_INCONCLUSIVE,
- INCONCLUSIVE_TORBREAKAGE)
- if self.rescan_nodes: result.from_rescan = True
- datahandler.saveResult(result)
- self.results.append(result)
- return TEST_INCONCLUSIVE
-
- # if we got no cert, there was an ssl error
if not cert:
- result = SSLTestResult(exit_node, address, ssl_file_name,
- TEST_FAILURE,
- FAILURE_NOEXITCONTENT)
- self.register_exit_failure(result)
- return TEST_FAILURE
+ if code < 0 and type(code) == float:
+ if code == -2: # "connection not allowed aka ExitPolicy
+ fail_reason = FAILURE_EXITPOLICY
+ elif code == -3: # "Net Unreach" ??
+ fail_reason = FAILURE_NETUNREACH
+ elif code == -4: # "Host Unreach" aka RESOLVEFAILED
+ fail_reason = FAILURE_HOSTUNREACH
+ elif code == -5: # Connection refused
+ fail_reason = FAILURE_CONNREFUSED
+ elif code == -6: # timeout
+ fail_reason = FAILURE_TIMEOUT
+ result = SSLTestResult(exit_node, address, ssl_file_name,
+ TEST_FAILURE, fail_reason)
+ return self.register_timeout_failure(result)
+ elif code == -23:
+ fail_reason = FAILURE_CRYPTOERROR
+ else:
+ fail_reason = FAILURE_MISCEXCEPTION
+ else:
+ fail_reason = FAILURE_MISCEXCEPTION
- # XXX: Improve this
- if isinstance(cert, Exception):
- if isinstance(cert, socks.Socks5Error):
- fail_reason = FAILURE_SOCKSERROR
- elif isinstance(cert, socket.timeout):
- fail_reason = FAILURE_TIMEOUT
- else: fail_reason = FAILURE_MISCEXCEPTION
result = SSLTestResult(exit_node, address, ssl_file_name, TEST_FAILURE,
fail_reason)
- result.extra_info = cert.__class__.__name__+str(cert)
+ result.extra_info = exc
self.register_exit_failure(result)
return TEST_FAILURE
-
+
try:
# 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_MISCEXCEPTION)
+ FAILURE_CRYPTOERROR)
self.extra_info=e.__class__.__name__+str(e)
self.register_exit_failure(result)
return TEST_FAILURE
More information about the tor-commits
mailing list