1/*
2 * Copyright (C) 2014-2019 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "NetworkSessionCreationParameters.h"
29#include "WebDeviceOrientationAndMotionAccessController.h"
30#include "WebProcessLifetimeObserver.h"
31#include "WebsiteDataStoreClient.h"
32#include "WebsiteDataStoreConfiguration.h"
33#include <WebCore/Cookie.h>
34#include <WebCore/DeviceOrientationOrMotionPermissionState.h>
35#include <WebCore/SecurityOriginData.h>
36#include <WebCore/SecurityOriginHash.h>
37#include <pal/SessionID.h>
38#include <wtf/Function.h>
39#include <wtf/HashSet.h>
40#include <wtf/Identified.h>
41#include <wtf/OptionSet.h>
42#include <wtf/RefCounted.h>
43#include <wtf/RefPtr.h>
44#include <wtf/UniqueRef.h>
45#include <wtf/WeakPtr.h>
46#include <wtf/WorkQueue.h>
47#include <wtf/text/WTFString.h>
48
49#if PLATFORM(COCOA)
50#include <pal/spi/cf/CFNetworkSPI.h>
51#endif
52
53#if USE(CURL)
54#include <WebCore/CurlProxySettings.h>
55#endif
56
57#if USE(APPLE_INTERNAL_SDK)
58#include <WebKitAdditions/WebsiteDataStoreAdditions.h>
59#endif
60
61namespace API {
62class HTTPCookieStore;
63}
64
65namespace WebCore {
66class RegistrableDomain;
67class SecurityOrigin;
68}
69
70namespace WebKit {
71
72class AuthenticatorManager;
73class SecKeyProxyStore;
74class StorageManager;
75class DeviceIdHashSaltStorage;
76class WebPageProxy;
77class WebProcessPool;
78class WebResourceLoadStatisticsStore;
79enum class WebsiteDataFetchOption;
80enum class WebsiteDataType;
81struct MockWebAuthenticationConfiguration;
82struct WebsiteDataRecord;
83struct WebsiteDataStoreParameters;
84
85#if ENABLE(RESOURCE_LOAD_STATISTICS)
86enum class ShouldGrandfatherStatistics : bool;
87enum class StorageAccessStatus : uint8_t;
88enum class StorageAccessPromptStatus;
89#endif
90
91#if ENABLE(NETSCAPE_PLUGIN_API)
92struct PluginModuleInfo;
93#endif
94
95class WebsiteDataStore : public RefCounted<WebsiteDataStore>, public WebProcessLifetimeObserver, public Identified<WebsiteDataStore>, public CanMakeWeakPtr<WebsiteDataStore> {
96public:
97 static Ref<WebsiteDataStore> createNonPersistent();
98 static Ref<WebsiteDataStore> create(Ref<WebsiteDataStoreConfiguration>&&, PAL::SessionID);
99 virtual ~WebsiteDataStore();
100
101 static WebsiteDataStore* existingNonDefaultDataStoreForSessionID(PAL::SessionID);
102
103 bool isPersistent() const { return !m_sessionID.isEphemeral(); }
104 PAL::SessionID sessionID() const { return m_sessionID; }
105
106 bool resourceLoadStatisticsEnabled() const;
107 void setResourceLoadStatisticsEnabled(bool);
108 bool resourceLoadStatisticsDebugMode() const;
109 void setResourceLoadStatisticsDebugMode(bool);
110 void setResourceLoadStatisticsDebugMode(bool, CompletionHandler<void()>&&);
111
112 uint64_t perOriginStorageQuota() const { return m_resolvedConfiguration->perOriginStorageQuota(); }
113 uint64_t perThirdPartyOriginStorageQuota() const;
114 void setPerOriginStorageQuota(uint64_t quota) { m_resolvedConfiguration->setPerOriginStorageQuota(quota); }
115 const String& cacheStorageDirectory() const { return m_resolvedConfiguration->cacheStorageDirectory(); }
116 void setCacheStorageDirectory(String&& directory) { m_resolvedConfiguration->setCacheStorageDirectory(WTFMove(directory)); }
117 const String& serviceWorkerRegistrationDirectory() const { return m_resolvedConfiguration->serviceWorkerRegistrationDirectory(); }
118 void setServiceWorkerRegistrationDirectory(String&& directory) { m_resolvedConfiguration->setServiceWorkerRegistrationDirectory(WTFMove(directory)); }
119
120#if ENABLE(RESOURCE_LOAD_STATISTICS)
121 WebResourceLoadStatisticsStore* resourceLoadStatistics() const { return m_resourceLoadStatistics.get(); }
122 void clearResourceLoadStatisticsInWebProcesses(CompletionHandler<void()>&&);
123#endif
124
125 static void cloneSessionData(WebPageProxy& sourcePage, WebPageProxy& newPage);
126
127 void fetchData(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, Function<void(Vector<WebsiteDataRecord>)>&& completionHandler);
128 void removeData(OptionSet<WebsiteDataType>, WallTime modifiedSince, Function<void()>&& completionHandler);
129 void removeData(OptionSet<WebsiteDataType>, const Vector<WebsiteDataRecord>&, Function<void()>&& completionHandler);
130
131#if ENABLE(RESOURCE_LOAD_STATISTICS)
132 void fetchDataForRegistrableDomains(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, const Vector<WebCore::RegistrableDomain>&, CompletionHandler<void(Vector<WebsiteDataRecord>&&, HashSet<WebCore::RegistrableDomain>&&)>&&);
133 void clearPrevalentResource(const URL&, CompletionHandler<void()>&&);
134 void clearUserInteraction(const URL&, CompletionHandler<void()>&&);
135 void dumpResourceLoadStatistics(CompletionHandler<void(const String&)>&&);
136 void logTestingEvent(const String&);
137 void logUserInteraction(const URL&, CompletionHandler<void()>&&);
138 void getAllStorageAccessEntries(uint64_t pageID, CompletionHandler<void(Vector<String>&& domains)>&&);
139 void hasHadUserInteraction(const URL&, CompletionHandler<void(bool)>&&);
140 void isPrevalentResource(const URL&, CompletionHandler<void(bool)>&&);
141 void isRegisteredAsRedirectingTo(const URL& hostRedirectedFrom, const URL& hostRedirectedTo, CompletionHandler<void(bool)>&&);
142 void isRegisteredAsSubresourceUnder(const URL& subresource, const URL& topFrame, CompletionHandler<void(bool)>&&);
143 void isRegisteredAsSubFrameUnder(const URL& subFrame, const URL& topFrame, CompletionHandler<void(bool)>&&);
144 void isVeryPrevalentResource(const URL&, CompletionHandler<void(bool)>&&);
145 void resetParametersToDefaultValues(CompletionHandler<void()>&&);
146 void scheduleCookieBlockingUpdate(CompletionHandler<void()>&&);
147 void scheduleClearInMemoryAndPersistent(WallTime modifiedSince, ShouldGrandfatherStatistics, CompletionHandler<void()>&&);
148 void scheduleClearInMemoryAndPersistent(ShouldGrandfatherStatistics, CompletionHandler<void()>&&);
149 void scheduleStatisticsAndDataRecordsProcessing(CompletionHandler<void()>&&);
150 void submitTelemetry();
151 void setGrandfathered(const URL&, bool, CompletionHandler<void()>&&);
152 void setGrandfatheringTime(Seconds, CompletionHandler<void()>&&);
153 void setLastSeen(const URL&, Seconds, CompletionHandler<void()>&&);
154 void setNotifyPagesWhenDataRecordsWereScanned(bool, CompletionHandler<void()>&&);
155 void setIsRunningResourceLoadStatisticsTest(bool, CompletionHandler<void()>&&);
156 void setPruneEntriesDownTo(size_t, CompletionHandler<void()>&&);
157 void setSubframeUnderTopFrameDomain(const URL& subframe, const URL& topFrame, CompletionHandler<void()>&&);
158 void setSubresourceUnderTopFrameDomain(const URL& subresource, const URL& topFrame, CompletionHandler<void()>&&);
159 void setSubresourceUniqueRedirectTo(const URL& subresource, const URL& hostNameRedirectedTo, CompletionHandler<void()>&&);
160 void setSubresourceUniqueRedirectFrom(const URL& subresource, const URL& hostNameRedirectedFrom, CompletionHandler<void()>&&);
161 void setTimeToLiveUserInteraction(Seconds, CompletionHandler<void()>&&);
162 void setTopFrameUniqueRedirectTo(const URL& topFrameHostName, const URL& hostNameRedirectedTo, CompletionHandler<void()>&&);
163 void setTopFrameUniqueRedirectFrom(const URL& topFrameHostName, const URL& hostNameRedirectedFrom, CompletionHandler<void()>&&);
164 void setMaxStatisticsEntries(size_t, CompletionHandler<void()>&&);
165 void setMinimumTimeBetweenDataRecordsRemoval(Seconds, CompletionHandler<void()>&&);
166 void setNotifyPagesWhenTelemetryWasCaptured(bool, CompletionHandler<void()>&&);
167 void setPrevalentResource(const URL&, CompletionHandler<void()>&&);
168 void setPrevalentResourceForDebugMode(const URL&, CompletionHandler<void()>&&);
169 void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool, CompletionHandler<void()>&&);
170 void setStatisticsTestingCallback(WTF::Function<void(const String&)>&& callback) { m_statisticsTestingCallback = WTFMove(callback); }
171 void setVeryPrevalentResource(const URL&, CompletionHandler<void()>&&);
172 void setSubframeUnderTopFrameDomain(const URL& subframe, const URL& topFrame);
173 void setCrossSiteLoadWithLinkDecorationForTesting(const URL& fromURL, const URL& toURL, CompletionHandler<void()>&&);
174 void resetCrossSiteLoadsWithLinkDecorationForTesting(CompletionHandler<void()>&&);
175 void deleteCookiesForTesting(const URL&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
176 void hasLocalStorageForTesting(const URL&, CompletionHandler<void(bool)>&&) const;
177#endif
178 void setCacheMaxAgeCapForPrevalentResources(Seconds, CompletionHandler<void()>&&);
179 void resetCacheMaxAgeCapForPrevalentResources(CompletionHandler<void()>&&);
180 void resolveDirectoriesIfNecessary();
181 const String& resolvedApplicationCacheDirectory() const { return m_resolvedConfiguration->applicationCacheDirectory(); }
182 const String& resolvedMediaCacheDirectory() const { return m_resolvedConfiguration->mediaCacheDirectory(); }
183 const String& resolvedMediaKeysDirectory() const { return m_resolvedConfiguration->mediaKeysStorageDirectory(); }
184 const String& resolvedDatabaseDirectory() const { return m_resolvedConfiguration->webSQLDatabaseDirectory(); }
185 const String& resolvedJavaScriptConfigurationDirectory() const { return m_resolvedConfiguration->javaScriptConfigurationDirectory(); }
186 const String& resolvedCookieStorageFile() const { return m_resolvedConfiguration->cookieStorageFile(); }
187 const String& resolvedIndexedDatabaseDirectory() const { return m_resolvedConfiguration->indexedDBDatabaseDirectory(); }
188 const String& resolvedServiceWorkerRegistrationDirectory() const { return m_resolvedConfiguration->serviceWorkerRegistrationDirectory(); }
189 const String& resolvedResourceLoadStatisticsDirectory() const { return m_resolvedConfiguration->resourceLoadStatisticsDirectory(); }
190
191 StorageManager* storageManager() { return m_storageManager.get(); }
192
193 DeviceIdHashSaltStorage& deviceIdHashSaltStorage() { return m_deviceIdHashSaltStorage.get(); }
194
195 WebProcessPool* processPoolForCookieStorageOperations();
196 bool isAssociatedProcessPool(WebProcessPool&) const;
197
198 WebsiteDataStoreParameters parameters();
199
200 Vector<WebCore::Cookie> pendingCookies() const;
201 void addPendingCookie(const WebCore::Cookie&);
202 void removePendingCookie(const WebCore::Cookie&);
203 void clearPendingCookies();
204
205 void enableResourceLoadStatisticsAndSetTestingCallback(Function<void (const String&)>&& callback);
206
207 void setBoundInterfaceIdentifier(String&& identifier) { m_boundInterfaceIdentifier = WTFMove(identifier); }
208 const String& boundInterfaceIdentifier() { return m_boundInterfaceIdentifier; }
209
210 const String& sourceApplicationBundleIdentifier() const { return m_sourceApplicationBundleIdentifier; }
211 bool setSourceApplicationBundleIdentifier(String&&);
212
213 const String& sourceApplicationSecondaryIdentifier() const { return m_sourceApplicationSecondaryIdentifier; }
214 bool setSourceApplicationSecondaryIdentifier(String&&);
215
216 bool allowsTLSFallback() const { return m_allowsTLSFallback; }
217 bool setAllowsTLSFallback(bool);
218
219 void networkingHasBegun() { m_networkingHasBegun = true; }
220
221 void setAllowsCellularAccess(AllowsCellularAccess allows) { m_allowsCellularAccess = allows; }
222 AllowsCellularAccess allowsCellularAccess() { return m_allowsCellularAccess; }
223
224#if PLATFORM(COCOA)
225 void setProxyConfiguration(CFDictionaryRef configuration) { m_proxyConfiguration = configuration; }
226 CFDictionaryRef proxyConfiguration() { return m_proxyConfiguration.get(); }
227#endif
228
229#if USE(CURL)
230 void setNetworkProxySettings(WebCore::CurlProxySettings&&);
231 const WebCore::CurlProxySettings& networkProxySettings() const { return m_proxySettings; }
232#endif
233
234 static void allowWebsiteDataRecordsForAllOrigins();
235
236#if HAVE(SEC_KEY_PROXY)
237 void addSecKeyProxyStore(Ref<SecKeyProxyStore>&&);
238#endif
239
240#if ENABLE(WEB_AUTHN)
241 AuthenticatorManager& authenticatorManager() { return m_authenticatorManager.get(); }
242 void setMockWebAuthenticationConfiguration(MockWebAuthenticationConfiguration&&);
243#endif
244
245 void didCreateNetworkProcess();
246
247 const WebsiteDataStoreConfiguration& configuration() { return m_configuration.get(); }
248
249 WebsiteDataStoreClient& client() { return m_client.get(); }
250 void setClient(UniqueRef<WebsiteDataStoreClient>&& client) { m_client = WTFMove(client); }
251
252 API::HTTPCookieStore& cookieStore();
253
254#if ENABLE(DEVICE_ORIENTATION)
255 WebDeviceOrientationAndMotionAccessController& deviceOrientationAndMotionAccessController() { return m_deviceOrientationAndMotionAccessController; }
256#endif
257
258#if HAVE(LOAD_OPTIMIZER)
259WEBSITEDATASTORE_LOADOPTIMIZER_ADDITIONS_1
260#endif
261
262private:
263 explicit WebsiteDataStore(PAL::SessionID);
264 explicit WebsiteDataStore(Ref<WebsiteDataStoreConfiguration>&&, PAL::SessionID);
265
266 void fetchDataAndApply(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, RefPtr<WorkQueue>&&, Function<void(Vector<WebsiteDataRecord>)>&& apply);
267
268 // WebProcessLifetimeObserver.
269 void webPageWasAdded(WebPageProxy&) override;
270 void webPageWasInvalidated(WebPageProxy&) override;
271 void webProcessWillOpenConnection(WebProcessProxy&, IPC::Connection&) override;
272 void webPageWillOpenConnection(WebPageProxy&, IPC::Connection&) override;
273 void webPageDidCloseConnection(WebPageProxy&, IPC::Connection&) override;
274 void webProcessDidCloseConnection(WebProcessProxy&, IPC::Connection&) override;
275
276 void platformInitialize();
277 void platformDestroy();
278 static void platformRemoveRecentSearches(WallTime);
279
280#if USE(CURL) || USE(SOUP)
281 void platformSetNetworkParameters(WebsiteDataStoreParameters&);
282#endif
283
284 HashSet<RefPtr<WebProcessPool>> processPools(size_t count = std::numeric_limits<size_t>::max(), bool ensureAPoolExists = true) const;
285
286#if ENABLE(NETSCAPE_PLUGIN_API)
287 Vector<PluginModuleInfo> plugins() const;
288#endif
289
290 static Vector<WebCore::SecurityOriginData> mediaKeyOrigins(const String& mediaKeysStorageDirectory);
291 static void removeMediaKeys(const String& mediaKeysStorageDirectory, WallTime modifiedSince);
292 static void removeMediaKeys(const String& mediaKeysStorageDirectory, const HashSet<WebCore::SecurityOriginData>&);
293
294 void maybeRegisterWithSessionIDMap();
295
296 const PAL::SessionID m_sessionID;
297
298 Ref<WebsiteDataStoreConfiguration> m_resolvedConfiguration;
299 Ref<const WebsiteDataStoreConfiguration> m_configuration;
300 bool m_hasResolvedDirectories { false };
301
302 const RefPtr<StorageManager> m_storageManager;
303 const Ref<DeviceIdHashSaltStorage> m_deviceIdHashSaltStorage;
304
305#if ENABLE(RESOURCE_LOAD_STATISTICS)
306 RefPtr<WebResourceLoadStatisticsStore> m_resourceLoadStatistics;
307 bool m_resourceLoadStatisticsDebugMode { false };
308 bool m_resourceLoadStatisticsEnabled { false };
309 WTF::Function<void(const String&)> m_statisticsTestingCallback;
310#endif
311
312 Ref<WorkQueue> m_queue;
313
314#if PLATFORM(COCOA)
315 Vector<uint8_t> m_uiProcessCookieStorageIdentifier;
316 RetainPtr<CFHTTPCookieStorageRef> m_cfCookieStorage;
317 RetainPtr<CFDictionaryRef> m_proxyConfiguration;
318#endif
319
320#if USE(CURL)
321 WebCore::CurlProxySettings m_proxySettings;
322#endif
323
324 HashSet<WebCore::Cookie> m_pendingCookies;
325
326 String m_boundInterfaceIdentifier;
327 AllowsCellularAccess m_allowsCellularAccess { AllowsCellularAccess::Yes };
328 String m_sourceApplicationBundleIdentifier;
329 String m_sourceApplicationSecondaryIdentifier;
330 bool m_allowsTLSFallback { true };
331 bool m_networkingHasBegun { false };
332
333#if HAVE(SEC_KEY_PROXY)
334 Vector<Ref<SecKeyProxyStore>> m_secKeyProxyStores;
335#endif
336
337#if ENABLE(WEB_AUTHN)
338 UniqueRef<AuthenticatorManager> m_authenticatorManager;
339#endif
340
341#if ENABLE(DEVICE_ORIENTATION)
342 WebDeviceOrientationAndMotionAccessController m_deviceOrientationAndMotionAccessController;
343#endif
344
345 UniqueRef<WebsiteDataStoreClient> m_client;
346
347 RefPtr<API::HTTPCookieStore> m_cookieStore;
348};
349
350}
351