Httpie: HTTPie ignora certificados do sistema

Criado em 9 jun. 2016  ·  20Comentários  ·  Fonte: httpie/httpie

HTTPie ignora certificados do sistema

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)

Para referência, curl funciona bem: curl https://example_using_my_ca.com

bug

Todos 20 comentários

Faria sentido usar ssl.get_default_verify_paths () para obter os caminhos padrão?

Eu proporia o seguinte comportamento:

Se --verify for passado um parâmetro diferente de não ou sim, passe o parâmetro para as solicitações.

Se --verify estiver definido como sim:
1) se REQUESTS_CA_BUNDLE estiver definido, passe True para verificar as solicitações.
2) a variável de ambiente elif ssl.get_default_verify_paths (). Openssl_cafile_env está definida, passe para a verificação de solicitações
4) a variável de ambiente elif ssl.get_default_verify_paths (). Openssl_capath_env é definida para passar para verificar as solicitações
5) elif ssl.get_default_verify_paths (). Capath não é Nenhum, passe para as solicitações de verificação
6) caso contrário, passe True para verificar as solicitações

mas observe que ssl.get_default_verify_paths está disponível apenas a partir de python3.4

@luv não só está disponível nas versões 3.4+ e 2.7.10+, mas também não funciona em todas as plataformas. É por isso que o Request está trabalhando em seu próprio problema para resolver isso para as pessoas. Por favor, pare de comentar constantemente sobre httpie. Essa é uma preocupação que existe em solicitações e não em httpie IMO.

@ sigmavirus24 wtf man? Não tenho ideia do que você quer dizer com comentar constantemente, mas enfim, vejo que você nem mesmo é um colaborador httpie. Presumo que seja apenas um troll estúpido: /

uma rápida olhada no código-fonte curl para ver como é uma implementação funcional ....

Desconsiderando todos os ifdefs amiga e VMS e o suporte para muitas bibliotecas ssl diferentes, é realmente muito estúpido e não está usando métodos de pesquisa do openssl X509_ * (como, por exemplo, usado em get_default_verify_paths () no módulo SSL do Python).

Em vez disso, curl simplesmente itera sobre um monte de locais conhecidos no momento da compilação (veja este m4dness https://github.com/curl/curl/blob/master/acinclude.m4#L2560) e então suporta explicitamente a substituição com (CURL_CA_BUNDLE e ) Variáveis ​​de ambiente SSL_CERT_DIR e SSL_CERT_FILE em tempo de execução (novamente não usando coisas como X509_get_default_cert_file_env ()). É isso aí.

Então, que tal implementar a mesma abordagem em Python puro? (Sim, parece rápido e sujo, mas funciona para curl!), Mas adicionando suporte para Windows (ssl.enum_certificates?) E OS X (não tenho certeza aqui, mas o python parece usar a biblioteca openssl fornecida pela apple no OS X 10.6+ então isso já deve estar bom!).

@luv obrigado pelo relatório, mas por favor seja mais respeitoso com os outros membros. @ sigmavirus24 é um desenvolvedor central de solicitações nas quais httpie se baseia para todo o HTTP e sem as quais ele nem existiria, então sua visão é extremamente relevante.

observe que isso não será corrigido nas solicitações até o lançamento 3.0.0 ... nem mesmo SSL_CERT_FILE terá suporte devido a possíveis problemas de compatibilidade https://github.com/kennethreitz/requests/pull/2903

btw. Eu não queria ser desrespeitoso, eu realmente pensei que ele / ela estava trollando :) Saí do meu caminho para ajudar a encontrar uma solução para um problema e alguém que nem uma vez contribuiu para o projeto (verifiquei os contribuidores de HTTPie porque fiquei realmente surpreso com a reação hostil) estava basicamente me dizendo para calar a boca: /

@luv, eu não estava dizendo para você calar a boca. Há 763 pessoas inscritas nesta edição. 100% deles _podem_ receber e-mails por isso (mas provavelmente é mais como 70% ou ~ 534). Isso significa que você gerou (nas 2 horas após a abertura do problema) cerca de 1602 e-mails (possivelmente mais ou menos). Em outras palavras, você está enviando spam para as pessoas com um fluxo de postagens conscientes como essa. A melhor maneira de documentar novas informações quando ninguém lhe respondeu é editando a postagem original.

Finalmente, as contribuições de código não são a única contribuição para um projeto. Se você quiser ver todas as contribuições em um projeto, você pode usar um projeto como o octohatrack . Respondi a várias solicitações relacionadas a bugs no httpie para @jkbrzt porque eles não têm tempo para acompanhar o desenvolvimento das solicitações. Quando vejo um bug relacionado a solicitações aqui, eu respondo porque 99% das vezes, ele já está sendo tratado. Felizmente para @jkbrzt , já fui tratado como mal (e algumas vezes pior) antes, então tenho a pele mais grossa.

