hsts: duplicate live HSTS data in curl_easy_duphandle

Verified by test 1922

Closes #21809
This commit is contained in:
A Johnston 2026-06-01 14:52:23 -07:00 committed by Daniel Stenberg
parent 4ead4285a6
commit 084ceb6601
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
8 changed files with 244 additions and 2 deletions

View file

@ -1052,6 +1052,11 @@ CURL *curl_easy_duphandle(CURL *curl)
(void)Curl_hsts_loadfile(outcurl,
outcurl->hsts, outcurl->set.str[STRING_HSTS]);
(void)Curl_hsts_loadcb(outcurl, outcurl->hsts);
/* Copy entries learned at runtime. (E.g. Strict-Transport-Security
headers.) */
if(Curl_hsts_copy(outcurl->hsts, data->hsts))
goto fail;
}
#endif

View file

@ -130,6 +130,25 @@ static CURLcode hsts_create(struct hsts *h,
return CURLE_OK;
}
/* Copy all live entries from src into dst. Used by curl_easy_duphandle so the
* clone inherits entries learned at runtime. E.g. Strict-Transport-Security.
*/
CURLcode Curl_hsts_copy(struct hsts *dst, struct hsts *src)
{
struct Curl_llist_node *e;
time_t now = time(NULL);
for(e = Curl_llist_head(&src->list); e; e = Curl_node_next(e)) {
struct stsentry *sts = Curl_node_elem(e);
if(sts->expires > now) {
CURLcode result = hsts_create(dst, sts->host, strlen(sts->host),
sts->includeSubDomains != 0, sts->expires);
if(result)
return result;
}
}
return CURLE_OK;
}
/*
* Return the matching HSTS entry, or NULL if the given hostname is not
* currently an HSTS one.

View file

@ -54,6 +54,7 @@ struct hsts {
struct hsts *Curl_hsts_init(void);
void Curl_hsts_cleanup(struct hsts **hp);
CURLcode Curl_hsts_copy(struct hsts *dst, struct hsts *src);
CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname,
const char *header);
CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h,