1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/caps/src/nsNullPrincipal.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,316 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/** 1.10 + * This is the principal that has no rights and can't be accessed by 1.11 + * anything other than itself and chrome; null principals are not 1.12 + * same-origin with anything but themselves. 1.13 + */ 1.14 + 1.15 +#include "mozilla/ArrayUtils.h" 1.16 + 1.17 +#include "nsNullPrincipal.h" 1.18 +#include "nsNullPrincipalURI.h" 1.19 +#include "nsMemory.h" 1.20 +#include "nsIUUIDGenerator.h" 1.21 +#include "nsID.h" 1.22 +#include "nsNetUtil.h" 1.23 +#include "nsIClassInfoImpl.h" 1.24 +#include "nsNetCID.h" 1.25 +#include "nsError.h" 1.26 +#include "nsIScriptSecurityManager.h" 1.27 +#include "nsPrincipal.h" 1.28 +#include "nsScriptSecurityManager.h" 1.29 +#include "pratom.h" 1.30 + 1.31 +using namespace mozilla; 1.32 + 1.33 +NS_IMPL_CLASSINFO(nsNullPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY, 1.34 + NS_NULLPRINCIPAL_CID) 1.35 +NS_IMPL_QUERY_INTERFACE_CI(nsNullPrincipal, 1.36 + nsIPrincipal, 1.37 + nsISerializable) 1.38 +NS_IMPL_CI_INTERFACE_GETTER(nsNullPrincipal, 1.39 + nsIPrincipal, 1.40 + nsISerializable) 1.41 + 1.42 +NS_IMETHODIMP_(MozExternalRefCountType) 1.43 +nsNullPrincipal::AddRef() 1.44 +{ 1.45 + NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt"); 1.46 + nsrefcnt count = ++refcount; 1.47 + NS_LOG_ADDREF(this, count, "nsNullPrincipal", sizeof(*this)); 1.48 + return count; 1.49 +} 1.50 + 1.51 +NS_IMETHODIMP_(MozExternalRefCountType) 1.52 +nsNullPrincipal::Release() 1.53 +{ 1.54 + NS_PRECONDITION(0 != refcount, "dup release"); 1.55 + nsrefcnt count = --refcount; 1.56 + NS_LOG_RELEASE(this, count, "nsNullPrincipal"); 1.57 + if (count == 0) { 1.58 + delete this; 1.59 + } 1.60 + 1.61 + return count; 1.62 +} 1.63 + 1.64 +nsNullPrincipal::nsNullPrincipal() 1.65 +{ 1.66 +} 1.67 + 1.68 +nsNullPrincipal::~nsNullPrincipal() 1.69 +{ 1.70 +} 1.71 + 1.72 +#define NS_NULLPRINCIPAL_PREFIX NS_NULLPRINCIPAL_SCHEME ":" 1.73 + 1.74 +nsresult 1.75 +nsNullPrincipal::Init() 1.76 +{ 1.77 + // FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant. 1.78 + nsresult rv; 1.79 + nsCOMPtr<nsIUUIDGenerator> uuidgen = 1.80 + do_GetService("@mozilla.org/uuid-generator;1", &rv); 1.81 + NS_ENSURE_SUCCESS(rv, rv); 1.82 + 1.83 + nsID id; 1.84 + rv = uuidgen->GenerateUUIDInPlace(&id); 1.85 + NS_ENSURE_SUCCESS(rv, rv); 1.86 + 1.87 + char chars[NSID_LENGTH]; 1.88 + id.ToProvidedString(chars); 1.89 + 1.90 + uint32_t suffixLen = NSID_LENGTH - 1; 1.91 + uint32_t prefixLen = ArrayLength(NS_NULLPRINCIPAL_PREFIX) - 1; 1.92 + 1.93 + // Use an nsCString so we only do the allocation once here and then share 1.94 + // with nsJSPrincipals 1.95 + nsCString str; 1.96 + str.SetCapacity(prefixLen + suffixLen); 1.97 + 1.98 + str.Append(NS_NULLPRINCIPAL_PREFIX); 1.99 + str.Append(chars); 1.100 + 1.101 + if (str.Length() != prefixLen + suffixLen) { 1.102 + NS_WARNING("Out of memory allocating null-principal URI"); 1.103 + return NS_ERROR_OUT_OF_MEMORY; 1.104 + } 1.105 + 1.106 + mURI = new nsNullPrincipalURI(str); 1.107 + NS_ENSURE_TRUE(mURI, NS_ERROR_OUT_OF_MEMORY); 1.108 + 1.109 + return NS_OK; 1.110 +} 1.111 + 1.112 +void 1.113 +nsNullPrincipal::GetScriptLocation(nsACString &aStr) 1.114 +{ 1.115 + mURI->GetSpec(aStr); 1.116 +} 1.117 + 1.118 +#ifdef DEBUG 1.119 +void nsNullPrincipal::dumpImpl() 1.120 +{ 1.121 + nsAutoCString str; 1.122 + mURI->GetSpec(str); 1.123 + fprintf(stderr, "nsNullPrincipal (%p) = %s\n", this, str.get()); 1.124 +} 1.125 +#endif 1.126 + 1.127 +/** 1.128 + * nsIPrincipal implementation 1.129 + */ 1.130 + 1.131 +NS_IMETHODIMP 1.132 +nsNullPrincipal::Equals(nsIPrincipal *aOther, bool *aResult) 1.133 +{ 1.134 + // Just equal to ourselves. Note that nsPrincipal::Equals will return false 1.135 + // for us since we have a unique domain/origin/etc. 1.136 + *aResult = (aOther == this); 1.137 + return NS_OK; 1.138 +} 1.139 + 1.140 +NS_IMETHODIMP 1.141 +nsNullPrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult) 1.142 +{ 1.143 + return Equals(aOther, aResult); 1.144 +} 1.145 + 1.146 +NS_IMETHODIMP 1.147 +nsNullPrincipal::GetHashValue(uint32_t *aResult) 1.148 +{ 1.149 + *aResult = (NS_PTR_TO_INT32(this) >> 2); 1.150 + return NS_OK; 1.151 +} 1.152 + 1.153 +NS_IMETHODIMP 1.154 +nsNullPrincipal::GetURI(nsIURI** aURI) 1.155 +{ 1.156 + return NS_EnsureSafeToReturn(mURI, aURI); 1.157 +} 1.158 + 1.159 +NS_IMETHODIMP 1.160 +nsNullPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) 1.161 +{ 1.162 + NS_IF_ADDREF(*aCsp = mCSP); 1.163 + return NS_OK; 1.164 +} 1.165 + 1.166 +NS_IMETHODIMP 1.167 +nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) 1.168 +{ 1.169 + // If CSP was already set, it should not be destroyed! Instead, it should 1.170 + // get set anew when a new principal is created. 1.171 + if (mCSP) 1.172 + return NS_ERROR_ALREADY_INITIALIZED; 1.173 + 1.174 + mCSP = aCsp; 1.175 + return NS_OK; 1.176 +} 1.177 + 1.178 +NS_IMETHODIMP 1.179 +nsNullPrincipal::GetDomain(nsIURI** aDomain) 1.180 +{ 1.181 + return NS_EnsureSafeToReturn(mURI, aDomain); 1.182 +} 1.183 + 1.184 +NS_IMETHODIMP 1.185 +nsNullPrincipal::SetDomain(nsIURI* aDomain) 1.186 +{ 1.187 + // I think the right thing to do here is to just throw... Silently failing 1.188 + // seems counterproductive. 1.189 + return NS_ERROR_NOT_AVAILABLE; 1.190 +} 1.191 + 1.192 +NS_IMETHODIMP 1.193 +nsNullPrincipal::GetOrigin(char** aOrigin) 1.194 +{ 1.195 + *aOrigin = nullptr; 1.196 + 1.197 + nsAutoCString str; 1.198 + nsresult rv = mURI->GetSpec(str); 1.199 + NS_ENSURE_SUCCESS(rv, rv); 1.200 + 1.201 + *aOrigin = ToNewCString(str); 1.202 + NS_ENSURE_TRUE(*aOrigin, NS_ERROR_OUT_OF_MEMORY); 1.203 + 1.204 + return NS_OK; 1.205 +} 1.206 + 1.207 +NS_IMETHODIMP 1.208 +nsNullPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult) 1.209 +{ 1.210 + // We don't subsume anything except ourselves. Note that nsPrincipal::Equals 1.211 + // will return false for us, since we're not about:blank and not Equals to 1.212 + // reasonable nsPrincipals. 1.213 + *aResult = (aOther == this); 1.214 + return NS_OK; 1.215 +} 1.216 + 1.217 +NS_IMETHODIMP 1.218 +nsNullPrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult) 1.219 +{ 1.220 + return Subsumes(aOther, aResult); 1.221 +} 1.222 + 1.223 +NS_IMETHODIMP 1.224 +nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal) 1.225 + { 1.226 + if (aAllowIfInheritsPrincipal) { 1.227 + if (nsPrincipal::IsPrincipalInherited(aURI)) { 1.228 + return NS_OK; 1.229 + } 1.230 + 1.231 + // Also allow the load if the principal of the URI being checked is exactly 1.232 + // us ie this. 1.233 + nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI); 1.234 + if (uriPrinc) { 1.235 + nsCOMPtr<nsIPrincipal> principal; 1.236 + uriPrinc->GetPrincipal(getter_AddRefs(principal)); 1.237 + 1.238 + if (principal && principal == this) { 1.239 + return NS_OK; 1.240 + } 1.241 + } 1.242 + } 1.243 + 1.244 + if (aReport) { 1.245 + nsScriptSecurityManager::ReportError( 1.246 + nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mURI, aURI); 1.247 + } 1.248 + 1.249 + return NS_ERROR_DOM_BAD_URI; 1.250 +} 1.251 + 1.252 +NS_IMETHODIMP 1.253 +nsNullPrincipal::GetJarPrefix(nsACString& aJarPrefix) 1.254 +{ 1.255 + aJarPrefix.Truncate(); 1.256 + return NS_OK; 1.257 +} 1.258 + 1.259 +NS_IMETHODIMP 1.260 +nsNullPrincipal::GetAppStatus(uint16_t* aAppStatus) 1.261 +{ 1.262 + *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED; 1.263 + return NS_OK; 1.264 +} 1.265 + 1.266 +NS_IMETHODIMP 1.267 +nsNullPrincipal::GetAppId(uint32_t* aAppId) 1.268 +{ 1.269 + *aAppId = nsIScriptSecurityManager::NO_APP_ID; 1.270 + return NS_OK; 1.271 +} 1.272 + 1.273 +NS_IMETHODIMP 1.274 +nsNullPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement) 1.275 +{ 1.276 + *aIsInBrowserElement = false; 1.277 + return NS_OK; 1.278 +} 1.279 + 1.280 +NS_IMETHODIMP 1.281 +nsNullPrincipal::GetUnknownAppId(bool* aUnknownAppId) 1.282 +{ 1.283 + *aUnknownAppId = false; 1.284 + return NS_OK; 1.285 +} 1.286 + 1.287 +NS_IMETHODIMP 1.288 +nsNullPrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal) 1.289 +{ 1.290 + *aIsNullPrincipal = true; 1.291 + return NS_OK; 1.292 +} 1.293 + 1.294 +NS_IMETHODIMP 1.295 +nsNullPrincipal::GetBaseDomain(nsACString& aBaseDomain) 1.296 +{ 1.297 + // For a null principal, we use our unique uuid as the base domain. 1.298 + return mURI->GetPath(aBaseDomain); 1.299 +} 1.300 + 1.301 +/** 1.302 + * nsISerializable implementation 1.303 + */ 1.304 +NS_IMETHODIMP 1.305 +nsNullPrincipal::Read(nsIObjectInputStream* aStream) 1.306 +{ 1.307 + // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI 1.308 + // is not really relevant. 1.309 + return NS_OK; 1.310 +} 1.311 + 1.312 +NS_IMETHODIMP 1.313 +nsNullPrincipal::Write(nsIObjectOutputStream* aStream) 1.314 +{ 1.315 + // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI 1.316 + // is not really relevant. 1.317 + return NS_OK; 1.318 +} 1.319 +