Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用OpenSSL后端在libcurl中伪造服务器名称指示(SNI)_C_Openssl_Libcurl - Fatal编程技术网

使用OpenSSL后端在libcurl中伪造服务器名称指示(SNI)

使用OpenSSL后端在libcurl中伪造服务器名称指示(SNI),c,openssl,libcurl,C,Openssl,Libcurl,我使用OpenSSL后端构建了libcurl。我想将SNI设置为某个指定的字符串。我可以找到的方法是使用函数SSL\u set\u tlsext\u host\u name,它获取SSL*实例和一个字符串,然后设置它。(见附件) 但是,curl\u easy没有回调来检索SSL*实例。有没有其他办法 更多背景: 在我的环境中,我必须使用CURLOPT_RESOLVE将FQDN解析为IPv4。 有FQDN:const char*FQDN fqdn应解析为:uint32\t IPv4的IPv4 假S

我使用OpenSSL后端构建了libcurl。我想将SNI设置为某个指定的字符串。我可以找到的方法是使用函数
SSL\u set\u tlsext\u host\u name
,它获取
SSL*
实例和一个字符串,然后设置它。(见附件)

但是,curl\u easy没有回调来检索
SSL*
实例。有没有其他办法

更多背景: 在我的环境中,我必须使用
CURLOPT_RESOLVE
将FQDN解析为IPv4。 有FQDN:
const char*FQDN
fqdn
应解析为:
uint32\t IPv4的IPv4
假SNI:
const char*SNI
要点如下:

CURL *ez;
char buf[ENOUGH];
struct curl_slist *resolver;
/* ... */
snprintf(buf, sizeof(buf), "%s:%d:%d.%d.%d.%d", fqdn, port, IP(IPv4));
resolver = curl_slist_append(NULL, buf);
curl_easy_setopt(ez, CURLOPT_RESOLVE, resolver);
在此之后,我需要在不接触解析器的情况下将SNI设置为假SNI。

如果要“假”SNI,则
CURLOPT\u RESOLVE
CURLOPT\u CONNECT\u to
是实现相同最终目标的可用选项

CULLOPT_解析示例 在127.0.0.1上运行一个HTTPS服务器,但当它连接到它时,让curl认为它是
example.com
(因此它将其作为SNI发送,并在
主机:
标题中发送)

CURLOPT_连接到示例 在主机名
server1.example.com
上运行一个dev HTTPS服务器,但您希望curl连接到它,认为它是
www.example.org
服务器

CURL *curl;
struct curl_slist *connect_to = NULL;
connect_to = curl_slist_append(NULL, "www.example.org::server1.example.com:");

curl = curl_easy_init();
if(curl) {
  curl_easy_setopt(curl, CURLOPT_CONNECT_TO, connect_to);
  curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.org");

  curl_easy_perform(curl);

  /* always cleanup */
  curl_easy_cleanup(curl);
}

curl_slist_free_all(connect_to);

SSL\u CTX\u set\u tlsext\u servername\u回调
可能会起作用。如果有效,我会更新。如果有效,请自己回答问题:)@AnttiHaapala,不幸的是,我的解决方案不起作用。它只适用于服务器,但在我的情况下,我是客户机。使用
CURLOPT_RESOLVE
CURLOPT_CONNECT_TO
如何准确地实现这一点?我已经在使用
CURLOPT_RESOLVE
将FQDN解析为IPv4。感谢您在回答中包含代码。然而,这对我来说不起作用。我正在使用
CURLOPT\u RESOLVE
将FQDN解析为IPv4(看起来像
curl\u slist\u append(NULL,“www.example.org:10443:172.18.27.161”)
(我必须这样做,因为我有一个特定的API将FQDN解析为IPv4,否则curl无法解析)。我试图注入SNI的字符串实际上是一个令牌,服务器使用它来标识应该如何调度连接。该令牌看起来像这样:
tYqxjS6ntrqmPtBwUli1
。因此,如果我想用
CURLOPT_RESOLVE
伪造SNI,我无法解析fqdn!好吧,但是你不再做HTTPS了。。。这没什么错,但是curl专注于讨论我们使其支持的特定协议。实际上我在做https!它类似于
curl\u easy\u setopt(ez\u h,CURLOPT\u URL,“https://www.example.org:10443/api/entry/point)
。你是在暗示我不能在https中伪造SNI吗?再考虑一下这个解决方案,它对我的案例有效<代码>ipv4=获取ipv4(fqdn);snprintf(解析项,sizeof(解析项),%s:%s:%d.%d.%d.%d),假sni,端口,IP(ipv4));resolve_list=curl_slist_add(NULL,resolve_条目);snprintf(url,sizeof(url),“https://%s:%s/%s”,假sni,端口,api入口点)唯一的问题是我必须将referer设置为
fqdn
CURL *curl;
struct curl_slist *connect_to = NULL;
connect_to = curl_slist_append(NULL, "www.example.org::server1.example.com:");

curl = curl_easy_init();
if(curl) {
  curl_easy_setopt(curl, CURLOPT_CONNECT_TO, connect_to);
  curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.org");

  curl_easy_perform(curl);

  /* always cleanup */
  curl_easy_cleanup(curl);
}

curl_slist_free_all(connect_to);