-
-
Save szepnapot/fc0ba3c9d104cc83808588d00886a711 to your computer and use it in GitHub Desktop.
Handler for authenticating HTTPS connections with urllib2. (Python 2.x) Note that the 'ciphers' option in ssl.wrap_socket is python 2.7 only.
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
import logging, urllib2 | |
import https | |
client_cert_key = None # file path | |
client_cert_pem = None #file path | |
ca_certs = None # file path | |
handlers = [] | |
handlers.append( HTTPSClientAuthHandler( | |
key = client_cert_key, | |
cert = client_cert_pem, | |
ca_certs = ca_certs, | |
ssl_version = ssl.PROTOCOL_TLSv1, | |
ciphers = 'TLS_RSA_WITH_AES_256_CBC_SHA' ) ) | |
http = urllib2.build_opener(*handlers) | |
# do it! | |
resp = http.open('https://something.com') | |
data = resp.read() | |
resp.close() |
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
import urllib2, httplib, ssl, socket | |
DEFAULT_HTTP_TIMEOUT = 10 #seconds | |
# http://code.activestate.com/recipes/577548-https-httplib-client-connection-with-certificate-v/ | |
# http://stackoverflow.com/questions/1875052/using-paired-certificates-with-urllib2 | |
class HTTPSClientAuthHandler(urllib2.HTTPSHandler): | |
''' | |
Allows sending a client certificate with the HTTPS connection. | |
This version also validates the peer (server) certificate since, well... | |
WTF IS THE POINT OF SSL IF YOU DON"T AUTHENTICATE THE PERSON YOU"RE TALKING TO!??! | |
''' | |
def __init__(self, key=None, cert=None, ca_certs=None, ssl_version=None, ciphers=None): | |
urllib2.HTTPSHandler.__init__(self) | |
self.key = key | |
self.cert = cert | |
self.ca_certs = ca_certs | |
self.ssl_version = ssl_version | |
self.ciphers = ciphers | |
def https_open(self, req): | |
# Rather than pass in a reference to a connection class, we pass in | |
# a reference to a function which, for all intents and purposes, | |
# will behave as a constructor | |
return self.do_open(self.get_connection, req) | |
def get_connection(self, host, timeout=DEFAULT_HTTP_TIMEOUT): | |
return HTTPSConnection( host, | |
key_file = self.key, | |
cert_file = self.cert, | |
timeout = timeout, | |
ciphers = self.ciphers, | |
ca_certs = self.ca_certs, | |
ssl_version = self.ssl_version ) | |
class HTTPSConnection(httplib.HTTPSConnection): | |
''' | |
Overridden to allow peer certificate validation, configuration | |
of SSL/ TLS version and cipher selection. See: | |
http://hg.python.org/cpython/file/c1c45755397b/Lib/httplib.py#l1144 | |
and `ssl.wrap_socket()` | |
''' | |
def __init__(self, host, **kwargs): | |
self.ciphers = kwargs.pop('ciphers',None) | |
self.ca_certs = kwargs.pop('ca_certs',None) | |
self.ssl_version = kwargs.pop('ssl_version',ssl.PROTOCOL_SSLv23) | |
httplib.HTTPSConnection.__init__(self,host,**kwargs) | |
def connect(self): | |
sock = socket.create_connection( (self.host, self.port), self.timeout ) | |
if self._tunnel_host: | |
self.sock = sock | |
self._tunnel() | |
# with open(self.ca_certs,'r') as test: | |
# logging.info('+++++++++++++++ CA CERTS: %s ++++++++++++++', self.ca_certs) | |
self.sock = ssl.wrap_socket( sock, | |
keyfile = self.key_file, | |
certfile = self.cert_file, | |
ca_certs = self.ca_certs, | |
# ciphers = self.ciphers, # DOH! This is Python 2.7-only! | |
cert_reqs = ssl.CERT_REQUIRED if self.ca_certs else ssl.CERT_NONE, | |
ssl_version = self.ssl_version ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment