Title: [249192] trunk
Revision
249192
Author
csaave...@igalia.com
Date
2019-08-28 03:15:36 -0700 (Wed, 28 Aug 2019)

Log Message

[GTK][WPE] Implement HSTS for the soup network backend
https://bugs.webkit.org/show_bug.cgi?id=192074

Reviewed by Carlos Garcia Campos.

libsoup 2.67.1 introduced HSTS support via a SoupSessionFeature.
Add support to the soup network backend by adding the feature to
SoupNetworkSession and handling HSTS protocol upgrades, by
propagating the scheme change further to clients. This patch adds
the HSTS feature unconditionally, but it still possible to add
a boolean property to the web context class if desired.

Additionally, add API to the WebKitWebsiteDataManager to specify
the directory where the HSTS database is saved. If the directory
is not set or if the data manager is ephemeral, use a
non-persistent, memory only HSTS enforcer.

Implement as well the methods needed to clean-up and delete HSTS
Source/WebCore:

policies from the storage and expose the feature in GTK+ MiniBrowser's
about:data.

* platform/network/soup/GUniquePtrSoup.h:
* platform/network/soup/SoupNetworkSession.cpp:
(WebCore::hstsStorageDirectory):
(WebCore::SoupNetworkSession::SoupNetworkSession):
(WebCore::SoupNetworkSession::setHSTSPersistentStorage):
(WebCore::SoupNetworkSession::setupHSTSEnforcer):
(WebCore::SoupNetworkSession::getHostNamesWithHSTSCache):
(WebCore::SoupNetworkSession::deleteHSTSCacheForHostNames):
(WebCore::SoupNetworkSession::clearHSTSCache):
* platform/network/soup/SoupNetworkSession.h:

Source/WebKit:

policies from the storage and expose the feature in GTK+
MiniBrowser's about:data.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::fetchWebsiteData):
(WebKit::NetworkProcess::deleteWebsiteData):
(WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
(WebKit::NetworkProcess::deleteWebsiteDataForRegistrableDomains):
(WebKit::NetworkProcess::registrableDomainsWithWebsiteData):
* NetworkProcess/NetworkProcess.h:
(WebKit::NetworkProcess::suppressesConnectionTerminationOnSystemChange const):
* NetworkProcess/soup/NetworkDataTaskSoup.cpp:
(WebKit::NetworkDataTaskSoup::createRequest):
(WebKit::NetworkDataTaskSoup::clearRequest):
(WebKit::NetworkDataTaskSoup::shouldAllowHSTSPolicySetting const):
(WebKit::NetworkDataTaskSoup::shouldAllowHSTSProtocolUpgrade const):
(WebKit::NetworkDataTaskSoup::protocolUpgradedViaHSTS):
(WebKit::NetworkDataTaskSoup::hstsEnforced):
* NetworkProcess/soup/NetworkDataTaskSoup.h:
* NetworkProcess/soup/NetworkProcessSoup.cpp:
(WebKit::NetworkProcess::getHostNamesWithHSTSCache):
(WebKit::NetworkProcess::deleteHSTSCacheForHostNames):
(WebKit::NetworkProcess::clearHSTSCache):
(WebKit::NetworkProcess::platformInitializeNetworkProcess):
* UIProcess/API/APIWebsiteDataStore.h:
* UIProcess/API/glib/APIWebsiteDataStoreGLib.cpp:
(API::WebsiteDataStore::defaultHSTSDirectory):
* UIProcess/API/glib/WebKitWebContext.cpp:
(webkitWebContextConstructed):
* UIProcess/API/glib/WebKitWebsiteData.cpp:
(recordContainsSupportedDataTypes):
(toWebKitWebsiteDataTypes):
* UIProcess/API/glib/WebKitWebsiteDataManager.cpp:
(webkitWebsiteDataManagerGetProperty):
(webkitWebsiteDataManagerSetProperty):
(webkitWebsiteDataManagerConstructed):
(webkit_website_data_manager_class_init):
(webkitWebsiteDataManagerGetDataStore):
(webkit_website_data_manager_get_hsts_cache_directory):
(toWebsiteDataTypes):
* UIProcess/API/gtk/WebKitWebsiteData.h:
* UIProcess/API/gtk/WebKitWebsiteDataManager.h:
* UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
* UIProcess/API/wpe/WebKitWebsiteData.h:
* UIProcess/API/wpe/WebKitWebsiteDataManager.h:
* UIProcess/API/wpe/docs/wpe-1.0-sections.txt:
* UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
(WebKit::WebsiteDataStoreConfiguration::copy):
* UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
(WebKit::WebsiteDataStoreConfiguration::hstsStorageDirectory const):
(WebKit::WebsiteDataStoreConfiguration::setHSTSStorageDirectory):

Tools:

policies from the storage and expose the feature in GTK+
MiniBrowser's about:data.

* MiniBrowser/gtk/main.c:
(gotWebsiteDataCallback):
* TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp:
(serverCallback):
(testWebsiteDataConfiguration):
(testWebsiteDataEphemeral):
(prepopulateHstsData):
(testWebsiteDataHsts):
(beforeAll):
* TestWebKitAPI/glib/WebKitGLib/TestMain.h:
(Test::Test):
* gtk/jhbuild.modules: Bump libsoup to 2.67.91 for the new APIs
* wpe/jhbuild.modules: Ditto
* MiniBrowser/gtk/main.c:
(gotWebsiteDataCallback):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (249191 => 249192)


--- trunk/Source/WebCore/ChangeLog	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebCore/ChangeLog	2019-08-28 10:15:36 UTC (rev 249192)
@@ -1,3 +1,37 @@
+2019-08-28  Claudio Saavedra  <csaave...@igalia.com>
+
+        [GTK][WPE] Implement HSTS for the soup network backend
+        https://bugs.webkit.org/show_bug.cgi?id=192074
+
+        Reviewed by Carlos Garcia Campos.
+
+        libsoup 2.67.1 introduced HSTS support via a SoupSessionFeature.
+        Add support to the soup network backend by adding the feature to
+        SoupNetworkSession and handling HSTS protocol upgrades, by
+        propagating the scheme change further to clients. This patch adds
+        the HSTS feature unconditionally, but it still possible to add
+        a boolean property to the web context class if desired.
+
+        Additionally, add API to the WebKitWebsiteDataManager to specify
+        the directory where the HSTS database is saved. If the directory
+        is not set or if the data manager is ephemeral, use a
+        non-persistent, memory only HSTS enforcer.
+
+        Implement as well the methods needed to clean-up and delete HSTS
+        policies from the storage and expose the feature in GTK+ MiniBrowser's
+        about:data.
+
+        * platform/network/soup/GUniquePtrSoup.h:
+        * platform/network/soup/SoupNetworkSession.cpp:
+        (WebCore::hstsStorageDirectory):
+        (WebCore::SoupNetworkSession::SoupNetworkSession):
+        (WebCore::SoupNetworkSession::setHSTSPersistentStorage):
+        (WebCore::SoupNetworkSession::setupHSTSEnforcer):
+        (WebCore::SoupNetworkSession::getHostNamesWithHSTSCache):
+        (WebCore::SoupNetworkSession::deleteHSTSCacheForHostNames):
+        (WebCore::SoupNetworkSession::clearHSTSCache):
+        * platform/network/soup/SoupNetworkSession.h:
+
 2019-08-28  Said Abou-Hallawa  <sabouhall...@apple.com>
 
         SVG2: Add length, item getter and item setter to all SVG lists

Modified: trunk/Source/WebCore/platform/network/soup/GUniquePtrSoup.h (249191 => 249192)


--- trunk/Source/WebCore/platform/network/soup/GUniquePtrSoup.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebCore/platform/network/soup/GUniquePtrSoup.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -32,6 +32,9 @@
 WTF_DEFINE_GPTR_DELETER(SoupCookie, soup_cookie_free)
 WTF_DEFINE_GPTR_DELETER(SoupMessageHeaders, soup_message_headers_free)
 WTF_DEFINE_GPTR_DELETER(SoupBuffer, soup_buffer_free)
+#if SOUP_CHECK_VERSION(2, 67, 1)
+WTF_DEFINE_GPTR_DELETER(SoupHSTSPolicy, soup_hsts_policy_free)
+#endif
 
 } // namespace WTF
 

Modified: trunk/Source/WebCore/platform/network/soup/SoupNetworkSession.cpp (249191 => 249192)


--- trunk/Source/WebCore/platform/network/soup/SoupNetworkSession.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebCore/platform/network/soup/SoupNetworkSession.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -59,6 +59,12 @@
     return settings.get();
 }
 
+static CString& hstsStorageDirectory()
+{
+    static NeverDestroyed<CString> directory;
+    return directory.get();
+}
+
 #if !LOG_DISABLED
 inline static void soupLogPrinter(SoupLogger*, SoupLoggerLogLevel, char direction, const char* data, gpointer)
 {
@@ -108,6 +114,7 @@
 
 SoupNetworkSession::SoupNetworkSession(PAL::SessionID sessionID)
     : m_soupSession(adoptGRef(soup_session_new()))
+    , m_sessionID(sessionID)
 {
     // Values taken from http://www.browserscope.org/ following
     // the rule "Do What Every Other Modern Browser Is Doing". They seem
@@ -132,7 +139,7 @@
     if (!initialAcceptLanguages().isNull())
         setAcceptLanguages(initialAcceptLanguages());
 
-    if (soup_auth_negotiate_supported() && !sessionID.isEphemeral()) {
+    if (soup_auth_negotiate_supported() && !m_sessionID.isEphemeral()) {
         g_object_set(m_soupSession.get(),
             SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_AUTH_NEGOTIATE,
             nullptr);
@@ -141,6 +148,7 @@
     if (proxySettings().mode != SoupNetworkProxySettings::Mode::Default)
         setupProxy();
     setupLogger();
+    setupHSTSEnforcer();
 }
 
 SoupNetworkSession::~SoupNetworkSession() = default;
@@ -169,6 +177,88 @@
     return SOUP_COOKIE_JAR(soup_session_get_feature(m_soupSession.get(), SOUP_TYPE_COOKIE_JAR));
 }
 
+void SoupNetworkSession::setHSTSPersistentStorage(const CString& directory)
+{
+    hstsStorageDirectory() = directory;
+}
+
+void SoupNetworkSession::setupHSTSEnforcer()
+{
+#if SOUP_CHECK_VERSION(2, 67, 1)
+    if (soup_session_has_feature(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER))
+        soup_session_remove_feature_by_type(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER);
+
+    GRefPtr<SoupHSTSEnforcer> enforcer;
+    if (m_sessionID.isEphemeral() || hstsStorageDirectory().isNull())
+        enforcer = adoptGRef(soup_hsts_enforcer_new());
+    else {
+        if (FileSystem::makeAllDirectories(hstsStorageDirectory().data())) {
+            CString storagePath = FileSystem::fileSystemRepresentation(hstsStorageDirectory().data());
+            GUniquePtr<char> dbFilename(g_build_filename(storagePath.data(), "hsts-storage.sqlite", nullptr));
+            enforcer = adoptGRef(soup_hsts_enforcer_db_new(dbFilename.get()));
+        } else {
+            RELEASE_LOG_ERROR("Unable to create the HSTS storage directory \"%s\". Using a memory enforcer instead.", hstsStorageDirectory.data());
+            enforcer = adoptGRef(soup_hsts_enforcer_new());
+        }
+    }
+    soup_session_add_feature(m_soupSession.get(), SOUP_SESSION_FEATURE(enforcer.get()));
+#endif
+}
+
+void SoupNetworkSession::getHostNamesWithHSTSCache(HashSet<String>& hostNames)
+{
+#if SOUP_CHECK_VERSION(2, 67, 91)
+    SoupHSTSEnforcer* enforcer = SOUP_HSTS_ENFORCER(soup_session_get_feature(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER));
+    if (!enforcer)
+        return;
+
+    GUniquePtr<GList> domains(soup_hsts_enforcer_get_domains(enforcer, FALSE));
+    for (GList* iter = domains.get(); iter; iter = iter->next) {
+        GUniquePtr<gchar> domain(static_cast<gchar*>(iter->data));
+        hostNames.add(String::fromUTF8(domain.get()));
+    }
+#else
+    UNUSED_PARAM(hostNames);
+#endif
+}
+
+void SoupNetworkSession::deleteHSTSCacheForHostNames(const Vector<String>& hostNames)
+{
+#if SOUP_CHECK_VERSION(2, 67, 1)
+    SoupHSTSEnforcer* enforcer = SOUP_HSTS_ENFORCER(soup_session_get_feature(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER));
+    if (!enforcer)
+        return;
+
+    for (const auto& hostName : hostNames) {
+        GUniquePtr<SoupHSTSPolicy> policy(soup_hsts_policy_new(hostName.utf8().data(), SOUP_HSTS_POLICY_MAX_AGE_PAST, FALSE));
+        soup_hsts_enforcer_set_policy(enforcer, policy.get());
+    }
+#else
+    UNUSED_PARAM(hostNames);
+#endif
+}
+
+void SoupNetworkSession::clearHSTSCache(WallTime modifiedSince)
+{
+#if SOUP_CHECK_VERSION(2, 67, 91)
+    SoupHSTSEnforcer* enforcer = SOUP_HSTS_ENFORCER(soup_session_get_feature(m_soupSession.get(), SOUP_TYPE_HSTS_ENFORCER));
+    if (!enforcer)
+        return;
+
+    GUniquePtr<GList> policies(soup_hsts_enforcer_get_policies(enforcer, FALSE));
+    for (GList* iter = policies.get(); iter != nullptr; iter = iter->next) {
+        GUniquePtr<SoupHSTSPolicy> policy(static_cast<SoupHSTSPolicy*>(iter->data));
+        auto modified = soup_date_to_time_t(policy.get()->expires) - policy.get()->max_age;
+        if (modified >= modifiedSince.secondsSinceEpoch().seconds()) {
+            GUniquePtr<SoupHSTSPolicy> newPolicy(soup_hsts_policy_new(policy.get()->domain, SOUP_HSTS_POLICY_MAX_AGE_PAST, FALSE));
+            soup_hsts_enforcer_set_policy(enforcer, newPolicy.get());
+        }
+    }
+#else
+    UNUSED_PARAM(modifiedSince);
+#endif
+}
+
 static inline bool stringIsNumeric(const char* str)
 {
     while (*str) {

Modified: trunk/Source/WebCore/platform/network/soup/SoupNetworkSession.h (249191 => 249192)


--- trunk/Source/WebCore/platform/network/soup/SoupNetworkSession.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebCore/platform/network/soup/SoupNetworkSession.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -57,6 +57,9 @@
     void setCookieJar(SoupCookieJar*);
     SoupCookieJar* cookieJar() const;
 
+    static void setHSTSPersistentStorage(const CString& hstsStorageDirectory);
+    void setupHSTSEnforcer();
+
     static void clearOldSoupCache(const String& cacheDirectory);
 
     static void setProxySettings(const SoupNetworkProxySettings&);
@@ -72,10 +75,15 @@
     static void setCustomProtocolRequestType(GType);
     void setupCustomProtocols();
 
+    void getHostNamesWithHSTSCache(HashSet<String>&);
+    void deleteHSTSCacheForHostNames(const Vector<String>&);
+    void clearHSTSCache(WallTime);
+
 private:
     void setupLogger();
 
     GRefPtr<SoupSession> m_soupSession;
+    PAL::SessionID m_sessionID;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (249191 => 249192)


--- trunk/Source/WebKit/ChangeLog	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/ChangeLog	2019-08-28 10:15:36 UTC (rev 249192)
@@ -1,3 +1,75 @@
+2019-08-28  Claudio Saavedra  <csaave...@igalia.com>
+
+        [GTK][WPE] Implement HSTS for the soup network backend
+        https://bugs.webkit.org/show_bug.cgi?id=192074
+
+        Reviewed by Carlos Garcia Campos.
+
+        libsoup 2.67.1 introduced HSTS support via a SoupSessionFeature.
+        Add support to the soup network backend by adding the feature to
+        SoupNetworkSession and handling HSTS protocol upgrades, by
+        propagating the scheme change further to clients. This patch adds
+        the HSTS feature unconditionally, but it still possible to add
+        a boolean property to the web context class if desired.
+
+        Additionally, add API to the WebKitWebsiteDataManager to specify
+        the directory where the HSTS database is saved. If the directory
+        is not set or if the data manager is ephemeral, use a
+        non-persistent, memory only HSTS enforcer.
+
+        Implement as well the methods needed to clean-up and delete HSTS
+        policies from the storage and expose the feature in GTK+
+        MiniBrowser's about:data.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::fetchWebsiteData):
+        (WebKit::NetworkProcess::deleteWebsiteData):
+        (WebKit::NetworkProcess::deleteWebsiteDataForOrigins):
+        (WebKit::NetworkProcess::deleteWebsiteDataForRegistrableDomains):
+        (WebKit::NetworkProcess::registrableDomainsWithWebsiteData):
+        * NetworkProcess/NetworkProcess.h:
+        (WebKit::NetworkProcess::suppressesConnectionTerminationOnSystemChange const):
+        * NetworkProcess/soup/NetworkDataTaskSoup.cpp:
+        (WebKit::NetworkDataTaskSoup::createRequest):
+        (WebKit::NetworkDataTaskSoup::clearRequest):
+        (WebKit::NetworkDataTaskSoup::shouldAllowHSTSPolicySetting const):
+        (WebKit::NetworkDataTaskSoup::shouldAllowHSTSProtocolUpgrade const):
+        (WebKit::NetworkDataTaskSoup::protocolUpgradedViaHSTS):
+        (WebKit::NetworkDataTaskSoup::hstsEnforced):
+        * NetworkProcess/soup/NetworkDataTaskSoup.h:
+        * NetworkProcess/soup/NetworkProcessSoup.cpp:
+        (WebKit::NetworkProcess::getHostNamesWithHSTSCache):
+        (WebKit::NetworkProcess::deleteHSTSCacheForHostNames):
+        (WebKit::NetworkProcess::clearHSTSCache):
+        (WebKit::NetworkProcess::platformInitializeNetworkProcess):
+        * UIProcess/API/APIWebsiteDataStore.h:
+        * UIProcess/API/glib/APIWebsiteDataStoreGLib.cpp:
+        (API::WebsiteDataStore::defaultHSTSDirectory):
+        * UIProcess/API/glib/WebKitWebContext.cpp:
+        (webkitWebContextConstructed):
+        * UIProcess/API/glib/WebKitWebsiteData.cpp:
+        (recordContainsSupportedDataTypes):
+        (toWebKitWebsiteDataTypes):
+        * UIProcess/API/glib/WebKitWebsiteDataManager.cpp:
+        (webkitWebsiteDataManagerGetProperty):
+        (webkitWebsiteDataManagerSetProperty):
+        (webkitWebsiteDataManagerConstructed):
+        (webkit_website_data_manager_class_init):
+        (webkitWebsiteDataManagerGetDataStore):
+        (webkit_website_data_manager_get_hsts_cache_directory):
+        (toWebsiteDataTypes):
+        * UIProcess/API/gtk/WebKitWebsiteData.h:
+        * UIProcess/API/gtk/WebKitWebsiteDataManager.h:
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
+        * UIProcess/API/wpe/WebKitWebsiteData.h:
+        * UIProcess/API/wpe/WebKitWebsiteDataManager.h:
+        * UIProcess/API/wpe/docs/wpe-1.0-sections.txt:
+        * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
+        (WebKit::WebsiteDataStoreConfiguration::copy):
+        * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
+        (WebKit::WebsiteDataStoreConfiguration::hstsStorageDirectory const):
+        (WebKit::WebsiteDataStoreConfiguration::setHSTSStorageDirectory):
+
 2019-08-27  Mark Lam  <mark....@apple.com>
 
         Refactor to use VM& instead of VM* at as many places as possible.

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (249191 => 249192)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -1349,7 +1349,7 @@
         });
     }
 
-#if PLATFORM(COCOA)
+#if PLATFORM(COCOA) || USE(SOUP)
     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
         if (auto* networkStorageSession = storageSession(sessionID))
             getHostNamesWithHSTSCache(*networkStorageSession, callbackAggregator->m_websiteData.hostNamesWithHSTSCache);
@@ -1389,7 +1389,7 @@
 
 void NetworkProcess::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, WallTime modifiedSince, uint64_t callbackID)
 {
-#if PLATFORM(COCOA)
+#if PLATFORM(COCOA) || USE(SOUP)
     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
         if (auto* networkStorageSession = storageSession(sessionID))
             clearHSTSCache(*networkStorageSession, modifiedSince);
@@ -1490,7 +1490,7 @@
             networkStorageSession->deleteCookiesForHostnames(cookieHostNames);
     }
 
-#if PLATFORM(COCOA)
+#if PLATFORM(COCOA) || USE(SOUP)
     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
         if (auto* networkStorageSession = storageSession(sessionID))
             deleteHSTSCacheForHostNames(*networkStorageSession, HSTSCacheHostNames);
@@ -1672,7 +1672,7 @@
     }
 
     Vector<String> hostnamesWithHSTSToDelete;
-#if PLATFORM(COCOA)
+#if PLATFORM(COCOA) || USE(SOUP)
     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
         if (auto* networkStorageSession = storageSession(sessionID)) {
             getHostNamesWithHSTSCache(*networkStorageSession, hostNamesWithHSTSCache);
@@ -1853,7 +1853,7 @@
     }
     
     Vector<String> hostnamesWithHSTSToDelete;
-#if PLATFORM(COCOA)
+#if PLATFORM(COCOA) || USE(SOUP)
     if (websiteDataTypes.contains(WebsiteDataType::HSTSCache)) {
         if (auto* networkStorageSession = storageSession(sessionID))
             getHostNamesWithHSTSCache(*networkStorageSession, websiteDataStore.hostNamesWithHSTSCache);

Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (249191 => 249192)


--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -193,10 +193,12 @@
 
 #if PLATFORM(COCOA)
     RetainPtr<CFDataRef> sourceApplicationAuditData() const;
+    bool suppressesConnectionTerminationOnSystemChange() const { return m_suppressesConnectionTerminationOnSystemChange; }
+#endif
+#if PLATFORM(COCOA) || USE(SOUP)
     void getHostNamesWithHSTSCache(WebCore::NetworkStorageSession&, HashSet<String>&);
     void deleteHSTSCacheForHostNames(WebCore::NetworkStorageSession&, const Vector<String>&);
     void clearHSTSCache(WebCore::NetworkStorageSession&, WallTime modifiedSince);
-    bool suppressesConnectionTerminationOnSystemChange() const { return m_suppressesConnectionTerminationOnSystemChange; }
 #endif
 
     void findPendingDownloadLocation(NetworkDataTask&, ResponseCompletionHandler&&, const WebCore::ResourceResponse&);

Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp (249191 => 249192)


--- trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -38,6 +38,7 @@
 #include <WebCore/HTTPParsers.h>
 #include <WebCore/MIMETypeRegistry.h>
 #include <WebCore/NetworkStorageSession.h>
+#include <WebCore/PublicSuffix.h>
 #include <WebCore/SharedBuffer.h>
 #include <WebCore/SoupNetworkSession.h>
 #include <WebCore/TextEncoding.h>
@@ -147,6 +148,13 @@
 #endif
     }
 
