128697 - Added a pref listener for changes to capability.policy prefs,
removed profile-change listener
131025 - Removed insecure "trusted codebase principals" feature
131340 - Make nsCodebasePrincipal::Equals handle jar URLs correctly
131342 - Clean up privilege-grant dialog code
128861 - class policy hashtables allocated only when needed; avoids
PLDHash memory-use warning
Fixed comparison of -1 and 80 ports (Can't find the bug # right now)

All r=harishd, sr=jst, a=asa.
This commit is contained in:
mstoltz%netscape.com 2002-03-20 05:53:46 +00:00
Родитель 5bf172e81d
Коммит 03fe97372a
5 изменённых файлов: 193 добавлений и 231 удалений

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

@ -204,11 +204,6 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
*/
boolean subjectPrincipalIsSystem();
/**
* Forget all currently stored security policies and reread from prefs.
* This must be called after any capability.policy prefs have changed.
*/
void reloadSecurityPolicies();
};
%{C++

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

@ -80,14 +80,12 @@ public:
nsresult
InitFromPersistent(const char* aPrefName, const char* aID,
const char* aGrantedList, const char* aDeniedList,
PRBool aTrusted);
const char* aGrantedList, const char* aDeniedList);
virtual ~nsCodebasePrincipal(void);
protected:
nsCOMPtr<nsIURI> mURI;
PRBool mTrusted;
};
#endif // _NS_CODEBASE_PRINCIPAL_H_

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

@ -157,9 +157,9 @@ ClearPropertyPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
struct ClassPolicy : public PLDHashEntryHdr
{
char* key;
PLDHashTable mPolicy;
ClassPolicy* mDefault;
ClassPolicy* mWildcard;
PLDHashTable* mPolicy;
ClassPolicy* mDefault;
ClassPolicy* mWildcard;
};
PR_STATIC_CALLBACK(PRBool)
@ -180,7 +180,7 @@ ClearClassPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
PL_strfree(cp->key);
cp->key = nsnull;
}
PL_DHashTableFinish(&cp->mPolicy);
PL_DHashTableDestroy(cp->mPolicy);
}
PR_STATIC_CALLBACK(void)
@ -203,8 +203,9 @@ InitClassPolicyEntry(PLDHashTable *table,
ClassPolicy* cp = (ClassPolicy*)entry;
cp->key = PL_strdup((const char*)key);
PL_DHashTableInit(&cp->mPolicy, &classPolicyOps, nsnull,
sizeof(PropertyPolicy), 16);
cp->mPolicy = PL_NewDHashTable(&classPolicyOps, nsnull,
sizeof(PropertyPolicy), 16);
NS_ASSERTION(cp->mPolicy, "Failed to create hashtable - out of memory?");
}
// Domain Policy
@ -333,7 +334,7 @@ private:
CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal** result);
nsresult
GetSubjectPrincipal(JSContext* aCx, nsIPrincipal** result);
GetSubjectPrincipal(JSContext* cx, nsIPrincipal** result);
nsresult
GetFramePrincipal(JSContext* cx, JSStackFrame* fp, nsIPrincipal** result);
@ -350,6 +351,9 @@ private:
nsIPrincipal** result,
JSStackFrame** frameResult);
static PRBool
CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrincipal, PRBool *checkValue);
nsresult
SavePrincipal(nsIPrincipal* aToSave);
@ -367,7 +371,7 @@ private:
InitPolicies();
nsresult
InitDomainPolicy(JSContext* cx,const char* aPolicyName,
InitDomainPolicy(JSContext* cx, const char* aPolicyName,
DomainPolicy* aDomainPolicy);
nsresult
@ -403,6 +407,7 @@ private:
PRBool mIsWritingPrefs;
nsCOMPtr<nsIThreadJSContextStack> mJSContextStack;
PRBool mNameSetRegistered;
PRBool mPolicyPrefsChanged;
};
#endif /*_NS_SCRIPT_SECURITY_MANAGER_H_*/

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

