* Fix 12124 [DOGFOOD] Reading user's preferences

* Implement site-specific security policies (bug 858)
r=mstoltz
* Use Recycle rather than delete[] to clean up Purify logs
r=law
This commit is contained in:
norris%netscape.com 1999-11-16 05:07:31 +00:00
Родитель 3252234585
Коммит 411aade911
20 изменённых файлов: 279 добавлений и 200 удалений

Просмотреть файл

@ -33,6 +33,8 @@ interface nsICodebasePrincipal : nsISupports {
readonly attribute nsIURI URI; readonly attribute nsIURI URI;
readonly attribute string origin;
boolean SameOrigin(in nsIPrincipal other); boolean SameOrigin(in nsIPrincipal other);
}; };

Просмотреть файл

@ -42,7 +42,21 @@ interface nsIScriptSecurityManager : nsISupports
boolean CheckScriptAccess(in nsIScriptContext cx, in voidStar obj, boolean CheckScriptAccess(in nsIScriptContext cx, in voidStar obj,
[const] in string prop, in boolean isWrite); [const] in string prop, in boolean isWrite);
boolean CheckURI(in nsIScriptContext cx, in nsIURI uri); /**
* Check that the script with context "cx" can load "uri".
*
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
* should be denied.
*/
void CheckLoadURIFromScript(in nsIScriptContext cx, in nsIURI uri);
/**
* Check that content from "from" can load "uri".
*
* Will return error code NS_ERROR_DOM_BAD_URI if the load request
* should be denied.
*/
void CheckLoadURI(in nsIURI from, in nsIURI uri);
boolean HasSubjectPrincipal(); boolean HasSubjectPrincipal();
@ -50,7 +64,7 @@ interface nsIScriptSecurityManager : nsISupports
nsIPrincipal GetSystemPrincipal(); nsIPrincipal GetSystemPrincipal();
nsIPrincipal CreateCodebasePrincipal(in nsIURI aURI); nsIPrincipal GetCodebasePrincipal(in nsIURI aURI);
boolean CanExecuteScripts(in nsIPrincipal principal); boolean CanExecuteScripts(in nsIPrincipal principal);

Просмотреть файл

@ -56,6 +56,8 @@ public:
POLICY_TYPE_PERDOMAIN = 2 POLICY_TYPE_PERDOMAIN = 2
}; };
nsObjectHashtable *mOriginToPolicyMap;
private: private:
NS_IMETHOD NS_IMETHOD
GetSubjectPrincipal(JSContext *aCx, nsIPrincipal **result); GetSubjectPrincipal(JSContext *aCx, nsIPrincipal **result);
@ -70,11 +72,9 @@ private:
GetSecurityLevel(JSContext *cx, char *prop_name, PolicyType type, GetSecurityLevel(JSContext *cx, char *prop_name, PolicyType type,
PRBool isWrite, char **capability); PRBool isWrite, char **capability);
char * NS_IMETHOD
AddSecPolicyPrefix(JSContext *cx, char *pref_str, PolicyType type); GetPrefName(JSContext *cx, char *propName, PolicyType type,
char **result);
char *
GetSitePolicy(const char *org);
NS_IMETHOD NS_IMETHOD
CheckXPCPermissions(JSContext *cx); CheckXPCPermissions(JSContext *cx);

Просмотреть файл

