NTLM с cURL возвращает 401

Цель: подключение к серверу Exchange (EWS)
Метод: cURL
Проблема: не удается пройти проверку подлинности (NTLM), запрос возвращает 401. 1

Кажется, существует старая, хорошо документированная проблема, которая началась с перехода cURL с OpenSSL на NSS. Я читал, что реализация NTLM зависит от OpenSSL, и поэтому этот шаг нарушил аутентификацию NTLM.

Проблема показана ниже, но важными частями, кажется, возвращаются 401 и gss_init_sec_context() ниже этого.

Я не понимаю, что моя текущая версия:

  • Имеет вариант OpenSSL в соответствии с https://launchpad.net/ubuntu/+source/curl/7.22.0-3ubuntu4
  • поддерживает NTLM по той же ссылке
  • На самом деле использует этот вариант (а не NSS) в соответствии с журналом ниже (он говорит libcurl/7.22.0 OpenSSL)
  • Не должно беспокоить связанная ошибка согласно пунктам выше.
  • но это влияет, как показывает тот факт, что я получаю 401

Я не уверен, как это можно исправить. Я мог найти много старых (в основном 2010) ссылок на эту проблему, но ничего нового и, конечно же, ничего с решением. Я знаю, что предоставленные ссылки (см. 2) показывают, что это может работать с более старой версией (7.19), но я не могу (или не желаю) перейти на эту версию.

Несколько реализаций Exchange-Communication (EWS) используют cURL для получения файлов EWS (wsdl и т. Д.), Поэтому я уверен, что должен быть работающий метод, но я не могу его найти. Кто-нибудь знает, что я могу сделать? У меня есть другая ошибка, я неправильно истолковываю факты, и это все та же ситуация, что и в ссылках, и она никогда не будет исправлена?


1 Ошибка выглядит примерно так:

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 например:


скручиваемая информация:

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

2 ответа

Решение

Я не совсем уверен, почему, но хотя моя версия 7.22 не должна быть затронута всей проблемой NTLM, похоже, что это так.

Похоже, единственное решение - использовать старую (<7.19, я пробовал с 7.15) версию или использовать новую версию (я пробовал 7.26). Как я уже сказал, я не могу понизить или обновить сам libcurl только для этой функции. Это означает, что нам нужно найти обходной путь....

Обходной путь используется (предупреждение: взломать)

  1. Скачайте и скомпилируйте локон, который вы хотите использовать. Я НЕ делал это как root // sudo это потому что я не хочу заменять текущий libcurl и т.д!

    wget http://curl.haxx.se/download/curl-7.26.0.zip
    ./configure --prefix=/local_path/
    make
    make install
    
  2. Протестировать новый curl Команда, которую мы только что скомпилировали: она дает 401, но затем вместо gss_init_sec_context() Вы должны увидеть, как оно достигает (в конце) 302. Это выигрыш.

  3. Взломать часть: используйте это libcurl при вызове вашего скрипта. Мы работаем с сторонним PHP-приложением (одна из причин, по которой меня не устраивает изменение всех curl-библиотек), и вместо прямого вызова этого мы создаем уродливую, но работающую оболочку, которая вызывает что-то вроде этого:

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

Да, у этого есть недостатки, и да, это немного скелетный пример (имеется в виду, что вы, вероятно, захотите добавить некоторые вещи, например, может быть, оригинальный путь, например), но основы вроде бы есть.

Не очень горжусь этим, но я думаю, что все больше людей ограничены тем, что они не могут просто пойти и обновить свои libcurl к случайной версии и используют какой-то плагин, который использует, например, php-ewsили что-нибудь построить на NTLMSoapClient,

Я надеюсь, что есть еще один вариант в будущем, но так как в настоящее время это единственный способ заставить его работать, я решил поделиться.

Для всех пользователей Centos /RHEL 6.X обратите внимание на:

https://bugzilla.redhat.com/show_bug.cgi?id=953864

Другие вопросы по тегам