river-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From peter_firmst...@apache.org
Subject svn commit: r1158535 [3/4] - in /river/jtsk/skunk/peterConcurrentPolicy: ./ qa/ qa/harness/policy/ qa/src/com/sun/jini/qa/harness/ qa/src/com/sun/jini/qa/resources/ qa/src/com/sun/jini/test/impl/reggie/ qa/src/com/sun/jini/test/impl/start/loadersplitpo...
Date Wed, 17 Aug 2011 06:18:12 GMT
Propchange: river/jtsk/skunk/peterConcurrentPolicy/qa_test_baseline.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/ConcurrentPermissions.java (from r1153098, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/ConcurrentPermissions.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/ConcurrentPermissions.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/ConcurrentPermissions.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/ConcurrentPermissions.java&r1=1153098&r2=1158535&rev=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/ConcurrentPermissions.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/ConcurrentPermissions.java Wed Aug 17 06:18:09 2011
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-package org.apache.river.impl.security.policy.se;
+package net.jini.security;
 
 import java.io.Serializable;
 import java.security.AllPermission;
@@ -167,7 +167,7 @@ implements Serializable {
         ArrayList<PermissionCollection> elem = 
                 new ArrayList<PermissionCollection>(permsMap.size() 
                                     + unresolved.awaitingResolution() + 2);
-	// Unresolved Permission's are added first in case the are resolved in 
+	// Unresolved Permission's are added first in case they are resolved in 
 	// the interim, meaning that they may also be present in resolved form
 	// also.  To do the reverse would risk some Permission's being absent.
         if (unresolved.awaitingResolution() > 0) {
@@ -178,18 +178,18 @@ implements Serializable {
         return new PermissionEnumerator(perms);                 
     }
     
-    /**
-     * Attempt to resolve any unresolved permissions whose class is visible
-     * from within this protection domain.
-     * @param pd 
-     */
-    public void resolve(ProtectionDomain pd){
-        if (unresolved.awaitingResolution() == 0){return;}
-        Enumeration<Permission> perms = unresolved.resolvePermissions(pd);
-        while (perms.hasMoreElements()){
-            add(perms.nextElement());
-        }
-    }
+//    /**
+//     * Attempt to resolve any unresolved permissions whose class is visible
+//     * from within this protection domain.
+//     * @param pd 
+//     */
+//    public void resolve(ProtectionDomain pd){
+//        if (unresolved.awaitingResolution() == 0){return;}
+//        Enumeration<Permission> perms = unresolved.resolvePermissions(pd);
+//        while (perms.hasMoreElements()){
+//            add(perms.nextElement());
+//        }
+//    }
     
     /*
      * This Enumeration is not intended for concurrent access, underlying

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/GrantPermission.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/GrantPermission.java?rev=1158535&r1=1158534&r2=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/GrantPermission.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/GrantPermission.java Wed Aug 17 06:18:09 2011
@@ -555,7 +555,7 @@ public final class GrantPermission exten
      * of permissions.
      */
     private static String constructName(Permission[] pa) {
-	StringBuffer sb = new StringBuffer();
+	StringBuffer sb = new StringBuffer(60);
 	for (int i = 0; i < pa.length; i++) {
 	    Permission p = pa[i];
 	    if (p instanceof UnresolvedPermission) {
@@ -763,7 +763,7 @@ public final class GrantPermission exten
 	    new ObjectStreamField("perms", List.class, true)
 	};
 
-	private List perms = new ArrayList();
+	private List perms = new ArrayList(40);
 	private Implier implier = new Implier();
 
 	public synchronized void add(Permission p) {
@@ -774,8 +774,10 @@ public final class GrantPermission exten
 		throw new SecurityException(
 		    "can't add to read-only PermissionCollection");
 	    }
-	    perms.add(p);
-	    implier.add((GrantPermission) p);
+	    if (!perms.contains(p)){
+		perms.add(p);
+		implier.add((GrantPermission) p);
+	    }
 	}
 	
 	public synchronized Enumeration elements() {

Copied: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/MultiReadPermissionCollection.java (from r1153098, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/MultiReadPermissionCollection.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/MultiReadPermissionCollection.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/MultiReadPermissionCollection.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/MultiReadPermissionCollection.java&r1=1153098&r2=1158535&rev=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/MultiReadPermissionCollection.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/MultiReadPermissionCollection.java Wed Aug 17 06:18:09 2011
@@ -16,10 +16,12 @@
  * limitations under the License.
  */
 
-package org.apache.river.impl.security.policy.se;
+package net.jini.security;
 
+import java.io.IOException;
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.security.Permission;
 import java.security.PermissionCollection;
@@ -49,19 +51,17 @@ import java.util.logging.Logger;
  * changed to a new cache.  Old Enumeration's will refer to stale
  * cache collections.
  * 
- * TODO Serialization Correctly
- * @version 0.3 2010/08/12
+ * @version 0.4 06 Aug 2011
  * @author Peter Firmstone
+ * @since 2.2.2
  */
-public final class MultiReadPermissionCollection extends PermissionCollection 
+final class MultiReadPermissionCollection extends PermissionCollection 
     implements Serializable {
     private final static long serialVersionUID = 1L;
-    private transient PermissionCollection permCl; // all access protected by rwl
+    private final PermissionCollection permCl; // all access protected by rwl
     private final transient ReadWriteLock rwl;
     private final transient Lock rl;
     private final transient Lock wl;
-    private boolean readOnly; // never instantiate for ide code completion of Serialization Proxy
-    private Permission[] permissions; //never instantiate for ide code completion of Serialization Proxy
     // Read only copy to prevent publication of internal PermissionCollection
     // state.  For generation of Enumeration<Permission>.
     // It is volatile because other read locks may update the cache reference
@@ -115,15 +115,15 @@ public final class MultiReadPermissionCo
         }finally {rl.unlock();}
         return false;
     }
-    
-    public int hashCode(){
-        rl.lock();
-        try {
-            return permCl.hashCode();
-        }finally {rl.unlock();}
-    }
 
     @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 37 * hash + (this.permCl != null ? this.permCl.hashCode() : 0);
+        return hash;
+    }
+    
+    @Override
     public void add(Permission permission) {
         wl.lock();
         try {
@@ -168,7 +168,8 @@ public final class MultiReadPermissionCo
     }
     
     
-    /* Returns an empty PermissionCollection
+    /* Returns an empty PermissionCollection, if not implemented by the
+     * permission, a PermissionHash is provided.
      */ 
     private PermissionCollection newPermissionCollection(Permission permission){        
         PermissionCollection pc = permission.newPermissionCollection();
@@ -180,8 +181,8 @@ public final class MultiReadPermissionCo
     
     private static class SerializationProxy implements Serializable {
         private static final long serialVersionUID = 1L;
-        private final Permission[] permissions;
-        private final boolean readOnly;
+        private Permission[] permissions;
+        private boolean readOnly;
         SerializationProxy(PermissionCollection pc){
             ArrayList<Permission> collection = new ArrayList<Permission>();
             Enumeration<Permission> en = pc.elements();
@@ -191,7 +192,27 @@ public final class MultiReadPermissionCo
             permissions = new Permission[collection.size()];
             collection.toArray(permissions);
             readOnly = pc.isReadOnly();
-        }        
+        } 
+        
+        private Object readResolve() {
+            MultiReadPermissionCollection pc = 
+                    new MultiReadPermissionCollection(permissions[0]);
+            int length = permissions.length;
+            for ( int i = 0 ; i < length ; i++){
+                pc.add(permissions[i]);
+            }
+            if ( readOnly == true ) {pc.setReadOnly();}
+            return pc;
+        }
+        
+        private void writeObject(ObjectOutputStream s) throws IOException{
+            s.defaultWriteObject();
+        }
+        
+        private void readObject(ObjectInputStream stream) throws 
+                InvalidObjectException, IOException, ClassNotFoundException {
+            stream.defaultReadObject();
+        }
     }
     
     private Object writeReplace(){
@@ -205,18 +226,10 @@ public final class MultiReadPermissionCo
         throw new InvalidObjectException("Proxy required");
     }
     
-    private Object readResolve() {
-        MultiReadPermissionCollection pc = new MultiReadPermissionCollection(permissions[0]);
-        int length = permissions.length;
-        for ( int i = 0 ; i < length ; i++){
-            pc.add(permissions[i]);
-        }
-        if ( readOnly == true ) {pc.setReadOnly();}
-        return pc;
-    }
+    
     
     private static final class PermissionHash extends PermissionCollection {
-        // This class is never serialized.
+        // This class is never serialized, locking must be performed externally.
         private final static long serialVersionUID = 1L;        
         private HashSet<Permission> permSet;
 
@@ -224,6 +237,7 @@ public final class MultiReadPermissionCo
             permSet = new HashSet<Permission>();
         }
 
+        @Override
         public boolean equals(Object obj){
             if (this == obj) return true;
             if (!(obj instanceof PermissionHash)) return false;
@@ -232,10 +246,14 @@ public final class MultiReadPermissionCo
             return false;
         }
 
-        public int hashCode(){
-            return permSet.hashCode();
+        @Override
+        public int hashCode() {
+            int hash = 3;
+            hash = 29 * hash + (this.permSet != null ? this.permSet.hashCode() : 0);
+            return hash;
         }
 
+        @Override
         public String toString(){
             return permSet.toString();
         }

Copied: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/PermissionPendingResolution.java (from r1153098, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/PermissionPendingResolution.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/PermissionPendingResolution.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/PermissionPendingResolution.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/PermissionPendingResolution.java&r1=1153098&r2=1158535&rev=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/PermissionPendingResolution.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/PermissionPendingResolution.java Wed Aug 17 06:18:09 2011
@@ -15,7 +15,7 @@
  *  limitations under the License.
  */
 
-package org.apache.river.impl.security.policy.se;
+package net.jini.security;
 
 import java.lang.reflect.Constructor;
 import java.security.Permission;

Copied: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/PermissionPendingResolutionCollection.java (from r1153098, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/PermissionPendingResolutionCollection.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/PermissionPendingResolutionCollection.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/PermissionPendingResolutionCollection.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/PermissionPendingResolutionCollection.java&r1=1153098&r2=1158535&rev=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/PermissionPendingResolutionCollection.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/PermissionPendingResolutionCollection.java Wed Aug 17 06:18:09 2011
@@ -15,7 +15,7 @@
  *  limitations under the License.
  */
 
-package org.apache.river.impl.security.policy.se;
+package net.jini.security;
 
 import java.security.AccessController;
 import java.security.Permission;
@@ -37,7 +37,7 @@ import java.util.concurrent.atomic.Atomi
  *
  * @author Peter Firmstone
  */
-public class PermissionPendingResolutionCollection  extends PermissionCollection {
+class PermissionPendingResolutionCollection  extends PermissionCollection {
     private static final long serialVersionUID = 1L;
     private ConcurrentHashMap<String,Collection<PermissionPendingResolution>> klasses;
     // This is a best effort counter, it doesn't try to identify duplicates.
@@ -115,32 +115,37 @@ public class PermissionPendingResolution
     
     //Should I be performing a privileged action? Or should it run with
     // the caller thread's privileges?
-    Enumeration<Permission> resolvePermissions(final ProtectionDomain pd){
-        @SuppressWarnings("unchecked")
-        ClassLoader cl = (ClassLoader) AccessController.doPrivileged(
-                new PrivilegedAction(){
-                public Object run(){
-                    ClassLoader cL = pd.getClassLoader();
-                    if (cL == null){
-                        cL = this.getClass().getClassLoader();
-                    }
-                    return cL;
-                }
-        });
-        
-        
-        List<Permission> perms = new ArrayList<Permission>();
-        Enumeration enPending = elements();
-        while (enPending.hasMoreElements()){
-            PermissionPendingResolution pendPerm = 
-                    (PermissionPendingResolution) enPending.nextElement();
-            Permission resolved =  pendPerm.resolve(cl);
-            if ( resolved != null ){
-                perms.add(resolved);
-            }           
-        }
-        return Collections.enumeration(perms);
-    }
+//    Enumeration<Permission> resolvePermissions(final ProtectionDomain pd){
+//        @SuppressWarnings("unchecked")
+//        ClassLoader cl = (ClassLoader) AccessController.doPrivileged(
+//                new PrivilegedAction(){
+//                public Object run(){
+//                    ClassLoader cL = pd.getClassLoader();
+//                    if (cL == null){
+//                        cL = Thread.currentThread().getContextClassLoader();
+//                    }
+//                    // This is no good because the ClassLoader is the extension loader.
+//                    // It might stop a null ClassLoader being returned though.
+//                    if (cL == null){
+//                        cL = this.getClass().getClassLoader();
+//                    }
+//                    return cL;
+//                }
+//        });
+//        
+//        
+//        List<Permission> perms = new ArrayList<Permission>();
+//        Enumeration enPending = elements();
+//        while (enPending.hasMoreElements()){
+//            PermissionPendingResolution pendPerm = 
+//                    (PermissionPendingResolution) enPending.nextElement();
+//            Permission resolved =  pendPerm.resolve(cl);
+//            if ( resolved != null ){
+//                perms.add(resolved);
+//            }           
+//        }
+//        return Collections.enumeration(perms);
+//    }
 
     @Override
     public boolean implies(Permission permission) {

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java?rev=1158535&r1=1158534&r2=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java Wed Aug 17 06:18:09 2011
@@ -43,6 +43,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
@@ -50,6 +51,7 @@ import javax.security.auth.Subject;
 import javax.security.auth.SubjectDomainCombiner;
 import net.jini.security.policy.DynamicPolicy;
 import net.jini.security.policy.SecurityContextSource;
+import org.apache.river.impl.util.ConcurrentWeakIdentityMap;
 
 /**
  * Provides methods for executing actions with privileges enabled, for
@@ -497,15 +499,17 @@ public final class Security {
      * principals of the <code>Subject</code>, as well as the ability to use
      * credentials of the <code>Subject</code> for authentication.
      * 
+     * @param <T> 
      * @param action the action to be executed
      * @return the object returned by the action's <code>run</code> method
      * @throws NullPointerException if the action is <code>null</code>
      */
-    public static Object doPrivileged(final PrivilegedAction action) {
+    public static <T> T doPrivileged(final PrivilegedAction<T> action) {
 	final Class caller = ctxAccess.getCaller();
 	final AccessControlContext acc = AccessController.getContext();
-	return AccessController.doPrivileged(new PrivilegedAction() {
-	    public Object run() {
+	return AccessController.doPrivileged(new PrivilegedAction<T>() {
+            
+	    public T run() {
 		return AccessController.doPrivileged(
 		    action, createPrivilegedContext(caller, acc));
 	    }
@@ -526,19 +530,21 @@ public final class Security {
      * to principals of the <code>Subject</code>, as well as the ability to use
      * credentials of the <code>Subject</code> for authentication.
      * 
+     * @param <T> 
      * @param action the action to be executed
      * @return the object returned by the action's <code>run</code> method
      * @throws PrivilegedActionException if the action's <code>run</code>
      * method throws a checked exception
      * @throws NullPointerException if the action is <code>null</code>
      */
-    public static Object doPrivileged(final PrivilegedExceptionAction action)
+    public static <T> T doPrivileged(final PrivilegedExceptionAction<T> action)
 	throws PrivilegedActionException
     {
 	final Class caller = ctxAccess.getCaller();
 	final AccessControlContext acc = AccessController.getContext();
-	return AccessController.doPrivileged(new PrivilegedExceptionAction() {
-	    public Object run() throws Exception {
+	return AccessController.doPrivileged(new PrivilegedExceptionAction<T>() {
+            
+	    public T run() throws Exception {
 		try {
 		    return AccessController.doPrivileged(
 			action, createPrivilegedContext(caller, acc));
@@ -765,21 +771,24 @@ public final class Security {
      * Returns current thread's context class loader.
      */
     private static ClassLoader getContextClassLoader() {
-	return (ClassLoader)
-	    AccessController.doPrivileged(new PrivilegedAction() {
-		    public Object run() {
-			return Thread.currentThread().getContextClassLoader();
-		    }
-		});
+	return AccessController.doPrivileged(
+            new PrivilegedAction<ClassLoader>() {
+               
+               public ClassLoader run() {
+                   return Thread.currentThread().getContextClassLoader();
+               }
+            }
+        );
     }
 
     /**
      * Returns currently installed security policy, if any.
      */
     private static Policy getPolicy() {
-	return (Policy) AccessController.doPrivileged(new PrivilegedAction() {
-	    public Object run() { return Policy.getPolicy(); }
-	});
+	return AccessController.doPrivileged(new PrivilegedAction<Policy>() {
+            
+            public Policy run() { return Policy.getPolicy(); }
+        });
     }
 
     /**
@@ -799,7 +808,7 @@ public final class Security {
 	} catch (SecurityException e) {
 	}
 
-	ArrayList list = new ArrayList(permissions.length);
+	ArrayList<Permission> list = new ArrayList<Permission>(permissions.length);
 	for (int i = 0; i < permissions.length; i++) {
 	    try {
 		Permission p = permissions[i];
@@ -808,7 +817,7 @@ public final class Security {
 	    } catch (SecurityException e) {
 	    }
 	}
-	return (Permission[]) list.toArray(new Permission[list.size()]);
+	return list.toArray(new Permission[list.size()]);
     }
 
     /**
@@ -816,20 +825,23 @@ public final class Security {
      */
     private static Principal[] getCurrentPrincipals() {
 	final AccessControlContext acc = AccessController.getContext();
-	Subject s = (Subject) AccessController.doPrivileged(
-	    new PrivilegedAction() {
-		public Object run() { return Subject.getSubject(acc); }
+	Subject s = AccessController.doPrivileged(
+	    new PrivilegedAction<Subject>() {
+            
+		public Subject run() { return Subject.getSubject(acc); }
 	    });
 	if (s != null) {
-	    Set ps = s.getPrincipals();
-	    return (Principal[]) ps.toArray(new Principal[ps.size()]);
+	    Set<Principal> ps = s.getPrincipals();
+	    return ps.toArray(new Principal[ps.size()]);
 	} else {
 	    return null;
 	}
     }
 
     /**
-     * TrustVerifier.Context implementation.
+     * TrustVerifier.Context implementation.  This implementation is only
+     * used to verify trust it is never handed outside this class,
+     * so we never bother to defensively copy state.
      */
     private static class Context implements TrustVerifier.Context {
 	/**
@@ -872,9 +884,10 @@ public final class Security {
 		final ArrayList list = new ArrayList(1);
 		final ClassLoader scl = cl;
 		AccessController.doPrivileged(new PrivilegedAction() {
+                    
 		    public Object run() {
 			for (Iterator iter =
-				 Service.providers(TrustVerifier.class, scl);
+				Service.providers(TrustVerifier.class, scl);
 			     iter.hasNext(); )
 			{
 			    list.add(iter.next());
@@ -891,7 +904,7 @@ public final class Security {
 					       new TrustVerifier[list.size()]);
 		synchronized (map) {
 		    map.put(cl, new SoftReference(verifiers));
-		}
+                }
 	    }
 	    this.verifiers = verifiers;
 	    this.context = context;

Copied: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java (from r1153098, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/ConcurrentPolicyFile.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/ConcurrentPolicyFile.java&r1=1153098&r2=1158535&rev=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/ConcurrentPolicyFile.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java Wed Aug 17 06:18:09 2011
@@ -24,7 +24,7 @@
   * @version $Revision$
   */
 
-package org.apache.river.impl.security.policy.se;
+package net.jini.security.policy;
 
 import java.io.File;
 import java.net.URL;
@@ -32,19 +32,26 @@ import java.security.AccessController;
 import java.security.CodeSource;
 import java.security.Permission;
 import java.security.PermissionCollection;
+import java.security.Permissions;
 import java.security.Policy;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
 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.ConcurrentPermissions;
 import org.apache.river.api.security.PermissionGrant;
 import org.apache.river.impl.security.policy.util.DefaultPolicyParser;
 import org.apache.river.impl.security.policy.util.PolicyParser;
@@ -165,26 +172,26 @@ public class ConcurrentPolicyFile extend
     /**
      * System property for dynamically added policy location.
      */
-    public static final String JAVA_SECURITY_POLICY = "java.security.policy"; //$NON-NLS-1$
+    private static final String JAVA_SECURITY_POLICY = "java.security.policy"; //$NON-NLS-1$
 
     /**
      * Prefix for numbered Policy locations specified in security.properties.
      */
-    public static final String POLICY_URL_PREFIX = "policy.url."; //$NON-NLS-1$
-
-    // A set of PolicyEntries constituting this Policy.
-    private final ReentrantReadWriteLock rwl;
-    private final ReadLock rl;
-    private final WriteLock wl;
+    private static final String POLICY_URL_PREFIX = "policy.url."; //$NON-NLS-1$
+    
+    private final Lock rl;
     
-    private Set<PermissionGrant> grants = new HashSet<PermissionGrant>(); // protected by rwl
+    private final Lock wl;
+    
+    private final Set<PermissionGrant> grants ; // protected by rwl
 
     // Calculated Permissions cache, organized as
     // Map{Object->Collection&lt;Permission&gt;}.
     // The Object is a ProtectionDomain, a CodeSource or
     // any other permissions-granted entity.
-    private final ConcurrentMap<Object, Collection<Permission>> cache = 
-            new ConcurrentWeakIdentityMap<Object, Collection<Permission>>();
+    private final ConcurrentMap<Object, Collection<Permission>> cache;
+    
+    private final ConcurrentMap<ProtectionDomain,PermissionCollection> impliesCache;
 
     // A specific parser for a particular policy file format.
     private final PolicyParser parser;
@@ -203,9 +210,13 @@ public class ConcurrentPolicyFile extend
      */
     public ConcurrentPolicyFile(PolicyParser dpr) {
         parser = dpr;
-        rwl = new ReentrantReadWriteLock();
+        ReadWriteLock rwl = new ReentrantReadWriteLock();
         rl = rwl.readLock();
         wl = rwl.writeLock();
+        grants = new HashSet<PermissionGrant>(120);
+        cache = new ConcurrentWeakIdentityMap<Object, Collection<Permission>>(120);
+        impliesCache = 
+            new ConcurrentWeakIdentityMap<ProtectionDomain,PermissionCollection>(80);
         refresh();
     }
 
@@ -219,35 +230,49 @@ public class ConcurrentPolicyFile extend
      */
     @Override
     public PermissionCollection getPermissions(ProtectionDomain pd) {
-        CodeSource cs = pd.getCodeSource();
-        Collection<Permission> pc = cache.get(cs); // saves new object creation.
-        if (pc == null){
-            // Just because the new object is contained within a ConcurrentMap
-            // doesn't mean it doesn't need to be synchronized!
-            pc = ConcurrentCollections.multiReadSet( new HashSet<Permission>() );
-            Collection<Permission> existed = cache.putIfAbsent(cs, pc);
-            if ( !(existed == null) ){ pc = existed;}
-        }
+        /* Permissions is used in preference to ConcurrentPermissions
+         * due the correctness of elements(), ConcurrentPermission's
+         * cannot guarantee that the Enumeration returned by elements()
+         * will be current and copy them, but the Enumeration returned
+         * by Permissions will instead throw a ConcurrentModificationException.
+         */
+        if (pd == null) return new Permissions();
+        /* When write lock holds thread it will already have this lock
+         * allowing priviledged domain security checks to be performed.
+         */
+        rl.lock();
         try {
-            rl.lock();
-            Iterator<PermissionGrant> it = grants.iterator();
-            while (it.hasNext()) {
-                PermissionGrant ge = it.next();
-//                if (ge.impliesPrincipals(pd == null ? null : pd.getPrincipals())
-//                    && ge.impliesCodeSource(pd == null ? null : pd.getCodeSource())) {
-                if (ge.implies(pd == null ? null : pd.getCodeSource(),
-                       pd == null ? null : pd.getPrincipals() )){
-		    Collection<Permission> permCol = ge.getPermissions();
-		    Permission[] perm = permCol.toArray(new Permission [permCol.size()]);
-                    pc.addAll(Arrays.asList(perm));
+            PermissionCollection perms = impliesCache.get(pd);
+            if (perms != null) return perms;
+            perms = new Permissions();
+                Iterator<PermissionGrant> it = grants.iterator();
+                while (it.hasNext()){
+                    PermissionGrant ge = it.next();
+                    if (ge.implies(pd)){
+                        Collection<Permission> c = ge.getPermissions();
+                        Iterator<Permission> i = c.iterator();
+                        while (i.hasNext()){
+                            perms.add(i.next());
+                        }
+                    }
+                }
+            // Don't forget to merge the static Permissions.
+            PermissionCollection staticPC = null;
+            if (pd != null) {
+                staticPC = pd.getPermissions();
+                if (staticPC != null){
+                    Enumeration<Permission> e = staticPC.elements();
+                    while (e.hasMoreElements()){
+                        perms.add(e.nextElement());
+                    }
                 }
-            }               
-        } finally { rl.unlock(); } 
-	// Don't forget to merge the static Permissions.
-        return PolicyUtils.mergePermissions(
-	new PermissionCollection[]{ PolicyUtils.toPermissionCollection(pc),
-	pd.getPermissions()}
-	);
+            }
+            impliesCache.put(pd, perms); //Overwrite older.
+            return perms;
+        }finally{
+            rl.unlock();
+        }
+       
     }
 
     /**
@@ -259,39 +284,40 @@ public class ConcurrentPolicyFile extend
      */
     @Override
     public PermissionCollection getPermissions(CodeSource cs) {
-        Collection<Permission> pc = cache.get(cs); // saves new object creation.
-        if (pc == null){
+        if (cs == null) throw new NullPointerException("CodeSource cannot be null");
+        rl.lock();
+        try {
+            Collection<Permission> pc = cache.get(cs); // saves new object creation.
+            if (pc != null){
+                return PolicyUtils.toPermissionCollection(pc);
+            }
             // Just because the new object is contained within a ConcurrentMap
             // doesn't mean it doesn't need to be synchronized!
-            pc = Collections.synchronizedSet( new HashSet<Permission>() );
-            Collection<Permission> existed = cache.putIfAbsent(cs, pc);
-            if ( !(existed == null) ){ pc = existed;}
-        }
-        try {
-            rl.lock();
+            // However it isn't modified again after being added to the cache.
+            pc = new HashSet<Permission>();
             Iterator<PermissionGrant> it = grants.iterator();
             while (it.hasNext()) {
                 PermissionGrant ge = it.next();
-//                if (ge.impliesPrincipals(null)
-//                    && ge.impliesCodeSource(cs)) {
+    //                if (ge.impliesPrincipals(null)
+    //                    && ge.impliesCodeSource(cs)) {
                 if (ge.implies(cs,null )){
-		    Collection<Permission> permCol = ge.getPermissions();
-		    Permission[] perm = permCol.toArray(new Permission [permCol.size()]);
-                    pc.addAll(Arrays.asList(perm)); // we still hold a reference
-//                    pc.addAll(ge.getPermissions()); // we still hold a reference
+                    Collection<Permission> permCol = ge.getPermissions();
+                    Permission[] perm = permCol.toArray(new Permission [permCol.size()]);
+                    pc.addAll(Arrays.asList(perm));
                 }
-            }     
-        } finally { rl.unlock(); }
-        return PolicyUtils.toPermissionCollection(pc);
+            }
+            cache.put(cs, pc); // replace existing.
+            return PolicyUtils.toPermissionCollection(pc);
+        } finally {
+            rl.unlock();
+        }
     }
     
     @Override
     public boolean implies(ProtectionDomain domain, Permission permission) {
+        if (permission == null) throw new NullPointerException("permission not allowed to be null");
 	PermissionCollection pc = getPermissions(domain);
-	if (pc == null) {
-	    return false;
-	}
-	return pc.implies(permission);
+        return pc.implies(permission);
     }
 
     /**
@@ -303,29 +329,49 @@ public class ConcurrentPolicyFile extend
      */
     @Override
     public void refresh() {
-        Set<PermissionGrant> fresh = new HashSet<PermissionGrant>();
-        Properties system = new Properties(AccessController
-                .doPrivileged(new PolicyUtils.SystemKit()));
-        system.setProperty("/", File.separator); //$NON-NLS-1$
-        URL[] policyLocations = PolicyUtils.getPolicyURLs(system,
+        Set<PermissionGrant> fresh = Collections.emptySet();
+        wl.lock();
+        try {
+            fresh = AccessController.doPrivileged( 
+                new PrivilegedExceptionAction<Set<PermissionGrant>>(){
+                    public Set<PermissionGrant> run() throws Exception {
+                        Set<PermissionGrant> fresh = new HashSet<PermissionGrant>(120);
+                        Properties system = System.getProperties();
+                        system.setProperty("/", File.separator); //$NON-NLS-1$
+                        URL[] policyLocations = PolicyUtils.getPolicyURLs(system,
                                                           JAVA_SECURITY_POLICY,
                                                           POLICY_URL_PREFIX);
-        for (int i = 0; i < policyLocations.length; i++) {
-            try {
-                //TODO debug log
-                //System.err.println("Parsing policy file: " + policyLocations[i]);
-                Collection<PermissionGrant> pc = parser.parse(policyLocations[i], system);
-                fresh.addAll(pc);
-            } catch (Exception e) {
-                // TODO log warning
-                //System.err.println("Ignoring policy file: " 
-                //                 + policyLocations[i] + ". Reason:\n"+ e);
-            }
+                        for (int i = 0; i < policyLocations.length; i++) {
+                            //TODO debug log
+//                                System.err.println("Parsing policy file: " + policyLocations[i]);
+                            try {
+                                Collection<PermissionGrant> pc = null;
+                                pc = parser.parse(policyLocations[i], system);
+                                    grants.addAll(pc); 
+                                fresh.addAll(pc);
+                            } catch (Exception e){
+                                // TODO log warning
+//                                System.err.println("Ignoring policy file: " 
+//                                                 + policyLocations[i] + ". Reason:\n"+ e);
+                            }
+                        } 
+//                            System.err.println(fresh.toString());
+                        return fresh;
+                    }
+                }
+            );
+            // Even though grant's are removed, it's not that important
+            // as policies generally are additive,
+            //static ProtectionDomains call Policy.getPermissions(CodeSource)
+            // references escape etc.
+            grants.retainAll(fresh); // removes all that are no longer valid.
+            cache.clear(); // Clear the cache.
+            impliesCache.clear();
+        }catch (PrivilegedActionException e){
+            System.err.println(e);
+        } finally {
+            wl.unlock();
         }
-        try {
-            wl.lock();
-            grants = fresh;
-            cache.clear();
-        }finally {wl.unlock();}
     }
+    
 }

Copied: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/DynamicPolicyProvider.java (from r1153103, 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/net/jini/security/policy/DynamicPolicyProvider.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/DynamicPolicyProvider.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java&r1=1153103&r2=1158535&rev=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/DynamicPolicyProvider.java Wed Aug 17 06:18:09 2011
@@ -1,15 +1,17 @@
 
 
-package org.apache.river.impl.security.policy.se;
+package net.jini.security.policy;
 
 import java.io.IOException;
-import org.apache.river.api.security.InternetSecurityManager;
+import java.rmi.RemoteException;
+import org.apache.river.api.security.DelegateSecurityManager;
 import java.security.AccessController;
 import java.security.AllPermission;
 import java.security.CodeSource;
 import java.security.Guard;
 import java.security.Permission;
 import java.security.PermissionCollection;
+import java.security.Permissions;
 import java.security.Policy;
 import java.security.Principal;
 import java.security.PrivilegedAction;
@@ -19,29 +21,34 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import net.jini.security.GrantPermission;
-import net.jini.security.policy.DynamicPolicy;
-import net.jini.security.policy.PolicyInitializationException;
-import net.jini.security.policy.UmbrellaGrantPermission;
 import org.apache.river.api.security.PermissionGrant;
 import org.apache.river.api.security.PermissionGrantBuilder;
-import org.apache.river.api.security.RemotePolicy;
+import org.apache.river.api.security.policy.RemotePolicy;
 import org.apache.river.api.security.RevokePermission;
-import org.apache.river.api.security.RevokeableDynamicPolicy;
+import org.apache.river.api.security.policy.RevokeableDynamicPolicy;
 import org.apache.river.impl.security.policy.util.PolicyUtils;
 import org.apache.river.impl.util.ConcurrentCollections;
 import org.apache.river.impl.util.ConcurrentWeakIdentityMap;
 
 /**
+ * Security policy provider that supports dynamic granting of permissions at
+ * run-time.  This provider is designed as a wrapper to layer dynamic grant
+ * functionality on top of an underlying policy provider.  If the underlying
+ * provider does not implement the {@link DynamicPolicy} interface, then its
+ * permission mappings are assumed to change only when its {@link
+ * Policy#refresh refresh} method is called.  Permissions are granted on the
+ * granularity of class loader; granting a permission requires (of the calling
+ * context) {@link GrantPermission} for that permission.
+ * 
  * <p>This is a Dynamic Policy Provider that supports concurrent access,
  * for instances where a Policy provider is used for a distributed network
  * of computers, or where there is a large number of ProtectionDomains and
@@ -126,21 +133,28 @@ import org.apache.river.impl.util.Concur
  * @see ConcurrentPolicyFile
  * @see net.jini.security.policy.PolicyFileProvider
  * @see ConcurrentPermissionCollection
+ * @see DelegateSecurityManager
+ * @see RemotePolicy
  */
 
-public class DynamicConcurrentPolicyProvider extends Policy implements RemotePolicy, 
+public class DynamicPolicyProvider extends Policy implements RemotePolicy, 
         RevokeableDynamicPolicy {
      private static final String basePolicyClassProperty =
-	"net.jini.security.policy." +
-	"DynamicPolicyProvider.basePolicyClass";
+	"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(); }
 	});
+    private static final String revocationSupported = 
+            "net.jini.security.policy.DynamicPolicyProvider.revocation";
     
-    /* reference update Protected by grantLock, this array reference must only 
+    /* 
+     * Copy referent before use.
+     * 
+     * Reference update Protected by grantLock, this array reference must only 
      * be copied or replaced, it must never be read directly or operated on 
      * unless holding grantLock.
      * Local methods must first copy the reference before using the array in
@@ -165,21 +179,55 @@ public class DynamicConcurrentPolicyProv
     private final boolean basePolicyIsDynamic; // Don't use cache if true.
     private final boolean revokeable;
     private final boolean basePolicyIsRemote;
-    private final Logger logger;
+    private static final Logger logger = Logger.getLogger("net.jini.security.policy");
     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 revokePermission;
     private final Guard protectionDomainPermission;
     
-    
-    public DynamicConcurrentPolicyProvider() throws PolicyInitializationException{
+    /**
+     * Creates a new <code>DynamicPolicyProvider</code> instance that wraps a
+     * default underlying policy.  The underlying policy is created as follows:
+     * if the
+     * <code>net.jini.security.policy.DynamicPolicyProvider.basePolicyClass</code>
+     * security property is set, then its value is interpreted as the class
+     * name of the base (underlying) policy provider; otherwise, a default
+     * class name of
+     * <code>"net.jini.security.policy.PolicyFileProvider"</code>
+     * is used.  The base policy is then instantiated using the no-arg public
+     * constructor of the named class.  If the base policy class is not found,
+     * is not instantiable via a public no-arg constructor, or if invocation of
+     * its constructor fails, then a <code>PolicyInitializationException</code>
+     * is thrown.
+     * <p>
+     * Note that this constructor requires the appropriate
+     * <code>"getProperty"</code> {@link java.security.SecurityPermission} to
+     * read the
+     * <code>net.jini.security.policy.DynamicPolicyProvider.basePolicyClass</code>
+     * security property, and may require <code>"accessClassInPackage.*"</code>
+     * {@link RuntimePermission}s, depending on the package of the base policy
+     * class.
+     *
+     * @throws  PolicyInitializationException if unable to construct the base
+     *          policy
+     * @throws  SecurityException if there is a security manager and the
+     *          calling context does not have adequate permissions to read the
+     *          <code>net.jini.security.policy.DynamicPolicyProvider.basePolicyClass</code>
+     *          security property, or if the calling context does not have
+     *          adequate permissions to access the base policy class
+     */
+    public DynamicPolicyProvider() throws PolicyInitializationException{
         String cname = Security.getProperty(basePolicyClassProperty);
 	if (cname == null) {
 	    cname = defaultBasePolicyClass;
 	}
+        String tRue = "TRUE";
+        String revoke = Security.getProperty(revocationSupported);
+        if (revoke == null){
+            revoke = tRue;
+        }
 	try {
 	    basePolicy = (Policy) Class.forName(cname).newInstance();
 	} catch (SecurityException e) {
@@ -194,15 +242,8 @@ public class DynamicConcurrentPolicyProv
 	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) {
@@ -216,7 +257,7 @@ public class DynamicConcurrentPolicyProv
             }
         } else {
             basePolicyIsDynamic = false;
-            revokeable = false;
+            revokeable = revoke.equals(tRue);
         }
         if (basePolicy instanceof RemotePolicy){
             basePolicyIsRemote = true;
@@ -226,22 +267,24 @@ public class DynamicConcurrentPolicyProv
         ensureDependenciesResolved();
     }
     
-    public DynamicConcurrentPolicyProvider(Policy basePolicy){
+    /**
+     * Creates a new <code>DynamicPolicyProvider</code> instance that wraps
+     * around the given non-<code>null</code> base policy object.
+     *
+     * @param   basePolicy base policy object containing information about
+     *          non-dynamic grants
+     * @throws  NullPointerException if <code>basePolicy</code> is
+     * 		<code>null</code>
+     */
+    public DynamicPolicyProvider(Policy basePolicy){
         this.basePolicy = basePolicy;
         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) {
@@ -255,7 +298,7 @@ public class DynamicConcurrentPolicyProv
             }
         } else {
             basePolicyIsDynamic = false;
-            revokeable = false;
+            revokeable = true;
         }
         if (basePolicy instanceof RemotePolicy){
             basePolicyIsRemote = true;
@@ -270,11 +313,57 @@ public class DynamicConcurrentPolicyProv
      * resolved.  This is to preclude lazy resolution of such classes during
      * operation of the provider, which can result in deadlock as described by
      * bug 4911907.
+     * 
+We are seeing intermittent deadlocks between class resolution (of classes
+referred to by our policy providers) and other synchronization performed in
+or around our security policy providers. A specific example is with the
+synchronization on subPolicies in AggregatePolicyProvider.getCurrentSubPolicy.
+
+Thread 1:
+    calls ClassLoader.loadClass on thw system class loader
+    which locks the system class loader
+    and then calls SecurityManager.checkPackageAccess
+    <Thread 2 runs here>
+    which ultimately causes a call to AggregatePolicyProvider.implies
+    which calls getCurrentSubPolicy
+    which hangs waiting to lock subPolicies
+
+Thread 2:
+    calls AggregatePolicyProvider.implies
+    which locks subPolicies
+    and then attempts to resolve the anonymous PrivilegedAction
+    which hangs waiting to lock the system class loader
+
+A similar deadlock occurs due to synchronization in SecurityManager.checkPackageAccess.
+
+Thread 1:
+    calls ClassLoader.loadClass on the system class loader
+    which calls SecurityManager.checkPackageAccess
+    which locks the SecurityManager.packageAccess  customer 
+    and then calls SecurityManager.checkPermission
+    <Thread 2 runs here>
+    which eventually calls AggregatePolicyProvider.implies
+    which calls getCurrentSubPolicy
+    which calls WeakIdentityMap.get
+    which tries to resolve the internal Key class
+    which hangs waiting to lock the extension class loader
+
+Thread 2:
+    references a class in the extension class loader
+    which locks the extension class loader
+    and then calls ClassLoader.checkPackageAccess
+    which calls SecurityManager.checkPackageAccess
+    which hangs waiting to lock the SecurityManager.packageAccess lock
+
+Work Around 	
+
+Put the policy providers and all referenced classes in the bootstrap class loader.
      */
     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());
+        // Investigate bug 4911907, do we need to do anything?
+        // From the work around above, we might not need to do anything.
+        // But these actions prevent the JVM from delaying classloading
+        // of required classes.
         ProtectionDomain own = this.getClass().getProtectionDomain();
         implies(own, new AllPermission());
         new GrantPermission(new UmbrellaGrantPermission());
@@ -284,15 +373,38 @@ public class DynamicConcurrentPolicyProv
         return revokeable;
     }
 
+    @Override
     public PermissionCollection getPermissions(CodeSource codesource) {
 	/* 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
 	 * ProtectionDomain.  Static Permissions are irrevocable.
 	 */ 
-        return basePolicy.getPermissions(codesource); 
+        if (revokeable == true){
+            return basePolicy.getPermissions(codesource);
+        }
+        PermissionCollection pc = basePolicy.getPermissions(codesource);
+        PermissionCollection permissions = new Permissions();
+        Enumeration<Permission> enu = pc.elements();
+        while (enu.hasMoreElements()){
+            permissions.add(enu.nextElement());
+        }
+        Iterator<PermissionGrant> dynamicGrants = dynamicPolicyGrants.iterator();
+        while (dynamicGrants.hasNext()){
+            PermissionGrant p = dynamicGrants.next();
+            if ( p.implies(codesource, null) ){
+		// Only use the trusted grantCache.
+		Permission[] perm = grantCache.get(p);
+		int s = perm.length;
+		for ( int j = 0; j < s; j++){
+		    permissions.add(perm[j]);
+		}
+	    }
+        }
+	return permissions;
     }
 
+    @Override
     public PermissionCollection getPermissions(ProtectionDomain domain) {
 	/* It is extremely important that dynamic grant's are not returned,
 	 * to prevent them becoming part of the static permissions held
@@ -306,6 +418,11 @@ public class DynamicConcurrentPolicyProv
 	 * container.
 	 */
         PermissionCollection pc = basePolicy.getPermissions(domain);
+        PermissionCollection permissions = new Permissions();
+        Enumeration<Permission> enu = pc.elements();
+        while (enu.hasMoreElements()){
+            permissions.add(enu.nextElement());
+        }
 	PermissionGrant [] grantsRefCopy = remotePolicyGrants; // Interim updates not seen.
 	int l = grantsRefCopy.length;
 	for ( int i = 0; i < l; i++ ){
@@ -315,27 +432,39 @@ public class DynamicConcurrentPolicyProv
 		int s = perm.length;
 		for ( int j = 0; j < s; j++){
 		    PolicyPermission pp = new PolicyPermission(perm[j]);
-		    pc.add(pp);
+		    permissions.add(pp);
 		}
 	    }
 	}
-	return pc;	
+        Iterator<PermissionGrant> dynamicGrants = dynamicPolicyGrants.iterator();
+        while (dynamicGrants.hasNext()){
+            PermissionGrant p = dynamicGrants.next();
+            if ( p.implies(domain) ){
+		// Only use the trusted grantCache.
+		Permission[] perm = grantCache.get(p);
+		int s = perm.length;
+		for ( int j = 0; j < s; j++){
+                    Permission pp = null;
+                    if (revokeable) {
+                        pp = new PolicyPermission(perm[j]);
+                    }else{
+                        pp = perm[j];
+                    }
+		    permissions.add(pp);
+		}
+	    }
+        }
+	return permissions;	
     }
     
     /* River-26 Mark Brouwer suggested making UmbrellaPermission's expandable
-     * from Dynamic Grants.  Since it is the preferred behaviour of a
-     * RevokableDynamicPolicy, to minimise the Permission's granted by
-     * and underlying policy, so they can be later revoked, this is
-     * desireable behaviour.
+     * from Dynamic Grants.
      */ 
     private void expandUmbrella(PermissionCollection pc) {
-	if (pc.implies(new UmbrellaGrantPermission())) {
-	    List<Permission> l = Collections.list(pc.elements());
-	    pc.add(new GrantPermission(
-		       l.toArray(new Permission[l.size()])));
-	}
+	PolicyFileProvider.expandUmbrella(pc);
     }
 
+    @Override
     public boolean implies(ProtectionDomain domain, Permission permission) {
         if (basePolicyIsDynamic || basePolicyIsRemote){
             // Total delegation revoke supported only by underlying policy.
@@ -433,25 +562,34 @@ public class DynamicConcurrentPolicyProv
      * Calling refresh doesn't remove any dynamic grant's, it only clears
      * the cache and refreshes the underlying Policy, it also removes any
      * grants for ProtectionDomains that no longer exist.
+     * 
+     * If a DelegateSecurityManager has been set, this method will clear it's 
+     * checked cache.
+     * 
      */
+    
     public void refresh() {
         cache.clear();
         basePolicy.refresh();
-        // Clean up any void grants.
-	synchronized (grantLock) {
-	    // This lock doesn't stop reads to grants only other volatile reference updates.
-	    // Manipulating, alterations (writes) to the remotePolicyGrants array is prohibited.
-	    int l = remotePolicyGrants.length;
-	    ArrayList<PermissionGrant> grantHolder 
-		    = new ArrayList<PermissionGrant>(l);
-	    for ( int i = 0; i < l; i++ ){
-		if ( remotePolicyGrants[i].isVoid(null)) continue;
-		grantHolder.add(remotePolicyGrants[i]);
-	    }
-	    PermissionGrant[] remaining = new PermissionGrant[grantHolder.size()];
-	    remotePolicyGrants = grantHolder.toArray(remaining); // Volatile reference update.
-	}
-        ensureDependenciesResolved();
+        // Clean up any void dynamic grants.
+        Collection<PermissionGrant> remove = new ArrayList<PermissionGrant>(40);
+	Iterator<PermissionGrant> i = dynamicPolicyGrants.iterator();
+        while (i.hasNext()){
+            PermissionGrant p = i.next();
+            if (p.isVoid(null)){
+                remove.add(p);
+            }
+        }
+        dynamicPolicyGrants.removeAll(remove);
+        // Don't bother removing void from the remotePolicy, it get's replaced anyway.
+        // Policy file based grant's don't become void, only dynamic grant's
+        // to ProtectionDomain or ClassLoader.
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null){
+            if (sm instanceof DelegateSecurityManager){
+                ((DelegateSecurityManager) sm).clearFromCache(null);
+            }
+        }
     }
 
     public boolean grantSupported() {
@@ -459,13 +597,10 @@ public class DynamicConcurrentPolicyProv
     }
 
     public void grant(Class cl, Principal[] principals, Permission[] permissions) {
-        if (permissions == null || permissions.length == 0) {return;}
         if (principals == null){ principals = new Principal[0];}
-        if (principals.length > 0) {
-	    //principals = principals.clone(); // Don't bother the builder will do it.
-	    checkNullElements(principals);
-	} 
-        //permissions = permissions.clone(); // Don't bother the builder will do it.
+        checkNullElements(principals);
+        // This has to be after checkNullElements principals or we fail the NullCases test.
+        if (permissions == null || permissions.length == 0) {return;}
         checkNullElements(permissions);
         if ( basePolicyIsDynamic ){
             /* Delegate, otherwise, if base policy is an instance of this class, we
@@ -478,8 +613,11 @@ public class DynamicConcurrentPolicyProv
             dp.grant(cl, principals, permissions);
             return;
         }
-	sm.checkPermission(new GrantPermission(permissions));
-        PermissionGrantBuilder pgb = PermissionGrantBuilder.create();
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null){
+            sm.checkPermission(new GrantPermission(permissions));
+        }
+        PermissionGrantBuilder pgb = PermissionGrantBuilder.newBuilder();
         PermissionGrant pe = pgb.clazz(cl).principals(principals)
                 .permissions(permissions)
                 .context(PermissionGrantBuilder.CLASSLOADER)
@@ -489,7 +627,7 @@ public class DynamicConcurrentPolicyProv
 	// This grant is new, in the grantCache and we trust it.
 	dynamicPolicyGrants.add(pe);
 	if (loggable){
-	    logger.log(Level.FINEST, "Granting: " + pe.toString());
+	    logger.log(Level.FINEST, "Granting: {0}", pe.toString());
 	}
     }
     
@@ -547,8 +685,9 @@ public class DynamicConcurrentPolicyProv
 	}
         // Unfortunately this is quite expensive, but we don't know which ProtectionDomains a ClassLoader references.
         cache.clear();
-        if (sm instanceof InternetSecurityManager) {
-            ((InternetSecurityManager) sm).clearFromCache(removed);
+        SecurityManager sm = System.getSecurityManager();
+        if (sm instanceof DelegateSecurityManager) {
+            ((DelegateSecurityManager) sm).clearFromCache(removed);
         }
        return removed.toArray(new Permission[removed.size()]);
     }
@@ -576,19 +715,24 @@ public class DynamicConcurrentPolicyProv
          */ 
         // because PermissionGrant's are given references to ProtectionDomain's
         // we must check the caller has this permission.
+        try {
         protectionDomainPermission.checkGuard(null); 
         // Delegating to the underlying policy is not supported.
-	checkNullElements(grants);
+	processRemotePolicyGrants(grants);
         // If we get to here, the caller has permission.
-	processGrants(grants);
+        } catch (SecurityException e){
+            throw new RemoteException("Policy update failed", (Throwable) e);
+        } catch (NullPointerException e) {
+            throw new RemoteException("Policy update failed", (Throwable) e);
+        }
     }
     
     /**
      * This method checks that the PermissionGrant's are authorised to be
      * granted by it's caller, if it Fails, it will throw a SecurityException
-     * or AccessControlException, if it succeeds it will return a Map containing
-     * the PermissionGrant's mapped to their corresponding arrays of 
-     * checked Permission's.
+     * or AccessControlException.
+     * 
+     * 
      * 
      * The PermissionGrant should not be requested for it's Permission's 
      * again, since doing so would risk an escallation of privelege attack if the
@@ -597,10 +741,8 @@ public class DynamicConcurrentPolicyProv
      * @param grants
      * @return map of checked grants.
      */
-    private Map<PermissionGrant, Permission[]> 
-	    checkGrants(Collection<PermissionGrant> grants){
-	Map<PermissionGrant, Permission[]> allowed =
-		new HashMap<PermissionGrant, Permission[]>(grants.size());
+    private void 
+	    checkCallerHasGrants(Collection<PermissionGrant> grants) throws SecurityException {
         Iterator<PermissionGrant> grantsItr = grants.iterator();
         while (grantsItr.hasNext()){
             PermissionGrant grant = grantsItr.next();
@@ -609,30 +751,30 @@ public class DynamicConcurrentPolicyProv
 	    checkNullElements(perms);
             Guard g = new GrantPermission(perms);
 	    g.checkGuard(this);
-	    allowed.put(grant, perms);
         }
-	return allowed;
     }
     
     /**
-     * Any grants must first be checked for PermissionGrants, checkGrants has
+     * Any grants must first be checked for PermissionGrants, checkCallerHasGrants has
      * been provided for this purpose, then prior to calling this method,
      * the PermissionGrant's must be added to the grantsCache.
      * 
-     * processGrants places the PermissionGrant's in the remotePolicyGrants array. It is
+     * processRemotePolicyGrants places the PermissionGrant's in the remotePolicyGrants array. It is
      * recommended that only this method be used to update the remotePolicyGrants
      * reference.
      * 
      * @param grants
      */
-    private void processGrants(PermissionGrant[] grants) {
+    private void processRemotePolicyGrants(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.
+        checkNullElements(grants);
 	HashSet<PermissionGrant> holder 
 		    = new HashSet<PermissionGrant>(grants.length);
 	    holder.addAll(Arrays.asList(grants));
+            checkCallerHasGrants(holder);
         PermissionGrant[] old = null;
 	synchronized (grantLock) {
             old = remotePolicyGrants;
@@ -643,16 +785,66 @@ 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.
+        // Collect removed Permission's to notify DelegateSecurityManager.
         Set<Permission> removed = new HashSet<Permission>(120);
         Iterator<PermissionGrant> rgi = oldGrants.iterator();
         while (rgi.hasNext()){
             PermissionGrant g = rgi.next();
                     removed.addAll(g.getPermissions());
         }
-        if (sm instanceof InternetSecurityManager) {
-            ((InternetSecurityManager) sm).clearFromCache(removed);
+        
+        SecurityManager sm = System.getSecurityManager();
+        if (sm instanceof DelegateSecurityManager) {
+            ((DelegateSecurityManager) sm).clearFromCache(removed);
         }
         // oldGrants now only has the grants which have been removed.
     }
+    
+    /*
+     * The sole purpose of this implementation is to make Dynamic permissions
+     * printable for debugging from a ProtectionDomain without their contained 
+     * permissions becoming merged in the static ProtectionDomain permissions.
+     */
+    private static class PolicyPermission extends Permission {
+        private static final long serialVersionUID = 1L;
+
+        private final Permission perm;
+
+        PolicyPermission(Permission p){
+            super("Dynamic Policy");
+            perm = p;
+        }
+
+        @Override
+        public boolean implies(Permission permission) {
+            return equals(permission);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) return true;
+            if (obj instanceof PolicyPermission &&
+                this.perm.equals(((PolicyPermission) obj).perm)) return true;           
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 7;
+            hash = 31 * hash + (this.perm != null ? this.perm.hashCode() : 0);
+            return hash;
+        }
+
+        @Override
+        public String toString(){
+            return perm.toString();
+        }
+
+        @Override
+        public String getActions() {
+            return "";
+        }
+
+    }
+
 }

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=1158535&r1=1158534&r2=1158535&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 Wed Aug 17 06:18:09 2011
@@ -27,7 +27,10 @@ import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
 import java.security.Security;
 import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import net.jini.security.GrantPermission;
 
 /**
@@ -55,13 +58,14 @@ import net.jini.security.GrantPermission
 public class PolicyFileProvider extends Policy {
 
     private static final String basePolicyClassProperty =
-	"net.jini.security.policy." +
-	"PolicyFileProvider.basePolicyClass";
+	"net.jini.security.policy.PolicyFileProvider.basePolicyClass";
     private static final String defaultBasePolicyClass =
-        //    "org.apache.river.impl.security.policy.se.ConcurrentPolicyFile";
-	"sun.security.provider.PolicyFile";
+        // Having our own implementation removes a platform dependency
+        "net.jini.security.policy.ConcurrentPolicyFile";
+//	"sun.security.provider.PolicyFile";
     private static final String policyProperty = "java.security.policy";
     private static final Object propertyLock = new Object();
+    private static final Permission umbrella = new UmbrellaGrantPermission();
 
     private final String policyFile;
     private final Policy basePolicy;
@@ -267,14 +271,24 @@ public class PolicyFileProvider extends 
      */
     private void ensureDependenciesResolved() {
 	// force resolution of GrantPermission and UmbrellaGrantPermission
-	new GrantPermission(new UmbrellaGrantPermission());
+	new GrantPermission(umbrella);
     }
 
-    private static void expandUmbrella(PermissionCollection pc) {
-	if (pc.implies(new UmbrellaGrantPermission())) {
-	    List l = Collections.list(pc.elements());
-	    pc.add(new GrantPermission(
-		       (Permission[]) l.toArray(new Permission[l.size()])));
+    static void expandUmbrella(PermissionCollection pc) {
+	if (pc.implies(umbrella)) {
+            Set<Permission> perms = new HashSet<Permission>(120);
+            Enumeration<Permission> e = pc.elements();
+            while (e.hasMoreElements()){
+                Permission p = e.nextElement();
+                // Avoid unintended granting of GrantPermission 
+                // and recursive UmbrellaGrantPermission
+                if ( p instanceof GrantPermission || 
+                        p instanceof UmbrellaGrantPermission){
+                    continue;
+                }
+                perms.add(p);
+            }
+            pc.add(new GrantPermission(perms.toArray(new Permission[perms.size()])));
 	}
     }
     

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java?rev=1158535&r1=1158534&r2=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/delegates/DelegatePermission.java Wed Aug 17 06:18:09 2011
@@ -18,8 +18,10 @@
 
 package org.apache.river.api.delegates;
 
+import java.io.IOException;
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.security.Permission;
 import java.security.PermissionCollection;
@@ -29,6 +31,7 @@ import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
+import org.apache.river.api.security.DelegateSecurityManager;
 import org.apache.river.impl.util.ConcurrentWeakMap;
 
 /**
@@ -39,20 +42,25 @@ import org.apache.river.impl.util.Concur
  * 
  * A Security Delegate does not have an interface that identifies it as a Delegate,
  * it is a wrapper class that has an identical interface, where 
- * practical, to the object it encapsulates, to discuise it from clients.
+ * practical, to the object it encapsulates, to disguise it from clients.
  * 
  * Security Delegates enable sensitive objects to be used by code that isn't
- * fully trusted and may want to monitor, such as a 
+ * fully trusted you may want to monitor, such as a 
  * file write that is limited by the number of bytes written, or a Permission
- * to write a file, that we might decide to retract or revoke if the code
+ * to write a file, that we might decide to retract or revoke if a user
  * does something we don't like, such as exceed a pre set limit or behave
  * in a manner we would like to avoid, such as hogging network bandwidth.
  * 
  * A DelegatePermission never implies it's candidate, however if a 
  * ProtectionDomain has the Permission the delegate represents, then the 
- * InternetSecurityManager, which a Security Delegate must utilise,
+ * DelegateSecurityManager, which a Security Delegate must utilise,
  * must ensure that it is also checked.
  * 
+ * If the SecurityManager installed doesn't implement DelegateSecurityManager,
+ * the DelegatePermission Guard's will be disabled.  This allows delegate's
+ * to be included in code, the decision to utilise delegate functionality may
+ * delayed until runtime or deployment.
+ * 
  * The DelegatePermissionCollection returned by newPermissionCollection() is not
  * synchronized, this decision was made because PermissionCollection's are 
  * usually accessed from within a heterogenous PermissionCollection like 
@@ -98,8 +106,6 @@ public final class DelegatePermission ex
     
     private final Permission permission;
     private final transient int hashCode;
-    /* The following null reference is for IDE code completion only */
-    private transient Permission perm = null;
     
     private DelegatePermission(Permission p){
 	super(p.getClass().toString() + " " + p.getName());
@@ -108,6 +114,11 @@ public final class DelegatePermission ex
 	hash = 41 * hash + (this.permission != null ? this.permission.hashCode() : 0);
 	hashCode = hash;
     }
+    
+    public void checkGuard(Object object) throws SecurityException {
+	SecurityManager sm = System.getSecurityManager();
+	if (sm instanceof DelegateSecurityManager) sm.checkPermission(this);
+    }
 
     @Override
     public boolean implies(Permission permission) {
@@ -129,7 +140,7 @@ public final class DelegatePermission ex
 	if (!(obj instanceof DelegatePermission)) return false;
 	if ( obj.getClass() != this.getClass() ) return false;
 	return permission.equals(((DelegatePermission) permission).getPermission());
-    }
+        }
 
     @Override
     public int hashCode() {
@@ -154,7 +165,19 @@ public final class DelegatePermission ex
 	SerializationProxy(Permission p){
 	    perm = p;
 	}
-	
+        
+        private void writeObject(ObjectOutputStream out) throws IOException{
+            out.defaultWriteObject();
+        }
+        
+        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
+            in.defaultReadObject();
+        }
+        
+        private Object readResolve() {
+            // perm is the field from the Serialization proxy.
+            return get(perm);
+        }
     }
     
     /* Serialization */
@@ -167,19 +190,12 @@ public final class DelegatePermission ex
 	throw new InvalidObjectException("Proxy required");
     }
     
-    private Object readResolve() {
-	// perm is the field from the Serialization proxy.
-	return get(perm);
-    }
-    
     /* PermissionCollection */
     
     private static class DelegatePermissionCollection extends PermissionCollection {
 	private static final long serialVersionUID = 1L;
 	private final transient PermissionCollection candidates;
 	private final Set<Permission> delegates;
-	/* IDE code completion for serialization proxy */
-	private transient Permission[] perms = null;
 	
 	DelegatePermissionCollection(){
 	    candidates = new Permissions();
@@ -219,6 +235,16 @@ public final class DelegatePermission ex
 	    CollectionSerializationProxy(Set<Permission> p){
 		perms = p.toArray(new Permission[p.size()]);
 	    }
+            
+            private Object readResolve() {
+                // perms is the field from the Serialization proxy.
+                DelegatePermissionCollection dpc = new DelegatePermissionCollection();
+                int l = perms.length;
+                for (int i = 0; i < l; i++ ){
+                    dpc.add(perms[i]);
+                }
+                return dpc;
+            }
 
 	}
 
@@ -232,15 +258,7 @@ public final class DelegatePermission ex
 	    throw new InvalidObjectException("Proxy required");
 	}
 
-	private Object readResolve() {
-	    // perms is the field from the Serialization proxy.
-	    DelegatePermissionCollection dpc = new DelegatePermissionCollection();
-	    int l = perms.length;
-	    for (int i = 0; i < l; i++ ){
-		dpc.add(perms[i]);
-	    }
-	    return dpc;
-	}
+	
 	
     }
 

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=1158535&r1=1158534&r2=1158535&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 Wed Aug 17 06:18:09 2011
@@ -31,7 +31,6 @@ import java.security.PrivilegedActionExc
 import java.security.PrivilegedExceptionAction;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import sun.security.util.SecurityConstants;
 
 /**
  * 
@@ -41,7 +40,7 @@ public class FileInputStream extends jav
     private final Guard g;
     private final java.io.FileInputStream in;
     public FileInputStream(final String name) throws FileNotFoundException {
-	Permission p = new FilePermission(name, SecurityConstants.FILE_READ_ACTION);
+	Permission p = new FilePermission(name, "read");
 	g = DelegatePermission.get(p);
 	java.io.FileInputStream input = null;
 	try {	    
@@ -59,8 +58,7 @@ public class FileInputStream extends jav
     }
     
     public FileInputStream(final File file) throws FileNotFoundException {
-	Permission p = new FilePermission(file.getPath(), 
-		SecurityConstants.FILE_READ_ACTION);
+	Permission p = new FilePermission(file.getPath(), "read");
 	g = DelegatePermission.get(p);
 	java.io.FileInputStream input = null;
 	try {

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=1158535&r1=1158534&r2=1158535&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 Wed Aug 17 06:18:09 2011
@@ -32,7 +32,7 @@ import java.security.PrivilegedActionExc
 import java.security.PrivilegedExceptionAction;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import sun.security.util.SecurityConstants;
+import org.apache.river.api.security.DelegateSecurityManager;
 
 /**
  * <p>This is a simple FileOutputStream delegate to replace a java.io.FileOutputStream
@@ -56,22 +56,30 @@ public class FileOutputStream extends Ou
     
     public FileOutputStream(final String name, final boolean append) 
 	    throws FileNotFoundException {
-	Permission p = new FilePermission(name, SecurityConstants.FILE_READ_ACTION);
+	Permission p = new FilePermission(name, "write");
 	g = DelegatePermission.get(p);
 	java.io.FileOutputStream output = null;
-	try {
-	    // Permission check is delayed.    
-	    output = AccessController.doPrivileged(
-		new PrivilegedExceptionAction<java.io.FileOutputStream>() {
-		    public java.io.FileOutputStream run() throws FileNotFoundException {
-			return new java.io.FileOutputStream(name, append);
-		    }
-		}
-	    );
-	} catch (PrivilegedActionException ex) {
-	    Throwable e = ex.getCause();
-	    constrEx(e,p);
-	}
+        SecurityManager sm = System.getSecurityManager();
+        if (sm instanceof DelegateSecurityManager){
+            try {
+                output = AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<java.io.FileOutputStream>() {
+                        public java.io.FileOutputStream run() throws FileNotFoundException {
+                            return new java.io.FileOutputStream(name, append);
+                        }
+                    }
+                );
+            } catch (PrivilegedActionException ex) {
+                Throwable e = ex.getCause();
+                constrEx(e,p);
+            }
+        }else{
+            /* No DelegateSecurityManager installed, since guard doesn't
+             * do anything, don't create FileOutputStream using
+             * doPrivileged or it will create a security vulnerability.
+             */
+            output = new java.io.FileOutputStream(name, append);
+        }
 	out = output;
     }
     
@@ -80,21 +88,29 @@ public class FileOutputStream extends Ou
     }
 	
     public FileOutputStream(final File file, final boolean append) throws FileNotFoundException {
-	Permission p = new FilePermission(file.getPath(),
-		SecurityConstants.FILE_READ_ACTION);
+	Permission p = new FilePermission(file.getPath(),"write");
 	g = DelegatePermission.get(p);
 	java.io.FileOutputStream output = null;
-	try {
-	    output = AccessController.doPrivileged(
-		    new PrivilegedExceptionAction<java.io.FileOutputStream>() {
-		public java.io.FileOutputStream run() throws FileNotFoundException {
-		    return new java.io.FileOutputStream(file, append);
-		}
-	    });
-	} catch (PrivilegedActionException ex) {	    
-	    Throwable e = ex.getCause();
-	    constrEx(e,p);
-	}
+        SecurityManager sm = System.getSecurityManager();
+        if (sm instanceof DelegateSecurityManager){
+            try {
+                output = AccessController.doPrivileged(
+                        new PrivilegedExceptionAction<java.io.FileOutputStream>() {
+                    public java.io.FileOutputStream run() throws FileNotFoundException {
+                        return new java.io.FileOutputStream(file, append);
+                    }
+                });
+            } catch (PrivilegedActionException ex) {	    
+                Throwable e = ex.getCause();
+                constrEx(e,p);
+            }
+        } else {
+            /* No DelegateSecurityManager installed, since guard doesn't
+             * do anything, don't create FileOutputStream using
+             * doPrivileged or it will create a security vulnerability.
+             */
+            output = new java.io.FileOutputStream(file, append);
+        }
 	out = output;
     }
 	
@@ -104,11 +120,18 @@ public class FileOutputStream extends Ou
 	
     public FileOutputStream(final FileDescriptor fdObj) {
 	g = DelegatePermission.get(new RuntimePermission("readFileDescriptor"));
-	out = AccessController.doPrivileged(new PrivilegedAction<java.io.FileOutputStream>() {
-	    public java.io.FileOutputStream run() {
-		return new java.io.FileOutputStream(fdObj);
-	    }
-	});
+        java.io.FileOutputStream output = null;
+        SecurityManager sm = System.getSecurityManager();
+        if (sm instanceof DelegateSecurityManager){
+            output = AccessController.doPrivileged(new PrivilegedAction<java.io.FileOutputStream>() {
+                public java.io.FileOutputStream run() {
+                    return new java.io.FileOutputStream(fdObj);
+                }
+            });
+        }else{
+            output = new java.io.FileOutputStream(fdObj);
+        }
+        out = output;
     }
     
     private void constrEx(Throwable e, Permission p) throws FileNotFoundException {

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java?rev=1158535&r1=1158534&r2=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java Wed Aug 17 06:18:09 2011
@@ -20,8 +20,6 @@ package org.apache.river.api.security;
 
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
-import java.io.Serializable;
-import org.apache.river.api.security.PermissionGrantBuilder;
 import java.security.CodeSource;
 import java.security.Permission;
 import java.security.Principal;
@@ -33,7 +31,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.river.api.security.Exclusion;
 
 /**
  *
@@ -41,6 +38,7 @@ import org.apache.river.api.security.Exc
  */
 class CertificateGrant extends PrincipalGrant {
     private static final long serialVersionUID = 1L;
+    private static final Exclusion nullEx = new NullExclusion();
     private final Collection<Certificate> certs;
     private final int hashCode;
     private final Exclusion exclusion;
@@ -48,7 +46,7 @@ class CertificateGrant extends Principal
     CertificateGrant(Certificate[] codeSourceCerts, Principal[] pals, 
                                     Permission[] perms, Exclusion deny){
         super(pals, perms);
-        exclusion = deny;
+        exclusion = deny != null ? deny : nullEx;
          if (codeSourceCerts == null || codeSourceCerts.length == 0) {
             certs = Collections.EMPTY_SET;
         }else{
@@ -95,7 +93,8 @@ class CertificateGrant extends Principal
     
     @Override
     public boolean implies(ProtectionDomain pd) {
-	if ( !super.implies(pd)) return false;
+        // File policy grant compatibility, different behaviour to dynamic grants.
+        if (pd == null) return false; 
         if ( exclusion.excludes(pd)) return false;
 	CodeSource c = null;
 	Principal[] pals = null;
@@ -116,7 +115,8 @@ class CertificateGrant extends Principal
     }
     
     public boolean implies(CodeSource codeSource, Principal[] p) {
-        if ( !super.implies(codeSource, p)) return false;
+        if ( !implies(p)) return false;
+        if ( codeSource == null ) return false;
 	if ( certs.isEmpty() ) return true;
 	Certificate[] signers = codeSource.getCertificates();
 	List<Certificate> certificates = Arrays.asList(signers);
@@ -127,6 +127,7 @@ class CertificateGrant extends Principal
     public PermissionGrantBuilder getBuilderTemplate() {
         PermissionGrantBuilder pgb = super.getBuilderTemplate();
         return pgb.certificates(certs.toArray(new Certificate[certs.size()]))
+                .exclude(exclusion)
                 .context(PermissionGrantBuilder.CODESOURCE_CERTS);
     }
     
@@ -140,4 +141,12 @@ class CertificateGrant extends Principal
             throws InvalidObjectException{
         throw new InvalidObjectException("PermissionGrantBuilder required");
     }
+    
+    private static class NullExclusion implements Exclusion{
+
+        public boolean excludes(ProtectionDomain pd) {
+            return false;
+        }
+        
+    }
 }

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ClassLoaderGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ClassLoaderGrant.java?rev=1158535&r1=1158534&r2=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ClassLoaderGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ClassLoaderGrant.java Wed Aug 17 06:18:09 2011
@@ -20,7 +20,6 @@ package org.apache.river.api.security;
 
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
-import org.apache.river.api.security.PermissionGrantBuilder;
 import java.lang.ref.WeakReference;
 import java.security.Permission;
 import java.security.Principal;

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java?rev=1158535&r1=1158534&r2=1158535&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java Wed Aug 17 06:18:09 2011
@@ -69,7 +69,7 @@ class CodeSourceGrant extends Certificat
         StringBuilder sb = new StringBuilder(500);
         return sb.append(super.toString())
                  .append("CodeSource: \n")
-                 .append(cs.toString())
+                 .append( cs == null ? "null" : cs.toString())
                  .toString();
     }
     
@@ -81,8 +81,10 @@ class CodeSourceGrant extends Certificat
     @Override
     public boolean implies(CodeSource codeSource, Principal[] p) {
         if ( !implies(p)) return false;
-	if ( cs == null ) return true;
-	if ( codeSource == null ) return false;
+        // sun.security.provider.PolicyFile compatibility for null CodeSource.
+        // see com.sun.jini.test.spec.policyprovider.dynamicPolicyProvider.GrantPrincipal test.
+        if ( codeSource == null ) return false; 
+	if ( cs == null || nullCS.equals(cs)) return true;
 	return cs.implies(normalizeCodeSource(codeSource));
     }
 



Mime
View raw message