@ -124,6 +124,21 @@ nsCodebasePrincipal::GetURI(nsIURI **uri)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsCodebasePrincipal::GetOrigin(char **origin)
{
nsXPIDLCString s;
if (NS_FAILED(mURI->GetScheme(getter_Copies(s))))
return NS_ERROR_FAILURE;
nsAutoString t = (const char *) s;
t += "://";
if (NS_FAILED(mURI->GetHost(getter_Copies(s))))
return NS_ERROR_FAILURE;
t += s;
*origin = t.ToNewCString();
return *origin ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP NS_IMETHODIMP
nsCodebasePrincipal::SameOrigin(nsIPrincipal *other, PRBool *result) nsCodebasePrincipal::SameOrigin(nsIPrincipal *other, PRBool *result)
{ {

Просмотреть файл

@ -367,23 +367,59 @@ nsScriptSecurityManager::CheckScriptAccess(nsIScriptContext *aContext,
} }
NS_IMETHODIMP NS_IMETHODIMP
nsScriptSecurityManager::CheckURI(nsIScriptContext *aContext, nsScriptSecurityManager::CheckLoadURIFromScript(nsIScriptContext *aContext,
nsIURI *aURI, nsIURI *aURI)
PRBool *aResult)
{ {
// Temporary: only enforce if security.checkuri pref is enabled // Get principal of currently executing script.
nsresult rv; JSContext *cx = (JSContext*) aContext->GetNativeContext();
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(rv)) if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal)))) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
PRBool enabled;
if (NS_FAILED(prefs->GetBoolPref("security.checkuri", &enabled)) ||
!enabled)
{
*aResult = PR_TRUE;
return NS_OK;
} }
// The system principal can load all URIs.
PRBool equals;
if (NS_FAILED(principal->Equals(mSystemPrincipal, &equals)))
return NS_ERROR_FAILURE;
if (equals)
return NS_OK;
// Otherwise, principal should have a codebase that we can use to
// do the remaining tests.
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal);
if (!principal)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> uri;
if (NS_FAILED(codebase->GetURI(getter_AddRefs(uri))))
return NS_ERROR_FAILURE;
if (NS_SUCCEEDED(CheckLoadURI(uri, aURI)))
return NS_OK;
// See if we're attempting to load a file: URI. If so, let a
// UniversalFileRead capability trump the above check.
nsXPIDLCString scheme;
if (NS_FAILED(aURI->GetScheme(getter_Copies(scheme))))
return NS_ERROR_FAILURE;
if (nsCRT::strcmp(scheme, "file") == 0) {
PRBool enabled;
if (NS_FAILED(IsCapabilityEnabled("UniversalFileRead", &enabled)))
return NS_ERROR_FAILURE;
if (enabled)
return NS_OK;
}
// Report error.
nsXPIDLCString spec;
if (NS_FAILED(aURI->GetSpec(getter_Copies(spec))))
return NS_ERROR_FAILURE;
JS_ReportError(cx, "illegal URL method '%s'", (const char *)spec);
return NS_ERROR_DOM_BAD_URI;
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckLoadURI(nsIURI *aFromURI,
nsIURI *aURI)
{
nsXPIDLCString scheme; nsXPIDLCString scheme;
if (NS_FAILED(aURI->GetScheme(getter_Copies(scheme)))) if (NS_FAILED(aURI->GetScheme(getter_Copies(scheme))))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -394,7 +430,6 @@ nsScriptSecurityManager::CheckURI(nsIScriptContext *aContext,
nsCRT::strcmp(scheme, "mailto") == 0 || nsCRT::strcmp(scheme, "mailto") == 0 ||
nsCRT::strcmp(scheme, "news") == 0) nsCRT::strcmp(scheme, "news") == 0)
{ {
*aResult = PR_TRUE;
return NS_OK; return NS_OK;
} }
if (nsCRT::strcmp(scheme, "about") == 0) { if (nsCRT::strcmp(scheme, "about") == 0) {
@ -402,53 +437,31 @@ nsScriptSecurityManager::CheckURI(nsIScriptContext *aContext,
if (NS_FAILED(aURI->GetSpec(getter_Copies(spec)))) if (NS_FAILED(aURI->GetSpec(getter_Copies(spec))))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
if (nsCRT::strcmp(spec, "about:blank") == 0) { if (nsCRT::strcmp(spec, "about:blank") == 0) {
*aResult = PR_TRUE;
return NS_OK; return NS_OK;
} }
} }
JSContext *cx = (JSContext*) aContext->GetNativeContext();
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal)))) {
return NS_ERROR_FAILURE;
}
if (nsCRT::strcmp(scheme, "file") == 0) { if (nsCRT::strcmp(scheme, "file") == 0) {
nsCOMPtr<nsICodebasePrincipal> codebase; nsXPIDLCString scheme2;
if (NS_SUCCEEDED(principal->QueryInterface( if (NS_SUCCEEDED(aFromURI->GetScheme(getter_Copies(scheme2))) &&
NS_GET_IID(nsICodebasePrincipal), nsCRT::strcmp(scheme2, "file") == 0)
(void **) getter_AddRefs(codebase))))
{ {
nsCOMPtr<nsIURI> uri;
if (NS_SUCCEEDED(codebase->GetURI(getter_AddRefs(uri)))) {
nsXPIDLCString scheme2;
if (NS_SUCCEEDED(uri->GetScheme(getter_Copies(scheme2))) &&
nsCRT::strcmp(scheme2, "file") == 0)
{
*aResult = PR_TRUE;
return NS_OK;
}
}
}
if (NS_FAILED(IsCapabilityEnabled("UniversalFileRead", aResult)))
return NS_ERROR_FAILURE;
if (*aResult)
return NS_OK; return NS_OK;
}
} }
// Only allowed for the system principal to create other URIs. // Temporary: allow a preference to disable this check
if (NS_FAILED(principal->Equals(mSystemPrincipal, aResult))) nsresult rv;
return NS_ERROR_FAILURE; NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (NS_FAILED(rv))
if (!*aResult) { return NS_ERROR_FAILURE;
// Report error. PRBool enabled;
nsXPIDLCString spec; if (NS_SUCCEEDED(prefs->GetBoolPref("security.checkuri", &enabled)) &&
if (NS_FAILED(aURI->GetSpec(getter_Copies(spec)))) !enabled)
return NS_ERROR_FAILURE; {
JS_ReportError(cx, "illegal URL method '%s'", (const char *)spec); return NS_OK;
return NS_ERROR_DOM_BAD_URI;
} }
return NS_OK;
return NS_ERROR_DOM_BAD_URI;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -482,12 +495,12 @@ nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI *aURI, nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI,
nsIPrincipal **result) nsIPrincipal **result)
{ {
nsresult rv; nsresult rv;
nsCodebasePrincipal *codebase = new nsCodebasePrincipal(); nsCodebasePrincipal *codebase = new nsCodebasePrincipal();
NS_ADDREF(codebase); // XXX should constructor addref? NS_ADDREF(codebase);
if (!codebase) if (!codebase)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
if (NS_FAILED(codebase->Init(aURI))) { if (NS_FAILED(codebase->Init(aURI))) {
@ -593,7 +606,9 @@ nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
&canEnable); &canEnable);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
if (canEnable == nsIPrincipal::ENABLE_DENIED) { if (canEnable != nsIPrincipal::ENABLE_GRANTED &&
canEnable != nsIPrincipal::ENABLE_WITH_USER_PERMISSION)
{
*result = PR_FALSE; *result = PR_FALSE;
return NS_OK; return NS_OK;
} }
@ -792,7 +807,8 @@ nsScriptSecurityManager::CanSetProperty(JSContext *aJSContext,
/////////////////// ///////////////////
nsScriptSecurityManager::nsScriptSecurityManager(void) nsScriptSecurityManager::nsScriptSecurityManager(void)
: mSystemPrincipal(nsnull), mPrincipals(nsnull) : mOriginToPolicyMap(nsnull), mSystemPrincipal(nsnull),
mPrincipals(nsnull)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
memset(domPropertyPolicyTypes, 0, sizeof(domPropertyPolicyTypes)); memset(domPropertyPolicyTypes, 0, sizeof(domPropertyPolicyTypes));
@ -801,6 +817,7 @@ nsScriptSecurityManager::nsScriptSecurityManager(void)
nsScriptSecurityManager::~nsScriptSecurityManager(void) nsScriptSecurityManager::~nsScriptSecurityManager(void)
{ {
delete mOriginToPolicyMap;
NS_IF_RELEASE(mSystemPrincipal); NS_IF_RELEASE(mSystemPrincipal);
delete mPrincipals; delete mPrincipals;
} }
@ -931,14 +948,14 @@ nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj,
PRInt32 PRInt32
nsScriptSecurityManager::GetSecurityLevel(JSContext *cx, char *prop_name, nsScriptSecurityManager::GetSecurityLevel(JSContext *cx, char *propName,
PolicyType type, PRBool isWrite, PolicyType type, PRBool isWrite,
char **capability) char **capability)
{ {
if (prop_name == nsnull) if (propName == nsnull)
return SCRIPT_SECURITY_NO_ACCESS; return SCRIPT_SECURITY_NO_ACCESS;
char *tmp_prop_name = AddSecPolicyPrefix(cx, prop_name, type); nsXPIDLCString prefName;
if (tmp_prop_name == nsnull) if (NS_FAILED(GetPrefName(cx, propName, type, getter_Copies(prefName))))
return SCRIPT_SECURITY_NO_ACCESS; return SCRIPT_SECURITY_NO_ACCESS;
PRInt32 secLevel; PRInt32 secLevel;
char *secLevelString; char *secLevelString;
@ -946,18 +963,17 @@ nsScriptSecurityManager::GetSecurityLevel(JSContext *cx, char *prop_name,
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
rv = prefs->CopyCharPref(tmp_prop_name, &secLevelString); rv = prefs->CopyCharPref(prefName, &secLevelString);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
nsAutoString s = tmp_prop_name; nsAutoString s = (const char *) prefName;
s += (isWrite ? ".write" : ".read"); s += (isWrite ? ".write" : ".read");
char *cp = s.ToNewCString(); char *cp = s.ToNewCString();
if (!cp) if (!cp)
return SCRIPT_SECURITY_NO_ACCESS; return SCRIPT_SECURITY_NO_ACCESS;
rv = prefs->CopyCharPref(cp, &secLevelString); rv = prefs->CopyCharPref(cp, &secLevelString);
Recycle(cp); Recycle(cp);
} }
if (NS_SUCCEEDED(rv) && secLevelString) { if (NS_SUCCEEDED(rv) && secLevelString) {
PR_FREEIF(tmp_prop_name);
if (PL_strcmp(secLevelString, "sameOrigin") == 0) if (PL_strcmp(secLevelString, "sameOrigin") == 0)
secLevel = SCRIPT_SECURITY_SAME_DOMAIN_ACCESS; secLevel = SCRIPT_SECURITY_SAME_DOMAIN_ACCESS;
else if (PL_strcmp(secLevelString, "allAccess") == 0) else if (PL_strcmp(secLevelString, "allAccess") == 0)
@ -979,40 +995,51 @@ nsScriptSecurityManager::GetSecurityLevel(JSContext *cx, char *prop_name,
// This violates the rule of a safe default, but means we don't have // This violates the rule of a safe default, but means we don't have
// to specify the large majority of unchecked properties, only the // to specify the large majority of unchecked properties, only the
// minority of checked ones. // minority of checked ones.
PR_FREEIF(tmp_prop_name);
return SCRIPT_SECURITY_ALL_ACCESS; return SCRIPT_SECURITY_ALL_ACCESS;
} }
char * NS_IMETHODIMP
nsScriptSecurityManager::AddSecPolicyPrefix(JSContext *cx, char *pref_str, nsScriptSecurityManager::GetPrefName(JSContext *cx, char *propName,
PolicyType type) PolicyType type, char **result)
{ {
const char *subjectOrigin = "";//GetSubjectOriginURL(cx); nsresult rv;
char *policy_str, *retval = 0; static const char *defaultStr = "default";
if ((policy_str = GetSitePolicy(subjectOrigin)) == 0) { nsAutoString s = "security.policy.";
/* No site-specific policy. Get global policy name. */ if (type == POLICY_TYPE_DEFAULT) {
nsresult rv; s += defaultStr;
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); } else if (type == POLICY_TYPE_PERDOMAIN) {
if (NS_FAILED(rv) || nsCOMPtr<nsIPrincipal> principal;
NS_FAILED(prefs->CopyCharPref("javascript.security_policy", &policy_str))) if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal)))) {
{ return NS_ERROR_FAILURE;
policy_str = PL_strdup("default"); }
} PRBool equals;
if (NS_FAILED(principal->Equals(mSystemPrincipal, &equals)))
return NS_ERROR_FAILURE;
if (equals) {
s += defaultStr;
} else {
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal, &rv);
if (NS_FAILED(rv))
return rv;
nsXPIDLCString origin;
if (NS_FAILED(rv = codebase->GetOrigin(getter_Copies(origin))))
return rv;
nsCString *policy = nsnull;
if (mOriginToPolicyMap) {
nsStringKey key(origin);
policy = (nsCString *) mOriginToPolicyMap->Get(&key);
}
if (policy)
s += *policy;
else
s += defaultStr;
}
} }
if (policy_str) { //why can't this be default? && PL_strcasecmp(policy_str, "default") != 0) { s += '.';
retval = PR_sprintf_append(NULL, "security.policy.%s.%s", policy_str, pref_str); s += propName;
PR_Free(policy_str); *result = s.ToNewCString();
} return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
return retval;
}
char *
nsScriptSecurityManager::GetSitePolicy(const char *org)
{
return nsnull;
} }
@ -1959,12 +1986,25 @@ findDomProp(const char *propName, int n)
return -1; return -1;
} }
// security.policy.<policyname>.<object>.<property>[.read|.write] PR_STATIC_CALLBACK(PRBool)
DeleteEntry(nsHashKey *aKey, void *aData, void* closure)
{
nsCString* entry = (nsCString*) aData;
delete entry;
return PR_TRUE;
}
struct PolicyEnumeratorInfo {
nsScriptSecurityManager::PolicyType *policies;
nsIPref *prefs;
nsScriptSecurityManager *secMan;
};
PR_STATIC_CALLBACK(void) PR_STATIC_CALLBACK(void)
enumeratePolicy(const char *prefName, void *policies) { enumeratePolicy(const char *prefName, void *data) {
if (!prefName || !*prefName) if (!prefName || !*prefName)
return; return;
PolicyEnumeratorInfo *info = (PolicyEnumeratorInfo *) data;
unsigned count = 0; unsigned count = 0;
const char *dots[5]; const char *dots[5];
const char *p; const char *p;
@ -1977,23 +2017,59 @@ enumeratePolicy(const char *prefName, void *policies) {
} }
if (count < sizeof(dots)/sizeof(dots[0])) if (count < sizeof(dots)/sizeof(dots[0]))
dots[count] = p; dots[count] = p;
if (count >= 4) { if (count < 3)
const char *policyName = dots[1] + 1; return;
int policyLength = dots[2] - policyName; const char *policyName = dots[1] + 1;
PRBool isDefault = PL_strncmp("default", policyName, policyLength) == 0; int policyLength = dots[2] - policyName;
PRBool isDefault = PL_strncmp("default", policyName, policyLength) == 0;
if (!isDefault && count == 3) {
// security.policy.<policyname>.sites
const char *sitesName = dots[2] + 1;
int sitesLength = dots[3] - sitesName;
if (PL_strncmp("sites", sitesName, sitesLength) == 0) {
if (!info->secMan->mOriginToPolicyMap) {
info->secMan->mOriginToPolicyMap =
new nsObjectHashtable(nsnull, nsnull, DeleteEntry, nsnull);
if (!info->secMan->mOriginToPolicyMap)
return;
}
char *s;
if (NS_FAILED(info->prefs->CopyCharPref(prefName, &s)))
return;
char *q=s;
char *r=s;
PRBool working = PR_TRUE;
while (working) {
if (*r == ' ' || *r == '\0') {
working = (*r != '\0');
*r = '\0';
nsStringKey key(q);
nsCString *value = new nsCString(policyName, policyLength);
if (!value)
break;
info->secMan->mOriginToPolicyMap->Put(&key, value);
q = r + 1;
}
r++;
}
PR_Free(s);
return;
}
} else if (count >= 4) {
// security.policy.<policyname>.<object>.<property>[.read|.write]
const char *domPropName = dots[2] + 1; const char *domPropName = dots[2] + 1;
int domPropLength = dots[4] - domPropName; int domPropLength = dots[4] - domPropName;
PRInt16 domProp = findDomProp(domPropName, domPropLength); PRInt16 domProp = findDomProp(domPropName, domPropLength);
if (domProp >= 0) { if (domProp >= 0) {
nsScriptSecurityManager::PolicyType *policyType = nsScriptSecurityManager::PolicyType *policyType =
((nsScriptSecurityManager::PolicyType *) policies) + domProp; info->policies + domProp;
if (!isDefault) if (!isDefault)
*policyType = nsScriptSecurityManager::POLICY_TYPE_PERDOMAIN; *policyType = nsScriptSecurityManager::POLICY_TYPE_PERDOMAIN;
else if (*policyType == nsScriptSecurityManager::POLICY_TYPE_NONE) else if (*policyType == nsScriptSecurityManager::POLICY_TYPE_NONE)
*policyType = nsScriptSecurityManager::POLICY_TYPE_DEFAULT; *policyType = nsScriptSecurityManager::POLICY_TYPE_DEFAULT;
return; return;
} }
} }
NS_ASSERTION(PR_FALSE, "DOM property name invalid or not found"); NS_ASSERTION(PR_FALSE, "DOM property name invalid or not found");
} }
@ -2004,7 +2080,11 @@ nsScriptSecurityManager::InitFromPrefs()
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
PolicyEnumeratorInfo info;
info.policies = domPropertyPolicyTypes;
info.prefs = prefs;
info.secMan = this;
prefs->EnumerateChildren("security.policy", enumeratePolicy, prefs->EnumerateChildren("security.policy", enumeratePolicy,
(void *) domPropertyPolicyTypes); (void *) &info);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -870,8 +870,8 @@ nsIPrincipal* nsDocument::GetDocumentPrincipal()
NS_SCRIPTSECURITYMANAGER_PROGID, &rv); NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return nsnull; return nsnull;
if (NS_FAILED(securityManager->CreateCodebasePrincipal(mDocumentURL, if (NS_FAILED(securityManager->GetCodebasePrincipal(mDocumentURL,
&mPrincipal))) &mPrincipal)))
return nsnull; return nsnull;
} }
NS_ADDREF(mPrincipal); NS_ADDREF(mPrincipal);

Просмотреть файл

@ -68,6 +68,7 @@
#include "nsIRefreshURI.h" #include "nsIRefreshURI.h"
#include "nsVoidArray.h" #include "nsVoidArray.h"
#include "nsIScriptContextOwner.h" #include "nsIScriptContextOwner.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
#include "nsHTMLIIDs.h" #include "nsHTMLIIDs.h"
#include "nsTextFragment.h" #include "nsTextFragment.h"
@ -3629,35 +3630,6 @@ HTMLContentSink::OnUnicharStreamComplete(nsIUnicharStreamLoader* aLoader,
return rv; return rv;
} }
/*
** The enum "SchemeOrder" defines an ordering of URI schemes used to
** determine whether a page can load a script. Schemes are listed in
** order of declining power: chrome can access everything, resource
** can access everything but chrome, and so forth.
*/
enum SchemeOrder { CHROME_SCHEME, RESOURCE_SCHEME, FILE_SCHEME, OTHER_SCHEME };
static SchemeOrder
GetSchemeOrder(nsIURI *uri)
{
SchemeOrder result = OTHER_SCHEME;
if (uri) {
char *scheme;
uri->GetScheme(&scheme);
if (scheme) {
if (PL_strcmp(scheme, "chrome") == 0)
result = CHROME_SCHEME;
else if (PL_strcmp(scheme, "resource") == 0)
result = RESOURCE_SCHEME;
else if (PL_strcmp(scheme, "file") == 0)
result = FILE_SCHEME;
nsCRT::free(scheme);
}
}
return result;
}
nsresult nsresult
HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode) HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
{ {
@ -3786,13 +3758,14 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
return rv; return rv;
} }
// Check access to file:, chrome:, and resource:. // Check that this page is allowed to load this URI.
SchemeOrder order = GetSchemeOrder(url); NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
SchemeOrder baseOrder = GetSchemeOrder(mDocumentBaseURL); NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (baseOrder > order) { if (NS_FAILED(rv))
NS_RELEASE(url); return rv;
return NS_ERROR_DOM_BAD_URI; rv = securityManager->CheckLoadURI(mDocumentBaseURL, url);
} if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsILoadGroup> loadGroup; nsCOMPtr<nsILoadGroup> loadGroup;
nsIUnicharStreamLoader* loader; nsIUnicharStreamLoader* loader;

Просмотреть файл

@ -1387,13 +1387,13 @@ nsHTMLDocument::SetDomain(const nsString& aDomain)
if (NS_FAILED(NS_NewURI(&newURI, newURIString))) if (NS_FAILED(NS_NewURI(&newURI, newURIString)))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
// Create new codebase principal // Get codebase principal
nsresult rv; nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv); NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
return securityManager->CreateCodebasePrincipal(newURI, &mPrincipal); return securityManager->GetCodebasePrincipal(newURI, &mPrincipal);
} }
NS_IMETHODIMP NS_IMETHODIMP

Просмотреть файл

@ -53,6 +53,8 @@
#include "nsIScriptContextOwner.h" #include "nsIScriptContextOwner.h"
#include "nsINameSpace.h" #include "nsINameSpace.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIServiceManager.h"
#include "nsIScriptSecurityManager.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "jsapi.h" // for JSVERSION_* and JS_VersionToString #include "jsapi.h" // for JSVERSION_* and JS_VersionToString
#include "prtime.h" #include "prtime.h"
@ -1798,6 +1800,15 @@ nsXMLContentSink::ProcessStartSCRIPTTag(const nsIParserNode& aNode)
return rv; return rv;
} }
// Check that this page is allowed to load this URI.
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv))
return rv;
rv = securityManager->CheckLoadURI(mDocumentBaseURL, url);
if (NS_FAILED(rv))
return rv;
nsIUnicharStreamLoader* loader; nsIUnicharStreamLoader* loader;
nsCOMPtr<nsILoadGroup> loadGroup; nsCOMPtr<nsILoadGroup> loadGroup;

