Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

disable default certificate verification in python 2.7.9

Tags:

python

ssl

I try to make a local HTTPS connection to a XMLRPC api. Since I upgrade to python 2.7.9 that enable by default certificates verification, I got a CERTIFICATE_VERIFY_FAILED error when I use my API

>>> test=xmlrpclib.ServerProxy('https://admin:bz15h9v9n@localhost:9999/API',verbose=False, use_datetime=True)
>>> test.list_satellites()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/xmlrpclib.py", line 1233, in __call__
    return self.__send(self.__name, args)
  File "/usr/local/lib/python2.7/xmlrpclib.py", line 1591, in __request
    verbose=self.__verbose
  File "/usr/local/lib/python2.7/xmlrpclib.py", line 1273, in request
    return self.single_request(host, handler, request_body, verbose)
  File "/usr/local/lib/python2.7/xmlrpclib.py", line 1301, in single_request
    self.send_content(h, request_body)
  File "/usr/local/lib/python2.7/xmlrpclib.py", line 1448, in send_content
    connection.endheaders(request_body)
  File "/usr/local/lib/python2.7/httplib.py", line 997, in endheaders
    self._send_output(message_body)
  File "/usr/local/lib/python2.7/httplib.py", line 850, in _send_output
    self.send(msg)
  File "/usr/local/lib/python2.7/httplib.py", line 812, in send
    self.connect()
  File "/usr/local/lib/python2.7/httplib.py", line 1212, in connect
    server_hostname=server_hostname)
  File "/usr/local/lib/python2.7/ssl.py", line 350, in wrap_socket
    _context=self)
  File "/usr/local/lib/python2.7/ssl.py", line 566, in __init__
    self.do_handshake()
  File "/usr/local/lib/python2.7/ssl.py", line 788, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)
>>> import ssl
>>> ssl._create_default_https_context = ssl._create_unverified_context
>>> test.list_satellites()
[{'paired': True, 'serial': '...', 'enabled': True, 'id': 1, 'date_paired': datetime.datetime(2015, 5, 26, 16, 17, 6)}]

Does exists a pythonic way to disable default certificate verification in python 2.7.9 ?

I don't realy know if it's good to change "private" global SSL attribute (ssl._create_default_https_context = ssl._create_unverified_context)

like image 399
Guillaume Vincent Avatar asked May 26 '15 14:05

Guillaume Vincent


3 Answers

You have to provide an unverified SSL context, constructed by hand or using the private function _create_unverified_context() from ssl module:

import xmlrpclib
import ssl

test = xmlrpclib.ServerProxy('https://admin:bz15h9v9n@localhost:9999/API',
                             verbose=False, use_datetime=True, 
                             context=ssl._create_unverified_context())
test.list_satellites()

Note: this code only works with python >= 2.7.9 (contextparameter was added in Python 2.7.9)

If you want to have a code compatible with previous Python version, you have to use the transport parameter:

import xmlrpclib
import ssl

context = hasattr(ssl, '_create_unverified_context') and ssl._create_unverified_context() \
          or None
test = xmlrpclib.ServerProxy('https://admin:bz15h9v9n@localhost:9999/API',
                             verbose=False, use_datetime=True, 
                             transport=xmlrpclib.SafeTransport(use_datetime=True, 
                                                               context=context))
test.list_satellites()
like image 167
Cédric Avatar answered Nov 13 '22 18:11

Cédric


I think another way to disable certificate verification could be:

import xmlrpclib
import ssl

s=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
s.verify_mode=ssl.CERT_NONE

test=xmlrpclib.Server('https://admin:bz15h9v9n@localhost:9999/API',verbose=0,context=s)
like image 30
Adnan Reza Avatar answered Nov 13 '22 20:11

Adnan Reza


It's possible to disable verification using the public ssl APIs existing on Python 2.7.9+:

import xmlrpclib
import ssl

ssl_ctx = ssl.create_default_context()
ssl_ctx.check_hostname = False
ssl_ctx.verify_mode = ssl.CERT_NONE
test = xmlrpclib.ServerProxy('https://admin:bz15h9v9n@localhost:9999/API',
                             verbose=False, use_datetime=True, 
                             context=ssl_ctx)
test.list_satellites()
like image 9
Benjamin Peterson Avatar answered Nov 13 '22 19:11

Benjamin Peterson