提交 3c16d034 编写于 作者: D Daniel Stenberg 提交者: zhouhaifeng

share: add sharing of HSTS cache among handles

Closes #10138

CVE-2023-23914, CVE-2023-23915
Signed-off-by: Nzhouhaifeng <kutcher.zhou@huawei.com>
上级 c51cd4b8
......@@ -943,6 +943,7 @@ CURL_LOCK_ACCESS_SINGLE 7.10.3
CURL_LOCK_DATA_CONNECT 7.10.3
CURL_LOCK_DATA_COOKIE 7.10.3
CURL_LOCK_DATA_DNS 7.10.3
CURL_LOCK_DATA_HSTS 7.88.0
CURL_LOCK_DATA_NONE 7.10.3
CURL_LOCK_DATA_PSL 7.61.0
CURL_LOCK_DATA_SHARE 7.10.4
......
......@@ -2824,6 +2824,7 @@ typedef enum {
CURL_LOCK_DATA_SSL_SESSION,
CURL_LOCK_DATA_CONNECT,
CURL_LOCK_DATA_PSL,
CURL_LOCK_DATA_HSTS,
CURL_LOCK_DATA_LAST
} curl_lock_data;
......
......@@ -38,6 +38,7 @@
#include "fopen.h"
#include "rename.h"
#include "strtoofft.h"
#include "share.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
......@@ -528,4 +529,18 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h)
return hsts_pull(data, h);
}
void Curl_hsts_loadfiles(struct Curl_easy *data)
{
struct curl_slist *l = data->set.hstslist;
if(l) {
Curl_share_lock(data, CURL_LOCK_DATA_HSTS, CURL_LOCK_ACCESS_SINGLE);
while(l) {
(void)Curl_hsts_loadfile(data, data->hsts, l->data);
l = l->next;
}
Curl_share_unlock(data, CURL_LOCK_DATA_HSTS);
}
}
#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */
......@@ -57,9 +57,11 @@ CURLcode Curl_hsts_loadfile(struct Curl_easy *data,
struct hsts *h, const char *file);
CURLcode Curl_hsts_loadcb(struct Curl_easy *data,
struct hsts *h);
void Curl_hsts_loadfiles(struct Curl_easy *data);
#else
#define Curl_hsts_cleanup(x)
#define Curl_hsts_loadcb(x,y)
#define Curl_hsts_save(x,y,z)
#define Curl_hsts_loadfiles(x)
#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */
#endif /* HEADER_CURL_HSTS_H */
......@@ -2230,9 +2230,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->cookies = NULL;
#endif
#ifndef CURL_DISABLE_HSTS
if(data->share->hsts == data->hsts)
data->hsts = NULL;
#endif
#ifdef USE_SSL
if(data->share->sslsession == data->state.session)
data->state.session = NULL;
#endif
#ifdef USE_LIBPSL
if(data->psl == &data->share->psl)
data->psl = data->multi? &data->multi->psl: NULL;
......@@ -2266,10 +2271,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->cookies = data->share->cookies;
}
#endif /* CURL_DISABLE_HTTP */
#ifndef CURL_DISABLE_HSTS
if(data->share->hsts) {
/* first free the private one if any */
Curl_hsts_cleanup(&data->hsts);
data->hsts = data->share->hsts;
}
#endif /* CURL_DISABLE_HTTP */
#ifdef USE_SSL
if(data->share->sslsession) {
data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
data->state.session = data->share->sslsession;
}
#endif
#ifdef USE_LIBPSL
if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL))
data->psl = &data->share->psl;
......@@ -2961,19 +2975,39 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
case CURLOPT_HSTSWRITEDATA:
data->set.hsts_write_userp = va_arg(param, void *);
break;
case CURLOPT_HSTS:
case CURLOPT_HSTS: {
struct curl_slist *h;
if(!data->hsts) {
data->hsts = Curl_hsts_init();
if(!data->hsts)
return CURLE_OUT_OF_MEMORY;
}
argptr = va_arg(param, char *);
result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr);
if(result)
return result;
if(argptr)
(void)Curl_hsts_loadfile(data, data->hsts, argptr);
if(argptr) {
result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr);
if(result)
return result;
/* this needs to build a list of file names to read from, so that it can
read them later, as we might get a shared HSTS handle to load them
into */
h = curl_slist_append(data->set.hstslist, argptr);
if(!h) {
curl_slist_free_all(data->set.hstslist);
data->set.hstslist = NULL;
return CURLE_OUT_OF_MEMORY;
}
data->set.hstslist = h; /* store the list for later use */
}
else {
/* clear the list of HSTS files */
curl_slist_free_all(data->set.hstslist);
data->set.hstslist = NULL;
if(!data->share || !data->share->hsts)
/* throw away the HSTS cache unless shared */
Curl_hsts_cleanup(&data->hsts);
}
break;
}
case CURLOPT_HSTS_CTRL:
arg = va_arg(param, long);
if(arg & CURLHSTS_ENABLE) {
......
......@@ -27,9 +27,11 @@
#include "share.h"
#include "psl.h"
#include "vtls/vtls.h"
#include "curl_memory.h"
#include "hsts.h"
/* The last #include file should be: */
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
struct Curl_share *
......@@ -91,6 +93,18 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
#endif
break;
case CURL_LOCK_DATA_HSTS:
#ifndef CURL_DISABLE_HSTS
if(!share->hsts) {
share->hsts = Curl_hsts_init();
if(!share->hsts)
res = CURLSHE_NOMEM;
}
#else /* CURL_DISABLE_HSTS */
res = CURLSHE_NOT_BUILT_IN;
#endif
break;
case CURL_LOCK_DATA_SSL_SESSION:
#ifdef USE_SSL
if(!share->sslsession) {
......@@ -143,6 +157,16 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
#endif
break;
case CURL_LOCK_DATA_HSTS:
#ifndef CURL_DISABLE_HSTS
if(share->hsts) {
Curl_hsts_cleanup(&share->hsts);
}
#else /* CURL_DISABLE_HSTS */
res = CURLSHE_NOT_BUILT_IN;
#endif
break;
case CURL_LOCK_DATA_SSL_SESSION:
#ifdef USE_SSL
Curl_safefree(share->sslsession);
......@@ -209,6 +233,10 @@ curl_share_cleanup(struct Curl_share *share)
Curl_cookie_cleanup(share->cookies);
#endif
#ifndef CURL_DISABLE_HSTS
Curl_hsts_cleanup(&share->hsts);
#endif
#ifdef USE_SSL
if(share->sslsession) {
size_t i;
......
......@@ -57,10 +57,14 @@ struct Curl_share {
#ifdef USE_LIBPSL
struct PslCache psl;
#endif
#ifndef CURL_DISABLE_HSTS
struct hsts *hsts;
#endif
#ifdef USE_SSL
struct Curl_ssl_session *sslsession;
size_t max_ssl_sessions;
long sessionage;
#endif
};
CURLSHcode Curl_share_lock(struct Curl_easy *, curl_lock_data,
......
......@@ -1468,6 +1468,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
if(data->state.resolve)
result = Curl_loadhostpairs(data);
/* If there is a list of hsts files to read */
Curl_hsts_loadfiles(data);
if(!result) {
/* Allow data->set.use_port to set which port to use. This needs to be
* disabled for example when we follow Location: headers to URLs using
......
......@@ -427,7 +427,11 @@ CURLcode Curl_close(struct Curl_easy **datap)
Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
Curl_altsvc_cleanup(&data->asi);
Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]);
Curl_hsts_cleanup(&data->hsts);
#ifndef CURL_DISABLE_HSTS
if(!data->share || !data->share->hsts)
Curl_hsts_cleanup(&data->hsts);
curl_slist_free_all(data->set.hstslist); /* clean up list */
#endif
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
Curl_http_auth_cleanup_digest(data);
#endif
......
......@@ -1669,6 +1669,8 @@ struct UserDefined {
/* function to convert from UTF-8 encoding: */
curl_conv_callback convfromutf8;
#ifndef CURL_DISABLE_HSTS
struct curl_slist *hstslist; /* list of HSTS files set by
curl_easy_setopt(HSTS) calls */
curl_hstsread_callback hsts_read;
void *hsts_read_userp;
curl_hstswrite_callback hsts_write;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册