Httpie: HTTPie ignore les certificats système

Créé le 9 juin 2016  ·  20Commentaires  ·  Source: httpie/httpie

HTTPie ignore les certificats système

http --debug -j https://example_using_my_ca.com

HTTPie 0.9.3
HTTPie data: /home/lukas/.httpie
Requests 2.10.0
Pygments 1.6
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] linux

>>> requests.request(**{'allow_redirects': False,
 'auth': None,
 'cert': None,
 'data': '',
 'files': DataDict(),
 'headers': {'Accept': b'application/json',
             'Content-Type': b'application/json',
             'User-Agent': b'HTTPie/0.9.3'},
 'method': 'get',
 'params': ParamsDict(),
 'proxies': {},
 'stream': True,
 'timeout': 30,
 'url': 'https://example_using_my_ca.com',
 'verify': True})

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 578, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 351, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 814, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connection.py", line 289, in connect
    ssl_version=resolved_ssl_version)
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/util/ssl_.py", line 308, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/lib/python3.4/ssl.py", line 365, in wrap_socket
    _context=self)
  File "/usr/lib/python3.4/ssl.py", line 601, in __init__
    self.do_handshake()
  File "/usr/lib/python3.4/ssl.py", line 828, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/requests/adapters.py", line 403, in send
    timeout=timeout
  File "/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py", line 604, in urlopen
    raise SSLError(e)
requests.packages.urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/http", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.4/dist-packages/httpie/core.py", line 115, in main
    response = get_response(args, config_dir=env.config.directory)
  File "/usr/local/lib/python3.4/dist-packages/httpie/client.py", line 48, in get_response
    response = requests_session.request(**kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 585, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/requests/adapters.py", line 477, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

Pour référence, curl fonctionne bien: curl https://example_using_my_ca.com

bug

Tous les 20 commentaires

Serait-il judicieux d'utiliser ssl.get_default_verify_paths () pour obtenir les chemins par défaut?

Je proposerais le comportement suivant:

Si --verify reçoit un paramètre autre que no ou yes, transmettez le paramètre aux requêtes.

Si --verify est défini sur yes:
1) si REQUESTS_CA_BUNDLE est défini, transmettez True à la vérification des demandes.
2) La variable d'environnement elif ssl.get_default_verify_paths (). Openssl_cafile_env est définie, transmettez-la aux requêtes, vérifiez
4) La variable d'environnement elif ssl.get_default_verify_paths ().
5) elif ssl.get_default_verify_paths (). Capath n'est pas None, transmettez cela aux requêtes verify
6) sinon passer True aux demandes de vérification

mais veuillez noter que ssl.get_default_verify_paths n'est disponible que depuis python3.4

@luv n'est pas seulement disponible en 3.4+ et 2.7.10+, mais cela ne fonctionne pas sur toutes les plates-formes. C'est pourquoi requests travaille sur son propre problème pour résoudre ce problème pour les gens. Veuillez arrêter de commenter constamment sur httpie. C'est une préoccupation qui existe dans les demandes et non dans httpie IMO.

@ sigmavirus24 wtf homme? Aucune idée de ce que vous entendez par des commentaires constants, mais peu importe, je vois que vous n'êtes même pas un contributeur httpie. Je suppose juste un troll stupide: /

un rapide coup d'œil sur le code source de curl pour voir à quoi ressemble une implémentation fonctionnelle ...

Sans tenir compte de tous ces ifdefs amiga et VMS et de la prise en charge de nombreuses bibliothèques ssl différentes, c'est en fait assez stupide et il n'utilise pas les méthodes de recherche openssl X509_ * (comme, par exemple, utilisées dans get_default_verify_paths () dans le module SSL Python).

Au lieu de cela, curl itère simplement sur un tas d'emplacements connus au moment de la compilation (voir ce m4dness https://github.com/curl/curl/blob/master/acinclude.m4#L2560) puis prend explicitement en charge le remplacement avec (CURL_CA_BUNDLE et ) Variables d'environnement SSL_CERT_DIR et SSL_CERT_FILE au moment de l'exécution (encore une fois, sans utiliser des éléments tels que X509_get_default_cert_file_env ()). C'est ça.

Alors, qu'en est-il de la mise en œuvre de la même approche en python pur? (Oui, cela a l'air rapide et sale comme l'enfer mais cela fonctionne pour curl!) Mais en ajoutant le support pour Windows (ssl.enum_certificates?) Et OS X (pas sûr ici mais python semble utiliser la bibliothèque openssl fournie par Apple sur OS X 10.6+ donc ça devrait déjà être bien!).

@luv merci pour le rapport mais soyez plus respectueux envers les autres membres. @ sigmavirus24 est un développeur principal de requêtes sur lesquelles httpie s'appuie pour tout HTTP et sans lesquelles il n'existerait même pas, donc sa vision est extrêmement pertinente.

veuillez noter que cela ne sera pas corrigé dans les demandes jusqu'à la version 3.0.0 ... même SSL_CERT_FILE ne sera pas pris en charge en raison de problèmes de compatibilité possibles https://github.com/kennethreitz/requests/pull/2903

