From a2de4a2c023ac3947bb7c06f90c7dfc2327d4a08 Mon Sep 17 00:00:00 2001 From: Fabien ZARIFIAN Date: Sat, 22 Sep 2018 16:09:35 +0200 Subject: [PATCH 1/4] SNI support #523 as it mentionned on : https://docs.python.org/3/library/ssl.html#socket-creation Since Python 3.2 and 2.7.9, it is recommended to use the SSLContext.wrap_socket() of an SSLContext instance to wrap sockets as SSLSocket objects. The helper functions create_default_context() returns a new context with secure default settings. The old wrap_socket() function is deprecated since it is both inefficient and has no support for server name indication (SNI) and hostname matching. --- raven/utils/http.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/raven/utils/http.py b/raven/utils/http.py index f0d14a0c4..3c604f62a 100644 --- a/raven/utils/http.py +++ b/raven/utils/http.py @@ -26,21 +26,36 @@ def __init__(self, *args, **kwargs): httplib.HTTPConnection.__init__(self, *args, **kwargs) def connect(self): - sock = socket.create_connection( - address=(self.host, self.port), - timeout=self.timeout, - ) - if self._tunnel_host: - self.sock = sock - self._tunnel() + # https://docs.python.org/3/library/ssl.html#socket-creation + if sys.version_info > (2, 7, 9) or sys.version_info > (3, 2): + context = ssl.create_default_context() + context.verify_mode = ssl.CERT_REQUIRED - self.sock = ssl.wrap_socket( - sock, ca_certs=ca_certs, cert_reqs=ssl.CERT_REQUIRED) + sock = socket.create_connection( + address=(self.host, self.port), + timeout=self.timeout) + + if self._tunnel_host: + self.sock = sock + self._tunnel() + + self.sock = context.wrap_socket(sock, server_hostname=self.host) + else: + sock = socket.create_connection( + address=(self.host, self.port), + timeout=self.timeout, + ) + if self._tunnel_host: + self.sock = sock + self._tunnel() + + self.sock = ssl.wrap_socket( + sock, ca_certs=ca_certs, cert_reqs=ssl.CERT_REQUIRED) if assert_hostname is not None: match_hostname(self.sock.getpeercert(), self.assert_hostname or self.host) - + class ValidHTTPSHandler(urllib2.HTTPSHandler): def https_open(self, req): return self.do_open(ValidHTTPSConnection, req) From b3b96f2af15fb97f0534ff33a2b4efdf2032b1cc Mon Sep 17 00:00:00 2001 From: Fabien ZARIFIAN Date: Sat, 22 Sep 2018 16:56:12 +0200 Subject: [PATCH 2/4] Update http.py --- raven/utils/http.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/raven/utils/http.py b/raven/utils/http.py index 3c604f62a..88f49ac42 100644 --- a/raven/utils/http.py +++ b/raven/utils/http.py @@ -28,23 +28,23 @@ def __init__(self, *args, **kwargs): def connect(self): # https://docs.python.org/3/library/ssl.html#socket-creation if sys.version_info > (2, 7, 9) or sys.version_info > (3, 2): - context = ssl.create_default_context() - context.verify_mode = ssl.CERT_REQUIRED - sock = socket.create_connection( address=(self.host, self.port), - timeout=self.timeout) + timeout=self.timeout, + ) if self._tunnel_host: self.sock = sock self._tunnel() + context = ssl.create_default_context(cafile=ca_certs) self.sock = context.wrap_socket(sock, server_hostname=self.host) else: sock = socket.create_connection( address=(self.host, self.port), timeout=self.timeout, ) + if self._tunnel_host: self.sock = sock self._tunnel() @@ -52,10 +52,7 @@ def connect(self): self.sock = ssl.wrap_socket( sock, ca_certs=ca_certs, cert_reqs=ssl.CERT_REQUIRED) - if assert_hostname is not None: - match_hostname(self.sock.getpeercert(), - self.assert_hostname or self.host) - + class ValidHTTPSHandler(urllib2.HTTPSHandler): def https_open(self, req): return self.do_open(ValidHTTPSConnection, req) From a0d564d95b6826cf0fcb3590ef70de2f9c7241fe Mon Sep 17 00:00:00 2001 From: Fabien ZARIFIAN Date: Sat, 22 Sep 2018 17:07:59 +0200 Subject: [PATCH 3/4] Missing code for hostname check --- raven/utils/http.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/raven/utils/http.py b/raven/utils/http.py index 88f49ac42..bc4db4112 100644 --- a/raven/utils/http.py +++ b/raven/utils/http.py @@ -52,6 +52,10 @@ def connect(self): self.sock = ssl.wrap_socket( sock, ca_certs=ca_certs, cert_reqs=ssl.CERT_REQUIRED) + if assert_hostname is not None: + match_hostname(self.sock.getpeercert(), + self.assert_hostname or self.host) + class ValidHTTPSHandler(urllib2.HTTPSHandler): def https_open(self, req): From 9e829b53b9954a26ef4d20280e2b09d9f8c3e4a3 Mon Sep 17 00:00:00 2001 From: Fabien ZARIFIAN Date: Sat, 22 Sep 2018 17:15:15 +0200 Subject: [PATCH 4/4] flake8 E303 too many blank lines (2) raven/utils/http.py:60:5: E303 too many blank lines (2) --- raven/utils/http.py | 1 - 1 file changed, 1 deletion(-) diff --git a/raven/utils/http.py b/raven/utils/http.py index bc4db4112..b6226f633 100644 --- a/raven/utils/http.py +++ b/raven/utils/http.py @@ -56,7 +56,6 @@ def connect(self): match_hostname(self.sock.getpeercert(), self.assert_hostname or self.host) - class ValidHTTPSHandler(urllib2.HTTPSHandler): def https_open(self, req): return self.do_open(ValidHTTPSConnection, req)