Como uma observação lateral, "eles" tem tantos caracteres quanto "ele / ela" e é aplicável de forma muito mais geral, pois pode ser usado para se referir a uma única pessoa também.

então estamos consertando isso?

@jkbrzt Eu chamaria isso de recurso, não de bug. É intencional que Requests funcione de forma idêntica em Windows, * nixes e BSDs e, de fato, muitas distribuições de sistema de Requests ativamente removem esse comportamento e apontam para o armazenamento / pacote de certificados do sistema. Portanto, se os usuários precisarem desse comportamento, eles podem usar a versão de Requests empacotada por seus distribuidores de sistema com HTTPie (e possivelmente o sistema HTTPie empacotado).

Quanto a "consertar isso", depende da sua definição de consertado. Este é um recurso que _será_ adicionado às Solicitações. Nesse ponto, o HTTPie obterá o comportamento gratuitamente. Se, em vez disso, o HTTPie considerar isso uma prioridade mais alta (o que @jkbrzt pode fazer como achar melhor), eles podem duplicar o esforço de desenvolvimento para criar uma versão que faça isso antes.

Como parece que você está usando o linux, @luv , você pode tirar vantagem do fato de que sua distribuição do linux quase certamente tem uma versão do Requests que usa o armazenamento de certificados do sistema hoje. Requests são empacotados em todas as distribuições do Linux que verifiquei e praticamente todas essas distribuições usam seu armazenamento de certificados do sistema. Se este não for o caso, talvez você deva registrar um bug com o mantenedor do pacote Requests dessa distribuição.

mesmo problema com HTTPie instalado via apt (ubuntu 14.04lts)

@luv, isso é surpreendente porque eu sei com

Limpei todos os "pedidos" e versões "httpie" para verificar se a distribuição ubuntu do httpie é usada e você está certo, eu ainda estava usando o httpie do PyPI. Ubuntu httpie falha com "ImportError: não é possível importar o nome is_windows" que é um problema conhecido.

Acho que esqueci de executar "pip3 uninstall" e executei apenas "pip uninstall", pois antes de mais nada tive que usar o python3 para fazer o SSL funcionar.

Peço desculpas a 761 pessoas por "spam" com a descrição da minha configuração httpie.

Estou usando Gentoo Linux, httpie-0.9.9 e requests-2.18.4 (mais recente disponível no Gentoo) instalados em todo o sistema pelo gerenciador de pacotes, nenhuma outra versão instalada (nem tenho o pip instalado). Outras ferramentas (openssl s_client, sslclient, curl) detectam o certificado CA local instalado e funcionam bem, mas httpie falha:

$ 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/

Devo atualizar algo para que funcione?

@powerman Essa é uma questão mais apropriada para os redistribuidores gentoo desses pacotes.

@ sigmavirus24 Por que isso? Minha pergunta é que essas solicitações / versões httpie devem lidar com a lista de CA do sistema ou não. Se sim, então provavelmente algo está configurado incorretamente em meu sistema ou há um bug. Se não, qual versão preciso para fazer funcionar.

@powerman nada mudou. Nenhum dos dois oferece suporte aos pacotes de certificado do sistema, mas se você instalou ambos a partir do gerenciador de pacotes de sua distribuição, é provável que tenham corrigido o software para usá-los. Se você usou os pacotes disponíveis no Gentoo e eles não estão usando certificados de sistema, então é um problema do Gentoo.

Só vou adicionar um comentário adicional sobre isso: Eu uso um proxy que é projetado especificamente para que quando você fizer solicitações SSL, ele estabeleça um túnel seguro entre você e o proxy e depois outro entre o proxy e o destino. Ele faz isso para que eu possa monitorar com segurança o tráfego que passa pelo meu proxy para garantir que ninguém esteja tentando fazer algo desagradável e ocultá-lo. Infelizmente, isso significa que o certificado que httpie recebe de volta não é confiável (porque está na raiz do sistema, mas httpie não o usa).

Na verdade, posso reproduzir o mesmo problema no NixOS.

4+ anos depois ...

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Abdallah-Obaid picture Abdallah-Obaid  ·  4Comentários

pyvotal-cguers picture pyvotal-cguers  ·  5Comentários

hrj picture hrj  ·  5Comentários

jclem picture jclem  ·  6Comentários

ghost picture ghost  ·  5Comentários