@ -43,6 +43,7 @@
#include "nsIServiceManager.h"
#include "nsNetUtil.h"
#include "nsIURL.h"
#include "nsIJARURI.h"
#include "nsCOMPtr.h"
#include "nsIPref.h"
#include "nsXPIDLString.h"
@ -105,29 +106,24 @@ NS_IMETHODIMP
nsCodebasePrincipal::CanEnableCapability(const char *capability,
PRInt16 *result)
{
// Either this principal must be preconfigured as a trusted source
// (mTrusted), or else the codebase principal pref must be enabled
if (!mTrusted)
{
static char pref[] = "signed.applets.codebase_principal_support";
nsresult rv;
nsCOMPtr<nsIPref> prefs(do_GetService("@mozilla.org/preferences;1", &rv));
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
PRBool enabled;
if (NS_FAILED(prefs->GetBoolPref(pref, &enabled)) || !enabled)
{
// Deny unless subject is executing from file: or resource:
PRBool isFile = PR_FALSE;
PRBool isRes = PR_FALSE;
static char pref[] = "signed.applets.codebase_principal_support";
nsresult rv;
nsCOMPtr<nsIPref> prefs(do_GetService("@mozilla.org/preferences;1", &rv));
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
PRBool enabled;
if (NS_FAILED(prefs->GetBoolPref(pref, &enabled)) || !enabled)
{
// Deny unless subject is executing from file: or resource:
PRBool isFile = PR_FALSE;
PRBool isRes = PR_FALSE;
if (NS_FAILED(mURI->SchemeIs("file", &isFile)) ||
NS_FAILED(mURI->SchemeIs("resource", &isRes)) ||
(!isFile && !isRes))
{
*result = nsIPrincipal::ENABLE_DENIED;
return NS_OK;
}
if (NS_FAILED(mURI->SchemeIs("file", &isFile)) ||
NS_FAILED(mURI->SchemeIs("resource", &isRes)) ||
(!isFile && !isRes))
{
*result = nsIPrincipal::ENABLE_DENIED;
return NS_OK;
}
}
nsBasePrincipal::CanEnableCapability(capability, result);
@ -181,8 +177,7 @@ nsCodebasePrincipal::GetSpec(char **spec)
NS_IMETHODIMP
nsCodebasePrincipal::Equals(nsIPrincipal *other, PRBool *result)
{
//-- Equals is defined as object equality or same origin
// Equals is defined as object equality or same origin
*result = PR_FALSE;
if (this == other)
{
@ -192,6 +187,8 @@ nsCodebasePrincipal::Equals(nsIPrincipal *other, PRBool *result)
if (other == nsnull)
// return false
return NS_OK;
// Get the other principal's URI
nsCOMPtr<nsICodebasePrincipal> otherCodebase;
if (NS_FAILED(other->QueryInterface(
NS_GET_IID(nsICodebasePrincipal),
@ -200,21 +197,38 @@ nsCodebasePrincipal::Equals(nsIPrincipal *other, PRBool *result)
nsCOMPtr<nsIURI> otherURI;
if (NS_FAILED(otherCodebase->GetURI(getter_AddRefs(otherURI))))
return NS_ERROR_FAILURE;
// If either uri is a jar URI, get the base URI
nsCOMPtr<nsIJARURI> jarURI;
nsCOMPtr<nsIURI> myBaseURI(mURI);
while((jarURI = do_QueryInterface(myBaseURI)))
{
jarURI->GetJARFile(getter_AddRefs(myBaseURI));
}
while((jarURI = do_QueryInterface(otherURI)))
{
jarURI->GetJARFile(getter_AddRefs(otherURI));
}
if (!myBaseURI || !otherURI)
return NS_ERROR_FAILURE;
// Compare schemes
nsCAutoString otherScheme;
nsresult rv = otherURI->GetScheme(otherScheme);
nsCAutoString myScheme;
if (NS_SUCCEEDED(rv))
rv = mURI->GetScheme(myScheme);
if (NS_SUCCEEDED(rv) && strcmp(otherScheme.get(), myScheme.get()) == 0)
rv = myBaseURI->GetScheme(myScheme);
if (NS_SUCCEEDED(rv) && otherScheme.Equals(myScheme))
{
if (strcmp(otherScheme.get(), "file") == 0)
if (otherScheme.Equals("file"))
{
// All file: urls are considered to have the same origin.
*result = PR_TRUE;
}
else if (strcmp(otherScheme.get(), "imap") == 0 ||
strcmp(otherScheme.get(), "mailbox") == 0 ||
strcmp(otherScheme.get(), "news") == 0)
else if (otherScheme.Equals("imap") ||
otherScheme.Equals("mailbox") ||
otherScheme.Equals("news"))
{
// Each message is a distinct trust domain; use the
// whole spec for comparison
@ -222,27 +236,62 @@ nsCodebasePrincipal::Equals(nsIPrincipal *other, PRBool *result)
if (NS_FAILED(otherURI->GetSpec(otherSpec)))
return NS_ERROR_FAILURE;
nsCAutoString mySpec;
if (NS_FAILED(mURI->GetSpec(mySpec)))
if (NS_FAILED(myBaseURI->GetSpec(mySpec)))
return NS_ERROR_FAILURE;
*result = strcmp(otherSpec.get(), mySpec.get()) == 0;
*result = otherSpec.Equals(mySpec);
}
else
{
// Need to check the host
// Compare hosts
nsCAutoString otherHost;
rv = otherURI->GetHost(otherHost);
nsCAutoString myHost;
if (NS_SUCCEEDED(rv))
rv = mURI->GetHost(myHost);
*result = NS_SUCCEEDED(rv) && strcmp(otherHost.get(), myHost.get()) == 0;
rv = myBaseURI->GetHost(myHost);
*result = NS_SUCCEEDED(rv) && otherHost.Equals(myHost);
if (*result)
{
int otherPort;
// Compare ports
PRInt32 otherPort;
rv = otherURI->GetPort(&otherPort);
int myPort;
PRInt32 myPort;
if (NS_SUCCEEDED(rv))
rv = mURI->GetPort(&myPort);
rv = myBaseURI->GetPort(&myPort);
*result = NS_SUCCEEDED(rv) && otherPort == myPort;
// If the port comparison failed, see if either URL has a
// port of -1. If so, replace -1 with the default port
// for that scheme.
if(!*result && (myPort == -1 || otherPort == -1))
{
PRInt32 defaultPort;
//XXX had to hard-code the defualt port for http(s) here.
// remove this after darin fixes bug 113206
if (myScheme.Equals("http"))
defaultPort = 80;
else if (myScheme.Equals("https"))
defaultPort = 443;
else
{
nsCOMPtr<nsIIOService> ioService(
do_GetService(NS_IOSERVICE_CONTRACTID));
if (!ioService)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIProtocolHandler> protocolHandler;
rv = ioService->GetProtocolHandler(myScheme.get(),
getter_AddRefs(protocolHandler));
if (NS_FAILED(rv))
return rv;
rv = protocolHandler->GetDefaultPort(&defaultPort);
if (NS_FAILED(rv) || defaultPort == -1)
return NS_OK; // No default port for this scheme
}
if (myPort == -1)
myPort = defaultPort;
else if (otherPort == -1)
otherPort = defaultPort;
*result = otherPort == myPort;
}
}
}
}
@ -279,7 +328,7 @@ nsCodebasePrincipal::Write(nsIObjectOutputStream* aStream)
// Constructor, Destructor, initialization //
/////////////////////////////////////////////
nsCodebasePrincipal::nsCodebasePrincipal() : mTrusted(PR_FALSE)
nsCodebasePrincipal::nsCodebasePrincipal()
{
NS_INIT_ISUPPORTS();
}
@ -300,8 +349,7 @@ nsCodebasePrincipal::Init(nsIURI *uri)
// This method overrides nsBasePrincipal::InitFromPersistent
nsresult
nsCodebasePrincipal::InitFromPersistent(const char* aPrefName, const char* aURLStr,
const char* aGrantedList, const char* aDeniedList,
PRBool aTrusted)
const char* aGrantedList, const char* aDeniedList)
{
nsresult rv;
nsCOMPtr<nsIURI> uri;
@ -310,8 +358,6 @@ nsCodebasePrincipal::InitFromPersistent(const char* aPrefName, const char* aURLS
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(Init(uri))) return NS_ERROR_FAILURE;
// XXX: Add check for trusted = SSL only here?
mTrusted = aTrusted;
return nsBasePrincipal::InitFromPersistent(aPrefName, aURLStr,
aGrantedList, aDeniedList);

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

@ -58,7 +58,6 @@
#include "nsIXPConnect.h"
#include "nsIXPCSecurityManager.h"
#include "nsTextFormatter.h"
#include "nsIIOService.h"
#include "nsIStringBundle.h"
#include "nsNetUtil.h"
#include "nsDirectoryService.h"
@ -80,8 +79,6 @@
#include "nsIJSRuntimeService.h"
#include "nsIObserverService.h"
static NS_DEFINE_IID(kIIOServiceIID, NS_IIOSERVICE_IID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_IID(kIStringBundleServiceIID, NS_ISTRINGBUNDLESERVICE_IID);
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
static NS_DEFINE_CID(kCScriptNameSetRegistryCID,
@ -113,7 +110,6 @@ IsDOMClass(nsIClassInfo* aClassInfo)
return NS_SUCCEEDED(rv) && (classFlags & nsIClassInfo::DOM_OBJECT);
}
// Convenience method to get the current js context stack.
// Uses cached JSContextStack service instead of calling through
// to the service manager.
@ -374,7 +370,7 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
#endif
//-- Initialize policies if necessary
if (!mDefaultPolicy)
if (mPolicyPrefsChanged)
{
rv = InitPolicies();
if (NS_FAILED(rv))
@ -740,7 +736,7 @@ nsScriptSecurityManager::GetPropertyPolicy(jsval aProperty, ClassPolicy* aClassP
if (aClassPolicy && aClassPolicy != NO_POLICY_FOR_CLASS)
{
ppolicy =
(PropertyPolicy*) PL_DHashTableOperate(&aClassPolicy->mPolicy,
(PropertyPolicy*) PL_DHashTableOperate(aClassPolicy->mPolicy,
NS_REINTERPRET_CAST(void*, aProperty),
PL_DHASH_LOOKUP);
if (!PL_DHASH_ENTRY_IS_LIVE(ppolicy))
@ -748,14 +744,14 @@ nsScriptSecurityManager::GetPropertyPolicy(jsval aProperty, ClassPolicy* aClassP
if (aClassPolicy->mWildcard)
{
ppolicy = NS_REINTERPRET_CAST(PropertyPolicy*,
PL_DHashTableOperate(&aClassPolicy->mWildcard->mPolicy,
PL_DHashTableOperate(aClassPolicy->mWildcard->mPolicy,
NS_REINTERPRET_CAST(void*, aProperty),
PL_DHASH_LOOKUP));
}
if (!PL_DHASH_ENTRY_IS_LIVE(ppolicy) && aClassPolicy->mDefault)
{ // Now look for a default policy
ppolicy = NS_REINTERPRET_CAST(PropertyPolicy*,
PL_DHashTableOperate(&aClassPolicy->mDefault->mPolicy,
PL_DHashTableOperate(aClassPolicy->mDefault->mPolicy,
NS_REINTERPRET_CAST(void*, aProperty),
PL_DHASH_LOOKUP));
}
@ -1192,8 +1188,8 @@ nsScriptSecurityManager::CanExecuteScripts(JSContext* cx,
//-- Check for a per-site policy
static const char jsPrefGroupName[] = "javascript";
// Initialize policies if necessary
if (!mDefaultPolicy)
//-- Initialize policies if necessary
if (mPolicyPrefsChanged)
{
rv = InitPolicies();
if (NS_FAILED(rv))
@ -1679,96 +1675,27 @@ nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
#define PROPERTIES_URL "chrome://communicator/locale/security/caps.properties"
nsresult
Localize(const char *genericString, nsString &result)
PRBool
nsScriptSecurityManager::CheckConfirmDialog(JSContext* cx, nsIPrincipal* aPrincipal,
PRBool *checkValue)
{
nsresult ret;
nsresult rv;
*checkValue = PR_FALSE;
/* create a URL for the string resource file */
nsIIOService *pNetService = nsnull;
ret = nsServiceManager::GetService(kIOServiceCID, kIIOServiceIID,
(nsISupports**) &pNetService);
if (NS_FAILED(ret))
{
NS_WARNING("cannot get net service\n");
return ret;
}
nsIURI *uri = nsnull;
ret = pNetService->NewURI(NS_LITERAL_CSTRING(PROPERTIES_URL), nsnull, nsnull, &uri);
if (NS_FAILED(ret))
{
NS_WARNING("cannot create URI\n");
nsServiceManager::ReleaseService(kIOServiceCID, pNetService);
return ret;
}
nsIURI *url = nsnull;
ret = uri->QueryInterface(NS_GET_IID(nsIURI), (void**)&url);
nsServiceManager::ReleaseService(kIOServiceCID, pNetService);
if (NS_FAILED(ret))
{
NS_WARNING("cannot create URL\n");
return ret;
}
/* create a bundle for the localization */
nsIStringBundleService *pStringService = nsnull;
ret = nsServiceManager::GetService(kStringBundleServiceCID,
kIStringBundleServiceIID, (nsISupports**) &pStringService);
if (NS_FAILED(ret))
{
NS_WARNING("cannot get string service\n");
return ret;
}
nsCAutoString spec;
ret = url->GetAsciiSpec(spec);
if (NS_FAILED(ret))
{
NS_WARNING("cannot get url spec\n");
nsServiceManager::ReleaseService(kStringBundleServiceCID, pStringService);
return ret;
}
nsIStringBundle *bundle = nsnull;
ret = pStringService->CreateBundle(spec.get(), &bundle);
nsServiceManager::ReleaseService(kStringBundleServiceCID, pStringService);
if (NS_FAILED(ret))
{
NS_WARNING("cannot create instance\n");
return ret;
}
/* localize the given string */
nsAutoString strtmp;
strtmp.AssignWithConversion(genericString);
nsXPIDLString ptrv;
ret = bundle->GetStringFromName(strtmp.get(), getter_Copies(ptrv));
NS_RELEASE(bundle);
NS_WARN_IF_FALSE(NS_SUCCEEDED(ret), "cannot get string from name\n");
result.Assign(ptrv);
return ret;
}
static PRBool
CheckConfirmDialog(JSContext* cx, const PRUnichar *szMessage, const PRUnichar *szCheckMessage,
PRBool *checkValue)
{
nsresult res;
//-- Get a prompter for the current window.
nsCOMPtr<nsIPrompt> prompter;
nsCOMPtr<nsIScriptContext> scriptContext = (nsIScriptContext*)JS_GetContextPrivate(cx);
if (scriptContext)
if (cx)
{
nsCOMPtr<nsIScriptGlobalObject> globalObject;
scriptContext->GetGlobalObject(getter_AddRefs(globalObject));
NS_ASSERTION(globalObject, "script context has no global object");
nsCOMPtr<nsIDOMWindowInternal> domWin(do_QueryInterface(globalObject));
if (domWin)
domWin->GetPrompter(getter_AddRefs(prompter));
nsCOMPtr<nsIScriptContext> scriptContext = (nsIScriptContext*)JS_GetContextPrivate(cx);
if (scriptContext)
{
nsCOMPtr<nsIScriptGlobalObject> globalObject;
scriptContext->GetGlobalObject(getter_AddRefs(globalObject));
NS_ASSERTION(globalObject, "script context has no global object");
nsCOMPtr<nsIDOMWindowInternal> domWin(do_QueryInterface(globalObject));
if (domWin)
domWin->GetPrompter(getter_AddRefs(prompter));
}
}
if (!prompter)
@ -1777,27 +1704,50 @@ CheckConfirmDialog(JSContext* cx, const PRUnichar *szMessage, const PRUnichar *s
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
if (wwatch)
wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
}
if (!prompter)
{
*checkValue = 0;
return PR_FALSE;
if (!prompter)
return PR_FALSE;
}
PRInt32 buttonPressed = 1; /* in case user exits dialog by clicking X */
nsAutoString dialogTitle;
if (NS_FAILED(res = Localize("Titleline", dialogTitle)))
// create a bundle for the localization
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(kStringBundleServiceCID, &rv));
if (NS_FAILED(rv))
return PR_FALSE;
res = prompter->ConfirmEx(dialogTitle.get(), szMessage,
(nsIPrompt::BUTTON_TITLE_YES * nsIPrompt::BUTTON_POS_0) +
(nsIPrompt::BUTTON_TITLE_NO * nsIPrompt::BUTTON_POS_1),
nsnull, nsnull, nsnull, szCheckMessage, checkValue, &buttonPressed);
nsCOMPtr<nsIStringBundle> bundle;
rv = bundleService->CreateBundle(PROPERTIES_URL, getter_AddRefs(bundle));
if (NS_FAILED(rv))
return PR_FALSE;
if (NS_FAILED(res))
*checkValue = 0;
if (*checkValue != 0 && *checkValue != 1)
*checkValue = 0; /* this should never happen but it is happening!!! */
//-- Localize the dialog text
nsXPIDLString query, check, title;
rv = bundle->GetStringFromName(NS_LITERAL_STRING("EnableCapabilityQuery").get(),
getter_Copies(query));
if (NS_FAILED(rv))
return PR_FALSE;
rv = bundle->GetStringFromName(NS_LITERAL_STRING("CheckMessage").get(),
getter_Copies(check));
if (NS_FAILED(rv))
return PR_FALSE;
rv = bundle->GetStringFromName(NS_LITERAL_STRING("Titleline").get(),
getter_Copies(title));
if (NS_FAILED(rv))
return PR_FALSE;
nsXPIDLCString source;
rv = aPrincipal->ToUserVisibleString(getter_Copies(source));
if (NS_FAILED(rv))
return PR_FALSE;
nsXPIDLString message;
message.Assign(nsTextFormatter::smprintf(query.get(), source.get()));
PRInt32 buttonPressed = 1; // If the user exits by clicking the close box, assume No (button 1)
rv = prompter->ConfirmEx(title.get(), message.get(),
(nsIPrompt::BUTTON_TITLE_YES * nsIPrompt::BUTTON_POS_0) +
(nsIPrompt::BUTTON_TITLE_NO * nsIPrompt::BUTTON_POS_1),
nsnull, nsnull, nsnull, check.get(), checkValue, &buttonPressed);
if (NS_FAILED(rv))
*checkValue = PR_FALSE;
return (buttonPressed == 0);
}
@ -1810,24 +1760,12 @@ nsScriptSecurityManager::RequestCapability(nsIPrincipal* aPrincipal,
if (*canEnable == nsIPrincipal::ENABLE_WITH_USER_PERMISSION)
{
// Prompt user for permission to enable capability.
// "Remember This Decision" is unchecked by default.
static PRBool remember = PR_FALSE;
nsAutoString query, check;
if (NS_FAILED(Localize("EnableCapabilityQuery", query)))
return NS_ERROR_FAILURE;
if (NS_FAILED(Localize("CheckMessage", check)))
return NS_ERROR_FAILURE;
char *source;
if (NS_FAILED(aPrincipal->ToUserVisibleString(&source)))
return NS_ERROR_FAILURE;
PRUnichar *message = nsTextFormatter::smprintf(query.get(), source);
Recycle(source);
JSContext *cx = GetCurrentJSContext();
if (CheckConfirmDialog(cx, message, check.get(), &remember))
JSContext* cx = GetCurrentJSContext();
PRBool remember;
if (CheckConfirmDialog(cx, aPrincipal, &remember))
*canEnable = nsIPrincipal::ENABLE_GRANTED;
else
*canEnable = nsIPrincipal::ENABLE_DENIED;
PR_FREEIF(message);
if (remember)
{
//-- Save principal to prefs and to mPrincipals
@ -2146,7 +2084,7 @@ nsScriptSecurityManager::CheckXPCPermissions(nsISupports* aObj,
// Method implementing nsIObserver //
/////////////////////////////////////
static const char sPrincipalPrefix[] = "capability.principal";
static const char sProfileChangeMsg[] = "profile-after-change";
static NS_NAMED_LITERAL_CSTRING(sPolicyPrefix, "capability.policy.");
NS_IMETHODIMP
nsScriptSecurityManager::Observe(nsISupports* aObject, const char* aTopic,
@ -2159,6 +2097,8 @@ nsScriptSecurityManager::Observe(nsISupports* aObject, const char* aTopic,
static const char jsPrefix[] = "javascript.";
if(PL_strncmp(message, jsPrefix, sizeof(jsPrefix)-1) == 0)
JSEnabledPrefChanged(mSecurityPref);
if(PL_strncmp(message, sPolicyPrefix.get(), sPolicyPrefix.Length()) == 0)
mPolicyPrefsChanged = PR_TRUE; // This will force re-initialization of the pref table
else if((PL_strncmp(message, sPrincipalPrefix, sizeof(sPrincipalPrefix)-1) == 0) &&
!mIsWritingPrefs)
{
@ -2172,8 +2112,6 @@ nsScriptSecurityManager::Observe(nsISupports* aObject, const char* aTopic,
rv = InitPrincipals(1, idPrefArray, mSecurityPref);
}
}
else if((PL_strcmp(aTopic, sProfileChangeMsg) == 0))
rv = InitPolicies();
return rv;
}
@ -2188,7 +2126,8 @@ nsScriptSecurityManager::nsScriptSecurityManager(void)
mIsJavaScriptEnabled(PR_FALSE),
mIsMailJavaScriptEnabled(PR_FALSE),
mIsWritingPrefs(PR_FALSE),
mNameSetRegistered(PR_FALSE)
mNameSetRegistered(PR_FALSE),
mPolicyPrefsChanged(PR_TRUE)
{
NS_ASSERTION(sizeof(long) == sizeof(void*), "long and void* have different lengths on this platform. This may cause a security failure.");
@ -2287,25 +2226,20 @@ nsScriptSecurityManager::SystemPrincipalSingletonConstructor()
return NS_STATIC_CAST(nsSystemPrincipal*, sysprin);
}
NS_IMETHODIMP
nsScriptSecurityManager::ReloadSecurityPolicies()
{
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
if (NS_FAILED(rv)) return rv;
rv = xpc->ClearAllWrappedNativeSecurityPolicies();
if (NS_FAILED(rv)) return rv;
return InitPolicies();
}
static NS_NAMED_LITERAL_CSTRING(policyPrefPrefix, "capability.policy.");
nsresult
nsScriptSecurityManager::InitPolicies()
{
nsresult rv;
// Reset the "dirty" flag
mPolicyPrefsChanged = PR_FALSE;
// Clear any policies cached on XPConnect wrappers
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
if (NS_FAILED(rv)) return rv;
rv = xpc->ClearAllWrappedNativeSecurityPolicies();
if (NS_FAILED(rv)) return rv;
//-- Reset mOriginToPolicyMap
delete mOriginToPolicyMap;
mOriginToPolicyMap =
@ -2359,9 +2293,8 @@ nsScriptSecurityManager::InitPolicies()
morePolicies = (*policyCurrent != '\0');
*policyCurrent = '\0';
policyCurrent++;
//XXX use better concatenation?
nsCAutoString sitesPrefName(policyPrefPrefix +
nsCAutoString sitesPrefName(sPolicyPrefix +
nsDependentCString(nameBegin) +
NS_LITERAL_CSTRING(".sites"));
nsXPIDLCString domainList;
@ -2448,7 +2381,7 @@ nsScriptSecurityManager::InitDomainPolicy(JSContext* cx,
DomainPolicy* aDomainPolicy)
{
nsresult rv;
nsCAutoString policyPrefix(policyPrefPrefix +
nsCAutoString policyPrefix(sPolicyPrefix +
nsDependentCString(aPolicyName) +
NS_LITERAL_CSTRING("."));
PRUint32 prefixLength = policyPrefix.Length() - 1; // subtract the '.'
@ -2530,7 +2463,7 @@ nsScriptSecurityManager::InitDomainPolicy(JSContext* cx,
// Store this property in the class policy
PropertyPolicy* ppolicy =
(PropertyPolicy*) PL_DHashTableOperate(&cpolicy->mPolicy,
(PropertyPolicy*) PL_DHashTableOperate(cpolicy->mPolicy,
(void*)STRING_TO_JSVAL(propertyKey),
PL_DHASH_ADD);
if (!ppolicy)
@ -2595,18 +2528,13 @@ nsScriptSecurityManager::InitPrincipals(PRUint32 aPrefCount, const char** aPrefN
nsISecurityPref* aSecurityPref)
{
/* This is the principal preference syntax:
* capability.principal.[codebase|codebaseTrusted|certificate].<name>.[id|granted|denied]
* capability.principal.[codebase|certificate].<name>.[id|granted|denied]
* For example:
* user_pref("capability.principal.certificate.p1.id","12:34:AB:CD");
* user_pref("capability.principal.certificate.p1.granted","Capability1 Capability2");
* user_pref("capability.principal.certificate.p1.denied","Capability3");
*/
/* codebaseTrusted means a codebase principal that can enable capabilities even if
* codebase principals are disabled. Don't use trustedCodebase except with unspoofable
* URLs such as HTTPS URLs.
*/
static const char idSuffix[] = ".id";
for (PRUint32 c = 0; c < aPrefCount; c++)
{
@ -2646,9 +2574,8 @@ nsScriptSecurityManager::InitPrincipals(PRUint32 aPrefCount, const char** aPrefN
}
//-- Create a principal based on the prefs
static const char certificateName[] = "capability.principal.certificate";
static const char codebaseName[] = "capability.principal.codebase";
static const char codebaseTrustedName[] = "capability.principal.codebaseTrusted";
static const char certificateName[] = "capability.principal.certificate.";
static const char codebaseName[] = "capability.principal.codebase.";
nsCOMPtr<nsIPrincipal> principal;
if (PL_strncmp(aPrefNames[c], certificateName,
sizeof(certificateName)-1) == 0)
@ -2667,11 +2594,8 @@ nsScriptSecurityManager::InitPrincipals(PRUint32 aPrefCount, const char** aPrefN
nsCodebasePrincipal *codebase = new nsCodebasePrincipal();
if (codebase) {
NS_ADDREF(codebase);
PRBool trusted = (PL_strncmp(aPrefNames[c], codebaseTrustedName,
sizeof(codebaseTrustedName)-1) == 0);
if (NS_SUCCEEDED(codebase->InitFromPersistent(aPrefNames[c], id,
grantedList, deniedList,
trusted)))
grantedList, deniedList)))
principal = do_QueryInterface((nsBasePrincipal*)codebase);
NS_RELEASE(codebase);
}
@ -2732,14 +2656,8 @@ nsScriptSecurityManager::InitPrefs()
PRUint32 prefCount;
char** prefNames;
// Registering the security manager as an observer to the
// profile-after-change topic. We will build up the policy table
// after the initial profile loads and after profile switches.
nsCOMPtr<nsIObserverService> observerService
(do_GetService("@mozilla.org/observer-service;1", &rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = observerService->AddObserver(this, sProfileChangeMsg, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
// Set a callback for policy pref changes
prefBranchInternal->AddObserver(sPolicyPrefix.get(), this, PR_FALSE);
//-- Initialize the principals database from prefs
rv = mPrefBranch->GetChildList(sPrincipalPrefix, &prefCount, &prefNames);
@ -2795,7 +2713,7 @@ PrintClassPolicy(PLDHashTable *table, PLDHashEntryHdr *entry,
ClassPolicy* cp = (ClassPolicy*)entry;
printf(" %s\n", cp->key);
PL_DHashTableEnumerate(&cp->mPolicy, PrintPropertyPolicy, arg);
PL_DHashTableEnumerate(cp->mPolicy, PrintPropertyPolicy, arg);
return PL_DHASH_NEXT;
}