目标:连接到 Exchange 服务器 (EWS)
方法:卷曲
问题:无法获得身份验证(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
- 根据下面的日志(它说
libcurl/7.22.0 OpenSSL
)实际上使用了这个变体(而不是 NSS) - 根据上述几点,不应该被链接的错误所困扰。
- 但确实受到影响,因为我收到了 401
我不确定如何修复这个问题。我找到了很多关于这个问题的旧参考资料(大部分是 2010 年的),但没有新的,当然也没有解决方案。我知道提供的参考资料(见2)表明这可能适用于旧版本(7.19),但我无法(也不愿意)降级到该版本。
Exchange 通信 (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 :
- https://bugs.launchpad.net/ubuntu/+source/curl/+bug/675974
- https://bugzilla.redhat.com/show_bug.cgi?id=603783
- https://stackoverflow.com/questions/4341368/curl-always-returns-401-with-ntlm
- 这是同样的问题,但没有解决该
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
答案1
我不太清楚为什么,但是虽然我的 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
。
我希望以后还有其他选择,但由于这是目前让它“发挥作用”的唯一方法,所以我想分享一下。
答案2
所有 Centos /RHEL 6.X 用户请查看: