Gitweb links:

...log 
http://git.netsurf-browser.org/netsurf.git/shortlog/cbe445e19178045c0bdf649f927e6e7cc904c6c5
...commit 
http://git.netsurf-browser.org/netsurf.git/commit/cbe445e19178045c0bdf649f927e6e7cc904c6c5
...tree 
http://git.netsurf-browser.org/netsurf.git/tree/cbe445e19178045c0bdf649f927e6e7cc904c6c5

The branch, jmb/hsts has been created
        at  cbe445e19178045c0bdf649f927e6e7cc904c6c5 (commit)

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=cbe445e19178045c0bdf649f927e6e7cc904c6c5
commit cbe445e19178045c0bdf649f927e6e7cc904c6c5
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>

    HSTS: make llcache update policy on 3xx responses

diff --git a/content/llcache.c b/content/llcache.c
index 166804c..54f20e0 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -1985,6 +1985,8 @@ static nserror llcache_fetch_redirect(llcache_object 
*object,
        /* And mark it complete */
        object->fetch.state = LLCACHE_FETCH_COMPLETE;
 
+       (void) llcache_hsts_update_policy(object);
+
        /* Forcibly stop redirecting if we've followed too many redirects */
 #define REDIRECT_LIMIT 10
        if (object->fetch.redirect_count > REDIRECT_LIMIT) {


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=c42ea9b30d8197f688eec80c974575eb213a35e6
commit c42ea9b30d8197f688eec80c974575eb213a35e6
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>

    HSTS: prevent llcache being nice
    
    If the server has defined a HSTS policy, then the user no longer
    gets to click-through a garbage certificate. Additionally, if
    the server has provided a HSTS policy, it should do TLS properly,
    so don't permit client-driven TLS version downgrades in that case,
    either.

diff --git a/content/llcache.c b/content/llcache.c
index ab69e65..166804c 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -109,6 +109,8 @@ typedef struct {
 
        uint32_t retries_remaining;     /**< Number of times to retry on 
timeout */
 
+       bool hsts_in_use;               /**< Whether HSTS applies to this fetch 
*/
+
        bool tried_with_auth;           /**< Whether we've tried with auth */
 
        bool tried_with_tls_downgrade;  /**< Whether we've tried TLS <= 1.0 */
@@ -904,11 +906,12 @@ static nserror llcache_object_refetch(llcache_object 
*object)
  * \param referer        Referring URL, or NULL for none
  * \param post           POST data, or NULL for GET
  * \param redirect_count  Number of redirects followed so far
+ * \param hsts_in_use     Whether HSTS applies to this fetch
  * \return NSERROR_OK on success, appropriate error otherwise
  */
 static nserror llcache_object_fetch(llcache_object *object, uint32_t flags,
                nsurl *referer, const llcache_post_data *post,
-               uint32_t redirect_count)
+               uint32_t redirect_count, bool hsts_in_use)
 {
        nserror error;
        nsurl *referer_clone = NULL;
@@ -930,6 +933,7 @@ static nserror llcache_object_fetch(llcache_object *object, 
uint32_t flags,
        object->fetch.post = post_clone;
        object->fetch.redirect_count = redirect_count;
        object->fetch.retries_remaining = llcache->fetch_attempts;
+       object->fetch.hsts_in_use = hsts_in_use;
 
        return llcache_object_refetch(object);
 }
@@ -1566,6 +1570,7 @@ llcache_object_fetch_persistent(llcache_object *object,
  * \param referer        Referring URL, or NULL if none
  * \param post           POST data, or NULL for a GET request
  * \param redirect_count  Number of redirects followed so far
+ * \param hsts_in_use     Whether HSTS applies to this fetch
  * \param result         Pointer to location to receive retrieved object
  * \return NSERROR_OK on success, appropriate error otherwise
  */
@@ -1575,6 +1580,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
                                   nsurl *referer,
                                   const llcache_post_data *post,
                                   uint32_t redirect_count,
+                                  bool hsts_in_use,
                                   llcache_object **result)
 {
        nserror error;
@@ -1683,7 +1689,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
 
                        /* Attempt to kick-off fetch */
                        error = llcache_object_fetch(obj, flags, referer, post,
-                                                    redirect_count);
+                                                    redirect_count, 
hsts_in_use);
                        if (error != NSERROR_OK) {
                                newest->candidate_count--;
                                llcache_object_destroy(obj);
@@ -1715,7 +1721,8 @@ llcache_object_retrieve_from_cache(nsurl *url,
        }
 
        /* Attempt to kick-off fetch */
-       error = llcache_object_fetch(obj, flags, referer, post, redirect_count);
+       error = llcache_object_fetch(obj, flags, referer, post,
+                       redirect_count, hsts_in_use);
        if (error != NSERROR_OK) {
                llcache_object_destroy(obj);
                return error;
@@ -1737,6 +1744,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
  * \param referer        Referring URL, or NULL if none
  * \param post           POST data, or NULL for a GET request
  * \param redirect_count  Number of redirects followed so far
+ * \param hsts_in_use     Whether HSTS applies to this fetch
  * \param result         Pointer to location to receive retrieved object
  * \return NSERROR_OK on success, appropriate error otherwise
  */
@@ -1746,6 +1754,7 @@ llcache_object_retrieve(nsurl *url,
                        nsurl *referer,
                        const llcache_post_data *post,
                        uint32_t redirect_count,
+                       bool hsts_in_use,
                        llcache_object **result)
 {
        nserror error;
@@ -1800,7 +1809,7 @@ llcache_object_retrieve(nsurl *url,
 
                /* Attempt to kick-off fetch */
                error = llcache_object_fetch(obj, flags, referer, post,
-                               redirect_count);
+                               redirect_count, hsts_in_use);
                if (error != NSERROR_OK) {
                        llcache_object_destroy(obj);
                        nsurl_unref(defragmented_url);
@@ -1811,7 +1820,8 @@ llcache_object_retrieve(nsurl *url,
                llcache_object_add_to_list(obj, &llcache->uncached_objects);
        } else {
                error = llcache_object_retrieve_from_cache(defragmented_url,
-                               flags, referer, post, redirect_count, &obj);
+                               flags, referer, post, redirect_count,
+                               hsts_in_use, &obj);
                if (error != NSERROR_OK) {
                        nsurl_unref(defragmented_url);
                        return error;
@@ -2058,7 +2068,8 @@ static nserror llcache_fetch_redirect(llcache_object 
*object,
        /* Attempt to fetch target URL */
        error = llcache_object_retrieve(hsts_url, object->fetch.flags,
                        object->fetch.referer, post,
-                       object->fetch.redirect_count + 1, &dest);
+                       object->fetch.redirect_count + 1,
+                       hsts_in_use, &dest);
 
        /* No longer require url */
        nsurl_unref(hsts_url);
@@ -2352,7 +2363,8 @@ static nserror llcache_fetch_cert_error(llcache_object 
*object,
        /* Consider the TLS transport tainted */
        object->fetch.tainted_tls = true;
 
-       if (llcache->query_cb != NULL) {
+       /* Only give the user a chance if HSTS isn't in use for this fetch */
+       if (object->fetch.hsts_in_use == false && llcache->query_cb != NULL) {
                llcache_query query;
 
                /* Emit query for TLS */
@@ -2405,7 +2417,10 @@ static nserror llcache_fetch_ssl_error(llcache_object 
*object)
        /* Consider the TLS transport tainted */
        object->fetch.tainted_tls = true;
 
-       if (object->fetch.tried_with_tls_downgrade == true) {
+       /* Make no attempt to downgrade if HSTS is in use
+        * (i.e. assume server does TLS properly) */
+       if (object->fetch.hsts_in_use ||
+                       object->fetch.tried_with_tls_downgrade) {
                /* Have already tried to downgrade, so give up */
                llcache_event event;
 
@@ -3611,7 +3626,8 @@ nserror llcache_handle_retrieve(nsurl *url, uint32_t 
flags,
 
        /* Retrieve a suitable object from the cache,
         * creating a new one if needed. */
-       error = llcache_object_retrieve(hsts_url, flags, referer, post, 0, 
&object);
+       error = llcache_object_retrieve(hsts_url, flags, referer, post, 0,
+                       hsts_in_use, &object);
        if (error != NSERROR_OK) {
                llcache_object_user_destroy(user);
                nsurl_unref(hsts_url);


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=99a29000b937807c7f946d597295c96733ff60f3
commit 99a29000b937807c7f946d597295c96733ff60f3
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>

    HSTS: teach llcache to update and enforce policy.

diff --git a/content/llcache.c b/content/llcache.c
index 58803ea..ab69e65 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -114,6 +114,8 @@ typedef struct {
        bool tried_with_tls_downgrade;  /**< Whether we've tried TLS <= 1.0 */
 
        bool outstanding_query;         /**< Waiting for a query response */
+
+       bool tainted_tls;               /**< Whether the TLS transport is 
tainted */
 } llcache_fetch_ctx;
 
 /**
@@ -1857,6 +1859,90 @@ static nserror llcache_object_add_user(llcache_object 
*object,
 }
 
 /**
+ * Transform a request-URI based on HSTS policy
+ *
+ * \param url URL to transform
+ * \param result Pointer to location to receive transformed URL
+ * \param hsts_in_use Pointer to location to receive HSTS in-use flag
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+static nserror llcache_hsts_transform_url(nsurl *url, nsurl **result,
+               bool *hsts_in_use)
+{
+       lwc_string *scheme = NULL;
+       bool match;
+       nserror error = NSERROR_OK;;
+
+       scheme = nsurl_get_component(url, NSURL_SCHEME);
+       if (lwc_string_caseless_isequal(scheme, corestring_lwc_http,
+                       &match) != lwc_error_ok || match == false) {
+               /* Non-HTTP fetch: ignore */
+               if (scheme != NULL) {
+                       lwc_string_unref(scheme);
+               }
+               *result = nsurl_ref(url);
+               *hsts_in_use = false;
+               return NSERROR_OK;
+       }
+       lwc_string_unref(scheme);
+
+       if (urldb_get_hsts_enabled(url)) {
+               /* Only need to force HTTPS. If original port was explicitly
+                * specified as 80, nsurl_create/join will remove it (as
+                * it's redundant) */
+               error = nsurl_replace_scheme(url, corestring_lwc_https,
+                               result);
+               *hsts_in_use = (error == NSERROR_OK);
+       } else {
+               *result = nsurl_ref(url);
+               *hsts_in_use = false;
+       }
+
+       return error;
+}
+
+/**
+ * Update HSTS policy for target domain.
+ *
+ * \param object Newly-fetched cache object
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+static nserror llcache_hsts_update_policy(llcache_object *object)
+{
+       size_t i;
+       lwc_string *scheme = NULL;
+       bool match = false;
+
+       scheme = nsurl_get_component(object->url, NSURL_SCHEME);
+       if (lwc_string_caseless_isequal(scheme, corestring_lwc_https,
+                       &match) != lwc_error_ok || match == false) {
+               /* Non-HTTPS fetch: ignore */
+               if (scheme != NULL) {
+                       lwc_string_unref(scheme);
+               }
+               return NSERROR_OK;
+       }
+       lwc_string_unref(scheme);
+
+       if (object->fetch.tainted_tls) {
+               /* Transport is tainted: ignore */
+               return NSERROR_OK;
+       }
+
+       for (i = 0; i < object->num_headers; i++) {
+               if (strcasecmp("Strict-Transport-Security",
+                               object->headers[i].name) == 0) {
+                       urldb_set_hsts_policy(object->url,
+                                       object->headers[i].value);
+                       /* Only process the first one we find */
+                       break;
+               }
+       }
+
+       return NSERROR_OK;
+}
+
+/**
  * Handle FETCH_REDIRECT event
  *
  * \param object       Object being redirected
@@ -1871,10 +1957,10 @@ static nserror llcache_fetch_redirect(llcache_object 
*object,
        llcache_object *dest;
        llcache_object_user *user, *next;
        const llcache_post_data *post = object->fetch.post;
-       nsurl *url;
+       nsurl *url, *hsts_url;
        lwc_string *scheme;
        lwc_string *object_scheme;
-       bool match;
+       bool match, hsts_in_use;
        /* Extract HTTP response code from the fetch object */
        long http_code = fetch_http_code(object->fetch.fetch);
        llcache_event event;
@@ -1906,15 +1992,23 @@ static nserror llcache_fetch_redirect(llcache_object 
*object,
        if (error != NSERROR_OK)
                return error;
 
+       /* Perform HSTS transform */
+       error = llcache_hsts_transform_url(url, &hsts_url, &hsts_in_use);
+       if (error != NSERROR_OK) {
+               nsurl_unref(url);
+               return error;
+       }
+       nsurl_unref(url);
+
        /* Inform users of redirect */
        event.type = LLCACHE_EVENT_REDIRECT;
        event.data.redirect.from = object->url;
-       event.data.redirect.to = url;
+       event.data.redirect.to = hsts_url;
 
        error = llcache_send_event_to_users(object, &event);
 
        if (error != NSERROR_OK) {
-               nsurl_unref(url);
+               nsurl_unref(hsts_url);
                return error;
        }
 
@@ -1922,7 +2016,7 @@ static nserror llcache_fetch_redirect(llcache_object 
*object,
         * A "validated" scheme is one over which we have some guarantee that
         * the source is trustworthy. */
        object_scheme = nsurl_get_component(object->url, NSURL_SCHEME);
-       scheme = nsurl_get_component(url, NSURL_SCHEME);
+       scheme = nsurl_get_component(hsts_url, NSURL_SCHEME);
 
        /* resource: and about: are allowed to redirect anywhere */
        if ((lwc_string_isequal(object_scheme, corestring_lwc_resource,
@@ -1938,7 +2032,7 @@ static nserror llcache_fetch_redirect(llcache_object 
*object,
                                &match) == lwc_error_ok && match == true)) {
                        lwc_string_unref(object_scheme);
                        lwc_string_unref(scheme);
-                       nsurl_unref(url);
+                       nsurl_unref(hsts_url);
                        return NSERROR_OK;
                }
        }
@@ -1947,8 +2041,8 @@ static nserror llcache_fetch_redirect(llcache_object 
*object,
        lwc_string_unref(object_scheme);
 
        /* Bail out if we've no way of handling this URL */
-       if (fetch_can_fetch(url) == false) {
-               nsurl_unref(url);
+       if (fetch_can_fetch(hsts_url) == false) {
+               nsurl_unref(hsts_url);
                return NSERROR_OK;
        }
 
@@ -1957,17 +2051,17 @@ static nserror llcache_fetch_redirect(llcache_object 
*object,
                post = NULL;
        } else if (http_code != 307 || post != NULL) {
                /** \todo 300, 305, 307 with POST */
-               nsurl_unref(url);
+               nsurl_unref(hsts_url);
                return NSERROR_OK;
        }
 
        /* Attempt to fetch target URL */
-       error = llcache_object_retrieve(url, object->fetch.flags,
+       error = llcache_object_retrieve(hsts_url, object->fetch.flags,
                        object->fetch.referer, post,
                        object->fetch.redirect_count + 1, &dest);
 
        /* No longer require url */
-       nsurl_unref(url);
+       nsurl_unref(hsts_url);
 
        if (error != NSERROR_OK)
                return error;
@@ -2059,6 +2153,8 @@ static nserror llcache_fetch_notmodified(llcache_object 
*object,
        /* Mark it complete */
        object->fetch.state = LLCACHE_FETCH_COMPLETE;
 
+       (void) llcache_hsts_update_policy(object);
+
        /* Old object will be flushed from the cache on the next poll */
 
        return NSERROR_OK;
@@ -2253,6 +2349,9 @@ static nserror llcache_fetch_cert_error(llcache_object 
*object,
        /* Invalidate cache-control data */
        llcache_invalidate_cache_control_data(object);
 
+       /* Consider the TLS transport tainted */
+       object->fetch.tainted_tls = true;
+
        if (llcache->query_cb != NULL) {
                llcache_query query;
 
@@ -2303,6 +2402,9 @@ static nserror llcache_fetch_ssl_error(llcache_object 
*object)
        /* Invalidate cache-control data */
        llcache_invalidate_cache_control_data(object);
 
+       /* Consider the TLS transport tainted */
+       object->fetch.tainted_tls = true;
+
        if (object->fetch.tried_with_tls_downgrade == true) {
                /* Have already tried to downgrade, so give up */
                llcache_event event;
@@ -2684,6 +2786,8 @@ static void llcache_fetch_callback(const fetch_msg *msg, 
void *p)
                /* record when the fetch finished */
                object->cache.fin_time = time(NULL);
 
+               (void) llcache_hsts_update_policy(object);
+
                guit->misc->schedule(5000, llcache_persist, NULL);
        }
                break;
@@ -3483,23 +3587,34 @@ nserror llcache_handle_retrieve(nsurl *url, uint32_t 
flags,
        nserror error;
        llcache_object_user *user;
        llcache_object *object;
+       nsurl *hsts_url;
+       bool hsts_in_use;
+
+       /* Perform HSTS transform */
+       error = llcache_hsts_transform_url(url, &hsts_url, &hsts_in_use);
+       if (error != NSERROR_OK) {
+               return error;
+       }
 
        /* Can we fetch this URL at all? */
-       if (fetch_can_fetch(url) == false) {
+       if (fetch_can_fetch(hsts_url) == false) {
+               nsurl_unref(hsts_url);
                return NSERROR_NO_FETCH_HANDLER;
        }
 
        /* Create a new object user */
        error = llcache_object_user_new(cb, pw, &user);
        if (error != NSERROR_OK) {
+               nsurl_unref(hsts_url);
                return error;
        }
 
        /* Retrieve a suitable object from the cache,
         * creating a new one if needed. */
-       error = llcache_object_retrieve(url, flags, referer, post, 0, &object);
+       error = llcache_object_retrieve(hsts_url, flags, referer, post, 0, 
&object);
        if (error != NSERROR_OK) {
                llcache_object_user_destroy(user);
+               nsurl_unref(hsts_url);
                return error;
        }
 
@@ -3511,6 +3626,8 @@ nserror llcache_handle_retrieve(nsurl *url, uint32_t 
flags,
        /* Users exist which are now not caught up! */
        llcache_users_not_caught_up();
 
+       nsurl_unref(hsts_url);
+
        return NSERROR_OK;
 }
 


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=7d7bcb526bc8df9f5705e6a37711eef20da84df1
commit 7d7bcb526bc8df9f5705e6a37711eef20da84df1
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>

    NSURL: add ability to create replacement scheme

diff --git a/utils/corestringlist.h b/utils/corestringlist.h
index 8d15eeb..90dd796 100644
--- a/utils/corestringlist.h
+++ b/utils/corestringlist.h
@@ -70,6 +70,7 @@ CORESTRING_LWC_STRING(filename);
 CORESTRING_LWC_STRING(font);
 CORESTRING_LWC_STRING(frame);
 CORESTRING_LWC_STRING(frameset);
+CORESTRING_LWC_STRING(ftp);
 CORESTRING_LWC_STRING(h1);
 CORESTRING_LWC_STRING(h2);
 CORESTRING_LWC_STRING(h3);
diff --git a/utils/nsurl.h b/utils/nsurl.h
index f97562b..054baf2 100644
--- a/utils/nsurl.h
+++ b/utils/nsurl.h
@@ -301,6 +301,25 @@ nserror nsurl_replace_query(const nsurl *url, const char 
*query,
 
 
 /**
+ * Create a NetSurf URL object, with scheme replaced
+ *
+ * \param url    NetSurf URL to create new NetSurf URL from
+ * \param scheme  Scheme to use
+ * \param new_url Returns new NetSurf URL with scheme provided
+ * \return NSERROR_OK on success, appropriate error otherwise
+ *
+ * If return value != NSERROR_OK, nothing will be returned in new_url.
+ *
+ * It is up to the client to call nsurl_unref when they are finished with
+ * the created object.
+ *
+ * Any scheme component in url is replaced with scheme in new_url.
+ */
+nserror nsurl_replace_scheme(const nsurl *url, lwc_string *scheme,
+               nsurl **new_url);
+
+
+/**
  * Attempt to find a nice filename for a URL.
  *
  * \param url          A NetSurf URL object to create a filename from
diff --git a/utils/nsurl/nsurl.c b/utils/nsurl/nsurl.c
index 3b0af93..8c769cf 100644
--- a/utils/nsurl/nsurl.c
+++ b/utils/nsurl/nsurl.c
@@ -648,6 +648,93 @@ nserror nsurl_replace_query(const nsurl *url, const char 
*query,
 }
 
 
+/* exported interface, documented in nsurl.h */
+nserror nsurl_replace_scheme(const nsurl *url, lwc_string *scheme,
+               nsurl **new_url)
+{
+       int scheme_len;
+       int base_len;
+       char *pos;
+       size_t len;
+       bool match;
+
+       assert(url != NULL);
+       assert(scheme != NULL);
+
+       /* Get the length of the new scheme */
+       scheme_len = lwc_string_length(scheme);
+
+       /* Find the change in length from url to new_url */
+       base_len = url->length;
+       if (url->components.scheme != NULL) {
+               base_len -= lwc_string_length(url->components.scheme);
+       }
+
+       /* Set new_url's length */
+       len = base_len + scheme_len;
+
+       /* Create NetSurf URL object */
+       *new_url = malloc(sizeof(nsurl) + len + 1); /* Add 1 for \0 */
+       if (*new_url == NULL) {
+               return NSERROR_NOMEM;
+       }
+
+       (*new_url)->length = len;
+
+       /* Set string */
+       pos = (*new_url)->string;
+       memcpy(pos, lwc_string_data(scheme), scheme_len);
+       memcpy(pos + scheme_len,
+                       url->string + url->length - base_len, base_len);
+       pos[len] = '\0';
+
+       /* Copy components */
+       (*new_url)->components.scheme = lwc_string_ref(scheme);
+       (*new_url)->components.username =
+                       nsurl__component_copy(url->components.username);
+       (*new_url)->components.password =
+                       nsurl__component_copy(url->components.password);
+       (*new_url)->components.host =
+                       nsurl__component_copy(url->components.host);
+       (*new_url)->components.port =
+                       nsurl__component_copy(url->components.port);
+       (*new_url)->components.path =
+                       nsurl__component_copy(url->components.path);
+       (*new_url)->components.query =
+                       nsurl__component_copy(url->components.query);
+       (*new_url)->components.fragment =
+                       nsurl__component_copy(url->components.fragment);
+
+       /* Compute new scheme type */
+       if (lwc_string_caseless_isequal(scheme, corestring_lwc_http,
+                       &match) == lwc_error_ok && match == true) {
+               (*new_url)->components.scheme_type = NSURL_SCHEME_HTTP;
+       } else if (lwc_string_caseless_isequal(scheme, corestring_lwc_https,
+                       &match) == lwc_error_ok && match == true) {
+               (*new_url)->components.scheme_type = NSURL_SCHEME_HTTPS;
+       } else if (lwc_string_caseless_isequal(scheme, corestring_lwc_file,
+                       &match) == lwc_error_ok && match == true) {
+               (*new_url)->components.scheme_type = NSURL_SCHEME_FILE;
+       } else if (lwc_string_caseless_isequal(scheme, corestring_lwc_ftp,
+                       &match) == lwc_error_ok && match == true) {
+               (*new_url)->components.scheme_type = NSURL_SCHEME_FTP;
+       } else if (lwc_string_caseless_isequal(scheme, corestring_lwc_mailto,
+                       &match) == lwc_error_ok && match == true) {
+               (*new_url)->components.scheme_type = NSURL_SCHEME_MAILTO;
+       } else {
+               (*new_url)->components.scheme_type = NSURL_SCHEME_OTHER;
+       }
+
+       /* Get the nsurl's hash */
+       nsurl__calc_hash(*new_url);
+
+       /* Give the URL a reference */
+       (*new_url)->count = 1;
+
+       return NSERROR_OK;
+}
+
+
 /* exported interface documented in utils/nsurl.h */
 nserror nsurl_nice(const nsurl *url, char **result, bool remove_extensions)
 {


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=447e2aa4cb0468907f8996d4e02fb34d19c29510
commit 447e2aa4cb0468907f8996d4e02fb34d19c29510
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>

    HSTS: support policy in urldb

diff --git a/content/urldb.c b/content/urldb.c
index cacc475..1bf2233 100644
--- a/content/urldb.c
+++ b/content/urldb.c
@@ -108,6 +108,7 @@
 #include "utils/time.h"
 #include "utils/nsurl.h"
 #include "utils/ascii.h"
+#include "utils/http.h"
 #include "netsurf/bitmap.h"
 #include "desktop/cookie_manager.h"
 #include "desktop/gui_internal.h"
@@ -222,6 +223,11 @@ struct path_data {
        struct path_data *last; /**< Last child */
 };
 
+struct hsts_data {
+       time_t expires; /**< Expiry time */
+       bool include_sub_domains; /**< Whether to include subdomains */
+};
+
 struct host_part {
        /**
         * Known paths on this host. This _must_ be first so that
@@ -233,6 +239,8 @@ struct host_part {
         * without verifying certificate authenticity
         */
        bool permit_invalid_certs;
+       /* HSTS data */
+       struct hsts_data hsts;
 
        /**
         * Part of host string
@@ -290,7 +298,7 @@ static int loaded_cookie_file_version;
 /** Minimum URL database file version */
 #define MIN_URL_FILE_VERSION 106
 /** Current URL database file version */
-#define URL_FILE_VERSION 106
+#define URL_FILE_VERSION 107
 
 /**
  * filter for url presence in database
@@ -511,7 +519,8 @@ static void urldb_save_search_tree(struct search_node 
*parent, FILE *fp)
        unsigned int path_count = 0;
        char *path, *p, *end;
        int path_alloc = 64, path_used = 1;
-       time_t expiry;
+       time_t expiry, hsts_expiry = 0;
+       int hsts_include_subdomains = 0;
 
        expiry = time(NULL) - ((60 * 60 * 24) * nsoption_int(expire_url));
 
@@ -537,13 +546,25 @@ static void urldb_save_search_tree(struct search_node 
*parent, FILE *fp)
                p += written;
        }
 
+       h = parent->data;
+       if (h && h->hsts.expires > expiry) {
+               hsts_expiry = h->hsts.expires;
+               hsts_include_subdomains = h->hsts.include_sub_domains;
+       }
+
        urldb_count_urls(&parent->data->paths, expiry, &path_count);
 
        if (path_count > 0) {
-               fprintf(fp, "%s\n%i\n", host, path_count);
+               fprintf(fp, "%s %i ", host, hsts_include_subdomains);
+               urldb_write_timet(fp, hsts_expiry);
+               fprintf(fp, "%i\n", path_count);
 
                urldb_write_paths(&parent->data->paths, host, fp,
                                  &path, &path_alloc, &path_used, expiry);
+       } else if (hsts_expiry) {
+               fprintf(fp, "%s %i ", host, hsts_include_subdomains);
+               urldb_write_timet(fp, hsts_expiry);
+               fprintf(fp, "0\n");
        }
 
        free(path);
@@ -2894,6 +2915,9 @@ nserror urldb_load(const char *filename)
        }
 
        while (fgets(host, sizeof host, fp)) {
+               time_t hsts_expiry = 0;
+               int hsts_include_sub_domains = 0;
+
                /* get the hostname */
                length = strlen(host) - 1;
                host[length] = '\0';
@@ -2911,6 +2935,25 @@ nserror urldb_load(const char *filename)
                        continue;
                }
 
+               if (version >= 107) {
+                       char *p = host;
+                       while (*p && *p != ' ') p++;
+                       while (*p && *p == ' ') { *p = '\0'; p++; }
+                       hsts_include_sub_domains = (*p == '1');
+                       while (*p && *p != ' ') p++;
+                       while (*p && *p == ' ') p++;
+                       nsc_snptimet(p, strlen(p), &hsts_expiry);
+               }
+
+               h = urldb_add_host(host);
+               if (!h) {
+                       NSLOG(netsurf, INFO, "Failed adding host: '%s'", host);
+                       fclose(fp);
+                       return NSERROR_NOMEM;
+               }
+               h->hsts.expires = hsts_expiry;
+               h->hsts.include_sub_domains = hsts_include_sub_domains;
+
                /* read number of URLs */
                if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
                        break;
@@ -2922,13 +2965,6 @@ nserror urldb_load(const char *filename)
                        continue;
                }
 
-               h = urldb_add_host(host);
-               if (!h) {
-                       NSLOG(netsurf, INFO, "Failed adding host: '%s'", host);
-                       fclose(fp);
-                       return NSERROR_NOMEM;
-               }
-
                /* load the non-corrupt data */
                for (i = 0; i < urls; i++) {
                        struct path_data *p = NULL;
@@ -3460,6 +3496,131 @@ bool urldb_get_cert_permissions(nsurl *url)
 }
 
 
+/* exported interface documented in content/urldb.h */
+bool urldb_set_hsts_policy(struct nsurl *url, const char *header)
+{
+       struct path_data *p;
+       struct host_part *h;
+       lwc_string *host;
+       time_t now = time(NULL);
+       http_strict_transport_security *sts;
+       uint32_t max_age = 0;
+       nserror error;
+
+       assert(url);
+
+       host = nsurl_get_component(url, NSURL_HOST);
+       if (host != NULL) {
+               if (urldb__host_is_ip_address(lwc_string_data(host))) {
+                       /* Host is IP: ignore */
+                       lwc_string_unref(host);
+                       return true;
+               }
+
+               lwc_string_unref(host);
+       }
+
+       /* add url, in case it's missing */
+       urldb_add_url(url);
+
+       p = urldb_find_url(url);
+       if (!p)
+               return false;
+
+       for (; p && p->parent; p = p->parent)
+               /* do nothing */;
+       assert(p);
+
+       h = (struct host_part *)p;
+       if (h->permit_invalid_certs) {
+               /* Transport is tainted: ignore */
+               return true;
+       }
+
+       error = http_parse_strict_transport_security(header, &sts);
+       if (error != NSERROR_OK) {
+               /* Parse failed: ignore */
+               return true;
+       }
+
+       h->hsts.include_sub_domains =
+               http_strict_transport_security_include_subdomains(sts);
+
+       max_age = http_strict_transport_security_max_age(sts);
+       if (max_age == 0) {
+               h->hsts.expires = 0;
+               h->hsts.include_sub_domains = false;
+       } else if (now + max_age > h->hsts.expires) {
+               h->hsts.expires = now + max_age;
+       }
+
+       http_strict_transport_security_destroy(sts);
+
+       return true;
+}
+
+
+/* exported interface documented in content/urldb.h */
+bool urldb_get_hsts_enabled(struct nsurl *url)
+{
+       struct path_data *p;
+       const struct host_part *h;
+       lwc_string *host;
+       time_t now = time(NULL);
+
+       assert(url);
+
+       host = nsurl_get_component(url, NSURL_HOST);
+       if (host != NULL) {
+               if (urldb__host_is_ip_address(lwc_string_data(host))) {
+                       /* Host is IP: not enabled */
+                       lwc_string_unref(host);
+                       return false;
+               } else if (lwc_string_length(host) == 0) {
+                       /* Host is blank: not enabled */
+                       lwc_string_unref(host);
+                       return false;
+               }
+
+               lwc_string_unref(host);
+       } else {
+               /* No host part: not enabled */
+               return false;
+       }
+
+       /* The URL must exist in the db in order to find HSTS policy, since
+        * we search up the tree from the URL node, and policy from further
+        * up may also apply. */
+       urldb_add_url(url);
+
+       p = urldb_find_url(url);
+       if (!p)
+               return false;
+
+       for (; p && p->parent; p = p->parent)
+               /* do nothing */;
+       assert(p);
+
+       h = (const struct host_part *)p;
+
+       /* Consult record for this host */
+       if (h->hsts.expires > now) {
+               /* Not expired */
+               return true;
+       }
+
+       /* Consult parent domains */
+       for (h = h->parent; h && h != &db_root; h = h->parent) {
+               if (h->hsts.expires > now && h->hsts.include_sub_domains) {
+                       /* Not expired and subdomains included */
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+
 /* exported interface documented in netsurf/url_db.h */
 void
 urldb_iterate_partial(const char *prefix,
diff --git a/content/urldb.h b/content/urldb.h
index 4aa5487..0ad6426 100644
--- a/content/urldb.h
+++ b/content/urldb.h
@@ -131,4 +131,22 @@ bool urldb_set_cookie(const char *header, struct nsurl 
*url, struct nsurl *refer
 char *urldb_get_cookie(struct nsurl *url, bool include_http_only);
 
 
+/**
+ * Set HSTS policy for an URL
+ *
+ * \param url URL being fetched
+ * \param header Strict-Transport-Security header value
+ * \return true on success, false otherwise
+ */
+bool urldb_set_hsts_policy(struct nsurl *url, const char *header);
+
+
+/**
+ * Determine if HSTS policy is enabled for an URL
+ *
+ * \param url URL being fetched
+ * \return true if HSTS policy is enabled, false otherwise
+ */
+bool urldb_get_hsts_enabled(struct nsurl *url);
+
 #endif


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=7d1c92069e3a85f1c340c52c050487ec0073d200
commit 7d1c92069e3a85f1c340c52c050487ec0073d200
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>

    HSTS: add parser for Strict-Transport-Security

diff --git a/utils/corestringlist.h b/utils/corestringlist.h
index def5a73..8d15eeb 100644
--- a/utils/corestringlist.h
+++ b/utils/corestringlist.h
@@ -86,6 +86,7 @@ CORESTRING_LWC_STRING(icon);
 CORESTRING_LWC_STRING(iframe);
 CORESTRING_LWC_STRING(image);
 CORESTRING_LWC_STRING(img);
+CORESTRING_LWC_STRING(includesubdomains);
 CORESTRING_LWC_STRING(input);
 CORESTRING_LWC_STRING(javascript);
 CORESTRING_LWC_STRING(justify);
@@ -141,6 +142,7 @@ CORESTRING_LWC_STRING(_top);
 /* unusual lwc strings */
 CORESTRING_LWC_VALUE(shortcut_icon, "shortcut icon");
 CORESTRING_LWC_VALUE(slash_, "/");
+CORESTRING_LWC_VALUE(max_age, "max-age");
 
 /* mime types */
 CORESTRING_LWC_VALUE(multipart_form_data, "multipart/form-data");
diff --git a/utils/http.h b/utils/http.h
index 173604f..00caf89 100644
--- a/utils/http.h
+++ b/utils/http.h
@@ -29,6 +29,7 @@
 
 #include "utils/http/content-disposition.h"
 #include "utils/http/content-type.h"
+#include "utils/http/strict-transport-security.h"
 #include "utils/http/www-authenticate.h"
 
 #endif
diff --git a/utils/http/Makefile b/utils/http/Makefile
index 198588b..f3bb765 100644
--- a/utils/http/Makefile
+++ b/utils/http/Makefile
@@ -1,6 +1,7 @@
 # http utils sources
 
 S_HTTP := challenge.c generics.c primitives.c parameter.c              \
-       content-disposition.c content-type.c www-authenticate.c
+       content-disposition.c content-type.c \
+       strict-transport-security.c www-authenticate.c
 
-S_HTTP := $(addprefix utils/http/,$(S_HTTP))
\ No newline at end of file
+S_HTTP := $(addprefix utils/http/,$(S_HTTP))
diff --git a/utils/http/challenge.c b/utils/http/challenge.c
index 578532e..9b85fcc 100644
--- a/utils/http/challenge.c
+++ b/utils/http/challenge.c
@@ -92,7 +92,7 @@ nserror http__parse_challenge(const char **input, 
http_challenge **challenge)
        http__skip_LWS(&pos);
 
        if (*pos == ',') {
-               error = http__item_list_parse(&pos, 
+               error = http__item_list_parse(&pos,
                                http__parse_parameter, first, &params);
                if (error != NSERROR_OK && error != NSERROR_NOT_FOUND) {
                        lwc_string_unref(scheme);
diff --git a/utils/http/content-disposition.c b/utils/http/content-disposition.c
index 5d5e94c..03bd12b 100644
--- a/utils/http/content-disposition.c
+++ b/utils/http/content-disposition.c
@@ -45,7 +45,7 @@ nserror http_parse_content_disposition(const char 
*header_value,
        http__skip_LWS(&pos);
 
        if (*pos == ';') {
-               error = http__item_list_parse(&pos, 
+               error = http__item_list_parse(&pos,
                                http__parse_parameter, NULL, &params);
                if (error != NSERROR_OK && error != NSERROR_NOT_FOUND) {
                        lwc_string_unref(mtype);
diff --git a/utils/http/content-type.c b/utils/http/content-type.c
index f84da8c..d4279f5 100644
--- a/utils/http/content-type.c
+++ b/utils/http/content-type.c
@@ -68,7 +68,7 @@ nserror http_parse_content_type(const char *header_value,
        http__skip_LWS(&pos);
 
        if (*pos == ';') {
-               error = http__item_list_parse(&pos, 
+               error = http__item_list_parse(&pos,
                                http__parse_parameter, NULL, &params);
                if (error != NSERROR_OK && error != NSERROR_NOT_FOUND) {
                        lwc_string_unref(subtype);
diff --git a/utils/http/generics.h b/utils/http/generics.h
index 8c391c4..a5af734 100644
--- a/utils/http/generics.h
+++ b/utils/http/generics.h
@@ -19,6 +19,8 @@
 #ifndef NETSURF_UTILS_HTTP_GENERICS_H_
 #define NETSURF_UTILS_HTTP_GENERICS_H_
 
+#include <stdbool.h>
+
 #include "utils/errors.h"
 
 /**
diff --git a/utils/http/strict-transport-security.c 
b/utils/http/strict-transport-security.c
new file mode 100644
index 0000000..64caf66
--- /dev/null
+++ b/utils/http/strict-transport-security.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2018 John-Mark Bell <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <limits.h>
+#include <stdlib.h>
+
+#include "utils/corestrings.h"
+#include "utils/http.h"
+
+#include "utils/http/generics.h"
+#include "utils/http/primitives.h"
+
+/**
+ * Representation of a Strict-Transport-Security
+ */
+struct http_strict_transport_security {
+       uint32_t max_age;               /**< Max age (delta seconds) */
+       bool include_sub_domains;       /**< Whether subdomains are included */
+};
+
+/**
+ * Representation of a directive
+ */
+typedef struct http_directive {
+       http__item base;
+
+       lwc_string *name;               /**< Parameter name */
+       lwc_string *value;              /**< Parameter value (optional) */
+} http_directive;
+
+
+static void http_destroy_directive(http_directive *self)
+{
+       lwc_string_unref(self->name);
+       if (self->value != NULL) {
+               lwc_string_unref(self->value);
+       }
+       free(self);
+}
+
+static nserror http__parse_directive(const char **input,
+               http_directive **result)
+{
+       const char *pos = *input;
+       lwc_string *name;
+       lwc_string *value = NULL;
+       http_directive *directive;
+       nserror error;
+
+       /* token [ "=" ( token | quoted-string ) ] */
+
+       error = http__parse_token(&pos, &name);
+       if (error != NSERROR_OK)
+               return error;
+
+       http__skip_LWS(&pos);
+
+       if (*pos == '=') {
+               pos++;
+
+               http__skip_LWS(&pos);
+
+               if (*pos == '"')
+                       error = http__parse_quoted_string(&pos, &value);
+               else
+                       error = http__parse_token(&pos, &value);
+
+               if (error != NSERROR_OK) {
+                       lwc_string_unref(name);
+                       return error;
+               }
+       }
+
+       directive = malloc(sizeof(*directive));
+       if (directive == NULL) {
+               if (value != NULL) {
+                       lwc_string_unref(value);
+               }
+               lwc_string_unref(name);
+               return NSERROR_NOMEM;
+       }
+
+       HTTP__ITEM_INIT(directive, NULL, http_destroy_directive);
+       directive->name = name;
+       directive->value = value;
+
+       *result = directive;
+       *input = pos;
+
+       return NSERROR_OK;
+}
+
+static void http_directive_list_destroy(http_directive *list)
+{
+       http__item_list_destroy(list);
+}
+
+static nserror http_directive_list_find_item(const http_directive *list,
+               lwc_string *name, lwc_string **value)
+{
+       bool match;
+
+       while (list != NULL) {
+               if (lwc_string_caseless_isequal(name, list->name,
+                               &match) == lwc_error_ok && match)
+                       break;
+
+               list = (http_directive *) list->base.next;
+       }
+
+       if (list == NULL)
+               return NSERROR_NOT_FOUND;
+
+       if (list->value != NULL) {
+               *value = lwc_string_ref(list->value);
+       } else {
+               *value = NULL;
+       }
+
+       return NSERROR_OK;
+}
+
+static const http_directive *http_directive_list_iterate(
+               const http_directive *cur,
+               lwc_string **name, lwc_string **value)
+{
+       if (cur == NULL)
+               return NULL;
+
+       *name = lwc_string_ref(cur->name);
+       if (cur->value != NULL) {
+               *value = lwc_string_ref(cur->value);
+       } else {
+               *value = NULL;
+       }
+
+       return (http_directive *) cur->base.next;
+}
+
+static uint32_t count(const http_directive *list, lwc_string *key)
+{
+       uint32_t count = 0;
+       bool match;
+
+       while (list != NULL) {
+               if (lwc_string_caseless_isequal(key, list->name,
+                               &match) == lwc_error_ok && match) {
+                       count++;
+               }
+
+               list = (http_directive *) list->base.next;
+       }
+
+       return count;
+}
+
+static bool check_duplicates(const http_directive *directives)
+{
+       bool result = true;
+       const http_directive *key = directives;
+
+       do {
+               lwc_string *name = NULL, *value = NULL;
+
+               key = http_directive_list_iterate(key, &name, &value);
+
+               result &= (count(directives, name) == 1);
+
+               lwc_string_unref(name);
+               if (value != NULL) {
+                       lwc_string_unref(value);
+               }
+       } while (key != NULL);
+
+       return result;
+}
+
+static nserror parse_max_age(lwc_string *value, uint32_t *result)
+{
+       const char *pos = lwc_string_data(value);
+       const char *end = pos + lwc_string_length(value);
+       uint32_t val = 0;
+
+       /* 1*DIGIT */
+
+       if (pos == end) {
+               /* Blank value */
+               return NSERROR_NOT_FOUND;
+       }
+
+       while (pos < end) {
+               if ('0' <= *pos && *pos <= '9') {
+                       uint32_t nv = val * 10 + (*pos - '0');
+                       if (nv < val) {
+                               val = UINT_MAX;
+                       } else {
+                               val = nv;
+                       }
+               } else {
+                       /* Non-digit */
+                       return NSERROR_NOT_FOUND;
+               }
+
+               pos++;
+       }
+
+       *result = val;
+
+       return NSERROR_OK;
+}
+
+/* See strict-transport-security.h for documentation */
+nserror http_parse_strict_transport_security(const char *header_value,
+               http_strict_transport_security **result)
+{
+       const char *pos = header_value;
+       http_strict_transport_security *sts;
+       http_directive *first = NULL;
+       http_directive *directives = NULL;
+       lwc_string *max_age_str = NULL, *isd_str = NULL;
+       uint32_t max_age;
+       bool include_sub_domains = false;
+       nserror error;
+
+       /* directive *( ";" directive ) */
+
+       http__skip_LWS(&pos);
+
+       error = http__parse_directive(&pos, &first);
+       if (error != NSERROR_OK) {
+               return error;
+       }
+
+       http__skip_LWS(&pos);
+
+       if (*pos == ';') {
+               error = http__item_list_parse(&pos,
+                               http__parse_directive, first, &directives);
+               if (error != NSERROR_OK) {
+                       if (directives != NULL) {
+                               http_directive_list_destroy(directives);
+                       }
+                       return error;
+               }
+       } else {
+               directives = first;
+       }
+
+       /* Each directive must only appear once */
+       if (check_duplicates(directives) == false) {
+               http_directive_list_destroy(directives);
+               return NSERROR_NOT_FOUND;
+       }
+
+       /* max-age is required */
+       error = http_directive_list_find_item(directives,
+                       corestring_lwc_max_age, &max_age_str);
+       if (error != NSERROR_OK || max_age_str == NULL) {
+               http_directive_list_destroy(directives);
+               return NSERROR_NOT_FOUND;
+       }
+
+       error = parse_max_age(max_age_str, &max_age);
+       if (error != NSERROR_OK) {
+               lwc_string_unref(max_age_str);
+               http_directive_list_destroy(directives);
+               return NSERROR_NOT_FOUND;
+       }
+       lwc_string_unref(max_age_str);
+
+       /* includeSubDomains is optional and valueless */
+       error = http_directive_list_find_item(directives,
+                       corestring_lwc_includesubdomains, &isd_str);
+       if (error != NSERROR_OK && error != NSERROR_NOT_FOUND) {
+               http_directive_list_destroy(directives);
+               return NSERROR_NOT_FOUND;
+       } else if (error == NSERROR_OK) {
+               if (isd_str != NULL) {
+                       /* Present, but not valueless: invalid */
+                       lwc_string_unref(isd_str);
+                       http_directive_list_destroy(directives);
+                       return NSERROR_NOT_FOUND;
+               }
+               include_sub_domains = true;
+       }
+       http_directive_list_destroy(directives);
+
+       sts = malloc(sizeof(*sts));
+       if (sts == NULL) {
+               return NSERROR_NOMEM;
+       }
+
+       sts->max_age = max_age;
+       sts->include_sub_domains = include_sub_domains;
+
+       *result = sts;
+
+       return NSERROR_OK;
+}
+
+/* See strict-transport-security.h for documentation */
+void http_strict_transport_security_destroy(
+               http_strict_transport_security *victim)
+{
+       free(victim);
+}
+
+/* See strict-transport-security.h for documentation */
+uint32_t http_strict_transport_security_max_age(
+               http_strict_transport_security *sts)
+{
+       return sts->max_age;
+}
+
+/* See strict-transport-security.h for documentation */
+bool http_strict_transport_security_include_subdomains(
+               http_strict_transport_security *sts)
+{
+       return sts->include_sub_domains;
+}
+
diff --git a/utils/http/strict-transport-security.h 
b/utils/http/strict-transport-security.h
new file mode 100644
index 0000000..4e52419
--- /dev/null
+++ b/utils/http/strict-transport-security.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2018 John-Mark Bell <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_UTILS_HTTP_STRICT_TRANSPORT_SECURITY_H_
+#define NETSURF_UTILS_HTTP_STRICT_TRANSPORT_SECURITY_H_
+
+#include <libwapcaplet/libwapcaplet.h>
+
+typedef struct http_strict_transport_security http_strict_transport_security;
+
+/**
+ * Parse an HTTP Strict-Transport-Security header value
+ *
+ * \param header_value  Header value to parse
+ * \param result        Pointer to location to receive result
+ * \return NSERROR_OK on success,
+ *         NSERROR_NOMEM on memory exhaustion,
+ *         appropriate error otherwise
+ */
+nserror http_parse_strict_transport_security(const char *header_value,
+               http_strict_transport_security **result);
+
+/**
+ * Destroy a strict transport security object
+ *
+ * \param victim  Object to destroy
+ */
+void http_strict_transport_security_destroy(
+               http_strict_transport_security *victim);
+
+/**
+ * Get the value of a strict transport security's max-age
+ *
+ * \param sts Object to inspect
+ * \return Max age, in delta-seconds
+ */
+uint32_t http_strict_transport_security_max_age(
+               http_strict_transport_security *sts);
+
+/**
+ * Get the value of a strict transport security's includeSubDomains flag
+ *
+ * \param sts Object to inspect
+ * \return Whether subdomains should be included
+ */
+bool http_strict_transport_security_include_subdomains(
+               http_strict_transport_security *sts);
+
+#endif


commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=475a0cd5d251fe813373b0ffa4ad85033f0b6dc3
commit 475a0cd5d251fe813373b0ffa4ad85033f0b6dc3
Author: John-Mark Bell <[email protected]>
Commit: John-Mark Bell <[email protected]>

    LLCache: correct typos/grammar/etc.

diff --git a/content/llcache.c b/content/llcache.c
index 0c6f3a9..58803ea 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -86,7 +86,7 @@ struct llcache_handle {
 typedef struct llcache_object_user {
        llcache_handle *handle;         /**< Handle data for client */
 
-       bool iterator_target;           /**< This is the an iterator target */
+       bool iterator_target;           /**< This is the iterator target */
        bool queued_for_delete;         /**< This user is queued for deletion */
 
        struct llcache_object_user *prev;       /**< Previous in list */
@@ -126,7 +126,7 @@ typedef enum {
 } llcache_validate;
 
 /**
- * cache control value for invalid age.
+ * Cache control value for invalid age.
  */
 #define INVALID_AGE -1
 
@@ -150,7 +150,7 @@ typedef struct {
        char *value;            /**< Header value */
 } llcache_header;
 
-/** Current status of objects data */
+/** Current status of an object's data */
 typedef enum {
        LLCACHE_STATE_RAM = 0, /**< source data is stored in RAM only */
        LLCACHE_STATE_DISC, /**< source data is stored on disc */
@@ -191,7 +191,7 @@ struct llcache_object {
 
        /* Instrumentation. These elements are strictly for information
         * to improve the cache performance and to provide performance
-        * metrics. The values are non-authorative and must not be used to
+        * metrics. The values are non-authoritative and must not be used to
         * determine object lifetime etc.
         */
        time_t last_used; /**< time the last user was removed from the object */
@@ -791,7 +791,7 @@ static nserror llcache_fetch_process_header(llcache_object 
*object,
 /**
  * (Re)fetch an object
  *
- * sets up headers and attempts to start an actual fetch from the
+ * Sets up headers and attempts to start an actual fetch from the
  * fetchers system updating the llcache object with the new fetch on
  * successful start.
  *
@@ -1165,14 +1165,14 @@ llcache_object_remove_from_list(llcache_object *object, 
llcache_object **list)
 /**
  * Retrieve source data for an object from persistent store if necessary.
  *
- * If an objects source data has been placed in the persistent store
- * and the in memory copy released this will attempt to retrieve the
- * source data.
+ * If an object's source data has been placed in the persistent store
+ * and there is no in-memory copy, then attempt to retrieve the source
+ * data.
  *
  * \param object the object to operate on.
  * \return appropriate error code.
  */
-static nserror llcache_persist_retrieve(llcache_object *object)
+static nserror llcache_retrieve_persisted_data(llcache_object *object)
 {
        /* ensure the source data is present if necessary */
        if ((object->source_data != NULL) ||
@@ -1191,7 +1191,7 @@ static nserror llcache_persist_retrieve(llcache_object 
*object)
 }
 
 /**
- * Generate a serialised version of an objects metadata
+ * Generate a serialised version of an object's metadata
  *
  * The metadata includes object headers.
  *
@@ -1335,7 +1335,7 @@ operror:
 }
 
 /**
- * Deserialisation of an objects metadata.
+ * Deserialisation of an object's metadata.
  *
  * Attempt to retrieve and deserialise the metadata for an object from
  * the backing store.
@@ -1361,7 +1361,7 @@ llcache_process_metadata(llcache_object *object)
 
        size_t source_length;
        time_t request_time;
-       time_t reponse_time;
+       time_t response_time;
        time_t completion_time;
        size_t num_headers;
        size_t hloop;
@@ -1412,7 +1412,7 @@ llcache_process_metadata(llcache_object *object)
        nsurl_unref(metadataurl);
 
 
-       /* metadata line 2 is the objects length */
+       /* metadata line 2 is the object's length */
        line = 2;
        ln += lnsize + 1;
        lnsize = strlen(ln);
@@ -1438,7 +1438,7 @@ llcache_process_metadata(llcache_object *object)
        ln += lnsize + 1;
        lnsize = strlen(ln);
 
-       res = nsc_snptimet(ln, lnsize, &reponse_time);
+       res = nsc_snptimet(ln, lnsize, &response_time);
        if (res != NSERROR_OK)
                goto format_error;
 
@@ -1485,7 +1485,7 @@ llcache_process_metadata(llcache_object *object)
        object->source_alloc = metadatalen;
 
        object->cache.req_time = request_time;
-       object->cache.res_time = reponse_time;
+       object->cache.res_time = response_time;
        object->cache.fin_time = completion_time;
 
        /* object stored in backing store */
@@ -1514,7 +1514,7 @@ format_error:
  *         cache else appropriate error code.
  */
 static nserror
-llcache_object_fetch_persistant(llcache_object *object,
+llcache_object_fetch_persistent(llcache_object *object,
                                uint32_t flags,
                                nsurl *referer,
                                const llcache_post_data *post,
@@ -1604,7 +1604,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
                        return error;
 
                /* attempt to retrieve object from persistent store */
-               error = llcache_object_fetch_persistant(obj, flags, referer, 
post, redirect_count);
+               error = llcache_object_fetch_persistent(obj, flags, referer, 
post, redirect_count);
                if (error == NSERROR_OK) {
                        NSLOG(llcache, DEBUG, "retrieved object from persistent 
store");
 
@@ -1631,7 +1631,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
                 */
 
                /* ensure the source data is present */
-               error = llcache_persist_retrieve(newest);
+               error = llcache_retrieve_persisted_data(newest);
                if (error == NSERROR_OK) {
                        /* source data was successfully retrieved from
                         * persistent store
@@ -1658,7 +1658,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
                /* Found a candidate object but it needs freshness validation */
 
                /* ensure the source data is present */
-               error = llcache_persist_retrieve(newest);
+               error = llcache_retrieve_persisted_data(newest);
                if (error == NSERROR_OK) {
 
                        /* Create a new object */
@@ -3444,8 +3444,8 @@ static void llcache_catch_up_all_users(void *ignored)
        llcache_object *object;
 
        /* Assume after this we'll be all caught up.  If any user of a handle
-        * defers then we'll end up set not caught up and we'll
-        * reschedule at that point via llcache_users_not_caught_up()
+        * defers then we'll invalidate all_caught_up and reschedule via
+        * llcache_users_not_caught_up()
         */
        llcache->all_caught_up = true;
 


-----------------------------------------------------------------------


-- 
NetSurf Browser

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to