diff --git a/mozilla/caps/idl/nsIPrincipal.idl b/mozilla/caps/idl/nsIPrincipal.idl index b90c04d0ad2..fa9ed78b7bd 100644 --- a/mozilla/caps/idl/nsIPrincipal.idl +++ b/mozilla/caps/idl/nsIPrincipal.idl @@ -49,7 +49,8 @@ interface nsIPrincipal : nsISupports { string ToUserVisibleString(); - void ToStreamableForm(out string name, out string data); + void GetPreferences(out string prefName, out string id, + out string grantedList, out string deniedList); boolean Equals(in nsIPrincipal other); diff --git a/mozilla/caps/idl/nsIScriptSecurityManager.idl b/mozilla/caps/idl/nsIScriptSecurityManager.idl index 59b3ff6c713..1d0caad7381 100644 --- a/mozilla/caps/idl/nsIScriptSecurityManager.idl +++ b/mozilla/caps/idl/nsIScriptSecurityManager.idl @@ -111,6 +111,13 @@ interface nsIScriptSecurityManager : nsISupports ///////////////// Capabilities ///////////////////// + + /** + * Request that 'capability' can be enabled by scripts or applets running + * with 'principal'. Will prompt user if necessary. Returns + * nsIPrincipal::ENABLE_GRANTED or nsIPrincipal::ENABLE_DENIED based on user's choice. + */ + void RequestCapability(in nsIPrincipal principal, in string capability, out short result); /** * Return true if the currently executing script has 'capability' enabled. diff --git a/mozilla/caps/include/nsAggregatePrincipal.h b/mozilla/caps/include/nsAggregatePrincipal.h index 0f716d841f9..8dea5bba391 100644 --- a/mozilla/caps/include/nsAggregatePrincipal.h +++ b/mozilla/caps/include/nsAggregatePrincipal.h @@ -80,9 +80,10 @@ public: NS_IMETHOD DisableCapability(const char *capability, void **annotation); - - NS_IMETHOD - ToStreamableForm(char** aName, char** aData); + + NS_IMETHOD + GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList); nsAggregatePrincipal(); diff --git a/mozilla/caps/include/nsBasePrincipal.h b/mozilla/caps/include/nsBasePrincipal.h index 95e87391c14..3a6f5fab3f4 100644 --- a/mozilla/caps/include/nsBasePrincipal.h +++ b/mozilla/caps/include/nsBasePrincipal.h @@ -57,12 +57,14 @@ public: NS_IMETHOD DisableCapability(const char *capability, void **annotation); + + NS_IMETHOD + GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList); nsresult - InitFromPersistent(const char *name, const char *data); - - NS_IMETHOD - ToStreamableForm(char** aName, char** aData); + InitFromPersistent(const char* aPrefName,const char* aID, + const char* aGrantedList, const char* aDeniedList); static const char Invalid[]; diff --git a/mozilla/caps/include/nsCertificatePrincipal.h b/mozilla/caps/include/nsCertificatePrincipal.h index d96962669de..3c90a072652 100644 --- a/mozilla/caps/include/nsCertificatePrincipal.h +++ b/mozilla/caps/include/nsCertificatePrincipal.h @@ -48,19 +48,21 @@ public: NS_IMETHOD ToString(char **result); NS_IMETHOD ToUserVisibleString(char **result); - - NS_IMETHOD ToStreamableForm(char** aName, char** aData); - + + NS_IMETHOD GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList); + NS_IMETHOD Equals(nsIPrincipal *other, PRBool *result); NS_IMETHOD HashValue(PRUint32 *result); NS_IMETHOD CanEnableCapability(const char *capability, PRInt16 *result); - NS_IMETHOD InitFromPersistent(const char *name, const char* data); - NS_IMETHOD Init(const char* aCertificateID); + nsresult InitFromPersistent(const char* aPrefName, const char* aID, + const char* aGrantedList, const char* aDeniedList); + nsCertificatePrincipal(); virtual ~nsCertificatePrincipal(void); diff --git a/mozilla/caps/include/nsCodebasePrincipal.h b/mozilla/caps/include/nsCodebasePrincipal.h index 0ecd58bf6c1..436a020dfc3 100644 --- a/mozilla/caps/include/nsCodebasePrincipal.h +++ b/mozilla/caps/include/nsCodebasePrincipal.h @@ -30,6 +30,7 @@ #include "nsBasePrincipal.h" #include "nsICodebasePrincipal.h" #include "nsIURI.h" +#include "nsCOMPtr.h" #define NS_CODEBASEPRINCIPAL_CID \ { 0x7ee2a400, 0x0b91, 0xaad3, \ @@ -46,9 +47,10 @@ public: NS_IMETHOD ToString(char **result); NS_IMETHOD ToUserVisibleString(char **result); - - NS_IMETHOD ToStreamableForm(char** aName, char** aData); - + + NS_IMETHOD GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList); + NS_IMETHOD Equals(nsIPrincipal *other, PRBool *result); NS_IMETHOD HashValue(PRUint32 *result); @@ -61,12 +63,13 @@ public: Init(nsIURI *uri); nsresult - InitFromPersistent(const char *name, const char* data); + InitFromPersistent(const char* aPrefName, const char* aID, + const char* aGrantedList, const char* aDeniedList); virtual ~nsCodebasePrincipal(void); protected: - nsIURI *mURI; + nsCOMPtr mURI; }; #endif // _NS_CODEBASE_PRINCIPAL_H_ diff --git a/mozilla/caps/include/nsScriptSecurityManager.h b/mozilla/caps/include/nsScriptSecurityManager.h index d80cd127a51..87e7aa10544 100644 --- a/mozilla/caps/include/nsScriptSecurityManager.h +++ b/mozilla/caps/include/nsScriptSecurityManager.h @@ -144,6 +144,9 @@ private: NS_IMETHOD InitFromPrefs(); + static nsresult + PrincipalPrefNames(const char* pref, char** grantedPref, char** deniedPref); + static void EnumeratePolicyCallback(const char *prefName, void *data); @@ -153,7 +156,7 @@ private: static int PR_CALLBACK JSEnabledPrefChanged(const char *pref, void *data); - static int + static int PR_CALLBACK PrincipalPrefChanged(const char *pref, void *data); nsObjectHashtable *mOriginToPolicyMap; diff --git a/mozilla/caps/include/nsSystemPrincipal.h b/mozilla/caps/include/nsSystemPrincipal.h index a2f3294f169..e672b3218a2 100644 --- a/mozilla/caps/include/nsSystemPrincipal.h +++ b/mozilla/caps/include/nsSystemPrincipal.h @@ -60,7 +60,8 @@ public: NS_IMETHOD DisableCapability(const char *capability, void * *annotation); - NS_IMETHOD ToStreamambleForm(char** aName, char** aData); + NS_IMETHOD GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList); NS_IMETHOD Init(); diff --git a/mozilla/caps/src/nsAggregatePrincipal.cpp b/mozilla/caps/src/nsAggregatePrincipal.cpp index 328646f6a71..e2f80a83724 100644 --- a/mozilla/caps/src/nsAggregatePrincipal.cpp +++ b/mozilla/caps/src/nsAggregatePrincipal.cpp @@ -368,12 +368,14 @@ nsAggregatePrincipal::DisableCapability(const char *capability, void **annotatio } NS_IMETHODIMP -nsAggregatePrincipal::ToStreamableForm(char** aName, char** aData) +nsAggregatePrincipal::GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList) { nsCOMPtr PrimaryChild; if (NS_FAILED(GetPrimaryChild(getter_AddRefs(PrimaryChild)))) return NS_ERROR_FAILURE; - return PrimaryChild->ToStreamableForm(aName, aData); + return PrimaryChild->GetPreferences(aPrefName, aID, + aGrantedList, aDeniedList); } ///////////////////////////////////////////// diff --git a/mozilla/caps/src/nsBasePrincipal.cpp b/mozilla/caps/src/nsBasePrincipal.cpp index e86d1ffc5ed..4be9bfcd8e4 100644 --- a/mozilla/caps/src/nsBasePrincipal.cpp +++ b/mozilla/caps/src/nsBasePrincipal.cpp @@ -220,95 +220,94 @@ nsBasePrincipal::SetCapability(const char *capability, void **annotation, int nsBasePrincipal::mCapabilitiesOrdinal = 0; nsresult -nsBasePrincipal::InitFromPersistent(const char *name, const char* data) +nsBasePrincipal::InitFromPersistent(const char* aPrefName, const char* aID, + const char* aGrantedList, const char* aDeniedList) { - // Parses capabilities strings of the form - // "Capability=value ..." - // ie. "UniversalBrowserRead=Granted UniversalBrowserWrite=Denied" - //-- Empty the capability table if (mCapabilities) mCapabilities->Reset(); //-- Save the preference name - nsCAutoString nameString(name); - mPrefName = nameString.ToNewCString(); + mPrefName = PL_strdup(aPrefName); + if (!mPrefName) + return NS_ERROR_OUT_OF_MEMORY; - const char* ordinalBegin = PL_strpbrk(name, "1234567890"); + const char* ordinalBegin = PL_strpbrk(aPrefName, "1234567890"); if (ordinalBegin) { int n = atoi(ordinalBegin); - if (mCapabilitiesOrdinal <= n) + if (mCapabilitiesOrdinal <= n) mCapabilitiesOrdinal = n+1; } - //-- Parse the capabilities - for (;;) - { - char* wordEnd = PL_strchr(data, '='); - if (wordEnd == nsnull) - break; - while (*(wordEnd-1) == ' ') - wordEnd--; - const char* cap = data; - data = wordEnd+1; - *wordEnd = '\0'; - while (*data == ' ' || *data == '=') - data++; - - PRInt16 value; - if (*data == 'G' || *data == 'g' || *data == 'Y' || - *data == 'y' || *data == 'T' || *data == 't' || - (*data - '0') == nsIPrincipal::ENABLE_GRANTED || - *data == '1') - value = nsIPrincipal::ENABLE_GRANTED; - else if (*data == 'D' || *data == 'd' || *data == 'N' || - *data == 'n' || *data == 'F' || *data == 'f' || - (*data - '0') == nsIPrincipal::ENABLE_DENIED || - *data == '0') - value = nsIPrincipal::ENABLE_DENIED; - else - value = nsIPrincipal::ENABLE_UNKNOWN; - - if(NS_FAILED(SetCanEnableCapability(cap, value))) + //-- Store the capabilities + if (aGrantedList) + if(NS_FAILED(SetCanEnableCapability(aGrantedList, nsIPrincipal::ENABLE_GRANTED))) + return NS_ERROR_FAILURE; + if (aDeniedList) + if(NS_FAILED(SetCanEnableCapability(aDeniedList, nsIPrincipal::ENABLE_DENIED))) return NS_ERROR_FAILURE; - while (*data != ' ' && *data != '\0') data++; - while (*data == ' ') data++; - } return NS_OK; } +struct CapabilityList +{ + nsCString* granted; + nsCString* denied; +}; + PR_STATIC_CALLBACK(PRBool) -AppendCapability(nsHashKey *aKey, void *aData, void *aStr) +AppendCapability(nsHashKey *aKey, void *aData, void *capListPtr) { - nsCString *capStr = (nsCString*) aStr; - capStr->Append(' '); - capStr->AppendWithConversion(((nsStringKey *) aKey)->GetString()); - capStr->Append('='); - switch ((PRInt16)(PRInt32)aData) + CapabilityList* capList = (CapabilityList*)capListPtr; + PRInt16 value = (PRInt16)(PRInt32)aData; + if (value == nsIPrincipal::ENABLE_GRANTED) { - case nsIPrincipal::ENABLE_GRANTED: - capStr->Append("Granted"); - break; - case nsIPrincipal::ENABLE_DENIED: - capStr->Append("Denied"); - break; - default: - capStr->Append("Unknown"); + capList->granted->AppendWithConversion(((nsStringKey *) aKey)->GetString()); + capList->granted->Append(' '); + } + else if (value == nsIPrincipal::ENABLE_DENIED) + { + capList->denied->AppendWithConversion(((nsStringKey *) aKey)->GetString()); + capList->denied->Append(' '); } return PR_TRUE; -} +} NS_IMETHODIMP -nsBasePrincipal::ToStreamableForm(char** aName, char** aData) +nsBasePrincipal::GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList) { - char *streamableForm; - if (NS_FAILED(ToString(&streamableForm))) + //-- Preference name + *aPrefName = nsCRT::strdup(mPrefName); + if (!aPrefName) + return NS_ERROR_OUT_OF_MEMORY; + + //-- ID + if (NS_FAILED(ToString(aID))) return NS_ERROR_FAILURE; + + //-- Capabilities + *aGrantedList = nsnull; + *aDeniedList = nsnull; if (mCapabilities) { - nsCAutoString buildingCapString(streamableForm); - mCapabilities->Enumerate(AppendCapability, (void*)&buildingCapString); - streamableForm = buildingCapString.ToNewCString(); + nsCAutoString grantedListStr; + nsCAutoString deniedListStr; + CapabilityList* capList = new CapabilityList(); + capList->granted = &grantedListStr; + capList->denied = &deniedListStr; + mCapabilities->Enumerate(AppendCapability, (void*)capList); + if (grantedListStr.Length() > 0) + { + grantedListStr.Truncate(grantedListStr.Length()-1); + *aGrantedList = grantedListStr.ToNewCString(); + if (!*aGrantedList) return NS_ERROR_OUT_OF_MEMORY; + } + if (deniedListStr.Length() > 0) + { + deniedListStr.Truncate(deniedListStr.Length()-1); + *aDeniedList = deniedListStr.ToNewCString(); + if (!*aDeniedList) return NS_ERROR_OUT_OF_MEMORY; + } } - *aData = streamableForm; return NS_OK; } diff --git a/mozilla/caps/src/nsCertificatePrincipal.cpp b/mozilla/caps/src/nsCertificatePrincipal.cpp index 243e4004a34..40a2e48d8f6 100644 --- a/mozilla/caps/src/nsCertificatePrincipal.cpp +++ b/mozilla/caps/src/nsCertificatePrincipal.cpp @@ -101,17 +101,18 @@ nsCertificatePrincipal::ToUserVisibleString(char **result) } NS_IMETHODIMP -nsCertificatePrincipal::ToStreamableForm(char** aName, char** aData) +nsCertificatePrincipal::GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList) { if (!mPrefName) { - nsCAutoString s("security.principal.certificate"); + nsCAutoString s; + s.Assign("security.principal.certificate.p"); s.AppendInt(mCapabilitiesOrdinal++); + s.Append(".id"); mPrefName = s.ToNewCString(); } - *aName = nsCRT::strdup(mPrefName); - if (!*aName) - return NS_ERROR_FAILURE; - return nsBasePrincipal::ToStreamableForm(aName, aData); + return nsBasePrincipal::GetPreferences(aPrefName, aID, + aGrantedList, aDeniedList); } NS_IMETHODIMP @@ -156,31 +157,14 @@ nsCertificatePrincipal::HashValue(PRUint32 *result) // Constructor, Destructor, initialization // ///////////////////////////////////////////// NS_IMETHODIMP -nsCertificatePrincipal::InitFromPersistent(const char *name, const char* data) +nsCertificatePrincipal::InitFromPersistent(const char* aPrefName, const char* aCertID, + const char* aGrantedList, const char* aDeniedList) { - // Parses preference strings of the form - // " - // ie. "AB:CD:12:34 UniversalBrowserRead=Granted" - - if (!data) - return NS_ERROR_ILLEGAL_VALUE; - - char* idEnd = PL_strchr(data, ' '); // Find end of certID - if (idEnd) - *idEnd = '\0'; - - if (NS_FAILED(Init(data))) + if (NS_FAILED(Init(aCertID))) return NS_ERROR_FAILURE; - if (idEnd) - { - data = idEnd+1; - while (*data == ' ') - data++; - if (data) - return nsBasePrincipal::InitFromPersistent(name, data); - } - return NS_OK; + return nsBasePrincipal::InitFromPersistent(aPrefName, aCertID, + aGrantedList, aDeniedList); } NS_IMETHODIMP diff --git a/mozilla/caps/src/nsCodebasePrincipal.cpp b/mozilla/caps/src/nsCodebasePrincipal.cpp index 5e520f8785b..f3780efc897 100644 --- a/mozilla/caps/src/nsCodebasePrincipal.cpp +++ b/mozilla/caps/src/nsCodebasePrincipal.cpp @@ -41,20 +41,10 @@ NSBASEPRINCIPALS_RELEASE(nsCodebasePrincipal); /////////////////////////////////////// // Methods implementing nsIPrincipal // /////////////////////////////////////// - NS_IMETHODIMP nsCodebasePrincipal::ToString(char **result) { - // STRING USE WARNING: perhaps |str| should be an |nsCAutoString|? -- scc - nsAutoString buf; - buf.AppendWithConversion("[Codebase "); - nsXPIDLCString origin; - if (NS_FAILED(GetOrigin(getter_Copies(origin)))) - return NS_ERROR_FAILURE; - buf.AppendWithConversion(origin); - buf.AppendWithConversion(']'); - *result = buf.ToNewCString(); - return *result ? NS_OK : NS_ERROR_OUT_OF_MEMORY; + return GetOrigin(result); } NS_IMETHODIMP @@ -64,17 +54,18 @@ nsCodebasePrincipal::ToUserVisibleString(char **result) } NS_IMETHODIMP -nsCodebasePrincipal::ToStreamableForm(char** aName, char** aData) +nsCodebasePrincipal::GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList) { if (!mPrefName) { - nsCAutoString s("security.principal.codebase"); + nsCAutoString s; + s.Assign("security.principal.codebase.p"); s.AppendInt(mCapabilitiesOrdinal++); + s.Append(".id"); mPrefName = s.ToNewCString(); } - *aName = nsCRT::strdup(mPrefName); - if (!*aName) - return NS_ERROR_FAILURE; - return nsBasePrincipal::ToStreamableForm(aName, aData); + return nsBasePrincipal::GetPreferences(aPrefName, aID, + aGrantedList, aDeniedList); } NS_IMETHODIMP @@ -246,7 +237,6 @@ nsCodebasePrincipal::SameOrigin(nsIPrincipal *other, PRBool *result) nsCodebasePrincipal::nsCodebasePrincipal() { NS_INIT_ISUPPORTS(); - mURI = nsnull; } nsresult @@ -261,45 +251,26 @@ nsCodebasePrincipal::Init(nsIURI *uri) } // JSPrincipals::Init adopts codebase, so no need to free now mURI = uri; - NS_ADDREF(mURI); return NS_OK; } // This method overrides nsBasePrincipal::InitFromPersistent nsresult -nsCodebasePrincipal::InitFromPersistent(const char *name, const char* data) +nsCodebasePrincipal::InitFromPersistent(const char* aPrefName, const char* aURLStr, + const char* aGrantedList, const char* aDeniedList) { - // Parses preference strings of the form - // "" - // ie. "http://www.mozilla.org UniversalBrowserRead=Granted" - if (!data) - return NS_ERROR_ILLEGAL_VALUE; - - char* urlEnd = PL_strchr(data, ' '); // Find end of URL - if (urlEnd) - *urlEnd = '\0'; - + nsresult rv; nsCOMPtr uri; - if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), data, nsnull))) { - NS_ASSERTION(PR_FALSE, "Malformed URI in security.principal preference."); - return NS_ERROR_FAILURE; - } + rv = NS_NewURI(getter_AddRefs(uri), aURLStr, nsnull); + NS_ASSERTION(NS_SUCCEEDED(rv), "Malformed URI in security.principal preference."); + if (NS_FAILED(rv)) return rv; + if (NS_FAILED(Init(uri))) return NS_ERROR_FAILURE; - if (urlEnd) - { - // Jump to beginning of capabilities list - data = urlEnd+1; - while (*data == ' ') - data++; - if (data) - return nsBasePrincipal::InitFromPersistent(name, data); - } - return NS_OK; + return nsBasePrincipal::InitFromPersistent(aPrefName, aURLStr, + aGrantedList, aDeniedList); } -nsCodebasePrincipal::~nsCodebasePrincipal(void) +nsCodebasePrincipal::~nsCodebasePrincipal() { - if (mURI) - NS_RELEASE(mURI); } diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index c6330b1a33c..3406febed82 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -53,7 +53,7 @@ #include "nsIStringBundle.h" #include "nsINetSupportDialogService.h" #include "nsNetUtil.h" -#include "nsSpecialSystemDirectory.h" +#include "nsDirectoryService.h" #include "nsIFile.h" #include "nsIZipReader.h" @@ -971,6 +971,41 @@ CheckConfirmDialog(const PRUnichar *szMessage, const PRUnichar *szCheckMessage, return (buttonPressed == 0); } +NS_IMETHODIMP +nsScriptSecurityManager::RequestCapability(nsIPrincipal* aPrincipal, + const char *capability, PRInt16* canEnable) +{ + if (NS_FAILED(aPrincipal->CanEnableCapability(capability, canEnable))) + return NS_ERROR_FAILURE; + if (*canEnable == nsIPrincipal::ENABLE_WITH_USER_PERMISSION) { + // Prompt user for permission to enable capability. + static PRBool remember = PR_TRUE; + 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.GetUnicode(), source); + Recycle(source); + if (CheckConfirmDialog(message, check.GetUnicode(), &remember)) + *canEnable = nsIPrincipal::ENABLE_GRANTED; + else + *canEnable = nsIPrincipal::ENABLE_DENIED; + PR_FREEIF(message); + if (remember) { + //-- Save principal to prefs and to mPrincipals + if (NS_FAILED(aPrincipal->SetCanEnableCapability(capability, *canEnable))) + return NS_ERROR_FAILURE; + if (NS_FAILED(SavePrincipal(aPrincipal))) + return NS_ERROR_FAILURE; + } + } + return NS_OK; +} + NS_IMETHODIMP nsScriptSecurityManager::GetPrincipalAndFrame(JSContext *cx, nsIPrincipal **result, @@ -1011,36 +1046,11 @@ nsScriptSecurityManager::EnableCapability(const char *capability) } if (enabled) return NS_OK; + PRInt16 canEnable; - if (NS_FAILED(principal->CanEnableCapability(capability, &canEnable))) + if (NS_FAILED(RequestCapability(principal, capability, &canEnable))) return NS_ERROR_FAILURE; - if (canEnable == nsIPrincipal::ENABLE_WITH_USER_PERMISSION) { - // Prompt user for permission to enable capability. - static PRBool remember = PR_TRUE; - 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(principal->ToUserVisibleString(&source))) - return NS_ERROR_FAILURE; - PRUnichar *message = nsTextFormatter::smprintf(query.GetUnicode(), - source); - Recycle(source); - if (CheckConfirmDialog(message, check.GetUnicode(), &remember)) - canEnable = nsIPrincipal::ENABLE_GRANTED; - else - canEnable = nsIPrincipal::ENABLE_DENIED; - PR_FREEIF(message); - if (remember) { - //-- Save principal to prefs and to mPrincipals - if (NS_FAILED(principal->SetCanEnableCapability(capability, canEnable))) - return NS_ERROR_FAILURE; - if (NS_FAILED(SavePrincipal(principal))) - return NS_ERROR_FAILURE; - } - } + if (canEnable != nsIPrincipal::ENABLE_GRANTED) { static const char msg[] = "enablePrivilege not granted"; JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, msg))); @@ -1100,8 +1110,10 @@ nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID, if (!mSystemCertificate) { nsCOMPtr systemCertFile; - rv = NS_GetSpecialDirectory("xpcom.currentProcess.componentDirectory", - getter_AddRefs(systemCertFile)); + NS_WITH_SERVICE(nsIProperties, directoryService, NS_DIRECTORY_SERVICE_PROGID, &rv); + if (!directoryService) return NS_ERROR_FAILURE; + rv = directoryService->Get("system.OS_CurrentProcessDirectory", NS_GET_IID(nsIFile), + getter_AddRefs(systemCertFile)); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; systemCertFile->Append("systemSignature.jar"); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; @@ -1112,10 +1124,12 @@ nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID, if (NS_FAILED(rv)) return NS_ERROR_FAILURE; systemCertJar->Init(systemCertFile); rv = systemCertJar->Open(); - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - rv = systemCertJar->GetCertificatePrincipal(nsnull, - getter_AddRefs(mSystemCertificate)); - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + if (NS_SUCCEEDED(rv)) + { + rv = systemCertJar->GetCertificatePrincipal(nsnull, + getter_AddRefs(mSystemCertificate)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + } } //-- Make sure the caller's principal is the system certificate @@ -1302,40 +1316,6 @@ nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj, return NS_ERROR_FAILURE; } -NS_IMETHODIMP -nsScriptSecurityManager::SavePrincipal(nsIPrincipal* aToSave) -{ - NS_ASSERTION(mPrefs, "nsScriptSecurityManager::mPrefs not initialized"); - nsresult rv; - nsCOMPtr persistent = aToSave; - nsCOMPtr aggregate = do_QueryInterface(aToSave, &rv); - if (NS_SUCCEEDED(rv)) - if (NS_FAILED(aggregate->GetPrimaryChild(getter_AddRefs(persistent)))) - return NS_ERROR_FAILURE; - - //-- Save to mPrincipals - if (!mPrincipals) - { - mPrincipals = new nsSupportsHashtable(31); - if (!mPrincipals) - return NS_ERROR_OUT_OF_MEMORY; - } - nsIPrincipalKey key(persistent); - mPrincipals->Put(&key, persistent); - - //-- Save to prefs - nsXPIDLCString prefName; - nsXPIDLCString prefData; - rv = persistent->ToStreamableForm(getter_Copies(prefName), - getter_Copies(prefData)); - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - mIsAccessingPrefs = PR_TRUE; - rv = mPrefs->SetCharPref(prefName, prefData); - mIsAccessingPrefs = PR_FALSE; - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - return mPrefs->SavePrefFile(); -} - NS_IMETHODIMP nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj, const char *aCapability) @@ -1443,21 +1423,6 @@ nsScriptSecurityManager::CheckXPCPermissions(JSContext *aJSContext) if (NS_FAILED(IsCapabilityEnabled("UniversalXPConnect", &ok))) ok = PR_FALSE; if (!ok) { - // T E M P O R A R Y - // Check the pref "security.checkxpconnect". If it exists and is - // set to false, don't report an error. - nsresult rv; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_SUCCEEDED(rv)) { - PRBool enabled; - if (NS_SUCCEEDED(prefs->GetBoolPref("security.checkxpconnect", - &enabled)) && - !enabled) - { - return NS_OK; - } - } - // T E M P O R A R Y static const char msg[] = "Access denied to XPConnect service."; JS_SetPendingException(aJSContext, STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext, msg))); @@ -1548,6 +1513,65 @@ nsScriptSecurityManager::GetPrefName(nsIPrincipal *principal, return NS_OK; } +NS_IMETHODIMP +nsScriptSecurityManager::SavePrincipal(nsIPrincipal* aToSave) +{ + NS_ASSERTION(mPrefs, "nsScriptSecurityManager::mPrefs not initialized"); + nsresult rv; + nsCOMPtr persistent = aToSave; + nsCOMPtr aggregate = do_QueryInterface(aToSave, &rv); + if (NS_SUCCEEDED(rv)) + if (NS_FAILED(aggregate->GetPrimaryChild(getter_AddRefs(persistent)))) + return NS_ERROR_FAILURE; + + //-- Save to mPrincipals + if (!mPrincipals) + { + mPrincipals = new nsSupportsHashtable(31); + if (!mPrincipals) + return NS_ERROR_OUT_OF_MEMORY; + } + nsIPrincipalKey key(persistent); + mPrincipals->Put(&key, persistent); + + //-- Save to prefs + nsXPIDLCString idPrefName; + nsXPIDLCString id; + nsXPIDLCString grantedList; + nsXPIDLCString deniedList; + rv = persistent->GetPreferences(getter_Copies(idPrefName), + getter_Copies(id), + getter_Copies(grantedList), + getter_Copies(deniedList)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsXPIDLCString grantedPrefName; + nsXPIDLCString deniedPrefName; + rv = PrincipalPrefNames( idPrefName, + getter_Copies(grantedPrefName), + getter_Copies(deniedPrefName) ); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + mIsAccessingPrefs = PR_TRUE; + if (grantedList) + mPrefs->SetCharPref(grantedPrefName, grantedList); + else + mPrefs->ClearUserPref(grantedPrefName); + + if (deniedList) + mPrefs->SetCharPref(deniedPrefName, deniedList); + else + mPrefs->ClearUserPref(deniedPrefName); + + if (grantedList || deniedList) + mPrefs->SetCharPref(idPrefName, id); + else + mPrefs->ClearUserPref(idPrefName); + + mIsAccessingPrefs = PR_FALSE; + return mPrefs->SavePrefFile(); +} + static nsDOMProp findDomProp(const char *propName, int n) { @@ -1686,23 +1710,77 @@ nsScriptSecurityManager::EnumeratePolicyCallback(const char *prefName, NS_ASSERTION(PR_FALSE, "DOM property name invalid or not found"); } +nsresult +nsScriptSecurityManager::PrincipalPrefNames(const char* pref, + char** grantedPref, char** deniedPref) +{ + char* lastDot = PL_strrchr(pref, '.'); + if (!lastDot) return NS_ERROR_FAILURE; + PRInt32 prefLen = lastDot - pref + 1; + + *grantedPref = nsnull; + *deniedPref = nsnull; + + static const char granted[] = "granted"; + *grantedPref = (char*)PR_MALLOC(prefLen + sizeof(granted)); + if (!grantedPref) return NS_ERROR_OUT_OF_MEMORY; + PL_strncpy(*grantedPref, pref, prefLen); + PL_strcpy(*grantedPref + prefLen, granted); + + static const char denied[] = "denied"; + *deniedPref = (char*)PR_MALLOC(prefLen + sizeof(denied)); + if (!deniedPref) + { + PR_FREEIF(*grantedPref); + return NS_ERROR_OUT_OF_MEMORY; + } + PL_strncpy(*deniedPref, pref, prefLen); + PL_strcpy(*deniedPref + prefLen, denied); + + return NS_OK; +} + struct EnumeratePrincipalsInfo { // this struct doesn't own these objects; consider them parameters on // the stack nsSupportsHashtable *ht; - nsIPref *prefs; + nsIPref *prefs; }; void nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName, void *voidParam) { + /* This is the principal preference syntax: + * security.principal.[codebase|certificate]..[id|granted|denied] + * For example: + * user_pref("security.principal.certificate.p1.id","12:34:AB:CD"); + * user_pref("security.principal.certificate.p1.granted","Capability1 Capability2"); + * user_pref("security.principal.certificate.p1.denied","Capability3"); + */ + EnumeratePrincipalsInfo *info = (EnumeratePrincipalsInfo *) voidParam; - - char* data; - if (NS_FAILED(info->prefs->CopyCharPref(prefName, &data))) + static const char idName[] = ".id"; + PRInt32 prefNameLen = PL_strlen(prefName) - (sizeof(idName)-1); + if (PL_strcasecmp(prefName + prefNameLen, idName) != 0) return; - + + char* id; + if (NS_FAILED(info->prefs->CopyCharPref(prefName, &id))) + return; + + nsXPIDLCString grantedPrefName; + nsXPIDLCString deniedPrefName; + if (NS_FAILED(PrincipalPrefNames( prefName, + getter_Copies(grantedPrefName), + getter_Copies(deniedPrefName) ))) + return; + + char* grantedList = nsnull; + info->prefs->CopyCharPref(grantedPrefName, &grantedList); + char* deniedList = nsnull; + info->prefs->CopyCharPref(deniedPrefName, &deniedList); + static const char certificateName[] = "security.principal.certificate"; static const char codebaseName[] = "security.principal.codebase"; nsCOMPtr principal; @@ -1712,7 +1790,8 @@ nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName, nsCertificatePrincipal *certificate = new nsCertificatePrincipal(); if (certificate) { NS_ADDREF(certificate); - if (NS_SUCCEEDED(certificate->InitFromPersistent(prefName, data))) + if (NS_SUCCEEDED(certificate->InitFromPersistent(prefName, id, + grantedList, deniedList))) principal = do_QueryInterface((nsBasePrincipal*)certificate); NS_RELEASE(certificate); } @@ -1722,12 +1801,15 @@ nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName, nsCodebasePrincipal *codebase = new nsCodebasePrincipal(); if (codebase) { NS_ADDREF(codebase); - if (NS_SUCCEEDED(codebase->InitFromPersistent(prefName, data))) + if (NS_SUCCEEDED(codebase->InitFromPersistent(prefName, id, + grantedList, deniedList))) principal = do_QueryInterface((nsBasePrincipal*)codebase); NS_RELEASE(codebase); } } - nsCRT::free(data); + PR_FREEIF(grantedList); + PR_FREEIF(deniedList); + if (principal) { nsIPrincipalKey key(principal); info->ht->Put(&key, principal); @@ -1737,7 +1819,7 @@ nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName, static const char jsEnabledPrefName[] = "javascript.enabled"; static const char jsMailEnabledPrefName[] = "javascript.allow.mailnews"; -int +int PR_CALLBACK nsScriptSecurityManager::JSEnabledPrefChanged(const char *pref, void *data) { nsScriptSecurityManager *secMgr = (nsScriptSecurityManager *) data; @@ -1759,16 +1841,28 @@ nsScriptSecurityManager::JSEnabledPrefChanged(const char *pref, void *data) return 0; } -int +int PR_CALLBACK nsScriptSecurityManager::PrincipalPrefChanged(const char *pref, void *data) { nsScriptSecurityManager *secMgr = (nsScriptSecurityManager *) data; if (secMgr->mIsAccessingPrefs) return 0; + + char* lastDot = PL_strrchr(pref, '.'); + if (!lastDot) return NS_ERROR_FAILURE; + PRInt32 prefLen = lastDot - pref + 1; + + static const char id[] = "id"; + char* idPref = (char*)PR_MALLOC(prefLen + sizeof(id)); + if (!idPref) return NS_ERROR_OUT_OF_MEMORY; + PL_strncpy(idPref, pref, prefLen); + PL_strcpy(idPref + prefLen, id); + EnumeratePrincipalsInfo info; info.ht = secMgr->mPrincipals; info.prefs = secMgr->mPrefs; - EnumeratePrincipalsCallback(pref, &info); + EnumeratePrincipalsCallback(idPref, &info); + PR_FREEIF(idPref); return 0; } @@ -1786,7 +1880,7 @@ nsScriptSecurityManager::InitFromPrefs() NS_ASSERTION(strcmp(domPropNames[i-1], domPropNames[i]) < 0, "DOM properties are not properly sorted"); } -#endif +#endif nsresult rv; NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); diff --git a/mozilla/caps/src/nsSystemPrincipal.cpp b/mozilla/caps/src/nsSystemPrincipal.cpp index 89954c60c69..6ccd0ae95fe 100644 --- a/mozilla/caps/src/nsSystemPrincipal.cpp +++ b/mozilla/caps/src/nsSystemPrincipal.cpp @@ -58,7 +58,8 @@ nsSystemPrincipal::ToUserVisibleString(char **result) } NS_IMETHODIMP -nsSystemPrincipal::ToStreamambleForm(char** aName, char** aData) +nsSystemPrincipal::GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList) { // The system principal should never be streamed out return NS_ERROR_FAILURE; @@ -94,6 +95,7 @@ nsSystemPrincipal::SetCanEnableCapability(const char *capability, return NS_ERROR_FAILURE; } + NS_IMETHODIMP nsSystemPrincipal::IsCapabilityEnabled(const char *capability, void *annotation,