1/*
2 * Copyright (C) 2012-2018 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 "CredentialStorage.h"
29#include "RegistrableDomain.h"
30#include <pal/SessionID.h>
31#include <wtf/Function.h>
32#include <wtf/HashMap.h>
33#include <wtf/HashSet.h>
34#include <wtf/WallTime.h>
35#include <wtf/text/WTFString.h>
36
37#if PLATFORM(COCOA) || USE(CFURLCONNECTION)
38#include <pal/spi/cf/CFNetworkSPI.h>
39#include <wtf/RetainPtr.h>
40#endif
41
42#if USE(SOUP)
43#include <wtf/Function.h>
44#include <wtf/glib/GRefPtr.h>
45typedef struct _SoupCookieJar SoupCookieJar;
46#endif
47
48#if USE(CURL)
49#include "CookieJarCurl.h"
50#include "CookieJarDB.h"
51#include <wtf/UniqueRef.h>
52#endif
53
54#ifdef __OBJC__
55#include <objc/objc.h>
56#endif
57
58#if PLATFORM(COCOA)
59#include "CookieStorageObserver.h"
60#endif
61
62namespace WebCore {
63
64class CurlProxySettings;
65class NetworkingContext;
66class ResourceRequest;
67class SoupNetworkSession;
68
69struct Cookie;
70struct CookieRequestHeaderFieldProxy;
71struct SameSiteInfo;
72
73enum class IncludeSecureCookies : bool;
74enum class IncludeHttpOnlyCookies : bool;
75
76class NetworkStorageSession {
77 WTF_MAKE_NONCOPYABLE(NetworkStorageSession); WTF_MAKE_FAST_ALLOCATED;
78public:
79 WEBCORE_EXPORT static void permitProcessToUseCookieAPI(bool);
80 WEBCORE_EXPORT static bool processMayUseCookieAPI();
81
82 PAL::SessionID sessionID() const { return m_sessionID; }
83 CredentialStorage& credentialStorage() { return m_credentialStorage; }
84
85#ifdef __OBJC__
86 WEBCORE_EXPORT NSHTTPCookieStorage *nsCookieStorage() const;
87#endif
88
89#if PLATFORM(COCOA) || USE(CFURLCONNECTION)
90 WEBCORE_EXPORT static RetainPtr<CFURLStorageSessionRef> createCFStorageSessionForIdentifier(CFStringRef identifier);
91 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, RetainPtr<CFURLStorageSessionRef>&&, RetainPtr<CFHTTPCookieStorageRef>&&);
92 WEBCORE_EXPORT explicit NetworkStorageSession(PAL::SessionID);
93
94 // May be null, in which case a Foundation default should be used.
95 CFURLStorageSessionRef platformSession() { return m_platformSession.get(); }
96 WEBCORE_EXPORT RetainPtr<CFHTTPCookieStorageRef> cookieStorage() const;
97 WEBCORE_EXPORT static void setStorageAccessAPIEnabled(bool);
98#elif USE(SOUP)
99 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, std::unique_ptr<SoupNetworkSession>&&);
100 ~NetworkStorageSession();
101
102 SoupNetworkSession& soupNetworkSession() const;
103 void clearSoupNetworkSession();
104 SoupCookieJar* cookieStorage() const;
105 void setCookieStorage(SoupCookieJar*);
106 void setCookieObserverHandler(Function<void ()>&&);
107 void getCredentialFromPersistentStorage(const ProtectionSpace&, GCancellable*, Function<void (Credential&&)>&& completionHandler);
108 void saveCredentialToPersistentStorage(const ProtectionSpace&, const Credential&);
109#elif USE(CURL)
110 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID);
111 ~NetworkStorageSession();
112
113 const CookieJarCurl& cookieStorage() const { return m_cookieStorage; };
114 CookieJarDB& cookieDatabase() const;
115 WEBCORE_EXPORT void setCookieDatabase(UniqueRef<CookieJarDB>&&);
116
117 WEBCORE_EXPORT void setProxySettings(CurlProxySettings&&);
118#else
119 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, NetworkingContext*);
120 ~NetworkStorageSession();
121
122 NetworkingContext* context() const;
123#endif
124
125 WEBCORE_EXPORT bool cookiesEnabled() const;
126 WEBCORE_EXPORT void setCookie(const Cookie&);
127 WEBCORE_EXPORT void setCookies(const Vector<Cookie>&, const URL&, const URL& mainDocumentURL);
128 WEBCORE_EXPORT void setCookiesFromDOM(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<uint64_t> pageID, const String&) const;
129 WEBCORE_EXPORT void deleteCookie(const Cookie&);
130 WEBCORE_EXPORT void deleteCookie(const URL&, const String&) const;
131 WEBCORE_EXPORT void deleteAllCookies();
132 WEBCORE_EXPORT void deleteAllCookiesModifiedSince(WallTime);
133 WEBCORE_EXPORT void deleteCookiesForHostnames(const Vector<String>& cookieHostNames);
134 WEBCORE_EXPORT void deleteCookiesForHostnames(const Vector<String>& cookieHostNames, IncludeHttpOnlyCookies);
135 WEBCORE_EXPORT Vector<Cookie> getAllCookies();
136 WEBCORE_EXPORT Vector<Cookie> getCookies(const URL&);
137 WEBCORE_EXPORT bool getRawCookies(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<uint64_t> pageID, Vector<Cookie>&) const;
138 WEBCORE_EXPORT void flushCookieStore();
139 WEBCORE_EXPORT void getHostnamesWithCookies(HashSet<String>& hostnames);
140 WEBCORE_EXPORT std::pair<String, bool> cookiesForDOM(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<uint64_t> pageID, IncludeSecureCookies) const;
141 WEBCORE_EXPORT std::pair<String, bool> cookieRequestHeaderFieldValue(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<uint64_t> pageID, IncludeSecureCookies) const;
142 WEBCORE_EXPORT std::pair<String, bool> cookieRequestHeaderFieldValue(const CookieRequestHeaderFieldProxy&) const;
143
144#if ENABLE(RESOURCE_LOAD_STATISTICS)
145 WEBCORE_EXPORT bool shouldBlockCookies(const ResourceRequest&, Optional<uint64_t> frameID, Optional<uint64_t> pageID) const;
146 WEBCORE_EXPORT bool shouldBlockCookies(const URL& firstPartyForCookies, const URL& resource, Optional<uint64_t> frameID, Optional<uint64_t> pageID) const;
147 WEBCORE_EXPORT void setPrevalentDomainsToBlockCookiesFor(const Vector<RegistrableDomain>&);
148 WEBCORE_EXPORT void setAgeCapForClientSideCookies(Optional<Seconds>);
149 WEBCORE_EXPORT void removePrevalentDomains(const Vector<RegistrableDomain>& domains);
150 WEBCORE_EXPORT bool hasStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID) const;
151 WEBCORE_EXPORT Vector<String> getAllStorageAccessEntries() const;
152 WEBCORE_EXPORT void grantStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID);
153 WEBCORE_EXPORT void removeStorageAccessForFrame(uint64_t frameID, uint64_t pageID);
154 WEBCORE_EXPORT void clearPageSpecificDataForResourceLoadStatistics(uint64_t pageID);
155 WEBCORE_EXPORT void removeAllStorageAccess();
156 WEBCORE_EXPORT void setCacheMaxAgeCapForPrevalentResources(Seconds);
157 WEBCORE_EXPORT void resetCacheMaxAgeCapForPrevalentResources();
158 WEBCORE_EXPORT Optional<Seconds> maxAgeCacheCap(const ResourceRequest&);
159 WEBCORE_EXPORT void committedCrossSiteLoadWithLinkDecoration(const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, uint64_t pageID);
160 WEBCORE_EXPORT void resetCrossSiteLoadsWithLinkDecorationForTesting();
161#endif
162
163private:
164 PAL::SessionID m_sessionID;
165
166#if PLATFORM(COCOA) || USE(CFURLCONNECTION)
167 RetainPtr<CFURLStorageSessionRef> m_platformSession;
168 RetainPtr<CFHTTPCookieStorageRef> m_platformCookieStorage;
169#elif USE(SOUP)
170 static void cookiesDidChange(NetworkStorageSession*);
171
172 mutable std::unique_ptr<SoupNetworkSession> m_session;
173 Function<void ()> m_cookieObserverHandler;
174#elif USE(CURL)
175 UniqueRef<CookieJarCurl> m_cookieStorage;
176 mutable UniqueRef<CookieJarDB> m_cookieDatabase;
177#else
178 RefPtr<NetworkingContext> m_context;
179#endif
180
181 CredentialStorage m_credentialStorage;
182
183#if ENABLE(RESOURCE_LOAD_STATISTICS)
184 bool shouldBlockThirdPartyCookies(const RegistrableDomain&) const;
185 Optional<Seconds> clientSideCookieCap(const RegistrableDomain& firstParty, Optional<uint64_t> pageID) const;
186 HashSet<RegistrableDomain> m_registrableDomainsToBlockCookieFor;
187 HashMap<uint64_t, HashMap<uint64_t, RegistrableDomain, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> m_framesGrantedStorageAccess;
188 HashMap<uint64_t, HashMap<RegistrableDomain, RegistrableDomain>, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> m_pagesGrantedStorageAccess;
189 Optional<Seconds> m_cacheMaxAgeCapForPrevalentResources { };
190 Optional<Seconds> m_ageCapForClientSideCookies { };
191 Optional<Seconds> m_ageCapForClientSideCookiesShort { };
192 HashMap<uint64_t, RegistrableDomain, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>> m_navigatedToWithLinkDecorationByPrevalentResource;
193 bool m_navigationWithLinkDecorationTestMode = false;
194#endif
195
196#if PLATFORM(COCOA)
197public:
198 CookieStorageObserver& cookieStorageObserver() const;
199
200private:
201 mutable RefPtr<CookieStorageObserver> m_cookieStorageObserver;
202#endif
203 static bool m_processMayUseCookieAPI;
204};
205
206#if PLATFORM(COCOA) || USE(CFURLCONNECTION)
207WEBCORE_EXPORT CFURLStorageSessionRef createPrivateStorageSession(CFStringRef identifier);
208#endif
209
210}
211