2000-01-23 04:23:14 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
1999-08-20 09:51:02 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
1999-08-20 09:51:02 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
1999-08-20 09:51:02 +00:00
|
|
|
*
|
1999-11-06 03:43:54 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1999-08-20 09:51:02 +00:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
2000-01-23 04:23:14 +00:00
|
|
|
* Copyright (C) 1998-2000 Netscape Communications Corporation. All
|
1999-11-06 03:43:54 +00:00
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
2000-02-10 04:56:56 +00:00
|
|
|
* Norris Boyd
|
2000-03-31 00:31:18 +00:00
|
|
|
* Mitch Stoltz
|
2000-02-10 04:56:56 +00:00
|
|
|
* Steve Morse
|
1999-08-20 09:51:02 +00:00
|
|
|
*/
|
|
|
|
#include "nsScriptSecurityManager.h"
|
|
|
|
#include "nsIServiceManager.h"
|
2000-01-26 15:33:57 +00:00
|
|
|
#include "nsIScriptObjectOwner.h"
|
1999-08-20 09:51:02 +00:00
|
|
|
#include "nsIURL.h"
|
2000-03-21 04:05:35 +00:00
|
|
|
#include "nsIJARURI.h"
|
1999-08-20 09:51:02 +00:00
|
|
|
#include "nspr.h"
|
|
|
|
#include "plstr.h"
|
1999-08-29 21:58:42 +00:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsJSPrincipals.h"
|
1999-09-01 00:54:35 +00:00
|
|
|
#include "nsSystemPrincipal.h"
|
|
|
|
#include "nsCodebasePrincipal.h"
|
2000-01-18 21:54:01 +00:00
|
|
|
#include "nsCertificatePrincipal.h"
|
2000-03-21 04:05:35 +00:00
|
|
|
#include "nsAggregatePrincipal.h"
|
1999-08-27 08:36:49 +00:00
|
|
|
#include "nsCRT.h"
|
1999-09-07 02:54:19 +00:00
|
|
|
#include "nsXPIDLString.h"
|
1999-09-15 20:58:41 +00:00
|
|
|
#include "nsIJSContextStack.h"
|
1999-10-02 03:41:37 +00:00
|
|
|
#include "nsDOMError.h"
|
1999-10-25 22:22:16 +00:00
|
|
|
#include "xpcexception.h"
|
1999-10-28 22:09:03 +00:00
|
|
|
#include "nsDOMCID.h"
|
|
|
|
#include "nsIScriptNameSetRegistry.h"
|
1999-11-11 22:10:36 +00:00
|
|
|
#include "nsIScriptExternalNameSet.h"
|
|
|
|
#include "jsdbgapi.h"
|
2000-01-06 00:59:18 +00:00
|
|
|
#include "nsDOMPropNames.h"
|
2000-01-26 08:38:10 +00:00
|
|
|
#include "nsIXPConnect.h"
|
|
|
|
#include "nsIXPCSecurityManager.h"
|
2000-02-10 04:56:56 +00:00
|
|
|
#include "nsTextFormatter.h"
|
|
|
|
#include "nsIIOService.h"
|
|
|
|
#include "nsIStringBundle.h"
|
|
|
|
#include "nsINetSupportDialogService.h"
|
2000-04-26 03:50:07 +00:00
|
|
|
#include "nsNetUtil.h"
|
2000-05-16 03:40:51 +00:00
|
|
|
#include "nsDirectoryService.h"
|
2000-08-14 22:38:27 +00:00
|
|
|
#include "nsDirectoryServiceDefs.h"
|
2000-04-26 03:50:07 +00:00
|
|
|
#include "nsIFile.h"
|
|
|
|
#include "nsIZipReader.h"
|
2000-05-17 02:38:22 +00:00
|
|
|
#include "nsIPluginInstance.h"
|
2000-08-16 04:01:02 +00:00
|
|
|
#include "nsIXPConnect.h"
|
2000-09-09 00:53:21 +00:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
|
|
|
#include "nsIDOMWindowInternal.h"
|
2000-02-10 04:56:56 +00:00
|
|
|
|
|
|
|
static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID);
|
|
|
|
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);
|
1999-08-20 09:51:02 +00:00
|
|
|
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
1999-10-28 22:09:03 +00:00
|
|
|
static NS_DEFINE_CID(kCScriptNameSetRegistryCID,
|
|
|
|
NS_SCRIPT_NAMESET_REGISTRY_CID);
|
2000-04-26 03:50:07 +00:00
|
|
|
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
|
1999-08-20 09:51:02 +00:00
|
|
|
|
1999-09-07 20:40:20 +00:00
|
|
|
enum {
|
2000-01-08 16:51:54 +00:00
|
|
|
SCRIPT_SECURITY_UNDEFINED_ACCESS,
|
1999-11-11 22:10:36 +00:00
|
|
|
SCRIPT_SECURITY_CAPABILITY_ONLY,
|
1999-09-07 20:40:20 +00:00
|
|
|
SCRIPT_SECURITY_SAME_DOMAIN_ACCESS,
|
|
|
|
SCRIPT_SECURITY_ALL_ACCESS,
|
|
|
|
SCRIPT_SECURITY_NO_ACCESS
|
|
|
|
};
|
|
|
|
|
1999-11-11 22:10:36 +00:00
|
|
|
static JSContext *
|
|
|
|
GetCurrentContext() {
|
|
|
|
// Get JSContext from stack.
|
|
|
|
nsresult rv;
|
2000-09-13 23:57:52 +00:00
|
|
|
nsCOMPtr<nsIJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return nsnull;
|
|
|
|
JSContext *cx;
|
|
|
|
if (NS_FAILED(stack->Peek(&cx)))
|
|
|
|
return nsnull;
|
|
|
|
return cx;
|
|
|
|
}
|
|
|
|
|
2000-08-22 06:02:14 +00:00
|
|
|
// Convinience method to get the current js context stack.
|
|
|
|
// Uses cached JSContextStack service instead of calling through
|
|
|
|
// to the service manager.
|
|
|
|
JSContext *
|
|
|
|
nsScriptSecurityManager::GetCurrentContextQuick() {
|
|
|
|
// Get JSContext from stack.
|
|
|
|
nsresult rv;
|
|
|
|
if (!mThreadJSContextStack) {
|
2000-09-13 23:57:52 +00:00
|
|
|
mThreadJSContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
|
2000-08-22 06:02:14 +00:00
|
|
|
}
|
|
|
|
if (!mThreadJSContextStack)
|
|
|
|
return nsnull;
|
|
|
|
JSContext *cx;
|
|
|
|
if (NS_FAILED(mThreadJSContextStack->Peek(&cx)))
|
|
|
|
return nsnull;
|
|
|
|
return cx;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-23 14:32:38 +00:00
|
|
|
#if 0
|
|
|
|
// unused.
|
2000-04-14 03:14:53 +00:00
|
|
|
static JSContext *
|
|
|
|
GetSafeContext() {
|
|
|
|
// Get the "safe" JSContext: our JSContext of last resort
|
|
|
|
nsresult rv;
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_WITH_SERVICE(nsIJSContextStack, stack, "@mozilla.org/js/xpc/ContextStack;1",
|
2000-04-14 03:14:53 +00:00
|
|
|
&rv);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return nsnull;
|
|
|
|
nsCOMPtr<nsIThreadJSContextStack> tcs = do_QueryInterface(stack);
|
|
|
|
JSContext *cx;
|
|
|
|
if (NS_FAILED(tcs->GetSafeJSContext(&cx)))
|
|
|
|
return nsnull;
|
|
|
|
return cx;
|
|
|
|
}
|
2000-06-23 14:32:38 +00:00
|
|
|
#endif
|
2000-04-14 03:14:53 +00:00
|
|
|
|
1999-11-20 07:28:34 +00:00
|
|
|
static nsDOMProp
|
1999-11-11 22:10:36 +00:00
|
|
|
findDomProp(const char *propName, int n);
|
|
|
|
|
|
|
|
///////////////////////
|
|
|
|
// nsSecurityNameSet //
|
|
|
|
///////////////////////
|
|
|
|
|
|
|
|
class nsSecurityNameSet : public nsIScriptExternalNameSet
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
nsSecurityNameSet();
|
|
|
|
virtual ~nsSecurityNameSet();
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_IMETHOD InitializeClasses(nsIScriptContext* aScriptContext);
|
|
|
|
NS_IMETHOD AddNameSet(nsIScriptContext* aScriptContext);
|
|
|
|
};
|
|
|
|
|
|
|
|
nsSecurityNameSet::nsSecurityNameSet()
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsSecurityNameSet::~nsSecurityNameSet()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(nsSecurityNameSet, NS_GET_IID(nsIScriptExternalNameSet));
|
|
|
|
|
|
|
|
static char *
|
2000-04-26 03:50:07 +00:00
|
|
|
getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsval *argv)
|
1999-11-11 22:10:36 +00:00
|
|
|
{
|
2000-04-26 03:50:07 +00:00
|
|
|
if (argc <= argNum || !JSVAL_IS_STRING(argv[argNum])) {
|
1999-11-11 22:10:36 +00:00
|
|
|
JS_ReportError(cx, "String argument expected");
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2000-04-26 03:50:07 +00:00
|
|
|
JSString *str = JSVAL_TO_STRING(argv[argNum]);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (!str)
|
|
|
|
return nsnull;
|
|
|
|
|
|
|
|
return JS_GetStringBytes(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
PR_STATIC_CALLBACK(JSBool)
|
|
|
|
netscape_security_isPrivilegeEnabled(JSContext *cx, JSObject *obj, uintN argc,
|
|
|
|
jsval *argv, jsval *rval)
|
|
|
|
{
|
|
|
|
JSBool result = JS_FALSE;
|
2000-04-26 03:50:07 +00:00
|
|
|
char *cap = getStringArgument(cx, obj, 0, argc, argv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (cap) {
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
|
|
|
|
rv = securityManager->IsCapabilityEnabled(cap, &result);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
result = JS_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*rval = BOOLEAN_TO_JSVAL(result);
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PR_STATIC_CALLBACK(JSBool)
|
|
|
|
netscape_security_enablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
|
|
|
jsval *argv, jsval *rval)
|
|
|
|
{
|
2000-04-26 03:50:07 +00:00
|
|
|
char *cap = getStringArgument(cx, obj, 0, argc, argv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (!cap)
|
|
|
|
return JS_FALSE;
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return JS_FALSE;
|
|
|
|
NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
|
|
|
|
if (NS_FAILED(securityManager->EnableCapability(cap)))
|
|
|
|
return JS_FALSE;
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PR_STATIC_CALLBACK(JSBool)
|
|
|
|
netscape_security_disablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
|
|
|
jsval *argv, jsval *rval)
|
|
|
|
{
|
2000-04-26 03:50:07 +00:00
|
|
|
char *cap = getStringArgument(cx, obj, 0, argc, argv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (!cap)
|
|
|
|
return JS_FALSE;
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return JS_FALSE;
|
|
|
|
NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
|
|
|
|
if (NS_FAILED(securityManager->DisableCapability(cap)))
|
|
|
|
return JS_FALSE;
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PR_STATIC_CALLBACK(JSBool)
|
|
|
|
netscape_security_revertPrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
|
|
|
jsval *argv, jsval *rval)
|
|
|
|
{
|
2000-04-26 03:50:07 +00:00
|
|
|
char *cap = getStringArgument(cx, obj, 0, argc, argv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (!cap)
|
|
|
|
return JS_FALSE;
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return JS_FALSE;
|
|
|
|
NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
|
|
|
|
if (NS_FAILED(securityManager->RevertCapability(cap)))
|
|
|
|
return JS_FALSE;
|
|
|
|
return JS_TRUE;
|
|
|
|
}
|
|
|
|
|
2000-04-26 03:50:07 +00:00
|
|
|
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,
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
2000-04-26 03:50:07 +00:00
|
|
|
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,
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
2000-04-26 03:50:07 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1999-11-11 22:10:36 +00:00
|
|
|
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},
|
2000-04-26 03:50:07 +00:00
|
|
|
//-- System Cert Functions
|
|
|
|
{ "setCanEnablePrivilege", netscape_security_setCanEnablePrivilege, 2},
|
|
|
|
{ "invalidate", netscape_security_invalidate, 1},
|
1999-11-11 22:10:36 +00:00
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege,
|
|
|
|
* et. al. so that code that worked with 4.0 can still work.
|
|
|
|
*/
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSecurityNameSet::InitializeClasses(nsIScriptContext* aScriptContext)
|
|
|
|
{
|
|
|
|
JSContext *cx = (JSContext *) aScriptContext->GetNativeContext();
|
|
|
|
JSObject *global = JS_GetGlobalObject(cx);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Find Object.prototype's class by walking up the global object's
|
|
|
|
* prototype chain.
|
|
|
|
*/
|
|
|
|
JSObject *obj = global;
|
|
|
|
JSObject *proto;
|
|
|
|
while ((proto = JS_GetPrototype(cx, obj)) != nsnull)
|
|
|
|
obj = proto;
|
|
|
|
JSClass *objectClass = JS_GetClass(cx, obj);
|
|
|
|
|
|
|
|
jsval v;
|
|
|
|
if (!JS_GetProperty(cx, global, "netscape", &v))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
JSObject *securityObj;
|
|
|
|
if (JSVAL_IS_OBJECT(v)) {
|
|
|
|
/*
|
|
|
|
* "netscape" property of window object exists; must be LiveConnect
|
|
|
|
* package. Get the "security" property.
|
|
|
|
*/
|
|
|
|
obj = JSVAL_TO_OBJECT(v);
|
|
|
|
if (!JS_GetProperty(cx, obj, "security", &v) || !JSVAL_IS_OBJECT(v))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
securityObj = JSVAL_TO_OBJECT(v);
|
|
|
|
} else {
|
|
|
|
/* define netscape.security object */
|
|
|
|
obj = JS_DefineObject(cx, global, "netscape", objectClass, nsnull, 0);
|
|
|
|
if (obj == nsnull)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
securityObj = JS_DefineObject(cx, obj, "security", objectClass,
|
|
|
|
nsnull, 0);
|
|
|
|
if (securityObj == nsnull)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Define PrivilegeManager object with the necessary "static" methods. */
|
|
|
|
obj = JS_DefineObject(cx, securityObj, "PrivilegeManager", objectClass,
|
|
|
|
nsnull, 0);
|
|
|
|
if (obj == nsnull)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
return JS_DefineFunctions(cx, obj, PrivilegeManager_static_methods)
|
|
|
|
? NS_OK
|
|
|
|
: NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsSecurityNameSet::AddNameSet(nsIScriptContext* aScriptContext)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////
|
|
|
|
// nsScriptSecurityManager //
|
|
|
|
/////////////////////////////
|
|
|
|
|
1999-09-07 20:40:20 +00:00
|
|
|
////////////////////////////////////
|
|
|
|
// Methods implementing ISupports //
|
|
|
|
////////////////////////////////////
|
|
|
|
|
2000-05-03 00:04:48 +00:00
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsScriptSecurityManager,
|
2000-03-29 03:58:50 +00:00
|
|
|
nsIScriptSecurityManager,
|
|
|
|
nsIXPCSecurityManager)
|
1999-08-20 09:51:02 +00:00
|
|
|
|
1999-11-25 05:28:18 +00:00
|
|
|
inline PRBool
|
|
|
|
GetBit(unsigned char *bitVector, PRInt32 index)
|
|
|
|
{
|
|
|
|
unsigned char c = bitVector[index >> 3];
|
|
|
|
c &= (1 << (index & 7));
|
|
|
|
return c != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
SetBit(unsigned char *bitVector, PRInt32 index)
|
|
|
|
{
|
|
|
|
bitVector[index >> 3] |= (1 << (index & 7));
|
|
|
|
}
|
|
|
|
|
1999-08-20 09:51:02 +00:00
|
|
|
|
1999-09-07 20:40:20 +00:00
|
|
|
///////////////////////////////////////////////////
|
|
|
|
// Methods implementing nsIScriptSecurityManager //
|
|
|
|
///////////////////////////////////////////////////
|
1999-08-20 09:51:02 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-12-18 20:29:29 +00:00
|
|
|
nsScriptSecurityManager::CheckScriptAccess(JSContext *cx,
|
1999-11-20 07:28:34 +00:00
|
|
|
void *aObj, PRInt32 domPropInt,
|
2000-02-02 00:22:58 +00:00
|
|
|
PRBool isWrite)
|
1999-08-20 09:51:02 +00:00
|
|
|
{
|
2000-01-08 16:51:54 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal)))) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2000-01-23 04:23:14 +00:00
|
|
|
PRBool equals;
|
|
|
|
if (!principal ||
|
|
|
|
NS_SUCCEEDED(principal->Equals(mSystemPrincipal, &equals)) && equals)
|
|
|
|
{
|
|
|
|
// We have native code or the system principal: just allow access
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsCAutoString capability;
|
2000-07-05 19:08:20 +00:00
|
|
|
nsDOMProp domProp = (nsDOMProp) domPropInt;
|
2000-01-08 16:51:54 +00:00
|
|
|
PRInt32 secLevel = GetSecurityLevel(principal, domProp, isWrite,
|
2000-01-23 04:23:14 +00:00
|
|
|
capability);
|
1999-08-29 21:58:42 +00:00
|
|
|
switch (secLevel) {
|
1999-09-01 00:54:35 +00:00
|
|
|
case SCRIPT_SECURITY_ALL_ACCESS:
|
1999-08-29 21:58:42 +00:00
|
|
|
return NS_OK;
|
2000-07-05 19:08:20 +00:00
|
|
|
case SCRIPT_SECURITY_UNDEFINED_ACCESS:
|
1999-09-01 00:54:35 +00:00
|
|
|
case SCRIPT_SECURITY_SAME_DOMAIN_ACCESS: {
|
|
|
|
const char *cap = isWrite
|
|
|
|
? "UniversalBrowserWrite"
|
|
|
|
: "UniversalBrowserRead";
|
2000-02-02 00:22:58 +00:00
|
|
|
return CheckPermissions(cx, (JSObject *) aObj, cap);
|
|
|
|
}
|
|
|
|
case SCRIPT_SECURITY_CAPABILITY_ONLY: {
|
|
|
|
PRBool capabilityEnabled = PR_FALSE;
|
|
|
|
nsresult rv = IsCapabilityEnabled(capability, &capabilityEnabled);
|
|
|
|
if (NS_FAILED(rv) || !capabilityEnabled)
|
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
2000-02-03 23:28:36 +00:00
|
|
|
return NS_OK;
|
1999-09-01 00:54:35 +00:00
|
|
|
}
|
|
|
|
default:
|
1999-08-29 21:58:42 +00:00
|
|
|
// Default is no access
|
2000-02-02 00:22:58 +00:00
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
1999-08-29 21:58:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-12-18 20:29:29 +00:00
|
|
|
nsScriptSecurityManager::CheckLoadURIFromScript(JSContext *cx,
|
1999-11-16 05:07:31 +00:00
|
|
|
nsIURI *aURI)
|
1999-08-29 21:58:42 +00:00
|
|
|
{
|
2000-09-20 23:38:28 +00:00
|
|
|
// Get a context if necessary
|
|
|
|
if (!cx)
|
|
|
|
{
|
|
|
|
cx = GetCurrentContextQuick();
|
|
|
|
if (!cx)
|
|
|
|
return NS_OK; // No JS context, so allow the load
|
|
|
|
}
|
|
|
|
|
1999-11-16 05:07:31 +00:00
|
|
|
// Get principal of currently executing script.
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
if (NS_FAILED(GetSubjectPrincipal(cx, getter_AddRefs(principal)))) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
1999-12-01 22:23:22 +00:00
|
|
|
// Native code can load all URIs.
|
|
|
|
if (!principal)
|
|
|
|
return NS_OK;
|
|
|
|
|
1999-11-16 05:07:31 +00:00
|
|
|
// The system principal can load all URIs.
|
1999-12-01 22:23:22 +00:00
|
|
|
PRBool equals = PR_FALSE;
|
1999-11-16 05:07:31 +00:00
|
|
|
if (NS_FAILED(principal->Equals(mSystemPrincipal, &equals)))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (equals)
|
1999-09-15 04:05:43 +00:00
|
|
|
return NS_OK;
|
1999-11-16 05:07:31 +00:00
|
|
|
|
|
|
|
// Otherwise, principal should have a codebase that we can use to
|
|
|
|
// do the remaining tests.
|
|
|
|
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal);
|
2000-01-08 16:51:54 +00:00
|
|
|
if (!codebase)
|
1999-11-16 05:07:31 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
if (NS_FAILED(codebase->GetURI(getter_AddRefs(uri))))
|
|
|
|
return NS_ERROR_FAILURE;
|
2000-10-13 22:59:47 +00:00
|
|
|
if (NS_SUCCEEDED(CheckLoadURI(uri, aURI, nsIScriptSecurityManager::STANDARD )))
|
1999-11-16 05:07:31 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// See if we're attempting to load a file: URI. If so, let a
|
|
|
|
// UniversalFileRead capability trump the above check.
|
2001-01-31 01:33:03 +00:00
|
|
|
PRBool isFile = PR_FALSE;
|
|
|
|
PRBool isRes = PR_FALSE;
|
|
|
|
if (NS_FAILED(aURI->SchemeIs(nsIURI::FILE, &isFile)) ||
|
|
|
|
NS_FAILED(aURI->SchemeIs(nsIURI::RESOURCE, &isRes)))
|
1999-11-16 05:07:31 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2001-01-31 01:33:03 +00:00
|
|
|
if (isFile || isRes)
|
2000-01-12 01:42:37 +00:00
|
|
|
{
|
1999-11-16 05:07:31 +00:00
|
|
|
PRBool enabled;
|
|
|
|
if (NS_FAILED(IsCapabilityEnabled("UniversalFileRead", &enabled)))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (enabled)
|
|
|
|
return NS_OK;
|
1999-09-15 04:05:43 +00:00
|
|
|
}
|
|
|
|
|
1999-11-16 05:07:31 +00:00
|
|
|
// Report error.
|
|
|
|
nsXPIDLCString spec;
|
|
|
|
if (NS_FAILED(aURI->GetSpec(getter_Copies(spec))))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
JS_ReportError(cx, "illegal URL method '%s'", (const char *)spec);
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-10-13 22:59:47 +00:00
|
|
|
nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
|
|
|
|
PRUint32 aFlags)
|
1999-11-16 05:07:31 +00:00
|
|
|
{
|
2000-03-23 04:37:37 +00:00
|
|
|
nsCOMPtr<nsIJARURI> jarURI;
|
2000-10-13 22:59:47 +00:00
|
|
|
nsCOMPtr<nsIURI> sourceUri(aSourceURI);
|
|
|
|
while((jarURI = do_QueryInterface(sourceUri)))
|
|
|
|
jarURI->GetJARFile(getter_AddRefs(sourceUri));
|
|
|
|
if (!sourceUri) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsXPIDLCString sourceScheme;
|
|
|
|
if (NS_FAILED(sourceUri->GetScheme(getter_Copies(sourceScheme))))
|
2000-02-23 22:34:40 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2000-10-13 22:59:47 +00:00
|
|
|
// Some loads are not allowed from mail/news messages
|
|
|
|
if ((aFlags & nsIScriptSecurityManager::DISALLOW_FROM_MAIL) &&
|
|
|
|
(nsCRT::strcasecmp(sourceScheme, "mailbox") == 0 ||
|
|
|
|
nsCRT::strcasecmp(sourceScheme, "imap") == 0 ||
|
|
|
|
nsCRT::strcasecmp(sourceScheme, "news") == 0))
|
2000-02-23 22:34:40 +00:00
|
|
|
{
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
|
|
|
|
2000-10-13 22:59:47 +00:00
|
|
|
nsCOMPtr<nsIURI> targetUri(aTargetURI);
|
|
|
|
while((jarURI = do_QueryInterface(targetUri)))
|
|
|
|
jarURI->GetJARFile(getter_AddRefs(targetUri));
|
|
|
|
if (!targetUri) return NS_ERROR_FAILURE;
|
2000-03-23 04:37:37 +00:00
|
|
|
|
2000-10-13 22:59:47 +00:00
|
|
|
nsXPIDLCString targetScheme;
|
|
|
|
if (NS_FAILED(targetUri->GetScheme(getter_Copies(targetScheme))))
|
1999-09-01 00:54:35 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-03-21 04:05:35 +00:00
|
|
|
|
2000-10-13 22:59:47 +00:00
|
|
|
if (nsCRT::strcasecmp(targetScheme, sourceScheme) == 0)
|
2000-03-21 04:05:35 +00:00
|
|
|
{
|
2000-01-12 01:42:37 +00:00
|
|
|
// every scheme can access another URI from the same scheme
|
1999-08-29 21:58:42 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-12 01:42:37 +00:00
|
|
|
|
2000-10-13 22:59:47 +00:00
|
|
|
enum Action { AllowProtocol, DenyProtocol, PrefControlled, ChromeProtocol };
|
2000-09-07 19:03:23 +00:00
|
|
|
static const struct {
|
2000-03-11 06:32:42 +00:00
|
|
|
const char *name;
|
|
|
|
Action action;
|
|
|
|
} protocolList[] = {
|
2000-10-13 22:59:47 +00:00
|
|
|
//-- Keep the most commonly used protocols at the top of the list
|
|
|
|
// to increase performance
|
2000-03-21 04:05:35 +00:00
|
|
|
{ "http", AllowProtocol },
|
2000-10-13 22:59:47 +00:00
|
|
|
{ "file", PrefControlled },
|
2000-03-21 04:05:35 +00:00
|
|
|
{ "https", AllowProtocol },
|
2000-10-13 22:59:47 +00:00
|
|
|
{ "chrome", ChromeProtocol },
|
|
|
|
{ "mailbox", DenyProtocol },
|
|
|
|
{ "pop", AllowProtocol },
|
|
|
|
{ "imap", DenyProtocol },
|
|
|
|
{ "pop3", DenyProtocol },
|
|
|
|
{ "news", AllowProtocol },
|
|
|
|
{ "javascript", AllowProtocol },
|
|
|
|
{ "ftp", AllowProtocol },
|
|
|
|
{ "about", AllowProtocol },
|
|
|
|
{ "mailto", AllowProtocol },
|
|
|
|
{ "data", AllowProtocol },
|
2000-03-21 04:05:35 +00:00
|
|
|
{ "keyword", DenyProtocol },
|
2000-08-22 02:06:52 +00:00
|
|
|
{ "resource", DenyProtocol },
|
2000-03-21 04:05:35 +00:00
|
|
|
{ "datetime", DenyProtocol },
|
|
|
|
{ "finger", AllowProtocol },
|
2000-10-13 22:59:47 +00:00
|
|
|
{ "res", DenyProtocol }
|
2000-03-11 06:32:42 +00:00
|
|
|
};
|
|
|
|
|
2000-03-21 04:05:35 +00:00
|
|
|
for (unsigned i=0; i < sizeof(protocolList)/sizeof(protocolList[0]); i++) {
|
2000-10-13 22:59:47 +00:00
|
|
|
if (nsCRT::strcasecmp(targetScheme, protocolList[i].name) == 0) {
|
2000-06-01 23:57:48 +00:00
|
|
|
PRBool doCheck = PR_FALSE;
|
2000-03-11 06:32:42 +00:00
|
|
|
switch (protocolList[i].action) {
|
|
|
|
case AllowProtocol:
|
|
|
|
// everyone can access these schemes.
|
|
|
|
return NS_OK;
|
2000-08-22 02:06:52 +00:00
|
|
|
case PrefControlled:
|
|
|
|
// Allow access if pref is false
|
2000-07-26 04:53:01 +00:00
|
|
|
mPrefs->GetBoolPref("security.checkloaduri", &doCheck);
|
2000-08-22 02:06:52 +00:00
|
|
|
return doCheck ? NS_ERROR_DOM_BAD_URI : NS_OK;
|
2000-10-13 22:59:47 +00:00
|
|
|
case ChromeProtocol:
|
|
|
|
return (aFlags & nsIScriptSecurityManager::ALLOW_CHROME) ?
|
|
|
|
NS_OK : NS_ERROR_DOM_BAD_URI;
|
2000-03-11 06:32:42 +00:00
|
|
|
case DenyProtocol:
|
|
|
|
// Deny access
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
|
|
}
|
1999-09-07 02:54:19 +00:00
|
|
|
}
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
2000-03-11 06:32:42 +00:00
|
|
|
// If we reach here, we have an unknown protocol. Warn, but allow.
|
|
|
|
// This is risky from a security standpoint, but allows flexibility
|
|
|
|
// in installing new protocol handlers after initial ship.
|
|
|
|
NS_WARN_IF_FALSE(PR_FALSE, "unknown protocol");
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-09-01 00:54:35 +00:00
|
|
|
}
|
|
|
|
|
2000-06-21 00:21:50 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
|
|
|
|
void *aTargetObj)
|
|
|
|
{
|
2000-08-22 02:06:52 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> subject;
|
2000-06-21 00:21:50 +00:00
|
|
|
nsresult rv = GetFunctionObjectPrincipal(aCx, (JSObject *)aFunObj,
|
2000-08-22 02:06:52 +00:00
|
|
|
getter_AddRefs(subject));
|
2000-06-21 00:21:50 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// First check if the principal the function was compiled under is
|
|
|
|
// allowed to execute scripts.
|
2000-08-22 02:06:52 +00:00
|
|
|
if (!subject) {
|
2000-06-21 00:21:50 +00:00
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool result;
|
2000-08-22 02:06:52 +00:00
|
|
|
rv = CanExecuteScripts(subject, &result);
|
2000-06-21 00:21:50 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!result) {
|
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Get origin of subject and object and compare.
|
|
|
|
*/
|
|
|
|
JSObject* obj = (JSObject*)aTargetObj;
|
|
|
|
nsCOMPtr<nsIPrincipal> object;
|
|
|
|
if (NS_FAILED(GetObjectPrincipal(aCx, obj, getter_AddRefs(object))))
|
|
|
|
return NS_ERROR_FAILURE;
|
2000-08-22 02:06:52 +00:00
|
|
|
if (subject == object) {
|
2000-06-21 00:21:50 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-08-22 02:06:52 +00:00
|
|
|
PRBool isSameOrigin = PR_FALSE;
|
|
|
|
if (NS_FAILED(subject->Equals(object, &isSameOrigin)))
|
|
|
|
return NS_ERROR_FAILURE;
|
2000-06-21 00:21:50 +00:00
|
|
|
|
2000-08-22 02:06:52 +00:00
|
|
|
if (isSameOrigin)
|
|
|
|
return NS_OK;
|
2000-06-21 00:21:50 +00:00
|
|
|
|
|
|
|
// Allow access to about:blank
|
|
|
|
nsCOMPtr<nsICodebasePrincipal> objectCodebase = do_QueryInterface(object);
|
|
|
|
if (objectCodebase) {
|
|
|
|
nsXPIDLCString origin;
|
|
|
|
if (NS_FAILED(objectCodebase->GetOrigin(getter_Copies(origin))))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (nsCRT::strcasecmp(origin, "about:blank") == 0) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Access tests failed. Fail silently without a JS exception.
|
|
|
|
*/
|
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
|
|
|
}
|
1999-09-01 00:54:35 +00:00
|
|
|
|
1999-09-15 20:58:41 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetSubjectPrincipal(nsIPrincipal **result)
|
|
|
|
{
|
2000-08-22 06:02:14 +00:00
|
|
|
JSContext *cx = GetCurrentContextQuick();
|
1999-12-01 22:23:22 +00:00
|
|
|
if (!cx) {
|
|
|
|
*result = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-09-15 20:58:41 +00:00
|
|
|
return GetSubjectPrincipal(cx, result);
|
|
|
|
}
|
|
|
|
|
1999-09-01 00:54:35 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetSystemPrincipal(nsIPrincipal **result)
|
|
|
|
{
|
|
|
|
if (!mSystemPrincipal) {
|
|
|
|
mSystemPrincipal = new nsSystemPrincipal();
|
|
|
|
if (!mSystemPrincipal)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
NS_ADDREF(mSystemPrincipal);
|
|
|
|
}
|
|
|
|
*result = mSystemPrincipal;
|
|
|
|
NS_ADDREF(*result);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-01-18 21:54:01 +00:00
|
|
|
NS_IMETHODIMP
|
2000-04-26 03:50:07 +00:00
|
|
|
nsScriptSecurityManager::GetCertificatePrincipal(const char* aCertID,
|
2000-01-18 21:54:01 +00:00
|
|
|
nsIPrincipal **result)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
2000-03-21 04:05:35 +00:00
|
|
|
//-- Create a certificate principal
|
2000-01-18 21:54:01 +00:00
|
|
|
nsCertificatePrincipal *certificate = new nsCertificatePrincipal();
|
|
|
|
if (!certificate)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
NS_ADDREF(certificate);
|
2000-04-26 03:50:07 +00:00
|
|
|
if (NS_FAILED(certificate->Init(aCertID)))
|
2000-01-18 21:54:01 +00:00
|
|
|
{
|
|
|
|
NS_RELEASE(certificate);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2000-03-21 04:05:35 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface((nsBasePrincipal*)certificate, &rv);
|
2000-01-18 21:54:01 +00:00
|
|
|
NS_RELEASE(certificate);
|
2000-03-21 04:05:35 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-01-18 21:54:01 +00:00
|
|
|
|
|
|
|
if (mPrincipals) {
|
|
|
|
// Check to see if we already have this principal.
|
|
|
|
nsIPrincipalKey key(principal);
|
2000-03-21 04:05:35 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> fromTable = (nsIPrincipal *) mPrincipals->Get(&key);
|
|
|
|
if (fromTable)
|
|
|
|
principal = fromTable;
|
2000-01-18 21:54:01 +00:00
|
|
|
}
|
2000-03-21 04:05:35 +00:00
|
|
|
|
|
|
|
//-- Bundle this certificate principal into an aggregate principal
|
|
|
|
nsAggregatePrincipal* agg = new nsAggregatePrincipal();
|
|
|
|
if (!agg) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
rv = agg->SetCertificate(principal);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
principal = do_QueryInterface((nsBasePrincipal*)agg, &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-01-18 21:54:01 +00:00
|
|
|
*result = principal;
|
|
|
|
NS_ADDREF(*result);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-01-27 01:42:20 +00:00
|
|
|
nsresult
|
|
|
|
nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal **result)
|
1999-09-01 00:54:35 +00:00
|
|
|
{
|
2001-01-27 01:42:20 +00:00
|
|
|
nsresult rv = NS_OK;
|
1999-11-11 22:10:36 +00:00
|
|
|
nsCodebasePrincipal *codebase = new nsCodebasePrincipal();
|
1999-09-01 00:54:35 +00:00
|
|
|
if (!codebase)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2000-01-18 21:54:01 +00:00
|
|
|
NS_ADDREF(codebase);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (NS_FAILED(codebase->Init(aURI))) {
|
|
|
|
NS_RELEASE(codebase);
|
1999-09-01 00:54:35 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
1999-11-11 22:10:36 +00:00
|
|
|
}
|
2001-01-27 01:42:20 +00:00
|
|
|
rv = CallQueryInterface((nsBasePrincipal*)codebase, result);
|
1999-11-11 22:10:36 +00:00
|
|
|
NS_RELEASE(codebase);
|
2001-01-27 01:42:20 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI,
|
|
|
|
nsIPrincipal **result)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
rv = CreateCodebasePrincipal(aURI, getter_AddRefs(principal));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-11 22:10:36 +00:00
|
|
|
|
|
|
|
if (mPrincipals) {
|
2001-01-27 01:42:20 +00:00
|
|
|
//-- Check to see if we already have this principal.
|
1999-11-11 22:10:36 +00:00
|
|
|
nsIPrincipalKey key(principal);
|
2000-03-31 00:31:18 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> fromTable = (nsIPrincipal *) mPrincipals->Get(&key);
|
|
|
|
if (fromTable)
|
|
|
|
principal = fromTable;
|
2001-01-27 01:42:20 +00:00
|
|
|
else //-- Check to see if we have a more general principal
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsICodebasePrincipal> codebasePrin = do_QueryInterface(principal);
|
|
|
|
nsXPIDLCString originUrl;
|
|
|
|
rv = codebasePrin->GetOrigin(getter_Copies(originUrl));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsCOMPtr<nsIURI> newURI;
|
|
|
|
rv = NS_NewURI(getter_AddRefs(newURI), originUrl, nsnull);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsCOMPtr<nsIPrincipal> principal2;
|
|
|
|
rv = CreateCodebasePrincipal(newURI, getter_AddRefs(principal2));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsIPrincipalKey key2(principal2);
|
|
|
|
fromTable = (nsIPrincipal *) mPrincipals->Get(&key2);
|
|
|
|
if (fromTable)
|
|
|
|
principal = fromTable;
|
|
|
|
}
|
1999-11-11 22:10:36 +00:00
|
|
|
}
|
2000-03-31 00:31:18 +00:00
|
|
|
|
|
|
|
//-- Bundle this codebase principal into an aggregate principal
|
|
|
|
nsAggregatePrincipal* agg = new nsAggregatePrincipal();
|
|
|
|
if (!agg) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
rv = agg->SetCodebase(principal);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
principal = do_QueryInterface((nsBasePrincipal*)agg, &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
1999-11-11 22:10:36 +00:00
|
|
|
*result = principal;
|
1999-09-01 00:54:35 +00:00
|
|
|
NS_ADDREF(*result);
|
1999-08-29 21:58:42 +00:00
|
|
|
return NS_OK;
|
1999-08-20 09:51:02 +00:00
|
|
|
}
|
|
|
|
|
2000-11-30 05:32:08 +00:00
|
|
|
PRBool
|
|
|
|
nsScriptSecurityManager::EnsureNameSetRegistered()
|
|
|
|
{
|
|
|
|
// Confirm that our nameset is registered. We used to do this only when the
|
|
|
|
// secman was first created. But it turns out that it is possible for code
|
|
|
|
// to force instatiation of the security manager *before* the namespace
|
|
|
|
// registry is available. In that case we would fail to register our
|
|
|
|
// nameset and never try again. Now we keep trying until it succeeds.
|
|
|
|
|
|
|
|
if (!mNameSetRegistered) {
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIScriptNameSetRegistry, registry,
|
|
|
|
kCScriptNameSetRegistryCID, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
nsSecurityNameSet* nameSet = new nsSecurityNameSet();
|
|
|
|
if (nameSet) {
|
|
|
|
rv = registry->AddExternalNameSet(nameSet);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
mNameSetRegistered = PR_TRUE;
|
|
|
|
#ifdef DEBUG_jband
|
|
|
|
printf("##### security manager nameset registered\n");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return mNameSetRegistered;
|
|
|
|
}
|
|
|
|
|
1999-09-17 20:13:52 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CanExecuteScripts(nsIPrincipal *principal,
|
|
|
|
PRBool *result)
|
|
|
|
{
|
2000-11-30 05:32:08 +00:00
|
|
|
// XXX Really OK to fail?
|
|
|
|
// I suppose that in some embedding there may be no ScriptNameSetRegistry.
|
|
|
|
EnsureNameSetRegistered();
|
|
|
|
|
2000-01-08 16:51:54 +00:00
|
|
|
if (principal == mSystemPrincipal) {
|
|
|
|
// Even if JavaScript is disabled, we must still execute system scripts
|
|
|
|
*result = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetBit(hasDomainPolicyVector, NS_DOM_PROP_JAVASCRIPT_ENABLED)) {
|
|
|
|
// We may have a per-domain security policy for JavaScript execution
|
2000-01-23 04:23:14 +00:00
|
|
|
nsCAutoString capability;
|
2000-01-08 16:51:54 +00:00
|
|
|
PRInt32 secLevel = GetSecurityLevel(principal,
|
|
|
|
NS_DOM_PROP_JAVASCRIPT_ENABLED,
|
2000-01-23 04:23:14 +00:00
|
|
|
PR_FALSE, capability);
|
2000-01-08 16:51:54 +00:00
|
|
|
if (secLevel != SCRIPT_SECURITY_UNDEFINED_ACCESS) {
|
|
|
|
*result = (secLevel == SCRIPT_SECURITY_ALL_ACCESS);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mIsJavaScriptEnabled != mIsMailJavaScriptEnabled) {
|
|
|
|
// Is this script running from mail?
|
|
|
|
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal);
|
|
|
|
if (!codebase)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
if (NS_FAILED(codebase->GetURI(getter_AddRefs(uri))))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsXPIDLCString scheme;
|
|
|
|
if (NS_FAILED(uri->GetScheme(getter_Copies(scheme))))
|
|
|
|
return NS_ERROR_FAILURE;
|
2000-03-08 04:57:05 +00:00
|
|
|
if (nsCRT::strcasecmp(scheme, "imap") == 0 ||
|
|
|
|
nsCRT::strcasecmp(scheme, "mailbox") == 0 ||
|
|
|
|
nsCRT::strcasecmp(scheme, "news") == 0)
|
2000-01-08 16:51:54 +00:00
|
|
|
{
|
|
|
|
*result = mIsMailJavaScriptEnabled;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*result = mIsJavaScriptEnabled;
|
1999-09-17 20:13:52 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-04-14 03:14:53 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetScriptPrincipal(JSContext *cx,
|
|
|
|
JSScript *script,
|
|
|
|
nsIPrincipal **result)
|
|
|
|
{
|
|
|
|
if (!script) {
|
|
|
|
*result = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
JSPrincipals *jsp = JS_GetScriptPrincipals(cx, script);
|
|
|
|
if (!jsp) {
|
|
|
|
// Script didn't have principals -- shouldn't happen.
|
2000-01-08 16:51:54 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-04-14 03:14:53 +00:00
|
|
|
}
|
|
|
|
nsJSPrincipals *nsJSPrin = NS_STATIC_CAST(nsJSPrincipals *, jsp);
|
|
|
|
*result = nsJSPrin->nsIPrincipalPtr;
|
|
|
|
if (!result)
|
2000-01-08 16:51:54 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-04-14 03:14:53 +00:00
|
|
|
NS_ADDREF(*result);
|
|
|
|
return NS_OK;
|
2000-01-08 16:51:54 +00:00
|
|
|
|
2000-04-14 03:14:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
|
|
|
|
JSObject *obj,
|
|
|
|
nsIPrincipal **result)
|
|
|
|
{
|
|
|
|
JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, obj);
|
|
|
|
if (JS_GetFunctionObject(fun) != obj) {
|
|
|
|
// Function has been cloned; get principals from scope
|
|
|
|
return GetObjectPrincipal(cx, obj, result);
|
|
|
|
}
|
|
|
|
JSScript *script = JS_GetFunctionScript(cx, fun);
|
|
|
|
return GetScriptPrincipal(cx, script, result);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetFramePrincipal(JSContext *cx,
|
|
|
|
JSStackFrame *fp,
|
|
|
|
nsIPrincipal **result)
|
|
|
|
{
|
|
|
|
JSObject *obj = JS_GetFrameFunctionObject(cx, fp);
|
|
|
|
if (!obj) {
|
|
|
|
// Must be in a top-level script. Get principal from the script.
|
|
|
|
JSScript *script = JS_GetFrameScript(cx, fp);
|
|
|
|
return GetScriptPrincipal(cx, script, result);
|
|
|
|
}
|
|
|
|
return GetFunctionObjectPrincipal(cx, obj, result);
|
1999-09-17 20:13:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-09-15 04:05:43 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-11 22:10:36 +00:00
|
|
|
nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
|
1999-09-15 04:05:43 +00:00
|
|
|
PRBool *result)
|
|
|
|
{
|
1999-11-11 22:10:36 +00:00
|
|
|
nsresult rv;
|
|
|
|
JSStackFrame *fp = nsnull;
|
2000-08-22 06:02:14 +00:00
|
|
|
JSContext *cx = GetCurrentContextQuick();
|
1999-11-11 22:10:36 +00:00
|
|
|
fp = cx ? JS_FrameIterator(cx, &fp) : nsnull;
|
|
|
|
if (!fp) {
|
|
|
|
// No script code on stack. Allow execution.
|
|
|
|
*result = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-07-12 03:10:33 +00:00
|
|
|
|
2000-04-14 03:14:53 +00:00
|
|
|
do {
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
if (NS_FAILED(GetFramePrincipal(cx, fp, getter_AddRefs(principal)))) {
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-11-11 22:10:36 +00:00
|
|
|
}
|
2000-04-14 03:14:53 +00:00
|
|
|
if (!principal)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// First check if the principal is even able to enable the
|
|
|
|
// given capability. If not, don't look any further.
|
|
|
|
PRInt16 canEnable;
|
|
|
|
rv = principal->CanEnableCapability(capability, &canEnable);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
if (canEnable != nsIPrincipal::ENABLE_GRANTED &&
|
|
|
|
canEnable != nsIPrincipal::ENABLE_WITH_USER_PERMISSION)
|
|
|
|
{
|
|
|
|
*result = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now see if the capability is enabled.
|
|
|
|
void *annotation = JS_GetFrameAnnotation(cx, fp);
|
|
|
|
rv = principal->IsCapabilityEnabled(capability, annotation,
|
|
|
|
result);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
if (*result)
|
|
|
|
return NS_OK;
|
|
|
|
} while ((fp = JS_FrameIterator(cx, &fp)) != nsnull);
|
1999-11-11 22:10:36 +00:00
|
|
|
*result = PR_FALSE;
|
|
|
|
return NS_OK;
|
1999-09-15 04:05:43 +00:00
|
|
|
}
|
|
|
|
|
2000-04-19 21:42:30 +00:00
|
|
|
#define PROPERTIES_URL "chrome://communicator/locale/security/security.properties"
|
2000-02-10 04:56:56 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
Localize(char *genericString, nsString &result)
|
|
|
|
{
|
|
|
|
nsresult ret;
|
|
|
|
|
|
|
|
/* create a URL for the string resource file */
|
|
|
|
nsIIOService *pNetService = nsnull;
|
|
|
|
ret = nsServiceManager::GetService(kIOServiceCID, kIIOServiceIID,
|
|
|
|
(nsISupports**) &pNetService);
|
|
|
|
if (NS_FAILED(ret)) {
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING("cannot get net service\n");
|
2000-02-10 04:56:56 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
nsIURI *uri = nsnull;
|
|
|
|
ret = pNetService->NewURI(PROPERTIES_URL, nsnull, &uri);
|
|
|
|
if (NS_FAILED(ret)) {
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING("cannot create URI\n");
|
2000-02-10 04:56:56 +00:00
|
|
|
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)) {
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING("cannot create URL\n");
|
2000-02-10 04:56:56 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create a bundle for the localization */
|
|
|
|
nsIStringBundleService *pStringService = nsnull;
|
|
|
|
ret = nsServiceManager::GetService(kStringBundleServiceCID,
|
|
|
|
kIStringBundleServiceIID, (nsISupports**) &pStringService);
|
|
|
|
if (NS_FAILED(ret)) {
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING("cannot get string service\n");
|
2000-02-10 04:56:56 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
char *spec = nsnull;
|
|
|
|
ret = url->GetSpec(&spec);
|
|
|
|
if (NS_FAILED(ret)) {
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING("cannot get url spec\n");
|
2000-02-10 04:56:56 +00:00
|
|
|
nsServiceManager::ReleaseService(kStringBundleServiceCID, pStringService);
|
|
|
|
nsCRT::free(spec);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
nsILocale *locale = nsnull;
|
|
|
|
nsIStringBundle *bundle = nsnull;
|
|
|
|
ret = pStringService->CreateBundle(spec, locale, &bundle);
|
|
|
|
nsCRT::free(spec);
|
|
|
|
nsServiceManager::ReleaseService(kStringBundleServiceCID, pStringService);
|
|
|
|
if (NS_FAILED(ret)) {
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING("cannot create instance\n");
|
2000-02-10 04:56:56 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* localize the given string */
|
2000-04-01 00:39:02 +00:00
|
|
|
nsAutoString strtmp;
|
|
|
|
strtmp.AssignWithConversion(genericString);
|
|
|
|
|
2000-02-10 04:56:56 +00:00
|
|
|
PRUnichar *ptrv = nsnull;
|
|
|
|
ret = bundle->GetStringFromName(strtmp.GetUnicode(), &ptrv);
|
|
|
|
NS_RELEASE(bundle);
|
|
|
|
if (NS_FAILED(ret)) {
|
2000-10-28 22:17:53 +00:00
|
|
|
NS_WARNING("cannot get string from name\n");
|
2000-02-10 04:56:56 +00:00
|
|
|
}
|
|
|
|
result = ptrv;
|
|
|
|
nsCRT::free(ptrv);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PRBool
|
2000-09-09 00:53:21 +00:00
|
|
|
CheckConfirmDialog(JSContext* cx, const PRUnichar *szMessage, const PRUnichar *szCheckMessage,
|
2000-02-10 04:56:56 +00:00
|
|
|
PRBool *checkValue)
|
|
|
|
{
|
2000-09-09 00:53:21 +00:00
|
|
|
nsresult res;
|
|
|
|
//-- Get a prompter for the current window.
|
|
|
|
nsCOMPtr<nsIPrompt> prompter;
|
|
|
|
nsCOMPtr<nsIScriptContext> scriptContext = (nsIScriptContext*)JS_GetContextPrivate(cx);
|
|
|
|
if (scriptContext)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject = scriptContext->GetGlobalObject();
|
|
|
|
NS_ASSERTION(globalObject, "script context has no global object");
|
|
|
|
nsCOMPtr<nsIDOMWindowInternal> domWin = do_QueryInterface(globalObject);
|
|
|
|
if (domWin)
|
|
|
|
domWin->GetPrompter(getter_AddRefs(prompter));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!prompter)
|
|
|
|
{
|
|
|
|
//-- Couldn't get prompter from the current window, so get the propmt service.
|
|
|
|
NS_WITH_SERVICE(nsIPrompt, backupPrompter, kNetSupportDialogCID, &res);
|
|
|
|
if (NS_FAILED(res))
|
|
|
|
{
|
|
|
|
*checkValue = 0;
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
prompter = backupPrompter;
|
2000-02-10 04:56:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PRInt32 buttonPressed = 1; /* in case user exits dialog by clicking X */
|
|
|
|
nsAutoString yes, no, titleline;
|
|
|
|
if (NS_FAILED(res = Localize("Yes", yes)))
|
|
|
|
return PR_FALSE;
|
|
|
|
if (NS_FAILED(res = Localize("No", no)))
|
|
|
|
return PR_FALSE;
|
|
|
|
if (NS_FAILED(res = Localize("Titleline", titleline)))
|
|
|
|
return PR_FALSE;
|
|
|
|
|
2000-09-09 00:53:21 +00:00
|
|
|
res = prompter->UniversalDialog(
|
2000-02-10 04:56:56 +00:00
|
|
|
nsnull, /* title message */
|
|
|
|
titleline.GetUnicode(), /* title text in top line of window */
|
|
|
|
szMessage, /* this is the main message */
|
|
|
|
szCheckMessage, /* This is the checkbox message */
|
|
|
|
yes.GetUnicode(), /* first button text */
|
|
|
|
no.GetUnicode(), /* second button text */
|
|
|
|
nsnull, /* third button text */
|
|
|
|
nsnull, /* fourth button text */
|
|
|
|
nsnull, /* first edit field label */
|
|
|
|
nsnull, /* second edit field label */
|
|
|
|
nsnull, /* first edit field initial and final value */
|
|
|
|
nsnull, /* second edit field initial and final value */
|
|
|
|
nsnull, /* icon: question mark by default */
|
|
|
|
checkValue, /* initial and final value of checkbox */
|
|
|
|
2, /* number of buttons */
|
|
|
|
0, /* number of edit fields */
|
|
|
|
0, /* is first edit field a password field */
|
|
|
|
&buttonPressed);
|
|
|
|
|
|
|
|
if (NS_FAILED(res)) {
|
|
|
|
*checkValue = 0;
|
|
|
|
}
|
|
|
|
if (*checkValue != 0 && *checkValue != 1) {
|
|
|
|
*checkValue = 0; /* this should never happen but it is happening!!! */
|
|
|
|
}
|
|
|
|
return (buttonPressed == 0);
|
|
|
|
}
|
|
|
|
|
2000-05-16 03:40:51 +00:00
|
|
|
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);
|
2000-09-09 00:53:21 +00:00
|
|
|
JSContext *cx = GetCurrentContextQuick();
|
|
|
|
if (CheckConfirmDialog(cx, message, check.GetUnicode(), &remember))
|
2000-05-16 03:40:51 +00:00
|
|
|
*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;
|
|
|
|
}
|
|
|
|
|
2000-04-14 03:14:53 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::GetPrincipalAndFrame(JSContext *cx,
|
|
|
|
nsIPrincipal **result,
|
|
|
|
JSStackFrame **frameResult)
|
1999-10-28 22:09:03 +00:00
|
|
|
{
|
1999-11-11 22:10:36 +00:00
|
|
|
// Get principals from innermost frame of JavaScript or Java.
|
|
|
|
JSStackFrame *fp = nsnull; // tell JS_FrameIterator to start at innermost
|
2000-04-14 03:14:53 +00:00
|
|
|
for (fp = JS_FrameIterator(cx, &fp); fp; fp = JS_FrameIterator(cx, &fp)) {
|
|
|
|
if (NS_FAILED(GetFramePrincipal(cx, fp, result))) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
if (*result) {
|
1999-11-11 22:10:36 +00:00
|
|
|
*frameResult = fp;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
2000-11-07 01:14:08 +00:00
|
|
|
|
|
|
|
//-- If there's no principal on the stack, look at the global object
|
|
|
|
// and return the innermost frame for annotations.
|
|
|
|
if (cx)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIScriptContext> scriptContext =
|
|
|
|
NS_REINTERPRET_CAST(nsIScriptContext*,JS_GetContextPrivate(cx));
|
|
|
|
if (scriptContext)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> global = scriptContext->GetGlobalObject();
|
|
|
|
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
|
|
|
|
nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(global);
|
|
|
|
NS_ENSURE_TRUE(globalData, NS_ERROR_FAILURE);
|
|
|
|
globalData->GetPrincipal(result);
|
|
|
|
if (*result)
|
|
|
|
{
|
|
|
|
JSStackFrame *inner = nsnull;
|
|
|
|
*frameResult = JS_FrameIterator(cx, &inner);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-11 22:10:36 +00:00
|
|
|
*result = nsnull;
|
|
|
|
return NS_OK;
|
1999-10-28 22:09:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::EnableCapability(const char *capability)
|
1999-09-15 04:05:43 +00:00
|
|
|
{
|
2000-08-22 06:02:14 +00:00
|
|
|
JSContext *cx = GetCurrentContextQuick();
|
1999-11-11 22:10:36 +00:00
|
|
|
JSStackFrame *fp;
|
2000-08-11 03:11:24 +00:00
|
|
|
|
|
|
|
//Error checks for capability string length (200)
|
|
|
|
if(PL_strlen(capability)>200) {
|
|
|
|
static const char msg[] = "Capability name too long";
|
|
|
|
JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, msg)));
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
1999-11-11 22:10:36 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
if (NS_FAILED(GetPrincipalAndFrame(cx, getter_AddRefs(principal),
|
|
|
|
&fp)))
|
|
|
|
{
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
void *annotation = JS_GetFrameAnnotation(cx, fp);
|
|
|
|
PRBool enabled;
|
|
|
|
if (NS_FAILED(principal->IsCapabilityEnabled(capability, annotation,
|
|
|
|
&enabled)))
|
|
|
|
{
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
if (enabled)
|
|
|
|
return NS_OK;
|
2000-05-16 03:40:51 +00:00
|
|
|
|
1999-11-11 22:10:36 +00:00
|
|
|
PRInt16 canEnable;
|
2000-05-16 03:40:51 +00:00
|
|
|
if (NS_FAILED(RequestCapability(principal, capability, &canEnable)))
|
1999-11-11 22:10:36 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-05-16 03:40:51 +00:00
|
|
|
|
1999-11-11 22:10:36 +00:00
|
|
|
if (canEnable != nsIPrincipal::ENABLE_GRANTED) {
|
|
|
|
static const char msg[] = "enablePrivilege not granted";
|
|
|
|
JS_SetPendingException(cx, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, msg)));
|
|
|
|
return NS_ERROR_FAILURE; // XXX better error code?
|
|
|
|
}
|
|
|
|
if (NS_FAILED(principal->EnableCapability(capability, &annotation)))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
JS_SetFrameAnnotation(cx, fp, annotation);
|
|
|
|
return NS_OK;
|
1999-09-15 04:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-28 22:09:03 +00:00
|
|
|
nsScriptSecurityManager::RevertCapability(const char *capability)
|
1999-09-15 04:05:43 +00:00
|
|
|
{
|
2000-08-22 06:02:14 +00:00
|
|
|
JSContext *cx = GetCurrentContextQuick();
|
1999-11-11 22:10:36 +00:00
|
|
|
JSStackFrame *fp;
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
if (NS_FAILED(GetPrincipalAndFrame(cx, getter_AddRefs(principal),
|
|
|
|
&fp)))
|
|
|
|
{
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
void *annotation = JS_GetFrameAnnotation(cx, fp);
|
|
|
|
principal->RevertCapability(capability, &annotation);
|
|
|
|
JS_SetFrameAnnotation(cx, fp, annotation);
|
|
|
|
return NS_OK;
|
1999-09-15 04:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-10-28 22:09:03 +00:00
|
|
|
nsScriptSecurityManager::DisableCapability(const char *capability)
|
1999-09-15 04:05:43 +00:00
|
|
|
{
|
2000-08-22 06:02:14 +00:00
|
|
|
JSContext *cx = GetCurrentContextQuick();
|
1999-11-11 22:10:36 +00:00
|
|
|
JSStackFrame *fp;
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
if (NS_FAILED(GetPrincipalAndFrame(cx, getter_AddRefs(principal),
|
|
|
|
&fp)))
|
|
|
|
{
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
void *annotation = JS_GetFrameAnnotation(cx, fp);
|
|
|
|
principal->DisableCapability(capability, &annotation);
|
|
|
|
JS_SetFrameAnnotation(cx, fp, annotation);
|
|
|
|
return NS_OK;
|
1999-09-15 04:05:43 +00:00
|
|
|
}
|
|
|
|
|
2000-04-26 03:50:07 +00:00
|
|
|
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;
|
2000-09-13 23:57:52 +00:00
|
|
|
NS_WITH_SERVICE(nsIProperties, directoryService, NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
2000-05-16 03:40:51 +00:00
|
|
|
if (!directoryService) return NS_ERROR_FAILURE;
|
2000-08-14 22:38:27 +00:00
|
|
|
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile),
|
2000-05-16 03:40:51 +00:00
|
|
|
getter_AddRefs(systemCertFile));
|
2000-04-26 03:50:07 +00:00
|
|
|
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
2000-06-02 22:22:11 +00:00
|
|
|
#ifdef XP_MAC
|
|
|
|
// On Mac, this file will be located in the Essential Files folder
|
|
|
|
systemCertFile->Append("Essential Files");
|
|
|
|
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
|
|
|
#endif
|
2000-04-26 03:50:07 +00:00
|
|
|
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();
|
2000-05-16 03:40:51 +00:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
{
|
|
|
|
rv = systemCertJar->GetCertificatePrincipal(nsnull,
|
|
|
|
getter_AddRefs(mSystemCertificate));
|
|
|
|
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
|
|
|
}
|
2000-04-26 03:50:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-- 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)
|
|
|
|
{
|
2000-08-22 06:02:14 +00:00
|
|
|
JSContext* cx = GetCurrentContextQuick();
|
2000-04-26 03:50:07 +00:00
|
|
|
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);
|
|
|
|
}
|
1999-09-15 04:05:43 +00:00
|
|
|
|
1999-09-07 20:40:20 +00:00
|
|
|
////////////////////////////////////////////////
|
|
|
|
// Methods implementing nsIXPCSecurityManager //
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
2000-06-23 14:32:38 +00:00
|
|
|
#include "nsISecurityCheckedComponent.h"
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsScriptSecurityManager::CheckXPCCapability(JSContext *aJSContext, const char *aCapability)
|
|
|
|
{
|
|
|
|
// Check for the carte blanche before anything else.
|
|
|
|
if (aCapability) {
|
|
|
|
if (PL_strcasecmp(aCapability, "AllAccess") == 0)
|
|
|
|
return NS_OK;
|
|
|
|
else if (PL_strcasecmp(aCapability, "NoAccess") != 0) {
|
|
|
|
PRBool canAccess;
|
|
|
|
if (NS_FAILED(IsCapabilityEnabled(aCapability, &canAccess)))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (canAccess)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char msg[] = "Access to XPConnect service denied.";
|
|
|
|
JS_SetPendingException(aJSContext,
|
|
|
|
STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext, msg)));
|
|
|
|
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
|
1999-09-07 20:40:20 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CanCreateWrapper(JSContext *aJSContext,
|
|
|
|
const nsIID &aIID,
|
|
|
|
nsISupports *aObj)
|
|
|
|
{
|
2000-06-23 14:32:38 +00:00
|
|
|
// XXX could un-special-case-this
|
|
|
|
if (aIID.Equals(NS_GET_IID(nsIXPCException)))
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
rv = CheckXPCPermissions(aJSContext, aObj);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// If check fails, QI to interface that lets scomponents advertise
|
|
|
|
// their own security requirements.
|
|
|
|
nsCOMPtr<nsISecurityCheckedComponent> checkedComponent =
|
|
|
|
do_QueryInterface(aObj, &rv);
|
|
|
|
|
|
|
|
nsXPIDLCString capability;
|
|
|
|
if (NS_SUCCEEDED(rv) && checkedComponent) {
|
|
|
|
checkedComponent->CanCreateWrapper((nsIID *)&aIID,
|
|
|
|
getter_Copies(capability));
|
|
|
|
}
|
|
|
|
|
|
|
|
return CheckXPCCapability(aJSContext, capability);
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CanCreateInstance(JSContext *aJSContext,
|
|
|
|
const nsCID &aCID)
|
|
|
|
{
|
2000-06-23 14:32:38 +00:00
|
|
|
nsresult rv;
|
|
|
|
rv = CheckXPCPermissions(aJSContext, nsnull);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
static const char msg[] = "Access to XPConnect service denied.";
|
|
|
|
JS_SetPendingException(aJSContext,
|
|
|
|
STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext, msg)));
|
|
|
|
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CanGetService(JSContext *aJSContext,
|
|
|
|
const nsCID &aCID)
|
|
|
|
{
|
2000-06-23 14:32:38 +00:00
|
|
|
nsresult rv;
|
|
|
|
rv = CheckXPCPermissions(aJSContext, nsnull);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
static const char msg[] = "Access to XPConnect service denied.";
|
|
|
|
JS_SetPendingException(aJSContext,
|
|
|
|
STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext, msg)));
|
|
|
|
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Result of this function should not be freed.
|
|
|
|
static const PRUnichar *
|
|
|
|
JSIDToString(JSContext *aJSContext, const jsid id) {
|
|
|
|
jsval v;
|
|
|
|
JS_IdToValue(aJSContext, id, &v);
|
|
|
|
JSString *str = JS_ValueToString(aJSContext, v);
|
|
|
|
return NS_REINTERPRET_CAST(PRUnichar*, JS_GetStringChars(str));
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CanCallMethod(JSContext *aJSContext,
|
|
|
|
const nsIID &aIID,
|
|
|
|
nsISupports *aObj,
|
|
|
|
nsIInterfaceInfo *aInterfaceInfo,
|
|
|
|
PRUint16 aMethodIndex,
|
|
|
|
const jsid aName)
|
|
|
|
{
|
2000-06-23 14:32:38 +00:00
|
|
|
nsresult rv;
|
|
|
|
rv = CheckXPCPermissions(aJSContext, aObj);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// If check fails, QI to interface that lets scomponents advertise
|
|
|
|
// their own security requirements.
|
|
|
|
nsCOMPtr<nsISecurityCheckedComponent> checkedComponent =
|
|
|
|
do_QueryInterface(aObj, &rv);
|
|
|
|
|
|
|
|
nsXPIDLCString capability;
|
|
|
|
if (NS_SUCCEEDED(rv) && checkedComponent) {
|
|
|
|
checkedComponent->CanCallMethod((const nsIID *)&aIID,
|
|
|
|
JSIDToString(aJSContext, aName),
|
|
|
|
getter_Copies(capability));
|
|
|
|
}
|
|
|
|
|
|
|
|
return CheckXPCCapability(aJSContext, capability);
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CanGetProperty(JSContext *aJSContext,
|
|
|
|
const nsIID &aIID,
|
|
|
|
nsISupports *aObj,
|
|
|
|
nsIInterfaceInfo *aInterfaceInfo,
|
|
|
|
PRUint16 aMethodIndex,
|
|
|
|
const jsid aName)
|
|
|
|
{
|
2000-06-23 14:32:38 +00:00
|
|
|
nsresult rv;
|
|
|
|
rv = CheckXPCPermissions(aJSContext, aObj);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// If check fails, QI to interface that lets scomponents advertise
|
|
|
|
// their own security requirements.
|
|
|
|
nsCOMPtr<nsISecurityCheckedComponent> checkedComponent =
|
|
|
|
do_QueryInterface(aObj, &rv);
|
|
|
|
|
|
|
|
nsXPIDLCString capability;
|
|
|
|
if (NS_SUCCEEDED(rv) && checkedComponent) {
|
|
|
|
checkedComponent->CanGetProperty((const nsIID *)&aIID,
|
|
|
|
JSIDToString(aJSContext, aName),
|
|
|
|
getter_Copies(capability));
|
|
|
|
}
|
|
|
|
|
|
|
|
return CheckXPCCapability(aJSContext, capability);
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CanSetProperty(JSContext *aJSContext,
|
|
|
|
const nsIID &aIID,
|
|
|
|
nsISupports *aObj,
|
|
|
|
nsIInterfaceInfo *aInterfaceInfo,
|
|
|
|
PRUint16 aMethodIndex,
|
|
|
|
const jsid aName)
|
|
|
|
{
|
2000-06-23 14:32:38 +00:00
|
|
|
nsresult rv;
|
|
|
|
rv = CheckXPCPermissions(aJSContext, aObj);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// If check fails, QI to interface that lets scomponents advertise
|
|
|
|
// their own security requirements.
|
|
|
|
nsCOMPtr<nsISecurityCheckedComponent> checkedComponent =
|
|
|
|
do_QueryInterface(aObj, &rv);
|
|
|
|
|
|
|
|
nsXPIDLCString capability;
|
|
|
|
if (NS_SUCCEEDED(rv) && checkedComponent) {
|
|
|
|
checkedComponent->CanSetProperty((const nsIID *)&aIID,
|
|
|
|
JSIDToString(aJSContext, aName),
|
|
|
|
getter_Copies(capability));
|
|
|
|
}
|
|
|
|
|
|
|
|
return CheckXPCCapability(aJSContext, capability);
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
|
|
// Other methods //
|
|
|
|
///////////////////
|
|
|
|
|
2000-07-26 04:53:01 +00:00
|
|
|
|
1999-09-07 20:40:20 +00:00
|
|
|
nsScriptSecurityManager::nsScriptSecurityManager(void)
|
2000-07-26 04:53:01 +00:00
|
|
|
: mOriginToPolicyMap(nsnull),
|
2000-01-23 04:23:14 +00:00
|
|
|
mSystemPrincipal(nsnull), mPrincipals(nsnull),
|
|
|
|
mIsJavaScriptEnabled(PR_FALSE),
|
2000-02-10 04:56:56 +00:00
|
|
|
mIsMailJavaScriptEnabled(PR_FALSE),
|
2000-11-30 05:32:08 +00:00
|
|
|
mIsWritingPrefs(PR_FALSE),
|
|
|
|
mNameSetRegistered(PR_FALSE)
|
|
|
|
|
1999-09-07 20:40:20 +00:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
1999-11-25 05:28:18 +00:00
|
|
|
memset(hasDomainPolicyVector, 0, sizeof(hasDomainPolicyVector));
|
2000-07-26 04:53:01 +00:00
|
|
|
InitPrefs();
|
2000-09-13 23:57:52 +00:00
|
|
|
mThreadJSContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsScriptSecurityManager::~nsScriptSecurityManager(void)
|
|
|
|
{
|
1999-11-16 05:07:31 +00:00
|
|
|
delete mOriginToPolicyMap;
|
1999-11-11 22:10:36 +00:00
|
|
|
NS_IF_RELEASE(mSystemPrincipal);
|
|
|
|
delete mPrincipals;
|
1999-09-07 20:40:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsScriptSecurityManager *
|
|
|
|
nsScriptSecurityManager::GetScriptSecurityManager()
|
|
|
|
{
|
|
|
|
static nsScriptSecurityManager *ssecMan = NULL;
|
1999-10-28 22:09:03 +00:00
|
|
|
if (!ssecMan) {
|
1999-09-07 20:40:20 +00:00
|
|
|
ssecMan = new nsScriptSecurityManager();
|
2000-01-26 08:38:10 +00:00
|
|
|
if (!ssecMan)
|
|
|
|
return NULL;
|
2000-11-30 05:32:08 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Try to register the nameset. This can sometimes fail on first run
|
|
|
|
// when the nameset service is not yet available at the time when
|
|
|
|
// the script security manager is created. That is OK. We will try
|
|
|
|
// again when CanExecuteSCripts is called if necessary.
|
|
|
|
ssecMan->EnsureNameSetRegistered();
|
2000-01-26 08:38:10 +00:00
|
|
|
|
|
|
|
NS_WITH_SERVICE(nsIXPConnect, xpc, nsIXPConnect::GetCID(), &rv);
|
|
|
|
if (NS_SUCCEEDED(rv) && xpc) {
|
|
|
|
rv = xpc->SetDefaultSecurityManager(
|
|
|
|
NS_STATIC_CAST(nsIXPCSecurityManager*, ssecMan),
|
2000-02-11 04:18:39 +00:00
|
|
|
nsIXPCSecurityManager::HOOK_ALL);
|
2000-01-26 08:38:10 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_WARNING("failed to install xpconnect security manager!");
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
#ifdef DEBUG_jband
|
2000-01-26 08:38:10 +00:00
|
|
|
else {
|
2000-10-28 22:17:53 +00:00
|
|
|
printf("!!!!! xpc security manager registered\n");
|
2000-01-26 08:38:10 +00:00
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
#endif
|
2000-01-26 08:38:10 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
NS_WARNING("can't get xpconnect to install security manager!");
|
|
|
|
}
|
1999-10-28 22:09:03 +00:00
|
|
|
}
|
1999-09-07 20:40:20 +00:00
|
|
|
return ssecMan;
|
|
|
|
}
|
|
|
|
|
1999-08-20 09:51:02 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-11 22:10:36 +00:00
|
|
|
nsScriptSecurityManager::GetSubjectPrincipal(JSContext *cx,
|
1999-08-29 21:58:42 +00:00
|
|
|
nsIPrincipal **result)
|
1999-08-20 09:51:02 +00:00
|
|
|
{
|
1999-08-29 21:58:42 +00:00
|
|
|
JSStackFrame *fp;
|
1999-12-01 22:23:22 +00:00
|
|
|
return GetPrincipalAndFrame(cx, result, &fp);
|
1999-08-20 09:51:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-08-29 21:58:42 +00:00
|
|
|
nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
|
|
|
|
nsIPrincipal **result)
|
1999-08-20 09:51:02 +00:00
|
|
|
{
|
2000-01-26 15:33:57 +00:00
|
|
|
JSObject *parent = aObj;
|
|
|
|
do {
|
|
|
|
JSClass *jsClass = JS_GetClass(aCx, parent);
|
2000-01-27 15:59:34 +00:00
|
|
|
const uint32 privateNsISupports = JSCLASS_HAS_PRIVATE |
|
|
|
|
JSCLASS_PRIVATE_IS_NSISUPPORTS;
|
2000-01-26 15:33:57 +00:00
|
|
|
if (jsClass && (jsClass->flags & (privateNsISupports)) ==
|
|
|
|
privateNsISupports)
|
|
|
|
{
|
2000-08-16 04:01:02 +00:00
|
|
|
nsCOMPtr<nsISupports> supports = (nsISupports *) JS_GetPrivate(aCx, parent);
|
2000-01-26 15:33:57 +00:00
|
|
|
nsCOMPtr<nsIScriptObjectPrincipal> objPrin =
|
|
|
|
do_QueryInterface(supports);
|
2000-08-16 04:01:02 +00:00
|
|
|
if (!objPrin) {
|
|
|
|
/*
|
|
|
|
* If it's a wrapped native, check the underlying native
|
|
|
|
* instead.
|
|
|
|
*/
|
|
|
|
nsCOMPtr<nsIXPConnectWrappedNative> xpcNative =
|
|
|
|
do_QueryInterface(supports);
|
|
|
|
if (xpcNative)
|
|
|
|
xpcNative->GetNative(getter_AddRefs(supports));
|
|
|
|
objPrin = do_QueryInterface(supports);
|
|
|
|
}
|
|
|
|
|
2000-01-26 15:33:57 +00:00
|
|
|
if (objPrin && NS_SUCCEEDED(objPrin->GetPrincipal(result)))
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
parent = JS_GetParent(aCx, parent);
|
|
|
|
} while (parent);
|
|
|
|
|
|
|
|
// Couldn't find a principal for this object.
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-08-20 09:51:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj,
|
2000-02-02 00:22:58 +00:00
|
|
|
const char *aCapability)
|
1999-08-20 09:51:02 +00:00
|
|
|
{
|
1999-09-01 00:54:35 +00:00
|
|
|
/*
|
|
|
|
** Get origin of subject and object and compare.
|
|
|
|
*/
|
1999-08-29 21:58:42 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> subject;
|
1999-09-09 13:47:16 +00:00
|
|
|
if (NS_FAILED(GetSubjectPrincipal(aCx, getter_AddRefs(subject))))
|
1999-08-29 21:58:42 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPrincipal> object;
|
|
|
|
if (NS_FAILED(GetObjectPrincipal(aCx, aObj, getter_AddRefs(object))))
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-09-15 04:05:43 +00:00
|
|
|
if (subject == object) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-08-29 21:58:42 +00:00
|
|
|
|
2000-08-22 02:06:52 +00:00
|
|
|
PRBool isSameOrigin = PR_FALSE;
|
|
|
|
if (NS_FAILED(subject->Equals(object, &isSameOrigin)))
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
if (isSameOrigin)
|
|
|
|
return NS_OK;
|
1999-08-29 21:58:42 +00:00
|
|
|
|
2000-01-11 22:02:06 +00:00
|
|
|
// Allow access to about:blank
|
|
|
|
nsCOMPtr<nsICodebasePrincipal> objectCodebase = do_QueryInterface(object);
|
|
|
|
if (objectCodebase) {
|
|
|
|
nsXPIDLCString origin;
|
|
|
|
if (NS_FAILED(objectCodebase->GetOrigin(getter_Copies(origin))))
|
|
|
|
return NS_ERROR_FAILURE;
|
2000-03-08 04:57:05 +00:00
|
|
|
if (nsCRT::strcasecmp(origin, "about:blank") == 0) {
|
2000-01-11 22:02:06 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-08-20 09:51:02 +00:00
|
|
|
/*
|
|
|
|
** If we failed the origin tests it still might be the case that we
|
1999-08-29 21:58:42 +00:00
|
|
|
** are a signed script and have permissions to do this operation.
|
1999-08-20 09:51:02 +00:00
|
|
|
** Check for that here
|
|
|
|
*/
|
2000-02-02 00:22:58 +00:00
|
|
|
PRBool capabilityEnabled = PR_FALSE;
|
|
|
|
if (NS_FAILED(IsCapabilityEnabled(aCapability, &capabilityEnabled)))
|
1999-09-01 00:54:35 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
2000-02-02 00:22:58 +00:00
|
|
|
if (capabilityEnabled)
|
1999-09-01 00:54:35 +00:00
|
|
|
return NS_OK;
|
1999-08-20 09:51:02 +00:00
|
|
|
|
1999-09-01 00:54:35 +00:00
|
|
|
/*
|
|
|
|
** Access tests failed, so now report error.
|
|
|
|
*/
|
1999-12-02 05:41:17 +00:00
|
|
|
char *str;
|
2000-02-10 04:56:56 +00:00
|
|
|
if (NS_FAILED(subject->ToUserVisibleString(&str)))
|
1999-08-29 21:58:42 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
1999-10-02 03:41:37 +00:00
|
|
|
JS_ReportError(aCx, "access disallowed from scripts at %s to documents "
|
1999-12-02 05:41:17 +00:00
|
|
|
"at another domain", str);
|
|
|
|
nsCRT::free(str);
|
1999-10-02 03:41:37 +00:00
|
|
|
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
1999-08-20 09:51:02 +00:00
|
|
|
}
|
|
|
|
|
1999-08-29 21:58:42 +00:00
|
|
|
PRInt32
|
2000-01-08 16:51:54 +00:00
|
|
|
nsScriptSecurityManager::GetSecurityLevel(nsIPrincipal *principal,
|
|
|
|
nsDOMProp domProp,
|
2000-01-23 04:23:14 +00:00
|
|
|
PRBool isWrite,
|
|
|
|
nsCString &capability)
|
1999-08-20 09:51:02 +00:00
|
|
|
{
|
2000-01-23 04:23:14 +00:00
|
|
|
nsCAutoString prefName;
|
|
|
|
if (NS_FAILED(GetPrefName(principal, domProp, prefName)))
|
1999-08-29 21:58:42 +00:00
|
|
|
return SCRIPT_SECURITY_NO_ACCESS;
|
|
|
|
PRInt32 secLevel;
|
|
|
|
char *secLevelString;
|
1999-10-12 22:51:54 +00:00
|
|
|
nsresult rv;
|
2000-07-26 04:53:01 +00:00
|
|
|
rv = mSecurityPrefs->SecurityGetCharPref(prefName, &secLevelString);
|
1999-11-11 22:10:36 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2000-01-23 04:23:14 +00:00
|
|
|
prefName += (isWrite ? ".write" : ".read");
|
2000-07-26 04:53:01 +00:00
|
|
|
rv = mSecurityPrefs->SecurityGetCharPref(prefName, &secLevelString);
|
1999-11-11 22:10:36 +00:00
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rv) && secLevelString) {
|
1999-08-29 21:58:42 +00:00
|
|
|
if (PL_strcmp(secLevelString, "sameOrigin") == 0)
|
|
|
|
secLevel = SCRIPT_SECURITY_SAME_DOMAIN_ACCESS;
|
1999-09-15 04:05:43 +00:00
|
|
|
else if (PL_strcmp(secLevelString, "allAccess") == 0)
|
1999-08-29 21:58:42 +00:00
|
|
|
secLevel = SCRIPT_SECURITY_ALL_ACCESS;
|
1999-09-15 04:05:43 +00:00
|
|
|
else if (PL_strcmp(secLevelString, "noAccess") == 0)
|
1999-08-29 21:58:42 +00:00
|
|
|
secLevel = SCRIPT_SECURITY_NO_ACCESS;
|
1999-11-11 22:10:36 +00:00
|
|
|
else {
|
|
|
|
// string should be the name of a capability
|
2000-01-23 04:23:14 +00:00
|
|
|
capability = secLevelString;
|
1999-11-11 22:10:36 +00:00
|
|
|
secLevelString = nsnull;
|
|
|
|
secLevel = SCRIPT_SECURITY_CAPABILITY_ONLY;
|
|
|
|
}
|
|
|
|
if (secLevelString)
|
|
|
|
PR_Free(secLevelString);
|
1999-08-29 21:58:42 +00:00
|
|
|
return secLevel;
|
1999-08-20 09:51:02 +00:00
|
|
|
}
|
2000-01-08 16:51:54 +00:00
|
|
|
return SCRIPT_SECURITY_UNDEFINED_ACCESS;
|
1999-08-20 09:51:02 +00:00
|
|
|
}
|
|
|
|
|
1999-09-07 02:54:19 +00:00
|
|
|
NS_IMETHODIMP
|
2000-05-17 02:38:22 +00:00
|
|
|
nsScriptSecurityManager::CheckXPCPermissions(JSContext *aJSContext,
|
|
|
|
nsISupports* aObj)
|
1999-09-07 02:54:19 +00:00
|
|
|
{
|
2000-05-17 02:38:22 +00:00
|
|
|
NS_ASSERTION(mPrefs,"nsScriptSecurityManager::mPrefs not initialized");
|
1999-09-07 02:54:19 +00:00
|
|
|
PRBool ok = PR_FALSE;
|
1999-11-11 22:10:36 +00:00
|
|
|
if (NS_FAILED(IsCapabilityEnabled("UniversalXPConnect", &ok)))
|
1999-10-25 22:22:16 +00:00
|
|
|
ok = PR_FALSE;
|
1999-09-07 02:54:19 +00:00
|
|
|
if (!ok) {
|
2000-05-17 02:38:22 +00:00
|
|
|
//-- If user allows scripting of plugins by untrusted scripts,
|
|
|
|
// and the target object is a plugin, allow the access anyway.
|
|
|
|
if(aObj)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIPluginInstance> plugin = do_QueryInterface(aObj, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
{
|
|
|
|
PRBool allow = PR_FALSE;
|
|
|
|
//XXX May want to store the value of the pref in a local,
|
|
|
|
// this will help performance when dealing with plugins.
|
2000-07-26 04:53:01 +00:00
|
|
|
rv = mPrefs->GetBoolPref("security.xpconnect.plugin.unrestricted", &allow);
|
2000-05-17 02:38:22 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && allow)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
1999-10-02 03:41:37 +00:00
|
|
|
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
1999-09-07 02:54:19 +00:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-01-06 00:59:18 +00:00
|
|
|
static char *domPropNames[] = {
|
|
|
|
NS_DOM_PROP_NAMES
|
1999-11-11 22:10:36 +00:00
|
|
|
};
|
1999-09-15 04:05:43 +00:00
|
|
|
|
2000-02-03 23:28:36 +00:00
|
|
|
struct nsDomainEntry {
|
|
|
|
nsDomainEntry(const char *anOrigin, const char *aPolicy,
|
|
|
|
int aPolicyLength)
|
|
|
|
: mNext(nsnull), mOrigin(anOrigin), mPolicy(aPolicy, aPolicyLength)
|
|
|
|
{ }
|
|
|
|
PRBool Matches(const char *anOrigin) {
|
|
|
|
int len = nsCRT::strlen(anOrigin);
|
|
|
|
int thisLen = mOrigin.Length();
|
|
|
|
if (len < thisLen)
|
|
|
|
return PR_FALSE;
|
2000-10-24 00:52:02 +00:00
|
|
|
if (mOrigin.RFindChar(':', PR_FALSE, thisLen-1, 1) != -1)
|
|
|
|
//-- Policy applies to all URLs of this scheme, compare scheme only
|
|
|
|
return mOrigin.EqualsWithConversion(anOrigin, PR_TRUE, thisLen);
|
|
|
|
|
|
|
|
//-- Policy applies to a particular host; compare scheme://host.domain
|
2000-09-03 06:41:18 +00:00
|
|
|
if (!mOrigin.Equals(anOrigin + (len - thisLen)))
|
2000-02-03 23:28:36 +00:00
|
|
|
return PR_FALSE;
|
|
|
|
if (len == thisLen)
|
|
|
|
return PR_TRUE;
|
|
|
|
char charBefore = anOrigin[len-thisLen-1];
|
|
|
|
return (charBefore == '.' || charBefore == ':' || charBefore == '/');
|
|
|
|
}
|
|
|
|
nsDomainEntry *mNext;
|
|
|
|
nsCString mOrigin;
|
|
|
|
nsCString mPolicy;
|
|
|
|
};
|
|
|
|
|
1999-11-20 07:28:34 +00:00
|
|
|
NS_IMETHODIMP
|
2000-01-23 04:23:14 +00:00
|
|
|
nsScriptSecurityManager::GetPrefName(nsIPrincipal *principal,
|
|
|
|
nsDOMProp domProp, nsCString &result)
|
1999-11-20 07:28:34 +00:00
|
|
|
{
|
|
|
|
static const char *defaultStr = "default";
|
2000-07-26 04:53:01 +00:00
|
|
|
result = "capability.policy.";
|
1999-11-25 05:28:18 +00:00
|
|
|
if (!GetBit(hasDomainPolicyVector, domProp)) {
|
2000-01-23 04:23:14 +00:00
|
|
|
result += defaultStr;
|
1999-11-25 05:28:18 +00:00
|
|
|
} else {
|
1999-12-01 22:23:22 +00:00
|
|
|
PRBool equals = PR_TRUE;
|
|
|
|
if (principal && NS_FAILED(principal->Equals(mSystemPrincipal, &equals)))
|
1999-11-20 07:28:34 +00:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
if (equals) {
|
2000-01-23 04:23:14 +00:00
|
|
|
result += defaultStr;
|
1999-11-20 07:28:34 +00:00
|
|
|
} else {
|
2000-01-23 04:23:14 +00:00
|
|
|
nsCOMPtr<nsICodebasePrincipal> codebase = do_QueryInterface(principal);
|
|
|
|
if (!codebase)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nsresult rv;
|
1999-11-20 07:28:34 +00:00
|
|
|
nsXPIDLCString origin;
|
|
|
|
if (NS_FAILED(rv = codebase->GetOrigin(getter_Copies(origin))))
|
|
|
|
return rv;
|
|
|
|
nsCString *policy = nsnull;
|
|
|
|
if (mOriginToPolicyMap) {
|
2000-02-03 23:28:36 +00:00
|
|
|
const char *s = origin;
|
|
|
|
const char *nextToLastDot = nsnull;
|
|
|
|
const char *lastDot = nsnull;
|
2000-10-24 00:52:02 +00:00
|
|
|
const char *colon = nsnull;
|
2000-02-03 23:28:36 +00:00
|
|
|
const char *p = s;
|
|
|
|
while (*p) {
|
|
|
|
if (*p == '.') {
|
|
|
|
nextToLastDot = lastDot;
|
|
|
|
lastDot = p;
|
|
|
|
}
|
2000-10-24 00:52:02 +00:00
|
|
|
if (!colon && *p == ':')
|
|
|
|
colon = p;
|
2000-02-03 23:28:36 +00:00
|
|
|
p++;
|
|
|
|
}
|
2000-08-10 06:19:37 +00:00
|
|
|
nsCStringKey key(nextToLastDot ? nextToLastDot+1 : s);
|
2000-02-03 23:28:36 +00:00
|
|
|
nsDomainEntry *de = (nsDomainEntry *) mOriginToPolicyMap->Get(&key);
|
2000-10-24 00:52:02 +00:00
|
|
|
if (!de)
|
|
|
|
{
|
|
|
|
nsCAutoString scheme(s, colon-s+1);
|
|
|
|
nsCStringKey schemeKey(scheme);
|
|
|
|
de = (nsDomainEntry *) mOriginToPolicyMap->Get(&schemeKey);
|
|
|
|
}
|
2000-02-03 23:28:36 +00:00
|
|
|
while (de) {
|
|
|
|
if (de->Matches(s)) {
|
|
|
|
policy = &de->mPolicy;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
de = de->mNext;
|
|
|
|
}
|
1999-11-20 07:28:34 +00:00
|
|
|
}
|
|
|
|
if (policy)
|
2000-01-23 04:23:14 +00:00
|
|
|
result += *policy;
|
1999-11-20 07:28:34 +00:00
|
|
|
else
|
2000-01-23 04:23:14 +00:00
|
|
|
result += defaultStr;
|
1999-11-20 07:28:34 +00:00
|
|
|
}
|
|
|
|
}
|
2000-01-23 04:23:14 +00:00
|
|
|
result += '.';
|
|
|
|
result += domPropNames[domProp];
|
|
|
|
return NS_OK;
|
1999-11-20 07:28:34 +00:00
|
|
|
}
|
|
|
|
|
2000-05-16 03:40:51 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsScriptSecurityManager::SavePrincipal(nsIPrincipal* aToSave)
|
|
|
|
{
|
2000-07-26 04:53:01 +00:00
|
|
|
NS_ASSERTION(mSecurityPrefs, "nsScriptSecurityManager::mSecurityPrefs not initialized");
|
2000-05-16 03:40:51 +00:00
|
|
|
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;
|
|
|
|
|
2000-07-20 01:16:15 +00:00
|
|
|
mIsWritingPrefs = PR_TRUE;
|
2000-05-16 03:40:51 +00:00
|
|
|
if (grantedList)
|
2000-07-26 04:53:01 +00:00
|
|
|
mSecurityPrefs->SecuritySetCharPref(grantedPrefName, grantedList);
|
2000-05-16 03:40:51 +00:00
|
|
|
else
|
2000-07-26 04:53:01 +00:00
|
|
|
mSecurityPrefs->SecurityClearUserPref(grantedPrefName);
|
2000-05-16 03:40:51 +00:00
|
|
|
|
|
|
|
if (deniedList)
|
2000-07-26 04:53:01 +00:00
|
|
|
mSecurityPrefs->SecuritySetCharPref(deniedPrefName, deniedList);
|
2000-05-16 03:40:51 +00:00
|
|
|
else
|
2000-07-26 04:53:01 +00:00
|
|
|
mSecurityPrefs->SecurityClearUserPref(deniedPrefName);
|
2000-05-16 03:40:51 +00:00
|
|
|
|
|
|
|
if (grantedList || deniedList)
|
2000-07-26 04:53:01 +00:00
|
|
|
mSecurityPrefs->SecuritySetCharPref(idPrefName, id);
|
2000-05-16 03:40:51 +00:00
|
|
|
else
|
2000-07-26 04:53:01 +00:00
|
|
|
mSecurityPrefs->SecurityClearUserPref(idPrefName);
|
2000-05-16 03:40:51 +00:00
|
|
|
|
2000-07-20 01:16:15 +00:00
|
|
|
mIsWritingPrefs = PR_FALSE;
|
2000-05-16 03:40:51 +00:00
|
|
|
return mPrefs->SavePrefFile();
|
|
|
|
}
|
|
|
|
|
1999-11-20 07:28:34 +00:00
|
|
|
static nsDOMProp
|
1999-11-11 22:10:36 +00:00
|
|
|
findDomProp(const char *propName, int n)
|
1999-10-28 22:09:03 +00:00
|
|
|
{
|
1999-11-11 22:10:36 +00:00
|
|
|
int hi = sizeof(domPropNames)/sizeof(domPropNames[0]) - 1;
|
|
|
|
int lo = 0;
|
|
|
|
do {
|
|
|
|
int mid = (hi + lo) / 2;
|
|
|
|
int cmp = PL_strncmp(propName, domPropNames[mid], n);
|
2000-02-11 04:18:39 +00:00
|
|
|
if (cmp == 0) {
|
|
|
|
if (domPropNames[mid][n] == '\0')
|
|
|
|
return (nsDOMProp) mid;
|
|
|
|
cmp = -1;
|
|
|
|
}
|
1999-11-11 22:10:36 +00:00
|
|
|
if (cmp < 0)
|
|
|
|
hi = mid - 1;
|
|
|
|
else
|
|
|
|
lo = mid + 1;
|
|
|
|
} while (hi > lo);
|
2000-02-11 04:18:39 +00:00
|
|
|
if (PL_strncmp(propName, domPropNames[lo], n) == 0 &&
|
|
|
|
domPropNames[lo][n] == '\0')
|
|
|
|
{
|
1999-11-20 07:28:34 +00:00
|
|
|
return (nsDOMProp) lo;
|
2000-02-11 04:18:39 +00:00
|
|
|
}
|
1999-11-20 07:28:34 +00:00
|
|
|
return NS_DOM_PROP_MAX;
|
1999-10-28 22:09:03 +00:00
|
|
|
}
|
|
|
|
|
1999-11-16 05:07:31 +00:00
|
|
|
PR_STATIC_CALLBACK(PRBool)
|
|
|
|
DeleteEntry(nsHashKey *aKey, void *aData, void* closure)
|
|
|
|
{
|
2000-02-03 23:28:36 +00:00
|
|
|
nsDomainEntry *entry = (nsDomainEntry *) aData;
|
|
|
|
do {
|
|
|
|
nsDomainEntry *next = entry->mNext;
|
|
|
|
delete entry;
|
|
|
|
entry = next;
|
|
|
|
} while (entry);
|
1999-11-16 05:07:31 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
1999-11-25 05:28:18 +00:00
|
|
|
void
|
2000-02-10 04:56:56 +00:00
|
|
|
nsScriptSecurityManager::EnumeratePolicyCallback(const char *prefName,
|
1999-11-25 05:28:18 +00:00
|
|
|
void *data)
|
|
|
|
{
|
1999-11-11 22:10:36 +00:00
|
|
|
if (!prefName || !*prefName)
|
|
|
|
return;
|
2000-05-26 23:28:40 +00:00
|
|
|
|
2000-01-23 04:23:14 +00:00
|
|
|
nsScriptSecurityManager *mgr = (nsScriptSecurityManager *) data;
|
1999-11-12 03:07:37 +00:00
|
|
|
unsigned count = 0;
|
1999-11-11 22:10:36 +00:00
|
|
|
const char *dots[5];
|
1999-11-11 23:07:14 +00:00
|
|
|
const char *p;
|
|
|
|
for (p=prefName; *p; p++) {
|
1999-11-11 22:10:36 +00:00
|
|
|
if (*p == '.') {
|
|
|
|
dots[count++] = p;
|
|
|
|
if (count == sizeof(dots)/sizeof(dots[0]))
|
|
|
|
break;
|
|
|
|
}
|
1999-09-15 04:05:43 +00:00
|
|
|
}
|
1999-11-11 22:10:36 +00:00
|
|
|
if (count < sizeof(dots)/sizeof(dots[0]))
|
|
|
|
dots[count] = p;
|
1999-11-16 05:07:31 +00:00
|
|
|
if (count < 3)
|
|
|
|
return;
|
|
|
|
const char *policyName = dots[1] + 1;
|
|
|
|
int policyLength = dots[2] - policyName;
|
|
|
|
PRBool isDefault = PL_strncmp("default", policyName, policyLength) == 0;
|
|
|
|
if (!isDefault && count == 3) {
|
2000-07-26 04:53:01 +00:00
|
|
|
// capability.policy.<policyname>.sites
|
1999-11-16 05:07:31 +00:00
|
|
|
const char *sitesName = dots[2] + 1;
|
|
|
|
int sitesLength = dots[3] - sitesName;
|
|
|
|
if (PL_strncmp("sites", sitesName, sitesLength) == 0) {
|
2000-01-23 04:23:14 +00:00
|
|
|
if (!mgr->mOriginToPolicyMap) {
|
|
|
|
mgr->mOriginToPolicyMap =
|
1999-11-16 05:07:31 +00:00
|
|
|
new nsObjectHashtable(nsnull, nsnull, DeleteEntry, nsnull);
|
2000-01-23 04:23:14 +00:00
|
|
|
if (!mgr->mOriginToPolicyMap)
|
1999-11-16 05:07:31 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
char *s;
|
2000-07-26 04:53:01 +00:00
|
|
|
if (NS_FAILED(mgr->mSecurityPrefs->SecurityGetCharPref(prefName, &s)))
|
1999-11-16 05:07:31 +00:00
|
|
|
return;
|
|
|
|
char *q=s;
|
|
|
|
char *r=s;
|
2000-02-03 23:28:36 +00:00
|
|
|
char *lastDot = nsnull;
|
|
|
|
char *nextToLastDot = nsnull;
|
1999-11-16 05:07:31 +00:00
|
|
|
PRBool working = PR_TRUE;
|
|
|
|
while (working) {
|
|
|
|
if (*r == ' ' || *r == '\0') {
|
|
|
|
working = (*r != '\0');
|
|
|
|
*r = '\0';
|
2000-08-10 06:19:37 +00:00
|
|
|
nsCStringKey key(nextToLastDot ? nextToLastDot+1 : q);
|
2000-02-03 23:28:36 +00:00
|
|
|
nsDomainEntry *value = new nsDomainEntry(q, policyName,
|
|
|
|
policyLength);
|
1999-11-16 05:07:31 +00:00
|
|
|
if (!value)
|
|
|
|
break;
|
2000-02-03 23:28:36 +00:00
|
|
|
nsDomainEntry *de = (nsDomainEntry *)
|
|
|
|
mgr->mOriginToPolicyMap->Get(&key);
|
|
|
|
if (!de) {
|
|
|
|
mgr->mOriginToPolicyMap->Put(&key, value);
|
|
|
|
} else {
|
|
|
|
if (de->Matches(q)) {
|
|
|
|
value->mNext = de;
|
|
|
|
mgr->mOriginToPolicyMap->Put(&key, value);
|
|
|
|
} else {
|
|
|
|
while (de->mNext) {
|
|
|
|
if (de->mNext->Matches(q)) {
|
|
|
|
value->mNext = de->mNext;
|
|
|
|
de->mNext = value;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
de = de->mNext;
|
|
|
|
}
|
|
|
|
if (!de->mNext) {
|
|
|
|
de->mNext = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-11-16 05:07:31 +00:00
|
|
|
q = r + 1;
|
2000-02-03 23:28:36 +00:00
|
|
|
lastDot = nextToLastDot = nsnull;
|
|
|
|
} else if (*r == '.') {
|
|
|
|
nextToLastDot = lastDot;
|
|
|
|
lastDot = r;
|
1999-11-16 05:07:31 +00:00
|
|
|
}
|
|
|
|
r++;
|
|
|
|
}
|
|
|
|
PR_Free(s);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (count >= 4) {
|
2000-07-26 04:53:01 +00:00
|
|
|
// capability.policy.<policyname>.<object>.<property>[.read|.write]
|
1999-11-11 22:10:36 +00:00
|
|
|
const char *domPropName = dots[2] + 1;
|
|
|
|
int domPropLength = dots[4] - domPropName;
|
1999-11-20 07:28:34 +00:00
|
|
|
nsDOMProp domProp = findDomProp(domPropName, domPropLength);
|
|
|
|
if (domProp < NS_DOM_PROP_MAX) {
|
2000-07-05 19:08:20 +00:00
|
|
|
if (!isDefault)
|
2000-01-23 04:23:14 +00:00
|
|
|
SetBit(mgr->hasDomainPolicyVector, domProp);
|
1999-11-11 22:10:36 +00:00
|
|
|
return;
|
1999-10-28 22:09:03 +00:00
|
|
|
}
|
1999-11-16 05:07:31 +00:00
|
|
|
}
|
1999-11-11 22:10:36 +00:00
|
|
|
NS_ASSERTION(PR_FALSE, "DOM property name invalid or not found");
|
1999-09-15 04:05:43 +00:00
|
|
|
}
|
|
|
|
|
2000-05-16 03:40:51 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2000-01-23 04:23:14 +00:00
|
|
|
struct EnumeratePrincipalsInfo {
|
|
|
|
// this struct doesn't own these objects; consider them parameters on
|
|
|
|
// the stack
|
|
|
|
nsSupportsHashtable *ht;
|
2000-07-20 01:16:15 +00:00
|
|
|
nsISecurityPref *prefs;
|
2000-01-23 04:23:14 +00:00
|
|
|
};
|
|
|
|
|
2000-01-18 21:54:01 +00:00
|
|
|
void
|
2000-02-10 04:56:56 +00:00
|
|
|
nsScriptSecurityManager::EnumeratePrincipalsCallback(const char *prefName,
|
2000-01-23 04:23:14 +00:00
|
|
|
void *voidParam)
|
2000-01-18 21:54:01 +00:00
|
|
|
{
|
2000-05-16 03:40:51 +00:00
|
|
|
/* This is the principal preference syntax:
|
2000-07-26 04:53:01 +00:00
|
|
|
* capability.principal.[codebase|certificate].<name>.[id|granted|denied]
|
2000-05-16 03:40:51 +00:00
|
|
|
* For example:
|
2000-07-26 04:53:01 +00:00
|
|
|
* 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");
|
2000-05-16 03:40:51 +00:00
|
|
|
*/
|
|
|
|
|
2000-01-23 04:23:14 +00:00
|
|
|
EnumeratePrincipalsInfo *info = (EnumeratePrincipalsInfo *) voidParam;
|
2000-05-16 03:40:51 +00:00
|
|
|
static const char idName[] = ".id";
|
|
|
|
PRInt32 prefNameLen = PL_strlen(prefName) - (sizeof(idName)-1);
|
|
|
|
if (PL_strcasecmp(prefName + prefNameLen, idName) != 0)
|
2000-01-23 04:23:14 +00:00
|
|
|
return;
|
2000-05-16 03:40:51 +00:00
|
|
|
|
|
|
|
char* id;
|
2000-07-26 04:53:01 +00:00
|
|
|
if (NS_FAILED(info->prefs->SecurityGetCharPref(prefName, &id)))
|
2000-05-16 03:40:51 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
nsXPIDLCString grantedPrefName;
|
|
|
|
nsXPIDLCString deniedPrefName;
|
|
|
|
if (NS_FAILED(PrincipalPrefNames( prefName,
|
|
|
|
getter_Copies(grantedPrefName),
|
|
|
|
getter_Copies(deniedPrefName) )))
|
|
|
|
return;
|
|
|
|
|
|
|
|
char* grantedList = nsnull;
|
2000-07-26 04:53:01 +00:00
|
|
|
info->prefs->SecurityGetCharPref(grantedPrefName, &grantedList);
|
2000-05-16 03:40:51 +00:00
|
|
|
char* deniedList = nsnull;
|
2000-07-26 04:53:01 +00:00
|
|
|
info->prefs->SecurityGetCharPref(deniedPrefName, &deniedList);
|
2000-05-16 03:40:51 +00:00
|
|
|
|
2000-07-20 01:16:15 +00:00
|
|
|
//-- Delete prefs if their value is the empty string
|
|
|
|
if ((!id || id[0] == '\0') ||
|
|
|
|
((!grantedList || grantedList[0] == '\0') && (!deniedList || deniedList[0] == '\0')))
|
|
|
|
{
|
|
|
|
info->prefs->SecurityClearUserPref(prefName);
|
|
|
|
info->prefs->SecurityClearUserPref(grantedPrefName);
|
|
|
|
info->prefs->SecurityClearUserPref(deniedPrefName);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-- Create a principal based on the prefs
|
2000-07-26 04:53:01 +00:00
|
|
|
static const char certificateName[] = "capability.principal.certificate";
|
|
|
|
static const char codebaseName[] = "capability.principal.codebase";
|
2000-01-23 04:23:14 +00:00
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
2000-04-26 03:50:07 +00:00
|
|
|
if (PL_strncmp(prefName, certificateName,
|
|
|
|
sizeof(certificateName)-1) == 0)
|
2000-01-23 04:23:14 +00:00
|
|
|
{
|
|
|
|
nsCertificatePrincipal *certificate = new nsCertificatePrincipal();
|
|
|
|
if (certificate) {
|
|
|
|
NS_ADDREF(certificate);
|
2000-05-16 03:40:51 +00:00
|
|
|
if (NS_SUCCEEDED(certificate->InitFromPersistent(prefName, id,
|
|
|
|
grantedList, deniedList)))
|
2000-01-23 04:23:14 +00:00
|
|
|
principal = do_QueryInterface((nsBasePrincipal*)certificate);
|
|
|
|
NS_RELEASE(certificate);
|
|
|
|
}
|
2000-04-26 03:50:07 +00:00
|
|
|
} else if(PL_strncmp(prefName, codebaseName,
|
|
|
|
sizeof(codebaseName)-1) == 0)
|
|
|
|
{
|
|
|
|
nsCodebasePrincipal *codebase = new nsCodebasePrincipal();
|
|
|
|
if (codebase) {
|
|
|
|
NS_ADDREF(codebase);
|
2000-05-16 03:40:51 +00:00
|
|
|
if (NS_SUCCEEDED(codebase->InitFromPersistent(prefName, id,
|
|
|
|
grantedList, deniedList)))
|
2000-04-26 03:50:07 +00:00
|
|
|
principal = do_QueryInterface((nsBasePrincipal*)codebase);
|
|
|
|
NS_RELEASE(codebase);
|
|
|
|
}
|
2000-01-23 04:23:14 +00:00
|
|
|
}
|
2000-05-16 03:40:51 +00:00
|
|
|
PR_FREEIF(grantedList);
|
|
|
|
PR_FREEIF(deniedList);
|
|
|
|
|
2000-01-23 04:23:14 +00:00
|
|
|
if (principal) {
|
|
|
|
nsIPrincipalKey key(principal);
|
|
|
|
info->ht->Put(&key, principal);
|
|
|
|
}
|
2000-01-18 21:54:01 +00:00
|
|
|
}
|
|
|
|
|
2000-01-06 00:59:18 +00:00
|
|
|
static const char jsEnabledPrefName[] = "javascript.enabled";
|
2000-01-08 16:51:54 +00:00
|
|
|
static const char jsMailEnabledPrefName[] = "javascript.allow.mailnews";
|
2000-01-06 00:59:18 +00:00
|
|
|
|
2000-05-16 03:40:51 +00:00
|
|
|
int PR_CALLBACK
|
2000-01-06 00:59:18 +00:00
|
|
|
nsScriptSecurityManager::JSEnabledPrefChanged(const char *pref, void *data)
|
|
|
|
{
|
|
|
|
nsScriptSecurityManager *secMgr = (nsScriptSecurityManager *) data;
|
|
|
|
|
2000-07-26 04:53:01 +00:00
|
|
|
if (NS_FAILED(secMgr->mPrefs->GetBoolPref(jsEnabledPrefName,
|
2000-07-20 01:16:15 +00:00
|
|
|
&secMgr->mIsJavaScriptEnabled)))
|
2000-01-06 00:59:18 +00:00
|
|
|
{
|
|
|
|
// Default to enabled.
|
|
|
|
secMgr->mIsJavaScriptEnabled = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2000-07-26 04:53:01 +00:00
|
|
|
if (NS_FAILED(secMgr->mPrefs->GetBoolPref(jsMailEnabledPrefName,
|
2000-07-20 01:16:15 +00:00
|
|
|
&secMgr->mIsMailJavaScriptEnabled)))
|
2000-01-08 16:51:54 +00:00
|
|
|
{
|
|
|
|
// Default to enabled.
|
|
|
|
secMgr->mIsMailJavaScriptEnabled = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2000-01-06 00:59:18 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-05-16 03:40:51 +00:00
|
|
|
int PR_CALLBACK
|
2000-02-10 04:56:56 +00:00
|
|
|
nsScriptSecurityManager::PrincipalPrefChanged(const char *pref, void *data)
|
|
|
|
{
|
|
|
|
nsScriptSecurityManager *secMgr = (nsScriptSecurityManager *) data;
|
2000-07-20 01:16:15 +00:00
|
|
|
if (secMgr->mIsWritingPrefs)
|
2000-02-10 04:56:56 +00:00
|
|
|
return 0;
|
2000-05-16 03:40:51 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2000-02-10 04:56:56 +00:00
|
|
|
EnumeratePrincipalsInfo info;
|
|
|
|
info.ht = secMgr->mPrincipals;
|
2000-07-26 04:53:01 +00:00
|
|
|
info.prefs = secMgr->mSecurityPrefs;
|
2000-05-16 03:40:51 +00:00
|
|
|
EnumeratePrincipalsCallback(idPref, &info);
|
|
|
|
PR_FREEIF(idPref);
|
2000-02-10 04:56:56 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1999-10-28 22:09:03 +00:00
|
|
|
NS_IMETHODIMP
|
2000-07-26 04:53:01 +00:00
|
|
|
nsScriptSecurityManager::InitPrefs()
|
1999-09-15 04:05:43 +00:00
|
|
|
{
|
2000-01-06 00:59:18 +00:00
|
|
|
// The DOM property enums and names better be in sync
|
|
|
|
NS_ASSERTION(NS_DOM_PROP_MAX == sizeof(domPropNames)/sizeof(domPropNames[0]),
|
|
|
|
"mismatch in property name count");
|
|
|
|
|
2000-03-23 23:42:46 +00:00
|
|
|
// The DOM property names had better be sorted for binary search to work
|
|
|
|
#ifdef DEBUG
|
|
|
|
for (unsigned i=1; i < sizeof(domPropNames)/sizeof(domPropNames[0]); i++) {
|
|
|
|
NS_ASSERTION(strcmp(domPropNames[i-1], domPropNames[i]) < 0,
|
|
|
|
"DOM properties are not properly sorted");
|
|
|
|
}
|
2000-05-16 03:40:51 +00:00
|
|
|
#endif
|
2000-03-23 23:42:46 +00:00
|
|
|
|
1999-11-12 03:07:37 +00:00
|
|
|
nsresult rv;
|
2000-07-26 04:53:01 +00:00
|
|
|
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
|
1999-11-12 03:07:37 +00:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return NS_ERROR_FAILURE;
|
2000-01-23 04:23:14 +00:00
|
|
|
mPrefs = prefs;
|
2000-07-26 04:53:01 +00:00
|
|
|
|
|
|
|
mSecurityPrefs = do_QueryInterface(prefs, &rv);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return NS_ERROR_FAILURE;
|
2000-01-23 04:23:14 +00:00
|
|
|
|
2000-01-06 00:59:18 +00:00
|
|
|
// Set the initial value of the "javascript.enabled" pref
|
|
|
|
JSEnabledPrefChanged(jsEnabledPrefName, this);
|
|
|
|
|
2000-01-08 16:51:54 +00:00
|
|
|
// set callbacks in case the value of the pref changes
|
2000-01-06 00:59:18 +00:00
|
|
|
prefs->RegisterCallback(jsEnabledPrefName, JSEnabledPrefChanged, this);
|
2000-01-08 16:51:54 +00:00
|
|
|
prefs->RegisterCallback(jsMailEnabledPrefName, JSEnabledPrefChanged, this);
|
2000-01-18 21:54:01 +00:00
|
|
|
|
2000-08-22 02:06:52 +00:00
|
|
|
mPrefs->EnumerateChildren("capability.policy",
|
|
|
|
nsScriptSecurityManager::EnumeratePolicyCallback,
|
|
|
|
(void *) this);
|
|
|
|
|
|
|
|
if (!mPrincipals) {
|
|
|
|
mPrincipals = new nsSupportsHashtable(31);
|
|
|
|
if (!mPrincipals)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
2000-01-23 04:23:14 +00:00
|
|
|
}
|
2000-08-22 02:06:52 +00:00
|
|
|
EnumeratePrincipalsInfo info;
|
|
|
|
info.ht = mPrincipals;
|
|
|
|
info.prefs = mSecurityPrefs;
|
|
|
|
|
|
|
|
mPrefs->EnumerateChildren("capability.principal",
|
|
|
|
nsScriptSecurityManager::EnumeratePrincipalsCallback,
|
|
|
|
(void *) &info);
|
|
|
|
|
|
|
|
mPrefs->RegisterCallback("capability.principal", PrincipalPrefChanged, this);
|
2000-02-10 04:56:56 +00:00
|
|
|
|
1999-11-11 22:10:36 +00:00
|
|
|
return NS_OK;
|
1999-09-15 04:05:43 +00:00
|
|
|
}
|