Цель: подключение к серверу Exchange (EWS)
Метод: cURL
Проблема: Не удается пройти проверку подлинности (NTLM), запрос возвращает 401.1
Кажется, есть старый, хорошо задокументированный 2 проблема, которая началась с переходом cURL с OpenSSL на NSS. Я читал, что реализация NTLM зависит от OpenSSL, и поэтому этот шаг нарушил аутентификацию NTLM.
Проблема показана ниже, но важные детали кажутся возвращенными 401
и gss_init_sec_context()
ниже этого.
Я не понимаю, что моя текущая версия:
libcurl/7.22.0 OpenSSL
)Я не знаю, как это можно исправить. Я смог найти много старых (в основном 2010 года) ссылок на эту проблему, но ничего нового и, конечно, ничего с решением. Я знаю, что предоставил ссылки (см. 2) показывают, что это может работать с более старой версией (7.19), но я не могу (и не хочу) перейти на эту версию.
Несколько реализаций обмена данными (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 например :
NSS
проблема не должна присутствовать в моем OpenSSL
libcurl.информация о завитке:
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
Я не совсем уверен, почему, но хотя моя версия 7.22 не должна зависеть от всей проблемы NTLM, похоже, что это так.
Единственное решение - использовать старую (<7.19, я пробовал с 7.15) версию или использовать новую версию (я пробовал 7.26). Как уже было сказано, я не могу понизить или обновить сам libcurl только для этой функции. Это означает, что нам нужно найти обходной путь ...
Используется обходной путь (предупреждение: готовится взлом)
Загрузите и скомпилируйте curl, который хотите использовать. Я НЕ делал это как root // sudo
это потому, что я не хочу заменять текущий libcurl и т. д.!
wget http://curl.haxx.se/download/curl-7.26.0.zip
./configure --prefix=/local_path/
make
make install
Испытайте новый curl
команда, которую мы только что скомпилировали: она дает 401, но вместо gss_init_sec_context()
вы должны увидеть, что он идет к (в конце) 302. Это выигрыш.
Часть взлома: используйте это libcurl
при вызове вашего скрипта. Мы работаем со сторонним «приложением» PHP (одна из причин, по которой я не доволен изменением всех библиотек curl), и вместо того, чтобы напрямую вызывать это, мы делаем уродливую, но работающую оболочку, которая вызывает что-то вроде этого :
$se = shell_exec("LD_LIBRARY_PATH=/local_path/lib php /path/3rdparty.php");
Да, у этого есть недостатки, и да, это немного скелетный пример (что означает, что вы, вероятно, захотите добавить некоторые вещи, например, например, исходный путь), но основы вроде как там.
Не очень горжусь этим, но я думаю, что больше людей сдерживает тот факт, что они не могут просто пойти и обновить свои libcurl
к случайной версии и используют какой-то плагин, например, php-ews
, или что-нибудь, построенное на NTLMSoapClient
.
Я надеюсь, что в будущем есть еще один вариант, но, поскольку в настоящее время это единственный способ заставить его «работать», я решил поделиться.
Для всех пользователей Centos / RHEL 6.X обратите внимание на: