Skip to content

Commit

Permalink
share: add sharing of HSTS cache among handles
Browse files Browse the repository at this point in the history
Closes #10138
  • Loading branch information
bagder committed Dec 27, 2022
1 parent 692c737 commit 076a2f6
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 11 deletions.
4 changes: 4 additions & 0 deletions docs/libcurl/opts/CURLSHOPT_SHARE.3
Expand Up @@ -78,6 +78,10 @@ Added in 7.61.0.

Note that when you use the multi interface, all easy handles added to the same
multi handle will share PSL cache by default without using this option.
.IP CURL_LOCK_DATA_HSTS
The in-memory HSTS cache.

Added in 7.88.0
.SH PROTOCOLS
All
.SH EXAMPLE
Expand Down
1 change: 1 addition & 0 deletions docs/libcurl/symbols-in-versions
Expand Up @@ -73,6 +73,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
Expand Down
1 change: 1 addition & 0 deletions include/curl/curl.h
Expand Up @@ -2953,6 +2953,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;

Expand Down
15 changes: 15 additions & 0 deletions lib/hsts.c
Expand Up @@ -39,6 +39,7 @@
#include "parsedate.h"
#include "fopen.h"
#include "rename.h"
#include "share.h"

/* The last 3 #include files should be in this order */
#include "curl_printf.h"
Expand Down Expand Up @@ -551,4 +552,18 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h)
return CURLE_OK;
}

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 */
2 changes: 2 additions & 0 deletions lib/hsts.h
Expand Up @@ -59,9 +59,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) CURLE_OK
#define Curl_hsts_save(x,y,z)
#define Curl_hsts_loadfiles(x)
#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */
#endif /* HEADER_CURL_HSTS_H */
48 changes: 41 additions & 7 deletions lib/setopt.c
Expand Up @@ -2262,9 +2262,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;
Expand Down Expand Up @@ -2298,10 +2303,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;
Expand Down Expand Up @@ -3053,19 +3067,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) {
Expand Down
32 changes: 30 additions & 2 deletions lib/share.c
Expand Up @@ -29,9 +29,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 *
Expand Down Expand Up @@ -89,6 +91,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) {
Expand Down Expand Up @@ -141,6 +155,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);
Expand Down Expand Up @@ -207,6 +231,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;
Expand Down
6 changes: 5 additions & 1 deletion lib/share.h
Expand Up @@ -59,10 +59,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,
Expand Down
3 changes: 3 additions & 0 deletions lib/transfer.c
Expand Up @@ -1396,6 +1396,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
Expand Down
6 changes: 5 additions & 1 deletion lib/url.c
Expand Up @@ -437,7 +437,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
Expand Down
2 changes: 2 additions & 0 deletions lib/urldata.h
Expand Up @@ -1659,6 +1659,8 @@ struct UserDefined {
curl_easy_setopt(COOKIEFILE) calls */
#endif
#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;
Expand Down

0 comments on commit 076a2f6

Please sign in to comment.