From 8c3946d31c0a55228576f60c682486611c537a87 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Mon, 22 Feb 2016 18:36:53 +0100 Subject: [PATCH 01/11] =?UTF-8?q?Actually,=203.2=20and=203.3=20don't=20hav?= =?UTF-8?q?e=20SSLContext=20either.=20Let's=20recommend=20only=20=E2=89=A5?= =?UTF-8?q?=203.4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/net.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/net.py b/src/utils/net.py index 8ae3ac1b2..505737453 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -171,7 +171,6 @@ else: logger.critical('This Python version does not support SSL/TLS ' 'certification authority verification, which makes your ' 'connection vulnerable to man-in-the-middle attacks.' - 'You should consider upgrading to Python 3 ' - '(or at least 2.7.9).') + 'You should consider upgrading to Python 3.4 or newer.') return conn # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: From 880addf256abbebd72b7e7b52fef33198d6e557a Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Mon, 22 Feb 2016 20:18:37 +0100 Subject: [PATCH 02/11] Add link to FAQ items on how to upgrade to Python 3. --- setup.py | 15 +++++++++------ src/utils/net.py | 3 ++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/setup.py b/setup.py index 8bec9c6dc..ca9772206 100644 --- a/setup.py +++ b/setup.py @@ -236,11 +236,14 @@ setup( ) -if sys.version_info < (2, 7, 9): - sys.stderr.write('+------------------------------------------------+\n') - sys.stderr.write('| Running Limnoria on Python versions older than |\n') - sys.stderr.write('| 2.7.9 is deprecated. |\n') - sys.stderr.write('| Please consider upgrading to Python 3.x. |\n') - sys.stderr.write('+------------------------------------------------+\n') +if sys.version_info < (2, 7, 9) or True: + sys.stderr.write('+-----------------------------------------------------+\n') + sys.stderr.write('| Running Limnoria on Python versions older than |\n') + sys.stderr.write('| 2.7.9 is deprecated. |\n') + sys.stderr.write('| Please consider upgrading to Python 3.4 or greater. |\n') + sys.stderr.write('+-----------------------------------------------------+\n') + sys.stderr.write('\n') + sys.stderr.write('See \n') + sys.stderr.write('\n') # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/src/utils/net.py b/src/utils/net.py index 505737453..83584d00e 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -171,6 +171,7 @@ else: logger.critical('This Python version does not support SSL/TLS ' 'certification authority verification, which makes your ' 'connection vulnerable to man-in-the-middle attacks.' - 'You should consider upgrading to Python 3.4 or newer.') + 'You should consider upgrading to Python 3.4 or newer. ' + 'See ') return conn # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: From 78cf550674ef23586e697da95c6b50451a5440e7 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 23 Feb 2016 16:25:37 +0100 Subject: [PATCH 03/11] Socket: fix crash on Python versions that do no support certificate validation. --- src/drivers/Socket.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/drivers/Socket.py b/src/drivers/Socket.py index ad4b563c3..7ab479793 100644 --- a/src/drivers/Socket.py +++ b/src/drivers/Socket.py @@ -374,7 +374,9 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): verify=verifyCertificates, trusted_fingerprints=network_config.ssl.serverFingerprints(), ) - except ssl.CertificateError as e: + except getattr(ssl, 'CertificateError', None) as e: + # Default to None for old Python version, which do not have + # CertificateError drivers.log.critical(('Certificate validation failed when ' 'connecting to %s: %s\n' 'This means someone is doing a man-in-the-middle attack ' From b34ee949cbb796a54b6a98d697acf7771edd32c7 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 23 Feb 2016 19:11:47 +0000 Subject: [PATCH 04/11] Remove debug expression I shouldn't have committed. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ca9772206..0b80c3ae1 100644 --- a/setup.py +++ b/setup.py @@ -236,7 +236,7 @@ setup( ) -if sys.version_info < (2, 7, 9) or True: +if sys.version_info < (2, 7, 9): sys.stderr.write('+-----------------------------------------------------+\n') sys.stderr.write('| Running Limnoria on Python versions older than |\n') sys.stderr.write('| 2.7.9 is deprecated. |\n') From 0b66abaf5b38d554d2c1007263ffb12bf604126c Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 23 Feb 2016 19:12:22 +0000 Subject: [PATCH 05/11] Channel: Fix 'ignore remove' converter to work like 'ignore add'. --- plugins/Channel/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Channel/plugin.py b/plugins/Channel/plugin.py index 1a11cffd5..9a4db1c54 100644 --- a/plugins/Channel/plugin.py +++ b/plugins/Channel/plugin.py @@ -663,7 +663,7 @@ class Channel(callbacks.Plugin): @internationalizeDocstring def remove(self, irc, msg, args, channel, banmask): - """[] + """[] If you have the #channel,op capability, this will remove the persistent ignore on in the channel. is only @@ -676,7 +676,7 @@ class Channel(callbacks.Plugin): irc.replySuccess() except KeyError: irc.error(_('There are no ignores for that hostmask.')) - remove = wrap(remove, ['op', 'hostmask']) + remove = wrap(remove, ['op', 'banmask']) @internationalizeDocstring def list(self, irc, msg, args, channel): From 81a9d1fa39d9ff7eaf66d3b90d6f4d2f441493f0 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 23 Feb 2016 20:52:07 +0100 Subject: [PATCH 06/11] =?UTF-8?q?Remove=20=E2=80=9CSupybot=E2=80=9D=20by?= =?UTF-8?q?=20=E2=80=9CLimnoria=E2=80=9D=20in=20the=20default=20version=20?= =?UTF-8?q?(following=20661a32d1a96f26071efc98b5b6d522f214ea07bf).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf.py b/src/conf.py index 8fb0deeb8..fa90a16db 100644 --- a/src/conf.py +++ b/src/conf.py @@ -210,7 +210,7 @@ class VersionIfEmpty(registry.String): def __call__(self): ret = registry.String.__call__(self) if not ret: - ret = 'Supybot %s' % version + ret = 'Limnoria %s' % version return ret registerGlobalValue(supybot, 'user', From d163d1a1a3c0058c2520ba7c2a730c235f397e7d Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 23 Feb 2016 20:52:36 +0100 Subject: [PATCH 07/11] Add support for authority certificates. --- src/conf.py | 3 +++ src/drivers/Socket.py | 3 ++- src/utils/net.py | 8 +++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/conf.py b/src/conf.py index fa90a16db..85db4410b 100644 --- a/src/conf.py +++ b/src/conf.py @@ -329,6 +329,9 @@ def registerNetwork(name, password='', ssl=True, sasl_username='', of fingerprints of trusted certificates for this network. If non-empty, Certification Authority signatures will not be used to verify certificates."""))) + registerGlobalValue(network.ssl, 'authorityCertificate', + registry.String('', _("""A certificate that is trusted to verify + certificates of this network (aka. Certificate Authority)."""))) registerGlobalValue(network, 'requireStarttls', registry.Boolean(False, _("""Determines whether the bot will connect in plain text to %s but require STARTTLS before authentication. This is ignored if the diff --git a/src/drivers/Socket.py b/src/drivers/Socket.py index 7ab479793..bd4e2833b 100644 --- a/src/drivers/Socket.py +++ b/src/drivers/Socket.py @@ -373,6 +373,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): certfile=certfile, verify=verifyCertificates, trusted_fingerprints=network_config.ssl.serverFingerprints(), + ca_file=network_config.ssl.authorityCertificate(), ) except getattr(ssl, 'CertificateError', None) as e: # Default to None for old Python version, which do not have @@ -389,7 +390,7 @@ class SocketDriver(drivers.IrcDriver, drivers.ServersMixin): drivers.log.critical(('Certificate validation failed when ' 'connecting to %s: %s\n' 'This means someone is doing a man-in-the-middle attack ' - 'on your connection, or because the server\'s ' + 'on your connection, or that the server\'s ' 'certificate is not trusted.') % (self.irc.network, e.args[1])) raise ssl.SSLError('Aborting because of failed certificate ' diff --git a/src/utils/net.py b/src/utils/net.py index 83584d00e..83e1e7f86 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -144,13 +144,15 @@ def check_certificate_fingerprint(conn, trusted_fingerprints): if hasattr(ssl, 'create_default_context'): def ssl_wrap_socket(conn, hostname, logger, certfile=None, - trusted_fingerprints=None, verify=True, + trusted_fingerprints=None, verify=True, ca_file=None, **kwargs): context = ssl.create_default_context(**kwargs) if trusted_fingerprints or not verify: # Do not use Certification Authorities context.check_hostname = False context.verify_mode = ssl.CERT_NONE + if ca_file: + context.load_verify_locations(cafile=ca_file) if certfile: context.load_cert_chain(certfile) conn = context.wrap_socket(conn, server_hostname=hostname) @@ -160,10 +162,10 @@ if hasattr(ssl, 'create_default_context'): else: def ssl_wrap_socket(conn, hostname, logger, verify=True, certfile=None, - ca_certs=None, trusted_fingerprints=None): + ca_file=None, trusted_fingerprints=None): # TLSv1.0 is the only TLS version Python < 2.7.9 supports # (besides SSLv2 and v3, which are known to be insecure) - conn = ssl.wrap_socket(conn, certfile=certfile, ca_certs=ca_certs, + conn = ssl.wrap_socket(conn, certfile=certfile, ca_certs=ca_file, ssl_version=ssl.ssl.PROTOCOL_TLSv1, verify_mode=ssl.CERT_NONE) if trusted_fingerprints: check_certificate_fingerprint(conn, trusted_fingerprints) From 90c565c0c50d032b4088b9627285c370e5edd4dc Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 23 Feb 2016 21:56:52 +0100 Subject: [PATCH 08/11] Fix name. I thought I fixed that d922af10436b26074c003f8abdf29340fe9c6340, but I messed up with Git so hard I had to re-do that commit multiple times, forgetting a new thing each time; and apparently that one passed through. --- src/utils/net.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/net.py b/src/utils/net.py index 83e1e7f86..b6a17938b 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -166,7 +166,7 @@ else: # TLSv1.0 is the only TLS version Python < 2.7.9 supports # (besides SSLv2 and v3, which are known to be insecure) conn = ssl.wrap_socket(conn, certfile=certfile, ca_certs=ca_file, - ssl_version=ssl.ssl.PROTOCOL_TLSv1, verify_mode=ssl.CERT_NONE) + ssl_version=ssl.PROTOCOL_TLSv1, verify_mode=ssl.CERT_NONE) if trusted_fingerprints: check_certificate_fingerprint(conn, trusted_fingerprints) elif verify: From a702a95357f97a566a2c3329744579241b5f27e9 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Tue, 23 Feb 2016 21:59:18 +0100 Subject: [PATCH 09/11] Update recommended version in the README. [SKIP CI] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa286aa04..0411fdcd8 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Master branch: [![Build Status (master branch)](https://travis-ci.org/ProgVal/Li Testing branch: [![Build Status (testing branch)](https://travis-ci.org/ProgVal/Limnoria.png?branch=testing)](https://travis-ci.org/ProgVal/Limnoria) Limnoria supports CPython 2.6, 2.7, 3.2, 3.3, 3.4, 3.5, nightly; -and Pypy 2 and 3. It works best with CPython 3.3 and higher. +and Pypy 2 and 3. It works best with CPython 3.4 and higher. Python 2.5 and older versions are not supported. # Support From e1a86665aeb1febd8dc98e872f520e60a985b097 Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Wed, 24 Feb 2016 07:43:21 +0100 Subject: [PATCH 10/11] Remove unsupported option verify_mode to ssl.wrap_socket. --- src/utils/net.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/net.py b/src/utils/net.py index b6a17938b..74e2fa981 100644 --- a/src/utils/net.py +++ b/src/utils/net.py @@ -166,7 +166,7 @@ else: # TLSv1.0 is the only TLS version Python < 2.7.9 supports # (besides SSLv2 and v3, which are known to be insecure) conn = ssl.wrap_socket(conn, certfile=certfile, ca_certs=ca_file, - ssl_version=ssl.PROTOCOL_TLSv1, verify_mode=ssl.CERT_NONE) + ssl_version=ssl.PROTOCOL_TLSv1) if trusted_fingerprints: check_certificate_fingerprint(conn, trusted_fingerprints) elif verify: From 7c9b92bee5a67644651a43a097dee02180fb6222 Mon Sep 17 00:00:00 2001 From: James Lu Date: Wed, 24 Feb 2016 07:02:10 -0800 Subject: [PATCH 11/11] conf: fix help for verifyCertificates Closes #1216. --- src/conf.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/conf.py b/src/conf.py index 85db4410b..190a6d2bb 100644 --- a/src/conf.py +++ b/src/conf.py @@ -1179,10 +1179,8 @@ utils.web.proxy = supybot.protocols.http.proxy registerGroup(supybot.protocols, 'ssl') registerGlobalValue(supybot.protocols.ssl, 'verifyCertificates', registry.Boolean(False, _("""Determines whether server certificates - will be verified. Valid values are "required", "optional", and "none". - The default and recommended setting is "required", which checks the - server certificate is signed by a known Certificate Authority, and - aborts the connection if it is not."""))) + will be verified, which checks whether the server certificate is signed + by a known certificate authority, and aborts the connection if it is not."""))) ###