Python demande des requêtes.exception.SSLError: [Errno 8] ssl.c: 504: L'EOF s'est produit en violation du protocole

je suis sur Ubuntu 12.10 avec OpenSSL 1.0.1 c, python 2.7.3, Demandes 1.0.3 et 1.0.4 (essayé les deux), et lorsque vous tentez de vous connecter au site web de la variable d'url avec le code suivant.

def SendInitialRequest(xmlmessage, redirecturl):
    url = 'https://centineltest.cardinalcommerce.com/maps/txns.asp'

    payload = 'cmpi_msg=' + ET.tostring(xmlmessage)
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
    }
    r = requests.post(url, data=payload, headers=headers, verify=None)
    print r.text

il lance l'erreur suivante:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "clams/libs/centinel/thinclient.py", line 134, in SendInitialRequest
    r = requests.post(url, data=payload, headers=headers, verify=None)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 87, in post
    return request('post', url, data=data, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 269, in request
    resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 364, in send
    r = adapter.send(request, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/adapters.py", line 163, in send
    raise SSLError(e)
requests.exceptions.SSLError: [Errno 8] _ssl.c:504: EOF occurred in violation of protocol

tenter la connexion avec openssl renvoie ce qui suit:

$ openssl s_client -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
140019346777760:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 226 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

si je le force à utiliser tls1 il fonctionne (sortie tronqué):

$ openssl s_client -tls1 -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
depth=2 C = US, O = "thawte, Inc.", OU = Certification Services Division, OU
verify error:num=20:unable to get local issuer certificate
verify return:0
---

j'ai vu de nombreux rapports de bogues pour ceci; cependant, je n'ai pas trouvé un moyen de le contourner en utilisant la bibliothèque des requêtes python. Toute aide serait grandement appréciée.

59
demandé sur Piotr Dobrogost 2012-12-31 17:51:58

10 réponses

Reposter ici pour d'autres de la demande de la page :

Requests " ne supporte pas de faire cela avant la version 1. Après la version 1, Vous êtes censé sous-classe le HTTPAdapter, comme suit:

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl

class MyAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       ssl_version=ssl.PROTOCOL_TLSv1)

quand vous avez fait cela, vous pouvez le faire:

import requests
s = requests.Session()
s.mount('https://', MyAdapter())

toute requête via cet objet de session utilisera alors TLSv1.

43
répondu jasonamyers 2014-07-11 15:50:54

paramètre verify=False ne fait que sauter la vérification du certificat du serveur, mais ne permettra pas de résoudre les erreurs de protocole SSL.

ce problème est probablement dû au fait que SSLv2 est désactivé sur le serveur web, mais Python 2.x essaie d'établir une connexion avec PROTOCOL_SSLv23 par défaut. Cela se produit à https://github.com/python/cpython/blob/360aa60b2a36f5f6e9e20325efd8d472f7559b1e/Lib/ssl.py#L1057

Vous pouvez singe-patch SSL.wrap_socket () dans le module ssl en remplaçant le paramètre mot-clé ssl_version. Le code suivant peut être utilisé comme tel. Mettre ceci au début de votre programme avant de faire toute demande.

import ssl
from functools import wraps
def sslwrap(func):
    @wraps(func)
    def bar(*args, **kw):
        kw['ssl_version'] = ssl.PROTOCOL_TLSv1
        return func(*args, **kw)
    return bar

ssl.wrap_socket = sslwrap(ssl.wrap_socket)
34
répondu chnrxn 2015-02-19 16:34:33

installation des options du paquet "sécurité" pour requests résolu pour moi:

sudo apt-get install libffi-dev

sudo pip install-U des demandes[de sécurité]

21
répondu Ricardo Cabral 2016-02-15 21:35:38

c'est un bug connu, vous pouvez le contourner avec un hack:

ouvrez site-packages/requests/packages/urllib3/connectionpool.py (ou faites une copie locale des requêtes à l'intérieur de votre propre projet), et changez le bloc qui dit:

def connect(self):
    # Add certificate verification
    sock = socket.create_connection((self.host, self.port), self.timeout)

    # Wrap socket using verification with the root certs in
    # trusted_root_certs
    self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
                                cert_reqs=self.cert_reqs,
                                ca_certs=self.ca_certs,
                                server_hostname=self.host,
                                ssl_version=self.ssl_version)

à:

def connect(self):
    # Add certificate verification
    sock = socket.create_connection((self.host, self.port), self.timeout)

    # Wrap socket using verification with the root certs in
    # trusted_root_certs
    self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
                                cert_reqs=self.cert_reqs,
                                ca_certs=self.ca_certs,
                                server_hostname=self.host,
                                ssl_version=ssl.PROTOCOL_TLSv1)

sinon, je suppose qu'il y a un contrôleur quelque part qui est moins hacky, mais je n'ai pas pu en trouver un avec quelques regards.

NOTE : sidenote, requests de PIP (1.0.4) sur un MacOS ne fonctionne qu'avec l'URL que vous avez fournie.

5
répondu favoretti 2012-12-31 14:07:49

j'ai rencontré cette erreur, et le correctif semble désactiver SNI, ce que Python 2.7 ne supporte pas:

http://bugs.python.org/issue5639

urllib3 on python 2.7 SNI error on Google App Engine

3
répondu Chris Pushbullet 2017-05-23 11:54:59

pour les gens qui ne peuvent pas obtenir au-dessus des corrections de travail.

a dû changer de fichier ssl.py pour arranger ça. Rechercher la fonction create_default_context et modifier la ligne:

context = SSLContext(PROTOCOL_SSLv23)

à

context = SSLContext(PROTOCOL_TLSv1)

peut-être que quelqu'un peut créer une solution plus facile sans éditer ssl.py Je ne sais pas.

3
répondu Zhack 2016-08-31 13:39:08

j'ai eu le même problème:

raise SSLError (e)

demande.exception.SSLError: [Errno 8] _ssl.c:504: EOF eu lieu en violation du protocole

j'ai fait courir fiddler, j'ai arrêté la capture de fiddler et je n'ai pas vu cette erreur. Peut-être parce que de violoneux.

2
répondu fd98279 2014-07-11 15:51:15

malheureusement, la réponse acceptée n'a pas fonctionné pour moi. Comme solution temporaire, vous pouvez également utiliser verify=False lorsque vous vous connectez au site Web sécurisé.

From Python Requests giving up SSLError

requests.get('https://example.com', verify=True)
0
répondu bibstha 2017-05-23 12:18:22

j'ai eu cette erreur en me connectant à un serveur MQTT RabbitMQ via TLS. Je suis assez sûr que le serveur est cassé mais de toute façon il a fonctionné avec OpenSSL 1.0.1, mais pas OpenSSL 1.0.2.

vous pouvez vérifier votre version en Python en utilisant ceci:

import ssl
ssl.OPENSSL_VERSION

Je ne suis pas sûr de savoir comment déclasser OpenSSL en Python (il semble être lié statiquement sur Windows au moins), à part utiliser une ancienne version de Python.

0
répondu Timmmm 2016-04-13 15:27:17

j'avais un problème similaire et je pense que si nous ignorons simplement la vérification ssl fonctionnera comme charme comme il a fonctionné pour moi. Donc se connecter au serveur avec le schéma https mais en leur demandant de ne pas vérifier le certificat.

par requests . Il suffit de mentionner verify=False au lieu de None

    requests.post(url, data=payload, headers=headers, verify=False)

en Espérant que cela fonctionne pour ceux qui ont besoin :).

0
répondu MaNKuR 2017-06-27 07:36:43