~statik/etherpad/trunk

« back to all changes in this revision

Viewing changes to infrastructure/rhino1_7R1/src/org/mozilla/javascript/SecurityController.java

  • Committer: Elliot Murphy
  • Date: 2009-12-19 01:40:46 UTC
  • Revision ID: elliot@elliotmurphy.com-20091219014046-7icbb6oxc29ccdn3
Copied over from zero-history mercurial repo.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 
2
 *
 
3
 * ***** BEGIN LICENSE BLOCK *****
 
4
 * Version: MPL 1.1/GPL 2.0
 
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 Rhino code, released
 
17
 * May 6, 1999.
 
18
 *
 
19
 * The Initial Developer of the Original Code is
 
20
 * Netscape Communications Corporation.
 
21
 * Portions created by the Initial Developer are Copyright (C) 1997-1999
 
22
 * the Initial Developer. All Rights Reserved.
 
23
 *
 
24
 * Contributor(s):
 
25
 *   Norris Boyd
 
26
 *   Igor Bukanov
 
27
 *
 
28
 * Alternatively, the contents of this file may be used under the terms of
 
29
 * the GNU General Public License Version 2 or later (the "GPL"), in which
 
30
 * case the provisions of the GPL are applicable instead of those above. If
 
31
 * you wish to allow use of your version of this file only under the terms of
 
32
 * the GPL and not to allow others to use your version of this file under the
 
33
 * MPL, indicate your decision by deleting the provisions above and replacing
 
34
 * them with the notice and other provisions required by the GPL. If you do
 
35
 * not delete the provisions above, a recipient may use your version of this
 
36
 * file under either the MPL or the GPL.
 
37
 *
 
38
 * ***** END LICENSE BLOCK ***** */
 
39
 
 
40
// API class
 
41
 
 
42
package org.mozilla.javascript;
 
43
 
 
44
/**
 
45
 * This class describes the support needed to implement security.
 
46
 * <p>
 
47
 * Three main pieces of functionality are required to implement
 
48
 * security for JavaScript. First, it must be possible to define
 
49
 * classes with an associated security domain. (This security
 
50
 * domain may be any object incorporating notion of access
 
51
 * restrictions that has meaning to an embedding; for a client-side
 
52
 * JavaScript embedding this would typically be
 
53
 * java.security.ProtectionDomain or similar object depending on an
 
54
 * origin URL and/or a digital certificate.)
 
55
 * Next it must be possible to get a security domain object that
 
56
 * allows a particular action only if all security domains
 
57
 * associated with code on the current Java stack allows it. And
 
58
 * finally, it must be possible to execute script code with
 
59
 * associated security domain injected into Java stack.
 
60
 * <p>
 
61
 * These three pieces of functionality are encapsulated in the
 
62
 * SecurityController class.
 
63
 *
 
64
 * @see org.mozilla.javascript.Context#setSecurityController(SecurityController)
 
65
 * @see java.lang.ClassLoader
 
66
 * @since 1.5 Release 4
 
67
 */
 
68
public abstract class SecurityController
 
