1 /*
2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.security;
27 
28 import java.util.HashMap;
29 import java.util.ArrayList;
30 import java.net.URL;
31 
32 import sun.security.util.Debug;
33 
34 /**
35  * This class extends ClassLoader with additional support for defining
36  * classes with an associated code source and permissions which are
37  * retrieved by the system policy by default.
38  *
39  * @author  Li Gong
40  * @author  Roland Schemers
41  */
42 public class SecureClassLoader extends ClassLoader {
43     /*
44      * If initialization succeed this is set to true and security checks will
45      * succeed. Otherwise the object is not initialized and the object is
46      * useless.
47      */
48     private final boolean initialized;
49 
50     // HashMap that maps CodeSource to ProtectionDomain
51     // @GuardedBy("pdcache")
52     private final HashMap<CodeSource, ProtectionDomain> pdcache =
53                         new HashMap<>(11);
54 
55     private static final Debug debug = Debug.getInstance("scl");
56 
57     static {
ClassLoader.registerAsParallelCapable()58         ClassLoader.registerAsParallelCapable();
59     }
60 
61     /**
62      * Creates a new SecureClassLoader using the specified parent
63      * class loader for delegation.
64      *
65      * <p>If there is a security manager, this method first
66      * calls the security manager's {@code checkCreateClassLoader}
67      * method  to ensure creation of a class loader is allowed.
68      * <p>
69      * @param parent the parent ClassLoader
70      * @exception  SecurityException  if a security manager exists and its
71      *             {@code checkCreateClassLoader} method doesn't allow
72      *             creation of a class loader.
73      * @see SecurityManager#checkCreateClassLoader
74      */
SecureClassLoader(ClassLoader parent)75     protected SecureClassLoader(ClassLoader parent) {
76         super(parent);
77         // this is to make the stack depth consistent with 1.1
78         SecurityManager security = System.getSecurityManager();
79         if (security != null) {
80             security.checkCreateClassLoader();
81         }
82         initialized = true;
83     }
84 
85     /**
86      * Creates a new SecureClassLoader using the default parent class
87      * loader for delegation.
88      *
89      * <p>If there is a security manager, this method first
90      * calls the security manager's {@code checkCreateClassLoader}
91      * method  to ensure creation of a class loader is allowed.
92      *
93      * @exception  SecurityException  if a security manager exists and its
94      *             {@code checkCreateClassLoader} method doesn't allow
95      *             creation of a class loader.
96      * @see SecurityManager#checkCreateClassLoader
97      */
SecureClassLoader()98     protected SecureClassLoader() {
99         super();
100         // this is to make the stack depth consistent with 1.1
101         SecurityManager security = System.getSecurityManager();
102         if (security != null) {
103             security.checkCreateClassLoader();
104         }
105         initialized = true;
106     }
107 
108     /**
109      * Converts an array of bytes into an instance of class Class,
110      * with an optional CodeSource. Before the
111      * class can be used it must be resolved.
112      * <p>
113      * If a non-null CodeSource is supplied a ProtectionDomain is
114      * constructed and associated with the class being defined.
115      * <p>
116      * @param      name the expected name of the class, or {@code null}
117      *                  if not known, using '.' and not '/' as the separator
118      *                  and without a trailing ".class" suffix.
119      * @param      b    the bytes that make up the class data. The bytes in
120      *             positions {@code off} through {@code off+len-1}
121      *             should have the format of a valid class file as defined by
122      *             <cite>The Java&trade; Virtual Machine Specification</cite>.
123      * @param      off  the start offset in {@code b} of the class data
124      * @param      len  the length of the class data
125      * @param      cs   the associated CodeSource, or {@code null} if none
126      * @return the {@code Class} object created from the data,
127      *         and optional CodeSource.
128      * @exception  ClassFormatError if the data did not contain a valid class
129      * @exception  IndexOutOfBoundsException if either {@code off} or
130      *             {@code len} is negative, or if
131      *             {@code off+len} is greater than {@code b.length}.
132      *
133      * @exception  SecurityException if an attempt is made to add this class
134      *             to a package that contains classes that were signed by
135      *             a different set of certificates than this class, or if
136      *             the class name begins with "java.".
137      */
defineClass(String name, byte[] b, int off, int len, CodeSource cs)138     protected final Class<?> defineClass(String name,
139                                          byte[] b, int off, int len,
140                                          CodeSource cs)
141     {
142         return defineClass(name, b, off, len, getProtectionDomain(cs));
143     }
144 
145     /**
146      * Converts a {@link java.nio.ByteBuffer ByteBuffer}
147      * into an instance of class {@code Class}, with an optional CodeSource.
148      * Before the class can be used it must be resolved.
149      * <p>
150      * If a non-null CodeSource is supplied a ProtectionDomain is
151      * constructed and associated with the class being defined.
152      * <p>
153      * @param      name the expected name of the class, or {@code null}
154      *                  if not known, using '.' and not '/' as the separator
155      *                  and without a trailing ".class" suffix.
156      * @param      b    the bytes that make up the class data.  The bytes from positions
157      *                  {@code b.position()} through {@code b.position() + b.limit() -1}
158      *                  should have the format of a valid class file as defined by
159      *                  <cite>The Java&trade; Virtual Machine Specification</cite>.
160      * @param      cs   the associated CodeSource, or {@code null} if none
161      * @return the {@code Class} object created from the data,
162      *         and optional CodeSource.
163      * @exception  ClassFormatError if the data did not contain a valid class
164      * @exception  SecurityException if an attempt is made to add this class
165      *             to a package that contains classes that were signed by
166      *             a different set of certificates than this class, or if
167      *             the class name begins with "java.".
168      *
169      * @since  1.5
170      */
defineClass(String name, java.nio.ByteBuffer b, CodeSource cs)171     protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
172                                          CodeSource cs)
173     {
174         return defineClass(name, b, getProtectionDomain(cs));
175     }
176 
177     /**
178      * Returns the permissions for the given CodeSource object.
179      * <p>
180      * This method is invoked by the defineClass method which takes
181      * a CodeSource as an argument when it is constructing the
182      * ProtectionDomain for the class being defined.
183      * <p>
184      * @param codesource the codesource.
185      *
186      * @return the permissions granted to the codesource.
187      *
188      */
getPermissions(CodeSource codesource)189     protected PermissionCollection getPermissions(CodeSource codesource)
190     {
191         check();
192         return new Permissions(); // ProtectionDomain defers the binding
193     }
194 
195     /*
196      * Returned cached ProtectionDomain for the specified CodeSource.
197      */
getProtectionDomain(CodeSource cs)198     private ProtectionDomain getProtectionDomain(CodeSource cs) {
199         if (cs == null)
200             return null;
201 
202         ProtectionDomain pd = null;
203         synchronized (pdcache) {
204             pd = pdcache.get(cs);
205             if (pd == null) {
206                 PermissionCollection perms = getPermissions(cs);
207                 pd = new ProtectionDomain(cs, perms, this, null);
208                 pdcache.put(cs, pd);
209                 if (debug != null) {
210                     debug.println(" getPermissions "+ pd);
211                     debug.println("");
212                 }
213             }
214         }
215         return pd;
216     }
217 
218     /*
219      * Check to make sure the class loader has been initialized.
220      */
check()221     private void check() {
222         if (!initialized) {
223             throw new SecurityException("ClassLoader object not initialized");
224         }
225     }
226 
227 }
228