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