Bug 1494162 - Part 45: Lazy load Menu and MenuItem in TabBar. r=pbro
[gecko.git] / netwerk / cookie / CookieServiceParent.cpp
blob0118d87de35c23b4ff6450a9169138e16b297cd6
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/net/CookieServiceParent.h"
7 #include "mozilla/dom/PContentParent.h"
8 #include "mozilla/net/NeckoParent.h"
10 #include "mozilla/BasePrincipal.h"
11 #include "mozilla/ipc/URIUtils.h"
12 #include "nsArrayUtils.h"
13 #include "nsCookieService.h"
14 #include "nsIChannel.h"
15 #include "nsIEffectiveTLDService.h"
16 #include "nsIScriptSecurityManager.h"
17 #include "nsIPrivateBrowsingChannel.h"
18 #include "nsNetCID.h"
19 #include "nsPrintfCString.h"
21 using namespace mozilla::ipc;
22 using mozilla::BasePrincipal;
23 using mozilla::OriginAttributes;
24 using mozilla::dom::PContentParent;
25 using mozilla::net::NeckoParent;
27 namespace {
29 // Ignore failures from this function, as they only affect whether we do or
30 // don't show a dialog box in private browsing mode if the user sets a pref.
31 void
32 CreateDummyChannel(nsIURI* aHostURI, nsIURI* aChannelURI,
33 OriginAttributes& aAttrs, nsIChannel** aChannel)
35 nsCOMPtr<nsIPrincipal> principal =
36 BasePrincipal::CreateCodebasePrincipal(aHostURI, aAttrs);
37 if (!principal) {
38 return;
41 // The following channel is never openend, so it does not matter what
42 // securityFlags we pass; let's follow the principle of least privilege.
43 nsCOMPtr<nsIChannel> dummyChannel;
44 NS_NewChannel(getter_AddRefs(dummyChannel), aChannelURI, principal,
45 nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
46 nsIContentPolicy::TYPE_INVALID);
47 nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(dummyChannel);
48 if (!pbChannel) {
49 return;
52 pbChannel->SetPrivate(aAttrs.mPrivateBrowsingId > 0);
53 dummyChannel.forget(aChannel);
58 namespace mozilla {
59 namespace net {
61 CookieServiceParent::CookieServiceParent()
63 // Instantiate the cookieservice via the service manager, so it sticks around
64 // until shutdown.
65 nsCOMPtr<nsICookieService> cs = do_GetService(NS_COOKIESERVICE_CONTRACTID);
67 // Get the nsCookieService instance directly, so we can call internal methods.
68 mCookieService = nsCookieService::GetSingleton();
69 NS_ASSERTION(mCookieService, "couldn't get nsICookieService");
70 mProcessingCookie = false;
73 void
74 GetInfoFromCookie(nsCookie *aCookie,
75 CookieStruct &aCookieStruct)
77 aCookieStruct.name() = aCookie->Name();
78 aCookieStruct.value() = aCookie->Value();
79 aCookieStruct.host() = aCookie->Host();
80 aCookieStruct.path() = aCookie->Path();
81 aCookieStruct.expiry() = aCookie->Expiry();
82 aCookieStruct.lastAccessed() = aCookie->LastAccessed();
83 aCookieStruct.creationTime() = aCookie->CreationTime();
84 aCookieStruct.isSession() = aCookie->IsSession();
85 aCookieStruct.isSecure() = aCookie->IsSecure();
86 aCookieStruct.isHttpOnly() = aCookie->IsHttpOnly();
87 aCookieStruct.sameSite() = aCookie->SameSite();
90 void
91 CookieServiceParent::RemoveBatchDeletedCookies(nsIArray *aCookieList) {
92 uint32_t len = 0;
93 aCookieList->GetLength(&len);
94 OriginAttributes attrs;
95 CookieStruct cookieStruct;
96 nsTArray<CookieStruct> cookieStructList;
97 nsTArray<OriginAttributes> attrsList;
98 for (uint32_t i = 0; i < len; i++) {
99 nsCOMPtr<nsICookie> xpcCookie = do_QueryElementAt(aCookieList, i);
100 auto cookie = static_cast<nsCookie*>(xpcCookie.get());
101 attrs = cookie->OriginAttributesRef();
102 GetInfoFromCookie(cookie, cookieStruct);
103 if (cookie->IsHttpOnly()) {
104 // Child only needs to exist if an HttpOnly cookie exists, not its value
105 cookieStruct.value() = "";
107 cookieStructList.AppendElement(cookieStruct);
108 attrsList.AppendElement(attrs);
110 Unused << SendRemoveBatchDeletedCookies(cookieStructList, attrsList);
113 void
114 CookieServiceParent::RemoveAll()
116 Unused << SendRemoveAll();
119 void
120 CookieServiceParent::RemoveCookie(nsICookie *aCookie)
122 auto cookie = static_cast<nsCookie*>(aCookie);
123 OriginAttributes attrs = cookie->OriginAttributesRef();
124 CookieStruct cookieStruct;
125 GetInfoFromCookie(cookie, cookieStruct);
126 if (cookie->IsHttpOnly()) {
127 cookieStruct.value() = "";
129 Unused << SendRemoveCookie(cookieStruct, attrs);
132 void
133 CookieServiceParent::AddCookie(nsICookie *aCookie)
135 auto cookie = static_cast<nsCookie*>(aCookie);
136 OriginAttributes attrs = cookie->OriginAttributesRef();
137 CookieStruct cookieStruct;
138 GetInfoFromCookie(cookie, cookieStruct);
139 if (cookie->IsHttpOnly()) {
140 cookieStruct.value() = "";
142 Unused << SendAddCookie(cookieStruct, attrs);
145 void
146 CookieServiceParent::TrackCookieLoad(nsIChannel *aChannel)
148 nsCOMPtr<nsIURI> uri;
149 aChannel->GetURI(getter_AddRefs(uri));
151 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
152 mozilla::OriginAttributes attrs;
153 if (loadInfo) {
154 attrs = loadInfo->GetOriginAttributes();
156 bool isSafeTopLevelNav = NS_IsSafeTopLevelNav(aChannel);
157 bool aIsSameSiteForeign = NS_IsSameSiteForeign(aChannel, uri);
159 // Send matching cookies to Child.
160 nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil;
161 thirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID);
162 bool isForeign = true;
163 thirdPartyUtil->IsThirdPartyChannel(aChannel, uri, &isForeign);
165 bool isTrackingResource = false;
166 bool storageAccessGranted = false;
167 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
168 if (httpChannel) {
169 isTrackingResource = httpChannel->GetIsTrackingResource();
170 // Check first-party storage access even for non-tracking resources, since
171 // we will need the result when computing the access rights for the reject
172 // foreign cookie behavior mode.
173 if (isForeign &&
174 AntiTrackingCommon::IsFirstPartyStorageAccessGrantedFor(httpChannel,
175 uri,
176 nullptr)) {
177 storageAccessGranted = true;
181 nsTArray<nsCookie*> foundCookieList;
182 mCookieService->GetCookiesForURI(uri, isForeign, isTrackingResource,
183 storageAccessGranted, isSafeTopLevelNav,
184 aIsSameSiteForeign, false, attrs,
185 foundCookieList);
186 nsTArray<CookieStruct> matchingCookiesList;
187 SerialializeCookieList(foundCookieList, matchingCookiesList, uri);
188 Unused << SendTrackCookiesLoad(matchingCookiesList, attrs);
191 void
192 CookieServiceParent::SerialializeCookieList(const nsTArray<nsCookie*> &aFoundCookieList,
193 nsTArray<CookieStruct> &aCookiesList,
194 nsIURI *aHostURI)
196 for (uint32_t i = 0; i < aFoundCookieList.Length(); i++) {
197 nsCookie *cookie = aFoundCookieList.ElementAt(i);
198 CookieStruct* cookieStruct = aCookiesList.AppendElement();
199 cookieStruct->name() = cookie->Name();
200 if (!cookie->IsHttpOnly()) {
201 cookieStruct->value() = cookie->Value();
203 cookieStruct->host() = cookie->Host();
204 cookieStruct->path() = cookie->Path();
205 cookieStruct->expiry() = cookie->Expiry();
206 cookieStruct->lastAccessed() = cookie->LastAccessed();
207 cookieStruct->creationTime() = cookie->CreationTime();
208 cookieStruct->isSession() = cookie->IsSession();
209 cookieStruct->isSecure() = cookie->IsSecure();
210 cookieStruct->sameSite() = cookie->SameSite();
214 mozilla::ipc::IPCResult
215 CookieServiceParent::RecvPrepareCookieList(const URIParams &aHost,
216 const bool &aIsForeign,
217 const bool &aIsTrackingResource,
218 const bool &aFirstPartyStorageAccessGranted,
219 const bool &aIsSafeTopLevelNav,
220 const bool &aIsSameSiteForeign,
221 const OriginAttributes &aAttrs)
223 nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost);
225 // Send matching cookies to Child.
226 nsTArray<nsCookie*> foundCookieList;
227 mCookieService->GetCookiesForURI(hostURI, aIsForeign, aIsTrackingResource,
228 aFirstPartyStorageAccessGranted, aIsSafeTopLevelNav,
229 aIsSameSiteForeign, false, aAttrs,
230 foundCookieList);
231 nsTArray<CookieStruct> matchingCookiesList;
232 SerialializeCookieList(foundCookieList, matchingCookiesList, hostURI);
233 Unused << SendTrackCookiesLoad(matchingCookiesList, aAttrs);
234 return IPC_OK();
237 void
238 CookieServiceParent::ActorDestroy(ActorDestroyReason aWhy)
240 // Nothing needed here. Called right before destructor since this is a
241 // non-refcounted class.
244 mozilla::ipc::IPCResult
245 CookieServiceParent::RecvSetCookieString(const URIParams& aHost,
246 const OptionalURIParams& aChannelURI,
247 const bool& aIsForeign,
248 const bool& aIsTrackingResource,
249 const bool& aFirstPartyStorageAccessGranted,
250 const nsCString& aCookieString,
251 const nsCString& aServerTime,
252 const OriginAttributes& aAttrs,
253 const bool& aFromHttp)
255 if (!mCookieService)
256 return IPC_OK();
258 // Deserialize URI. Having a host URI is mandatory and should always be
259 // provided by the child; thus we consider failure fatal.
260 nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost);
261 if (!hostURI)
262 return IPC_FAIL_NO_REASON(this);
264 nsCOMPtr<nsIURI> channelURI = DeserializeURI(aChannelURI);
266 // This is a gross hack. We've already computed everything we need to know
267 // for whether to set this cookie or not, but we need to communicate all of
268 // this information through to nsICookiePermission, which indirectly
269 // computes the information from the channel. We only care about the
270 // aIsPrivate argument as nsCookieService::SetCookieStringInternal deals
271 // with aIsForeign before we have to worry about nsCookiePermission trying
272 // to use the channel to inspect it.
273 nsCOMPtr<nsIChannel> dummyChannel;
274 CreateDummyChannel(hostURI, channelURI,
275 const_cast<OriginAttributes&>(aAttrs),
276 getter_AddRefs(dummyChannel));
278 // NB: dummyChannel could be null if something failed in CreateDummyChannel.
279 nsDependentCString cookieString(aCookieString, 0);
281 // We set this to true while processing this cookie update, to make sure
282 // we don't send it back to the same content process.
283 mProcessingCookie = true;
284 mCookieService->SetCookieStringInternal(hostURI, aIsForeign,
285 aIsTrackingResource,
286 aFirstPartyStorageAccessGranted,
287 cookieString, aServerTime, aFromHttp,
288 aAttrs, dummyChannel);
289 mProcessingCookie = false;
290 return IPC_OK();
293 } // namespace net
294 } // namespace mozilla