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/ArrayUtils.h"
14 #include "nsNullPrincipal.h"
15 #include "nsNullPrincipalURI.h"
17 #include "nsIUUIDGenerator.h"
19 #include "nsNetUtil.h"
20 #include "nsIClassInfoImpl.h"
21 #include "nsIObjectInputStream.h"
22 #include "nsIObjectOutputStream.h"
25 #include "nsIScriptSecurityManager.h"
26 #include "nsPrincipal.h"
27 #include "nsScriptSecurityManager.h"
30 using namespace mozilla
;
32 NS_IMPL_CLASSINFO(nsNullPrincipal
, nullptr, nsIClassInfo::MAIN_THREAD_ONLY
,
34 NS_IMPL_QUERY_INTERFACE_CI(nsNullPrincipal
,
37 NS_IMPL_CI_INTERFACE_GETTER(nsNullPrincipal
,
41 NS_IMETHODIMP_(MozExternalRefCountType
)
42 nsNullPrincipal::AddRef()
44 NS_PRECONDITION(int32_t(refcount
) >= 0, "illegal refcnt");
45 nsrefcnt count
= ++refcount
;
46 NS_LOG_ADDREF(this, count
, "nsNullPrincipal", sizeof(*this));
50 NS_IMETHODIMP_(MozExternalRefCountType
)
51 nsNullPrincipal::Release()
53 NS_PRECONDITION(0 != refcount
, "dup release");
54 nsrefcnt count
= --refcount
;
55 NS_LOG_RELEASE(this, count
, "nsNullPrincipal");
63 nsNullPrincipal::nsNullPrincipal()
67 nsNullPrincipal::~nsNullPrincipal()
71 /* static */ already_AddRefed
<nsNullPrincipal
>
72 nsNullPrincipal::CreateWithInheritedAttributes(nsIPrincipal
* aInheritFrom
)
74 nsRefPtr
<nsNullPrincipal
> nullPrin
= new nsNullPrincipal();
75 nsresult rv
= nullPrin
->Init(aInheritFrom
->GetAppId(),
76 aInheritFrom
->GetIsInBrowserElement());
77 return NS_SUCCEEDED(rv
) ? nullPrin
.forget() : nullptr;
80 #define NS_NULLPRINCIPAL_PREFIX NS_NULLPRINCIPAL_SCHEME ":"
83 nsNullPrincipal::Init(uint32_t aAppId
, bool aInMozBrowser
)
85 MOZ_ASSERT(aAppId
!= nsIScriptSecurityManager::UNKNOWN_APP_ID
);
87 mInMozBrowser
= aInMozBrowser
;
89 // FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
91 nsCOMPtr
<nsIUUIDGenerator
> uuidgen
=
92 do_GetService("@mozilla.org/uuid-generator;1", &rv
);
93 NS_ENSURE_SUCCESS(rv
, rv
);
96 rv
= uuidgen
->GenerateUUIDInPlace(&id
);
97 NS_ENSURE_SUCCESS(rv
, rv
);
99 char chars
[NSID_LENGTH
];
100 id
.ToProvidedString(chars
);
102 uint32_t suffixLen
= NSID_LENGTH
- 1;
103 uint32_t prefixLen
= ArrayLength(NS_NULLPRINCIPAL_PREFIX
) - 1;
105 // Use an nsCString so we only do the allocation once here and then share
106 // with nsJSPrincipals
108 str
.SetCapacity(prefixLen
+ suffixLen
);
110 str
.Append(NS_NULLPRINCIPAL_PREFIX
);
113 if (str
.Length() != prefixLen
+ suffixLen
) {
114 NS_WARNING("Out of memory allocating null-principal URI");
115 return NS_ERROR_OUT_OF_MEMORY
;
118 mURI
= new nsNullPrincipalURI(str
);
119 NS_ENSURE_TRUE(mURI
, NS_ERROR_OUT_OF_MEMORY
);
125 nsNullPrincipal::GetScriptLocation(nsACString
&aStr
)
131 void nsNullPrincipal::dumpImpl()
135 fprintf(stderr
, "nsNullPrincipal (%p) = %s\n", this, str
.get());
140 * nsIPrincipal implementation
144 nsNullPrincipal::Equals(nsIPrincipal
*aOther
, bool *aResult
)
146 // Just equal to ourselves. Note that nsPrincipal::Equals will return false
147 // for us since we have a unique domain/origin/etc.
148 *aResult
= (aOther
== this);
153 nsNullPrincipal::EqualsConsideringDomain(nsIPrincipal
*aOther
, bool *aResult
)
155 return Equals(aOther
, aResult
);
159 nsNullPrincipal::GetHashValue(uint32_t *aResult
)
161 *aResult
= (NS_PTR_TO_INT32(this) >> 2);
166 nsNullPrincipal::GetURI(nsIURI
** aURI
)
168 return NS_EnsureSafeToReturn(mURI
, aURI
);
172 nsNullPrincipal::GetCsp(nsIContentSecurityPolicy
** aCsp
)
174 NS_IF_ADDREF(*aCsp
= mCSP
);
179 nsNullPrincipal::SetCsp(nsIContentSecurityPolicy
* aCsp
)
181 // If CSP was already set, it should not be destroyed! Instead, it should
182 // get set anew when a new principal is created.
184 return NS_ERROR_ALREADY_INITIALIZED
;
191 nsNullPrincipal::GetDomain(nsIURI
** aDomain
)
193 return NS_EnsureSafeToReturn(mURI
, aDomain
);
197 nsNullPrincipal::SetDomain(nsIURI
* aDomain
)
199 // I think the right thing to do here is to just throw... Silently failing
200 // seems counterproductive.
201 return NS_ERROR_NOT_AVAILABLE
;
205 nsNullPrincipal::GetOrigin(char** aOrigin
)
210 nsresult rv
= mURI
->GetSpec(str
);
211 NS_ENSURE_SUCCESS(rv
, rv
);
213 *aOrigin
= ToNewCString(str
);
214 NS_ENSURE_TRUE(*aOrigin
, NS_ERROR_OUT_OF_MEMORY
);
220 nsNullPrincipal::Subsumes(nsIPrincipal
*aOther
, bool *aResult
)
222 // We don't subsume anything except ourselves. Note that nsPrincipal::Equals
223 // will return false for us, since we're not about:blank and not Equals to
224 // reasonable nsPrincipals.
225 *aResult
= (aOther
== this);
230 nsNullPrincipal::SubsumesConsideringDomain(nsIPrincipal
*aOther
, bool *aResult
)
232 return Subsumes(aOther
, aResult
);
236 nsNullPrincipal::CheckMayLoad(nsIURI
* aURI
, bool aReport
, bool aAllowIfInheritsPrincipal
)
238 if (aAllowIfInheritsPrincipal
) {
239 if (nsPrincipal::IsPrincipalInherited(aURI
)) {
243 // Also allow the load if the principal of the URI being checked is exactly
245 nsCOMPtr
<nsIURIWithPrincipal
> uriPrinc
= do_QueryInterface(aURI
);
247 nsCOMPtr
<nsIPrincipal
> principal
;
248 uriPrinc
->GetPrincipal(getter_AddRefs(principal
));
250 if (principal
&& principal
== this) {
257 nsScriptSecurityManager::ReportError(
258 nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mURI
, aURI
);
261 return NS_ERROR_DOM_BAD_URI
;
265 nsNullPrincipal::GetJarPrefix(nsACString
& aJarPrefix
)
267 aJarPrefix
.Truncate();
272 nsNullPrincipal::GetAppStatus(uint16_t* aAppStatus
)
274 *aAppStatus
= nsScriptSecurityManager::AppStatusForPrincipal(this);
279 nsNullPrincipal::GetAppId(uint32_t* aAppId
)
286 nsNullPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement
)
288 *aIsInBrowserElement
= mInMozBrowser
;
293 nsNullPrincipal::GetUnknownAppId(bool* aUnknownAppId
)
295 *aUnknownAppId
= false;
300 nsNullPrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal
)
302 *aIsNullPrincipal
= true;
307 nsNullPrincipal::GetBaseDomain(nsACString
& aBaseDomain
)
309 // For a null principal, we use our unique uuid as the base domain.
310 return mURI
->GetPath(aBaseDomain
);
314 * nsISerializable implementation
317 nsNullPrincipal::Read(nsIObjectInputStream
* aStream
)
319 // Note - nsNullPrincipal use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT, which means
320 // that the Init() method has already been invoked by the time we deserialize.
321 // This is in contrast to nsPrincipal, which uses NS_GENERIC_FACTORY_CONSTRUCTOR,
322 // in which case ::Read needs to invoke Init().
323 nsresult rv
= aStream
->Read32(&mAppId
);
324 NS_ENSURE_SUCCESS(rv
, rv
);
326 rv
= aStream
->ReadBoolean(&mInMozBrowser
);
327 NS_ENSURE_SUCCESS(rv
, rv
);
333 nsNullPrincipal::Write(nsIObjectOutputStream
* aStream
)
335 aStream
->Write32(mAppId
);
336 aStream
->WriteBoolean(mInMozBrowser
);