Просмотреть файл

@ -566,7 +566,7 @@ nsXULDocument::GetDocumentPrincipal()
NS_SCRIPTSECURITYMANAGER_PROGID, &rv); NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return nsnull; return nsnull;
if (NS_FAILED(securityManager->CreateCodebasePrincipal(mDocumentURL, if (NS_FAILED(securityManager->GetCodebasePrincipal(mDocumentURL,
getter_AddRefs(mDocumentPrincipal)))) getter_AddRefs(mDocumentPrincipal))))
{ {
return nsnull; return nsnull;

Просмотреть файл

@ -2206,7 +2206,7 @@ GlobalWindowImpl::OpenInternal(JSContext *cx,
PRBool ok = PR_FALSE; PRBool ok = PR_FALSE;
if (NS_FAILED(scriptCX->GetSecurityManager(getter_AddRefs(secMan))) || if (NS_FAILED(scriptCX->GetSecurityManager(getter_AddRefs(secMan))) ||
NS_FAILED(NS_NewURI(getter_AddRefs(newUrl), mAbsURL)) || NS_FAILED(NS_NewURI(getter_AddRefs(newUrl), mAbsURL)) ||
NS_FAILED(secMan->CheckURI(scriptCX, newUrl, &ok)) || !ok) NS_FAILED(secMan->CheckLoadURIFromScript(scriptCX, newUrl)))
{ {
NS_RELEASE(newOuterShell); NS_RELEASE(newOuterShell);
NS_RELEASE(webShellContainer); NS_RELEASE(webShellContainer);

Просмотреть файл

@ -142,13 +142,13 @@ LocationImpl::CheckURL(nsIURI* aURL)
// Get security manager. // Get security manager.
nsIScriptContext *scriptCX = (nsIScriptContext *)JS_GetContextPrivate(cx); nsIScriptContext *scriptCX = (nsIScriptContext *)JS_GetContextPrivate(cx);
nsCOMPtr<nsIScriptSecurityManager> secMan; nsCOMPtr<nsIScriptSecurityManager> secMan;
if (NS_FAILED(scriptCX->GetSecurityManager(getter_AddRefs(secMan)))) if (!scriptCX || NS_FAILED(scriptCX->GetSecurityManager(getter_AddRefs(secMan))))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
// Check to see if URI is allowed. // Check to see if URI is allowed.
PRBool ok = PR_FALSE; PRBool ok = PR_FALSE;
if (NS_FAILED(secMan->CheckURI(scriptCX, aURL, &ok)) || !ok) if (NS_FAILED(result = secMan->CheckLoadURIFromScript(scriptCX, aURL)))
return NS_ERROR_FAILURE; return result;
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -248,7 +248,7 @@ nsJSProtocolHandler::NewChannel(const char* verb, nsIURI* uri,
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
if (NS_FAILED(NewURI(urlStr.GetBuffer(), nsnull, getter_AddRefs(uri)))) if (NS_FAILED(NewURI(urlStr.GetBuffer(), nsnull, getter_AddRefs(uri))))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
if (NS_FAILED(securityManager->CreateCodebasePrincipal(uri, getter_AddRefs(principal)))) if (NS_FAILED(securityManager->GetCodebasePrincipal(uri, getter_AddRefs(principal))))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }

Просмотреть файл

@ -870,8 +870,8 @@ nsIPrincipal* nsDocument::GetDocumentPrincipal()
NS_SCRIPTSECURITYMANAGER_PROGID, &rv); NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return nsnull; return nsnull;
if (NS_FAILED(securityManager->CreateCodebasePrincipal(mDocumentURL, if (NS_FAILED(securityManager->GetCodebasePrincipal(mDocumentURL,
&mPrincipal))) &mPrincipal)))
return nsnull; return nsnull;
} }
NS_ADDREF(mPrincipal); NS_ADDREF(mPrincipal);

Просмотреть файл

@ -68,6 +68,7 @@
#include "nsIRefreshURI.h" #include "nsIRefreshURI.h"
#include "nsVoidArray.h" #include "nsVoidArray.h"
#include "nsIScriptContextOwner.h" #include "nsIScriptContextOwner.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
#include "nsHTMLIIDs.h" #include "nsHTMLIIDs.h"
#include "nsTextFragment.h" #include "nsTextFragment.h"
@ -3629,35 +3630,6 @@ HTMLContentSink::OnUnicharStreamComplete(nsIUnicharStreamLoader* aLoader,
return rv; return rv;
} }
/*
** The enum "SchemeOrder" defines an ordering of URI schemes used to
** determine whether a page can load a script. Schemes are listed in
** order of declining power: chrome can access everything, resource
** can access everything but chrome, and so forth.
*/
enum SchemeOrder { CHROME_SCHEME, RESOURCE_SCHEME, FILE_SCHEME, OTHER_SCHEME };
static SchemeOrder
GetSchemeOrder(nsIURI *uri)
{
SchemeOrder result = OTHER_SCHEME;
if (uri) {
char *scheme;
uri->GetScheme(&scheme);
if (scheme) {
if (PL_strcmp(scheme, "chrome") == 0)
result = CHROME_SCHEME;
else if (PL_strcmp(scheme, "resource") == 0)
result = RESOURCE_SCHEME;
else if (PL_strcmp(scheme, "file") == 0)
result = FILE_SCHEME;
nsCRT::free(scheme);
}
}
return result;
}
nsresult nsresult
HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode) HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
{ {
@ -3786,13 +3758,14 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
return rv; return rv;
} }
// Check access to file:, chrome:, and resource:. // Check that this page is allowed to load this URI.
SchemeOrder order = GetSchemeOrder(url); NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
SchemeOrder baseOrder = GetSchemeOrder(mDocumentBaseURL); NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (baseOrder > order) { if (NS_FAILED(rv))
NS_RELEASE(url); return rv;
return NS_ERROR_DOM_BAD_URI; rv = securityManager->CheckLoadURI(mDocumentBaseURL, url);
} if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsILoadGroup> loadGroup; nsCOMPtr<nsILoadGroup> loadGroup;
nsIUnicharStreamLoader* loader; nsIUnicharStreamLoader* loader;

