michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim: set ts=8 sts=4 et sw=4 tw=99: */ 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: michael@0: #ifndef __AccessCheck_h__ michael@0: #define __AccessCheck_h__ michael@0: michael@0: #include "jswrapper.h" michael@0: #include "js/Id.h" michael@0: michael@0: class nsIPrincipal; michael@0: michael@0: namespace xpc { michael@0: michael@0: class AccessCheck { michael@0: public: michael@0: static bool subsumes(JSCompartment *a, JSCompartment *b); michael@0: static bool subsumes(JSObject *a, JSObject *b); michael@0: static bool wrapperSubsumes(JSObject *wrapper); michael@0: static bool subsumesConsideringDomain(JSCompartment *a, JSCompartment *b); michael@0: static bool isChrome(JSCompartment *compartment); michael@0: static bool isChrome(JSObject *obj); michael@0: static bool callerIsChrome(); michael@0: static nsIPrincipal *getPrincipal(JSCompartment *compartment); michael@0: static bool isCrossOriginAccessPermitted(JSContext *cx, JSObject *obj, jsid id, michael@0: js::Wrapper::Action act); michael@0: }; michael@0: michael@0: struct Policy { michael@0: }; michael@0: michael@0: // This policy allows no interaction with the underlying callable. Everything throws. michael@0: struct Opaque : public Policy { michael@0: static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) { michael@0: return false; michael@0: } michael@0: static bool deny(js::Wrapper::Action act, JS::HandleId id) { michael@0: return false; michael@0: } michael@0: static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl) { michael@0: return false; michael@0: } michael@0: }; michael@0: michael@0: // Like the above, but allows CALL. michael@0: struct OpaqueWithCall : public Policy { michael@0: static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) { michael@0: return act == js::Wrapper::CALL; michael@0: } michael@0: static bool deny(js::Wrapper::Action act, JS::HandleId id) { michael@0: return false; michael@0: } michael@0: static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl) { michael@0: return false; michael@0: } michael@0: }; michael@0: michael@0: // This policy is designed to protect privileged callers from untrusted non- michael@0: // Xrayable objects. Nothing is allowed, and nothing throws. michael@0: struct GentlyOpaque : public Policy { michael@0: static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) { michael@0: return false; michael@0: } michael@0: static bool deny(js::Wrapper::Action act, JS::HandleId id) { michael@0: return true; michael@0: } michael@0: static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl) { michael@0: // We allow nativeCall here because the alternative is throwing (which michael@0: // happens in SecurityWrapper::nativeCall), which we don't want. There's michael@0: // unlikely to be too much harm to letting this through, because this michael@0: // wrapper is only used to wrap less-privileged objects in more-privileged michael@0: // scopes, so unwrapping here only drops privileges. michael@0: return true; michael@0: } michael@0: }; michael@0: michael@0: // This policy only permits access to properties that are safe to be used michael@0: // across origins. michael@0: struct CrossOriginAccessiblePropertiesOnly : public Policy { michael@0: static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act) { michael@0: return AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act); michael@0: } michael@0: static bool deny(js::Wrapper::Action act, JS::HandleId id) { michael@0: // Silently fail for enumerate-like operations. michael@0: if (act == js::Wrapper::ENUMERATE) michael@0: return true; michael@0: return false; michael@0: } michael@0: static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl) { michael@0: return false; michael@0: } michael@0: }; michael@0: michael@0: // This policy only permits access to properties if they appear in the michael@0: // objects exposed properties list. michael@0: struct ExposedPropertiesOnly : public Policy { michael@0: static bool check(JSContext *cx, JSObject *wrapper, jsid id, js::Wrapper::Action act); michael@0: michael@0: static bool deny(js::Wrapper::Action act, JS::HandleId id) { michael@0: // Fail silently for GETs and ENUMERATEs. michael@0: return act == js::Wrapper::GET || act == js::Wrapper::ENUMERATE; michael@0: } michael@0: static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl); michael@0: }; michael@0: michael@0: } michael@0: michael@0: #endif /* __AccessCheck_h__ */