+#if SOUP_CHECK_VERSION(2, 67, 1)
+    if ((m_currentRequest.url().protocolIs("https") && !shouldAllowHSTSPolicySetting()) || (m_currentRequest.url().protocolIs("http") && !shouldAllowHSTSProtocolUpgrade()))
+        soup_message_disable_feature(soupMessage.get(), SOUP_TYPE_HSTS_ENFORCER);
+    else
+        g_signal_connect(soup_session_get_feature(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), SOUP_TYPE_HSTS_ENFORCER), "hsts-enforced", G_CALLBACK(hstsEnforced), this);
+#endif
+
     // Make sure we have an Accept header for subresources; some sites want this to serve some of their subresources.
     if (!soup_message_headers_get_one(soupMessage->request_headers, "Accept"))
         soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*");
@@ -192,8 +200,12 @@
             soup_session_cancel_message(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), m_soupMessage.get(), SOUP_STATUS_CANCELLED);
         m_soupMessage = nullptr;
     }
-    if (m_session)
+    if (m_session) {
         g_signal_handlers_disconnect_matched(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
+#if SOUP_CHECK_VERSION(2, 67, 1)
+        g_signal_handlers_disconnect_by_data(soup_session_get_feature(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), SOUP_TYPE_HSTS_ENFORCER), this);
+#endif
+    }
 }
 
 void NetworkDataTaskSoup::resume()
@@ -1060,6 +1072,45 @@
     task->didStartRequest();
 }
 
+#if SOUP_CHECK_VERSION(2, 67, 1)
+bool NetworkDataTaskSoup::shouldAllowHSTSPolicySetting() const
+{
+    // Follow Apple's HSTS abuse mitigation 1:
+    //  "Limit HSTS State to the Hostname, or the Top Level Domain + 1"
+    if (isTopLevelNavigation() || hostsAreEqual(m_currentRequest.url(), m_currentRequest.firstPartyForCookies()) || isPublicSuffix(m_currentRequest.url().host().toStringWithoutCopying()))
+        return true;
+
+    return false;
+}
+
+bool NetworkDataTaskSoup::shouldAllowHSTSProtocolUpgrade() const
+{
+    // Follow Apple's HSTS abuse mitgation 2:
+    // "Ignore HSTS State for Subresource Requests to Blocked Domains"
+    if (!isTopLevelNavigation() && !m_currentRequest.allowCookies())
+        return false;
+
+    return true;
+}
+
+void NetworkDataTaskSoup::protocolUpgradedViaHSTS(SoupMessage* soupMessage)
+{
+    m_response = ResourceResponse::syntheticRedirectResponse(m_currentRequest.url(), soupURIToURL(soup_message_get_uri(soupMessage)));
+    continueHTTPRedirection();
+}
+
+void NetworkDataTaskSoup::hstsEnforced(SoupHSTSEnforcer*, SoupMessage* soupMessage, NetworkDataTaskSoup* task)
+{
+    if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+        task->clearRequest();
+        return;
+    }
+
+    if (soupMessage == task->m_soupMessage.get())
+        task->protocolUpgradedViaHSTS(soupMessage);
+}
+#endif
+
 void NetworkDataTaskSoup::didStartRequest()
 {
     m_networkLoadMetrics.requestStart = MonotonicTime::now() - m_startTime;

Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h (249191 => 249192)


--- trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -112,6 +112,12 @@
 #else
     static void requestStartedCallback(SoupSession*, SoupMessage*, SoupSocket*, NetworkDataTaskSoup*);
 #endif
+#if SOUP_CHECK_VERSION(2, 67, 1)
+    bool shouldAllowHSTSPolicySetting() const;
+    bool shouldAllowHSTSProtocolUpgrade() const;
+    void protocolUpgradedViaHSTS(SoupMessage*);
+    static void hstsEnforced(SoupHSTSEnforcer*, SoupMessage*, NetworkDataTaskSoup*);
+#endif
     void didStartRequest();
     static void restartedCallback(SoupMessage*, NetworkDataTaskSoup*);
     void didRestart();

Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp (249191 => 249192)


--- trunk/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkProcessSoup.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -95,6 +95,24 @@
     return builder.toString().utf8();
 }
 
+void NetworkProcess::getHostNamesWithHSTSCache(WebCore::NetworkStorageSession& storageSession, HashSet<String>& hostNames)
+{
+    const auto* session = static_cast<NetworkSessionSoup*>(networkSession(storageSession.sessionID()));
+    session->soupNetworkSession().getHostNamesWithHSTSCache(hostNames);
+}
+
+void NetworkProcess::deleteHSTSCacheForHostNames(WebCore::NetworkStorageSession& storageSession, const Vector<String>& hostNames)
+{
+    const auto* session = static_cast<NetworkSessionSoup*>(networkSession(storageSession.sessionID()));
+    session->soupNetworkSession().deleteHSTSCacheForHostNames(hostNames);
+}
+
+void NetworkProcess::clearHSTSCache(WebCore::NetworkStorageSession& storageSession, WallTime modifiedSince)
+{
+    const auto* session = static_cast<NetworkSessionSoup*>(networkSession(storageSession.sessionID()));
+    session->soupNetworkSession().clearHSTSCache(modifiedSince);
+}
+
 void NetworkProcess::userPreferredLanguagesChanged(const Vector<String>& languages)
 {
     auto acceptLanguages = buildAcceptLanguages(languages);
@@ -129,6 +147,12 @@
         userPreferredLanguagesChanged(parameters.languages);
 
     setIgnoreTLSErrors(parameters.ignoreTLSErrors);
+
+    if (!parameters.hstsStorageDirectory.isEmpty())
+        SoupNetworkSession::setHSTSPersistentStorage(parameters.hstsStorageDirectory.utf8());
+    forEachNetworkSession([](const auto& session) {
+        static_cast<const NetworkSessionSoup&>(session).soupNetworkSession().setupHSTSEnforcer();
+    });
 }
 
 std::unique_ptr<WebCore::NetworkStorageSession> NetworkProcess::platformCreateDefaultStorageSession() const

