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/. */
7 * This is the principal that has no rights and can't be accessed by
8 * anything other than itself and chrome; null principals are not
9 * same-origin with anything but themselves.
12 #include "mozilla/Util.h"
14 #include "nsNullPrincipal.h"
15 #include "nsNullPrincipalURI.h"
17 #include "nsIUUIDGenerator.h"
19 #include "nsNetUtil.h"
20 #include "nsIClassInfoImpl.h"
23 #include "nsIScriptSecurityManager.h"
24 #include "nsScriptSecurityManager.h"
27 using namespace mozilla
;
29 NS_IMPL_CLASSINFO(nsNullPrincipal
, nullptr, nsIClassInfo::MAIN_THREAD_ONLY
,
31 NS_IMPL_QUERY_INTERFACE2_CI(nsNullPrincipal
,
34 NS_IMPL_CI_INTERFACE_GETTER2(nsNullPrincipal
,
38 NS_IMETHODIMP_(nsrefcnt
)
39 nsNullPrincipal::AddRef()
41 NS_PRECONDITION(int32_t(refcount
) >= 0, "illegal refcnt");
42 nsrefcnt count
= ++refcount
;
43 NS_LOG_ADDREF(this, count
, "nsNullPrincipal", sizeof(*this));
47 NS_IMETHODIMP_(nsrefcnt
)
48 nsNullPrincipal::Release()
50 NS_PRECONDITION(0 != refcount
, "dup release");
51 nsrefcnt count
= --refcount
;
52 NS_LOG_RELEASE(this, count
, "nsNullPrincipal");
60 nsNullPrincipal::nsNullPrincipal()
64 nsNullPrincipal::~nsNullPrincipal()
68 #define NS_NULLPRINCIPAL_PREFIX NS_NULLPRINCIPAL_SCHEME ":"
71 nsNullPrincipal::Init()
73 // FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
75 nsCOMPtr
<nsIUUIDGenerator
> uuidgen
=
76 do_GetService("@mozilla.org/uuid-generator;1", &rv
);
77 NS_ENSURE_SUCCESS(rv
, rv
);
80 rv
= uuidgen
->GenerateUUIDInPlace(&id
);
81 NS_ENSURE_SUCCESS(rv
, rv
);
83 char chars
[NSID_LENGTH
];
84 id
.ToProvidedString(chars
);
86 uint32_t suffixLen
= NSID_LENGTH
- 1;
87 uint32_t prefixLen
= ArrayLength(NS_NULLPRINCIPAL_PREFIX
) - 1;
89 // Use an nsCString so we only do the allocation once here and then share
90 // with nsJSPrincipals
92 str
.SetCapacity(prefixLen
+ suffixLen
);
94 str
.Append(NS_NULLPRINCIPAL_PREFIX
);
97 if (str
.Length() != prefixLen
+ suffixLen
) {
98 NS_WARNING("Out of memory allocating null-principal URI");
99 return NS_ERROR_OUT_OF_MEMORY
;
102 mURI
= new nsNullPrincipalURI(str
);
103 NS_ENSURE_TRUE(mURI
, NS_ERROR_OUT_OF_MEMORY
);
109 nsNullPrincipal::GetScriptLocation(nsACString
&aStr
)
115 void nsNullPrincipal::dumpImpl()
119 fprintf(stderr
, "nsNullPrincipal (%p) = %s\n", this, str
.get());
124 * nsIPrincipal implementation
128 nsNullPrincipal::Equals(nsIPrincipal
*aOther
, bool *aResult
)
130 // Just equal to ourselves. Note that nsPrincipal::Equals will return false
131 // for us since we have a unique domain/origin/etc.
132 *aResult
= (aOther
== this);
137 nsNullPrincipal::EqualsIgnoringDomain(nsIPrincipal
*aOther
, bool *aResult
)
139 return Equals(aOther
, aResult
);
143 nsNullPrincipal::GetHashValue(uint32_t *aResult
)
145 *aResult
= (NS_PTR_TO_INT32(this) >> 2);
150 nsNullPrincipal::GetSecurityPolicy(void** aSecurityPolicy
)
152 // Leftover from old security model, a "security policy" is a set of
153 // rules for property access that can override the SOP. Policies are
154 // associated with origins and since nsNullPinricipals never get the
155 // same origin twice, it's not possible to specify a "security
156 // policy" for it. Hence, we do not cache the security policy.
157 *aSecurityPolicy
= nullptr;
162 nsNullPrincipal::SetSecurityPolicy(void* aSecurityPolicy
)
164 // Leftover from old security model, a "security policy" is a set of
165 // rules for property access that can override the SOP. Policies are
166 // associated with origins and since nsNullPinricipals never get the
167 // same origin twice, it's not possible to specify a "security
168 // policy" for it. Hence, we do not cache the security policy.
173 nsNullPrincipal::GetURI(nsIURI
** aURI
)
175 return NS_EnsureSafeToReturn(mURI
, aURI
);
179 nsNullPrincipal::GetCsp(nsIContentSecurityPolicy
** aCsp
)
181 NS_IF_ADDREF(*aCsp
= mCSP
);
186 nsNullPrincipal::SetCsp(nsIContentSecurityPolicy
* aCsp
)
188 // If CSP was already set, it should not be destroyed! Instead, it should
189 // get set anew when a new principal is created.
191 return NS_ERROR_ALREADY_INITIALIZED
;
198 nsNullPrincipal::GetDomain(nsIURI
** aDomain
)
200 return NS_EnsureSafeToReturn(mURI
, aDomain
);
204 nsNullPrincipal::SetDomain(nsIURI
* aDomain
)
206 // I think the right thing to do here is to just throw... Silently failing
207 // seems counterproductive.
208 return NS_ERROR_NOT_AVAILABLE
;
212 nsNullPrincipal::GetOrigin(char** aOrigin
)
217 nsresult rv
= mURI
->GetSpec(str
);
218 NS_ENSURE_SUCCESS(rv
, rv
);
220 *aOrigin
= ToNewCString(str
);
221 NS_ENSURE_TRUE(*aOrigin
, NS_ERROR_OUT_OF_MEMORY
);
227 nsNullPrincipal::Subsumes(nsIPrincipal
*aOther
, bool *aResult
)
229 // We don't subsume anything except ourselves. Note that nsPrincipal::Equals
230 // will return false for us, since we're not about:blank and not Equals to
231 // reasonable nsPrincipals.
232 *aResult
= (aOther
== this);
237 nsNullPrincipal::SubsumesIgnoringDomain(nsIPrincipal
*aOther
, bool *aResult
)
239 return Subsumes(aOther
, aResult
);
243 nsNullPrincipal::CheckMayLoad(nsIURI
* aURI
, bool aReport
, bool aAllowIfInheritsPrincipal
)
245 if (aAllowIfInheritsPrincipal
) {
246 if (nsPrincipal::IsPrincipalInherited(aURI
)) {
250 // Also allow the load if the principal of the URI being checked is exactly
252 nsCOMPtr
<nsIURIWithPrincipal
> uriPrinc
= do_QueryInterface(aURI
);
254 nsCOMPtr
<nsIPrincipal
> principal
;
255 uriPrinc
->GetPrincipal(getter_AddRefs(principal
));
257 if (principal
&& principal
== this) {
264 nsScriptSecurityManager::ReportError(
265 nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mURI
, aURI
);
268 return NS_ERROR_DOM_BAD_URI
;
272 nsNullPrincipal::GetJarPrefix(nsACString
& aJarPrefix
)
274 aJarPrefix
.Truncate();
279 nsNullPrincipal::GetAppStatus(uint16_t* aAppStatus
)
281 *aAppStatus
= nsIPrincipal::APP_STATUS_NOT_INSTALLED
;
286 nsNullPrincipal::GetAppId(uint32_t* aAppId
)
288 *aAppId
= nsIScriptSecurityManager::NO_APP_ID
;
293 nsNullPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement
)
295 *aIsInBrowserElement
= false;
300 nsNullPrincipal::GetUnknownAppId(bool* aUnknownAppId
)
302 *aUnknownAppId
= false;
307 nsNullPrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal
)
309 *aIsNullPrincipal
= true;
314 nsNullPrincipal::GetBaseDomain(nsACString
& aBaseDomain
)
316 // For a null principal, we use our unique uuid as the base domain.
317 return mURI
->GetPath(aBaseDomain
);
321 * nsISerializable implementation
324 nsNullPrincipal::Read(nsIObjectInputStream
* aStream
)
326 // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI
327 // is not really relevant.
332 nsNullPrincipal::Write(nsIObjectOutputStream
* aStream
)
334 // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI
335 // is not really relevant.