Source code

Revision control

Other Tools

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 "nsIClassInfoImpl.h"
20
#include "nsNetCID.h"
21
#include "nsError.h"
22
#include "ContentPrincipal.h"
23
#include "nsScriptSecurityManager.h"
24
#include "pratom.h"
25
26
#include "json/json.h"
27
28
using namespace mozilla;
29
30
NS_IMPL_CLASSINFO(NullPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
31
NS_NULLPRINCIPAL_CID)
32
NS_IMPL_QUERY_INTERFACE_CI(NullPrincipal, nsIPrincipal, nsISerializable)
33
NS_IMPL_CI_INTERFACE_GETTER(NullPrincipal, nsIPrincipal, nsISerializable)
34
35
/* static */
36
already_AddRefed<NullPrincipal> NullPrincipal::CreateWithInheritedAttributes(
37
nsIPrincipal* aInheritFrom) {
38
MOZ_ASSERT(aInheritFrom);
39
return CreateWithInheritedAttributes(
40
Cast(aInheritFrom)->OriginAttributesRef(), false);
41
}
42
43
/* static */
44
already_AddRefed<NullPrincipal> NullPrincipal::CreateWithInheritedAttributes(
45
nsIDocShell* aDocShell, bool aIsFirstParty) {
46
MOZ_ASSERT(aDocShell);
47
48
OriginAttributes attrs = nsDocShell::Cast(aDocShell)->GetOriginAttributes();
49
return CreateWithInheritedAttributes(attrs, aIsFirstParty);
50
}
51
52
/* static */
53
already_AddRefed<NullPrincipal> NullPrincipal::CreateWithInheritedAttributes(
54
const OriginAttributes& aOriginAttributes, bool aIsFirstParty) {
55
RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
56
nullPrin->Init(aOriginAttributes, aIsFirstParty);
57
return nullPrin.forget();
58
}
59
60
/* static */
61
already_AddRefed<NullPrincipal> NullPrincipal::Create(
62
const OriginAttributes& aOriginAttributes, nsIURI* aURI) {
63
RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
64
nsresult rv = nullPrin->Init(aOriginAttributes, aURI);
65
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
66
67
return nullPrin.forget();
68
}
69
70
/* static */
71
already_AddRefed<NullPrincipal> NullPrincipal::CreateWithoutOriginAttributes() {
72
return NullPrincipal::Create(OriginAttributes(), nullptr);
73
}
74
75
nsresult NullPrincipal::Init(const OriginAttributes& aOriginAttributes,
76
nsIURI* aURI) {
77
if (aURI) {
78
nsAutoCString scheme;
79
nsresult rv = aURI->GetScheme(scheme);
80
NS_ENSURE_SUCCESS(rv, rv);
81
82
NS_ENSURE_TRUE(scheme.EqualsLiteral(NS_NULLPRINCIPAL_SCHEME),
83
NS_ERROR_NOT_AVAILABLE);
84
85
mURI = aURI;
86
} else {
87
mURI = new NullPrincipalURI();
88
}
89
90
nsAutoCString originNoSuffix;
91
DebugOnly<nsresult> rv = mURI->GetSpec(originNoSuffix);
92
MOZ_ASSERT(NS_SUCCEEDED(rv));
93
94
FinishInit(originNoSuffix, aOriginAttributes);
95
96
return NS_OK;
97
}
98
99
void NullPrincipal::Init(const OriginAttributes& aOriginAttributes,
100
bool aIsFirstParty) {
101
mURI = new NullPrincipalURI();
102
103
nsAutoCString originNoSuffix;
104
DebugOnly<nsresult> rv = mURI->GetSpec(originNoSuffix);
105
MOZ_ASSERT(NS_SUCCEEDED(rv));
106
107
nsAutoCString path;
108
rv = mURI->GetPathQueryRef(path);
109
MOZ_ASSERT(NS_SUCCEEDED(rv));
110
111
OriginAttributes attrs(aOriginAttributes);
112
if (aIsFirstParty) {
113
// remove the '{}' characters from both ends.
114
path.Mid(path, 1, path.Length() - 2);
115
path.AppendLiteral(".mozilla");
116
attrs.SetFirstPartyDomain(true, path);
117
}
118
119
FinishInit(originNoSuffix, attrs);
120
}
121
122
nsresult NullPrincipal::GetScriptLocation(nsACString& aStr) {
123
return mURI->GetSpec(aStr);
124
}
125
126
/**
127
* nsIPrincipal implementation
128
*/
129
130
uint32_t NullPrincipal::GetHashValue() { return (NS_PTR_TO_INT32(this) >> 2); }
131
132
NS_IMETHODIMP
133
NullPrincipal::GetURI(nsIURI** aURI) {
134
nsCOMPtr<nsIURI> uri = mURI;
135
uri.forget(aURI);
136
return NS_OK;
137
}
138
NS_IMETHODIMP
139
NullPrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult) {
140
*aResult = false;
141
return NS_OK;
142
}
143
144
NS_IMETHODIMP
145
NullPrincipal::GetDomain(nsIURI** aDomain) {
146
nsCOMPtr<nsIURI> uri = mURI;
147
uri.forget(aDomain);
148
return NS_OK;
149
}
150
151
NS_IMETHODIMP
152
NullPrincipal::SetDomain(nsIURI* aDomain) {
153
// I think the right thing to do here is to just throw... Silently failing
154
// seems counterproductive.
155
return NS_ERROR_NOT_AVAILABLE;
156
}
157
158
bool NullPrincipal::MayLoadInternal(nsIURI* aURI) {
159
// Also allow the load if we are the principal of the URI being checked.
160
nsCOMPtr<nsIPrincipal> blobPrincipal;
161
if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
162
aURI, getter_AddRefs(blobPrincipal))) {
163
MOZ_ASSERT(blobPrincipal);
164
return SubsumesInternal(blobPrincipal,
165
BasePrincipal::ConsiderDocumentDomain);
166
}
167
168
return false;
169
}
170
171
NS_IMETHODIMP
172
NullPrincipal::GetBaseDomain(nsACString& aBaseDomain) {
173
// For a null principal, we use our unique uuid as the base domain.
174
return mURI->GetPathQueryRef(aBaseDomain);
175
}
176
177
NS_IMETHODIMP
178
NullPrincipal::GetAddonId(nsAString& aAddonId) {
179
aAddonId.Truncate();
180
return NS_OK;
181
};
182
183
/**
184
* nsISerializable implementation
185
*/
186
NS_IMETHODIMP
187
NullPrincipal::Read(nsIObjectInputStream* aStream) {
188
// Note - NullPrincipal use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT, which means
189
// that the Init() method has already been invoked by the time we deserialize.
190
// This is in contrast to ContentPrincipal, which uses
191
// NS_GENERIC_FACTORY_CONSTRUCTOR, in which case ::Read needs to invoke
192
// Init().
193
194
nsAutoCString spec;
195
nsresult rv = aStream->ReadCString(spec);
196
NS_ENSURE_SUCCESS(rv, rv);
197
198
nsCOMPtr<nsIURI> uri;
199
rv = NS_NewURI(getter_AddRefs(uri), spec);
200
NS_ENSURE_SUCCESS(rv, rv);
201
202
nsAutoCString suffix;
203
rv = aStream->ReadCString(suffix);
204
NS_ENSURE_SUCCESS(rv, rv);
205
206
OriginAttributes attrs;
207
bool ok = attrs.PopulateFromSuffix(suffix);
208
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
209
210
return Init(attrs, uri);
211
}
212
213
NS_IMETHODIMP
214
NullPrincipal::Write(nsIObjectOutputStream* aStream) {
215
// Read is used still for legacy principals
216
MOZ_RELEASE_ASSERT(false, "Old style serialization is removed");
217
return NS_OK;
218
}
219
220
nsresult NullPrincipal::PopulateJSONObject(Json::Value& aObject) {
221
nsAutoCString principalURI;
222
nsresult rv = mURI->GetSpec(principalURI);
223
NS_ENSURE_SUCCESS(rv, rv);
224
MOZ_ASSERT(principalURI.Length() ==
225
NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":").Length() +
226
NSID_LENGTH - 1,
227
"Length of the URI should be: (scheme, uuid, - nullptr)");
228
aObject[std::to_string(eSpec)] = principalURI.get();
229
230
nsAutoCString suffix;
231
OriginAttributesRef().CreateSuffix(suffix);
232
if (suffix.Length() > 0) {
233
aObject[std::to_string(eSuffix)] = suffix.get();
234
}
235
236
return NS_OK;
237
}
238
239
already_AddRefed<BasePrincipal> NullPrincipal::FromProperties(
240
nsTArray<NullPrincipal::KeyVal>& aFields) {
241
MOZ_ASSERT(aFields.Length() == eMax + 1, "Must have all the keys");
242
nsresult rv;
243
nsCOMPtr<nsIURI> uri;
244
OriginAttributes attrs;
245
246
// The odd structure here is to make the code to not compile
247
// if all the switch enum cases haven't been codified
248
for (const auto& field : aFields) {
249
switch (field.key) {
250
case NullPrincipal::eSpec:
251
if (!field.valueWasSerialized) {
252
MOZ_ASSERT(false,
253
"Null principals require a spec URI in serialized JSON");
254
return nullptr;
255
}
256
rv = NS_NewURI(getter_AddRefs(uri), field.value);
257
NS_ENSURE_SUCCESS(rv, nullptr);
258
break;
259
case NullPrincipal::eSuffix:
260
bool ok = attrs.PopulateFromSuffix(field.value);
261
if (!ok) {
262
return nullptr;
263
}
264
break;
265
}
266
}
267
268
if (!uri) {
269
MOZ_ASSERT(false, "No URI deserialized");
270
return nullptr;
271
}
272
273
RefPtr<NullPrincipal> nullPrincipal = new NullPrincipal();
274
rv = nullPrincipal->Init(attrs, uri);
275
if (NS_FAILED(rv)) {
276
return nullptr;
277
}
278
return nullPrincipal.forget();
279
}