1. /*
  2. * @(#)SecureClassLoader.java 1.85 04/05/05
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.security;
  8. import java.util.HashMap;
  9. import java.util.ArrayList;
  10. import java.net.URL;
  11. import sun.security.util.Debug;
  12. /**
  13. * This class extends ClassLoader with additional support for defining
  14. * classes with an associated code source and permissions which are
  15. * retrieved by the system policy by default.
  16. *
  17. * @version 1.85, 05/05/04
  18. * @author Li Gong
  19. * @author Roland Schemers
  20. */
  21. public class SecureClassLoader extends ClassLoader {
  22. /*
  23. * If initialization succeed this is set to true and security checks will
  24. * succeed. Otherwise the object is not initialized and the object is
  25. * useless.
  26. */
  27. private boolean initialized = false;
  28. // HashMap that maps CodeSource to ProtectionDomain
  29. private HashMap pdcache = new HashMap(11);
  30. private static final Debug debug = Debug.getInstance("scl");
  31. /**
  32. * Creates a new SecureClassLoader using the specified parent
  33. * class loader for delegation.
  34. *
  35. * <p>If there is a security manager, this method first
  36. * calls the security manager's <code>checkCreateClassLoader</code>
  37. * method to ensure creation of a class loader is allowed.
  38. * <p>
  39. * @param parent the parent ClassLoader
  40. * @exception SecurityException if a security manager exists and its
  41. * <code>checkCreateClassLoader</code> method doesn't allow
  42. * creation of a class loader.
  43. * @see SecurityManager#checkCreateClassLoader
  44. */
  45. protected SecureClassLoader(ClassLoader parent) {
  46. super(parent);
  47. // this is to make the stack depth consistent with 1.1
  48. SecurityManager security = System.getSecurityManager();
  49. if (security != null) {
  50. security.checkCreateClassLoader();
  51. }
  52. initialized = true;
  53. }
  54. /**
  55. * Creates a new SecureClassLoader using the default parent class
  56. * loader for delegation.
  57. *
  58. * <p>If there is a security manager, this method first
  59. * calls the security manager's <code>checkCreateClassLoader</code>
  60. * method to ensure creation of a class loader is allowed.
  61. *
  62. * @exception SecurityException if a security manager exists and its
  63. * <code>checkCreateClassLoader</code> method doesn't allow
  64. * creation of a class loader.
  65. * @see SecurityManager#checkCreateClassLoader
  66. */
  67. protected SecureClassLoader() {
  68. super();
  69. // this is to make the stack depth consistent with 1.1
  70. SecurityManager security = System.getSecurityManager();
  71. if (security != null) {
  72. security.checkCreateClassLoader();
  73. }
  74. initialized = true;
  75. }
  76. /**
  77. * Converts an array of bytes into an instance of class Class,
  78. * with an optional CodeSource. Before the
  79. * class can be used it must be resolved.
  80. * <p>
  81. * If a non-null CodeSource is supplied a ProtectionDomain is
  82. * constructed and associated with the class being defined.
  83. * <p>
  84. * @param name the expected name of the class, or <code>null</code>
  85. * if not known, using '.' and not '/' as the separator
  86. * and without a trailing ".class" suffix.
  87. * @param b the bytes that make up the class data. The bytes in
  88. * positions <code>off</code> through <code>off+len-1</code>
  89. * should have the format of a valid class file as defined
  90. * by the
  91. * <a href="http://java.sun.com/docs/books/vmspec/">Java
  92. * Virtual Machine Specification</a>.
  93. * @param off the start offset in <code>b</code> of the class data
  94. * @param len the length of the class data
  95. * @param cs the associated CodeSource, or <code>null</code> if none
  96. * @return the <code>Class</code> object created from the data,
  97. * and optional CodeSource.
  98. * @exception ClassFormatError if the data did not contain a valid class
  99. * @exception IndexOutOfBoundsException if either <code>off</code> or
  100. * <code>len</code> is negative, or if
  101. * <code>off+len</code> is greater than <code>b.length</code>.
  102. *
  103. * @exception SecurityException if an attempt is made to add this class
  104. * to a package that contains classes that were signed by
  105. * a different set of certificates than this class, or if
  106. * the class name begins with "java.".
  107. */
  108. protected final Class<?> defineClass(String name,
  109. byte[] b, int off, int len,
  110. CodeSource cs)
  111. {
  112. if (cs == null)
  113. return defineClass(name, b, off, len);
  114. else
  115. return defineClass(name, b, off, len, getProtectionDomain(cs));
  116. }
  117. /**
  118. * Converts a {@link java.nio.ByteBuffer <tt>ByteBuffer</tt>}
  119. * into an instance of class <tt>Class</tt>, with an optional CodeSource.
  120. * Before the class can be used it must be resolved.
  121. * <p>
  122. * If a non-null CodeSource is supplied a ProtectionDomain is
  123. * constructed and associated with the class being defined.
  124. * <p>
  125. * @param name the expected name of the class, or <code>null</code>
  126. * if not known, using '.' and not '/' as the separator
  127. * and without a trailing ".class" suffix.
  128. * @param b the bytes that make up the class data. The bytes from positions
  129. * <tt>b.position()</tt> through <tt>b.position() + b.limit() -1</tt>
  130. * should have the format of a valid class file as defined by the
  131. * <a href="http://java.sun.com/docs/books/vmspec/">Java Virtual
  132. * Machine Specification</a>.
  133. * @param cs the associated CodeSource, or <code>null</code> if none
  134. * @return the <code>Class</code> object created from the data,
  135. * and optional CodeSource.
  136. * @exception ClassFormatError if the data did not contain a valid class
  137. * @exception SecurityException if an attempt is made to add this class
  138. * to a package that contains classes that were signed by
  139. * a different set of certificates than this class, or if
  140. * the class name begins with "java.".
  141. *
  142. * @since 1.5
  143. */
  144. protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
  145. CodeSource cs)
  146. {
  147. if (cs == null)
  148. return defineClass(name, b, (ProtectionDomain)null);
  149. else
  150. return defineClass(name, b, getProtectionDomain(cs));
  151. }
  152. /**
  153. * Returns the permissions for the given CodeSource object.
  154. * <p>
  155. * This method is invoked by the defineClass method which takes
  156. * a CodeSource as an argument when it is constructing the
  157. * ProtectionDomain for the class being defined.
  158. * <p>
  159. * @param codesource the codesource.
  160. *
  161. * @return the permissions granted to the codesource.
  162. *
  163. */
  164. protected PermissionCollection getPermissions(CodeSource codesource)
  165. {
  166. check();
  167. return new Permissions(); // ProtectionDomain defers the binding
  168. }
  169. /*
  170. * Returned cached ProtectionDomain for the specified CodeSource.
  171. */
  172. private ProtectionDomain getProtectionDomain(CodeSource cs) {
  173. if (cs == null)
  174. return null;
  175. ProtectionDomain pd = null;
  176. synchronized (pdcache) {
  177. pd = (ProtectionDomain)pdcache.get(cs);
  178. if (pd == null) {
  179. PermissionCollection perms = getPermissions(cs);
  180. pd = new ProtectionDomain(cs, perms, this, null);
  181. if (pd != null) {
  182. pdcache.put(cs, pd);
  183. if (debug != null) {
  184. debug.println(" getPermissions "+ pd);
  185. debug.println("");
  186. }
  187. }
  188. }
  189. }
  190. return pd;
  191. }
  192. /*
  193. * Check to make sure the class loader has been initialized.
  194. */
  195. private void check() {
  196. if (!initialized) {
  197. throw new SecurityException("ClassLoader object not initialized");
  198. }
  199. }
  200. }