Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 sts=2 ts=2 et tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /**
8 : * This is the principal that has no rights and can't be accessed by
9 : * anything other than itself and chrome; null principals are not
10 : * same-origin with anything but themselves.
11 : */
12 :
13 : #include "mozilla/ArrayUtils.h"
14 :
15 : #include "nsDocShell.h"
16 : #include "NullPrincipal.h"
17 : #include "NullPrincipalURI.h"
18 : #include "nsMemory.h"
19 : #include "nsIURIWithPrincipal.h"
20 : #include "nsIClassInfoImpl.h"
21 : #include "nsNetCID.h"
22 : #include "nsError.h"
23 : #include "nsIScriptSecurityManager.h"
24 : #include "ContentPrincipal.h"
25 : #include "nsScriptSecurityManager.h"
26 : #include "pratom.h"
27 :
28 : using namespace mozilla;
29 :
30 3 : NS_IMPL_CLASSINFO(NullPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
31 : NS_NULLPRINCIPAL_CID)
32 369 : NS_IMPL_QUERY_INTERFACE_CI(NullPrincipal,
33 : nsIPrincipal,
34 : nsISerializable)
35 1 : NS_IMPL_CI_INTERFACE_GETTER(NullPrincipal,
36 : nsIPrincipal,
37 : nsISerializable)
38 :
39 : /* static */ already_AddRefed<NullPrincipal>
40 0 : NullPrincipal::CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom)
41 : {
42 0 : RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
43 0 : nsresult rv = nullPrin->Init(Cast(aInheritFrom)->OriginAttributesRef());
44 0 : MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
45 0 : return nullPrin.forget();
46 : }
47 :
48 : /* static */ already_AddRefed<NullPrincipal>
49 1 : NullPrincipal::CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty)
50 : {
51 2 : OriginAttributes attrs = nsDocShell::Cast(aDocShell)->GetOriginAttributes();
52 :
53 2 : RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
54 1 : nsresult rv = nullPrin->Init(attrs, aIsFirstParty);
55 1 : MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
56 2 : return nullPrin.forget();
57 : }
58 :
59 : /* static */ already_AddRefed<NullPrincipal>
60 140 : NullPrincipal::Create(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
61 : {
62 280 : RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
63 140 : nsresult rv = nullPrin->Init(aOriginAttributes, aURI);
64 140 : MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
65 :
66 280 : return nullPrin.forget();
67 : }
68 :
69 : nsresult
70 140 : NullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
71 : {
72 140 : if (aURI) {
73 0 : nsAutoCString scheme;
74 0 : nsresult rv = aURI->GetScheme(scheme);
75 0 : NS_ENSURE_SUCCESS(rv, rv);
76 :
77 0 : NS_ENSURE_TRUE(scheme.EqualsLiteral(NS_NULLPRINCIPAL_SCHEME),
78 : NS_ERROR_NOT_AVAILABLE);
79 :
80 0 : mURI = aURI;
81 : } else {
82 140 : mURI = NullPrincipalURI::Create();
83 140 : NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE);
84 : }
85 :
86 280 : nsAutoCString originNoSuffix;
87 280 : DebugOnly<nsresult> rv = mURI->GetSpec(originNoSuffix);
88 140 : MOZ_ASSERT(NS_SUCCEEDED(rv));
89 :
90 140 : FinishInit(originNoSuffix, aOriginAttributes);
91 :
92 140 : return NS_OK;
93 : }
94 :
95 : nsresult
96 1 : NullPrincipal::Init(const OriginAttributes& aOriginAttributes, bool aIsFirstParty)
97 : {
98 1 : mURI = NullPrincipalURI::Create();
99 1 : NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE);
100 :
101 2 : nsAutoCString originNoSuffix;
102 2 : DebugOnly<nsresult> rv = mURI->GetSpec(originNoSuffix);
103 1 : MOZ_ASSERT(NS_SUCCEEDED(rv));
104 :
105 2 : nsAutoCString path;
106 1 : rv = mURI->GetPath(path);
107 1 : MOZ_ASSERT(NS_SUCCEEDED(rv));
108 :
109 2 : OriginAttributes attrs(aOriginAttributes);
110 1 : if (aIsFirstParty) {
111 : // remove the '{}' characters from both ends.
112 1 : path.Mid(path, 1, path.Length() - 2);
113 1 : path.AppendLiteral(".mozilla");
114 1 : attrs.SetFirstPartyDomain(true, path);
115 : }
116 :
117 1 : FinishInit(originNoSuffix, attrs);
118 :
119 1 : return NS_OK;
120 : }
121 :
122 : nsresult
123 0 : NullPrincipal::GetScriptLocation(nsACString &aStr)
124 : {
125 0 : return mURI->GetSpec(aStr);
126 : }
127 :
128 : /**
129 : * nsIPrincipal implementation
130 : */
131 :
132 : NS_IMETHODIMP
133 0 : NullPrincipal::GetHashValue(uint32_t *aResult)
134 : {
135 0 : *aResult = (NS_PTR_TO_INT32(this) >> 2);
136 0 : return NS_OK;
137 : }
138 :
139 : NS_IMETHODIMP
140 0 : NullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
141 : {
142 : // Never destroy an existing CSP on the principal.
143 : // This method should only be called in rare cases.
144 :
145 0 : MOZ_ASSERT(!mCSP, "do not destroy an existing CSP");
146 0 : if (mCSP) {
147 0 : return NS_ERROR_ALREADY_INITIALIZED;
148 : }
149 :
150 0 : mCSP = aCsp;
151 0 : return NS_OK;
152 : }
153 :
154 : NS_IMETHODIMP
155 33 : NullPrincipal::GetURI(nsIURI** aURI)
156 : {
157 33 : return NS_EnsureSafeToReturn(mURI, aURI);
158 : }
159 :
160 : NS_IMETHODIMP
161 0 : NullPrincipal::GetDomain(nsIURI** aDomain)
162 : {
163 0 : return NS_EnsureSafeToReturn(mURI, aDomain);
164 : }
165 :
166 : NS_IMETHODIMP
167 0 : NullPrincipal::SetDomain(nsIURI* aDomain)
168 : {
169 : // I think the right thing to do here is to just throw... Silently failing
170 : // seems counterproductive.
171 0 : return NS_ERROR_NOT_AVAILABLE;
172 : }
173 :
174 : bool
175 0 : NullPrincipal::MayLoadInternal(nsIURI* aURI)
176 : {
177 : // Also allow the load if we are the principal of the URI being checked.
178 0 : nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
179 0 : if (uriPrinc) {
180 0 : nsCOMPtr<nsIPrincipal> principal;
181 0 : uriPrinc->GetPrincipal(getter_AddRefs(principal));
182 :
183 0 : if (principal == this) {
184 0 : return true;
185 : }
186 : }
187 :
188 0 : return false;
189 : }
190 :
191 : NS_IMETHODIMP
192 12 : NullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
193 : {
194 : // For a null principal, we use our unique uuid as the base domain.
195 12 : return mURI->GetPath(aBaseDomain);
196 : }
197 :
198 : NS_IMETHODIMP
199 14 : NullPrincipal::GetAddonId(nsAString& aAddonId)
200 : {
201 14 : aAddonId.Truncate();
202 14 : return NS_OK;
203 : };
204 :
205 : /**
206 : * nsISerializable implementation
207 : */
208 : NS_IMETHODIMP
209 0 : NullPrincipal::Read(nsIObjectInputStream* aStream)
210 : {
211 : // Note - NullPrincipal use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT, which means
212 : // that the Init() method has already been invoked by the time we deserialize.
213 : // This is in contrast to ContentPrincipal, which uses NS_GENERIC_FACTORY_CONSTRUCTOR,
214 : // in which case ::Read needs to invoke Init().
215 :
216 0 : nsAutoCString spec;
217 0 : nsresult rv = aStream->ReadCString(spec);
218 0 : NS_ENSURE_SUCCESS(rv, rv);
219 :
220 0 : nsCOMPtr<nsIURI> uri;
221 0 : rv = NS_NewURI(getter_AddRefs(uri), spec);
222 0 : NS_ENSURE_SUCCESS(rv, rv);
223 :
224 0 : nsAutoCString suffix;
225 0 : rv = aStream->ReadCString(suffix);
226 0 : NS_ENSURE_SUCCESS(rv, rv);
227 :
228 0 : OriginAttributes attrs;
229 0 : bool ok = attrs.PopulateFromSuffix(suffix);
230 0 : NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
231 :
232 0 : return Init(attrs, uri);
233 : }
234 :
235 : NS_IMETHODIMP
236 0 : NullPrincipal::Write(nsIObjectOutputStream* aStream)
237 : {
238 0 : NS_ENSURE_STATE(mURI);
239 :
240 0 : nsAutoCString spec;
241 0 : nsresult rv = mURI->GetSpec(spec);
242 0 : NS_ENSURE_SUCCESS(rv, rv);
243 :
244 0 : rv = aStream->WriteStringZ(spec.get());
245 0 : NS_ENSURE_SUCCESS(rv, rv);
246 :
247 0 : nsAutoCString suffix;
248 0 : OriginAttributesRef().CreateSuffix(suffix);
249 :
250 0 : rv = aStream->WriteStringZ(suffix.get());
251 0 : NS_ENSURE_SUCCESS(rv, rv);
252 :
253 0 : return NS_OK;
254 : }
|