mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			298 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			298 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* Policy.java --- Policy Manager Class
 | |
|    Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
 | |
| 
 | |
| This file is part of GNU Classpath.
 | |
| 
 | |
| GNU Classpath is free software; you can redistribute it and/or modify
 | |
| it under the terms of the GNU General Public License as published by
 | |
| the Free Software Foundation; either version 2, or (at your option)
 | |
| any later version.
 | |
| 
 | |
| GNU Classpath 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 for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License
 | |
| along with GNU Classpath; see the file COPYING.  If not, write to the
 | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | |
| 02110-1301 USA.
 | |
| 
 | |
| Linking this library statically or dynamically with other modules is
 | |
| making a combined work based on this library.  Thus, the terms and
 | |
| conditions of the GNU General Public License cover the whole
 | |
| combination.
 | |
| 
 | |
| As a special exception, the copyright holders of this library give you
 | |
| permission to link this library with independent modules to produce an
 | |
| executable, regardless of the license terms of these independent
 | |
| modules, and to copy and distribute the resulting executable under
 | |
| terms of your choice, provided that you also meet, for each linked
 | |
| independent module, the terms and conditions of the license of that
 | |
| module.  An independent module is a module which is not derived from
 | |
| or based on this library.  If you modify this library, you may extend
 | |
| this exception to your version of the library, but you are not
 | |
| obligated to do so.  If you do not wish to do so, delete this
 | |
| exception statement from your version. */
 | |
| 
 | |
| package java.security;
 | |
| 
 | |
| import java.util.Collections;
 | |
| import java.util.Enumeration;
 | |
| import java.util.LinkedHashMap;
 | |
| import java.util.Map;
 | |
| 
 | |
| /**
 | |
|  * <code>Policy</code> is an abstract class for managing the system security
 | |
|  * policy for the Java application environment. It specifies which permissions
 | |
|  * are available for code from various sources. The security policy is
 | |
|  * represented through a subclass of <code>Policy</code>.
 | |
|  *
 | |
|  * <p>Only one <code>Policy</code> is in effect at any time. A
 | |
|  * {@link ProtectionDomain} initializes itself with information from this class
 | |
|  * on the set of permssions to grant.</p>
 | |
|  *
 | |
|  * <p>The location for the actual <code>Policy</code> could be anywhere in any
 | |
|  * form because it depends on the Policy implementation. The default system is
 | |
|  * in a flat ASCII file or it could be in a database.</p>
 | |
|  *
 | |
|  * <p>The current installed <code>Policy</code> can be accessed with
 | |
|  * {@link #getPolicy()} and changed with {@link #setPolicy(Policy)} if the code
 | |
|  * has the correct permissions.</p>
 | |
|  *
 | |
|  * <p>The {@link #refresh()} method causes the <code>Policy</code> instance to
 | |
|  * refresh/reload its configuration. The method used to refresh depends on the
 | |
|  * <code>Policy</code> implementation.</p>
 | |
|  *
 | |
|  * <p>When a protection domain initializes its permissions, it uses code like
 | |
|  * the following:</p>
 | |
|  *
 | |
|  * <code>
 | |
|  * policy = Policy.getPolicy();
 | |
|  * PermissionCollection perms = policy.getPermissions(myCodeSource);
 | |
|  * </code>
 | |
|  *
 | |
|  * <p>The protection domain passes the <code>Policy</code> handler a
 | |
|  * {@link CodeSource} instance which contains the codebase URL and a public key.
 | |
|  * The <code>Policy</code> implementation then returns the proper set of
 | |
|  * permissions for that {@link CodeSource}.</p>
 | |
|  *
 | |
|  * <p>The default <code>Policy</code> implementation can be changed by setting
 | |
|  * the "policy.provider" security provider in the "java.security" file to the
 | |
|  * correct <code>Policy</code> implementation class.</p>
 | |
|  *
 | |
|  * @author Mark Benvenuto
 | |
|  * @see CodeSource
 | |
|  * @see PermissionCollection
 | |
|  * @see SecureClassLoader
 | |
|  * @since 1.2
 | |
|  */
 | |