69
{
 
70
    private static SecurityController global;
 
71
 
 
72
// The method must NOT be public or protected
 
73
    static SecurityController global()
 
74
    {
 
75
        return global;
 
76
    }
 
77
 
 
78
    /**
 
79
     * Check if global {@link SecurityController} was already installed.
 
80
     * @see #initGlobal(SecurityController controller)
 
81
     */
 
82
    public static boolean hasGlobal()
 
83
    {
 
84
        return global != null;
 
85
    }
 
86
 
 
87
    /**
 
88
     * Initialize global controller that will be used for all
 
89
     * security-related operations. The global controller takes precedence
 
90
     * over already installed {@link Context}-specific controllers and cause
 
91
     * any subsequent call to
 
92
     * {@link Context#setSecurityController(SecurityController)}
 
93
     * to throw an exception.
 
94
     * <p>
 
95
     * The method can only be called once.
 
96
     *
 
97
     * @see #hasGlobal()
 
98
     */
 
99
    public static void initGlobal(SecurityController controller)
 
100
    {
 
101
        if (controller == null) throw new IllegalArgumentException();
 
102
        if (global != null) {
 
103
            throw new SecurityException("Cannot overwrite already installed global SecurityController");
 
104
        }
 
105
        global = controller;
 
106
    }
 
107
 
 
108
    /**
 
109
     * Get class loader-like object that can be used
 
110
     * to define classes with the given security context.
 
111
     * @param parentLoader parent class loader to delegate search for classes
 
112
     *        not defined by the class loader itself
 
113
     * @param securityDomain some object specifying the security
 
114
     *        context of the code that is defined by the returned class loader.
 
115
     */
 
116
    public abstract GeneratedClassLoader createClassLoader(
 
117
        ClassLoader parentLoader, Object securityDomain);
 
118
 
 
119
    /**
 
120
     * Create {@link GeneratedClassLoader} with restrictions imposed by
 
121
     * staticDomain and all current stack frames.
 
122
     * The method uses the SecurityController instance associated with the
 
123
     * current {@link Context} to construct proper dynamic domain and create
 
124
     * corresponding class loader.
 
125
     * <par>
 
126
     * If no SecurityController is associated with the current {@link Context} ,
 
127
     * the method calls {@link Context#createClassLoader(ClassLoader parent)}.
 
128
     *
 
129
     * @param parent parent class loader. If null,
 
130
     *        {@link Context#getApplicationClassLoader()} will be used.
 
131
     * @param staticDomain static security domain.
 
132
     */
 
133
    public static GeneratedClassLoader createLoader(
 
134
        ClassLoader parent, Object staticDomain)
 
135
    {
 
136
        Context cx = Context.getContext();
 
137
        if (parent == null) {
 
138
            parent = cx.getApplicationClassLoader();
 
139
        }
 
140
        SecurityController sc = cx.getSecurityController();
 
141
        GeneratedClassLoader loader;
 
142
        if (sc == null) {
 
143
            loader = cx.createClassLoader(parent);
 
144
        } else {
 
145
            Object dynamicDomain = sc.getDynamicSecurityDomain(staticDomain);
 
146
            loader = sc.createClassLoader(parent, dynamicDomain);
 
147
        }
 
148
        return loader;
 
149
    }
 
150
 
 
151
    public static Class getStaticSecurityDomainClass() {
 
152
        SecurityController sc = Context.getContext().getSecurityController();
 
153
        return sc == null ? null : sc.getStaticSecurityDomainClassInternal(); 
 
154
    }
 
155
    
 
156
    public Class getStaticSecurityDomainClassInternal()
 
157
    {
 
158
        return null;
 
159
    }
 
160
 
 
161
    /**
 
162
     * Get dynamic security domain that allows an action only if it is allowed
 
163
     * by the current Java stack and <i>securityDomain</i>. If
 
164
     * <i>securityDomain</i> is null, return domain representing permissions
 
165
     * allowed by the current stack.
 
166
     */
 
167
    public abstract Object getDynamicSecurityDomain(Object securityDomain);
 
168
 
 
169
    /**
 
170
     * Call {@link
 
171
     * Callable#call(Context cx, Scriptable scope, Scriptable thisObj,
 
172
     *               Object[] args)}
 
173
     * of <i>callable</i> under restricted security domain where an action is
 
174
     * allowed only if it is allowed according to the Java stack on the
 
175
     * moment of the <i>execWithDomain</i> call and <i>securityDomain</i>.
 
176
     * Any call to {@link #getDynamicSecurityDomain(Object)} during
 
177
     * execution of <tt>callable.call(cx, scope, thisObj, args)</tt>
 
178
     * should return a domain incorporate restrictions imposed by
 
179
     * <i>securityDomain</i> and Java stack on the moment of callWithDomain
 
180
     * invocation.
 
181
     * <p>
 
182
     * The method should always be overridden, it is not declared abstract
 
183
     * for compatibility reasons.
 
184
     */
 
185
    public Object callWithDomain(Object securityDomain, Context cx,
 
186
                                 final Callable callable, Scriptable scope,
 
187
                                 final Scriptable thisObj, final Object[] args)
 
188
    {
 
189
        return execWithDomain(cx, scope, new Script()
 
190
        {
 
191
            public Object exec(Context cx, Scriptable scope)
 
192
            {
 
193
                return callable.call(cx, scope, thisObj, args);
 
194
            }
 
195
 
 
196
        }, securityDomain);
 
197
    }
 
198
 
 
199
    /**
 
200
     * @deprecated The application should not override this method and instead
 
201
     * override
 
202
     * {@link #callWithDomain(Object securityDomain, Context cx, Callable callable, Scriptable scope, Scriptable thisObj, Object[] args)}.
 
203
     */
 
204
    public Object execWithDomain(Context cx, Scriptable scope,
 
205
                                 Script script, Object securityDomain)
 
206
    {
 
207
        throw new IllegalStateException("callWithDomain should be overridden");
 
208
    }
 
209
 
 
210
 
 
211
}