diff --git a/mozilla/lib/layout/layscrip.c b/mozilla/lib/layout/layscrip.c index 42b5b2f1c71..4e89ca4474b 100644 --- a/mozilla/lib/layout/layscrip.c +++ b/mozilla/lib/layout/layscrip.c @@ -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); } diff --git a/mozilla/lib/libmocha/lm.h b/mozilla/lib/libmocha/lm.h index bac8104f993..60ee947eeae 100644 --- a/mozilla/lib/libmocha/lm.h +++ b/mozilla/lib/libmocha/lm.h @@ -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); diff --git a/mozilla/lib/libmocha/lm_init.c b/mozilla/lib/libmocha/lm_init.c index fbe4efab02d..8e7429b11c4 100644 --- a/mozilla/lib/libmocha/lm_init.c +++ b/mozilla/lib/libmocha/lm_init.c @@ -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) { diff --git a/mozilla/lib/libmocha/lm_taint.c b/mozilla/lib/libmocha/lm_taint.c index da5a6424109..13d4d919616 100644 --- a/mozilla/lib/libmocha/lm_taint.c +++ b/mozilla/lib/libmocha/lm_taint.c @@ -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); diff --git a/mozilla/lib/libmocha/lm_win.c b/mozilla/lib/libmocha/lm_win.c index ff310c69360..7286eee4b21 100644 --- a/mozilla/lib/libmocha/lm_win.c +++ b/mozilla/lib/libmocha/lm_win.c @@ -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) &&