2015-05-26 75 views
5

我試圖建立一個本地HTTPS連接到XMLRPC api。自從我升級到2.7.9蟒是enable by default certificates verification,我得到了一個錯誤CERTIFICATE_VERIFY_FAILED當我用我的API禁用python中的默認證書驗證2.7.9

>>> test=xmlrpclib.ServerProxy('https://admin:[email protected]: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)}] 

確實存在一個Python的方式在Python 2.7.9禁用默認證書驗證?

我不真的知道它的好,變「私」全球SSL屬性(ssl._create_default_https_context = ssl._create_unverified_context

回答

16

你必須提供一個未經驗證SSL上下文,手工建造或利用SSL私有函數_create_unverified_context()模塊:

import xmlrpclib 
import ssl 

test = xmlrpclib.ServerProxy('https://admin:[email protected]:9999/API', 
          verbose=False, use_datetime=True, 
          context=ssl._create_unverified_context()) 
test.list_satellites() 

注:此代碼只對Python> = 2.7.9(在Python 2.7.9加入context參數)

如果你想與以前Pyth兼容的代碼在版本,你必須使用transport參數:

import xmlrpclib 
import ssl 

context = hasattr(ssl, '_create_unverified_context') and ssl._create_unverified_context() \ 
      or None 
test = xmlrpclib.ServerProxy('https://admin:[email protected]:9999/API', 
          verbose=False, use_datetime=True, 
          transport=xmlrpclib.SafeTransport(use_datetime=True, 
                   context=context)) 
test.list_satellites() 
+2

至少在Pytho 2.7.6第二種解決方案也不起作用,因爲'ssl'沒有函數'_create_unverified_context()',並且從我在源代碼中可以看到的東西,Python 2.7.8也沒有。 – Adaephon

+0

是的,你是真正的@Adaephon,但是當我寫這些行時,我沒有可能用老的Python版本進行測試。我認爲正確的方式來處理兼容性,而不是使用私人功能,是手工製作我們的_unverified_上下文。更簡單的解決方案是測試這個函數的存在。 –

-1

使用Python 2.6.6例如:

s = xmlrpclib.ServerProxy('https://admin:[email protected]:9999/API', transport=None, encoding=None, verbose=0,allow_none=0, use_datetime=0) 

它爲我...

1

有可能使用禁用驗證公衆ssl API的現有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:[email protected]:9999/API', 
          verbose=False, use_datetime=True, 
          context=ssl_ctx) 
test.list_satellites()