From 083b598d3ca23012bea4197bd9efa2387e4227f4 Mon Sep 17 00:00:00 2001 From: "mstoltz%netscape.com" Date: Wed, 20 Mar 2002 05:53:46 +0000 Subject: [PATCH] A bunch of fixes in caps: 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. git-svn-id: svn://10.0.0.236/trunk@116958 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/caps/idl/nsIScriptSecurityManager.idl | 5 - mozilla/caps/include/nsCodebasePrincipal.h | 4 +- .../caps/include/nsScriptSecurityManager.h | 21 +- mozilla/caps/src/nsCodebasePrincipal.cpp | 132 ++++++--- mozilla/caps/src/nsScriptSecurityManager.cpp | 262 ++++++------------ 5 files changed, 193 insertions(+), 231 deletions(-) diff --git a/mozilla/caps/idl/nsIScriptSecurityManager.idl b/mozilla/caps/idl/nsIScriptSecurityManager.idl index a102b40eee8..7b51341e15b 100644 --- a/mozilla/caps/idl/nsIScriptSecurityManager.idl +++ b/mozilla/caps/idl/nsIScriptSecurityManager.idl @@ -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++ diff --git a/mozilla/caps/include/nsCodebasePrincipal.h b/mozilla/caps/include/nsCodebasePrincipal.h index 710c54a6809..02795ccf9a5 100644 --- a/mozilla/caps/include/nsCodebasePrincipal.h +++ b/mozilla/caps/include/nsCodebasePrincipal.h @@ -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 mURI; - PRBool mTrusted; }; #endif // _NS_CODEBASE_PRINCIPAL_H_ diff --git a/mozilla/caps/include/nsScriptSecurityManager.h b/mozilla/caps/include/nsScriptSecurityManager.h index e94325a27e4..a1424c6905d 100644 --- a/mozilla/caps/include/nsScriptSecurityManager.h +++ b/mozilla/caps/include/nsScriptSecurityManager.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 mJSContextStack; PRBool mNameSetRegistered; + PRBool mPolicyPrefsChanged; }; #endif /*_NS_SCRIPT_SECURITY_MANAGER_H_*/ diff --git a/mozilla/caps/src/nsCodebasePrincipal.cpp b/mozilla/caps/src/nsCodebasePrincipal.cpp index 6d01d32c669..6610f6d5c03 100644 --- a/mozilla/caps/src/nsCodebasePrincipal.cpp +++ b/mozilla/caps/src/nsCodebasePrincipal.cpp @@ -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 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 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 otherCodebase; if (NS_FAILED(other->QueryInterface( NS_GET_IID(nsICodebasePrincipal), @@ -200,21 +197,38 @@ nsCodebasePrincipal::Equals(nsIPrincipal *other, PRBool *result) nsCOMPtr 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 jarURI; + nsCOMPtr 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 ioService( + do_GetService(NS_IOSERVICE_CONTRACTID)); + if (!ioService) + return NS_ERROR_FAILURE; + nsCOMPtr 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 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); diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index 2e753f76a9d..8be72a46b6c 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -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 prompter; - nsCOMPtr scriptContext = (nsIScriptContext*)JS_GetContextPrivate(cx); - if (scriptContext) + if (cx) { - nsCOMPtr globalObject; - scriptContext->GetGlobalObject(getter_AddRefs(globalObject)); - NS_ASSERTION(globalObject, "script context has no global object"); - nsCOMPtr domWin(do_QueryInterface(globalObject)); - if (domWin) - domWin->GetPrompter(getter_AddRefs(prompter)); + nsCOMPtr scriptContext = (nsIScriptContext*)JS_GetContextPrivate(cx); + if (scriptContext) + { + nsCOMPtr globalObject; + scriptContext->GetGlobalObject(getter_AddRefs(globalObject)); + NS_ASSERTION(globalObject, "script context has no global object"); + nsCOMPtr 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 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 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 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 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 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]..[id|granted|denied] + * capability.principal.[codebase|certificate]..[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 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 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; }