2015-05-26 8 views
5

Próbuję wykonać lokalne połączenie HTTPS z api XMLRPC. Od uaktualnienia do Python 2.7.9 że enable by default certificates verification, mam CERTIFICATE_VERIFY_FAILED błąd, gdy używam mój APIwyłącza domyślną weryfikację certyfikatu w 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)}] 

Czy istnieje pythonic sposób, aby wyłączyć domyślną weryfikację certyfikatu w języku Python 2.7.9?

ja nie naprawdę wiem, czy to dobrze, aby zmienić „prywatny” atrybut globalny SSL (ssl._create_default_https_context = ssl._create_unverified_context)

Odpowiedz

16

Trzeba zapewnić niepotwierdzone kontekstu SSL, wykonaną ręcznie lub przy użyciu prywatnych _create_unverified_context function() z SSL moduł:

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() 

Uwaga: ten kod działa tylko z python> = 2.7.9 (context parametr został dodany w Pythonie 2.7.9)

Jeśli chcesz mieć kod zgodny z poprzednim Pyth od wersji, trzeba użyć parametru 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

Przynajmniej dla Pytho n 2.7.6 drugie rozwiązanie też nie działa, ponieważ 'ssl' nie ma funkcji' _create_unverified_context() 'i z tego, co widzę w kodzie źródłowym, ani Python 2.7.8. – Adaephon

+0

Tak, jesteś prawdziwy @Adaephon, ale nie miałem możliwości testowania ze starszą wersją Pythona, kiedy napisałem tę linię. Myślę, że prawidłowym sposobem obsługi kompatybilności i nie używania funkcji prywatnej jest ręczne tworzenie kontekstu _unverified_. Prostszym rozwiązaniem jest przetestowanie istnienia tej funkcji. –

-1

z Pythona 2.6.6 na przykład:

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

To działa dla mnie ...

1

Jest możliwe, aby wyłączyć weryfikację za pomocą publiczne interfejsy API dostępne w Pythonie 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() 
Powiązane problemy