Create a powerless non-principal and start using it. Bug 326506, r=mrbkap,
sr=dveditz git-svn-id: svn://10.0.0.236/trunk@193399 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
4517b7601c
commit
e1ba63aa5f
86
mozilla/caps/include/nsNullPrincipal.h
Normal file
86
mozilla/caps/include/nsNullPrincipal.h
Normal file
@ -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 <bzbarsky@mit.edu> (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<nsIURI> mURI;
|
||||
};
|
||||
|
||||
#endif // nsNullPrincipal_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
|
||||
|
||||
@ -72,6 +72,7 @@ REQUIRES = xpcom \
|
||||
CPPSRCS = \
|
||||
nsPrincipal.cpp \
|
||||
nsSystemPrincipal.cpp \
|
||||
nsNullPrincipal.cpp \
|
||||
nsJSPrincipals.cpp \
|
||||
nsScriptSecurityManager.cpp \
|
||||
nsSecurityManagerFactory.cpp \
|
||||
|
||||
334
mozilla/caps/src/nsNullPrincipal.cpp
Normal file
334
mozilla/caps/src/nsNullPrincipal.cpp
Normal file
@ -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 <bzbarsky@mit.edu> (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<nsIUUIDGenerator> 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;
|
||||
}
|
||||
|
||||
@ -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<nsIURI> 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<nsIPrincipal> 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<nsIURI> 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<nsPrincipal> codebase = new nsPrincipal();
|
||||
if (!codebase)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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<nsIPrincipal> mHoldee;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(PrincipalHolder, PRINCIPALHOLDER_IID)
|
||||
|
||||
NS_IMPL_ISUPPORTS1(PrincipalHolder, nsIScriptObjectPrincipal)
|
||||
|
||||
nsIPrincipal *
|
||||
|
||||
@ -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<nsIPrincipal> mHoldee;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(PrincipalHolder, PRINCIPALHOLDER_IID)
|
||||
|
||||
#endif /* !XPCONNECT_STANDALONE */
|
||||
|
||||
/***************************************************************************/
|
||||
// Utilities
|
||||
|
||||
|
||||
@ -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<nsIPrincipal> principal =
|
||||
do_CreateInstance("@mozilla.org/nullprincipal;1");
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> 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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user