| public abstract class Policy
 | |
| {
 | |
|   private static Policy currentPolicy;
 | |
| 
 | |
|   /** Map of ProtectionDomains to PermissionCollections for this instance. */
 | |
|   private Map pd2pc = null;
 | |
| 
 | |
|   /** Constructs a new <code>Policy</code> object. */
 | |
|   public Policy()
 | |
|   {
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the currently installed <code>Policy</code> handler. The value
 | |
|    * should not be cached as it can be changed any time by
 | |
|    * {@link #setPolicy(Policy)}.
 | |
|    *
 | |
|    * @return the current <code>Policy</code>.
 | |
|    * @throws SecurityException
 | |
|    *           if a {@link SecurityManager} is installed which disallows this
 | |
|    *           operation.
 | |
|    */
 | |
|   public static Policy getPolicy()
 | |
|   {
 | |
|     SecurityManager sm = System.getSecurityManager();
 | |
|     if (sm != null)
 | |
|       sm.checkPermission(new SecurityPermission("getPolicy"));
 | |
| 
 | |
|     return getCurrentPolicy();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the <code>Policy</code> handler to a new value.
 | |
|    *
 | |
|    * @param policy
 | |
|    *          the new <code>Policy</code> to use.
 | |
|    * @throws SecurityException
 | |
|    *           if a {@link SecurityManager} is installed which disallows this
 | |
|    *           operation.
 | |
|    */
 | |
|   public static void setPolicy(Policy policy)
 | |
|   {
 | |
|     SecurityManager sm = System.getSecurityManager();
 | |
|     if (sm != null)
 | |
|       sm.checkPermission(new SecurityPermission("setPolicy"));
 | |
| 
 | |
|     setup(policy);
 | |
|     currentPolicy = policy;
 | |
|   }
 | |
| 
 | |
|   private static void setup(final Policy policy)
 | |
|   {
 | |
|     if (policy.pd2pc == null)
 | |
|       policy.pd2pc = Collections.synchronizedMap(new LinkedHashMap());
 | |
| 
 | |
|     ProtectionDomain pd = policy.getClass().getProtectionDomain();
 | |
|     if (pd.getCodeSource() != null)
 | |
|       {
 | |
|         PermissionCollection pc = null;
 | |
|         if (currentPolicy != null)
 | |
|           pc = currentPolicy.getPermissions(pd);
 | |
| 
 | |
|         if (pc == null) // assume it has all
 | |
|           {
 | |
|             pc = new Permissions();
 | |
|             pc.add(new AllPermission());
 | |
|           }
 | |
| 
 | |
|         policy.pd2pc.put(pd, pc); // add the mapping pd -> pc
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Ensures/forces loading of the configured policy provider, while bypassing
 | |
|    * the {@link SecurityManager} checks for <code>"getPolicy"</code> security
 | |
|    * permission.  Needed by {@link ProtectionDomain}.
 | |
|    */
 | |
|   static Policy getCurrentPolicy()
 | |
|   {
 | |
|     // FIXME: The class name of the Policy provider should really be sourced
 | |
|     // from the "java.security" configuration file. For now, just hard-code
 | |
|     // a stub implementation.
 | |
|     if (currentPolicy == null)
 | |
|       {
 | |
|         String pp = System.getProperty ("policy.provider");
 | |
|         if (pp != null)
 | |
|           try
 | |
|             {
 | |
|               currentPolicy = (Policy) Class.forName(pp).newInstance();
 | |
|             }
 | |
|           catch (Exception e)
 | |
|             {
 | |
|               // Ignored.
 | |
|             }
 | |
| 
 | |
|         if (currentPolicy == null)
 | |
|           currentPolicy = new gnu.java.security.provider.DefaultPolicy();
 | |
|       }
 | |
|     return currentPolicy;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Tests if <code>currentPolicy</code> is not <code>null</code>,
 | |
|    * thus allowing clients to not force loading of any policy
 | |
|    * provider; needed by {@link ProtectionDomain}.
 | |
|    */
 | |
|   static boolean isLoaded()
 | |
|   {
 | |
|     return currentPolicy != null;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the set of Permissions allowed for a given {@link CodeSource}.
 | |
|    *
 | |
|    * @param codesource
 | |
|    *          the {@link CodeSource} for which, the caller needs to find the
 | |
|    *          set of granted permissions.
 | |
|    * @return a set of permissions for {@link CodeSource} specified by the
 | |
|    *         current <code>Policy</code>.
 | |
|    * @throws SecurityException
 | |
|    *           if a {@link SecurityManager} is installed which disallows this
 | |
|    *           operation.
 | |
|    */
 | |
|   public abstract PermissionCollection getPermissions(CodeSource codesource);
 | |
| 
 | |
|   /**
 | |
|    * Returns the set of Permissions allowed for a given {@link ProtectionDomain}.
 | |
|    *
 | |
|    * @param domain
 | |
|    *          the {@link ProtectionDomain} for which, the caller needs to find
 | |
|    *          the set of granted permissions.
 | |
|    * @return a set of permissions for {@link ProtectionDomain} specified by the
 | |
|    *         current <code>Policy.</code>.
 | |
|    * @since 1.4
 | |
|    * @see ProtectionDomain
 | |
|    * @see SecureClassLoader
 | |
|    */
 | |
|   public PermissionCollection getPermissions(ProtectionDomain domain)
 | |
|   {
 | |
|     if (domain == null)
 | |
|       return new Permissions();
 | |
| 
 | |
|     if (pd2pc == null)
 | |
|       setup(this);
 | |
| 
 | |
|     PermissionCollection result = (PermissionCollection) pd2pc.get(domain);
 | |
|     if (result != null)
 | |
|       {
 | |
|         Permissions realResult = new Permissions();
 | |
|         for (Enumeration e = result.elements(); e.hasMoreElements(); )
 | |
|           realResult.add((Permission) e.nextElement());
 | |
| 
 | |
|         return realResult;
 | |
|       }
 | |
| 
 | |
|     result = getPermissions(domain.getCodeSource());
 | |
|     if (result == null)
 | |
|       result = new Permissions();
 | |
| 
 | |
|     PermissionCollection pc = domain.getPermissions();
 | |
|     if (pc != null)
 | |
|       for (Enumeration e = pc.elements(); e.hasMoreElements(); )
 | |
|         result.add((Permission) e.nextElement());
 | |
| 
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Checks if the designated {@link Permission} is granted to a designated
 | |
|    * {@link ProtectionDomain}.
 | |
|    *
 | |
|    * @param domain
 | |
|    *          the {@link ProtectionDomain} to test.
 | |
|    * @param permission
 | |
|    *          the {@link Permission} to check.
 | |
|    * @return <code>true</code> if <code>permission</code> is implied by a
 | |
|    *         permission granted to this {@link ProtectionDomain}. Returns
 | |
|    *         <code>false</code> otherwise.
 | |
|    * @since 1.4
 | |
|    * @see ProtectionDomain
 | |
|    */
 | |
|   public boolean implies(ProtectionDomain domain, Permission permission)
 | |
|   {
 | |
|     if (pd2pc == null)
 | |
|       setup(this);
 | |
| 
 | |
|     PermissionCollection pc = (PermissionCollection) pd2pc.get(domain);
 | |
|     if (pc != null)
 | |
|       return pc.implies(permission);
 | |
| 
 | |
|     boolean result = false;
 | |
|     pc = getPermissions(domain);
 | |
|     if (pc != null)
 | |
|       {
 | |
|         result = pc.implies(permission);
 | |
|         pd2pc.put(domain, pc);
 | |
|       }
 | |
| 
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Causes this <code>Policy</code> instance to refresh / reload its
 | |
|    * configuration. The method used to refresh depends on the concrete
 | |
|    * implementation.
 | |
|    */
 | |
|   public abstract void refresh();
 | |
| }
 |