0N/A/*
3909N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage java.security;
0N/A
0N/Aimport java.util.HashMap;
0N/Aimport java.util.ArrayList;
0N/Aimport java.net.URL;
0N/A
0N/Aimport sun.security.util.Debug;
0N/A
0N/A/**
0N/A * This class extends ClassLoader with additional support for defining
0N/A * classes with an associated code source and permissions which are
0N/A * retrieved by the system policy by default.
0N/A *
0N/A * @author Li Gong
0N/A * @author Roland Schemers
0N/A */
0N/Apublic class SecureClassLoader extends ClassLoader {
0N/A /*
0N/A * If initialization succeed this is set to true and security checks will
0N/A * succeed. Otherwise the object is not initialized and the object is
0N/A * useless.
0N/A */
1042N/A private final boolean initialized;
0N/A
0N/A // HashMap that maps CodeSource to ProtectionDomain
1042N/A // @GuardedBy("pdcache")
1042N/A private final HashMap<CodeSource, ProtectionDomain> pdcache =
3381N/A new HashMap<>(11);
0N/A
0N/A private static final Debug debug = Debug.getInstance("scl");
0N/A
1042N/A static {
1042N/A ClassLoader.registerAsParallelCapable();
1042N/A }
1042N/A
0N/A /**
0N/A * Creates a new SecureClassLoader using the specified parent
0N/A * class loader for delegation.
0N/A *
0N/A * <p>If there is a security manager, this method first
0N/A * calls the security manager's <code>checkCreateClassLoader</code>
0N/A * method to ensure creation of a class loader is allowed.
0N/A * <p>
0N/A * @param parent the parent ClassLoader
0N/A * @exception SecurityException if a security manager exists and its
0N/A * <code>checkCreateClassLoader</code> method doesn't allow
0N/A * creation of a class loader.
0N/A * @see SecurityManager#checkCreateClassLoader
0N/A */
0N/A protected SecureClassLoader(ClassLoader parent) {
0N/A super(parent);
0N/A // this is to make the stack depth consistent with 1.1
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A security.checkCreateClassLoader();
0N/A }
0N/A initialized = true;
0N/A }
0N/A
0N/A /**
0N/A * Creates a new SecureClassLoader using the default parent class
0N/A * loader for delegation.
0N/A *
0N/A * <p>If there is a security manager, this method first
0N/A * calls the security manager's <code>checkCreateClassLoader</code>
0N/A * method to ensure creation of a class loader is allowed.
0N/A *
0N/A * @exception SecurityException if a security manager exists and its
0N/A * <code>checkCreateClassLoader</code> method doesn't allow
0N/A * creation of a class loader.
0N/A * @see SecurityManager#checkCreateClassLoader
0N/A */
0N/A protected SecureClassLoader() {
0N/A super();
0N/A // this is to make the stack depth consistent with 1.1
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A security.checkCreateClassLoader();
0N/A }
0N/A initialized = true;
0N/A }
0N/A
0N/A /**
0N/A * Converts an array of bytes into an instance of class Class,
0N/A * with an optional CodeSource. Before the
0N/A * class can be used it must be resolved.
0N/A * <p>
0N/A * If a non-null CodeSource is supplied a ProtectionDomain is
0N/A * constructed and associated with the class being defined.
0N/A * <p>
0N/A * @param name the expected name of the class, or <code>null</code>
0N/A * if not known, using '.' and not '/' as the separator
0N/A * and without a trailing ".class" suffix.
0N/A * @param b the bytes that make up the class data. The bytes in
0N/A * positions <code>off</code> through <code>off+len-1</code>
4008N/A * should have the format of a valid class file as defined by
4008N/A * <cite>The Java&trade; Virtual Machine Specification</cite>.
0N/A * @param off the start offset in <code>b</code> of the class data
0N/A * @param len the length of the class data
0N/A * @param cs the associated CodeSource, or <code>null</code> if none
0N/A * @return the <code>Class</code> object created from the data,
0N/A * and optional CodeSource.
0N/A * @exception ClassFormatError if the data did not contain a valid class
0N/A * @exception IndexOutOfBoundsException if either <code>off</code> or
0N/A * <code>len</code> is negative, or if
0N/A * <code>off+len</code> is greater than <code>b.length</code>.
0N/A *
0N/A * @exception SecurityException if an attempt is made to add this class
0N/A * to a package that contains classes that were signed by
0N/A * a different set of certificates than this class, or if
0N/A * the class name begins with "java.".
0N/A */
0N/A protected final Class<?> defineClass(String name,
0N/A byte[] b, int off, int len,
0N/A CodeSource cs)
0N/A {
1042N/A return defineClass(name, b, off, len, getProtectionDomain(cs));
0N/A }
0N/A
0N/A /**
0N/A * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
0N/A * into an instance of class <tt>Class</tt>, with an optional CodeSource.
0N/A * Before the class can be used it must be resolved.
0N/A * <p>
0N/A * If a non-null CodeSource is supplied a ProtectionDomain is
0N/A * constructed and associated with the class being defined.
0N/A * <p>
0N/A * @param name the expected name of the class, or <code>null</code>
0N/A * if not known, using '.' and not '/' as the separator
0N/A * and without a trailing ".class" suffix.
0N/A * @param b the bytes that make up the class data. The bytes from positions
0N/A * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1</tt>
4008N/A * should have the format of a valid class file as defined by
4008N/A * <cite>The Java&trade; Virtual Machine Specification</cite>.
0N/A * @param cs the associated CodeSource, or <code>null</code> if none
0N/A * @return the <code>Class</code> object created from the data,
0N/A * and optional CodeSource.
0N/A * @exception ClassFormatError if the data did not contain a valid class
0N/A * @exception SecurityException if an attempt is made to add this class
0N/A * to a package that contains classes that were signed by
0N/A * a different set of certificates than this class, or if
0N/A * the class name begins with "java.".
0N/A *
0N/A * @since 1.5
0N/A */
0N/A protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
0N/A CodeSource cs)
0N/A {
1042N/A return defineClass(name, b, getProtectionDomain(cs));
0N/A }
0N/A
0N/A /**
0N/A * Returns the permissions for the given CodeSource object.
0N/A * <p>
0N/A * This method is invoked by the defineClass method which takes
0N/A * a CodeSource as an argument when it is constructing the
0N/A * ProtectionDomain for the class being defined.
0N/A * <p>
0N/A * @param codesource the codesource.
0N/A *
0N/A * @return the permissions granted to the codesource.
0N/A *
0N/A */
0N/A protected PermissionCollection getPermissions(CodeSource codesource)
0N/A {
0N/A check();
0N/A return new Permissions(); // ProtectionDomain defers the binding
0N/A }
0N/A
0N/A /*
0N/A * Returned cached ProtectionDomain for the specified CodeSource.
0N/A */
0N/A private ProtectionDomain getProtectionDomain(CodeSource cs) {
0N/A if (cs == null)
0N/A return null;
0N/A
0N/A ProtectionDomain pd = null;
0N/A synchronized (pdcache) {
0N/A pd = pdcache.get(cs);
0N/A if (pd == null) {
0N/A PermissionCollection perms = getPermissions(cs);
0N/A pd = new ProtectionDomain(cs, perms, this, null);
1042N/A pdcache.put(cs, pd);
1042N/A if (debug != null) {
1042N/A debug.println(" getPermissions "+ pd);
1042N/A debug.println("");
0N/A }
0N/A }
0N/A }
0N/A return pd;
0N/A }
0N/A
0N/A /*
0N/A * Check to make sure the class loader has been initialized.
0N/A */
0N/A private void check() {
0N/A if (!initialized) {
0N/A throw new SecurityException("ClassLoader object not initialized");
0N/A }
0N/A }
0N/A
0N/A}