Author: peter_firmstone Date: Tue Aug 2 01:15:27 2011 New Revision: 1152990
URL: http://svn.apache.org/viewvc?rev=1152990&view=rev Log: Refactoring Added: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java - copied, changed from r1139517, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegatePermission.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Deny.java - copied, changed from r1139517, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DenyImpl.java river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PrincipalGrantTest.java (with props) Removed: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ClassLoadingPermission.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegatePermission.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/DynamicGrants.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DenyImpl.java Modified: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/PolicyFileProvider.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileInputStream.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileOutputStream.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/Exclusion.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/InternetSecurityManager.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/RemotePolicy.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java river/jtsk/skunk/peterConcurrentPolicy/test/src/tests/support/MyPrincipal.java Modified: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/PolicyFileProvider.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/PolicyFileProvider.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/PolicyFileProvider.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/PolicyFileProvider.java Tue Aug 2 01:15:27 2011 @@ -47,8 +47,8 @@ import net.jini.security.GrantPermission * @com.sun.jini.impl <!-- Implementation Specifics --> * * This implementation's no-argument constructor uses a default class name of - * <code>"sun.security.provider.PolicyFile"</code> to instantiate base policy - * objects, if the + * <code>"org.apache.river.impl.security.policy.se.ConcurrentPolicyFile"</code> + * to instantiate base policy objects, if the * <code>net.jini.security.policy.PolicyFileProvider.basePolicyClass</code> * security property is not set. */ @@ -58,7 +58,8 @@ public class PolicyFileProvider extends "net.jini.security.policy." + "PolicyFileProvider.basePolicyClass"; private static final String defaultBasePolicyClass = - "sun.security.provider.PolicyFile"; + "org.apache.river.impl.security.policy.se.ConcurrentPolicyFile"; + //"sun.security.provider.PolicyFile"; private static final String policyProperty = "java.security.policy"; private static final Object propertyLock = new Object(); @@ -287,7 +288,8 @@ public class PolicyFileProvider extends public Object run() { if (value == null) { // TODO: Use System.clearProperty when we move to 1.5 - System.getProperties().remove(policyProperty); + System.clearProperty(policyProperty); + //System.getProperties().remove(policyProperty); } else { System.setProperty(policyProperty, value); } Copied: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java (from r1139517, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegatePermission.java) URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegatePermission.java&r1=1139517&r2=1152990&rev=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegatePermission.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java Tue Aug 2 01:15:27 2011 @@ -16,7 +16,7 @@ * limitations under the License. */ -package org.apache.river.api.security; +package org.apache.river.api.delegates; import java.io.InvalidObjectException; import java.io.ObjectInputStream; Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileInputStream.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileInputStream.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileInputStream.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileInputStream.java Tue Aug 2 01:15:27 2011 @@ -31,7 +31,6 @@ import java.security.PrivilegedActionExc import java.security.PrivilegedExceptionAction; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.river.api.security.DelegatePermission; import sun.security.util.SecurityConstants; /** Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileOutputStream.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileOutputStream.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileOutputStream.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/FileOutputStream.java Tue Aug 2 01:15:27 2011 @@ -32,7 +32,6 @@ import java.security.PrivilegedActionExc import java.security.PrivilegedExceptionAction; import java.util.logging.Level; import java.util.logging.Logger; -import org.apache.river.api.security.DelegatePermission; import sun.security.util.SecurityConstants; /** Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/Exclusion.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/Exclusion.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/Exclusion.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/Exclusion.java Tue Aug 2 01:15:27 2011 @@ -27,24 +27,15 @@ import java.security.ProtectionDomain; * "getProtectionDomain" * * The implementation may exclude a ProtectionDomain on any grounds, but it must be - * consistent and return the same result on every occassion. + * consistent and return the same result on every occasion. * * Exclusion will be used in combination with a PermissionGrant based on - * Code signer Certificate's to exclude individual CodeSource's or URL's with + * Code signer certificates to exclude individual CodeSource's or URL's with * known vulnerabilities. * - * Because there a multiple ways to specify a permission grant, removing a - * permission grant that applies to a domain may remove - * permission from other domain's as a side effect. Hence an Exclusion is - * used as a method to revoke all dynamic Permission's from a domain. - * - * An exclusion is used by a PermissionGrantBuilder to rebuild an entire - * array of PermissionGrant's, causing either the adding of an exclusion or - * the removal of the PermissionGrant. - * * @author Peter Firmstone */ -public abstract class Exclusion { +public interface Exclusion { /** * Exclusion is used by a PermissionGrantBuilder, to filter out unwanted * ProtectionDomain implies based on any set of conditions. This method Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/InternetSecurityManager.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/InternetSecurityManager.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/InternetSecurityManager.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/InternetSecurityManager.java Tue Aug 2 01:15:27 2011 @@ -18,6 +18,7 @@ package org.apache.river.api.security; +import org.apache.river.api.delegates.DelegatePermission; import java.lang.reflect.Field; import java.security.AccessControlContext; import java.security.AccessControlException; Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java Tue Aug 2 01:15:27 2011 @@ -22,19 +22,24 @@ import java.security.CodeSource; import java.security.Permission; import java.security.Principal; import java.security.cert.Certificate; +import org.apache.river.impl.security.policy.util.PermissionGrantBuilderImp; /** * The PermissionGrantBuilder creates Dynamic PermissionGrant's based on * information provided by the user. The user must have access to the * system policy and have permission to grant permissions. * - * Don't Serialize the PermissionGrant, instead get a builder template - * and send that. + * A PermissionGrantBuilder implementation should also be used as the serialized form + * for PermissionGrant's, the implementation of PermissionGrant's should + * remain package private. + * + * This prevents the serialized form becoming part of the public api. * * Single Thread use only. * @author Peter Firmstone. + * @see PermissionGrant */ -public interface PermissionGrantBuilder { +public abstract class PermissionGrantBuilder { /** * The PermissionGrant generated will apply to all classes loaded by @@ -68,6 +73,12 @@ public interface PermissionGrantBuilder */ public static final int CODESOURCE_CERTS = 3; + public static final int PRINCIPAL = 4; + + public static PermissionGrantBuilder create(){ + return new PermissionGrantBuilderImp(); + } + /** * Build the PermissionGrant using information supplied. * @return an appropriate PermissionGrant. Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/RemotePolicy.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/RemotePolicy.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/RemotePolicy.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/RemotePolicy.java Tue Aug 2 01:15:27 2011 @@ -19,44 +19,89 @@ package org.apache.river.api.security; import java.io.IOException; -import java.util.List; import net.jini.security.GrantPermission; import net.jini.security.policy.UmbrellaGrantPermission; +import org.apache.river.impl.security.policy.util.PolicyParser; +import org.apache.river.impl.security.policy.util.DefaultPolicyParser; +import org.apache.river.impl.security.policy.util.DefaultPolicyScanner; /** + * RemotePolicy is a service implemented by a Policy Provider, that allows + * the Policy provider to be updated remotely by a djinn group administrator. + * + * For security purposes, only secure jeri Endpoint's should be used and must + * require client and server authentication, in addition the proxy must be a + * reflective proxy only, as DownloadPermission should not be granted, which is + * also beneficial to reduced network load at the administrator client. + * RemotePolicy may be submitted to a lookup service, where an administrator + * client will look it up and replace PermissionGrant's periodically. + * + * To reduce network load, the administrator client may delay updates by + * lazily processing updates in a serial manner. New RemotePolicy services + * obtained by the administrator client's via RemoteEvent notification should + * be processed as a priority over policy updates. Eventually a djinn group + * policy should reach equilibrium where all nodes have had their policy's + * updated. + * * This policy, in addition to any local policy provider, allows a network djinn * administrator to provide a list of PermissionGrant's, from a single or * replicated remote location, distributed to all nodes in a djinn that - * administrator is responsible for, every time the administrator updates - * his network policy, he can use a RemoteEvent notification system to update - * all client node policies. - * - * This is implemented at the client, the list of PermissionGrant's provided, - * will replace any existing RemotePolicy permissions. This allows the administrator - * to replace or replicate his network security policy, the client can switch to - * any other network security policy advisory service. + * administrator is responsible for. Every time the administrator updates + * his network policy, he can use a RemoteEvent notification system to be + * notified for any new RemotePolicy registrations. * - * It is essential that the policy service authenticate as an administrator - * subject over a secure endpoint. + * In addition, replicating administrator clients may register a pseudo RemotePolicy + * in order to track the primary administrator client and take over in the + * event it fails. Failure may be failure to authenticate or failure to renew + * a Lease. * * RemotePolicy, if it encapsulates an underlying RemotePolicy, does not - * delegate updates to the underlying RemotePolicy, this is in case an + * delegate updates to the base RemotePolicy, this is in case an * implementer wants a number of different layers of RemotePolicy, where - * each layer represents a different administrator role or responsiblity. - * The administrator's subject must hold the necessary permissionss in order + * each layer represents a different administrator role or responsibility. + * The administrator's subject must hold the necessary permissions in order * to grant them, including RuntimePermission("getProtectionDomain"). * + * A node may join more than one djinn group, in this case RemotePolicy's may + * be used as nested basePolicy's. + * + * The intent of RemotePolicy is to make granting of DowloadPermission to + * new signer Certificates and adding new Principals and Permission's to + * distributed policy providers. + * + * Local policy files should be used to restrict the Permissions grantable + * via a RemotePolicy. + * + * PermissionGrant's that are replaced and no longer exist in the RemotePolicy + * will no longer be implied by the policy. + * + * DefaultPolicyParser has been provided for an administrator client to + * parse standard java format policy file's, to create PermissionGrant's + * custom policy file formats may be used by extending DefaultPolicyScanner. + * * @author Peter Firmstone * @see GrantPermission * @see UmbrellaGrantPermission + * @see PolicyParser + * @see DefaultPolicyParser + * @see DefaultPolicyScanner */ public interface RemotePolicy { /** - * Provides a list of policies, provided by a remote policy advisory - * service, this list replaces any existing list, it is defensively copied. + * Replaces the existing RemotePolicy's PermissionGrant's. + * + * The array is defensively copied, the caller, must have + * RuntimePermission("getProtectionDomain") + * as well as GrantPermission or UmbrellaGrantPermission for every + * Permission granted by each PermissionGrant. + * + * In this case the caller will be the client Subject. + * + * These Permissions should be set in the local policy files at the + * RemotePolicy server. * * @param policyPermissions * @throws java.io.IOException */ - public void update(List<PermissionGrant> policyPermissions) throws IOException; + public void replace(PermissionGrant[] policyPermissions) throws IOException; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java Tue Aug 2 01:15:27 2011 @@ -3,7 +3,6 @@ package org.apache.river.impl.security.policy.se; import java.io.IOException; -import java.util.concurrent.ExecutionException; import org.apache.river.api.security.InternetSecurityManager; import java.security.AccessController; import java.security.AllPermission; @@ -15,7 +14,7 @@ import java.security.Policy; import java.security.Principal; import java.security.PrivilegedAction; import java.security.ProtectionDomain; -import java.security.Provider; +import java.security.Security; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -27,9 +26,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; -import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; import java.util.logging.Level; import java.util.logging.Logger; import net.jini.security.GrantPermission; @@ -37,7 +33,6 @@ import net.jini.security.policy.DynamicP import net.jini.security.policy.PolicyInitializationException; import net.jini.security.policy.UmbrellaGrantPermission; import org.apache.river.api.security.PermissionGrant; -import org.apache.river.impl.security.policy.spi.RevokeableDynamicPolicySpi; import org.apache.river.api.security.PermissionGrantBuilder; import org.apache.river.api.security.RemotePolicy; import org.apache.river.api.security.RevokePermission; @@ -112,8 +107,8 @@ import org.apache.river.impl.util.Concur * and if it returns dynamically granted permissions, then those permissions * cannot be revoked.</p> * <p> - * It is thus reccommeded that Static policy files only be used for setting - * up your priveleged code and use UmbrellaGrantPermission's and grant + * It is thus recommended that Static policy files only be used for setting + * up your privileged code and use UmbrellaGrantPermission's and grant * all other Permission's using dynamic grants. This minimises the double * checking of Permission, that occurs when a ProtectionDomain is constructed * so it contains a default PermissionCollection that is not null. @@ -134,8 +129,13 @@ import org.apache.river.impl.util.Concur * @see ConcurrentPermissionCollection */ -public class DynamicConcurrentPolicyProvider implements RemotePolicy, +public class DynamicConcurrentPolicyProvider extends Policy implements RemotePolicy, RevokeableDynamicPolicy { + private static final String basePolicyClassProperty = + "net.jini.security.policy." + + "DynamicPolicyProvider.basePolicyClass"; + private static final String defaultBasePolicyClass = + "net.jini.security.policy.PolicyFileProvider"; private static final ProtectionDomain sysDomain = AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() { public ProtectionDomain run() { return Object.class.getProtectionDomain(); } @@ -146,38 +146,55 @@ public class DynamicConcurrentPolicyProv * unless holding grantLock. * Local methods must first copy the reference before using the array in * loops etc in case the reference is updated. + * This is important, to prevent the update of the remotePolicyGrant's from + * causing executing threads from being blocked. */ private volatile PermissionGrant[] remotePolicyGrants; // Write protected by grantLock. - /* This lock protects adding and removal of PermissionGrant's*/ + /* This lock protects write updating of remotePolicyGrants reference */ private final Object grantLock; - private volatile Policy basePolicy; // effectively final looks after its own sync + private final Policy basePolicy; // final looks after its own sync + /* cache of ProtectionDomain and their Permissions */ private final ConcurrentMap<ProtectionDomain, PermissionCollection> cache; + /* A cache of Permission's for each PermissionGrant, this avoids a mutating + * PermissionGrant implementation from escallating permissions, this + * cache should be updated when receiving PermissionGrant and checking + * the callers Permissions. The current implementation uses a weak identity + * map that cleans itself. */ private final ConcurrentMap<PermissionGrant, Permission[]> grantCache; // DynamicPolicy grant's for Proxy's. private final Collection<PermissionGrant> dynamicPolicyGrants; - private volatile boolean basePolicyIsDynamic; // Don't use cache if true. - private volatile boolean revokeable; - private volatile boolean basePolicyIsRemote; - private volatile boolean initialized = false; - private Logger logger; - private volatile boolean loggable; + private final boolean basePolicyIsDynamic; // Don't use cache if true. + private final boolean revokeable; + private final boolean basePolicyIsRemote; + private final Logger logger; + private final boolean loggable; // do something about some domain permissions for this domain so we can // avoid dead locks due to bug 4911907 private final SecurityManager sm; - private final Guard g; + private final Guard revokePermission; + private final Guard protectionDomainPermission; - public DynamicConcurrentPolicyProvider(){ + public DynamicConcurrentPolicyProvider() throws PolicyInitializationException{ + String cname = Security.getProperty(basePolicyClassProperty); + if (cname == null) { + cname = defaultBasePolicyClass; + } + try { + basePolicy = (Policy) Class.forName(cname).newInstance(); + } catch (SecurityException e) { + throw e; + } catch (Exception e) { + throw new PolicyInitializationException( + "unable to construct base policy", e); + } dynamicPolicyGrants = ConcurrentCollections.multiReadCollection( new ArrayList<PermissionGrant>(120)); remotePolicyGrants = new PermissionGrant[0]; - basePolicy = null; cache = new ConcurrentWeakIdentityMap<ProtectionDomain, PermissionCollection>(120); grantCache = new ConcurrentWeakIdentityMap<PermissionGrant, Permission[]>(60); - basePolicyIsDynamic = false; - revokeable = true; logger = Logger.getLogger("net.jini.security.policy"); loggable = logger.isLoggable(Level.FINEST); grantLock = new Object(); @@ -187,41 +204,66 @@ public class DynamicConcurrentPolicyProv System.setSecurityManager(s); } sm = s; - g = new RevokePermission(); + revokePermission = new RevokePermission(); + protectionDomainPermission = new RuntimePermission("getProtectionDomain"); + if (basePolicy instanceof DynamicPolicy) { + DynamicPolicy dp = (DynamicPolicy) basePolicy; + basePolicyIsDynamic = dp.grantSupported(); + if (basePolicy instanceof RevokeableDynamicPolicy ) { + RevokeableDynamicPolicy rp = (RevokeableDynamicPolicy) basePolicy; + revokeable = rp.revokeSupported(); + } else { + revokeable = false; + } + } else { + basePolicyIsDynamic = false; + revokeable = false; + } + if (basePolicy instanceof RemotePolicy){ + basePolicyIsRemote = true; + } else { + basePolicyIsRemote = false; + } + ensureDependenciesResolved(); } - /** - * Idempotent method. - * - * Actually we should consider allowing a null base policy so we can choose our own - * default. Or pass in a string for the basePolicy to find it itself. - * - * @param basePolicy - * @return - */ - public boolean basePolicy(Policy basePolicy) { - if (initialized == true) return false; + public DynamicConcurrentPolicyProvider(Policy basePolicy){ this.basePolicy = basePolicy; - return true; - } - - /** - * Idempotent method. - * @throws net.jini.security.policy.PolicyInitializationException - */ - public void initialize() throws PolicyInitializationException { - if (basePolicy == null) throw new PolicyInitializationException("Base Policy hasn't " + - "been set cannot initialize", new Exception("Failed to initialize")); - if (basePolicy instanceof DynamicPolicy) { + dynamicPolicyGrants = ConcurrentCollections.multiReadCollection( + new ArrayList<PermissionGrant>(120)); + remotePolicyGrants = new PermissionGrant[0]; + cache = new ConcurrentWeakIdentityMap<ProtectionDomain, PermissionCollection>(120); + grantCache = new ConcurrentWeakIdentityMap<PermissionGrant, Permission[]>(60); + logger = Logger.getLogger("net.jini.security.policy"); + loggable = logger.isLoggable(Level.FINEST); + grantLock = new Object(); + SecurityManager s = System.getSecurityManager(); + if (s == null) { + s = new InternetSecurityManager(); + System.setSecurityManager(s); + } + sm = s; + revokePermission = new RevokePermission(); + protectionDomainPermission = new RuntimePermission("getProtectionDomain"); + if (basePolicy instanceof DynamicPolicy) { DynamicPolicy dp = (DynamicPolicy) basePolicy; basePolicyIsDynamic = dp.grantSupported(); - revokeable = false; if (basePolicy instanceof RevokeableDynamicPolicy ) { RevokeableDynamicPolicy rp = (RevokeableDynamicPolicy) basePolicy; revokeable = rp.revokeSupported(); + } else { + revokeable = false; } + } else { + basePolicyIsDynamic = false; + revokeable = false; } - initialized = true; + if (basePolicy instanceof RemotePolicy){ + basePolicyIsRemote = true; + } else { + basePolicyIsRemote = false; + } + ensureDependenciesResolved(); } /** @@ -230,8 +272,7 @@ public class DynamicConcurrentPolicyProv * operation of the provider, which can result in deadlock as described by * bug 4911907. */ - public void ensureDependenciesResolved() { - if (initialized == false) throw new RuntimeException("Object not initialized"); + private void ensureDependenciesResolved() { // Investigate bug 4911907, do we need to do anything more here? Is this sufficient. if (sysDomain == null ) System.out.println("System Domain is null"); implies(sysDomain, new AllPermission()); @@ -241,12 +282,10 @@ public class DynamicConcurrentPolicyProv } public boolean revokeSupported() { - if (initialized == false) throw new RuntimeException("Object not initialized"); return revokeable; } public PermissionCollection getPermissions(CodeSource codesource) { - if (initialized == false) throw new RuntimeException("Object not initialized"); /* It is extremely important that dynamic grant's are not returned, * to prevent them becoming part of the static permissions held * by a ProtectionDomain. In this case during construction of a @@ -256,15 +295,15 @@ public class DynamicConcurrentPolicyProv } public PermissionCollection getPermissions(ProtectionDomain domain) { - if (initialized == false) throw new RuntimeException("Object not initialized"); /* It is extremely important that dynamic grant's are not returned, * to prevent them becoming part of the static permissions held * by a ProtectionDomain. In this case during the merge operation * performed by the ProtectionDomain. * - * However we add Permission's wrapped in a PolicyPermission for - * holding dynamic Permissions to print debugging information using toString - * PolicyPermission doesn't imply anything useful, it's just a + * Dynamic granted Permission's are wrapped in PolicyPermission's + * so ProtectionDomain's print debugging information when toString() + * is called. PolicyPermission doesn't imply anything, it + * implements toString() for debugging purposes, it's just a * container. */ PermissionCollection pc = basePolicy.getPermissions(domain); @@ -299,7 +338,6 @@ public class DynamicConcurrentPolicyProv } public boolean implies(ProtectionDomain domain, Permission permission) { - if (initialized == false) throw new RuntimeException("Object not initialized"); if (basePolicyIsDynamic || basePolicyIsRemote){ // Total delegation revoke supported only by underlying policy. if (basePolicy.implies(domain, permission)) return true; @@ -398,7 +436,6 @@ public class DynamicConcurrentPolicyProv * grants for ProtectionDomains that no longer exist. */ public void refresh() { - if (initialized == false) throw new RuntimeException("Object not initialized"); cache.clear(); basePolicy.refresh(); // Clean up any void grants. @@ -419,12 +456,10 @@ public class DynamicConcurrentPolicyProv } public boolean grantSupported() { - if (initialized == false) throw new RuntimeException("Object not initialized"); return true; } public void grant(Class cl, Principal[] principals, Permission[] permissions) { - if (initialized == false) throw new RuntimeException("Object not initialized"); if (permissions == null || permissions.length == 0) {return;} if (principals == null){ principals = new Principal[0];} if (principals.length > 0) { @@ -461,7 +496,6 @@ public class DynamicConcurrentPolicyProv // documentation inherited from DynamicPolicy.getGrants public Permission[] getGrants(Class cl, Principal[] principals) { - if (initialized == false) throw new RuntimeException("Object not initialized"); if (basePolicyIsDynamic){ return ((DynamicPolicy)basePolicy).getGrants(cl, principals); } @@ -488,8 +522,7 @@ public class DynamicConcurrentPolicyProv } public Permission[] revoke(Class cl, Principal[] principals) { - if (initialized == false) throw new RuntimeException("Object not initialized"); - g.checkGuard(null); + revokePermission.checkGuard(null); if (basePolicyIsDynamic && revokeable){ RevokeableDynamicPolicy bp = (RevokeableDynamicPolicy) basePolicy; return bp.revoke(cl, principals); @@ -530,9 +563,9 @@ public class DynamicConcurrentPolicyProv } } - public void update(List<PermissionGrant> grants) throws IOException { + public void replace(PermissionGrant[] grants) throws IOException { /* If the base policy is also remote, each will manage their own - * permissions, so we do not delegate to the underlying policy. + * permissions independantly, so we do not delegate to the underlying policy. * Any underlying local policy file permissions should be propagated up * into each policy, which means there will be duplication of some * policy information. @@ -542,12 +575,11 @@ public class DynamicConcurrentPolicyProv * where two permissions combined also implied a third permission, that * neither administrator intended to grant. */ - if (initialized == false) throw new RuntimeException("Object not initialized"); // because PermissionGrant's are given references to ProtectionDomain's // we must check the caller has this permission. - sm.checkPermission(new RuntimePermission("getProtectionDomain")); + protectionDomainPermission.checkGuard(null); // Delegating to the underlying policy is not supported. - grantCache.putAll(checkGrants(grants)); // Fails if SecurityException + checkNullElements(grants); // If we get to here, the caller has permission. processGrants(grants); } @@ -594,14 +626,14 @@ public class DynamicConcurrentPolicyProv * * @param grants */ - private void processGrants(Collection<PermissionGrant> grants) { + private void processGrants(PermissionGrant[] grants) { // This is slightly naughty calling a remotePolicyGrants method, however if it // changes between now and gaining the lock, only the length of the // HashSet is potentially not optimal, keeping the HashSet creation // outside of the lock reduces the lock held duration. HashSet<PermissionGrant> holder - = new HashSet<PermissionGrant>(grants.size()); - holder.addAll(grants); + = new HashSet<PermissionGrant>(grants.length); + holder.addAll(Arrays.asList(grants)); PermissionGrant[] old = null; synchronized (grantLock) { old = remotePolicyGrants; @@ -612,6 +644,7 @@ public class DynamicConcurrentPolicyProv Collection<PermissionGrant> oldGrants = new HashSet<PermissionGrant>(old.length); oldGrants.addAll(Arrays.asList(old)); oldGrants.removeAll(holder); + // Collect removed Permission's to notify InternetSecurityManager. Set<Permission> removed = new HashSet<Permission>(120); Iterator<PermissionGrant> rgi = oldGrants.iterator(); while (rgi.hasNext()){ Copied: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Deny.java (from r1139517, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DenyImpl.java) URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Deny.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Deny.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DenyImpl.java&r1=1139517&r2=1152990&rev=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DenyImpl.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Deny.java Tue Aug 2 01:15:27 2011 @@ -18,12 +18,18 @@ package org.apache.river.impl.security.policy.util; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; import org.apache.river.api.security.*; import java.net.URL; import java.security.CodeSigner; import java.security.CodeSource; import java.security.ProtectionDomain; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -45,17 +51,15 @@ import org.apache.river.impl.security.po * circumvent security bugs identified in known jar files by trusted developers. * * Exclusion does not allow any permission, only Exclusion. - * - * This class may be extended. The caller must have a DenyPermission before it - * can be added to a PermissionGrantBuilder. * * @author Peter Firmstone */ -public abstract class DenyImpl extends Exclusion { +public final class Deny implements Exclusion, Serializable { + private static final long serialVersionUID = 1L; private final List<URL> uri; private final List<CodeSource> code; - public DenyImpl(List<URL> denyURL, List<CodeSource> denyCode){ + public Deny(List<URL> denyURL, List<CodeSource> denyCode){ List<URL> denied = new ArrayList<URL>(denyURL.size()); Iterator<URL> itU = denyURL.iterator(); while (itU.hasNext()){ @@ -78,7 +82,7 @@ public abstract class DenyImpl extends E return code; } - public boolean allows(ProtectionDomain pd){ + public boolean excludes(ProtectionDomain pd){ CodeSource cs = pd.getCodeSource(); cs = normalizeCodeSource(cs); if (code.contains(cs)) return false; @@ -103,5 +107,42 @@ public abstract class DenyImpl extends E } } return result; - } + } + + //writeReplace method for serialization proxy pattern + private Object writeReplace() { + return new SerializationProxy(uri, code); + } + + //readObject method for the serialization proxy pattern + private void readObject(ObjectInputStream stream) + throws InvalidObjectException{ + throw new InvalidObjectException("SerializationProxy required"); + } + + private static class SerializationProxy { + // Converted to Array's for more compact serialization. + private URL[] url; + private CodeSource[] code; + private SerializationProxy(List<URL> urls, List<CodeSource> codeSources){ + url = urls.toArray(new URL[urls.size()]); + code = codeSources.toArray(new CodeSource[codeSources.size()]); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + } + + private void writeObject(ObjectOutputStream out) throws IOException{ + out.defaultWriteObject(); + } + + // readResolve method returns a PermissionGrant instance. + private Object readResolve(){ + return new Deny(Arrays.asList(url), Arrays.asList(code)); + } + + } } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java Tue Aug 2 01:15:27 2011 @@ -18,6 +18,10 @@ package org.apache.river.impl.security.policy.util; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; import org.apache.river.api.security.Exclusion; import org.apache.river.api.security.PermissionGrantBuilder; import java.lang.ref.WeakReference; @@ -32,7 +36,8 @@ import org.apache.river.api.security.Per * TODO: Document and complete Serializable. * @author Peter Firmstone */ -public class PermissionGrantBuilderImp implements PermissionGrantBuilder{ +public class PermissionGrantBuilderImp extends PermissionGrantBuilder implements + Serializable{ private static final long serialVersionUID = 1L; private CodeSource cs; private Certificate[] certs; @@ -48,7 +53,7 @@ public class PermissionGrantBuilderImp i } /** - * Resets builder back to initial state, ready to recieve new information + * Resets builder back to initial state, ready to receive new information * for building a new PermissionGrant. */ public void reset() { @@ -65,8 +70,8 @@ public class PermissionGrantBuilderImp i if (context < 0) { throw new IllegalStateException("context must be >= 0"); } - if (context > 3) { - throw new IllegalStateException("context must be <= 3"); + if (context > 4) { + throw new IllegalStateException("context must be <= 4"); } this.context = context; return this; @@ -128,6 +133,8 @@ public class PermissionGrantBuilderImp i return new CertificateGrant(certs, principals, permissions, deny ); case PROTECTIONDOMAIN: return new ProtectionDomainGrant(domain, principals, permissions ); + case PRINCIPAL: + return new PrincipalGrant(principals, permissions); default: return null; } @@ -137,5 +144,19 @@ public class PermissionGrantBuilderImp i deny = denial; return this; } - + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + } + + private void writeObject(ObjectOutputStream out) throws IOException{ + out.defaultWriteObject(); + } + + // readResolve method returns a PermissionGrant instance. + private Object readResolve(){ + return build(); + } } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java Tue Aug 2 01:15:27 2011 @@ -18,6 +18,10 @@ package org.apache.river.impl.security.policy.util; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.lang.ref.WeakReference; import org.apache.river.api.security.PermissionGrantBuilder; import java.net.URL; import java.security.CodeSigner; @@ -26,6 +30,7 @@ import java.security.Permission; import java.security.Principal; import java.security.ProtectionDomain; import java.security.acl.Group; +import java.security.cert.Certificate; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -40,29 +45,30 @@ import org.apache.river.api.security.Per * * @author Peter Firmstone. */ -class PrincipalGrant implements PermissionGrant { - private final Set<Principal> principals; +class PrincipalGrant implements PermissionGrant, Serializable{ + private static final long serialVersionUID = 1L; + private final Set<Principal> pals; private final int hashCode; - private final Set<Permission> permissions; + private final Set<Permission> perms; @SuppressWarnings("unchecked") PrincipalGrant(Principal[] pals, Permission[] perm){ if ( pals != null ){ Set<Principal> palCol = new HashSet<Principal>(pals.length); palCol.addAll(Arrays.asList(pals)); - principals = Collections.unmodifiableSet(palCol); + this.pals = Collections.unmodifiableSet(palCol); }else { - principals = Collections.EMPTY_SET; + this.pals = Collections.EMPTY_SET; } if (perm == null || perm.length == 0) { - this.permissions = Collections.EMPTY_SET; + this.perms = Collections.EMPTY_SET; }else{ Set<Permission> perms = new HashSet<Permission>(perm.length); perms.addAll(Arrays.asList(perm)); - this.permissions = Collections.unmodifiableSet(perms); + this.perms = Collections.unmodifiableSet(perms); } int hash = 5; - hash = 97 * hash + (this.principals != null ? this.principals.hashCode() : 0); - hash = 97 * hash + (this.permissions != null ? this.permissions.hashCode() : 0); + hash = 97 * hash + (this.pals != null ? this.pals.hashCode() : 0); + hash = 97 * hash + (this.perms != null ? this.perms.hashCode() : 0); hashCode = hash; } @@ -73,8 +79,8 @@ class PrincipalGrant implements Permissi if (o.hashCode() != this.hashCode()) return false; if (o instanceof PrincipalGrant ){ PrincipalGrant p = (PrincipalGrant) o; - if (principals.equals(p.principals) - && permissions.equals(p.permissions)) return true; + if (pals.equals(p.pals) + && perms.equals(p.perms)) return true; } return false; } @@ -85,14 +91,14 @@ class PrincipalGrant implements Permissi } boolean implies(Principal[] prs) { - if ( principals.isEmpty()) return true; + if ( pals.isEmpty()) return true; if ( prs == null || prs.length == 0 ) return false; // PermissionGrant Principals match if equal or if they are Groups and // the Principals being tested are their members. Every Principal // in this PermissionGrant must have a match. List<Principal> princp = Arrays.asList(prs); int matches = 0; - Iterator<Principal> principalItr = principals.iterator(); + Iterator<Principal> principalItr = pals.iterator(); while (principalItr.hasNext()){ Principal entrypal = principalItr.next(); Group g = null; @@ -132,7 +138,7 @@ class PrincipalGrant implements Permissi // } } } - if (matches == principals.size()) return true; + if (matches == pals.size()) return true; return false; } @@ -161,7 +167,7 @@ class PrincipalGrant implements Permissi public boolean implies(ProtectionDomain pd) { if (pd == null) return false; - if (principals.isEmpty()) return true; + if (pals.isEmpty()) return true; Principal[] hasPrincipals = pd.getPrincipals(); return implies(hasPrincipals); } @@ -177,17 +183,29 @@ class PrincipalGrant implements Permissi public PermissionGrantBuilder getBuilderTemplate() { PermissionGrantBuilder pgb = new PermissionGrantBuilderImp(); - pgb.principals(principals.toArray(new Principal[principals.size()])) - .permissions(permissions.toArray(new Permission[permissions.size()])); + pgb.context(PermissionGrantBuilder.PRINCIPAL) + .principals(pals.toArray(new Principal[pals.size()])) + .permissions(perms.toArray(new Permission[perms.size()])); return pgb; } public Collection<Permission> getPermissions() { - return permissions; + return perms; } public boolean isVoid(Exclusion excl) { - if (permissions.size() == 0 ) return true; + if (perms.size() == 0 ) return true; return false; } + + //writeReplace method for serialization proxy pattern + private Object writeReplace() { + return getBuilderTemplate(); + } + + //readObject method for the serialization proxy pattern + private void readObject(ObjectInputStream stream) + throws InvalidObjectException{ + throw new InvalidObjectException("PermissionGrantBuilder required"); + } } Added: river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PrincipalGrantTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PrincipalGrantTest.java?rev=1152990&view=auto ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PrincipalGrantTest.java (added) +++ river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PrincipalGrantTest.java Tue Aug 2 01:15:27 2011 @@ -0,0 +1,233 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.apache.river.impl.security.policy.util; + +import tests.support.MyPrincipal; +import java.io.Serializable; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.security.Permission; +import java.security.CodeSource; +import java.security.Principal; +import java.security.ProtectionDomain; +import java.util.Collection; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.river.api.security.Exclusion; +import org.apache.river.api.security.PermissionGrantBuilder; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author peter + */ +public class PrincipalGrantTest { + + public PrincipalGrantTest() { + } + + @BeforeClass + public static void setUpClass() throws Exception { + } + + @AfterClass + public static void tearDownClass() throws Exception { + } + + @Before + public void setUp() { + } + + /** + * Test of equals method, of class PrincipalGrant. + */ +// @Test +// public void testEquals() { +// System.out.println("equals"); +// Object o = null; +// PrincipalGrant instance = null; +// boolean expResult = false; +// boolean result = instance.equals(o); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of hashCode method, of class PrincipalGrant. +// */ +// @Test +// public void testHashCode() { +// System.out.println("hashCode"); +// PrincipalGrant instance = null; +// int expResult = 0; +// int result = instance.hashCode(); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of implies method, of class PrincipalGrant. +// */ +// @Test +// public void testImplies_PrincipalArr() { +// System.out.println("implies"); +// Principal[] prs = null; +// PrincipalGrant instance = null; +// boolean expResult = false; +// boolean result = instance.implies(prs); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of normalizeCodeSource method, of class PrincipalGrant. +// */ +// @Test +// public void testNormalizeCodeSource() { +// System.out.println("normalizeCodeSource"); +// CodeSource codeSource = null; +// PrincipalGrant instance = null; +// CodeSource expResult = null; +// CodeSource result = instance.normalizeCodeSource(codeSource); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of implies method, of class PrincipalGrant. +// */ +// @Test +// public void testImplies_ProtectionDomain() { +// System.out.println("implies"); +// ProtectionDomain pd = null; +// PrincipalGrant instance = null; +// boolean expResult = false; +// boolean result = instance.implies(pd); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of implies method, of class PrincipalGrant. +// */ +// @Test +// public void testImplies_ClassLoader_PrincipalArr() { +// System.out.println("implies"); +// ClassLoader cl = null; +// Principal[] pal = null; +// PrincipalGrant instance = null; +// boolean expResult = false; +// boolean result = instance.implies(cl, pal); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of implies method, of class PrincipalGrant. +// */ +// @Test +// public void testImplies_CodeSource_PrincipalArr() { +// System.out.println("implies"); +// CodeSource codeSource = null; +// Principal[] pal = null; +// PrincipalGrant instance = null; +// boolean expResult = false; +// boolean result = instance.implies(codeSource, pal); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of getBuilderTemplate method, of class PrincipalGrant. +// */ +// @Test +// public void testGetBuilderTemplate() { +// System.out.println("getBuilderTemplate"); +// PrincipalGrant instance = null; +// PermissionGrantBuilder expResult = null; +// PermissionGrantBuilder result = instance.getBuilderTemplate(); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of getPermissions method, of class PrincipalGrant. +// */ +// @Test +// public void testGetPermissions() { +// System.out.println("getPermissions"); +// PrincipalGrant instance = null; +// Collection expResult = null; +// Collection result = instance.getPermissions(); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of isVoid method, of class PrincipalGrant. +// */ +// @Test +// public void testIsVoid() { +// System.out.println("isVoid"); +// Exclusion excl = null; +// PrincipalGrant instance = null; +// boolean expResult = false; +// boolean result = instance.isVoid(excl); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } + + /** + * Test of readResolve method, of class PrincipalGrant. + */ + @Test + public void testSerialization() { + System.out.println("Serialization test"); + Principal pal1 = new MyPrincipal("Test Principal 1"); + Principal pal2 = new MyPrincipal("Test Principal 2"); + Principal[] pals = new Principal[2]; + pals[0]= pal1; + pals[1]= pal2; + Permission perm1 = new RuntimePermission("getProtationDomain"); + Permission perm2 = new RuntimePermission("getClassLoader"); + Permission[] perms = new Permission[2]; + perms[0] = perm1; + perms[1] = perm2; + PrincipalGrant instance = new PrincipalGrant(pals,perms); + PrincipalGrant result = null; + ObjectOutputStream out = null; + ObjectInputStream in = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + out = new ObjectOutputStream(baos); + out.writeObject(instance); + // Unmarshall it + in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); + result = (PrincipalGrant) in.readObject(); + } catch (IOException ex) { + ex.printStackTrace(System.out); + } catch (ClassNotFoundException ex){ + ex.printStackTrace(System.out); + } + assertEquals(instance, result); + } +} Propchange: river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PrincipalGrantTest.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: river/jtsk/skunk/peterConcurrentPolicy/test/src/tests/support/MyPrincipal.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/test/src/tests/support/MyPrincipal.java?rev=1152990&r1=1152989&r2=1152990&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/test/src/tests/support/MyPrincipal.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/test/src/tests/support/MyPrincipal.java Tue Aug 2 01:15:27 2011 @@ -22,9 +22,10 @@ package tests.support; +import java.io.Serializable; import java.security.Principal; -public class MyPrincipal implements Principal { +public class MyPrincipal implements Principal, Serializable { private String name;
