Fixes for bugs 27010, 32878, 32948.

git-svn-id: svn://10.0.0.236/trunk@66935 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mstoltz%netscape.com
2000-04-23 20:30:29 +00:00
parent 293ca6c86b
commit 85e8a5b8e2
24 changed files with 684 additions and 424 deletions

View File

@@ -52,6 +52,10 @@
#include "nsIIOService.h"
#include "nsIStringBundle.h"
#include "nsINetSupportDialogService.h"
#include "nsNetUtil.h"
#include "nsSpecialSystemDirectory.h"
#include "nsIFile.h"
#include "nsIZipReader.h"
static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID);
static NS_DEFINE_IID(kIIOServiceIID, NS_IIOSERVICE_IID);
@@ -61,6 +65,7 @@ static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static NS_DEFINE_CID(kCScriptNameSetRegistryCID,
NS_SCRIPT_NAMESET_REGISTRY_CID);
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
enum {
SCRIPT_SECURITY_UNDEFINED_ACCESS,
@@ -131,9 +136,9 @@ nsSecurityNameSet::~nsSecurityNameSet()
NS_IMPL_ISUPPORTS(nsSecurityNameSet, NS_GET_IID(nsIScriptExternalNameSet));
static char *
getStringArgument(JSContext *cx, JSObject *obj, uintN argc, jsval *argv)
getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsval *argv)
{
if (argc == 0 || !JSVAL_IS_STRING(argv[0])) {
if (argc <= argNum || !JSVAL_IS_STRING(argv[argNum])) {
JS_ReportError(cx, "String argument expected");
return nsnull;
}
@@ -141,7 +146,7 @@ getStringArgument(JSContext *cx, JSObject *obj, uintN argc, jsval *argv)
* We don't want to use JS_ValueToString because we want to be able
* to have an object to represent a target in subsequent versions.
*/
JSString *str = JSVAL_TO_STRING(argv[0]);
JSString *str = JSVAL_TO_STRING(argv[argNum]);
if (!str)
return nsnull;
@@ -153,7 +158,7 @@ netscape_security_isPrivilegeEnabled(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
JSBool result = JS_FALSE;
char *cap = getStringArgument(cx, obj, argc, argv);
char *cap = getStringArgument(cx, obj, 0, argc, argv);
if (cap) {
nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
@@ -174,7 +179,7 @@ PR_STATIC_CALLBACK(JSBool)
netscape_security_enablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
char *cap = getStringArgument(cx, obj, argc, argv);
char *cap = getStringArgument(cx, obj, 0, argc, argv);
if (!cap)
return JS_FALSE;
nsresult rv;
@@ -192,7 +197,7 @@ PR_STATIC_CALLBACK(JSBool)
netscape_security_disablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
char *cap = getStringArgument(cx, obj, argc, argv);
char *cap = getStringArgument(cx, obj, 0, argc, argv);
if (!cap)
return JS_FALSE;
nsresult rv;
@@ -210,7 +215,7 @@ PR_STATIC_CALLBACK(JSBool)
netscape_security_revertPrivilege(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
char *cap = getStringArgument(cx, obj, argc, argv);
char *cap = getStringArgument(cx, obj, 0, argc, argv);
if (!cap)
return JS_FALSE;
nsresult rv;
@@ -224,11 +229,55 @@ netscape_security_revertPrivilege(JSContext *cx, JSObject *obj, uintN argc,
return JS_TRUE;
}
PR_STATIC_CALLBACK(JSBool)
netscape_security_setCanEnablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
if (argc < 2) return JS_FALSE;
char *principalID = getStringArgument(cx, obj, 0, argc, argv);
char *cap = getStringArgument(cx, obj, 1, argc, argv);
if (!principalID || !cap)
return JS_FALSE;
nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv))
return JS_FALSE;
NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
if (NS_FAILED(securityManager->SetCanEnableCapability(principalID, cap,
nsIPrincipal::ENABLE_GRANTED)))
return JS_FALSE;
return JS_TRUE;
}
PR_STATIC_CALLBACK(JSBool)
netscape_security_invalidate(JSContext *cx, JSObject *obj, uintN argc,
jsval *argv, jsval *rval)
{
char *principalID = getStringArgument(cx, obj, 0, argc, argv);
if (!principalID)
return JS_FALSE;
nsresult rv;
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_FAILED(rv))
return JS_FALSE;
NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
if (NS_FAILED(securityManager->SetCanEnableCapability(principalID,
nsBasePrincipal::Invalid,
nsIPrincipal::ENABLE_GRANTED)))
return JS_FALSE;
return JS_TRUE;
}
static JSFunctionSpec PrivilegeManager_static_methods[] = {
{ "isPrivilegeEnabled", netscape_security_isPrivilegeEnabled, 1},
{ "enablePrivilege", netscape_security_enablePrivilege, 1},
{ "disablePrivilege", netscape_security_disablePrivilege, 1},
{ "revertPrivilege", netscape_security_revertPrivilege, 1},
//-- System Cert Functions
{ "setCanEnablePrivilege", netscape_security_setCanEnablePrivilege, 2},
{ "invalidate", netscape_security_invalidate, 1},
{0}
};
@@ -545,9 +594,7 @@ nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
}
NS_IMETHODIMP
nsScriptSecurityManager::GetCertificatePrincipal(const char* aIssuerName,
const char* aSerialNumber,
const char* aCompanyName,
nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
nsIPrincipal **result)
{
nsresult rv;
@@ -556,7 +603,7 @@ nsScriptSecurityManager::GetCertificatePrincipal(const char* aIssuerName,
if (!certificate)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(certificate);
if (NS_FAILED(certificate->Init(aIssuerName, aSerialNumber, aCompanyName)))
if (NS_FAILED(certificate->Init(aCertID)))
{
NS_RELEASE(certificate);
return NS_ERROR_FAILURE;
@@ -756,6 +803,14 @@ nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
*result = PR_TRUE;
return NS_OK;
}
// If this capability check is being called as a result of the security
// manager accessing a security preference, allow execution.
if (mIsAccessingPrefs &&
(PL_strcmp(capability, "SecurityPreferencesAccess") == 0))
{
*result = PR_TRUE;
return NS_OK;
}
do {
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(GetFramePrincipal(cx, fp, getter_AddRefs(principal)))) {
@@ -978,18 +1033,7 @@ nsScriptSecurityManager::EnableCapability(const char *capability)
//-- Save principal to prefs and to mPrincipals
if (NS_FAILED(principal->SetCanEnableCapability(capability, canEnable)))
return NS_ERROR_FAILURE;
if (!mPrincipals) {
mPrincipals = new nsSupportsHashtable(31);
if (!mPrincipals)
return NS_ERROR_OUT_OF_MEMORY;
}
mIsWritingPrefs = PR_TRUE;
if (NS_FAILED(principal->Save(mPrincipals, mPrefs))) {
mIsWritingPrefs = PR_FALSE;
return NS_ERROR_FAILURE;
}
mIsWritingPrefs = PR_FALSE;
if (NS_FAILED(mPrefs->SavePrefFile()))
if (NS_FAILED(SavePrincipal(principal)))
return NS_ERROR_FAILURE;
}
}
@@ -1038,6 +1082,64 @@ nsScriptSecurityManager::DisableCapability(const char *capability)
return NS_OK;
}
NS_IMETHODIMP
nsScriptSecurityManager::SetCanEnableCapability(const char* certificateID,
const char* capability,
PRInt16 canEnable)
{
nsresult rv;
nsCOMPtr<nsIPrincipal> subjectPrincipal;
rv = GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
//-- Get the system certificate
if (!mSystemCertificate)
{
nsCOMPtr<nsIFile> systemCertFile;
rv = NS_GetSpecialDirectory("xpcom.currentProcess.componentDirectory",
getter_AddRefs(systemCertFile));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
systemCertFile->Append("systemSignature.jar");
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
nsCOMPtr<nsIZipReader> systemCertJar;
rv = nsComponentManager::CreateInstance(kZipReaderCID, nsnull,
NS_GET_IID(nsIZipReader),
getter_AddRefs(systemCertJar));
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;
}
//-- Make sure the caller's principal is the system certificate
PRBool isEqual = PR_FALSE;
if (mSystemCertificate)
{
rv = mSystemCertificate->Equals(subjectPrincipal, &isEqual);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
}
if (!isEqual)
{
JSContext* cx = GetCurrentContext();
if (!cx) return NS_ERROR_FAILURE;
static const char msg1[] = "Only code signed by the system certificate may call SetCanEnableCapability or Invalidate";
static const char msg2[] = "Attempt to call SetCanEnableCapability or Invalidate when no system certificate has been established";
JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx,
mSystemCertificate ? msg1 : msg2)));
return NS_ERROR_FAILURE;
}
//-- Get the target principal
nsCOMPtr<nsIPrincipal> objectPrincipal;
rv = GetCertificatePrincipal(certificateID, getter_AddRefs(objectPrincipal));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
rv = objectPrincipal->SetCanEnableCapability(capability, canEnable);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
return SavePrincipal(objectPrincipal);
}
////////////////////////////////////////////////
// Methods implementing nsIXPCSecurityManager //
@@ -1109,7 +1211,7 @@ nsScriptSecurityManager::nsScriptSecurityManager(void)
mSystemPrincipal(nsnull), mPrincipals(nsnull),
mIsJavaScriptEnabled(PR_FALSE),
mIsMailJavaScriptEnabled(PR_FALSE),
mIsWritingPrefs(PR_FALSE)
mIsAccessingPrefs(PR_FALSE)
{
NS_INIT_REFCNT();
memset(hasPolicyVector, 0, sizeof(hasPolicyVector));
@@ -1196,6 +1298,40 @@ 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)
@@ -1269,7 +1405,9 @@ nsScriptSecurityManager::GetSecurityLevel(nsIPrincipal *principal,
PRInt32 secLevel;
char *secLevelString;
nsresult rv;
mIsAccessingPrefs = PR_TRUE;
rv = mPrefs->CopyCharPref(prefName, &secLevelString);
mIsAccessingPrefs = PR_FALSE;
if (NS_FAILED(rv)) {
prefName += (isWrite ? ".write" : ".read");
rv = mPrefs->CopyCharPref(prefName, &secLevelString);
@@ -1294,7 +1432,6 @@ nsScriptSecurityManager::GetSecurityLevel(nsIPrincipal *principal,
return SCRIPT_SECURITY_UNDEFINED_ACCESS;
}
NS_IMETHODIMP
nsScriptSecurityManager::CheckXPCPermissions(JSContext *aJSContext)
{
@@ -1351,7 +1488,6 @@ struct nsDomainEntry {
nsCString mPolicy;
};
NS_IMETHODIMP
nsScriptSecurityManager::GetPrefName(nsIPrincipal *principal,
nsDOMProp domProp, nsCString &result)
@@ -1563,19 +1699,11 @@ nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName,
if (NS_FAILED(info->prefs->CopyCharPref(prefName, &data)))
return;
static char codebaseName[] = "[Codebase ";
static char certificateName[] = "[Certificate ";
static const char certificateName[] = "security.principal.certificate";
static const char codebaseName[] = "security.principal.codebase";
nsCOMPtr<nsIPrincipal> principal;
if (PL_strncasecmp(data, codebaseName, sizeof(codebaseName)-1) == 0) {
nsCodebasePrincipal *codebase = new nsCodebasePrincipal();
if (codebase) {
NS_ADDREF(codebase);
if (NS_SUCCEEDED(codebase->InitFromPersistent(prefName, data)))
principal = do_QueryInterface((nsBasePrincipal*)codebase);
NS_RELEASE(codebase);
}
} else if (PL_strncasecmp(data, certificateName,
sizeof(certificateName)-1) == 0)
if (PL_strncmp(prefName, certificateName,
sizeof(certificateName)-1) == 0)
{
nsCertificatePrincipal *certificate = new nsCertificatePrincipal();
if (certificate) {
@@ -1584,6 +1712,16 @@ nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName,
principal = do_QueryInterface((nsBasePrincipal*)certificate);
NS_RELEASE(certificate);
}
} else if(PL_strncmp(prefName, codebaseName,
sizeof(codebaseName)-1) == 0)
{
nsCodebasePrincipal *codebase = new nsCodebasePrincipal();
if (codebase) {
NS_ADDREF(codebase);
if (NS_SUCCEEDED(codebase->InitFromPersistent(prefName, data)))
principal = do_QueryInterface((nsBasePrincipal*)codebase);
NS_RELEASE(codebase);
}
}
nsCRT::free(data);
if (principal) {
@@ -1621,7 +1759,7 @@ int
nsScriptSecurityManager::PrincipalPrefChanged(const char *pref, void *data)
{
nsScriptSecurityManager *secMgr = (nsScriptSecurityManager *) data;
if (secMgr->mIsWritingPrefs)
if (secMgr->mIsAccessingPrefs)
return 0;
EnumeratePrincipalsInfo info;
info.ht = secMgr->mPrincipals;