Line data Source code
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/. */
5 :
6 : #include "mozilla/net/CookieServiceChild.h"
7 : #include "mozilla/LoadInfo.h"
8 : #include "mozilla/BasePrincipal.h"
9 : #include "mozilla/dom/ContentChild.h"
10 : #include "mozilla/ipc/URIUtils.h"
11 : #include "mozilla/net/NeckoChild.h"
12 : #include "nsIChannel.h"
13 : #include "nsIURI.h"
14 : #include "nsIPrefService.h"
15 : #include "nsIPrefBranch.h"
16 : #include "nsServiceManagerUtils.h"
17 :
18 : using namespace mozilla::ipc;
19 :
20 : namespace mozilla {
21 : namespace net {
22 :
23 : // Pref string constants
24 : static const char kPrefCookieBehavior[] = "network.cookie.cookieBehavior";
25 : static const char kPrefThirdPartySession[] =
26 : "network.cookie.thirdparty.sessionOnly";
27 :
28 : static CookieServiceChild *gCookieService;
29 :
30 : CookieServiceChild*
31 0 : CookieServiceChild::GetSingleton()
32 : {
33 0 : if (!gCookieService)
34 0 : gCookieService = new CookieServiceChild();
35 :
36 0 : NS_ADDREF(gCookieService);
37 0 : return gCookieService;
38 : }
39 :
40 0 : NS_IMPL_ISUPPORTS(CookieServiceChild,
41 : nsICookieService,
42 : nsIObserver,
43 : nsISupportsWeakReference)
44 :
45 0 : CookieServiceChild::CookieServiceChild()
46 : : mCookieBehavior(nsICookieService::BEHAVIOR_ACCEPT)
47 0 : , mThirdPartySession(false)
48 : {
49 0 : NS_ASSERTION(IsNeckoChild(), "not a child process");
50 :
51 : mozilla::dom::ContentChild* cc =
52 0 : static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
53 0 : if (cc->IsShuttingDown()) {
54 0 : return;
55 : }
56 :
57 : // This corresponds to Release() in DeallocPCookieService.
58 0 : NS_ADDREF_THIS();
59 :
60 : // Create a child PCookieService actor.
61 0 : NeckoChild::InitNeckoChild();
62 0 : gNeckoChild->SendPCookieServiceConstructor(this);
63 :
64 : // Init our prefs and observer.
65 : nsCOMPtr<nsIPrefBranch> prefBranch =
66 0 : do_GetService(NS_PREFSERVICE_CONTRACTID);
67 0 : NS_WARNING_ASSERTION(prefBranch, "no prefservice");
68 0 : if (prefBranch) {
69 0 : prefBranch->AddObserver(kPrefCookieBehavior, this, true);
70 0 : prefBranch->AddObserver(kPrefThirdPartySession, this, true);
71 0 : PrefChanged(prefBranch);
72 : }
73 : }
74 :
75 0 : CookieServiceChild::~CookieServiceChild()
76 : {
77 0 : gCookieService = nullptr;
78 0 : }
79 :
80 : void
81 0 : CookieServiceChild::PrefChanged(nsIPrefBranch *aPrefBranch)
82 : {
83 : int32_t val;
84 0 : if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookieBehavior, &val)))
85 0 : mCookieBehavior =
86 0 : val >= nsICookieService::BEHAVIOR_ACCEPT &&
87 0 : val <= nsICookieService::BEHAVIOR_LIMIT_FOREIGN
88 0 : ? val : nsICookieService::BEHAVIOR_ACCEPT;
89 :
90 : bool boolval;
91 0 : if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kPrefThirdPartySession, &boolval)))
92 0 : mThirdPartySession = !!boolval;
93 :
94 0 : if (!mThirdPartyUtil && RequireThirdPartyCheck()) {
95 0 : mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID);
96 0 : NS_ASSERTION(mThirdPartyUtil, "require ThirdPartyUtil service");
97 : }
98 0 : }
99 :
100 : bool
101 0 : CookieServiceChild::RequireThirdPartyCheck()
102 : {
103 0 : return mCookieBehavior == nsICookieService::BEHAVIOR_REJECT_FOREIGN ||
104 0 : mCookieBehavior == nsICookieService::BEHAVIOR_LIMIT_FOREIGN ||
105 0 : mThirdPartySession;
106 : }
107 :
108 : nsresult
109 0 : CookieServiceChild::GetCookieStringInternal(nsIURI *aHostURI,
110 : nsIChannel *aChannel,
111 : char **aCookieString)
112 : {
113 0 : NS_ENSURE_ARG(aHostURI);
114 0 : NS_ENSURE_ARG_POINTER(aCookieString);
115 :
116 0 : *aCookieString = nullptr;
117 :
118 : // Fast past: don't bother sending IPC messages about nullprincipal'd
119 : // documents.
120 0 : nsAutoCString scheme;
121 0 : aHostURI->GetScheme(scheme);
122 0 : if (scheme.EqualsLiteral("moz-nullprincipal"))
123 0 : return NS_OK;
124 :
125 : // Determine whether the request is foreign. Failure is acceptable.
126 0 : bool isForeign = true;
127 0 : if (RequireThirdPartyCheck())
128 0 : mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
129 :
130 0 : URIParams uriParams;
131 0 : SerializeURI(aHostURI, uriParams);
132 :
133 0 : mozilla::OriginAttributes attrs;
134 0 : if (aChannel) {
135 0 : nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
136 0 : if (loadInfo) {
137 0 : attrs = loadInfo->GetOriginAttributes();
138 : }
139 : }
140 :
141 : // Synchronously call the parent.
142 0 : nsAutoCString result;
143 0 : SendGetCookieString(uriParams, !!isForeign, attrs, &result);
144 0 : if (!result.IsEmpty())
145 0 : *aCookieString = ToNewCString(result);
146 :
147 0 : return NS_OK;
148 : }
149 :
150 : nsresult
151 0 : CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI,
152 : nsIChannel *aChannel,
153 : const char *aCookieString,
154 : const char *aServerTime,
155 : bool aFromHttp)
156 : {
157 0 : NS_ENSURE_ARG(aHostURI);
158 0 : NS_ENSURE_ARG_POINTER(aCookieString);
159 :
160 : // Fast past: don't bother sending IPC messages about nullprincipal'd
161 : // documents.
162 0 : nsAutoCString scheme;
163 0 : aHostURI->GetScheme(scheme);
164 0 : if (scheme.EqualsLiteral("moz-nullprincipal"))
165 0 : return NS_OK;
166 :
167 : // Determine whether the request is foreign. Failure is acceptable.
168 0 : bool isForeign = true;
169 0 : if (RequireThirdPartyCheck())
170 0 : mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
171 :
172 0 : nsDependentCString cookieString(aCookieString);
173 0 : nsDependentCString serverTime;
174 0 : if (aServerTime)
175 0 : serverTime.Rebind(aServerTime);
176 :
177 0 : URIParams uriParams;
178 0 : SerializeURI(aHostURI, uriParams);
179 :
180 0 : mozilla::OriginAttributes attrs;
181 0 : if (aChannel) {
182 0 : nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
183 0 : if (loadInfo) {
184 0 : attrs = loadInfo->GetOriginAttributes();
185 : }
186 : }
187 :
188 : // Synchronously call the parent.
189 0 : SendSetCookieString(uriParams, !!isForeign, cookieString, serverTime,
190 0 : attrs, aFromHttp);
191 0 : return NS_OK;
192 : }
193 :
194 : NS_IMETHODIMP
195 0 : CookieServiceChild::Observe(nsISupports *aSubject,
196 : const char *aTopic,
197 : const char16_t *aData)
198 : {
199 0 : NS_ASSERTION(strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0,
200 : "not a pref change topic!");
201 :
202 0 : nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(aSubject);
203 0 : if (prefBranch)
204 0 : PrefChanged(prefBranch);
205 0 : return NS_OK;
206 : }
207 :
208 : NS_IMETHODIMP
209 0 : CookieServiceChild::GetCookieString(nsIURI *aHostURI,
210 : nsIChannel *aChannel,
211 : char **aCookieString)
212 : {
213 0 : return GetCookieStringInternal(aHostURI, aChannel, aCookieString);
214 : }
215 :
216 : NS_IMETHODIMP
217 0 : CookieServiceChild::GetCookieStringFromHttp(nsIURI *aHostURI,
218 : nsIURI *aFirstURI,
219 : nsIChannel *aChannel,
220 : char **aCookieString)
221 : {
222 0 : return NS_ERROR_NOT_IMPLEMENTED;
223 : }
224 :
225 : NS_IMETHODIMP
226 0 : CookieServiceChild::SetCookieString(nsIURI *aHostURI,
227 : nsIPrompt *aPrompt,
228 : const char *aCookieString,
229 : nsIChannel *aChannel)
230 : {
231 : return SetCookieStringInternal(aHostURI, aChannel, aCookieString,
232 0 : nullptr, false);
233 : }
234 :
235 : NS_IMETHODIMP
236 0 : CookieServiceChild::SetCookieStringFromHttp(nsIURI *aHostURI,
237 : nsIURI *aFirstURI,
238 : nsIPrompt *aPrompt,
239 : const char *aCookieString,
240 : const char *aServerTime,
241 : nsIChannel *aChannel)
242 : {
243 : return SetCookieStringInternal(aHostURI, aChannel, aCookieString,
244 0 : aServerTime, true);
245 : }
246 :
247 : NS_IMETHODIMP
248 0 : CookieServiceChild::RunInTransaction(nsICookieTransactionCallback* aCallback)
249 : {
250 0 : return NS_ERROR_NOT_IMPLEMENTED;
251 : }
252 :
253 : } // namespace net
254 : } // namespace mozilla
255 :
|