Fixes for 32878, 37739. Added PR_CALLBACK macros. Changed security.principal pref syntax to a nicer syntax. Removed "security.checkxpconnect" hack.

This commit is contained in:
mstoltz%netscape.com 2000-05-16 03:40:51 +00:00
Родитель fbaaa304db
Коммит ecc9b44676
14 изменённых файлов: 329 добавлений и 257 удалений

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

@ -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);

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

@ -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.

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

@ -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();

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

@ -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[];

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

@ -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);

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

@ -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<nsIURI> mURI;
};
#endif // _NS_CODEBASE_PRINCIPAL_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;

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

@ -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();

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

@ -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<nsIPrincipal> PrimaryChild;
if (NS_FAILED(GetPrimaryChild(getter_AddRefs(PrimaryChild))))
return NS_ERROR_FAILURE;
return PrimaryChild->ToStreamableForm(aName, aData);
return PrimaryChild->GetPreferences(aPrefName, aID,
aGrantedList, aDeniedList);
}
/////////////////////////////////////////////

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

@ -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;
}

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

@ -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
// <certificateID><space><capabilities list>"
// 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

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

@ -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
// "<codebase URL><space><capabilities string>"
// 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<nsIURI> 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);
}

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

@ -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<nsIFile> 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<nsIPrincipal> persistent = aToSave;
nsCOMPtr<nsIAggregatePrincipal> 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<nsIPrincipal> persistent = aToSave;
nsCOMPtr<nsIAggregatePrincipal> 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].<name>.[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<nsIPrincipal> 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);

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

@ -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,