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 "LocalStorageDatabaseTracker.h"
29#include "NetworkSessionCreationParameters.h"
30#include "WebDeviceOrientationAndMotionAccessController.h"
31#include "WebProcessLifetimeObserver.h"
32#include "WebsiteDataStoreClient.h"
33#include "WebsiteDataStoreConfiguration.h"
34#include <WebCore/Cookie.h>
35#include <WebCore/DeviceOrientationOrMotionPermissionState.h>
36#include <WebCore/PageIdentifier.h>
37#include <WebCore/SecurityOriginData.h>
38#include <WebCore/SecurityOriginHash.h>
39#include <pal/SessionID.h>
40#include <wtf/Function.h>
41#include <wtf/HashSet.h>
42#include <wtf/Identified.h>
43#include <wtf/OptionSet.h>
44#include <wtf/RefCounted.h>
45#include <wtf/RefPtr.h>
46#include <wtf/UniqueRef.h>
47#include <wtf/WeakPtr.h>
48#include <wtf/WorkQueue.h>
49#include <wtf/text/WTFString.h>
50
51#if PLATFORM(COCOA)
52#include <pal/spi/cf/CFNetworkSPI.h>
53#endif
54
55#if USE(CURL)
56#include <WebCore/CurlProxySettings.h>
57#endif
58
59#if USE(APPLE_INTERNAL_SDK)
60#include <WebKitAdditions/WebsiteDataStoreAdditions.h>
61#endif
62
63namespace API {
64class HTTPCookieStore;
65}
66
67namespace WebCore {
68class RegistrableDomain;
69class SecurityOrigin;
70}
71
72namespace WebKit {
73
74class AuthenticatorManager;
75class SecKeyProxyStore;
76class DeviceIdHashSaltStorage;
77class WebPageProxy;
78class WebProcessPool;
79class WebResourceLoadStatisticsStore;
80enum class WebsiteDataFetchOption;
81enum class WebsiteDataType;
82struct MockWebAuthenticationConfiguration;
83struct WebsiteDataRecord;
84struct WebsiteDataStoreParameters;
85
86#if ENABLE(RESOURCE_LOAD_STATISTICS)
87enum class ShouldGrandfatherStatistics : bool;
88enum class StorageAccessStatus : uint8_t;
89enum class StorageAccessPromptStatus;
90#endif
91
92#if ENABLE(NETSCAPE_PLUGIN_API)
93struct PluginModuleInfo;
94#endif
95
96class WebsiteDataStore : public RefCounted<WebsiteDataStore>, public WebProcessLifetimeObserver, public Identified<WebsiteDataStore>, public CanMakeWeakPtr<WebsiteDataStore> {
97public:
98 static Ref<WebsiteDataStore> createNonPersistent();
99 static Ref<WebsiteDataStore> create(Ref<WebsiteDataStoreConfiguration>&&, PAL::SessionID);
100 virtual ~WebsiteDataStore();
101
102 static WebsiteDataStore* existingNonDefaultDataStoreForSessionID(PAL::SessionID);
103
104 bool isPersistent() const { return !m_sessionID.isEphemeral(); }
105 PAL::SessionID sessionID() const { return m_sessionID; }
106
107 bool resourceLoadStatisticsEnabled() const;
108 void setResourceLoadStatisticsEnabled(bool);
109 bool resourceLoadStatisticsDebugMode() const;
110 void setResourceLoadStatisticsDebugMode(bool);
111 void setResourceLoadStatisticsDebugMode(bool, CompletionHandler<void()>&&);
112
113 uint64_t perOriginStorageQuota() const { return m_resolvedConfiguration->perOriginStorageQuota(); }
114 uint64_t perThirdPartyOriginStorageQuota() const;
115 void setPerOriginStorageQuota(uint64_t quota) { m_resolvedConfiguration->setPerOriginStorageQuota(quota); }
116 const String& cacheStorageDirectory() const { return m_resolvedConfiguration->cacheStorageDirectory(); }
117 void setCacheStorageDirectory(String&& directory) { m_resolvedConfiguration->setCacheStorageDirectory(WTFMove(directory)); }
118 const String& serviceWorkerRegistrationDirectory() const { return m_resolvedConfiguration->serviceWorkerRegistrationDirectory(); }
119 void setServiceWorkerRegistrationDirectory(String&& directory) { m_resolvedConfiguration->setServiceWorkerRegistrationDirectory(WTFMove(directory)); }
120
121#if ENABLE(RESOURCE_LOAD_STATISTICS)
122 WebResourceLoadStatisticsStore* resourceLoadStatistics() const { return m_resourceLoadStatistics.get(); }
123 void clearResourceLoadStatisticsInWebProcesses(CompletionHandler<void()>&&);
124#endif
125
126 void fetchData(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, Function<void(Vector<WebsiteDataRecord>)>&& completionHandler);
127 void removeData(OptionSet<WebsiteDataType>, WallTime modifiedSince, Function<void()>&& completionHandler);
128 void removeData(OptionSet<WebsiteDataType>, const Vector<WebsiteDataRecord>&, Function<void()>&& completionHandler);
129
130 void getLocalStorageDetails(Function<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&&);
131
132#if ENABLE(RESOURCE_LOAD_STATISTICS)
133 void fetchDataForRegistrableDomains(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, const Vector<WebCore::RegistrableDomain>&, CompletionHandler<void(Vector<WebsiteDataRecord>&&, HashSet<WebCore::RegistrableDomain>&&)>&&);
134 void clearPrevalentResource(const URL&, CompletionHandler<void()>&&);
135 void clearUserInteraction(const URL&, CompletionHandler<void()>&&);
136 void dumpResourceLoadStatistics(CompletionHandler<void(const String&)>&&);
137 void logTestingEvent(const String&);
138 void logUserInteraction(const URL&, CompletionHandler<void()>&&);
139 void getAllStorageAccessEntries(WebCore::PageIdentifier, CompletionHandler<void(Vector<String>&& domains)>&&);
140 void hasHadUserInteraction(const URL&, CompletionHandler<void(bool)>&&);
141 void isPrevalentResource(const URL&, CompletionHandler<void(bool)>&&);
142 void isRegisteredAsRedirectingTo(const URL& hostRedirectedFrom, const URL& hostRedirectedTo, CompletionHandler<void(bool)>&&);
143 void isRegisteredAsSubresourceUnder(const URL& subresource, const URL& topFrame, CompletionHandler<void(bool)>&&);
144 void isRegisteredAsSubFrameUnder(const URL& subFrame, const URL& topFrame, CompletionHandler<void(bool)>&&);
145 void isVeryPrevalentResource(const URL&, CompletionHandler<void(bool)>&&);
146 void resetParametersToDefaultValues(CompletionHandler<void()>&&);
147 void scheduleCookieBlockingUpdate(CompletionHandler<void()>&&);
148 void scheduleClearInMemoryAndPersistent(WallTime modifiedSince, ShouldGrandfatherStatistics, CompletionHandler<void()>&&);
149 void scheduleClearInMemoryAndPersistent(ShouldGrandfatherStatistics, CompletionHandler<void()>&&);
150 void scheduleStatisticsAndDataRecordsProcessing(CompletionHandler<void()>&&);
151 void submitTelemetry();
152 void setGrandfathered(const URL&, bool, CompletionHandler<void()>&&);
153 void setGrandfatheringTime(Seconds, CompletionHandler<void()>&&);
154 void setLastSeen(const URL&, Seconds, CompletionHandler<void()>&&);
155 void setNotifyPagesWhenDataRecordsWereScanned(bool, CompletionHandler<void()>&&);
156 void setIsRunningResourceLoadStatisticsTest(bool, CompletionHandler<void()>&&);
157 void setPruneEntriesDownTo(size_t, CompletionHandler<void()>&&);
158 void setSubframeUnderTopFrameDomain(const URL& subframe, const URL& topFrame, CompletionHandler<void()>&&);
159 void setSubresourceUnderTopFrameDomain(const URL& subresource, const URL& topFrame, CompletionHandler<void()>&&);
160 void setSubresourceUniqueRedirectTo(const URL& subresource, const URL& hostNameRedirectedTo, CompletionHandler<void()>&&);
161 void setSubresourceUniqueRedirectFrom(const URL& subresource, const URL& hostNameRedirectedFrom, CompletionHandler<void()>&&);
162 void setTimeToLiveUserInteraction(Seconds, CompletionHandler<void()>&&);
163 void setTopFrameUniqueRedirectTo(const URL& topFrameHostName, const URL& hostNameRedirectedTo, CompletionHandler<void()>&&);
164 void setTopFrameUniqueRedirectFrom(const URL& topFrameHostName, const URL& hostNameRedirectedFrom, CompletionHandler<void()>&&);
165 void setMaxStatisticsEntries(size_t, CompletionHandler<void()>&&);
166 void setMinimumTimeBetweenDataRecordsRemoval(Seconds, CompletionHandler<void()>&&);
167 void setNotifyPagesWhenTelemetryWasCaptured(bool, CompletionHandler<void()>&&);
168 void setPrevalentResource(const URL&, CompletionHandler<void()>&&);
169 void setPrevalentResourceForDebugMode(const URL&, CompletionHandler<void()>&&);
170 void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool, CompletionHandler<void()>&&);
171 void setStatisticsTestingCallback(WTF::Function<void(const String&)>&& callback) { m_statisticsTestingCallback = WTFMove(callback); }
172 void setVeryPrevalentResource(const URL&, CompletionHandler<void()>&&);
173 void setSubframeUnderTopFrameDomain(const URL& subframe, const URL& topFrame);
174 void setCrossSiteLoadWithLinkDecorationForTesting(const URL& fromURL, const URL& toURL, CompletionHandler<void()>&&);
175 void resetCrossSiteLoadsWithLinkDecorationForTesting(CompletionHandler<void()>&&);
176 void deleteCookiesForTesting(const URL&, bool includeHttpOnlyCookies, CompletionHandler<void()>&&);
177 void hasLocalStorageForTesting(const URL&, CompletionHandler<void(bool)>&&) const;
178#endif
179 void setCacheMaxAgeCapForPrevalentResources(Seconds, CompletionHandler<void()>&&);
180 void resetCacheMaxAgeCapForPrevalentResources(CompletionHandler<void()>&&);
181 void resolveDirectoriesIfNecessary();
182 const String& resolvedApplicationCacheDirectory() const { return m_resolvedConfiguration->applicationCacheDirectory(); }
183 const String& resolvedLocalStorageDirectory() const { return m_resolvedConfiguration->localStorageDirectory(); }
184 const String& resolvedMediaCacheDirectory() const { return m_resolvedConfiguration->mediaCacheDirectory(); }
185 const String& resolvedMediaKeysDirectory() const { return m_resolvedConfiguration->mediaKeysStorageDirectory(); }
186 const String& resolvedDatabaseDirectory() const { return m_resolvedConfiguration->webSQLDatabaseDirectory(); }
187 const String& resolvedJavaScriptConfigurationDirectory() const { return m_resolvedConfiguration->javaScriptConfigurationDirectory(); }
188 const String& resolvedCookieStorageFile() const { return m_resolvedConfiguration->cookieStorageFile(); }
189 const String& resolvedIndexedDatabaseDirectory() const { return m_resolvedConfiguration->indexedDBDatabaseDirectory(); }
190 const String& resolvedServiceWorkerRegistrationDirectory() const { return m_resolvedConfiguration->serviceWorkerRegistrationDirectory(); }
191 const String& resolvedResourceLoadStatisticsDirectory() const { return m_resolvedConfiguration->resourceLoadStatisticsDirectory(); }
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 void platformInitialize();
269 void platformDestroy();
270 static void platformRemoveRecentSearches(WallTime);
271
272#if USE(CURL) || USE(SOUP)
273 void platformSetNetworkParameters(WebsiteDataStoreParameters&);
274#endif
275
276 HashSet<RefPtr<WebProcessPool>> processPools(size_t count = std::numeric_limits<size_t>::max(), bool ensureAPoolExists = true) const;
277
278#if ENABLE(NETSCAPE_PLUGIN_API)
279 Vector<PluginModuleInfo> plugins() const;
280#endif
281
282 static Vector<WebCore::SecurityOriginData> mediaKeyOrigins(const String& mediaKeysStorageDirectory);
283 static void removeMediaKeys(const String& mediaKeysStorageDirectory, WallTime modifiedSince);
284 static void removeMediaKeys(const String& mediaKeysStorageDirectory, const HashSet<WebCore::SecurityOriginData>&);
285
286 void maybeRegisterWithSessionIDMap();
287
288 const PAL::SessionID m_sessionID;
289
290 Ref<WebsiteDataStoreConfiguration> m_resolvedConfiguration;
291 Ref<const WebsiteDataStoreConfiguration> m_configuration;
292 bool m_hasResolvedDirectories { false };
293
294 const Ref<DeviceIdHashSaltStorage> m_deviceIdHashSaltStorage;
295
296#if ENABLE(RESOURCE_LOAD_STATISTICS)
297 RefPtr<WebResourceLoadStatisticsStore> m_resourceLoadStatistics;
298 bool m_resourceLoadStatisticsDebugMode { false };
299 bool m_resourceLoadStatisticsEnabled { false };
300 WTF::Function<void(const String&)> m_statisticsTestingCallback;
301#endif
302
303 Ref<WorkQueue> m_queue;
304
305#if PLATFORM(COCOA)
306 Vector<uint8_t> m_uiProcessCookieStorageIdentifier;
307 RetainPtr<CFHTTPCookieStorageRef> m_cfCookieStorage;
308 RetainPtr<CFDictionaryRef> m_proxyConfiguration;
309#endif
310
311#if USE(CURL)
312 WebCore::CurlProxySettings m_proxySettings;
313#endif
314
315 HashSet<WebCore::Cookie> m_pendingCookies;
316
317 String m_boundInterfaceIdentifier;
318 AllowsCellularAccess m_allowsCellularAccess { AllowsCellularAccess::Yes };
319 String m_sourceApplicationBundleIdentifier;
320 String m_sourceApplicationSecondaryIdentifier;
321 bool m_allowsTLSFallback { true };
322 bool m_networkingHasBegun { false };
323
324#if HAVE(SEC_KEY_PROXY)
325 Vector<Ref<SecKeyProxyStore>> m_secKeyProxyStores;
326#endif
327
328#if ENABLE(WEB_AUTHN)
329 UniqueRef<AuthenticatorManager> m_authenticatorManager;
330#endif
331
332#if ENABLE(DEVICE_ORIENTATION)
333 WebDeviceOrientationAndMotionAccessController m_deviceOrientationAndMotionAccessController;
334#endif
335
336 UniqueRef<WebsiteDataStoreClient> m_client;
337
338 RefPtr<API::HTTPCookieStore> m_cookieStore;
339};
340
341}
342