我有使用OpenSSL后端构建的libcurl。我想将SNI设置为某些指定的字符串。我可以找到的方法是使用函数SSL_set_tlsext_host_name
,该函数接受SSL *
实例和一个字符串,然后对其进行设置。 (请参阅https://stackoverflow.com/a/5113466/3754125)
但是,curl_easy没有回调来检索SSL*
实例。有替代的方法吗?
更多上下文:
在我的环境中,我必须使用CURLOPT_RESOLVE
将FQDN解析为IPv4。
有FQDN:const char *fqdn
fqdn
应该解析为的IPv4:uint32_t 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,而无需触摸解析器。
答案 0 :(得分:1)
如果您要“伪造” SNI,则可以使用CURLOPT_RESOLVE
或CURLOPT_CONNECT_TO
来达到相同的最终目标。
在127.0.0.1上运行HTTPS服务器,但使curl在连接到它时认为它是example.com
(因此它将以SNI的形式发送到Host:
标头中)
CURL *curl;
struct curl_slist *host = NULL;
host = curl_slist_append(NULL, "example.com:443:127.0.0.1");
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_slist_free_all(host);
在主机名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);