aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java')
-rw-r--r--trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java240
1 files changed, 240 insertions, 0 deletions
diff --git a/trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java b/trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java
new file mode 100644
index 0000000..de39a5e
--- /dev/null
+++ b/trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/shell/JavaPolicySecurity.java
@@ -0,0 +1,240 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Igor Bukanov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.shell;
+
+import java.security.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.mozilla.javascript.*;
+
+public class JavaPolicySecurity extends SecurityProxy
+{
+
+ public Class getStaticSecurityDomainClassInternal() {
+ return ProtectionDomain.class;
+ }
+
+ private static class Loader extends ClassLoader
+ implements GeneratedClassLoader
+ {
+ private ProtectionDomain domain;
+
+ Loader(ClassLoader parent, ProtectionDomain domain) {
+ super(parent != null ? parent : getSystemClassLoader());
+ this.domain = domain;
+ }
+
+ public Class defineClass(String name, byte[] data) {
+ return super.defineClass(name, data, 0, data.length, domain);
+ }
+
+ public void linkClass(Class cl) {
+ resolveClass(cl);
+ }
+ }
+
+ private static class ContextPermissions extends PermissionCollection
+ {
+ static final long serialVersionUID = -1721494496320750721L;
+
+// Construct PermissionCollection that permits an action only
+// if it is permitted by staticDomain and by security context of Java stack on
+// the moment of constructor invocation
+ ContextPermissions(ProtectionDomain staticDomain) {
+ _context = AccessController.getContext();
+ if (staticDomain != null) {
+ _statisPermissions = staticDomain.getPermissions();
+ }
+ setReadOnly();
+ }
+
+ public void add(Permission permission) {
+ throw new RuntimeException("NOT IMPLEMENTED");
+ }
+
+ public boolean implies(Permission permission) {
+ if (_statisPermissions != null) {
+ if (!_statisPermissions.implies(permission)) {
+ return false;
+ }
+ }
+ try {
+ _context.checkPermission(permission);
+ return true;
+ }catch (AccessControlException ex) {
+ return false;
+ }
+ }
+
+ public Enumeration elements()
+ {
+ return new Enumeration() {
+ public boolean hasMoreElements() { return false; }
+ public Object nextElement() { return null; }
+ };
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append('@');
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" (context=");
+ sb.append(_context);
+ sb.append(", static_permitions=");
+ sb.append(_statisPermissions);
+ sb.append(')');
+ return sb.toString();
+ }
+
+ AccessControlContext _context;
+ PermissionCollection _statisPermissions;
+ }
+
+ public JavaPolicySecurity()
+ {
+ // To trigger error on jdk-1.1 with lazy load
+ new CodeSource(null, (java.security.cert.Certificate[])null);
+ }
+
+ protected void callProcessFileSecure(final Context cx,
+ final Scriptable scope,
+ final String filename)
+ {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ URL url = getUrlObj(filename);
+ ProtectionDomain staticDomain = getUrlDomain(url);
+ Main.processFileSecure(cx, scope, url.toExternalForm(),
+ staticDomain);
+ return null;
+ }
+ });
+ }
+
+ private URL getUrlObj(String url)
+ {
+ URL urlObj;
+ try {
+ urlObj = new URL(url);
+ } catch (MalformedURLException ex) {
+ // Assume as Main.processFileSecure it is file, need to build its
+ // URL
+ String curDir = System.getProperty("user.dir");
+ curDir = curDir.replace('\\', '/');
+ if (!curDir.endsWith("/")) {
+ curDir = curDir+'/';
+ }
+ try {
+ URL curDirURL = new URL("file:"+curDir);
+ urlObj = new URL(curDirURL, url);
+ } catch (MalformedURLException ex2) {
+ throw new RuntimeException
+ ("Can not construct file URL for '"+url+"':"
+ +ex2.getMessage());
+ }
+ }
+ return urlObj;
+ }
+
+ private ProtectionDomain getUrlDomain(URL url)
+ {
+ CodeSource cs;
+ cs = new CodeSource(url, (java.security.cert.Certificate[])null);
+ PermissionCollection pc = Policy.getPolicy().getPermissions(cs);
+ return new ProtectionDomain(cs, pc);
+ }
+
+ public GeneratedClassLoader
+ createClassLoader(ClassLoader parentLoader, Object securityDomain)
+ {
+ ProtectionDomain domain = (ProtectionDomain)securityDomain;
+ return new Loader(parentLoader, domain);
+ }
+
+ public Object getDynamicSecurityDomain(Object securityDomain)
+ {
+ ProtectionDomain staticDomain = (ProtectionDomain)securityDomain;
+ return getDynamicDomain(staticDomain);
+ }
+
+ private ProtectionDomain getDynamicDomain(ProtectionDomain staticDomain) {
+ ContextPermissions p = new ContextPermissions(staticDomain);
+ ProtectionDomain contextDomain = new ProtectionDomain(null, p);
+ return contextDomain;
+ }
+
+ public Object callWithDomain(Object securityDomain,
+ final Context cx,
+ final Callable callable,
+ final Scriptable scope,
+ final Scriptable thisObj,
+ final Object[] args)
+ {
+ ProtectionDomain staticDomain = (ProtectionDomain)securityDomain;
+ // There is no direct way in Java to intersect permitions according
+ // stack context with additional domain.
+ // The following implementation first constructs ProtectionDomain
+ // that allows actions only allowed by both staticDomain and current
+ // stack context, and then constructs AccessController for this dynamic
+ // domain.
+ // If this is too slow, alternative solution would be to generate
+ // class per domain with a proxy method to call to infect
+ // java stack.
+ // Another optimization in case of scripts coming from "world" domain,
+ // that is having minimal default privileges is to construct
+ // one AccessControlContext based on ProtectionDomain
+ // with least possible privileges and simply call
+ // AccessController.doPrivileged with this untrusted context
+
+ ProtectionDomain dynamicDomain = getDynamicDomain(staticDomain);
+ ProtectionDomain[] tmp = { dynamicDomain };
+ AccessControlContext restricted = new AccessControlContext(tmp);
+
+ PrivilegedAction action = new PrivilegedAction() {
+ public Object run() {
+ return callable.call(cx, scope, thisObj, args);
+ }
+ };
+
+ return AccessController.doPrivileged(action, restricted);
+ }
+}