You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2010/12/28 11:05:23 UTC

svn commit: r1053295 - in /incubator/river/jtsk/skunk/pepe: src/org/apache/river/api/lookup/ src/org/apache/river/api/security/ src/org/apache/river/impl/security/policy/se/ src/org/apache/river/impl/security/policy/util/ test/src/org/apache/river/impl...

Author: peter_firmstone
Date: Tue Dec 28 10:05:22 2010
New Revision: 1053295

URL: http://svn.apache.org/viewvc?rev=1053295&view=rev
Log:
Minor refactoring

Added:
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicGrants.java   (with props)
Modified:
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrant.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java
    incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java Tue Dec 28 10:05:22 2010
@@ -5,11 +5,12 @@
 
 package org.apache.river.api.lookup;
 
-import net.jini.core.lookup.*;
 import java.net.URI;
 import java.security.CodeSource;
 import java.util.Collection;
 import net.jini.core.entry.Entry;
+import net.jini.core.lookup.ServiceID;
+import net.jini.core.lookup.ServiceItem;
 
 /**
  * MarshalledServiceItem extends ServiceItem and can be used anywhere a 

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java Tue Dec 28 10:05:22 2010
@@ -27,9 +27,21 @@ import net.jini.core.lookup.ServiceItem;
  */
 public class ServiceResultStreamFilter implements ResultStream<ServiceItem> {
     private final List<ServiceItemFilter> filters;
-    private final ResultStream<ServiceItem> inputResultStream;
+    private final ResultStream inputResultStream;
     
-    public ServiceResultStreamFilter(ResultStream<ServiceItem> rs,
+    /**
+     * Note the methods of ServiceResultStreamFilter implement 
+     * ResultStream<ServiceItem>, but the constructor doesn't, this is to 
+     * protect the client against unchecked type casts that would occur
+     * if a ResultStream<ServiceItem> was obtained from a service.
+     * 
+     * All methods in this implementation perform their own type safety
+     * checks in order to implement ResultStream<ServiceItem> safely.
+     * 
+     * @param rs
+     * @param sf
+     */
+    public ServiceResultStreamFilter(ResultStream rs,
             ServiceItemFilter[] sf){
         inputResultStream = rs;
         filters = new ArrayList<ServiceItemFilter>(sf.length);
@@ -37,14 +49,17 @@ public class ServiceResultStreamFilter i
     }
 
     public ServiceItem get() {
-        for(ServiceItem item = inputResultStream.get(); item != null; 
+        for(Object item = inputResultStream.get(); item != null; 
                 item = inputResultStream.get()) {
-            int l = filters.size();
-            for ( int i = 0; i < l; i++){
-                ServiceItemFilter filter = filters.get(i);
-                if(filter == null)  continue;
-                if( filter.check(item) )  return item;
-            }// end filter loop
+	    if (item instanceof ServiceItem){
+		ServiceItem it = (ServiceItem) item;
+		int l = filters.size();
+		for ( int i = 0; i < l; i++){
+		    ServiceItemFilter filter = filters.get(i);
+		    if (filter == null) continue;
+		    if (filter.check(it))  return it;
+		}// end filter loop
+	    }// If it isn't a ServiceItem it is ignored.
         }//end item loop
         return null; // Our stream terminated item was null;
     }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java Tue Dec 28 10:05:22 2010
@@ -1,6 +1,19 @@
 /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package org.apache.river.api.lookup;
@@ -20,22 +33,31 @@ import net.jini.core.lookup.*;
  * @see StreamServiceRegistrar
  */
 public class ServiceResultStreamUnmarshaller implements ResultStream<ServiceItem> {
-    ResultStream<ServiceItem> input;
+    ResultStream input;
     
-    public ServiceResultStreamUnmarshaller(ResultStream<ServiceItem> rs){
+    /** 
+     * Note the methods of ServiceResultStreamUnmarshaller, implement the 
+     * generic methods of ResultStream<ServiceItem>, but the constructor 
+     * doesn't to ensure type safety at the client, where runtime binding 
+     * prevents the compiler from checking the type.
+     */ 
+    public ServiceResultStreamUnmarshaller(ResultStream rs){
         input = rs;
     }
 
     public ServiceItem get() {
-        for(ServiceItem item = input.get(); item != null; 
-                item = input.get()) {
+        for(Object item = input.get(); item != null; item = input.get()) {
             if (item instanceof MarshalledServiceItem){
                 MarshalledServiceItem msi = (MarshalledServiceItem) item;
                 ServiceItem it = new ServiceItem(msi.serviceID, msi.getService(null),
                         msi.getEntries());
-                item = it;
-            }
-            return item;
+                return it;
+            } else if (item instanceof ServiceItem) {
+		return (ServiceItem) item;
+	    }
+	    /* If item is not an instanceof ServiceItem or MarshalledServiceItem
+	     * it is ignored and the next item in the ResultStream is retrieved.
+	     */
         }//end item loop
         return null; // Our stream terminated item was null;
     }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java Tue Dec 28 10:05:22 2010
@@ -84,7 +84,7 @@ public interface StreamServiceRegistrar 
      * @see ResultStreamUnmarshaller
      * @since 2.2.0
      */
-    ResultStream<ServiceItem> lookup(ServiceTemplate tmpl, 
+    ResultStream lookup(ServiceTemplate tmpl, 
         Class[] unmarshalledEntries, int maxBatchSize) throws IOException;
     
     /**
@@ -100,11 +100,11 @@ public interface StreamServiceRegistrar 
      *
      * @param tmpl template to match
      * @param maxBatchSize 
-     * @return a ResultStream of entry Classes (attribute sets) for every service
+     * @return a ResultStream containing Class of entry (attribute sets) for every service
      * that matches the specified template
      * @throws java.rmi.RemoteException
      */
-    ResultStream<Class> getEntryClasses(ServiceTemplate tmpl, int maxBatchSize) 
+    ResultStream getEntryClasses(ServiceTemplate tmpl, int maxBatchSize) 
             throws IOException;
 
     /**
@@ -147,11 +147,11 @@ public interface StreamServiceRegistrar 
      * @param prefix class name prefix
      *
      * @param maxBatchSize 
-     * @return an array of Classes of all services that either match the
+     * @return a ResultStream containing a Class for all services that either match the
      * specified template or match the specified prefix
      * @throws java.rmi.RemoteException
      */
-    ResultStream<Class> getServiceTypes(ServiceTemplate tmpl, String prefix, 
+    ResultStream getServiceTypes(ServiceTemplate tmpl, String prefix, 
             int maxBatchSize) throws IOException;
 
 }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java Tue Dec 28 10:05:22 2010
@@ -18,8 +18,12 @@
 
 package org.apache.river.api.security;
 
+
+import java.security.CodeSource;
 import java.security.Permission;
+import java.security.Principal;
 import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
 
 /**
  * A Exclusion implementation must be immutable, it will be accessed by concurrent
@@ -33,17 +37,59 @@ import java.security.ProtectionDomain;
  * Code signer Certificate's 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 interface Exclusion {
+public abstract class Exclusion {
     /**
      * Exclusion is used by a PermissionGrantBuilder, to filter out unwanted
-     * ProtectionDomain implies based on any set of conditions.  This is useful
-     * for a PermissionGrant that generically grant's for one 
+     * ProtectionDomain implies based on any set of conditions.  This method
+     * is relevant to a Policy.
      * 
      * @param pd
      * @param perm may be null;
      * @return
      */
-    public boolean allows(ProtectionDomain pd);
+    public abstract boolean excludes(ProtectionDomain pd);
+    /**
+     * Checks if this Exclusion excludes a ProtectionDomain, the Principal
+     * array may be empty but not null.  The Principal array is provided
+     * to avoid needing to create a new ProtectionDomain instance containing
+     * the array of Principals.
+     * 
+     * @param pd
+     * @param p
+     * @return
+     */
+    public abstract boolean excludes(ProtectionDomain pd, Principal[] p);
+    /**
+     * Checks if this Exclusion excludes a ClassLoader domain, with an
+     * array of Principals
+     * @param cl
+     * @param p
+     * @return
+     */
+    public abstract boolean excludes(ClassLoader cl, Principal[] p);
+    /**
+     * Checks if the exclusions excludes a CodeSource and array of Principals
+     * @param cs
+     * @param p
+     * @return
+     */
+    public abstract boolean excludes(CodeSource cs, Principal[] p);
+    /**
+     * Checks if the exclusion excludes an array of Certificats and Principals.
+     * @param c
+     * @param p
+     * @return
+     */
+    public abstract boolean excludes(Certificate[] c, Principal[] p);
 }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrant.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrant.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrant.java Tue Dec 28 10:05:22 2010
@@ -88,8 +88,9 @@ public interface PermissionGrant {
 
     /**
      * Returns true if this PermissionGrant defines no Permissions, or if
-     * a PermissionGrant was made to a ProtectionDomain that no longer exists.
+     * a PermissionGrant was made to a ProtectionDomain that no longer exists,
+     * or if the Exclusion excludes the PermissionGrant.
      */
-    boolean isVoid();
+    public boolean isVoid(Exclusion excl);
 
 }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java Tue Dec 28 10:05:22 2010
@@ -41,6 +41,7 @@ import org.apache.river.api.security.Rev
 import org.apache.river.api.security.RevokeableDynamicPolicy;
 import org.apache.river.impl.security.policy.util.PermissionGrantBuilderImp;
 import org.apache.river.impl.security.policy.util.PolicyUtils;
+import org.apache.river.impl.util.ConcurrentCollections;
 import org.apache.river.impl.util.ConcurrentWeakIdentityMap;
 
 /**
@@ -145,7 +146,7 @@ public class DynamicConcurrentPolicyProv
     private volatile PermissionGrant[] pGrants;
     /* This lock protects adding and removal of PermissionGrant's*/
     private final Object grantLock;
-    //private final Set<PermissionGrant> dynamicGrants; // protected by rwl
+    private final Collection<DynamicGrants> dynamicGrants;
     private volatile Policy basePolicy; // effectively final looks after its own sync
     private final ConcurrentMap<ProtectionDomain, PermissionCollection> cache;
     private final ConcurrentMap<PermissionGrant, Permission[]> grantCache;
@@ -156,12 +157,7 @@ public class DynamicConcurrentPolicyProv
     private volatile boolean loggable;
     // do something about some domain permissions for this domain so we can 
     // avoid dead locks due to bug 4911907
-    /* This lock Protects denied */
-//    private final ReentrantReadWriteLock drwl;
-//    private final ReadLock drl;
-//    private final WriteLock dwl;
-//    private final Set<Denied> denied;
-//    private volatile boolean checkDenied;
+
     private final SecurityManager sm;
     private final Guard g;
     
@@ -171,6 +167,7 @@ public class DynamicConcurrentPolicyProv
         basePolicy = null;
         cache = new ConcurrentWeakIdentityMap<ProtectionDomain, PermissionCollection>();
 	grantCache = new ConcurrentWeakIdentityMap<PermissionGrant, Permission[]>();
+	dynamicGrants = ConcurrentCollections.multiReadCollection(new ArrayList<DynamicGrants>());
         basePolicyIsDynamic = false;
         revokeable = true;
         logger = Logger.getLogger("net.jini.security.policy");
@@ -268,7 +265,7 @@ public class DynamicConcurrentPolicyProv
 	 * performed by the ProtectionDomain.
 	 * 
 	 * However we add Permission's wrapped in a PolicyPermission for
-	 * holding dynamic Permissions to print debuggin information using toString
+	 * holding dynamic Permissions to print debugging information using toString
 	 * PolicyPermission doesn't imply anything useful, it's just a
 	 * container.
 	 */
@@ -407,7 +404,7 @@ public class DynamicConcurrentPolicyProv
 	    ArrayList<PermissionGrant> grantHolder 
 		    = new ArrayList<PermissionGrant>(l);
 	    for ( int i = 0; i < l; i++ ){
-		if ( pGrants[i].isVoid()) continue;
+		if ( pGrants[i].isVoid(null)) continue;
 		grantHolder.add(pGrants[i]);
 	    }
 	    PermissionGrant[] remaining = new PermissionGrant[grantHolder.size()];
@@ -566,7 +563,7 @@ public class DynamicConcurrentPolicyProv
 	synchronized (grantLock) {	    
 	    int l = pGrants.length;
 	    for ( int i = 0; i < l; i++ ){
-		if (pGrants[i].isVoid()) continue;
+		if (pGrants[i].isVoid(null)) continue;
 		holder.add(pGrants[i]);
 	    }
 	    PermissionGrant[] updated = new PermissionGrant[holder.size()];
@@ -587,7 +584,7 @@ public class DynamicConcurrentPolicyProv
 	synchronized (grantLock){
 	    int l = pGrants.length;
 	    for (int i = 0; i < l; i++){
-		if (pGrants[i].isVoid() || grants.contains(pGrants[i])) {
+		if (pGrants[i].isVoid(null) || grants.contains(pGrants[i])) {
 		    // should we consider removing from grantCache?
 		    // For now we just let GC clean it up.
 		    Permission [] perms = grantCache.get(pGrants[i]);

Added: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicGrants.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicGrants.java?rev=1053295&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicGrants.java (added)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicGrants.java Tue Dec 28 10:05:22 2010
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.impl.security.policy.se;
+
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.apache.river.api.security.Exclusion;
+import org.apache.river.api.security.PermissionGrant;
+
+/**
+ * Further grants cannot be added after an exclusion has been set, although further
+ * Exclusions may be added.
+ * 
+ * The behaviour of revocation of dynamic permission's needs either by removal
+ * of a PermissionGrant directly or via addition of Exclusions, this data
+ * structure allows the addition of grants until an exclusion is added.
+ * 
+ * Example: A number of different dynamic grants are specified, including
+ * CodeSource & Principal and ClassLoader & Principal it is determined that
+ * all Permission's should be revoked from a ClassLoader namespace (proxy), 
+ * hence an exclusion
+ * needs to be made to totally Exclude the ClassLoader namespace, this also
+ * needs to prevent any grants from CodeSource applying to the ClassLoader
+ * namespace.
+ * 
+ * Once an Exclusion has been made, it is expected that a new PermissionGrant
+ * will override an exclusion, which is why new PermissionGrants are prevented
+ * from being added after an Exclusion, since exclusions are checked before
+ * PermissionGrant's in a DynamicGrants instance.
+ * 
+ * If all exclusions are removed, it is possible to add grants again.
+ * 
+ * Should I allow irrelevant Permission grant's to remove themselves?
+ * 
+ * How should a user track state?
+ * 
+ * The problem with the way PermissionGrant's are managed, is that they
+ * are runtime binding, meaning we have to check every one, if each
+ * grant had it's own exclusion, it would mean that when adding a single
+ * exclusion and there were 100 grant's the exclusion would be checked
+ * 100 times.  This is obviously not efficient.
+ * 
+ * If an exclusion is removed, but grants were removed by adding an 
+ * exclusion, the policy doesn't return to an expected state.
+ * 
+ * However, if when we add a grant to DynamicGrant's that contains exclusions
+ * we should remove any exclusions that are cancelled out completely by the grant.
+ * 
+ * Then if no exclusions remain, then the grant may be added, however if
+ * exclusions still exist we must return false and the grant be added to
+ * another domain.
+ * 
+ * Therefore, Grants and Exclusions should only ever be added, never removed
+ * by a public interface.  Since this becomes a time based sequence, we 
+ * might like to Exclude then grant in one operation.
+ * 
+ * An Exclusion also needs to know when it no longer excludes anything. An 
+ * Exclusion becomes irrelevant when 
+ * 
+ * @author peter
+ */
+public class DynamicGrants {
+    private final List<PermissionGrant> grants;
+    // index always indicates the next available 
+    private final List<Exclusion> excludes;
+    private volatile boolean grantLock;
+    private final ReadWriteLock rwl;
+    private final Lock rl;
+    private final Lock wl;
+    
+    DynamicGrants(){
+	this.grants = new ArrayList<PermissionGrant>();
+	excludes = new ArrayList<Exclusion>();
+	rwl = new ReentrantReadWriteLock();
+	rl = rwl.readLock();
+	wl = rwl.writeLock();
+	grantLock = false;
+    }
+    
+    public boolean addGrant(PermissionGrant pg){
+	if (grantLock) return false;
+	wl.lock();
+	try {
+	   return grants.add(pg);
+	} finally {
+	    wl.unlock();
+	}
+    }
+    
+    public boolean removeGrant(PermissionGrant pg){
+	wl.lock();
+	try {
+	   return grants.remove(pg);
+	} finally {
+	    wl.unlock();
+	}
+    }
+    
+    public void addExclusion(Exclusion e){
+	wl.lock();
+	try {
+	    grantLock = true;
+	    excludes.add(e);
+	    Iterator<PermissionGrant> pgi = grants.iterator();
+	    while (pgi.hasNext()){
+		PermissionGrant g = pgi.next();
+		if (g.isVoid(e)) pgi.remove();
+	    }
+	} finally {
+	    wl.unlock();
+	}
+    }
+    
+    public void removeExclusion(Exclusion e){
+	wl.lock();
+	try {
+	    excludes.remove(e);
+	    if (excludes.size() == 0) {
+		grantLock = false;
+	    }
+	} finally {
+	    wl.unlock();
+	}
+    }
+	
+    public PermissionGrant [] get(ProtectionDomain pd){
+	rl.lock();
+	try {
+	    // Check all excludes first, if any exclude, return an empty grant.
+	    Iterator<Exclusion> exclusions = excludes.iterator();
+	    while (exclusions.hasNext()){
+		if ( (exclusions.next().excludes(pd))) return new PermissionGrant[0];
+	    }
+	    return getIgnoreExcl(pd);
+	} finally {
+	    rl.unlock();	 
+	}
+	    
+    }
+    
+    public PermissionGrant [] getIgnoreExcl(ProtectionDomain pd){
+	List<PermissionGrant> applicableGrants = new ArrayList<PermissionGrant>();
+	rl.lock();
+	try {
+	    Iterator<PermissionGrant> git = grants.iterator();
+	    while (git.hasNext()){
+		PermissionGrant g = git.next();
+		if (g.implies(pd)) applicableGrants.add(g);
+	    }
+	    return applicableGrants.toArray(new PermissionGrant[applicableGrants.size()]);
+	} finally {
+	    rl.unlock();	 
+	}
+    }
+    
+}

Propchange: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicGrants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java Tue Dec 28 10:05:22 2010
@@ -76,16 +76,14 @@ class CertificateGrant extends Principal
     @Override
     public boolean implies(ProtectionDomain pd) {
 	if ( !super.implies(pd)) return false;
-        if ( exclusion.allows(pd)){
-            CodeSource c = null;
-            Principal[] pals = null;
-            if (pd != null){
-                c = pd.getCodeSource();
-                pals = pd.getPrincipals();
-            }
-            return implies(c, pals);
-        }
-        return false;
+        if ( exclusion.excludes(pd)) return false;
+	CodeSource c = null;
+	Principal[] pals = null;
+	if (pd != null){
+	    c = pd.getCodeSource();
+	    pals = pd.getPrincipals();
+	}
+	return implies(c, pals);
     }
     
     // Subclasses shouldn't call this if 

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java Tue Dec 28 10:05:22 2010
@@ -136,7 +136,7 @@ public class DefaultPolicyParser impleme
                     .next();
             try {
                 PermissionGrant pe = resolveGrant(ge, ks, system, resolve);
-                if (!pe.isVoid()) {
+                if (!pe.isVoid(null)) {
                     result.add(pe);
                 }
             }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java Tue Dec 28 10:05:22 2010
@@ -33,6 +33,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import org.apache.river.api.security.Exclusion;
 import org.apache.river.api.security.PermissionGrant;
 
 /**
@@ -185,7 +186,7 @@ class PrincipalGrant implements Permissi
         return permissions;
     }
     
-    public boolean isVoid() {        
+    public boolean isVoid(Exclusion excl) {        
         if (permissions.size() == 0 ) return true;
         return false;
     }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java Tue Dec 28 10:05:22 2010
@@ -27,6 +27,7 @@ import java.security.ProtectionDomain;
 import java.security.cert.Certificate;
 import java.util.Arrays;
 import java.util.List;
+import org.apache.river.api.security.Exclusion;
 
 /**
  *
@@ -126,8 +127,8 @@ class ProtectionDomainGrant extends Prin
     }
 
     @Override
-    public boolean isVoid() {        
-        if ( super.isVoid()) return true;
+    public boolean isVoid(Exclusion excl) {        
+        if ( super.isVoid(null)) return true;
         if (hasDomain == true && domain.get() == null) return true;
         return false;
     }

Modified: incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java?rev=1053295&r1=1053294&r2=1053295&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java (original)
+++ incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java Tue Dec 28 10:05:22 2010
@@ -57,7 +57,7 @@ public class PolicyEntryTest extends Tes
 //        PolicyEntry pe =
 //            new PolicyEntry((CodeSource) null, (Collection<Principal>) null,
 //                (Collection<Permission>)null);
-        assertTrue(pe.isVoid());
+        assertTrue(pe.isVoid(null));
         assertTrue(pe.getPermissions().size() == 0);
 
 //        pe = new PolicyEntry(new CodeSource(null, (Certificate[])null),
@@ -66,14 +66,14 @@ public class PolicyEntryTest extends Tes
                 .principals(new Principal[0])
                 .permissions(new Permission[0])
                 .build();
-        assertTrue(pe.isVoid());
+        assertTrue(pe.isVoid(null));
         assertTrue(pe.getPermissions().size() == 0);
 
         Permission[] perms = new Permission[] {
             new SecurityPermission("dsfg"), new AllPermission() };
         //pe = new PolicyEntry((CodeSource) null, (Collection<Principal>) null, perms);
         pe = pgb.codeSource(null).principals(null).permissions(perms).build();
-        assertFalse(pe.isVoid());
+        assertFalse(pe.isVoid(null));
         assertTrue(Arrays.asList(perms).containsAll(pe.getPermissions()));
     }