Modified: trunk/Source/WebKit/UIProcess/API/APIWebsiteDataStore.h (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/APIWebsiteDataStore.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/APIWebsiteDataStore.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -66,6 +66,9 @@
     static WTF::String defaultMediaKeysStorageDirectory();
     static WTF::String defaultDeviceIdHashSaltsStorageDirectory();
     static WTF::String defaultWebSQLDatabaseDirectory();
+#if USE(GLIB)
+    static WTF::String defaultHSTSDirectory();
+#endif
     static WTF::String defaultResourceLoadStatisticsDirectory();
     static WTF::String defaultJavaScriptConfigurationDirectory();
 

Modified: trunk/Source/WebKit/UIProcess/API/glib/APIWebsiteDataStoreGLib.cpp (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/glib/APIWebsiteDataStoreGLib.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/glib/APIWebsiteDataStoreGLib.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -84,6 +84,11 @@
     return websiteDataDirectoryFileSystemRepresentation(BASE_DIRECTORY G_DIR_SEPARATOR_S "databases");
 }
 
+WTF::String WebsiteDataStore::defaultHSTSDirectory()
+{
+    return websiteDataDirectoryFileSystemRepresentation(BASE_DIRECTORY G_DIR_SEPARATOR_S);
+}
+
 WTF::String WebsiteDataStore::defaultResourceLoadStatisticsDirectory()
 {
     return websiteDataDirectoryFileSystemRepresentation(BASE_DIRECTORY G_DIR_SEPARATOR_S "ResourceLoadStatistics");

Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -341,6 +341,7 @@
         configuration.setDiskCacheDirectory(FileSystem::pathByAppendingComponent(FileSystem::stringFromFileSystemRepresentation(webkit_website_data_manager_get_disk_cache_directory(priv->websiteDataManager.get())), networkCacheSubdirectory));
         configuration.setApplicationCacheDirectory(FileSystem::stringFromFileSystemRepresentation(webkit_website_data_manager_get_offline_application_cache_directory(priv->websiteDataManager.get())));
         configuration.setIndexedDBDatabaseDirectory(FileSystem::stringFromFileSystemRepresentation(webkit_website_data_manager_get_indexeddb_directory(priv->websiteDataManager.get())));
+        configuration.setHSTSStorageDirectory(FileSystem::stringFromFileSystemRepresentation(webkit_website_data_manager_get_hsts_cache_directory(priv->websiteDataManager.get())));
 ALLOW_DEPRECATED_DECLARATIONS_BEGIN
         configuration.setWebSQLDatabaseDirectory(FileSystem::stringFromFileSystemRepresentation(webkit_website_data_manager_get_websql_directory(priv->websiteDataManager.get())));
 ALLOW_DEPRECATED_DECLARATIONS_END

Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitWebsiteData.cpp (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/glib/WebKitWebsiteData.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitWebsiteData.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -73,6 +73,7 @@
         WebsiteDataType::LocalStorage,
         WebsiteDataType::WebSQLDatabases,
         WebsiteDataType::IndexedDBDatabases,
+        WebsiteDataType::HSTSCache,
 #if ENABLE(NETSCAPE_PLUGIN_API)
         WebsiteDataType::PlugInData,
 #endif
@@ -98,6 +99,8 @@
         returnValue |= WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES;
     if (types.contains(WebsiteDataType::IndexedDBDatabases))
         returnValue |= WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES;
+    if (types.contains(WebsiteDataType::HSTSCache))
+        returnValue |= WEBKIT_WEBSITE_DATA_HSTS_CACHE;
 #if ENABLE(NETSCAPE_PLUGIN_API)
     if (types.contains(WebsiteDataType::PlugInData))
         returnValue |= WEBKIT_WEBSITE_DATA_PLUGIN_DATA;

Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitWebsiteDataManager.cpp (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/glib/WebKitWebsiteDataManager.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitWebsiteDataManager.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -84,6 +84,7 @@
     PROP_APPLICATION_CACHE_DIRECTORY,
     PROP_INDEXEDDB_DIRECTORY,
     PROP_WEBSQL_DIRECTORY,
+    PROP_HSTS_CACHE_DIRECTORY,
     PROP_IS_EPHEMERAL
 };
 
@@ -101,6 +102,7 @@
     GUniquePtr<char> applicationCacheDirectory;
     GUniquePtr<char> indexedDBDirectory;
     GUniquePtr<char> webSQLDirectory;
+    GUniquePtr<char> hstsCacheDirectory;
 
     GRefPtr<WebKitCookieManager> cookieManager;
     Vector<WebProcessPool*> processPools;
@@ -136,6 +138,9 @@
         g_value_set_string(value, webkit_website_data_manager_get_websql_directory(manager));
         ALLOW_DEPRECATED_DECLARATIONS_END
         break;
+    case PROP_HSTS_CACHE_DIRECTORY:
+        g_value_set_string(value, webkit_website_data_manager_get_hsts_cache_directory(manager));
+        break;
     case PROP_IS_EPHEMERAL:
         g_value_set_boolean(value, webkit_website_data_manager_is_ephemeral(manager));
         break;
@@ -170,6 +175,9 @@
     case PROP_WEBSQL_DIRECTORY:
         manager->priv->webSQLDirectory.reset(g_value_dup_string(value));
         break;
+    case PROP_HSTS_CACHE_DIRECTORY:
+        manager->priv->hstsCacheDirectory.reset(g_value_dup_string(value));
+        break;
     case PROP_IS_EPHEMERAL:
         if (g_value_get_boolean(value))
             manager->priv->websiteDataStore = API::WebsiteDataStore::createNonPersistentDataStore();
@@ -198,6 +206,8 @@
             priv->diskCacheDirectory.reset(g_strdup(priv->baseCacheDirectory.get()));
         if (!priv->applicationCacheDirectory)
             priv->applicationCacheDirectory.reset(g_build_filename(priv->baseCacheDirectory.get(), "applications", nullptr));
+        if (!priv->hstsCacheDirectory)
+            priv->hstsCacheDirectory.reset(g_strdup(priv->baseCacheDirectory.get()));
     }
 }
 
@@ -333,6 +343,23 @@
             static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_DEPRECATED)));
 
     /**
+     * WebKitWebsiteDataManager:hsts-cache-directory:
+     *
+     * The directory where the HTTP Strict-Transport-Security (HSTS) cache will be stored.
+     *
+     * Since: 2.26
+     */
+    g_object_class_install_property(
+        gObjectClass,
+        PROP_HSTS_CACHE_DIRECTORY,
+        g_param_spec_string(
+            "hsts-cache-directory",
+            _("HSTS Cache Directory"),
+            _("The directory where the HTTP Strict-Transport-Security cache will be stored"),
+            nullptr,
+            static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
+
+    /**
      * WebKitWebsiteDataManager:is-ephemeral:
      *
      * Whether the #WebKitWebsiteDataManager is ephemeral. An ephemeral #WebKitWebsiteDataManager
@@ -374,6 +401,8 @@
             API::WebsiteDataStore::defaultApplicationCacheDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->applicationCacheDirectory.get()));
         configuration->setWebSQLDatabaseDirectory(!priv->webSQLDirectory ?
             API::WebsiteDataStore::defaultWebSQLDatabaseDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->webSQLDirectory.get()));
+        configuration->setHSTSStorageDirectory(!priv->hstsCacheDirectory ?
+            API::WebsiteDataStore::defaultHSTSDirectory() : FileSystem::stringFromFileSystemRepresentation(priv->hstsCacheDirectory.get()));
         configuration->setMediaKeysStorageDirectory(API::WebsiteDataStore::defaultMediaKeysStorageDirectory());
         priv->websiteDataStore = API::WebsiteDataStore::createLegacy(WTFMove(configuration));
     }
@@ -613,6 +642,29 @@
 }
 
 /**
+ * webkit_website_data_manager_get_hsts_cache_directory:
+ * @manager: a #WebKitWebsiteDataManager
+ *
+ * Get the #WebKitWebsiteDataManager:hsts-cache-directory property.
+ *
+ * Returns: (allow-none): the directory where the HSTS cache is stored or %NULL if @manager is ephemeral.
+ *
+ * Since: 2.26
+ */
+const gchar* webkit_website_data_manager_get_hsts_cache_directory(WebKitWebsiteDataManager* manager)
+{
+    g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr);
+
+    WebKitWebsiteDataManagerPrivate* priv = manager->priv;
+    if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent())
+        return nullptr;
+
+    if (!priv->hstsCacheDirectory)
+        priv->hstsCacheDirectory.reset(g_strdup(API::WebsiteDataStore::defaultHSTSDirectory().utf8().data()));
+    return priv->hstsCacheDirectory.get();
+}
+
+/**
  * webkit_website_data_manager_get_cookie_manager:
  * @manager: a #WebKitWebsiteDataManager
  *
@@ -649,6 +701,8 @@
         returnValue.add(WebsiteDataType::WebSQLDatabases);
     if (types & WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES)
         returnValue.add(WebsiteDataType::IndexedDBDatabases);
+    if (types & WEBKIT_WEBSITE_DATA_HSTS_CACHE)
+        returnValue.add(WebsiteDataType::HSTSCache);
 #if ENABLE(NETSCAPE_PLUGIN_API)
     if (types & WEBKIT_WEBSITE_DATA_PLUGIN_DATA)
         returnValue.add(WebsiteDataType::PlugInData);

Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteData.h (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteData.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteData.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -45,6 +45,7 @@
  * @WEBKIT_WEBSITE_DATA_PLUGIN_DATA: Plugins data.
  * @WEBKIT_WEBSITE_DATA_COOKIES: Cookies.
  * @WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT: Hash salt used to generate the device ids used by webpages. Since 2.24
+ * @WEBKIT_WEBSITE_DATA_HSTS_CACHE: HSTS cache. Since 2.26
  * @WEBKIT_WEBSITE_DATA_ALL: All types.
  *
  * Enum values with flags representing types of Website data.
@@ -62,7 +63,8 @@
     WEBKIT_WEBSITE_DATA_PLUGIN_DATA               = 1 << 7,
     WEBKIT_WEBSITE_DATA_COOKIES                   = 1 << 8,
     WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT       = 1 << 9,
-    WEBKIT_WEBSITE_DATA_ALL                       = (1 << 10) - 1
+    WEBKIT_WEBSITE_DATA_HSTS_CACHE                = 1 << 10,
+    WEBKIT_WEBSITE_DATA_ALL                       = (1 << 11) - 1
 } WebKitWebsiteDataTypes;
 
 WEBKIT_API GType

Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteDataManager.h (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteDataManager.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebsiteDataManager.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -90,6 +90,9 @@
 WEBKIT_DEPRECATED const gchar *
 webkit_website_data_manager_get_websql_directory                      (WebKitWebsiteDataManager *manager);
 
+WEBKIT_API const gchar *
+webkit_website_data_manager_get_hsts_cache_directory                  (WebKitWebsiteDataManager *manager);
+
 WEBKIT_API WebKitCookieManager *
 webkit_website_data_manager_get_cookie_manager                        (WebKitWebsiteDataManager *manager);
 

Modified: trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt	2019-08-28 10:15:36 UTC (rev 249192)
@@ -1403,6 +1403,7 @@
 webkit_website_data_manager_get_offline_application_cache_directory
 webkit_website_data_manager_get_indexeddb_directory
 webkit_website_data_manager_get_websql_directory
+webkit_website_data_manager_get_hsts_cache_directory
 webkit_website_data_manager_get_cookie_manager
 webkit_website_data_manager_fetch
 webkit_website_data_manager_fetch_finish

Modified: trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebsiteData.h (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebsiteData.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebsiteData.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -45,6 +45,7 @@
  * @WEBKIT_WEBSITE_DATA_PLUGIN_DATA: Plugins data.
  * @WEBKIT_WEBSITE_DATA_COOKIES: Cookies.
  * @WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT: Hash salt used to generate the device ids used by webpages. Since 2.24
+ * @WEBKIT_WEBSITE_DATA_HSTS_CACHE: HSTS cache. Since 2.26
  * @WEBKIT_WEBSITE_DATA_ALL: All types.
  *
  * Enum values with flags representing types of Website data.
@@ -62,7 +63,8 @@
     WEBKIT_WEBSITE_DATA_PLUGIN_DATA               = 1 << 7,
     WEBKIT_WEBSITE_DATA_COOKIES                   = 1 << 8,
     WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT       = 1 << 9,
-    WEBKIT_WEBSITE_DATA_ALL                       = (1 << 10) - 1
+    WEBKIT_WEBSITE_DATA_HSTS_CACHE                = 1 << 10,
+    WEBKIT_WEBSITE_DATA_ALL                       = (1 << 11) - 1
 } WebKitWebsiteDataTypes;
 
 WEBKIT_API GType

Modified: trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebsiteDataManager.h (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebsiteDataManager.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebsiteDataManager.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -90,6 +90,9 @@
 WEBKIT_DEPRECATED const gchar *
 webkit_website_data_manager_get_websql_directory                      (WebKitWebsiteDataManager *manager);
 
+WEBKIT_API const gchar *
+webkit_website_data_manager_get_hsts_cache_directory                  (WebKitWebsiteDataManager *manager);
+
 WEBKIT_API WebKitCookieManager *
 webkit_website_data_manager_get_cookie_manager                        (WebKitWebsiteDataManager *manager);
 

Modified: trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt	2019-08-28 10:15:36 UTC (rev 249192)
@@ -1277,6 +1277,7 @@
 webkit_website_data_manager_get_offline_application_cache_directory
 webkit_website_data_manager_get_indexeddb_directory
 webkit_website_data_manager_get_websql_directory
+webkit_website_data_manager_get_hsts_cache_directory
 webkit_website_data_manager_get_cookie_manager
 webkit_website_data_manager_fetch
 webkit_website_data_manager_fetch_finish

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -50,6 +50,9 @@
     copy->m_indexedDBDatabaseDirectory = this->m_indexedDBDatabaseDirectory;
     copy->m_serviceWorkerRegistrationDirectory = this->m_serviceWorkerRegistrationDirectory;
     copy->m_webSQLDatabaseDirectory = this->m_webSQLDatabaseDirectory;
+#if USE(GLIB)
+    copy->m_hstsStorageDirectory = this->m_hstsStorageDirectory;
+#endif
     copy->m_localStorageDirectory = this->m_localStorageDirectory;
     copy->m_mediaKeysStorageDirectory = this->m_mediaKeysStorageDirectory;
     copy->m_deviceIdHashSaltsStorageDirectory = this->m_deviceIdHashSaltsStorageDirectory;

Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h (249191 => 249192)


--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -61,7 +61,10 @@
 
     const String& webSQLDatabaseDirectory() const { return m_webSQLDatabaseDirectory; }
     void setWebSQLDatabaseDirectory(String&& directory) { m_webSQLDatabaseDirectory = WTFMove(directory); }
-
+#if USE(GLIB) // According to r245075 this will eventually move here.
+    const String& hstsStorageDirectory() const { return m_hstsStorageDirectory; }
+    void setHSTSStorageDirectory(String&& directory) { m_hstsStorageDirectory = WTFMove(directory); }
+#endif
     const String& localStorageDirectory() const { return m_localStorageDirectory; }
     void setLocalStorageDirectory(String&& directory) { m_localStorageDirectory = WTFMove(directory); }
 
@@ -118,6 +121,9 @@
     String m_indexedDBDatabaseDirectory;
     String m_serviceWorkerRegistrationDirectory;
     String m_webSQLDatabaseDirectory;
+#if USE(GLIB)
+    String m_hstsStorageDirectory;
+#endif
     String m_localStorageDirectory;
     String m_mediaKeysStorageDirectory;
     String m_deviceIdHashSaltsStorageDirectory;

Modified: trunk/Tools/ChangeLog (249191 => 249192)


--- trunk/Tools/ChangeLog	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Tools/ChangeLog	2019-08-28 10:15:36 UTC (rev 249192)
@@ -1,3 +1,42 @@
+2019-08-02  Claudio Saavedra  <csaave...@igalia.com>
+
+        [GTK][WPE] Implement HSTS for the soup network backend
+        https://bugs.webkit.org/show_bug.cgi?id=192074
+
+        Reviewed by Carlos Garcia Campos.
+
+        libsoup 2.67.1 introduced HSTS support via a SoupSessionFeature.
+        Add support to the soup network backend by adding the feature to
+        SoupNetworkSession and handling HSTS protocol upgrades, by
+        propagating the scheme change further to clients. This patch adds
+        the HSTS feature unconditionally, but it still possible to add
+        a boolean property to the web context class if desired.
+
+        Additionally, add API to the WebKitWebsiteDataManager to specify
+        the directory where the HSTS database is saved. If the directory
+        is not set or if the data manager is ephemeral, use a
+        non-persistent, memory only HSTS enforcer.
+
+        Implement as well the methods needed to clean-up and delete HSTS
+        policies from the storage and expose the feature in GTK+
+        MiniBrowser's about:data.
+
+        * MiniBrowser/gtk/main.c:
+        (gotWebsiteDataCallback):
+        * TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp:
+        (serverCallback):
+        (testWebsiteDataConfiguration):
+        (testWebsiteDataEphemeral):
+        (prepopulateHstsData):
+        (testWebsiteDataHsts):
+        (beforeAll):
+        * TestWebKitAPI/glib/WebKitGLib/TestMain.h:
+        (Test::Test):
+        * gtk/jhbuild.modules: Bump libsoup to 2.67.91 for the new APIs
+        * wpe/jhbuild.modules: Ditto
+        * MiniBrowser/gtk/main.c:
+        (gotWebsiteDataCallback):
+
 2019-08-27  James Darpinian  <jdarpin...@google.com>
 
         Fix applying diffs that only change file mode

Modified: trunk/Tools/MiniBrowser/gtk/main.c (249191 => 249192)


--- trunk/Tools/MiniBrowser/gtk/main.c	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Tools/MiniBrowser/gtk/main.c	2019-08-28 10:15:36 UTC (rev 249192)
@@ -418,6 +418,7 @@
     aboutDataFillTable(result, dataRequest, dataList, "IndexedDB Databases", WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES, webkit_website_data_manager_get_indexeddb_directory(manager), pageID);
     aboutDataFillTable(result, dataRequest, dataList, "Plugins Data", WEBKIT_WEBSITE_DATA_PLUGIN_DATA, NULL, pageID);
     aboutDataFillTable(result, dataRequest, dataList, "Offline Web Applications Cache", WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE, webkit_website_data_manager_get_offline_application_cache_directory(manager), pageID);
+    aboutDataFillTable(result, dataRequest, dataList, "HSTS Cache", WEBKIT_WEBSITE_DATA_HSTS_CACHE, webkit_website_data_manager_get_hsts_cache_directory(manager), pageID);
 
     result = g_string_append(result, "</body></html>");
     gsize streamLength = result->len;

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp (249191 => 249192)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebsiteData.cpp	2019-08-28 10:15:36 UTC (rev 249192)
@@ -19,6 +19,7 @@
 
 #include "config.h"
 
+#include <WebCore/GUniquePtrSoup.h>
 #include "WebKitTestServer.h"
 #include "WebViewTest.h"
 #include <glib/gstdio.h>
@@ -35,6 +36,7 @@
     if (g_str_equal(path, "/empty")) {
         static const char* emptyHTML = "<html><body></body></html>";
         soup_message_headers_replace(message->response_headers, "Set-Cookie", "foo=bar; Max-Age=60");
+        soup_message_headers_replace(message->response_headers, "Strict-Transport-Security", "max-age=3600");
         soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, emptyHTML, strlen(emptyHTML));
         soup_message_body_complete(message->response_body);
         soup_message_set_status(message, SOUP_STATUS_OK);
@@ -162,7 +164,12 @@
     g_assert_cmpstr(diskCacheDirectory.get(), ==, webkit_website_data_manager_get_disk_cache_directory(test->m_manager));
     g_assert_true(g_file_test(diskCacheDirectory.get(), G_FILE_TEST_IS_DIR));
 
-    // Clear all persistent caches, since the data dir is common to all test cases.
+    GUniquePtr<char> hstsCacheDirectory(g_build_filename(Test::dataDirectory(), "hsts", nullptr));
+    g_assert_cmpstr(hstsCacheDirectory.get(), ==, webkit_website_data_manager_get_hsts_cache_directory(test->m_manager));
+    g_assert_true(g_file_test(hstsCacheDirectory.get(), G_FILE_TEST_IS_DIR));
+
+    // Clear all persistent caches, since the data dir is common to all test cases. Note: not cleaning the HSTS cache here as its data
+    // is needed for the HSTS tests, where data cleaning will be tested.
     static const WebKitWebsiteDataTypes persistentCaches = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DISK_CACHE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE
         | WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES | WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE | WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
     test->clear(persistentCaches, 0);
@@ -176,6 +183,7 @@
     g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(test->m_manager), !=, webkit_website_data_manager_get_indexeddb_directory(defaultManager));
     g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_disk_cache_directory(defaultManager));
     g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_offline_application_cache_directory(defaultManager));
+    g_assert_cmpstr(webkit_website_data_manager_get_hsts_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_hsts_cache_directory(defaultManager));
 
     // Using Test::dataDirectory() we get the default configuration but for a differrent prefix.
     GRefPtr<WebKitWebsiteDataManager> baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(), nullptr));
@@ -222,6 +230,7 @@
     g_assert_null(webkit_website_data_manager_get_disk_cache_directory(manager.get()));
     g_assert_null(webkit_website_data_manager_get_offline_application_cache_directory(manager.get()));
     g_assert_null(webkit_website_data_manager_get_indexeddb_directory(manager.get()));
+    g_assert_null(webkit_website_data_manager_get_hsts_cache_directory(manager.get()));
 
     // Configuration is ignored when is-ephemeral is used.
     manager = adoptGRef(WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, "base-data-directory", Test::dataDirectory(), "is-ephemeral", TRUE, nullptr)));
@@ -483,6 +492,47 @@
     g_assert_null(dataList);
 }
 
+#if SOUP_CHECK_VERSION(2, 67, 91)
+static void prepopulateHstsData()
+{
+    // HSTS headers will be ignored in this test because the spec forbids STS policies from being honored for hosts with
+    // an IP address instead of a domain. In order to be able to test the data manager API with HSTS website data, we
+    // prepopulate the HSTS storage using the libsoup API directly.
+
+    GUniquePtr<char> hstsCacheDirectory(g_build_filename(Test::dataDirectory(), "hsts", nullptr));
+    GUniquePtr<char> hstsDatabase(g_build_filename(hstsCacheDirectory.get(), "hsts-storage.sqlite", nullptr));
+    g_mkdir_with_parents(hstsCacheDirectory.get(), 0700);
+
+    GRefPtr<SoupHSTSEnforcer> enforcer = adoptGRef(soup_hsts_enforcer_db_new(hstsDatabase.get()));
+    GUniquePtr<SoupHSTSPolicy> policy(soup_hsts_policy_new("webkitgtk.org", 3600, true));
+    soup_hsts_enforcer_set_policy(enforcer.get(), policy.get());
+
+    policy.reset(soup_hsts_policy_new("webkit.org", 3600, true));
+    soup_hsts_enforcer_set_policy(enforcer.get(), policy.get());
+}
+
+static void testWebsiteDataHsts(WebsiteDataTest* test, gconstpointer)
+{
+    GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_HSTS_CACHE);
+    g_assert_cmpuint(g_list_length(dataList), ==, 2);
+    WebKitWebsiteData* data = ""
+    g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_HSTS_CACHE);
+    // HSTS data size is unknown.
+    g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_HSTS_CACHE), ==, 0);
+
+    GList removeList = { data, nullptr, nullptr };
+    test->remove(WEBKIT_WEBSITE_DATA_HSTS_CACHE, &removeList);
+    dataList = test->fetch(WEBKIT_WEBSITE_DATA_HSTS_CACHE);
+    g_assert_cmpuint(g_list_length(dataList), ==, 1);
+    data = ""
+    g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_HSTS_CACHE);
+
+    // Remove all HSTS data.
+    test->clear(WEBKIT_WEBSITE_DATA_HSTS_CACHE, 0);
+    g_assert_null(test->fetch(WEBKIT_WEBSITE_DATA_HSTS_CACHE));
+}
+#endif
+
 static void testWebsiteDataCookies(WebsiteDataTest* test, gconstpointer)
 {
     GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES);
@@ -571,6 +621,10 @@
     kServer = new WebKitTestServer();
     kServer->run(serverCallback);
 
+#if SOUP_CHECK_VERSION(2, 67, 91)
+    prepopulateHstsData();
+#endif
+
     WebsiteDataTest::add("WebKitWebsiteData", "configuration", testWebsiteDataConfiguration);
     WebViewTest::add("WebKitWebsiteData", "ephemeral", testWebsiteDataEphemeral);
     WebsiteDataTest::add("WebKitWebsiteData", "cache", testWebsiteDataCache);
@@ -578,6 +632,9 @@
     WebsiteDataTest::add("WebKitWebsiteData", "databases", testWebsiteDataDatabases);
     WebsiteDataTest::add("WebKitWebsiteData", "appcache", testWebsiteDataAppcache);
     WebsiteDataTest::add("WebKitWebsiteData", "cookies", testWebsiteDataCookies);
+#if SOUP_CHECK_VERSION(2, 67, 91)
+    WebsiteDataTest::add("WebKitWebsiteData", "hsts", testWebsiteDataHsts);
+#endif
     WebsiteDataTest::add("WebKitWebsiteData", "deviceidhashsalt", testWebsiteDataDeviceIdHashSalt);
 }
 

Modified: trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.h (249191 => 249192)


--- trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.h	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.h	2019-08-28 10:15:36 UTC (rev 249192)
@@ -121,10 +121,11 @@
         GUniquePtr<char> diskCacheDirectory(g_build_filename(dataDirectory(), "disk-cache", nullptr));
         GUniquePtr<char> applicationCacheDirectory(g_build_filename(dataDirectory(), "appcache", nullptr));
         GUniquePtr<char> webSQLDirectory(g_build_filename(dataDirectory(), "websql", nullptr));
+        GUniquePtr<char> hstsDirectory(g_build_filename(dataDirectory(), "hsts", nullptr));
         GRefPtr<WebKitWebsiteDataManager> websiteDataManager = adoptGRef(webkit_website_data_manager_new(
             "local-storage-directory", localStorageDirectory.get(), "indexeddb-directory", indexedDBDirectory.get(),
             "disk-cache-directory", diskCacheDirectory.get(), "offline-application-cache-directory", applicationCacheDirectory.get(),
-            "websql-directory", webSQLDirectory.get(), nullptr));
+            "websql-directory", webSQLDirectory.get(), "hsts-cache-directory", hstsDirectory.get(), nullptr));
 
         m_webContext = adoptGRef(webkit_web_context_new_with_website_data_manager(websiteDataManager.get()));
         g_signal_connect(m_webContext.get(), "initialize-web-extensions", G_CALLBACK(initializeWebExtensionsCallback), this);

Modified: trunk/Tools/gtk/jhbuild.modules (249191 => 249192)


--- trunk/Tools/gtk/jhbuild.modules	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Tools/gtk/jhbuild.modules	2019-08-28 10:15:36 UTC (rev 249192)
@@ -238,9 +238,9 @@
       <dep package="glib-networking"/>
       <dep package="libpsl"/>
     </dependencies>
-    <branch module="/pub/GNOME/sources/libsoup/2.67/libsoup-${version}.tar.xz" version="2.67.90"
+    <branch module="/pub/GNOME/sources/libsoup/2.67/libsoup-${version}.tar.xz" version="2.67.91"
             repo="ftp.gnome.org"
-            hash="sha256:303686002bd7d7bf93204eebe0d5ec9f5d57d071e3411e2304d6f8bcfa97ef79">
+            hash="sha256:390b5b28263d3bdf9866fa694346caa5e4bcb986e014e3383e9b6130b706f3da">
     </branch>
   </meson>
 

Modified: trunk/Tools/wpe/jhbuild.modules (249191 => 249192)


--- trunk/Tools/wpe/jhbuild.modules	2019-08-28 07:10:44 UTC (rev 249191)
+++ trunk/Tools/wpe/jhbuild.modules	2019-08-28 10:15:36 UTC (rev 249192)
@@ -100,9 +100,9 @@
       <dep package="glib-networking"/>
       <dep package="libpsl"/>
     </dependencies>
-    <branch module="/pub/GNOME/sources/libsoup/2.67/libsoup-${version}.tar.xz" version="2.67.90"
+    <branch module="/pub/GNOME/sources/libsoup/2.67/libsoup-${version}.tar.xz" version="2.67.91"
             repo="ftp.gnome.org"
-            hash="sha256:303686002bd7d7bf93204eebe0d5ec9f5d57d071e3411e2304d6f8bcfa97ef79">
+            hash="sha256:390b5b28263d3bdf9866fa694346caa5e4bcb986e014e3383e9b6130b706f3da">
     </branch>
   </meson>
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to