Просмотреть файл

@ -1387,13 +1387,13 @@ nsHTMLDocument::SetDomain(const nsString& aDomain)
if (NS_FAILED(NS_NewURI(&newURI, newURIString))) if (NS_FAILED(NS_NewURI(&newURI, newURIString)))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
// Create new codebase principal // Get codebase principal
nsresult rv; nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv); NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
return securityManager->CreateCodebasePrincipal(newURI, &mPrincipal); return securityManager->GetCodebasePrincipal(newURI, &mPrincipal);
} }
NS_IMETHODIMP NS_IMETHODIMP

Просмотреть файл

@ -53,6 +53,8 @@
#include "nsIScriptContextOwner.h" #include "nsIScriptContextOwner.h"
#include "nsINameSpace.h" #include "nsINameSpace.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIServiceManager.h"
#include "nsIScriptSecurityManager.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "jsapi.h" // for JSVERSION_* and JS_VersionToString #include "jsapi.h" // for JSVERSION_* and JS_VersionToString
#include "prtime.h" #include "prtime.h"
@ -1798,6 +1800,15 @@ nsXMLContentSink::ProcessStartSCRIPTTag(const nsIParserNode& aNode)
return rv; return rv;
} }
// Check that this page is allowed to load this URI.
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv))
return rv;
rv = securityManager->CheckLoadURI(mDocumentBaseURL, url);
if (NS_FAILED(rv))
return rv;
nsIUnicharStreamLoader* loader; nsIUnicharStreamLoader* loader;
nsCOMPtr<nsILoadGroup> loadGroup; nsCOMPtr<nsILoadGroup> loadGroup;