btw. Je ne voulais pas être irrespectueux, je pensais vraiment qu'il était à la traîne :) J'ai fait de mon mieux pour aider à trouver une solution à un problème et à quelqu'un qui n'a même pas contribué une seule fois au projet (j'ai vérifié les contributeurs de HTTPie parce que je a été vraiment surpris par une réaction aussi hostile) me disait en gros de me taire: /

@luv Je ne vous disais pas de vous taire. Il y a 763 personnes inscrites à ce numéro. 100% d'entre eux _pourraient_ recevoir des e-mails pour cela (mais c'est probablement plus comme 70% ou ~ 534). Cela signifie que vous avez généré (dans les 2 heures suivant l'ouverture du problème) ~ 1602 e-mails (peut-être plus ou moins). En d'autres termes, vous spammez les gens avec un flux de messages conscients comme celui-ci. La meilleure façon de documenter de nouvelles informations lorsque personne ne vous a répondu est de modifier le message d'origine.

Enfin, les contributions au code ne sont pas la seule contribution à un projet. Si vous voulez voir toutes les contributions sur un projet, vous pouvez utiliser un projet comme octohatrack . J'ai répondu à plusieurs requêtes liées à des bugs sur httpie pour @jkbrzt car ils n'ont pas tout à fait le temps de suivre le développement des requêtes. Quand je vois un bug lié aux requêtes ici, je réponds parce que 99% du temps, il est déjà traité. Heureusement pour @jkbrzt , j'ai déjà été mal traité (et parfois pire), donc j'ai une peau plus épaisse.

En remarque, «ils» sont autant de caractères que «s / he» et bien plus généralement applicable car il peut également être utilisé pour désigner une seule personne.

alors allons-nous résoudre ce problème?

@jkbrzt J'appellerais cela une fonctionnalité, pas un bug. Il est intentionnel que les requêtes fonctionnent de la même manière dans Windows, * nixes et BSD et en fait, de nombreuses distributions système de requêtes suppriment activement ce comportement et pointent vers le magasin / groupe de certificats système. Donc, si les utilisateurs ont besoin de ce comportement, ils peuvent utiliser la version des requêtes empaquetée par leurs distributeurs système avec HTTPie (et éventuellement le paquetage système HTTPie).

Quant à "faire réparer ce problème", cela dépend de votre définition de fixe. Il s'agit d'une fonctionnalité qui _will_ sera ajoutée aux demandes. À quel point HTTPie obtiendra le comportement gratuitement. Si HTTPie considère plutôt que c'est une priorité plus élevée (ce que @jkbrzt peut faire comme bon lui semble), ils peuvent dupliquer l'effort de développement pour créer une version qui le fasse plus tôt.

Comme il semble que vous utilisez Linux, @luv , vous pouvez profiter du fait que votre distribution de Linux a presque certainement une version de Requests qui utilise le magasin de certificats système aujourd'hui. Les requêtes sont incluses dans chaque distribution de Linux que j'ai vérifiée et à peu près chacune de ces distributions utilise leur magasin de certificats système. Si ce n'est pas le cas, vous devriez peut-être signaler un bogue avec le responsable du paquet Requests de cette distribution.

même problème avec HTTPie installé via apt (ubuntu 14.04lts)

@luv c'est surprenant car je sais

J'ai purgé toutes les versions "demandes" et "httpie" pour vérifier que la distribution ubuntu de httpie est utilisée et vous avez raison, j'utilisais toujours httpie de PyPI. Ubuntu httpie échoue avec "ImportError: impossible d'importer le nom is_windows" qui est un problème connu.

Je pense que j'ai oublié d'exécuter "pip3 uninstall" et que je n'ai exécuté que "pip uninstall" car j'ai dû utiliser python3 pour faire fonctionner ssl en premier lieu.

Je m'excuse auprès de 761 personnes de les "spammer" avec la description de ma configuration httpie.

J'utilise Gentoo Linux, httpie-0.9.9 et requests-2.18.4 (dernier disponible dans Gentoo) installés à l'échelle du système par le gestionnaire de paquets, aucune autre version installée (je n'ai même pas installé pip). D'autres outils (openssl s_client, sslclient, curl) détectent le certificat CA local installé et fonctionnent correctement, mais httpie échoue:

$ openssl s_client -quiet -connect localhost:8082                                              
depth=1 CN = Local CA home.lan
verify return:1
depth=0 CN = localhost
verify return:1
^C
$ http -v https://localhost:8082/                                                              

http: error: SSLError: HTTPSConnectionPool(host='localhost', port=8082): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",),)) while doing GET request to URL: https://localhost:8082/

Dois-je mettre à jour quelque chose pour que cela fonctionne?

@powerman C'est une question plus appropriée pour les redistributeurs gentoo de ces paquets.

@ sigmavirus24 Pourquoi est-ce? Ma question est que ces versions de requêtes / httpie sont censées gérer la liste des CA système ou non. Si oui, il y a probablement quelque chose de mal configuré sur mon système ou il y a un bogue. Si non, quelle version ai-je besoin pour le faire fonctionner.

@powerman rien n'a changé. Ni l'un ni l'autre ne prend en charge vos ensembles de certificats système, mais si vous avez installé les deux à partir du gestionnaire de packages de votre distribution, il est probable qu'ils aient corrigé le logiciel pour les utiliser. Si vous avez utilisé les packages disponibles dans Gentoo et qu'ils n'utilisent pas de certificats système, alors c'est un problème Gentoo.

Je vais juste ajouter un commentaire supplémentaire à ce sujet: j'utilise un proxy spécialement conçu pour que lorsque vous effectuez des requêtes SSL, il établit un tunnel sécurisé entre vous et le proxy, puis un autre entre le proxy et la destination. Il le fait pour que je puisse surveiller en toute sécurité le trafic passant par mon proxy pour m'assurer que personne n'essaie de faire quelque chose de méchant et de le cacher. Cela signifie malheureusement que le certificat récupéré par httpie n'est pas approuvé (car il se trouve à la racine du système, mais httpie ne l'utilise pas).

Je peux reproduire le même problème sur NixOS.

4+ ans plus tard ...

Cette page vous a été utile?
0 / 5 - 0 notes