From a54abf6b118f033cd25523e530cb0816d8184f8c Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Tue, 25 Nov 2014 22:53:16 +0100 Subject: [PATCH] Change main HSTS URI in navigation-policy-decision-requested scope (#146). In case a URL is rewritten to http for a host that is a known hsts host, the soup session feature rewrites the uri to https like expected. But webkit does not honor the changed scheme and port and does still return the http uri in webkit_web_view_get_uri(). To avoid irritations, the URI of the main request is checked in scope of navigation-policy-decision-requested event. If the uri must be changed, the changed uri is used for webkit_web_view_load_uri() to start a new request. --- src/hsts.c | 38 ++++++++++++++++++++++++++++++++++++++ src/hsts.h | 1 + src/main.c | 14 ++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/src/hsts.c b/src/hsts.c index d8f3ddf..9ac0603 100644 --- a/src/hsts.c +++ b/src/hsts.c @@ -69,6 +69,44 @@ static void request_unqueued(SoupSessionFeature *feature, static void load_entries(HSTSProvider *provider, const char *file); static void save_entries(HSTSProvider *provider, const char *file); +/** + * Change scheme and port of soup messages uri if the host is a known and + * valid hsts host. + * + * This logic should be implemented in request_queued function but the changes + * that are done there to the uri do not appear in webkit_web_view_get_uri(). + * If a valid hsts host is requested via http and the url is changed to https + * vimb would still show the http uri in url bar. This seems to be a + * missbehaviour in webkit, but for now we provide this function to put in the + * logic in the scope of the navigation-policy-decision-requested event of the + * webview. + * + * Returns newly allocated string with new URI if the URI was change to + * fullfill HSTS, else NULL. + */ +char *hsts_get_changed_uri(SoupSession* session, SoupMessage *msg) +{ + SoupSessionFeature *feature; + HSTSProvider *provider; + SoupURI *uri; + + feature = soup_session_get_feature_for_message(session, HSTS_TYPE_PROVIDER, msg); + uri = soup_message_get_uri(msg); + if (!feature || !uri) { + return NULL; + } + + provider = HSTS_PROVIDER(feature); + /* if URI uses still https we don't nee to rewrite it */ + if (uri->scheme != SOUP_URI_SCHEME_HTTPS + && should_secure_host(provider, uri->host) + ) { + /* the ports is set by soup uri if scheme is changed */ + soup_uri_set_scheme(uri, SOUP_URI_SCHEME_HTTPS); + return soup_uri_to_string(uri, false); + } + return NULL; +} /** * Generates a new hsts provider instance. diff --git a/src/hsts.h b/src/hsts.h index 92dc972..6fe24cd 100644 --- a/src/hsts.h +++ b/src/hsts.h @@ -44,6 +44,7 @@ typedef struct { } HSTSProviderClass; +char *hsts_get_changed_uri(SoupSession* session, SoupMessage *msg); GType hsts_provider_get_type(void); HSTSProvider *hsts_provider_new(void); diff --git a/src/main.c b/src/main.c index ee1cd61..8229c68 100644 --- a/src/main.c +++ b/src/main.c @@ -1236,6 +1236,20 @@ static gboolean navigation_decision_requested_cb(WebKitWebView *view, WebKitWebNavigationAction *action, WebKitWebPolicyDecision *policy, gpointer data) { +#ifdef FEATURE_HSTS + char *uri; + SoupMessage *msg = webkit_network_request_get_message(request); + + /* change uri for known and valid hsts hosts */ + uri = hsts_get_changed_uri(vb.session, msg); + if (uri) { + webkit_web_view_load_uri(view, uri); + + /* mark the request as handled */ + return true; + } +#endif + /* try to find a protocol handler to open the uri */ return handle_uri(webkit_network_request_get_uri(request)); } -- 2.20.1