123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- /***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
- #include "curlcheck.h"
- #include "urldata.h"
- #include "hsts.h"
- static CURLcode
- unit_setup(void)
- {
- return CURLE_OK;
- }
- static void
- unit_stop(void)
- {
- curl_global_cleanup();
- }
- #if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_HSTS)
- UNITTEST_START
- {
- puts("nothing to do when HTTP or HSTS are disabled");
- }
- UNITTEST_STOP
- #else
- struct testit {
- const char *host;
- const char *chost; /* if non-NULL, use to lookup with */
- const char *hdr; /* if NULL, just do the lookup */
- const CURLcode result; /* parse result */
- };
- static const struct testit headers[] = {
- /* two entries read from disk cache, verify first */
- { "-", "readfrom.example", NULL, CURLE_OK},
- { "-", "old.example", NULL, CURLE_OK},
- /* delete the remaining one read from disk */
- { "readfrom.example", NULL, "max-age=\"0\"", CURLE_OK},
- { "example.com", NULL, "max-age=\"31536000\"\r\n", CURLE_OK },
- { "example.com", NULL, "max-age=\"21536000\"\r\n", CURLE_OK },
- { "example.com", NULL, "max-age=\"21536000\"; \r\n", CURLE_OK },
- { "example.com", NULL, "max-age=\"21536000\"; includeSubDomains\r\n",
- CURLE_OK },
- { "example.org", NULL, "max-age=\"31536000\"\r\n", CURLE_OK },
- { "this.example", NULL, "max=\"31536\";", CURLE_BAD_FUNCTION_ARGUMENT },
- { "this.example", NULL, "max-age=\"31536", CURLE_BAD_FUNCTION_ARGUMENT },
- { "this.example", NULL, "max-age=31536\"", CURLE_OK },
- /* max-age=0 removes the entry */
- { "this.example", NULL, "max-age=0", CURLE_OK },
- { "another.example", NULL, "includeSubDomains; ",
- CURLE_BAD_FUNCTION_ARGUMENT },
- /* Two max-age is illegal */
- { "example.com", NULL,
- "max-age=\"21536000\"; includeSubDomains; max-age=\"3\";",
- CURLE_BAD_FUNCTION_ARGUMENT },
- /* Two includeSubDomains is illegal */
- { "2.example.com", NULL,
- "max-age=\"21536000\"; includeSubDomains; includeSubDomains;",
- CURLE_BAD_FUNCTION_ARGUMENT },
- /* use a unknown directive "include" that should be ignored */
- { "3.example.com", NULL, "max-age=\"21536000\"; include; includeSubDomains;",
- CURLE_OK },
- /* remove the "3.example.com" one, should still match the example.com */
- { "3.example.com", NULL, "max-age=\"0\"; includeSubDomains;",
- CURLE_OK },
- { "-", "foo.example.com", NULL, CURLE_OK},
- { "-", "foo.xample.com", NULL, CURLE_OK},
- /* should not match */
- { "example.net", "forexample.net", "max-age=\"31536000\"\r\n", CURLE_OK },
- /* should not match either, since forexample.net is not in the example.net
- domain */
- { "example.net", "forexample.net",
- "max-age=\"31536000\"; includeSubDomains\r\n", CURLE_OK },
- /* remove example.net again */
- { "example.net", NULL, "max-age=\"0\"; includeSubDomains\r\n", CURLE_OK },
- /* make this live for 7 seconds */
- { "expire.example", NULL, "max-age=\"7\"\r\n", CURLE_OK },
- { NULL, NULL, NULL, CURLE_OK }
- };
- static void showsts(struct stsentry *e, const char *chost)
- {
- if(!e)
- printf("'%s' is not HSTS\n", chost);
- else {
- printf("%s [%s]: %" CURL_FORMAT_CURL_OFF_T "%s\n",
- chost, e->host, e->expires,
- e->includeSubDomains ? " includeSubDomains" : "");
- }
- }
- UNITTEST_START
- {
- CURLcode result;
- struct stsentry *e;
- struct hsts *h = Curl_hsts_init();
- int i;
- const char *chost;
- CURL *easy;
- char savename[256];
- abort_unless(h, "Curl_hsts_init()");
- curl_global_init(CURL_GLOBAL_ALL);
- easy = curl_easy_init();
- if(!easy) {
- Curl_hsts_cleanup(&h);
- curl_global_cleanup();
- abort_unless(easy, "curl_easy_init()");
- }
- Curl_hsts_loadfile(easy, h, arg);
- for(i = 0; headers[i].host ; i++) {
- if(headers[i].hdr) {
- result = Curl_hsts_parse(h, headers[i].host, headers[i].hdr);
- if(result != headers[i].result) {
- fprintf(stderr, "Curl_hsts_parse(%s) failed: %d\n",
- headers[i].hdr, result);
- unitfail++;
- continue;
- }
- else if(result) {
- printf("Input %u: error %d\n", i, (int) result);
- continue;
- }
- }
- chost = headers[i].chost ? headers[i].chost : headers[i].host;
- e = Curl_hsts(h, chost, strlen(chost), TRUE);
- showsts(e, chost);
- }
- printf("Number of entries: %zu\n", Curl_llist_count(&h->list));
- /* verify that it is exists for 7 seconds */
- chost = "expire.example";
- for(i = 100; i < 110; i++) {
- e = Curl_hsts(h, chost, strlen(chost), TRUE);
- showsts(e, chost);
- deltatime++; /* another second passed */
- }
- msnprintf(savename, sizeof(savename), "%s.save", arg);
- (void)Curl_hsts_save(easy, h, savename);
- Curl_hsts_cleanup(&h);
- curl_easy_cleanup(easy);
- curl_global_cleanup();
- }
- UNITTEST_STOP
- #endif
|