3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-30 14:49:28 +01:00

core: merge TLS validation code into IRCNetwork (#592)

Certificate verification is now enabled for all Clientbot networks, but not yet for S2S links (self-signed certs are common here and direct IP links even more so)
This commit is contained in:
James Lu 2018-06-15 15:27:42 -07:00
parent e38cd0ada2
commit 76c0db15c4
3 changed files with 39 additions and 23 deletions

View File

@ -1588,11 +1588,23 @@ class IRCNetwork(PyLinkNetworkCoreWithUtils):
"""
Returns a ssl.SSLContext instance appropriate for this connection.
"""
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context = ssl.create_default_context()
# Use the ssl-should-verify protocol capability to determine whether we should
# accept invalid certs by default. Generally, cert validation is OFF for server protocols
# and ON for client-based protocols like clientbot
if self.serverdata.get('ssl_accept_invalid_certs', not self.has_cap("ssl-should-verify")):
# Note: check_hostname has to be off to set verify_mode to CERT_NONE,
# since it's possible for the remote link to not provide a cert at all
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
else:
# Otherwise, only check cert hostname if the target is a hostname OR we have
# ssl-should-verify defined
context.check_hostname = self.serverdata.get('ssl_validate_hostname',
self.has_cap("ssl-should-verify") or
utils.get_hostname_type(self.serverdata['ip']) is 0)
# Disable SSLv2 and SSLv3 - these are insecure
context.options |= ssl.OP_NO_SSLv2
context.options |= ssl.OP_NO_SSLv3
return context
def _setup_ssl(self):

View File

@ -191,8 +191,21 @@ servers:
#ssl_certfile: pylink-cert.pem
#ssl_keyfile: pylink-key.pem
# Optionally, you can set this option to verify the SSL certificate
# fingerprint of your uplink.
# New in 2.0: Determines whether the target server's TLS certificate hostnames should be
# checked against the hostname we're set to connect to. This defaults to true for Clientbot
# networks and others linked to via a hostname. It depends on ssl_accept_invalid_certs being
# *disabled* to take effect.
#ssl_validate_hostname: true
# New in 2.0: When enabled, this disables TLS certificate validation on the target network.
# This defaults to false (bad certs are rejected) on Clientbot and true for server protocols
# (where bad certs are accepted). This disables the ssl_validate_hostname option,
# effectively forcing it to be false.
#ssl_accept_invalid_certs: false
# Optionally, you can set this option to verify the SSL certificate fingerprint of your
# uplink. This check works regardless of whether ssl_validate_hostname and
# ssl_accept_invalid_certs are enabled.
#ssl_fingerprint: "e0fee1adf795c84eec4735f039503eb18d9c35cc"
# This sets the hash type for the fingerprint (md5, sha1, sha256, etc.)
@ -412,11 +425,15 @@ servers:
#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.
# checked against the hostname we're set to connect to. This defaults to true for Clientbot
# networks and others linked to via a hostname. It depends on ssl_accept_invalid_certs being
# *disabled* to take effect.
#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.
# This defaults to false (bad certs are rejected) on Clientbot and true for server protocols
# (where bad certs are accepted). This disables the ssl_validate_hostname option,
# effectively forcing it to be false.
#ssl_accept_invalid_certs: false
# Autoconnect works as usual.

View File

@ -25,7 +25,8 @@ class ClientbotWrapperProtocol(IRCCommonProtocol):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.protocol_caps = {'visible-state-only', 'slash-in-nicks', 'slash-in-hosts', 'underscore-in-hosts'}
self.protocol_caps = {'visible-state-only', 'slash-in-nicks', 'slash-in-hosts', 'underscore-in-hosts',
'ssl-should-verify'}
self.has_eob = False
@ -57,20 +58,6 @@ 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