michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: /*Factory for internal browser security resource managers*/ michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIScriptSecurityManager.h" michael@0: #include "nsScriptSecurityManager.h" michael@0: #include "nsIPrincipal.h" michael@0: #include "nsPrincipal.h" michael@0: #include "nsSystemPrincipal.h" michael@0: #include "nsNullPrincipal.h" michael@0: #include "nsIScriptNameSpaceManager.h" michael@0: #include "nsIScriptContext.h" michael@0: #include "nsICategoryManager.h" michael@0: #include "nsXPIDLString.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsString.h" michael@0: #include "nsNetCID.h" michael@0: #include "nsIClassInfoImpl.h" michael@0: #include "nsJSUtils.h" michael@0: #include "nsPIDOMWindow.h" michael@0: #include "nsIScriptGlobalObject.h" michael@0: #include "nsIDocument.h" michael@0: #include "jsfriendapi.h" michael@0: #include "xpcprivate.h" michael@0: #include "nsCxPusher.h" michael@0: #include "mozilla/Preferences.h" michael@0: #include "mozilla/Telemetry.h" michael@0: michael@0: using namespace mozilla; michael@0: michael@0: /////////////////////// michael@0: // nsSecurityNameSet // michael@0: /////////////////////// michael@0: michael@0: nsSecurityNameSet::nsSecurityNameSet() michael@0: { michael@0: } michael@0: michael@0: nsSecurityNameSet::~nsSecurityNameSet() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(nsSecurityNameSet, nsIScriptExternalNameSet) michael@0: michael@0: static bool michael@0: netscape_security_enablePrivilege(JSContext *cx, unsigned argc, JS::Value *vp) michael@0: { michael@0: Telemetry::Accumulate(Telemetry::ENABLE_PRIVILEGE_EVER_CALLED, true); michael@0: return xpc::EnableUniversalXPConnect(cx); michael@0: } michael@0: michael@0: static const JSFunctionSpec PrivilegeManager_static_methods[] = { michael@0: JS_FS("enablePrivilege", netscape_security_enablePrivilege, 1, 0), michael@0: JS_FS_END michael@0: }; michael@0: michael@0: /* michael@0: * "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege, michael@0: * et al. so that code that worked with 4.0 can still work. michael@0: */ michael@0: NS_IMETHODIMP michael@0: nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext) michael@0: { michael@0: AutoJSContext cx; michael@0: JS::Rooted global(cx, aScriptContext->GetWindowProxy()); michael@0: JSAutoCompartment ac(cx, global); michael@0: michael@0: /* michael@0: * Find Object.prototype's class by walking up the global object's michael@0: * prototype chain. michael@0: */ michael@0: JS::Rooted obj(cx, global); michael@0: JS::Rooted proto(cx); michael@0: for (;;) { michael@0: MOZ_ALWAYS_TRUE(JS_GetPrototype(cx, obj, &proto)); michael@0: if (!proto) michael@0: break; michael@0: obj = proto; michael@0: } michael@0: const JSClass *objectClass = JS_GetClass(obj); michael@0: michael@0: JS::Rooted v(cx); michael@0: if (!JS_GetProperty(cx, global, "netscape", &v)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: JS::Rooted securityObj(cx); michael@0: if (v.isObject()) { michael@0: /* michael@0: * "netscape" property of window object exists; get the michael@0: * "security" property. michael@0: */ michael@0: obj = &v.toObject(); michael@0: if (!JS_GetProperty(cx, obj, "security", &v) || !v.isObject()) michael@0: return NS_ERROR_FAILURE; michael@0: securityObj = &v.toObject(); michael@0: } else { michael@0: /* define netscape.security object */ michael@0: obj = JS_DefineObject(cx, global, "netscape", objectClass, nullptr, 0); michael@0: if (obj == nullptr) michael@0: return NS_ERROR_FAILURE; michael@0: securityObj = JS_DefineObject(cx, obj, "security", objectClass, michael@0: nullptr, 0); michael@0: if (securityObj == nullptr) michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: // We hide enablePrivilege behind a pref because it has been altered in a michael@0: // way that makes it fundamentally insecure to use in production. Mozilla michael@0: // uses this pref during automated testing to support legacy test code that michael@0: // uses enablePrivilege. If you're not doing test automation, you _must_ not michael@0: // flip this pref, or you will be exposing all your users to security michael@0: // vulnerabilities. michael@0: if (!Preferences::GetBool("security.turn_off_all_security_so_that_viruses_can_take_over_this_computer")) michael@0: return NS_OK; michael@0: michael@0: /* Define PrivilegeManager object with the necessary "static" methods. */ michael@0: obj = JS_DefineObject(cx, securityObj, "PrivilegeManager", objectClass, michael@0: nullptr, 0); michael@0: if (obj == nullptr) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: return JS_DefineFunctions(cx, obj, PrivilegeManager_static_methods) michael@0: ? NS_OK michael@0: : NS_ERROR_FAILURE; michael@0: }