|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 /*Factory for internal browser security resource managers*/ |
|
6 |
|
7 #include "nsCOMPtr.h" |
|
8 #include "nsIScriptSecurityManager.h" |
|
9 #include "nsScriptSecurityManager.h" |
|
10 #include "nsIPrincipal.h" |
|
11 #include "nsPrincipal.h" |
|
12 #include "nsSystemPrincipal.h" |
|
13 #include "nsNullPrincipal.h" |
|
14 #include "nsIScriptNameSpaceManager.h" |
|
15 #include "nsIScriptContext.h" |
|
16 #include "nsICategoryManager.h" |
|
17 #include "nsXPIDLString.h" |
|
18 #include "nsCOMPtr.h" |
|
19 #include "nsIServiceManager.h" |
|
20 #include "nsString.h" |
|
21 #include "nsNetCID.h" |
|
22 #include "nsIClassInfoImpl.h" |
|
23 #include "nsJSUtils.h" |
|
24 #include "nsPIDOMWindow.h" |
|
25 #include "nsIScriptGlobalObject.h" |
|
26 #include "nsIDocument.h" |
|
27 #include "jsfriendapi.h" |
|
28 #include "xpcprivate.h" |
|
29 #include "nsCxPusher.h" |
|
30 #include "mozilla/Preferences.h" |
|
31 #include "mozilla/Telemetry.h" |
|
32 |
|
33 using namespace mozilla; |
|
34 |
|
35 /////////////////////// |
|
36 // nsSecurityNameSet // |
|
37 /////////////////////// |
|
38 |
|
39 nsSecurityNameSet::nsSecurityNameSet() |
|
40 { |
|
41 } |
|
42 |
|
43 nsSecurityNameSet::~nsSecurityNameSet() |
|
44 { |
|
45 } |
|
46 |
|
47 NS_IMPL_ISUPPORTS(nsSecurityNameSet, nsIScriptExternalNameSet) |
|
48 |
|
49 static bool |
|
50 netscape_security_enablePrivilege(JSContext *cx, unsigned argc, JS::Value *vp) |
|
51 { |
|
52 Telemetry::Accumulate(Telemetry::ENABLE_PRIVILEGE_EVER_CALLED, true); |
|
53 return xpc::EnableUniversalXPConnect(cx); |
|
54 } |
|
55 |
|
56 static const JSFunctionSpec PrivilegeManager_static_methods[] = { |
|
57 JS_FS("enablePrivilege", netscape_security_enablePrivilege, 1, 0), |
|
58 JS_FS_END |
|
59 }; |
|
60 |
|
61 /* |
|
62 * "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege, |
|
63 * et al. so that code that worked with 4.0 can still work. |
|
64 */ |
|
65 NS_IMETHODIMP |
|
66 nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext) |
|
67 { |
|
68 AutoJSContext cx; |
|
69 JS::Rooted<JSObject*> global(cx, aScriptContext->GetWindowProxy()); |
|
70 JSAutoCompartment ac(cx, global); |
|
71 |
|
72 /* |
|
73 * Find Object.prototype's class by walking up the global object's |
|
74 * prototype chain. |
|
75 */ |
|
76 JS::Rooted<JSObject*> obj(cx, global); |
|
77 JS::Rooted<JSObject*> proto(cx); |
|
78 for (;;) { |
|
79 MOZ_ALWAYS_TRUE(JS_GetPrototype(cx, obj, &proto)); |
|
80 if (!proto) |
|
81 break; |
|
82 obj = proto; |
|
83 } |
|
84 const JSClass *objectClass = JS_GetClass(obj); |
|
85 |
|
86 JS::Rooted<JS::Value> v(cx); |
|
87 if (!JS_GetProperty(cx, global, "netscape", &v)) |
|
88 return NS_ERROR_FAILURE; |
|
89 |
|
90 JS::Rooted<JSObject*> securityObj(cx); |
|
91 if (v.isObject()) { |
|
92 /* |
|
93 * "netscape" property of window object exists; get the |
|
94 * "security" property. |
|
95 */ |
|
96 obj = &v.toObject(); |
|
97 if (!JS_GetProperty(cx, obj, "security", &v) || !v.isObject()) |
|
98 return NS_ERROR_FAILURE; |
|
99 securityObj = &v.toObject(); |
|
100 } else { |
|
101 /* define netscape.security object */ |
|
102 obj = JS_DefineObject(cx, global, "netscape", objectClass, nullptr, 0); |
|
103 if (obj == nullptr) |
|
104 return NS_ERROR_FAILURE; |
|
105 securityObj = JS_DefineObject(cx, obj, "security", objectClass, |
|
106 nullptr, 0); |
|
107 if (securityObj == nullptr) |
|
108 return NS_ERROR_FAILURE; |
|
109 } |
|
110 |
|
111 // We hide enablePrivilege behind a pref because it has been altered in a |
|
112 // way that makes it fundamentally insecure to use in production. Mozilla |
|
113 // uses this pref during automated testing to support legacy test code that |
|
114 // uses enablePrivilege. If you're not doing test automation, you _must_ not |
|
115 // flip this pref, or you will be exposing all your users to security |
|
116 // vulnerabilities. |
|
117 if (!Preferences::GetBool("security.turn_off_all_security_so_that_viruses_can_take_over_this_computer")) |
|
118 return NS_OK; |
|
119 |
|
120 /* Define PrivilegeManager object with the necessary "static" methods. */ |
|
121 obj = JS_DefineObject(cx, securityObj, "PrivilegeManager", objectClass, |
|
122 nullptr, 0); |
|
123 if (obj == nullptr) |
|
124 return NS_ERROR_FAILURE; |
|
125 |
|
126 return JS_DefineFunctions(cx, obj, PrivilegeManager_static_methods) |
|
127 ? NS_OK |
|
128 : NS_ERROR_FAILURE; |
|
129 } |