Просмотреть файл

@ -566,7 +566,7 @@ nsXULDocument::GetDocumentPrincipal()
NS_SCRIPTSECURITYMANAGER_PROGID, &rv); NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return nsnull; return nsnull;
if (NS_FAILED(securityManager->CreateCodebasePrincipal(mDocumentURL, if (NS_FAILED(securityManager->GetCodebasePrincipal(mDocumentURL,
getter_AddRefs(mDocumentPrincipal)))) getter_AddRefs(mDocumentPrincipal))))
{ {
return nsnull; return nsnull;

Просмотреть файл

@ -266,7 +266,7 @@ class ConstStringImpl
~ConstStringImpl() ~ConstStringImpl()
{ {
delete [] (char*)mConstString; Recycle((char*)mConstString);
} }
protected: protected:

Просмотреть файл

@ -433,7 +433,7 @@ nsAppShellService::InitializeComponent( const nsCID &aComponentCID ) {
char *name = aComponentCID.ToString(); char *name = aComponentCID.ToString();
printf( "Initialized app shell component %s, rv=0x%08X\n", printf( "Initialized app shell component %s, rv=0x%08X\n",
name, (int)rv ); name, (int)rv );
delete [] name; Recycle(name);
#endif #endif
// Release it (will live on if it registered itself as service). // Release it (will live on if it registered itself as service).
component->Release(); component->Release();
@ -443,7 +443,7 @@ nsAppShellService::InitializeComponent( const nsCID &aComponentCID ) {
char *name = aComponentCID.ToString(); char *name = aComponentCID.ToString();
printf( "Error creating app shell component %s, rv=0x%08X\n", printf( "Error creating app shell component %s, rv=0x%08X\n",
name, (int)rv ); name, (int)rv );
delete [] name; Recycle(name);
#endif #endif
} }