1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim: set ts=4 sw=4 et tw=99 ft=cpp: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code, released
17 : * June 24, 2010.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * the Mozilla Foundation.
21 : * Portions created by the Initial Developer are Copyright (C) 2010
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : * Andreas Gal <gal@mozilla.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either of the GNU General Public License Version 2 or later (the "GPL"),
29 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "FilteringWrapper.h"
42 : #include "AccessCheck.h"
43 : #include "CrossOriginWrapper.h"
44 : #include "XrayWrapper.h"
45 : #include "WrapperFactory.h"
46 :
47 : #include "XPCWrapper.h"
48 :
49 : #include "jsapi.h"
50 :
51 : using namespace js;
52 :
53 : namespace xpc {
54 :
55 : template <typename Base, typename Policy>
56 11712 : FilteringWrapper<Base, Policy>::FilteringWrapper(unsigned flags) : Base(flags)
57 : {
58 11712 : }
59 :
60 : template <typename Base, typename Policy>
61 11896 : FilteringWrapper<Base, Policy>::~FilteringWrapper()
62 11896 : {
63 23792 : }
64 :
65 : typedef Wrapper::Permission Permission;
66 :
67 : static const Permission PermitObjectAccess = Wrapper::PermitObjectAccess;
68 : static const Permission PermitPropertyAccess = Wrapper::PermitPropertyAccess;
69 : static const Permission DenyAccess = Wrapper::DenyAccess;
70 :
71 : template <typename Policy>
72 : static bool
73 0 : Filter(JSContext *cx, JSObject *wrapper, AutoIdVector &props)
74 : {
75 0 : size_t w = 0;
76 0 : for (size_t n = 0; n < props.length(); ++n) {
77 0 : jsid id = props[n];
78 : Permission perm;
79 0 : if (!Policy::check(cx, wrapper, id, Wrapper::GET, perm))
80 0 : return false; // Error
81 0 : if (perm != DenyAccess)
82 0 : props[w++] = id;
83 : }
84 0 : props.resize(w);
85 0 : return true;
86 : }
87 :
88 : template <typename Base, typename Policy>
89 : bool
90 0 : FilteringWrapper<Base, Policy>::getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props)
91 : {
92 : return Base::getOwnPropertyNames(cx, wrapper, props) &&
93 0 : Filter<Policy>(cx, wrapper, props);
94 : }
95 :
96 : template <typename Base, typename Policy>
97 : bool
98 0 : FilteringWrapper<Base, Policy>::enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props)
99 : {
100 : return Base::enumerate(cx, wrapper, props) &&
101 0 : Filter<Policy>(cx, wrapper, props);
102 : }
103 :
104 : template <typename Base, typename Policy>
105 : bool
106 0 : FilteringWrapper<Base, Policy>::keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props)
107 : {
108 : return Base::keys(cx, wrapper, props) &&
109 0 : Filter<Policy>(cx, wrapper, props);
110 : }
111 :
112 : template <typename Base, typename Policy>
113 : bool
114 0 : FilteringWrapper<Base, Policy>::iterate(JSContext *cx, JSObject *wrapper, unsigned flags, Value *vp)
115 : {
116 : // We refuse to trigger the iterator hook across chrome wrappers because
117 : // we don't know how to censor custom iterator objects. Instead we trigger
118 : // the default proxy iterate trap, which will ask enumerate() for the list
119 : // of (consored) ids.
120 0 : return js::ProxyHandler::iterate(cx, wrapper, flags, vp);
121 : }
122 :
123 : template <typename Base, typename Policy>
124 : bool
125 0 : FilteringWrapper<Base, Policy>::enter(JSContext *cx, JSObject *wrapper, jsid id,
126 : Wrapper::Action act, bool *bp)
127 : {
128 : Permission perm;
129 0 : if (!Policy::check(cx, wrapper, id, act, perm)) {
130 0 : *bp = false;
131 0 : return false;
132 : }
133 0 : *bp = true;
134 0 : if (perm == DenyAccess)
135 0 : return false;
136 0 : return Base::enter(cx, wrapper, id, act, bp);
137 : }
138 :
139 : #define SOW FilteringWrapper<CrossCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>
140 : #define SCSOW FilteringWrapper<SameCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>
141 : #define COW FilteringWrapper<CrossCompartmentSecurityWrapper, ExposedPropertiesOnly>
142 : #define XOW FilteringWrapper<XrayWrapper<CrossCompartmentSecurityWrapper>, \
143 : CrossOriginAccessiblePropertiesOnly>
144 : #define PXOW FilteringWrapper<XrayProxy, \
145 : CrossOriginAccessiblePropertiesOnly>
146 : #define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, \
147 : CrossOriginAccessiblePropertiesOnly>
148 : #define LW FilteringWrapper<XrayWrapper<SameCompartmentSecurityWrapper>, \
149 : SameOriginOrCrossOriginAccessiblePropertiesOnly>
150 : #define XLW FilteringWrapper<XrayWrapper<CrossCompartmentSecurityWrapper>, \
151 : SameOriginOrCrossOriginAccessiblePropertiesOnly>
152 :
153 1464 : template<> SOW SOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
154 1464 : WrapperFactory::SOW_FLAG);
155 1464 : template<> SCSOW SCSOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
156 1464 : WrapperFactory::SOW_FLAG);
157 1464 : template<> COW COW::singleton(0);
158 1464 : template<> XOW XOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
159 1464 : WrapperFactory::PARTIALLY_TRANSPARENT);
160 1464 : template<> PXOW PXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
161 1464 : WrapperFactory::PARTIALLY_TRANSPARENT);
162 1464 : template<> NNXOW NNXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
163 1464 : WrapperFactory::PARTIALLY_TRANSPARENT);
164 1464 : template<> LW LW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);
165 1464 : template<> XLW XLW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);
166 :
167 : template class SOW;
168 : template class COW;
169 : template class XOW;
170 : template class PXOW;
171 : template class NNXOW;
172 : template class LW;
173 : template class XLW;
174 :
175 4392 : }
|