Created
October 16, 2014 15:22
-
-
Save flandr/74be22d1c3d7c1dfefdd to your computer and use it in GitHub Desktop.
Forcing TLS in Python's urllib2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Python 2.6's urllib2 does not allow you to select the TLS dialect, | |
# and by default uses a SSLv23 compatibility negotiation implementation. | |
# Besides being vulnerable to POODLE, the OSX implementation doesn't | |
# work correctly, failing to connect to servers that respond only to | |
# TLS1.0+. These classes help set up TLS support for urllib2. | |
class TLS1Connection(httplib.HTTPSConnection): | |
"""Like HTTPSConnection but more specific""" | |
def __init__(self, host, **kwargs): | |
httplib.HTTPSConnection.__init__(self, host, **kwargs) | |
def connect(self): | |
"""Overrides HTTPSConnection.connect to specify TLS version""" | |
# Standard implementation from HTTPSConnection, which is not | |
# designed for extension, unfortunately | |
sock = socket.create_connection((self.host, self.port), | |
self.timeout, self.source_address) | |
if getattr(self, '_tunnel_host', None): | |
self.sock = sock | |
self._tunnel() | |
# This is the only difference; default wrap_socket uses SSLv23 | |
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, | |
ssl_version=ssl.PROTOCOL_TLSv1) | |
class TLS1Handler(urllib2.HTTPSHandler): | |
"""Like HTTPSHandler but more specific""" | |
def __init__(self): | |
urllib2.HTTPSHandler.__init__(self) | |
def https_open(self, req): | |
return self.do_open(TLS1Connection, req) | |
# Override default handler | |
urllib2.install_opener(urllib2.build_opener(TLS1Handler())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks a lot!