NTLM com cURL retorna 401

4

Meta : conectando-se a um servidor Exchange (EWS)
Método : cURL
Problema : Não é possível obter autenticação (NTLM ), solicita devoluções 401. 1

Parece haver um problema antigo e bem documentado 2 que começou com a mudança do cURL do OpenSSL para o NSS. Eu li que a implementação do NTLM é dependente do OpenSSL e, portanto, este movimento quebrou a autenticação NTLM.

O problema é mostrado abaixo, mas as partes importantes parecem ser as 401 e gss_init_sec_context() abaixo.

A coisa que não entendo é que minha versão atual:

  • Possui uma variante do OpenSSL de acordo com o link
  • suporta o NTLM de acordo com o mesmo link
  • Na verdade, usa essa variante (e não o NSS) de acordo com o log abaixo (ele diz libcurl/7.22.0 OpenSSL )
  • Não deve ser incomodado pelo bug vinculado conforme os pontos acima.
  • mas é afetado, como mostra o fato de que recebo o 401

Não sei como isso pode ser corrigido. Eu poderia encontrar muitas referências antigas (principalmente 2010) para este problema, mas nada de novo, e certamente nada com uma solução. Eu sei que as referências fornecidas (veja 2 ) mostram que isso pode funcionar com uma versão mais antiga (7.19), mas eu não sou capaz (nem desejoso) de fazer o downgrade para essa versão.

Várias implementações de comunicação do Exchange (EWS) usam o cURL para recuperar os arquivos do EWS (wsdl etc), portanto, tenho certeza que deve haver um método de trabalho, mas não consigo encontrá-lo. Alguém tem idéia do que eu posso fazer? Eu tenho outro bug, estou interpretando os fatos errados e essa ainda é a mesma situação fornecida nos links e nunca será corrigida?

1 O erro é mais ou menos assim:

curl https://*DOMAIN*/Exchange.asmx -w %{http_code} --ntlm -u *USERNAME* --verbose --show-error
Enter host password for user '*USERNAME':
* About to connect() to DOMAIN port 443 (#0)
*   Trying IP... connected
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using AES128-SHA
* Server certificate:
     *SNIP*
*        SSL certificate verify ok.
* Server auth using NTLM with user 'USERNAME'
> GET /EWS/Exchange.asmx HTTP/1.1
> Authorization: NTLM *snip*
> User-Agent: curl/7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: DOMAIN
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Server: Microsoft-IIS/7.5
< Set-Cookie: exchangecookie=xxx; expires=Wed, 17-Jul-2013 07:45:30 GMT; path=/; HttpOnly
< WWW-Authenticate: NTLM  *SNIP*
* gss_init_sec_context() failed: : Credentials cache file '/tmp/krb5cc_1005' not foundWWW-Authenticate: Negotiate
< X-Powered-By: ASP.NET
< Date: Tue, 17 Jul 2012 07:45:30 GMT
< Content-Length: 0
<
* Connection #0 to host DOMAIN left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):

2 por exemplo:

  • link
  • link
  • link
    • Este é o mesmo problema, mas não aborda o fato de que o problema NSS não deve estar presente no meu OpenSSL libcurl.

info de curl:

user@server:~$ curl -V
curl 7.22.0 (i686-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtmp rtsp smtp smtps telnet tftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
    
por Nanne 17.07.2012 / 10:15

2 respostas

1

Eu não sei ao certo por que, mas embora minha versão 7.22 não deva ser afetada por todo o problema do NTLM, parece que é.

A única solução parece ser usar uma versão antiga (< 7.19, tentei com 7.15) ou usar uma nova versão (tentei 7.26). Como dito, não posso fazer downgrade ou upgrade da própria libcurl apenas para este recurso. Isso significa que precisamos encontrar uma solução alternativa ...

Solução usada (aviso: hackear)

  1. Baixe e compile o curl que você deseja usar. Eu NÃO fiz isso como root // sudo isto porque eu não quero substituir a libcurl atual etc!

    wget http://curl.haxx.se/download/curl-7.26.0.zip
    ./configure --prefix=/local_path/
    make
    make install
    
  2. Teste o novo comando curl que acabamos de compilar: ele dá o 401, mas ao invés do gss_init_sec_context() você deve ver ele indo para um (no final) 302. Isso está ganhando. / p>

  3. A parte de hack: use este libcurl ao chamar seu script. Estamos trabalhando com um "app" PHP de terceiros (uma das razões pelas quais não estou feliz em mudar todos os curl libs) e, em vez de chamar isso diretamente, criamos um wrapper feio, mas que funciona, que chama algo assim :

    $se = shell_exec("LD_LIBRARY_PATH=/local_path/lib php /path/3rdparty.php");
    

Sim, isso tem desvantagens, e sim, isso é um exemplo de esqueleto (o que significa que você provavelmente deseja adicionar algumas coisas, como talvez o caminho original, por exemplo), mas os princípios básicos estão lá.

Não estou realmente orgulhoso disso, mas acho que mais pessoas são contidas pelo fato de não poderem simplesmente atualizar seu libcurl para uma versão aleatória e usarem algum tipo de plugin que usa, por exemplo, php-ews ou qualquer coisa criada no NTLMSoapClient .

Espero que haja outra opção, mas como esta é atualmente a única maneira de fazê-la funcionar, pensei em compartilhar.

    
por 18.07.2012 / 15:28
0

Para todos os usuários do Centos / RHEL 6.X, dê uma olhada em:

link

    
por 19.04.2013 / 17:53