Get signed JavaScript working using the non-Java capabilities code.
Also, implement a preference to run only signed JavaScript. git-svn-id: svn://10.0.0.236/trunk@7453 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -457,11 +457,8 @@ static void
|
||||
lo_script_archive_exit_fn(URL_Struct *url_struct, int status, MWContext *context)
|
||||
{
|
||||
ScriptData *data = NULL;
|
||||
#ifdef JAVA
|
||||
/* Vars only used in JAVA context */
|
||||
char *name;
|
||||
JSPrincipals *principals;
|
||||
#endif
|
||||
ETEvalStuff * stuff;
|
||||
|
||||
data = (ScriptData *) url_struct->fe_data;
|
||||
@@ -475,16 +472,6 @@ lo_script_archive_exit_fn(URL_Struct *url_struct, int status, MWContext *context
|
||||
stuff->version = data->version;
|
||||
stuff->data = context;
|
||||
|
||||
#ifndef JAVA
|
||||
/* No Java; execute without principals. */
|
||||
if (data->buffer) {
|
||||
stuff->principals = NULL;
|
||||
ET_EvaluateScript(context, data->buffer, stuff, lo_ScriptEvalExitFn);
|
||||
}
|
||||
else {
|
||||
XP_FREE(stuff);
|
||||
}
|
||||
#else
|
||||
name = data->archiveSrc ? data->archiveSrc : data->id;
|
||||
principals = LM_NewJSPrincipals(url_struct, name, data->codebase);
|
||||
if (principals != NULL) {
|
||||
@@ -538,14 +525,9 @@ lo_script_archive_exit_fn(URL_Struct *url_struct, int status, MWContext *context
|
||||
XP_FREE(stuff);
|
||||
}
|
||||
|
||||
#endif /* ifdef JAVA */
|
||||
|
||||
lo_DestroyScriptData(data);
|
||||
|
||||
#ifdef JAVA /* Label only used in this context */
|
||||
out:
|
||||
#endif
|
||||
|
||||
/* Always free (or drop a ref on) the url_struct before returning. */
|
||||
NET_FreeURLStruct(url_struct);
|
||||
}
|
||||
|
||||
@@ -507,6 +507,9 @@ lm_RegisterComponentMethod(const char *comp, const char *targetName,
|
||||
/*
|
||||
* Class initializers (the wave of the future).
|
||||
*/
|
||||
extern JSBool
|
||||
lm_InitSecurity(MochaDecoder *decoder);
|
||||
|
||||
extern JSBool
|
||||
lm_InitDocumentClass(MochaDecoder *decoder);
|
||||
|
||||
@@ -664,6 +667,9 @@ lm_CheckPermissions(JSContext *cx, JSObject *obj, JSTarget target);
|
||||
extern JSBool
|
||||
lm_GetCrossOriginEnabled(void);
|
||||
|
||||
extern JSBool
|
||||
lm_GetUnsignedExecutionEnabled(void);
|
||||
|
||||
extern JSBool
|
||||
lm_CheckContainerAccess(JSContext *cx, JSObject *obj, MochaDecoder *decoder,
|
||||
JSTarget target);
|
||||
|
||||
@@ -576,6 +576,7 @@ static XP_Bool lm_enabled = TRUE;
|
||||
static XP_Bool lm_enabledMailNews = TRUE;
|
||||
static XP_Bool lm_enabledSigning = TRUE;
|
||||
static XP_Bool lm_enabledCrossOrigin = TRUE;
|
||||
static XP_Bool lm_enabledUnsignedExecution = TRUE;
|
||||
|
||||
/*
|
||||
* Is this window enbled to do JS?
|
||||
@@ -639,10 +640,21 @@ lm_GetCrossOriginEnabled()
|
||||
return (JSBool) lm_enabledCrossOrigin;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is execution of unsigned scripts enabled?
|
||||
*/
|
||||
JSBool
|
||||
lm_GetUnsignedExecutionEnabled()
|
||||
{
|
||||
return (JSBool) lm_enabledUnsignedExecution;
|
||||
}
|
||||
|
||||
static char lm_jsEnabled[] = "javascript.enabled";
|
||||
static char lm_jsEnabledMN[] = "javascript.allow.mailnews";
|
||||
static char lm_jsEnabledSigning[] = "javascript.allow.signing";
|
||||
static char lm_jsEnabledCrossOrigin[] = "javascript.allow.crossOrigin";
|
||||
static char lm_jsEnabledUnsignedExecution[] =
|
||||
"javascript.allow.unsignedExecution";
|
||||
|
||||
PR_STATIC_CALLBACK(int)
|
||||
lm_PrefChangedFunc(const char *pref, void *data)
|
||||
@@ -651,6 +663,8 @@ lm_PrefChangedFunc(const char *pref, void *data)
|
||||
PREF_GetBoolPref(lm_jsEnabledMN, &lm_enabledMailNews);
|
||||
PREF_GetBoolPref(lm_jsEnabledSigning, &lm_enabledSigning);
|
||||
PREF_GetBoolPref(lm_jsEnabledCrossOrigin, &lm_enabledCrossOrigin);
|
||||
PREF_GetBoolPref(lm_jsEnabledUnsignedExecution,
|
||||
&lm_enabledUnsignedExecution);
|
||||
|
||||
/*
|
||||
* If we started up w/ JS turned off we will have not bothered
|
||||
@@ -672,11 +686,13 @@ lm_ReallyInitMocha(void)
|
||||
{
|
||||
int priority;
|
||||
|
||||
/* register callback incase pref changes while we're running */
|
||||
/* register callback in case pref changes while we're running */
|
||||
PREF_RegisterCallback(lm_jsEnabled, lm_PrefChangedFunc, NULL);
|
||||
PREF_RegisterCallback(lm_jsEnabledMN, lm_PrefChangedFunc, NULL);
|
||||
PREF_RegisterCallback(lm_jsEnabledSigning, lm_PrefChangedFunc, NULL);
|
||||
PREF_RegisterCallback(lm_jsEnabledCrossOrigin, lm_PrefChangedFunc, NULL);
|
||||
PREF_RegisterCallback(lm_jsEnabledUnsignedExecution, lm_PrefChangedFunc,
|
||||
NULL);
|
||||
|
||||
if ( mochaInited ) {
|
||||
return;
|
||||
@@ -798,12 +814,16 @@ LM_InitMocha(void)
|
||||
PREF_RegisterCallback(lm_jsEnabledMN, lm_PrefChangedFunc, NULL);
|
||||
PREF_RegisterCallback(lm_jsEnabledSigning, lm_PrefChangedFunc, NULL);
|
||||
PREF_RegisterCallback(lm_jsEnabledCrossOrigin, lm_PrefChangedFunc, NULL);
|
||||
PREF_RegisterCallback(lm_jsEnabledUnsignedExecution, lm_PrefChangedFunc,
|
||||
NULL);
|
||||
|
||||
/* get our enabled-ness states */
|
||||
PREF_GetBoolPref(lm_jsEnabled, &lm_enabled);
|
||||
PREF_GetBoolPref(lm_jsEnabledMN, &lm_enabledMailNews);
|
||||
PREF_GetBoolPref(lm_jsEnabledSigning, &lm_enabledSigning);
|
||||
PREF_GetBoolPref(lm_jsEnabledCrossOrigin, &lm_enabledCrossOrigin);
|
||||
PREF_GetBoolPref(lm_jsEnabledUnsignedExecution,
|
||||
&lm_enabledUnsignedExecution);
|
||||
|
||||
/* set up the initial queue stack pointers */
|
||||
if (!et_TopQueue) {
|
||||
|
||||
@@ -56,6 +56,10 @@ static char access_error_message[] =
|
||||
static char container_error_message[] =
|
||||
"script at '%s' is not signed by sufficient principals to access "
|
||||
"signed container";
|
||||
static char enablePrivilegeStr[] = "enablePrivilege";
|
||||
static char isPrivilegeEnabledStr[] = "isPrivilegeEnabled";
|
||||
static char disablePrivilegeStr[] = "disablePrivilege";
|
||||
static char revertPrivilegeStr[] = "revertPrivilege";
|
||||
|
||||
#define FILE_URL_PREFIX_LEN (sizeof file_url_prefix - 1)
|
||||
#define WYSIWYG_TYPE_LEN 10 /* wysiwyg:// */
|
||||
@@ -66,6 +70,145 @@ PRBool lm_console_is_ready = PR_FALSE;
|
||||
static void lm_PrintToConsole(const char *data);
|
||||
static void setupJSCapsCallbacks();
|
||||
|
||||
/* XXX what about the PREXTERN? */
|
||||
typedef PRBool
|
||||
(*nsCapsFn)(void* context, struct nsTarget *target, PRInt32 callerDepth);
|
||||
|
||||
static JSBool
|
||||
callCapsCode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval, nsCapsFn fn, char *name)
|
||||
{
|
||||
JSString *str;
|
||||
char *cstr;
|
||||
struct nsTarget *target;
|
||||
|
||||
if (argc == 0 || !JSVAL_IS_STRING(argv[0])) {
|
||||
JS_ReportError(cx, "String argument expected for %s.", name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
/*
|
||||
* 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.
|
||||
* XXX but then use of an object will cause errors here....
|
||||
*/
|
||||
str = JSVAL_TO_STRING(argv[0]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
|
||||
cstr = JS_GetStringBytes(str);
|
||||
if (cstr == NULL)
|
||||
return JS_FALSE;
|
||||
|
||||
target = nsCapsFindTarget(cstr);
|
||||
if (target == NULL)
|
||||
return JS_FALSE;
|
||||
/* stack depth of 1: first frame is for the native function called */
|
||||
if (!(*fn)(cx, target, 1)) {
|
||||
// XXX report error, later, throw exception
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
JSBool
|
||||
lm_netscape_security_isPrivilegeEnabled(JSContext *cx, JSObject *obj, uintN argc,
|
||||
jsval *argv, jsval *rval)
|
||||
{
|
||||
return callCapsCode(cx, obj, argc, argv, rval, nsCapsIsPrivilegeEnabled,
|
||||
isPrivilegeEnabledStr);
|
||||
}
|
||||
|
||||
JSBool
|
||||
lm_netscape_security_enablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
||||
jsval *argv, jsval *rval)
|
||||
{
|
||||
return callCapsCode(cx, obj, argc, argv, rval, nsCapsEnablePrivilege,
|
||||
enablePrivilegeStr);
|
||||
}
|
||||
|
||||
JSBool
|
||||
lm_netscape_security_disablePrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
||||
jsval *argv, jsval *rval)
|
||||
{
|
||||
return callCapsCode(cx, obj, argc, argv, rval, nsCapsDisablePrivilege,
|
||||
disablePrivilegeStr);
|
||||
}
|
||||
|
||||
JSBool
|
||||
lm_netscape_security_revertPrivilege(JSContext *cx, JSObject *obj, uintN argc,
|
||||
jsval *argv, jsval *rval)
|
||||
{
|
||||
return callCapsCode(cx, obj, argc, argv, rval, nsCapsRevertPrivilege,
|
||||
revertPrivilegeStr);
|
||||
}
|
||||
|
||||
static JSFunctionSpec PrivilegeManager_static_methods[] = {
|
||||
{ isPrivilegeEnabledStr, lm_netscape_security_isPrivilegeEnabled, 1},
|
||||
{ enablePrivilegeStr, lm_netscape_security_enablePrivilege, 1},
|
||||
{ disablePrivilegeStr, lm_netscape_security_disablePrivilege, 1},
|
||||
{ revertPrivilegeStr, lm_netscape_security_revertPrivilege, 1},
|
||||
{0}
|
||||
};
|
||||
|
||||
JSBool
|
||||
lm_InitSecurity(MochaDecoder *decoder)
|
||||
{
|
||||
JSContext *cx;
|
||||
JSObject *obj;
|
||||
JSObject *proto;
|
||||
JSClass *objectClass;
|
||||
jsval v;
|
||||
JSObject *securityObj;
|
||||
|
||||
/*
|
||||
* "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege,
|
||||
* et. al. so that code that worked with 4.0 can still work.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Find Object.prototype's class by walking up the window object's
|
||||
* prototype chain.
|
||||
*/
|
||||
cx = decoder->js_context;
|
||||
obj = decoder->window_object;
|
||||
while (proto = JS_GetPrototype(cx, obj))
|
||||
obj = proto;
|
||||
objectClass = JS_GetClass(obj);
|
||||
|
||||
if (!JS_GetProperty(cx, decoder->window_object, "netscape", &v))
|
||||
return JS_FALSE;
|
||||
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 JS_FALSE;
|
||||
securityObj = JSVAL_TO_OBJECT(v);
|
||||
} else {
|
||||
/* define netscape.security object */
|
||||
obj = JS_DefineObject(cx, decoder->window_object, "netscape",
|
||||
objectClass, NULL, 0);
|
||||
if (obj == NULL)
|
||||
return JS_FALSE;
|
||||
securityObj = JS_DefineObject(cx, obj, "security", objectClass,
|
||||
NULL, 0);
|
||||
if (securityObj == NULL)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Define PrivilegeManager object with the necessary "static" methods. */
|
||||
obj = JS_DefineObject(cx, securityObj, "PrivilegeManager", objectClass,
|
||||
NULL, 0);
|
||||
if (obj == NULL)
|
||||
return JS_FALSE;
|
||||
|
||||
return JS_DefineFunctions(cx, obj, PrivilegeManager_static_methods);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lm_PrintToConsole(const char *data)
|
||||
{
|
||||
@@ -470,9 +613,11 @@ lm_GetSubjectOriginURL(JSContext *cx)
|
||||
JSPrincipals *principals;
|
||||
JSStackFrame *fp;
|
||||
JSScript *script;
|
||||
MochaDecoder *running;
|
||||
#ifdef JAVA
|
||||
JRIEnv *env;
|
||||
char *str;
|
||||
MochaDecoder *running;
|
||||
#endif
|
||||
|
||||
fp = NULL;
|
||||
while ((fp = JS_FrameIterator(cx, &fp)) != NULL) {
|
||||
@@ -1753,6 +1898,10 @@ LM_RegisterPrincipals(MochaDecoder *decoder, JSPrincipals *principals,
|
||||
}
|
||||
|
||||
if (!verified) {
|
||||
if (!lm_GetUnsignedExecutionEnabled()) {
|
||||
/* Execution of unsigned scripts disabled. Return now. */
|
||||
return NULL;
|
||||
}
|
||||
/* No cert principals; try codebase principal */
|
||||
if (principals == NULL || principals == containerPrincipals) {
|
||||
if (container == inner ||
|
||||
@@ -1863,7 +2012,6 @@ static JSFrameIterator *
|
||||
lm_NewJSFrameIterator(void *context)
|
||||
{
|
||||
JSContext *cx = (JSContext *)context;
|
||||
char *errorString;
|
||||
JSFrameIterator *result;
|
||||
void *array;
|
||||
JRIEnv *env = NULL;
|
||||
@@ -1949,7 +2097,6 @@ struct NSJSJavaFrameWrapper *
|
||||
lm_NewNSJSJavaFrameWrapperCB(void *context)
|
||||
{
|
||||
struct NSJSJavaFrameWrapper *result;
|
||||
JRIEnv *env;
|
||||
|
||||
result = (struct NSJSJavaFrameWrapper *)PR_CALLOC(sizeof(struct NSJSJavaFrameWrapper));
|
||||
if (result == NULL) {
|
||||
@@ -2048,6 +2195,7 @@ setupJSCapsCallbacks()
|
||||
if (privManagerInited) return;
|
||||
privManagerInited = TRUE;
|
||||
|
||||
nsCapsInitialize();
|
||||
setNewNSJSJavaFrameWrapperCallback(lm_NewNSJSJavaFrameWrapperCB);
|
||||
setFreeNSJSJavaFrameWrapperCallback(lm_FreeNSJSJavaFrameWrapperCB);
|
||||
setGetStartFrameCallback(lm_GetStartFrameCB);
|
||||
|
||||
@@ -3264,6 +3264,7 @@ lm_DefineWindowProps(JSContext *cx, MochaDecoder *decoder)
|
||||
|
||||
obj = decoder->window_object;
|
||||
return (JSBool)(JS_DefineFunctions(cx, obj, lm_window_methods) &&
|
||||
lm_InitSecurity(decoder) &&
|
||||
lm_InitEventClasses(decoder) &&
|
||||
lm_InitDocumentClass(decoder) &&
|
||||
lm_DefineDocument(decoder, LO_DOCUMENT_LAYER_ID) &&
|
||||
|
||||
Reference in New Issue
Block a user