Ensure that all SSL cert error handling is overridable using event handlers.

Relevant events:

    ssl_invalid_cert
    ssl_invalid_chain
    ssl_expired_cert
This commit is contained in:
Lance Stout 2012-06-08 09:31:44 -07:00
parent f5652a667b
commit 7b1564947d

View file

@ -493,7 +493,8 @@ class XMLStream(object):
ssl_socket = ssl.wrap_socket(self.socket, ssl_socket = ssl.wrap_socket(self.socket,
ca_certs=self.ca_certs, ca_certs=self.ca_certs,
cert_reqs=cert_policy) cert_reqs=cert_policy,
do_handshake_on_connect=False)
if hasattr(self.socket, 'socket'): if hasattr(self.socket, 'socket'):
# We are using a testing socket, so preserve the top # We are using a testing socket, so preserve the top
@ -510,6 +511,17 @@ class XMLStream(object):
log.debug("Connecting to %s:%s", domain, self.address[1]) log.debug("Connecting to %s:%s", domain, self.address[1])
self.socket.connect(self.address) self.socket.connect(self.address)
try:
self.socket.do_handshake()
except:
log.error('CERT: Invalid certificate trust chain.')
if not self.event_handled('ssl_invalid_chain'):
self.disconnect(self.auto_reconnect, send_close=False)
else:
self.event('ssl_invalid_chain', direct=True)
return False
if self.use_ssl and self.ssl_support: if self.use_ssl and self.ssl_support:
self._der_cert = self.socket.getpeercert(binary_form=True) self._der_cert = self.socket.getpeercert(binary_form=True)
pem_cert = ssl.DER_cert_to_PEM_cert(self._der_cert) pem_cert = ssl.DER_cert_to_PEM_cert(self._der_cert)
@ -520,8 +532,10 @@ class XMLStream(object):
cert.verify(self._expected_server_name, self._der_cert) cert.verify(self._expected_server_name, self._der_cert)
except cert.CertificateError as err: except cert.CertificateError as err:
log.error(err.message) log.error(err.message)
self.event('ssl_invalid_cert', cert, direct=True) if not self.event_handled('ssl_invalid_cert'):
self.disconnect(send_close=False) self.disconnect(send_close=False)
else:
self.event('ssl_invalid_cert', cert, direct=True)
self.set_socket(self.socket, ignore=True) self.set_socket(self.socket, ignore=True)
#this event is where you should set your application state #this event is where you should set your application state
@ -790,8 +804,10 @@ class XMLStream(object):
self.socket.do_handshake() self.socket.do_handshake()
except: except:
log.error('CERT: Invalid certificate trust chain.') log.error('CERT: Invalid certificate trust chain.')
self.event('ssl_invalid_chain', direct=True) if not self.event_handled('ssl_invalid_chain'):
self.disconnect(self.auto_reconnect, send_close=False) self.disconnect(self.auto_reconnect, send_close=False)
else:
self.event('ssl_invalid_chain', direct=True)
return False return False
self._der_cert = self.socket.getpeercert(binary_form=True) self._der_cert = self.socket.getpeercert(binary_form=True)
@ -803,9 +819,10 @@ class XMLStream(object):
cert.verify(self._expected_server_name, self._der_cert) cert.verify(self._expected_server_name, self._der_cert)
except cert.CertificateError as err: except cert.CertificateError as err:
log.error(err.message) log.error(err.message)
self.event('ssl_invalid_cert', cert, direct=True)
if not self.event_handled('ssl_invalid_cert'): if not self.event_handled('ssl_invalid_cert'):
self.disconnect(self.auto_reconnect, send_close=False) self.disconnect(self.auto_reconnect, send_close=False)
else:
self.event('ssl_invalid_cert', cert, direct=True)
self.set_socket(self.socket) self.set_socket(self.socket)
return True return True
@ -820,8 +837,12 @@ class XMLStream(object):
return return
def restart(): def restart():
log.warn("The server certificate has expired. Restarting.") if not self.event_handled('ssl_expired_cert'):
self.reconnect() log.warn("The server certificate has expired. Restarting.")
self.reconnect()
else:
pem_cert = ssl.DER_cert_to_PEM_cert(self._der_cert)
self.event('ssl_expired_cert', pem_cert)
cert_ttl = cert.get_ttl(self._der_cert) cert_ttl = cert.get_ttl(self._der_cert)
if cert_ttl is None: if cert_ttl is None: