diff options
author | Daniel Stenberg <daniel@haxx.se> | 2020-11-02 23:17:01 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-11-03 16:08:48 +0100 |
commit | 2cfc4ed98347047249b8f7f91ad513a4b0b84e45 (patch) | |
tree | 6e69f05aeeb76db0a7f15f9c8314f1e983ed42e8 /lib/hsts.c | |
parent | 7385610d0c74c6a254fea5e4cd6e1d559d848c8c (diff) | |
download | curl-2cfc4ed98347047249b8f7f91ad513a4b0b84e45.tar.gz |
hsts: add read/write callbacks
- read/write callback options
- man pages for the 4 new setopts
- test 1915 verifies the callbacks
Closes #5896
Diffstat (limited to 'lib/hsts.c')
-rw-r--r-- | lib/hsts.c | 109 |
1 files changed, 102 insertions, 7 deletions
diff --git a/lib/hsts.c b/lib/hsts.c index 7eb3cda03..53b6d202b 100644 --- a/lib/hsts.c +++ b/lib/hsts.c @@ -262,6 +262,37 @@ struct stsentry *Curl_hsts(struct hsts *h, const char *hostname, } /* + * Send this HSTS entry to the write callback. + */ +static CURLcode hsts_push(struct Curl_easy *data, + struct curl_index *i, + struct stsentry *sts, + bool *stop) +{ + struct curl_hstsentry e; + CURLSTScode sc; + struct tm stamp; + CURLcode result; + + e.name = (char *)sts->host; + e.namelen = strlen(sts->host); + e.includeSubDomains = sts->includeSubDomains; + + result = Curl_gmtime(sts->expires, &stamp); + if(result) + return result; + + msnprintf(e.expire, sizeof(e.expire), "%d%02d%02d %02d:%02d:%02d", + stamp.tm_year + 1900, stamp.tm_mon + 1, stamp.tm_mday, + stamp.tm_hour, stamp.tm_min, stamp.tm_sec); + + sc = data->set.hsts_write(data, &e, i, + data->set.hsts_write_userp); + *stop = (sc != CURLSTS_OK); + return sc == CURLSTS_FAIL ? CURLE_BAD_FUNCTION_ARGUMENT : CURLE_OK; +} + +/* * Write this single hsts entry to a single output line */ static CURLcode hsts_out(struct stsentry *sts, FILE *fp) @@ -280,7 +311,7 @@ static CURLcode hsts_out(struct stsentry *sts, FILE *fp) /* - * Curl_https_save() writes the HSTS cache to a file. + * Curl_https_save() writes the HSTS cache to file and callback. */ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h, const char *file) @@ -302,7 +333,7 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h, if((h->flags & CURLHSTS_READONLYFILE) || !file || !file[0]) /* marked as read-only, no file or zero length file name */ - return CURLE_OK; + goto skipsave; if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix))) return CURLE_FAILED_INIT; @@ -333,6 +364,22 @@ CURLcode Curl_hsts_save(struct Curl_easy *data, struct hsts *h, unlink(tempstore); } free(tempstore); + skipsave: + if(data->set.hsts_write) { + /* if there's a write callback */ + struct curl_index i; /* count */ + i.total = h->list.size; + i.index = 0; + for(e = h->list.head; e; e = n) { + struct stsentry *sts = e->ptr; + bool stop; + n = e->next; + result = hsts_push(data, &i, sts, &stop); + if(result || stop) + break; + i.index++; + } + } return result; } @@ -368,6 +415,46 @@ static CURLcode hsts_add(struct hsts *h, char *line) } /* + * Load HSTS data from callback. + * + */ +static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h) +{ + /* if the HSTS read callback is set, use it */ + if(data->set.hsts_read) { + CURLSTScode sc; + DEBUGASSERT(h); + do { + char buffer[257]; + struct curl_hstsentry e; + e.name = buffer; + e.namelen = sizeof(buffer)-1; + e.includeSubDomains = FALSE; /* default */ + e.expire[0] = 0; + e.name[0] = 0; /* just to make it clean */ + sc = data->set.hsts_read(data, &e, data->set.hsts_read_userp); + if(sc == CURLSTS_OK) { + time_t expires; + CURLcode result; + if(!e.name[0]) + /* bail out if no name was stored */ + return CURLE_BAD_FUNCTION_ARGUMENT; + if(e.expire[0]) + expires = Curl_getdate_capped(e.expire); + else + expires = TIME_T_MAX; /* the end of time */ + result = hsts_create(h, e.name, e.includeSubDomains, expires); + if(result) + return result; + } + else if(sc == CURLSTS_FAIL) + return CURLE_BAD_FUNCTION_ARGUMENT; + } while(sc == CURLSTS_OK); + } + return CURLE_OK; +} + +/* * Load the HSTS cache from the given file. The text based line-oriented file * format is documented here: * https://github.com/curl/curl/wiki/HSTS @@ -417,14 +504,22 @@ static CURLcode hsts_load(struct hsts *h, const char *file) } /* - * Curl_hsts_load() loads HSTS from file. + * Curl_hsts_loadfile() loads HSTS from file */ -CURLcode Curl_hsts_load(struct hsts *h, const char *file) +CURLcode Curl_hsts_loadfile(struct Curl_easy *data, + struct hsts *h, const char *file) { - CURLcode result; DEBUGASSERT(h); - result = hsts_load(h, file); - return result; + (void)data; + return hsts_load(h, file); +} + +/* + * Curl_hsts_loadcb() loads HSTS from callback + */ +CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h) +{ + return hsts_pull(data, h); } #endif /* CURL_DISABLE_HTTP || USE_HSTS */ |