home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-03-20 | 6.3 KB | 242 lines |
- /*
- * @(#)SecureClassLoader.java 1.58 98/03/18
- *
- * Copyright 1997, 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
- package java.security;
-
- import java.util.Hashtable;
- import java.util.ArrayList;
- import java.net.URL;
-
- /**
- * This class extends ClassLoader with additional support for defining
- * classes with an associated code source and set of signers.
- *
- * @version 1.58, 03/18/98
- * @author Li Gong
- * @author Roland Schemers
- */
- public class SecureClassLoader extends ClassLoader {
- // Hashtable that maps CodeSource to ProtectionDomain
- private Hashtable pdcache = new Hashtable();
-
- /**
- * Creates a new SecureClassLoader using the specified parent
- * class loader for delegation.
- *
- * @param parent the parent ClassLoader
- */
- protected SecureClassLoader(ClassLoader parent) {
- super(parent);
- }
-
- /**
- * Creates a new SecureClassLoader using the default parent class
- * loader for delegation.
- */
- protected SecureClassLoader() {
- super();
- }
-
- /**
- * Converts an array of bytes into an instance of class Class,
- * with an optional ProtectionDomain and list of signers. Before the
- * class can be used it must be resolved.
- * @param name the name of the class
- * @param b the class bytes
- * @param off the start offset of the class bytes
- * @param len the length of the class bytes
- * @param protectionDomain the ProtectionDomain of the class
- * @param signers the list of signers, or null if none
- * @return the <code>Class</code> object created from the data,
- * optional ProtectionDomain, and list of signers
- */
- protected final Class defineClass(String name, byte[] b, int off, int len,
- ProtectionDomain protectionDomain,
- Object signers[])
- {
- Class c = defineClass(name, b, off, len);
- if (protectionDomain != null) {
- try {
- AccessController.beginPrivileged();
- c.setProtectionDomain(protectionDomain);
- } finally {
- AccessController.endPrivileged();
- }
- }
- if (signers != null) {
- setSigners(c, signers);
- }
- return c;
- }
-
- /**
- * Converts an array of bytes into an instance of class Class,
- * with an optional CodeSource and list of signers. Before the
- * class can be used it must be resolved.
- * @param name the name of the class
- * @param b the class bytes
- * @param off the start offset of the class bytes
- * @param len the length of the class bytes
- * @param cs the associated CodeSource, or null if none
- * @param signers the list of signers, or null if none
- * @return the <code>Class</code> object created from the data,
- * optional CodeSource, and list of signers
- */
- protected final Class defineClass(String name, byte[] b, int off, int len,
- CodeSource cs, Object signers[])
- {
- Class c = defineClass(name, b, off, len);
- if (cs != null) {
- try {
- AccessController.beginPrivileged();
- c.setProtectionDomain(getProtectionDomain(cs));
- } finally {
- AccessController.endPrivileged();
- }
- }
- if (signers != null) {
- setSigners(c, signers);
- }
- return c;
- }
-
- /*
- * Returned cached ProtectionDomain for the specified CodeSource.
- */
- private ProtectionDomain getProtectionDomain(CodeSource cs) {
- if (cs == null)
- return null;
-
- ProtectionDomain pd = (ProtectionDomain)pdcache.get(cs);
- if (pd == null) {
- synchronized (pdcache) {
- pd = (ProtectionDomain)pdcache.get(cs);
- if (pd == null) {
-
- Policy p = Policy.getPolicyNoCheck();
- Permissions perms;
- if (p == null) {
- perms = new Permissions();
- } else {
- perms = p.evaluate(cs);
- }
- pd = new ProtectionDomain(cs, perms);
-
- if (pd != null) {
- pdcache.put(cs, pd);
- }
- }
- }
- }
- return pd;
- }
-
- // used to Cache already created CodeSource's. Saves expensive lookups
- // and multiple calls to new.
-
- static class CodeSourceCache {
- public URL base;
- Object [] ids;
- CodeSource codesource;
-
- boolean equals(URL base, Object [] ids) {
- if (this.base == null) {
- if (base != null) return false;
- } else {
- if (!this.base.equals(base))
- return false;
- }
- if (this.ids == null) {
- if (ids!= null)
- return false;
- else
- return true;
- }
-
- if (ids == null)
- return false;
-
- boolean match;
-
- for (int i = 0; i < ids.length; i++) {
- match = false;
- for (int j = 0; j < this.ids.length; j++) {
- if (ids[i].equals(this.ids[j])) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
-
- for (int i = 0; i < this.ids.length; i++) {
- match = false;
- for (int j = 0; j < ids.length; j++) {
- if (this.ids[i].equals(ids[j])) {
- match = true;
- break;
- }
- }
- if (!match) return false;
- }
- return true;
- }
- }
-
- private ArrayList cscache = null;
-
- /**
- * Returns the CodeSource for the specified URL and list of signers.
- * @param url the URL for the CodeSource
- * @param signers the signers for the CodeSource
- * @return the resulting CodeSource
- */
- protected CodeSource getCodeSource(URL url, Object[] signers) {
- if (cscache == null)
- cscache = new ArrayList();
- CodeSourceCache csc;
- for (int i = 0; i < cscache.size(); i++) {
- csc = (CodeSourceCache) cscache.get(i);
- if (csc.equals(url, signers)) {
- return csc.codesource;
- }
- }
- csc = new CodeSourceCache();
- csc.base = url;
- PublicKey[] keys = null;
-
- if (signers != null) {
- csc.ids = new Object[signers.length];
- System.arraycopy(signers, 0, csc.ids, 0, signers.length);
-
- ArrayList keysAL = new ArrayList();
- for (int j=0; j < signers.length; j++) {
- if (signers[j] instanceof Identity) {
- PublicKey pk = ((Identity) signers[j]).getPublicKey();
- if (pk != null)
- keysAL.add(pk);
- }
- }
- keys = new PublicKey[keysAL.size()];
- for (int k=0; k< keysAL.size(); k++) {
- keys[k] = (PublicKey) keysAL.get(k);
- }
- }
-
- csc.codesource = new CodeSource(csc.base, keys);
- cscache.add(csc);
- return csc.codesource;
- }
- }
-