diff --git a/mozilla/caps/include/nsNullPrincipal.h b/mozilla/caps/include/nsNullPrincipal.h new file mode 100644 index 00000000000..e342d287bb7 --- /dev/null +++ b/mozilla/caps/include/nsNullPrincipal.h @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * the Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Boris Zbarsky (Original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * This is the principal that has no rights and can't be accessed by + * anything other than itself and chrome; null principals are not + * same-origin with anything but themselves. + */ + +#ifndef nsNullPrincipal_h__ +#define nsNullPrincipal_h__ + +#include "nsIPrincipal.h" +#include "nsJSPrincipals.h" +#include "nsCOMPtr.h" + +class nsIURI; + +#define NS_NULLPRINCIPAL_CLASSNAME "nullprincipal" +#define NS_NULLPRINCIPAL_CID \ +{ 0xdd156d62, 0xd26f, 0x4441, \ + { 0x9c, 0xdb, 0xe8, 0xf0, 0x91, 0x07, 0xc2, 0x73 } } +#define NS_NULLPRINCIPAL_CONTRACTID "@mozilla.org/nullprincipal;1" + +#define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal" + +class nsNullPrincipal : public nsIPrincipal +{ +public: + nsNullPrincipal(); + + // Our refcount is managed by mJSPrincipals. Use this macro to avoid an + // extra refcount member. + + // FIXME: bug 327245 -- I sorta wish there were a clean way to share the + // mJSPrincipals munging code between the various principal classes without + // giving up the NS_DECL_NSIPRINCIPAL goodness. + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIPRINCIPAL + NS_DECL_NSISERIALIZABLE + + nsresult Init(); + +protected: + virtual ~nsNullPrincipal(); + + nsJSPrincipals mJSPrincipals; + nsCOMPtr mURI; +}; + +#endif // nsNullPrincipal_h__ diff --git a/mozilla/caps/include/nsSystemPrincipal.h b/mozilla/caps/include/nsSystemPrincipal.h index 1fd6afc78c6..9d475cc5743 100644 --- a/mozilla/caps/include/nsSystemPrincipal.h +++ b/mozilla/caps/include/nsSystemPrincipal.h @@ -53,6 +53,8 @@ class nsSystemPrincipal : public nsIPrincipal { public: + // Our refcount is managed by mJSPrincipals. Use this macro to avoid + // an extra refcount member. NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIPRINCIPAL NS_DECL_NSISERIALIZABLE diff --git a/mozilla/caps/src/Makefile.in b/mozilla/caps/src/Makefile.in index 86d31e8afbf..2f43efe2a8f 100644 --- a/mozilla/caps/src/Makefile.in +++ b/mozilla/caps/src/Makefile.in @@ -72,6 +72,7 @@ REQUIRES = xpcom \ CPPSRCS = \ nsPrincipal.cpp \ nsSystemPrincipal.cpp \ + nsNullPrincipal.cpp \ nsJSPrincipals.cpp \ nsScriptSecurityManager.cpp \ nsSecurityManagerFactory.cpp \ diff --git a/mozilla/caps/src/nsNullPrincipal.cpp b/mozilla/caps/src/nsNullPrincipal.cpp new file mode 100644 index 00000000000..6b517ded8c3 --- /dev/null +++ b/mozilla/caps/src/nsNullPrincipal.cpp @@ -0,0 +1,334 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * the Mozilla Corporation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Boris Zbarsky (Original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * This is the principal that has no rights and can't be accessed by + * anything other than itself and chrome; null principals are not + * same-origin with anything but themselves. + */ + +#include "nsNullPrincipal.h" +#include "nsMemory.h" +#include "nsIUUIDGenerator.h" +#include "nsID.h" +#include "prmem.h" // For PF_Free, 'cause nsID::ToString sucks like that +#include "nsNetUtil.h" +#include "nsIClassInfoImpl.h" + +NS_IMPL_QUERY_INTERFACE2_CI(nsNullPrincipal, + nsIPrincipal, + nsISerializable) +NS_IMPL_CI_INTERFACE_GETTER2(nsNullPrincipal, + nsIPrincipal, + nsISerializable) + +NS_IMETHODIMP_(nsrefcnt) +nsNullPrincipal::AddRef() +{ + NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt"); + nsrefcnt count = PR_AtomicIncrement((PRInt32 *)&mJSPrincipals.refcount); + NS_LOG_ADDREF(this, count, "nsNullPrincipal", sizeof(*this)); + return count; +} + +NS_IMETHODIMP_(nsrefcnt) +nsNullPrincipal::Release() +{ + NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release"); + nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount); + NS_LOG_RELEASE(this, count, "nsNullPrincipal"); + if (count == 0) { + NS_DELETEXPCOM(this); + } + + return count; +} + +nsNullPrincipal::nsNullPrincipal() +{ +} + +nsNullPrincipal::~nsNullPrincipal() +{ +} + +nsresult +nsNullPrincipal::Init() +{ + // FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant. + nsresult rv; + nsCOMPtr uuidgen = + do_GetService("@mozilla.org/uuid-generator;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsID id; + rv = uuidgen->GenerateUUIDInPlace(&id); + NS_ENSURE_SUCCESS(rv, rv); + + char* chars = id.ToString(); + NS_ENSURE_TRUE(chars, NS_ERROR_OUT_OF_MEMORY); + + nsCAutoString str(NS_NULLPRINCIPAL_SCHEME ":"); + PRUint32 prefixLen = str.Length(); + PRUint32 suffixLen = strlen(chars); + + str.Append(chars); + + PR_Free(chars); + + if (str.Length() != prefixLen + suffixLen) { + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = NS_NewURI(getter_AddRefs(mURI), str); + NS_ENSURE_SUCCESS(rv, rv); + + return mJSPrincipals.Init(this, str.get()); +} + +/** + * nsIPrincipal implementation + */ + +NS_IMETHODIMP +nsNullPrincipal::GetPreferences(char** aPrefName, char** aID, + char** aSubjectName, + char** aGrantedList, char** aDeniedList) +{ + // The null principal should never be written to preferences. + *aPrefName = nsnull; + *aID = nsnull; + *aSubjectName = nsnull; + *aGrantedList = nsnull; + *aDeniedList = nsnull; + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsNullPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult) +{ + // Just equal to ourselves. Note that nsPrincipal::Equals will return false + // for us since we have a unique domain/origin/etc. + *aResult = (aOther == this); + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::GetHashValue(PRUint32 *aResult) +{ + *aResult = (NS_PTR_TO_INT32(this) >> 2); + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::GetJSPrincipals(JSContext *cx, JSPrincipals **aJsprin) +{ + NS_PRECONDITION(mJSPrincipals.nsIPrincipalPtr, + "mJSPrincipals is uninitalized!"); + + JSPRINCIPALS_HOLD(cx, &mJSPrincipals); + *aJsprin = &mJSPrincipals; + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::GetSecurityPolicy(void** aSecurityPolicy) +{ + // We don't actually do security policy caching. And it's not like anyone + // can set a security policy for us anyway. + *aSecurityPolicy = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::SetSecurityPolicy(void* aSecurityPolicy) +{ + // We don't actually do security policy caching. And it's not like anyone + // can set a security policy for us anyway. + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::CanEnableCapability(const char *aCapability, + PRInt16 *aResult) +{ + // Null principal can enable no capabilities. + *aResult = nsIPrincipal::ENABLE_DENIED; + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::SetCanEnableCapability(const char *aCapability, + PRInt16 aCanEnable) +{ + return NS_ERROR_NOT_AVAILABLE; +} + + +NS_IMETHODIMP +nsNullPrincipal::IsCapabilityEnabled(const char *aCapability, + void *aAnnotation, + PRBool *aResult) +{ + // Nope. No capabilities, I say! + *aResult = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::EnableCapability(const char *aCapability, void **aAnnotation) +{ + NS_NOTREACHED("Didn't I say it? NO CAPABILITIES!"); + *aAnnotation = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::RevertCapability(const char *aCapability, void **aAnnotation) +{ + *aAnnotation = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::DisableCapability(const char *aCapability, void **aAnnotation) +{ + // Just a no-op. They're all disabled anyway. + *aAnnotation = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::GetURI(nsIURI** aURI) +{ + NS_ADDREF(*aURI = mURI); + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::GetDomain(nsIURI** aDomain) +{ + NS_ADDREF(*aDomain = mURI); + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::SetDomain(nsIURI* aDomain) +{ + // I think the right thing to do here is to just throw... Silently failing + // seems counterproductive. + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsNullPrincipal::GetOrigin(char** aOrigin) +{ + *aOrigin = nsnull; + + nsCAutoString str; + nsresult rv = mURI->GetSpec(str); + NS_ENSURE_SUCCESS(rv, rv); + + *aOrigin = ToNewCString(str); + NS_ENSURE_TRUE(*aOrigin, NS_ERROR_OUT_OF_MEMORY); + + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::GetHasCertificate(PRBool* aResult) +{ + *aResult = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::GetFingerprint(nsACString& aID) +{ + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsNullPrincipal::GetPrettyName(nsACString& aName) +{ + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsNullPrincipal::Subsumes(nsIPrincipal *aOther, PRBool *aResult) +{ + // We don't subsume anything except ourselves. Note that nsPrincipal::Equals + // will return false for us, since we're not about:blank and not Equals to + // reasonable nsPrincipals. + *aResult = (aOther == this); + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::GetSubjectName(nsACString& aName) +{ + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsNullPrincipal::GetCertificate(nsISupports** aCertificate) +{ + *aCertificate = nsnull; + return NS_OK; +} + +/** + * nsISerializable implementation + */ +NS_IMETHODIMP +nsNullPrincipal::Read(nsIObjectInputStream* aStream) +{ + // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI + // is not really relevant. + return NS_OK; +} + +NS_IMETHODIMP +nsNullPrincipal::Write(nsIObjectOutputStream* aStream) +{ + // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI + // is not really relevant. + return NS_OK; +} + diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index 13029b049c4..8d06d18ed92 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -49,6 +49,7 @@ #include "nsJSPrincipals.h" #include "nsSystemPrincipal.h" #include "nsPrincipal.h" +#include "nsNullPrincipal.h" #include "nsXPIDLString.h" #include "nsCRT.h" #include "nsIJSContextStack.h" @@ -246,6 +247,11 @@ nsScriptSecurityManager::SecurityCompareURIs(nsIURI* aSourceURI, { *result = PR_FALSE; + // Note that this is not an Equals() test on purpose -- for URIs that don't + // support host/port, we want equality to basically be object identity, for + // security purposes. Otherwise, for example, two javascript: URIs that + // are otherwise unrelated could end up "same origin", which would be + // unfortunate. if (aSourceURI == aTargetURI) { *result = PR_TRUE; @@ -880,12 +886,18 @@ nsScriptSecurityManager::CheckSameOriginPrincipalInternal(nsIPrincipal* aSubject return NS_OK; } - // Allow access to about:blank - nsXPIDLCString origin; - rv = aObject->GetOrigin(getter_Copies(origin)); - NS_ENSURE_SUCCESS(rv, rv); - if (nsCRT::strcasecmp(origin, "about:blank") == 0) - return NS_OK; + // Allow access to about:blank, except from null principals (which + // never have access to anything but themselves). If SchemeIs + // fails, just deny access -- better safe than sorry. + PRBool nullSubject = PR_FALSE; + rv = subjectURI->SchemeIs(NS_NULLPRINCIPAL_SCHEME, &nullSubject); + if (NS_SUCCEEDED(rv) && !nullSubject) { + nsXPIDLCString origin; + rv = aObject->GetOrigin(getter_Copies(origin)); + NS_ENSURE_SUCCESS(rv, rv); + if (nsCRT::strcasecmp(origin, "about:blank") == 0) + return NS_OK; + } /* ** Access tests failed, so now report error. @@ -967,6 +979,9 @@ nsScriptSecurityManager::LookupPolicy(nsIPrincipal* aPrincipal, char *p = start; //-- skip (nested) jar schemes to reach the "real" URI + // FIXME: bug 327241 -- that's not what we do in SecurityCompareURIs! + // We should do something more like that, except I guess this is faster + // than QI followed by getter, etc... :( while (*p == 'j' && *(++p) == 'a' && *(++p) == 'r' && *(++p) == ':') start = ++p; @@ -1122,17 +1137,12 @@ nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx, nsIURI *aURI) if (!principal) return NS_OK; - // The system principal can load all URIs. - if (principal == mSystemPrincipal) - return NS_OK; - - // Otherwise, principal should have a codebase URI that we can use to - // do the remaining tests. - nsCOMPtr uri; - if (NS_FAILED(principal->GetURI(getter_AddRefs(uri)))) - return NS_ERROR_FAILURE; - if (NS_SUCCEEDED(CheckLoadURI(uri, aURI, nsIScriptSecurityManager::STANDARD ))) + rv = CheckLoadURIWithPrincipal(principal, aURI, + nsIScriptSecurityManager::STANDARD); + if (NS_SUCCEEDED(rv)) { + // OK to load return NS_OK; + } // See if we're attempting to load a file: URI. If so, let a // UniversalFileRead capability trump the above check. @@ -1221,9 +1231,14 @@ NS_IMETHODIMP nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI, PRUint32 aFlags) { + // FIXME: bug 327244 -- this function should really die... Really truly. NS_PRECONDITION(aSourceURI, "CheckLoadURI called with null source URI"); NS_ENSURE_ARG_POINTER(aSourceURI); - + + // Note: this is not _quite_ right if aSourceURI has + // NS_NULLPRINCIPAL_SCHEME, but we'll just extract the scheme in + // CheckLoadURIWithPrincipal anyway, so this is good enough. This method + // really needs to go away.... nsCOMPtr sourcePrincipal; nsresult rv = CreateCodebasePrincipal(aSourceURI, getter_AddRefs(sourcePrincipal)); @@ -1262,6 +1277,14 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, nsresult rv = GetBaseURIScheme(sourceURI, sourceScheme); if (NS_FAILED(rv)) return rv; + NS_NAMED_LITERAL_STRING(errorTag, "CheckLoadURIError"); + + // Don't allow null principals to load anything + if (sourceScheme.LowerCaseEqualsLiteral(NS_NULLPRINCIPAL_SCHEME)) { + ReportError(nsnull, errorTag, sourceURI, aTargetURI); + return NS_ERROR_DOM_BAD_URI; + } + // Some loads are not allowed from mail/news messages if ((aFlags & nsIScriptSecurityManager::DISALLOW_FROM_MAIL) && (sourceScheme.LowerCaseEqualsLiteral("mailbox") || @@ -1286,7 +1309,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, return NS_ERROR_DOM_BAD_URI; } - if (nsCRT::strcasecmp(targetScheme.get(), sourceScheme.get()) == 0) + if (targetScheme.Equals(sourceScheme, + nsCaseInsensitiveCStringComparator())) { // every scheme can access another URI from the same scheme return NS_OK; @@ -1325,10 +1349,14 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, { "datetime", DenyProtocol }, { "finger", AllowProtocol }, { "res", DenyProtocol }, - { "x-jsd", ChromeProtocol } + { "x-jsd", ChromeProtocol }, + + // Don't allow random people to load null-principal URIs. Not like it + // matters _that_ much, since we won't have a useful handler for them, + // but... + { NS_NULLPRINCIPAL_SCHEME, DenyProtocol } }; - NS_NAMED_LITERAL_STRING(errorTag, "CheckLoadURIError"); for (unsigned i=0; i < sizeof(protocolList)/sizeof(protocolList[0]); i++) { if (targetScheme.LowerCaseEqualsASCII(protocolList[i].name)) @@ -1449,6 +1477,7 @@ nsScriptSecurityManager::CheckLoadURIStr(const nsACString& aSourceURIStr, const nsACString& aTargetURIStr, PRUint32 aFlags) { + // FIXME: bug 327244 -- this function should really die... Really truly. nsCOMPtr source; nsresult rv = NS_NewURI(getter_AddRefs(source), aSourceURIStr, nsnull, nsnull, sIOService); @@ -1822,6 +1851,9 @@ nsScriptSecurityManager::DoGetCertificatePrincipal(const nsACString& aCertFinger nsresult nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal **result) { + // I _think_ it's safe to not create null principals here based on aURI. + // At least all the callers would do the right thing in those cases, as far + // as I can tell. --bz nsRefPtr codebase = new nsPrincipal(); if (!codebase) return NS_ERROR_OUT_OF_MEMORY; diff --git a/mozilla/caps/src/nsSecurityManagerFactory.cpp b/mozilla/caps/src/nsSecurityManagerFactory.cpp index 14339de9ebc..48e891bfec9 100644 --- a/mozilla/caps/src/nsSecurityManagerFactory.cpp +++ b/mozilla/caps/src/nsSecurityManagerFactory.cpp @@ -44,6 +44,7 @@ #include "nsIPrincipal.h" #include "nsPrincipal.h" #include "nsSystemPrincipal.h" +#include "nsNullPrincipal.h" #include "nsIScriptNameSpaceManager.h" #include "nsIScriptExternalNameSet.h" #include "nsIScriptContext.h" @@ -341,11 +342,11 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrincipal) NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecurityNameSet) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsSystemPrincipal, nsScriptSecurityManager::SystemPrincipalSingletonConstructor) - +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNullPrincipal, Init) NS_DECL_CLASSINFO(nsPrincipal) NS_DECL_CLASSINFO(nsSystemPrincipal) - +NS_DECL_CLASSINFO(nsNullPrincipal) static NS_IMETHODIMP Construct_nsIScriptSecurityManager(nsISupports *aOuter, REFNSIID aIID, @@ -466,6 +467,19 @@ static const nsModuleComponentInfo capsComponentInfo[] = nsIClassInfo::EAGER_CLASSINFO }, + { NS_NULLPRINCIPAL_CLASSNAME, + NS_NULLPRINCIPAL_CID, + NS_NULLPRINCIPAL_CONTRACTID, + nsNullPrincipalConstructor, + nsnull, + nsnull, + nsnull, + NS_CI_INTERFACE_GETTER_NAME(nsNullPrincipal), + nsnull, + &NS_CLASSINFO_NAME(nsNullPrincipal), + nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::EAGER_CLASSINFO + }, + { "Security Script Name Set", NS_SECURITYNAMESET_CID, NS_SECURITYNAMESET_CONTRACTID, diff --git a/mozilla/content/xbl/src/nsBindingManager.cpp b/mozilla/content/xbl/src/nsBindingManager.cpp index 27b84bf2105..e1d35fccc9e 100644 --- a/mozilla/content/xbl/src/nsBindingManager.cpp +++ b/mozilla/content/xbl/src/nsBindingManager.cpp @@ -77,11 +77,7 @@ #include "nsIXPConnect.h" #include "nsDOMCID.h" #include "nsIDOMScriptObjectFactory.h" -#include "nsIPrincipal.h" #include "nsIScriptGlobalObject.h" -#include "nsIScriptObjectPrincipal.h" -#include "nsIConsoleService.h" -#include "nsIScriptError.h" #include "nsIScriptContext.h" #include "nsBindingManager.h" diff --git a/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp b/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp index 8d82c3c63fe..8456e953519 100644 --- a/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp @@ -45,7 +45,6 @@ #include "nsIDOMNodeList.h" #include "nsIDOMXULDocument.h" #include "nsINodeInfo.h" -#include "nsIPrincipal.h" #include "nsIServiceManager.h" #include "nsITextContent.h" #include "nsIXULDocument.h" diff --git a/mozilla/dom/src/jsurl/nsJSProtocolHandler.cpp b/mozilla/dom/src/jsurl/nsJSProtocolHandler.cpp index 6fa1cc90611..2410feeea06 100644 --- a/mozilla/dom/src/jsurl/nsJSProtocolHandler.cpp +++ b/mozilla/dom/src/jsurl/nsJSProtocolHandler.cpp @@ -261,9 +261,8 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel) } if (NS_FAILED(rv) || !principal) { - // If all else fails, use the current URI to generate a principal. - rv = securityManager->GetCodebasePrincipal(mURI, - getter_AddRefs(principal)); + // If all else fails, use a null principal + principal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); } if (NS_FAILED(rv) || !principal) { diff --git a/mozilla/js/src/xpconnect/src/xpccomponents.cpp b/mozilla/js/src/xpconnect/src/xpccomponents.cpp index 0abeba8c174..de3d9175fd3 100644 --- a/mozilla/js/src/xpconnect/src/xpccomponents.cpp +++ b/mozilla/js/src/xpconnect/src/xpccomponents.cpp @@ -2067,30 +2067,6 @@ nsXPCComponents_Utils::ReportError() const char kScriptSecurityManagerContractID[] = NS_SCRIPTSECURITYMANAGER_CONTRACTID; const char kStandardURLContractID[] = "@mozilla.org/network/standard-url;1"; -#define PRINCIPALHOLDER_IID \ -{0xbf109f49, 0xf94a, 0x43d8, {0x93, 0xdb, 0xe4, 0x66, 0x49, 0xc5, 0xd9, 0x7d}} - -class PrincipalHolder : public nsIScriptObjectPrincipal -{ -public: - NS_DECLARE_STATIC_IID_ACCESSOR(PRINCIPALHOLDER_IID) - - PrincipalHolder(nsIPrincipal *holdee) - : mHoldee(holdee) - { - } - virtual ~PrincipalHolder() { } - - NS_DECL_ISUPPORTS - - nsIPrincipal *GetPrincipal(); - -private: - nsCOMPtr mHoldee; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(PrincipalHolder, PRINCIPALHOLDER_IID) - NS_IMPL_ISUPPORTS1(PrincipalHolder, nsIScriptObjectPrincipal) nsIPrincipal * diff --git a/mozilla/js/src/xpconnect/src/xpcprivate.h b/mozilla/js/src/xpconnect/src/xpcprivate.h index 2d7d4376e9f..dbfdbdc70fa 100644 --- a/mozilla/js/src/xpconnect/src/xpcprivate.h +++ b/mozilla/js/src/xpconnect/src/xpcprivate.h @@ -3510,6 +3510,35 @@ protected: NS_DEFINE_STATIC_IID_ACCESSOR(XPCVariant, XPCVARIANT_IID) +/***************************************************************************/ +#ifndef XPCONNECT_STANDALONE + +#define PRINCIPALHOLDER_IID \ +{0xbf109f49, 0xf94a, 0x43d8, {0x93, 0xdb, 0xe4, 0x66, 0x49, 0xc5, 0xd9, 0x7d}} + +class PrincipalHolder : public nsIScriptObjectPrincipal +{ +public: + NS_DECLARE_STATIC_IID_ACCESSOR(PRINCIPALHOLDER_IID) + + PrincipalHolder(nsIPrincipal *holdee) + : mHoldee(holdee) + { + } + virtual ~PrincipalHolder() { } + + NS_DECL_ISUPPORTS + + nsIPrincipal *GetPrincipal(); + +private: + nsCOMPtr mHoldee; +}; + +NS_DEFINE_STATIC_IID_ACCESSOR(PrincipalHolder, PRINCIPALHOLDER_IID) + +#endif /* !XPCONNECT_STANDALONE */ + /***************************************************************************/ // Utilities diff --git a/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp b/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp index 7515a93cb3a..70c2cfa93cd 100644 --- a/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp +++ b/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp @@ -127,10 +127,25 @@ SafeGlobalResolve(JSContext *cx, JSObject *obj, jsval id) return JS_ResolveStandardClass(cx, obj, id, &resolved); } +JS_STATIC_DLL_CALLBACK(void) +SafeFinalize(JSContext* cx, JSObject* obj) +{ +#ifndef XPCONNECT_STANDALONE + nsIScriptObjectPrincipal* sop = + NS_STATIC_CAST(nsIScriptObjectPrincipal*, JS_GetPrivate(cx, obj)); + NS_IF_RELEASE(sop); +#endif +} + static JSClass global_class = { - "global_for_XPCJSContextStack_SafeJSContext", 0, + "global_for_XPCJSContextStack_SafeJSContext", +#ifndef XPCONNECT_STANDALONE + JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS, +#else + 0, +#endif JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, - JS_EnumerateStub, SafeGlobalResolve, JS_ConvertStub, JS_FinalizeStub, + JS_EnumerateStub, SafeGlobalResolve, JS_ConvertStub, SafeFinalize, JSCLASS_NO_OPTIONAL_MEMBERS }; @@ -140,6 +155,23 @@ XPCJSContextStack::GetSafeJSContext(JSContext * *aSafeJSContext) { if(!mSafeJSContext) { +#ifndef XPCONNECT_STANDALONE + // Start by getting the principal holder and principal for this + // context. If we can't manage that, don't bother with the rest. + nsCOMPtr principal = + do_CreateInstance("@mozilla.org/nullprincipal;1"); + nsCOMPtr sop; + if(principal) + { + sop = new PrincipalHolder(principal); + } + if(!sop) + { + *aSafeJSContext = nsnull; + return NS_ERROR_FAILURE; + } +#endif /* !XPCONNECT_STANDALONE */ + JSRuntime *rt; XPCJSRuntime* xpcrt; @@ -155,6 +187,27 @@ XPCJSContextStack::GetSafeJSContext(JSContext * *aSafeJSContext) AutoJSRequestWithNoCallContext req(mSafeJSContext); JSObject *glob; glob = JS_NewObject(mSafeJSContext, &global_class, NULL, NULL); + +#ifndef XPCONNECT_STANDALONE + if(glob) + { + // Note: make sure to set the private before calling + // InitClasses + nsIScriptObjectPrincipal* priv = nsnull; + sop.swap(priv); + if(!JS_SetPrivate(mSafeJSContext, glob, priv)) + { + // Drop the whole thing + NS_RELEASE(priv); + glob = nsnull; + } + } + + // After this point either glob is null and the + // nsIScriptObjectPrincipal ownership is either handled by the + // nsCOMPtr or dealt with, or we'll release in the finalize + // hook. +#endif if(!glob || NS_FAILED(xpc->InitClasses(mSafeJSContext, glob))) { // Explicitly end the request since we are about to kill