src/java.desktop/share/classes/sun/applet/AppletSecurity.java
branchJDK-8200758-branch
changeset 56910 410fd33a2c81
parent 56902 6972c0e75e23
parent 51966 2a2a78bd1fc3
child 56933 9f59eeb3cc0f
--- a/src/java.desktop/share/classes/sun/applet/AppletSecurity.java	Fri Sep 21 09:32:02 2018 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,421 +0,0 @@
-/*
- * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.applet;
-
-import java.io.File;
-import java.io.FilePermission;
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.net.SocketPermission;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.HashSet;
-import java.util.StringTokenizer;
-import java.security.*;
-import java.lang.reflect.*;
-import jdk.internal.misc.JavaNetURLClassLoaderAccess;
-import jdk.internal.misc.JavaSecurityAccess;
-import jdk.internal.misc.SharedSecrets;
-import sun.awt.AWTSecurityManager;
-import sun.awt.AppContext;
-import sun.awt.AWTPermissions;
-import sun.security.util.SecurityConstants;
-
-import static java.lang.StackWalker.*;
-import static java.lang.StackWalker.Option.*;
-
-
-/**
- * This class defines an applet security policy
- *
- */
-public
-class AppletSecurity extends AWTSecurityManager {
-    private static final JavaNetURLClassLoaderAccess JNUCLA
-            = SharedSecrets.getJavaNetURLClassLoaderAccess();
-    private static final JavaSecurityAccess JSA = SharedSecrets.getJavaSecurityAccess();
-
-    /**
-     * Construct and initialize.
-     */
-    public AppletSecurity() {
-        reset();
-    }
-
-    // Cache to store known restricted packages
-    private HashSet<String> restrictedPackages = new HashSet<>();
-
-    /**
-     * Reset from Properties
-     */
-    public void reset()
-    {
-        // Clear cache
-        restrictedPackages.clear();
-
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run()
-            {
-                // Enumerate system properties
-                Enumeration<?> e = System.getProperties().propertyNames();
-
-                while (e.hasMoreElements())
-                {
-                    String name = (String) e.nextElement();
-
-                    if (name != null && name.startsWith("package.restrict.access."))
-                    {
-                        String value = System.getProperty(name);
-
-                        if (value != null && value.equalsIgnoreCase("true"))
-                        {
-                            String pkg = name.substring(24);
-
-                            // Cache restricted packages
-                            restrictedPackages.add(pkg);
-                        }
-                    }
-                }
-                return null;
-            }
-        });
-    }
-
-    private static final StackWalker walker =
-        AccessController.doPrivileged(
-            (PrivilegedAction<StackWalker>) () ->
-                StackWalker.getInstance(RETAIN_CLASS_REFERENCE));
-    /**
-     * Returns the class loader of the most recently executing method from
-     * a class defined using a non-system class loader. A non-system
-     * class loader is defined as being a class loader that is not equal to
-     * the system class loader (as returned
-     * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors.
-     * <p>
-     * This method will return
-     * <code>null</code> in the following three cases:
-     * <ol>
-     *   <li>All methods on the execution stack are from classes
-     *   defined using the system class loader or one of its ancestors.
-     *
-     *   <li>All methods on the execution stack up to the first
-     *   "privileged" caller
-     *   (see {@link java.security.AccessController#doPrivileged})
-     *   are from classes
-     *   defined using the system class loader or one of its ancestors.
-     *
-     *   <li> A call to <code>checkPermission</code> with
-     *   <code>java.security.AllPermission</code> does not
-     *   result in a SecurityException.
-     * </ol>
-     *
-     * NOTE: This is an implementation of the SecurityManager.currentClassLoader
-     * method that uses StackWalker. SecurityManager.currentClassLoader
-     * has been removed from SE. This is a temporary workaround which is
-     * only needed while applets are still supported.
-     *
-     * @return  the class loader of the most recent occurrence on the stack
-     *          of a method from a class defined using a non-system class
-     *          loader.
-     */
-    private static ClassLoader currentClassLoader() {
-        StackFrame f =
-            walker.walk(s -> s.takeWhile(AppletSecurity::isNonPrivileged)
-                              .filter(AppletSecurity::isNonSystemFrame)
-                              .findFirst())
-                  .orElse(null);
-
-        SecurityManager sm = System.getSecurityManager();
-        if (f != null && sm != null) {
-            try {
-                sm.checkPermission(new AllPermission());
-            } catch (SecurityException se) {
-                return f.getDeclaringClass().getClassLoader();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns true if the StackFrame is not AccessController.doPrivileged.
-     */
-    private static boolean isNonPrivileged(StackFrame f) {
-        // possibly other doPrivileged variants
-        Class<?> c = f.getDeclaringClass();
-        return c == AccessController.class &&
-               f.getMethodName().equals("doPrivileged");
-    }
-
-    /**
-     * Returns true if the StackFrame is not from a class defined by the
-     * system class loader or one of its ancestors.
-     */
-    private static boolean isNonSystemFrame(StackFrame f) {
-        ClassLoader loader = ClassLoader.getSystemClassLoader();
-        ClassLoader ld = f.getDeclaringClass().getClassLoader();
-        if (ld == null || ld == loader) return false;
-
-        while ((loader = loader.getParent()) != null) {
-            if (ld == loader)
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * get the current (first) instance of an AppletClassLoader on the stack.
-     */
-    private AppletClassLoader currentAppletClassLoader()
-    {
-        // try currentClassLoader first
-        ClassLoader loader = currentClassLoader();
-
-        if ((loader == null) || (loader instanceof AppletClassLoader))
-            return (AppletClassLoader)loader;
-
-        // if that fails, get all the classes on the stack and check them.
-        Class<?>[] context = getClassContext();
-        for (int i = 0; i < context.length; i++) {
-            loader = context[i].getClassLoader();
-            if (loader instanceof AppletClassLoader)
-                return (AppletClassLoader)loader;
-        }
-
-        /*
-         * fix bug # 6433620 the logic here is : try to find URLClassLoader from
-         * class context, check its AccessControlContext to see if
-         * AppletClassLoader is in stack when it's created. for this kind of
-         * URLClassLoader, return the AppContext associated with the
-         * AppletClassLoader.
-         */
-        for (int i = 0; i < context.length; i++) {
-            final ClassLoader currentLoader = context[i].getClassLoader();
-
-            if (currentLoader instanceof URLClassLoader) {
-                URLClassLoader ld = (URLClassLoader)currentLoader;
-                loader = AccessController.doPrivileged(
-                    new PrivilegedAction<ClassLoader>() {
-                        public ClassLoader run() {
-
-                            AccessControlContext acc = null;
-                            ProtectionDomain[] pds = null;
-
-                            try {
-                                acc = JNUCLA.getAccessControlContext(ld);
-                                if (acc == null) {
-                                    return null;
-                                }
-
-                                pds = JSA.getProtectDomains(acc);
-                                if (pds == null) {
-                                    return null;
-                                }
-                            } catch (Exception e) {
-                                throw new UnsupportedOperationException(e);
-                            }
-
-                            for (int i=0; i<pds.length; i++) {
-                                ClassLoader cl = pds[i].getClassLoader();
-
-                                if (cl instanceof AppletClassLoader) {
-                                        return cl;
-                                }
-                            }
-
-                            return null;
-                        }
-                    });
-
-                if (loader != null) {
-                    return (AppletClassLoader) loader;
-                }
-            }
-        }
-
-        // if that fails, try the context class loader
-        loader = Thread.currentThread().getContextClassLoader();
-        if (loader instanceof AppletClassLoader)
-            return (AppletClassLoader)loader;
-
-        // no AppletClassLoaders on the stack
-        return (AppletClassLoader)null;
-    }
-
-    /**
-     * Returns true if this threadgroup is in the applet's own thread
-     * group. This will return false if there is no current class
-     * loader.
-     */
-    protected boolean inThreadGroup(ThreadGroup g) {
-        if (currentAppletClassLoader() == null)
-            return false;
-        else
-            return getThreadGroup().parentOf(g);
-    }
-
-    /**
-     * Returns true of the threadgroup of thread is in the applet's
-     * own threadgroup.
-     */
-    protected boolean inThreadGroup(Thread thread) {
-        return inThreadGroup(thread.getThreadGroup());
-    }
-
-    /**
-     * Applets are not allowed to manipulate threads outside
-     * applet thread groups. However a terminated thread no longer belongs
-     * to any group.
-     */
-    public void checkAccess(Thread t) {
-        /* When multiple applets is reloaded simultaneously, there will be
-         * multiple invocations to this method from plugin's SecurityManager.
-         * This method should not be synchronized to avoid deadlock when
-         * a page with multiple applets is reloaded
-         */
-        if ((t.getState() != Thread.State.TERMINATED) && !inThreadGroup(t)) {
-            checkPermission(SecurityConstants.MODIFY_THREAD_PERMISSION);
-        }
-    }
-
-    private boolean inThreadGroupCheck = false;
-
-    /**
-     * Applets are not allowed to manipulate thread groups outside
-     * applet thread groups.
-     */
-    public synchronized void checkAccess(ThreadGroup g) {
-        if (inThreadGroupCheck) {
-            // if we are in a recursive check, it is because
-            // inThreadGroup is calling appletLoader.getThreadGroup
-            // in that case, only do the super check, as appletLoader
-            // has a begin/endPrivileged
-            checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
-        } else {
-            try {
-                inThreadGroupCheck = true;
-                if (!inThreadGroup(g)) {
-                    checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
-                }
-            } finally {
-                inThreadGroupCheck = false;
-            }
-        }
-    }
-
-
-    /**
-     * Throws a {@code SecurityException} if the
-     * calling thread is not allowed to access the package specified by
-     * the argument.
-     * <p>
-     * This method is used by the {@code loadClass} method of class
-     * loaders.
-     * <p>
-     * The {@code checkPackageAccess} method for class
-     * {@code SecurityManager}  calls
-     * {@code checkPermission} with the
-     * {@code RuntimePermission("accessClassInPackage."+ pkgname)}
-     * permission.
-     *
-     * @param      pkgname   the package name.
-     * @exception  SecurityException  if the caller does not have
-     *             permission to access the specified package.
-     * @see        java.lang.ClassLoader#loadClass(java.lang.String, boolean)
-     */
-    public void checkPackageAccess(final String pkgname) {
-
-        // first see if the VM-wide policy allows access to this package
-        super.checkPackageAccess(pkgname);
-
-        // now check the list of restricted packages
-        for (Iterator<String> iter = restrictedPackages.iterator(); iter.hasNext();)
-        {
-            String pkg = iter.next();
-
-            // Prevent matching "sun" and "sunir" even if they
-            // starts with similar beginning characters
-            //
-            if (pkgname.equals(pkg) || pkgname.startsWith(pkg + "."))
-            {
-                checkPermission(new java.lang.RuntimePermission
-                            ("accessClassInPackage." + pkgname));
-            }
-        }
-    }
-
-    /**
-     * Returns the thread group of the applet. We consult the classloader
-     * if there is one.
-     */
-    public ThreadGroup getThreadGroup() {
-        /* If any applet code is on the execution stack, we return
-           that applet's ThreadGroup.  Otherwise, we use the default
-           behavior. */
-        AppletClassLoader appletLoader = currentAppletClassLoader();
-        ThreadGroup loaderGroup = (appletLoader == null) ? null
-                                          : appletLoader.getThreadGroup();
-        if (loaderGroup != null) {
-            return loaderGroup;
-        } else {
-            return super.getThreadGroup();
-        }
-    } // getThreadGroup()
-
-    /**
-      * Get the AppContext corresponding to the current context.
-      * The default implementation returns null, but this method
-      * may be overridden by various SecurityManagers
-      * (e.g. AppletSecurity) to index AppContext objects by the
-      * calling context.
-      *
-      * @return  the AppContext corresponding to the current context.
-      * @see     sun.awt.AppContext
-      * @see     java.lang.SecurityManager
-      * @since   1.2.1
-      */
-    public AppContext getAppContext() {
-        AppletClassLoader appletLoader = currentAppletClassLoader();
-
-        if (appletLoader == null) {
-            return null;
-        } else {
-            AppContext context =  appletLoader.getAppContext();
-
-            // context == null when some thread in applet thread group
-            // has not been destroyed in AppContext.dispose()
-            if (context == null) {
-                throw new SecurityException("Applet classloader has invalid AppContext");
-            }
-
-            return context;
-        }
-    }
-
-} // class AppletSecurity