From 4524aebbacf397cb99328bdf9274fa73f2b1543c Mon Sep 17 00:00:00 2001 From: James Lu Date: Fri, 15 Jun 2018 02:47:12 -0700 Subject: [PATCH] clientbot: initial pass of TLS cert validation (#592) This works OK, but we should make the validation options built-in instead of clientbot-specific. --- classes.py | 2 +- example-conf.yml | 14 +++++++++++--- protocols/clientbot.py | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/classes.py b/classes.py index 9bfb086..9339e2e 100644 --- a/classes.py +++ b/classes.py @@ -1615,7 +1615,7 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils): self.name) raise - self._socket = context.wrap_socket(self._socket) + self._socket = context.wrap_socket(self._socket, server_hostname=self.serverdata.get('ip')) def _verify_ssl(self): """ diff --git a/example-conf.yml b/example-conf.yml index 01a6043..e9904b7 100644 --- a/example-conf.yml +++ b/example-conf.yml @@ -386,7 +386,7 @@ servers: # Sample Clientbot configuration, if you want to connect PyLink as a bot to relay somewhere # (or do other bot things). magicnet: - ip: 1.2.3.4 + ip: irc.somenet.local port: 6697 # Optional server password. @@ -405,12 +405,20 @@ servers: # number of underscores. #pylink_altnicks: ["pybot`", "pybot-"] - # SSL options. Certfile and keyfile are optional, but can be used for CertFP/SASL external - # if supported. + # TLS/SSL options. Certfile and keyfile are optional, but can be used for CertFP/SASL external + # where supported. ssl: true #ssl_certfile: mycert.pem #ssl_keyfile: mycert.pem + # New in 2.0: Determines whether the target server's TLS certificate hostnames should be + # checked against the hostname given. This defaults to true if not specified. + #ssl_validate_hostname: true + + # New in 2.0: When enabled, this disables TLS certificate validation on the target network. + # This defaults to false if not specified. + #ssl_accept_invalid_certs: false + # Autoconnect works as usual. autoconnect: 30 diff --git a/protocols/clientbot.py b/protocols/clientbot.py index 83fa10e..50ce28f 100644 --- a/protocols/clientbot.py +++ b/protocols/clientbot.py @@ -57,6 +57,20 @@ class ClientbotWrapperProtocol(IRCCommonProtocol): self.hook_map = {'ACCOUNT': 'CLIENT_SERVICES_LOGIN'} + def _make_ssl_context(self): + """ + Returns a ssl.SSLContext instance with certificate validation enabled by default. + """ + context = ssl.create_default_context() + if self.serverdata.get('ssl_accept_invalid_certs', False): + # Note: we have to disable hostname checking before disabling cert validation + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + else: + context.check_hostname = self.serverdata.get('ssl_validate_hostname', True) + + return context + def post_connect(self): """Initializes a connection to a server.""" # (Re)initialize counter-based pseudo UID generators