【问题标题】:Build working libcurl with WinSSL, NTLM, HTTP2, SSH2 and IPv6 support构建具有 WinSSL、NTLM、HTTP2、SSH2 和 IPv6 支持的工作 libcurl
【发布时间】:2019-06-03 10:53:25
【问题描述】:

在我们的 PHP 应用程序中,我们需要以某种方式构建 PHP curl-extension,它支持以下功能:

  • WinSSL(访问 Windows 证书存储)
  • NTLM、基本和摘要式身份验证
  • HTTP/2 支持
  • SSH2 支持
  • IPv6 支持

我试图以某种方式构建 curl 来实现这一点:

  • 将其与 WinSSL 链接
  • 将其与 nghttp2 链接
  • 将其链接到 libssh2
  • 启用 IPv6

我是用命令行来做的:

nmake /f Makefile.vc mode=dll VC=15 ENABLE_WINSSL=yes DEBUG=no MACHINE=x64 ENABLE_SSPI=no WITH_NGHTTP2=dll WITH_ZLIB=static WITH_SSH2=static WITH_DEVEL=C:\curl\deps-x64

在 curls winbuild/ 子文件夹中。然后我根据结果编译了 PHP curl 扩展。

因此,在对提供基本、摘要、NTLM 和协商身份验证的 Web 服务(Exchange Web 服务)执行 HTTP 请求时,我有以下不正确的行为

  • 如果使用curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);,一切正常。

  • 如果使用curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);,一切正常。

  • 如果使用curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM | CURLAUTH_BASIC);身份验证失败

失败的请求包含一个太短的 NTLM 令牌(似乎在某些时候被切断)。一些谷歌搜索表明这可能是由于 curl 被编译为使用 SSPI。但是,我无法禁用 SSPI,因为 WinSSL 需要它。

有人知道这个问题的解决方案吗?如何获得满足上述所有要求的 php-curl 扩展?

【问题讨论】:

  • 是身份验证协商问题还是 libcurl 错误?您可以为CURLAUTH_NTLM | CURLAUTH_BASIC 发布 CURLOPT_VERBOSE 日志吗?
  • TFM 说您需要 SSPI 才能在 Windows 上执行 NTLM,所以我认为不会是这样。根据@Mason.Chase 的评论,我将通过使用包装函数并执行 doNTLM() || 来解决它doBasicHTTP() 与将两个选项传递给 curl。
  • @ivanivan 失败的调用是由外部库完成的,因此我们不能在代码中真正拆分 NTLM 和基本身份验证。作为最后的手段,我们可以分叉库并更改代码,但这会给我们的软件增加额外的维护开销。我宁愿有一个解决方案,使准确的呼叫工作:(
  • 我不确定 CURL 是否可以在同一连接中同时执行 NTLM 和 Basic,因此忽略任何 SSL,NTLM 在将其发送到服务器之前需要加密和 Base64 编码,服务器将提供 Base64 编码数据当您尝试连接时,这可能是您的问题尝试首先打开连接并阅读标题以查看它首先需要什么方法基本或 NTLM。 davenport.sourceforge.net/ntlm.html#ntlmHttpAuthentication
  • @MartinBarker:服务器发送多个不同的 WWW-Authenticate 标头,curl 应该选择适当的一个并进行身份验证。 curl 可以从中选择适当的选项,这取决于问题中的选项,因此在失败的情况下 curl 应该选择 NTLM 或 Basic auth,并选择 NTLM。但是该身份验证失败,因为 curl 生成的 Authorization 标头已损坏

标签: php libcurl php-curl


【解决方案1】:

我相信这里的 LibCurl 可以满足这一切:

https://curl.haxx.se/windows

使用这个文件:

#include <curl/curl.h>
#include <stdio.h>
int main() {
   curl_version_info_data *o = curl_version_info(CURLVERSION_NOW); 
   printf("SSL: %s\n", o->ssl_version);
   printf("NTLM: %d\n", o->features & CURL_VERSION_NTLM);
   printf("HTTP/2: %d\n", o->features & CURL_VERSION_HTTP2);
   printf("SSH2: %s\n", o->libssh_version);
   printf("IPv6: %d\n", o->features & CURL_VERSION_IPV6);
}

构建:

cc https.c `
'-Icurl-7.70.0-win64-mingw\include' `
'-Lcurl-7.70.0-win64-mingw\lib' `
-lcrypt32 `
-lcurl `
-lwldap32 `
-lws2_32

结果:

SSL: OpenSSL/1.1.1g (Schannel)
NTLM: 16
HTTP/2: 65536
SSH2: libssh2/1.9.0
IPv6: 1

我没有使用 Visual Studio 构建,而是使用 Clang:

https://github.com/mstorsjo/llvm-mingw

我也不确定OpenSSL/1.1.1g (Schannel) 到底是什么,我猜这意味着 OpenSSL 和 WinSSL 两者?如果不是这样,您可以使用 CFG=-winssl 自己构建 LibCurl:

https://github.com/nu8/gulf/blob/master/c-https/1-curl.ps1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 2013-06-16
    相关资源
    最近更新 更多