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/07/05 15:28:20 UTC

svn commit: r960596 [1/2] - in /incubator/river/jtsk/trunk: src/net/jini/security/policy/ src/org/apache/river/api/security/ src/org/apache/river/imp/security/policy/cdc/ src/org/apache/river/imp/security/policy/concurrent/ src/org/apache/river/imp/sec...

Author: peter_firmstone
Date: Mon Jul  5 13:28:19 2010
New Revision: 960596

URL: http://svn.apache.org/viewvc?rev=960596&view=rev
Log:
River Refactoring, including the new RevokeableDynamicPolicy implementation for River-340

Added Denied interface.  Next step qa tests

Added:
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java
      - copied, changed from r958358, incubator/river/jtsk/trunk/src/org/apache/river/api/security/Deny.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantImp.java   (with props)
Removed:
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/Deny.java
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/DenyPermission.java
Modified:
    incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrant.java
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPolicyFile.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/DynamicConcurrentPolicyProvider.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ClassLoaderGrant.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CodeSourceGrant.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DefaultPolicyParser.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/NullPolicyParser.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyParser.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PrincipalGrant.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ProtectionDomainGrant.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/DefaultPolicyParserTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/PolicyEntryTest.java

Modified: incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java Mon Jul  5 13:28:19 2010
@@ -6,7 +6,7 @@
 package net.jini.security.policy;
 
 import java.util.List;
-import org.apache.river.api.security.PermissionGrant;
+import org.apache.river.api.security.Denied;
 import org.apache.river.api.security.PermissionGrantBuilder;
 import org.apache.river.imp.security.policy.cdc.DynamicPolicyProviderImpl;
 import java.security.AccessControlException;
@@ -23,6 +23,7 @@ import java.util.Iterator;
 //import java.util.ServiceLoader;
 import java.util.logging.Logger;
 import java.util.logging.Level;
+import org.apache.river.api.security.PermissionGrant;
 import org.apache.river.api.security.RevokePermission;
 import org.apache.river.api.security.RevokeableDynamicPolicy;
 import sun.misc.Service;
@@ -323,8 +324,16 @@ public class DynamicPolicyProvider exten
         return instance.getPermissionGrants();
     }
 
-    public PermissionGrantBuilder getPermissionGrantBuilder() {
-        return instance.getPermissionGrantBuilder();
+    public void add(List<Denied> denials) {
+        instance.add(denials);
+    }
+
+    public void remove(List<Denied> denials) {
+        instance.remove(denials);
+    }
+
+    public List<Denied> getDenied() {
+        return instance.getDenied();
     }
    
 }

Copied: incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java (from r958358, incubator/river/jtsk/trunk/src/org/apache/river/api/security/Deny.java)
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java?p2=incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java&p1=incubator/river/jtsk/trunk/src/org/apache/river/api/security/Deny.java&r1=958358&r2=960596&rev=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/api/security/Deny.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java Mon Jul  5 13:28:19 2010
@@ -18,89 +18,46 @@
 
 package org.apache.river.api.security;
 
-import java.net.URL;
-import java.security.CodeSigner;
-import java.security.CodeSource;
+import java.security.Permission;
 import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.river.imp.security.policy.util.PolicyUtils;
 
 /**
- * Immutable List of codebase URL's and CodeSource's to deny in a PermissionGrant. 
- * Supplied to a PermissionGrantBuilder.
+ * A Denied implementation must be immutable, it will be accessed by concurrent
+ * code.  To be utilised the implementation must have the RuntimePermission
+ * "getProtectionDomain"
+ * 
+ * The implementation may deny a Permission on any grounds, but it must be
+ * consistent and return the same result on every occassion.
+ * 
+ * Denied must implement a robust implementation of equals() and hashCode()
+ * 
+ * Denied can only deny Permissions that are Revokeable, Permission's granted
+ * by underlying Policy's cannot be denied, as the Permission's will become
+ * merged within a ProtectionDomain's own Permissions collection.
+ * 
+ * Under certain circumstances it may be possible to deny any and all Permission
+ * to ProtectionDomains if we have control of the creation of those
+ * ProtectionDomain's, passing in a null PermissionCollection.
+ * The underlying Policy also must not grant that ProtectionDomain any Permissions,
+ * only under these circumstances is it possible to Denied any or all Permission.
+ * 
+ * Denied code must be kept to a minimum, as every implies() will be checked.
+ * 
+ * Denied may also be used in combination with a PermissionGrant based on
+ * Code signer Certificate's to deny individual CodeSource's or URL's with
+ * known vulnerabilities.
  * 
- * Applies only to Certificate[] and ClassLoader grant's, serves no use for CodeSource
- * or PermissionDomain grants.
- * 
- * This is not a global list, however since it is immutable, it can be shared
- * among PermissionGrant's to save memory. 
- * 
- * The user is responsible for deciding how these apply to each PermissionGrant.
- * 
- * Usually this will be used in combination with Certificate[] grants, to
- * circumvent security bugs identified in known jar files by trusted developers.
- * 
- * Deny does not allow any permission, only Deny.
- * 
- * This class may be extended. The caller must have a DenyPermission before it
- * can be added to a PermissionGrantBuilder.
- *
  * @author Peter Firmstone
  */
-public class Deny {
-    private final List<URL> uri;
-    private final List<CodeSource> code;
-    
-    public Deny(List<URL> denyURL, List<CodeSource> denyCode){
-        List<URL> denied = new ArrayList<URL>(denyURL.size());
-        Iterator<URL> itU = denyURL.iterator();
-        while (itU.hasNext()){
-            denied.add(PolicyUtils.normalizeURL(itU.next()));
-        }
-        uri = Collections.unmodifiableList(denied);
-        List<CodeSource> c = new ArrayList<CodeSource>(denyCode.size());
-        Iterator<CodeSource> itC = c.iterator();
-        while (itC.hasNext()){
-            c.add(normalizeCodeSource(itC.next()));
-        }
-        code = Collections.unmodifiableList(c);
-    }
-    
-    public List<URL> deniedURLs(){
-        return uri;
-    }
-    
-    public List<CodeSource> deniedCode() {
-        return code;
-    }
-    
-    public boolean allow(ProtectionDomain pd){
-        CodeSource cs = pd.getCodeSource();
-        cs = normalizeCodeSource(cs);
-        if (code.contains(cs)) return false;
-        URL codeSourceURL = cs.getLocation();
-        if (uri.contains(codeSourceURL)) return false;
-        return true;
-    }
-    
-    private CodeSource normalizeCodeSource(CodeSource codeSource) {
-        if (codeSource == null ) return null;
-        URL codeSourceURL = PolicyUtils.normalizeURL(codeSource.getLocation());
-        CodeSource result = codeSource;
-
-        if (codeSourceURL != codeSource.getLocation()) {
-            // URL was normalized - recreate codeSource with new URL
-            CodeSigner[] signers = codeSource.getCodeSigners();
-            if (signers == null) {
-                result = new CodeSource(codeSourceURL, codeSource
-                        .getCertificates());
-            } else {
-                result = new CodeSource(codeSourceURL, signers);
-            }
-        }
-        return result;
-    } 
+public interface Denied {
+    /**
+     * Denied is used by a RevokeableDynamicPolicy, to cut short permission checks
+     * or allow the Policy.implies method to continue to execute to its
+     * normal conclusion.
+     * 
+     * @param pd
+     * @param perm may be null;
+     * @return
+     */
+    public boolean allow(ProtectionDomain pd, Permission perm);
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrant.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrant.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrant.java Mon Jul  5 13:28:19 2010
@@ -18,14 +18,10 @@
 
 package org.apache.river.api.security;
 
-import java.security.AccessController;
 import java.security.CodeSource;
 import java.security.Permission;
 import java.security.Principal;
-import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
-import java.security.cert.Certificate;
-import java.util.Collection;
 
 /**
  * PermissionGrant's are expected to be effectively immutable,
@@ -33,128 +29,28 @@ import java.util.Collection;
  * Collections.
  * 
  * You shouldn't pass around PermissionGrant's to just anyone as they can
- * provide an attacker with Permission's that may have been granted.
- * The RevokeableDynamicPolicy must be asked for the PermissionGrantBulder which creates the
- * PermissionGrant's for a less Privileged user.  The user must first have
- * access to a Policy.
+ * provide an attacker with information about which Permission's may be granted.
  * 
  * @author Peter Firmstone
- * @see RevokeableDynamicPolicy
  */
-public abstract class PermissionGrant {
-    /**
-     * Implied Context of Grant
-     */ 
-    public static final int CLASSLOADER = 0;
-    public static final int CODESOURCE = 1;
-    public static final int PROTECTIONDOMAIN = 2;
-    public static final int CODESOURCE_CERTS = 3;
-    public PermissionGrant(){
-        AccessController.checkPermission(new RuntimePermission("getProtectionDomain"));
-        AccessController.checkPermission(new RuntimePermission("getClassLoader"));
-    }
-    
-    /**
-     * This is here to provide functionality for less privileged code / users who
-     * have Permission to get a Policy. For cases where that user / code doesn't
-     * have access to ProtectionDomain's or ClassLoaders.
-     * 
-     * This is equalivant to the methods below, with Privileges.
-     * 
-     * A user will still require specific GrantPermission's before being
-     * able to build a PermissionGrant.
-     * 
-     * @param clazz - The class file.
-     * @param pal - An array of Principal's
-     * @param context - PermissionGrantBuilder context constant.
-     * @return
-     */
-    @SuppressWarnings("unchecked")
-    public final boolean implies( final Class clazz, final Principal[] pal, final int context){
-        AccessController.doPrivileged(new PrivilegedAction() {
-            public Object run(){
-                switch (context){
-                    case CLASSLOADER: {
-                        return implies(clazz.getClassLoader(), pal);
-                    }
-                    case PROTECTIONDOMAIN: {
-                        return implies(clazz.getProtectionDomain(), pal);
-                    }
-                    case CODESOURCE: {
-                        return implies(clazz.getProtectionDomain().getCodeSource(), pal);
-                    }
-                    case CODESOURCE_CERTS: {
-                        return implies(clazz.getProtectionDomain()
-                                .getCodeSource().getCertificates(),
-                                pal);
-                    }
-                    default:
-                        throw new IllegalStateException("int context unknown");
-                }
-            }
-        });
-        return false;
-    }
-    
+public interface PermissionGrant {
+
     /**
      * A DynamicPolicy implementation can use a PermissionGrant as a container
      * for Dynamic Grant's.  A PermissionGrant is first asked by the Policy
      * if it applies to a Particular ProtectionDomain, if it does, the Policy
      * calls getPermissions.
-     * 
+     *
      * Dynamic grants can be denied to some ProtectionDomains based on
      * CodeSource or URL's for codebases, this is to remove the possiblity of
      * executing Permissions for vulnerable codebases, once a vulnerability
      * is identified after the fact.
-     * 
+     *
      * @param pd ProtectionDomain
      * @return
      * @see RevokeableDynamicPolicy
      */
-    public final boolean applicable(ProtectionDomain pd){
-        Deny check = getDenials();
-        if (check == null){
-            return implies(pd);
-        } else if ( check.allow(pd)) {
-            return implies(pd);
-        }
-        return false;
-    }
-    
-    protected abstract Deny getDenials();
-    
-    /**
-     * A DynamicPolicy implementation can use a PermissionGrant as a container
-     * for Dynamic Grant's.  A PermissionGrant is first asked by the Policy
-     * if it implies a Particular ProtectionDomain, if it does, the Policy
-     * calls getPermissions.
-     * 
-     * Only this method is utilised by the RevokeableDynamicPolicy, 
-     * for Permission checks, extending classes must implement it.
-     * 
-     * @param pd ProtectionDomain
-     * @return
-     * @see RevokeableDynamicPolicy
-     */
-    protected abstract boolean implies(ProtectionDomain pd);
-    /**
-     * Checks if this PermissionGrant applies to the ProtectionDomain with
-     * the given principals, this is useful for Subject's where a Subject's
-     * Principals are added to a ProtectionDomain by a Policy check by the
-     * AccessController and DomainCombiner.  This is not used by the Policy.
-     * This is a utility method to determine if a ProtectionDomain had a set of
-     * Principals what the effect is.  
-     * 
-     * The ProtectionDomain's internal set of Principals are ignored for 
-     * this method.
-     * 
-     * @param pd
-     * @param pal
-     * @return
-     * @see AccessController
-     * @see DomainCombiner
-     */
-    public abstract boolean implies(ProtectionDomain pd, Principal[] pal);
+    boolean implies(ProtectionDomain pd);  
     /**
      * Checks if this PermissionGrant applies to the passed in ClassLoader
      * and Principal's.
@@ -167,38 +63,32 @@ public abstract class PermissionGrant {
      * If this method returns false, follow up using the ProtectionDomain for a
      * more specific test, which may return true.
      */
-    public abstract boolean implies(ClassLoader cl, Principal[] pal);
+    boolean implies(ClassLoader cl, Principal[] pal);
     /**
      * Checks if this PermissionGrant applies to the passed in CodeSource
      * and Principal's.
      * @param cs
      * @return 
      */
-    public abstract boolean implies(CodeSource codeSource, Principal[] pal);
-    /**
-     * Checks if this PermissionGrant applies to the passed in Certificate's
-     * and Principal's.
-     */
-    public abstract boolean implies(Certificate[] certs, Principal[] pal);
+    boolean implies(CodeSource codeSource, Principal[] pal);
+
+    @Override
+    boolean equals(Object o);
+
     /**
      * Returns an unmodifiable collection of permissions defined by this
-     * PolicyEntry, may be <code>null</code>.
-     * @return 
-     */
-    public abstract Collection<Permission> getPermissions();
-    /**
-     * Provides a builder that will replicate the PermissionGrant.  Useful
-     * when you want to change the Permission's but not the
-     * context.
+     * PermissionGrant, may be <code>null</code>.
+     * @return
      */
-    public abstract PermissionGrantBuilder getBuilderTemplate();
+    Permission[] getPermissions();
+
+    @Override
+    int hashCode();
+
     /**
      * Returns true if this PermissionGrant defines no Permissions, or if
      * a PermissionGrant was made to a ProtectionDomain that no longer exists.
      */
-    public abstract boolean isVoid();
-    @Override
-    public abstract boolean equals(Object o);
-    @Override
-    public abstract int hashCode();
+    boolean isVoid();
+
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java Mon Jul  5 13:28:19 2010
@@ -18,16 +18,10 @@
 
 package org.apache.river.api.security;
 
-import java.io.Serializable;
-import java.lang.ref.WeakReference;
-import java.security.AccessController;
 import java.security.CodeSource;
 import java.security.Permission;
 import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
 import java.security.cert.Certificate;
-import net.jini.security.GrantPermission;
 
 /**
  * The PermissionGrantBuilder creates Dynamic PermissionGrant's based on
@@ -40,12 +34,15 @@ import net.jini.security.GrantPermission
  * Single Thread use only.
  * @author Peter Firmstone.
  */
-public abstract class PermissionGrantBuilder implements Serializable{
-    private static final long serialVersionUID = 1L;
-    
-    public PermissionGrantBuilder(){
-        AccessController.checkPermission(new RuntimePermission("getProtectionDomain"));
-    }
+public interface PermissionGrantBuilder {
+   
+    /**
+     * Implied Context of Grant
+     */ 
+    public static final int CLASSLOADER = 0;
+    public static final int CODESOURCE = 1;
+    public static final int PROTECTIONDOMAIN = 2;
+    public static final int CODESOURCE_CERTS = 3;
     
     /**
      * Build the PermissionGrant using information supplied.
@@ -53,39 +50,19 @@ public abstract class PermissionGrantBui
      */
     public abstract void reset();
 
-    public abstract PermissionGrantBuilder context(int context);
+    public abstract PermissionGrantBuilder context(int context) throws IllegalStateException;
 
     public abstract PermissionGrantBuilder codeSource(CodeSource cs);
 
     public abstract PermissionGrantBuilder clazz(Class cl);
 
-    public abstract PermissionGrantBuilder domain(WeakReference<ProtectionDomain> pd);
-
     public abstract PermissionGrantBuilder certificates(Certificate[] certs);
 
     public abstract PermissionGrantBuilder principals(Principal[] pals);
     
-    public final PermissionGrantBuilder denials(Deny denied) {
-        AccessController.checkPermission(new DenyPermission());
-        return deny(denied);
-    }
-    
-    public final PermissionGrantBuilder grant(Permission[] permissions){
-        AccessController.checkPermission(new GrantPermission(permissions));
-        return permissions(permissions);
-    }
-    
-    public final PermissionGrant create(){
-        return AccessController.doPrivileged(new PrivilegedAction<PermissionGrant>(){
-            public PermissionGrant run(){
-                return build();
-            }
-        });
-    }
-
-    protected abstract PermissionGrantBuilder permissions(Permission[] permissions);
+    public abstract PermissionGrantBuilder permissions(Permission[] perm);
 
-    protected abstract PermissionGrant build();
+    public abstract PermissionGrantBuilder deny(Denied denial);
     
-    protected abstract PermissionGrantBuilder deny(Deny denied);
+    public abstract PermissionGrant build();
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java Mon Jul  5 13:28:19 2010
@@ -12,6 +12,8 @@ public interface RevokeableDynamicPolicy
     public void add(List<PermissionGrant> grants);
     public void remove(List<PermissionGrant> grants);
     public List<PermissionGrant> getPermissionGrants();
-    public PermissionGrantBuilder getPermissionGrantBuilder();
+    public void add(List<Denied> denials);
+    public void remove(List<Denied> denials);
+    public List<Denied> getDenied();    
     public boolean revokeSupported();
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java Mon Jul  5 13:28:19 2010
@@ -46,6 +46,7 @@ import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import net.jini.security.GrantPermission;
+import org.apache.river.api.security.Denied;
 import org.apache.river.api.security.PermissionGrant;
 import org.apache.river.api.security.PermissionGrantBuilder;
 import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
@@ -581,8 +582,16 @@ public class DynamicPolicyProviderImpl e
         throw new UnsupportedOperationException("Not supported.");
     }
 
-    public PermissionGrantBuilder getPermissionGrantBuilder() {
-        throw new UnsupportedOperationException("Not supported.");
+    public void add(List<Denied> denials) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public void remove(List<Denied> denials) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public List<Denied> getDenied() {
+        throw new UnsupportedOperationException("Not supported yet.");
     }
 
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPolicyFile.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPolicyFile.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPolicyFile.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPolicyFile.java Mon Jul  5 13:28:19 2010
@@ -34,6 +34,7 @@ import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.Policy;
 import java.security.ProtectionDomain;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -44,8 +45,8 @@ import java.util.concurrent.ConcurrentMa
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+import org.apache.river.api.security.PermissionGrant;
 import org.apache.river.imp.security.policy.util.DefaultPolicyParser;
-import org.apache.river.imp.security.policy.util.PolicyEntry;
 import org.apache.river.imp.security.policy.util.PolicyParser;
 import org.apache.river.imp.security.policy.util.PolicyUtils;
 import org.apache.river.imp.util.ConcurrentWeakIdentityMap;
@@ -175,7 +176,7 @@ public class ConcurrentPolicyFile extend
     private final ReadLock rl;
     private final WriteLock wl;
     
-    private Set<PolicyEntry> grants = new HashSet<PolicyEntry>(); // protected by rwl
+    private Set<PermissionGrant> grants = new HashSet<PermissionGrant>(); // protected by rwl
 
     // Calculated Permissions cache, organized as
     // Map{Object->Collection&lt;Permission&gt;}.
@@ -228,12 +229,15 @@ public class ConcurrentPolicyFile extend
         }
         try {
             rl.lock();
-            Iterator<PolicyEntry> it = grants.iterator();
+            Iterator<PermissionGrant> it = grants.iterator();
             while (it.hasNext()) {
-                PolicyEntry ge = it.next();
-                if (ge.impliesPrincipals(pd == null ? null : pd.getPrincipals())
-                    && ge.impliesCodeSource(pd == null ? null : pd.getCodeSource())) {
-                    pc.addAll(ge.getPermissions());
+                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() )){
+                    Permission[] perm = ge.getPermissions();
+                    pc.addAll(Arrays.asList(perm));
                 }
             }               
         } finally { rl.unlock(); }        
@@ -259,12 +263,15 @@ public class ConcurrentPolicyFile extend
         }
         try {
             rl.lock();
-            Iterator<PolicyEntry> it = grants.iterator();
+            Iterator<PermissionGrant> it = grants.iterator();
             while (it.hasNext()) {
-                PolicyEntry ge = it.next();
-                if (ge.impliesPrincipals(null)
-                    && ge.impliesCodeSource(cs)) {
-                    pc.addAll(ge.getPermissions()); // we still hold a reference
+                PermissionGrant ge = it.next();
+//                if (ge.impliesPrincipals(null)
+//                    && ge.impliesCodeSource(cs)) {
+                if (ge.implies(cs,null )){
+                    Permission[] perm = ge.getPermissions();
+                    pc.addAll(Arrays.asList(perm)); // we still hold a reference
+//                    pc.addAll(ge.getPermissions()); // we still hold a reference
                 }
             }     
         } finally { rl.unlock(); }
@@ -289,7 +296,7 @@ public class ConcurrentPolicyFile extend
      */
     @Override
     public void refresh() {
-        Set<PolicyEntry> fresh = new HashSet<PolicyEntry>();
+        Set<PermissionGrant> fresh = new HashSet<PermissionGrant>();
         Properties system = new Properties(AccessController
                 .doPrivileged(new PolicyUtils.SystemKit()));
         system.setProperty("/", File.separator); //$NON-NLS-1$
@@ -300,7 +307,7 @@ public class ConcurrentPolicyFile extend
             try {
                 //TODO debug log
                 //System.err.println("Parsing policy file: " + policyLocations[i]);
-                Collection<PolicyEntry> pc = parser.parse(policyLocations[i], system);
+                Collection<PermissionGrant> pc = parser.parse(policyLocations[i], system);
                 fresh.addAll(pc);
             } catch (Exception e) {
                 // TODO log warning

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/DynamicConcurrentPolicyProvider.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/DynamicConcurrentPolicyProvider.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/DynamicConcurrentPolicyProvider.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/DynamicConcurrentPolicyProvider.java Mon Jul  5 13:28:19 2010
@@ -13,6 +13,7 @@ import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
 import java.security.Provider;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -27,9 +28,11 @@ import java.util.logging.Logger;
 import net.jini.security.GrantPermission;
 import net.jini.security.policy.DynamicPolicy;
 import net.jini.security.policy.PolicyInitializationException;
-import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
+import org.apache.river.api.security.Denied;
 import org.apache.river.api.security.PermissionGrant;
+import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
 import org.apache.river.api.security.PermissionGrantBuilder;
+import org.apache.river.api.security.RevokePermission;
 import org.apache.river.api.security.RevokeableDynamicPolicy;
 import org.apache.river.imp.security.policy.util.PermissionGrantBuilderImp;
 import org.apache.river.imp.security.policy.util.PolicyUtils;
@@ -124,6 +127,12 @@ 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;
     
     
     public DynamicConcurrentPolicyProvider(){
@@ -137,6 +146,11 @@ public class DynamicConcurrentPolicyProv
         revokeable = true;
         logger = Logger.getLogger("net.jini.security.policy");
         loggable = logger.isLoggable(Level.FINEST);
+        drwl = new ReentrantReadWriteLock();
+        drl = drwl.readLock();
+        dwl = drwl.writeLock();
+        denied = new HashSet<Denied>(30);
+        checkDenied = false;
     }
     
     /**
@@ -217,6 +231,18 @@ public class DynamicConcurrentPolicyProv
 
     public boolean implies(ProtectionDomain domain, Permission permission) {
         if (initialized == false) throw new RuntimeException("Object not initialized");
+        // Will this ProtectionDomain and Permission be denied?
+        if (checkDenied){
+            try {
+                drl.lock();
+                Iterator<Denied> itr = denied.iterator();
+                while (itr.hasNext()){
+                    if ( !itr.next().allow(domain, permission)){
+                        return false;
+                    }
+                }
+            } finally { drl.unlock(); }
+        }
         // First check the our cache if the basePolicy is not dynamic.
         PermissionCollection pc = cache.get(domain);
         if (!basePolicyIsDynamic && pc != null) {
@@ -247,8 +273,8 @@ public class DynamicConcurrentPolicyProv
             Iterator<PermissionGrant> it = dynamicGrants.iterator();
             while (it.hasNext()) {
                 PermissionGrant ge = it.next();
-                if ( ge.applicable(domain)) {
-                    dynamicallyGrantedPermissions.addAll( ge.getPermissions());
+                if ( ge.implies(domain)) {
+                    dynamicallyGrantedPermissions.addAll( Arrays.asList(ge.getPermissions()));
                 }
             }               
         } finally { rl.unlock(); }
@@ -336,9 +362,9 @@ public class DynamicConcurrentPolicyProv
 	}
         PermissionGrantBuilder pgb = new PermissionGrantBuilderImp();
         PermissionGrant pe = pgb.clazz(cl).principals(principals)
-                .grant(permissions)
-                .context(PermissionGrant.CLASSLOADER)
-                .create();
+                .permissions(permissions)
+                .context(PermissionGrantBuilder.CLASSLOADER)
+                .build();
         if (loggable){
             logger.log(Level.FINEST, "Granting: " + pe.toString());
         }
@@ -370,7 +396,7 @@ public class DynamicConcurrentPolicyProv
                 // all grants that may be granted by other means.
                 // such as ProtectionDomain, Certificates, CodeSource or Principals alone.
                 if ( ge.implies(loader, principals)) {
-                    cperms.addAll(ge.getPermissions());
+                    cperms.addAll(Arrays.asList(ge.getPermissions()));
                 }     
             }
         } finally { rl.unlock(); }
@@ -389,11 +415,22 @@ public class DynamicConcurrentPolicyProv
 
     public void add(List<PermissionGrant> grants) {
         if (initialized == false) throw new RuntimeException("Object not initialized");
+        // because PermissionGrant's are given references to ProtectionDomain's
+        // we must check the caller has this permission.
+        AccessController.checkPermission(new RuntimePermission("getProtectionDomain"));
         if (revokeable){
             RevokeableDynamicPolicy bp = (RevokeableDynamicPolicy) basePolicy;
             bp.add(grants);
             return;
         }
+        //List<PermissionGrant> allowed = new ArrayList<PermissionGrant>(grants.size());
+        Iterator<PermissionGrant> grantsItr = grants.iterator();
+        while (grantsItr.hasNext()){
+            PermissionGrant grant = grantsItr.next();
+            Permission[] perms = grant.getPermissions();
+            AccessController.checkPermission(new GrantPermission(perms));
+        }
+        // If we get to here, the caller has permission.
         try {
             wl.lock();
             dynamicGrants.addAll(grants);
@@ -407,6 +444,7 @@ public class DynamicConcurrentPolicyProv
             bp.remove(grants);
             return;
         }
+        AccessController.checkPermission(new RevokePermission());
         try {
             wl.lock();
             dynamicGrants.removeAll(grants);
@@ -429,9 +467,35 @@ public class DynamicConcurrentPolicyProv
         }finally {rl.unlock();}
     }
 
-    public PermissionGrantBuilder getPermissionGrantBuilder() {
+    public void add(List<Denied> denials) {
         if (initialized == false) throw new RuntimeException("Object not initialized");
-        return new PermissionGrantBuilderImp();
+        AccessController.checkPermission(new RuntimePermission("getProtectionDomain"));
+        AccessController.checkPermission(new RevokePermission());
+        checkDenied = true;
+        try{
+            dwl.lock();
+            denied.addAll(denials);
+        } finally { dwl.unlock();}
+    }
+
+    public void remove(List<Denied> denials) {
+        if (initialized == false) throw new RuntimeException("Object not initialized");
+        try{
+            dwl.lock();
+            denied.removeAll(denials);
+            if ( denied.isEmpty()) { checkDenied = false; }
+        } finally { dwl.unlock();}
+    }
+
+    public List<Denied> getDenied() {
+        if (initialized == false) throw new RuntimeException("Object not initialized");
+        List<Denied> denials;
+        try{
+            drl.lock();
+            denials = new ArrayList<Denied>(denied.size());
+            denials.addAll(denied);
+            return denials;
+        } finally { dwl.unlock();}
     }
 
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java Mon Jul  5 13:28:19 2010
@@ -29,7 +29,8 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import org.apache.river.api.security.Deny;
+import org.apache.river.api.security.Denied;
+import org.apache.river.imp.security.policy.util.DenyImpl;
 
 /**
  *
@@ -38,9 +39,11 @@ import org.apache.river.api.security.Den
 class CertificateGrant extends CodeSourceGrant {
     private final Collection<Certificate> certs;
     private final int hashCode;
+    private final Denied denied;
     @SuppressWarnings("unchecked")
-    CertificateGrant(Certificate[] codeSourceCerts, Principal[] pals, Permission[] perms, Deny deny){
-        super(null, pals, perms, deny);
+    CertificateGrant(Certificate[] codeSourceCerts, Principal[] pals, Permission[] perms, Denied deny){
+        super(null, pals, perms);
+        denied = deny;
          if (codeSourceCerts == null || codeSourceCerts.length == 0) {
             certs = Collections.EMPTY_SET;
         }else{
@@ -72,13 +75,16 @@ class CertificateGrant extends CodeSourc
     
     @Override
     public boolean implies(ProtectionDomain pd) {
-        Certificate[] c = null;
-        Principal[] pals = null;
-        if (pd != null){
-            c = pd.getCodeSource().getCertificates();
-            pals = pd.getPrincipals();
+        if ( denied.allow(pd, null)){
+            Certificate[] c = null;
+            Principal[] pals = null;
+            if (pd != null){
+                c = pd.getCodeSource().getCertificates();
+                pals = pd.getPrincipals();
+            }
+            return implies(c, pals);
         }
-        return implies(c, pals);
+        return false;
     }
     
     @Override
@@ -101,6 +107,6 @@ class CertificateGrant extends CodeSourc
     public PermissionGrantBuilder getBuilderTemplate() {
         PermissionGrantBuilder pgb = super.getBuilderTemplate();
         return pgb.certificates(certs.toArray(new Certificate[certs.size()]))
-                .context(CODESOURCE_CERTS);
+                .context(PermissionGrantBuilder.CODESOURCE_CERTS);
     }
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ClassLoaderGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ClassLoaderGrant.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ClassLoaderGrant.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ClassLoaderGrant.java Mon Jul  5 13:28:19 2010
@@ -23,8 +23,6 @@ import java.lang.ref.WeakReference;
 import java.security.Permission;
 import java.security.Principal;
 import java.security.ProtectionDomain;
-import org.apache.river.api.security.Deny;
-import org.apache.river.api.security.PermissionGrant;
 
 /**
  *
@@ -34,8 +32,8 @@ class ClassLoaderGrant extends Protectio
     private final int hashCode;
     @SuppressWarnings("unchecked")
     ClassLoaderGrant(WeakReference<ProtectionDomain> domain, Principal[] groups, 
-            Permission[] perm, Deny deny){
-        super(domain, groups, perm, deny);
+            Permission[] perm){
+        super(domain, groups, perm);
         int hash = 7;
         hash = 19 * hash + super.hashCode();
         hashCode = hash;
@@ -70,6 +68,6 @@ class ClassLoaderGrant extends Protectio
     @Override
     public PermissionGrantBuilder getBuilderTemplate() {
         PermissionGrantBuilder pgb = super.getBuilderTemplate();
-        return pgb.context(CLASSLOADER);
+        return pgb.context(PermissionGrantBuilder.CLASSLOADER);
     }
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CodeSourceGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CodeSourceGrant.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CodeSourceGrant.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CodeSourceGrant.java Mon Jul  5 13:28:19 2010
@@ -26,7 +26,7 @@ import java.security.ProtectionDomain;
 import java.security.cert.Certificate;
 import java.util.Arrays;
 import java.util.List;
-import org.apache.river.api.security.Deny;
+import org.apache.river.imp.security.policy.util.DenyImpl;
 
 /**
  *
@@ -37,8 +37,8 @@ class CodeSourceGrant extends PrincipalG
     private final int hashCode;
     
     @SuppressWarnings("unchecked")
-    CodeSourceGrant(CodeSource cs, Principal[] pals, Permission[] perm, Deny deny){
-        super(pals, perm, deny);
+    CodeSourceGrant(CodeSource cs, Principal[] pals, Permission[] perm){
+        super(pals, perm);
         this.cs = normalizeCodeSource(cs);
         int hash = 3;
         hash = 67 * hash + (this.cs != null ? this.cs.hashCode() : 0);
@@ -113,7 +113,7 @@ class CodeSourceGrant extends PrincipalG
     public PermissionGrantBuilder getBuilderTemplate() {
         PermissionGrantBuilder pgb = super.getBuilderTemplate();
         pgb.codeSource(cs)
-           .context(CODESOURCE);
+           .context(PermissionGrantBuilder.CODESOURCE);
         return pgb;
     }
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DefaultPolicyParser.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DefaultPolicyParser.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DefaultPolicyParser.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DefaultPolicyParser.java Mon Jul  5 13:28:19 2010
@@ -46,6 +46,8 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.StringTokenizer;
 
+import org.apache.river.api.security.PermissionGrant;
+import org.apache.river.api.security.PermissionGrantBuilder;
 import org.apache.river.imp.security.policy.util.DefaultPolicyScanner.GrantEntry;
 import org.apache.river.imp.security.policy.util.DefaultPolicyScanner.KeystoreEntry;
 import org.apache.river.imp.security.policy.util.DefaultPolicyScanner.PermissionEntry;
@@ -107,7 +109,7 @@ public class DefaultPolicyParser impleme
      * @return a collection of PolicyEntry objects, may be empty
      * @throws Exception IO error while reading location or file syntax error 
      */
-    public Collection<PolicyEntry> parse(URL location, Properties system)
+    public Collection<PermissionGrant> parse(URL location, Properties system)
             throws Exception {
         boolean resolve = PolicyUtils.canExpandProperties();
         Reader r = new BufferedReader(new InputStreamReader(
@@ -127,12 +129,12 @@ public class DefaultPolicyParser impleme
         //XXX KeyStore could be loaded lazily...
         KeyStore ks = initKeyStore(keystores, location, system, resolve);
 
-        Collection<PolicyEntry> result = new HashSet<PolicyEntry>();
+        Collection<PermissionGrant> result = new HashSet<PermissionGrant>();
         for (Iterator<GrantEntry> iter = grantEntries.iterator(); iter.hasNext();) {
             DefaultPolicyScanner.GrantEntry ge = iter
                     .next();
             try {
-                PolicyEntry pe = resolveGrant(ge, ks, system, resolve);
+                PermissionGrant pe = resolveGrant(ge, ks, system, resolve);
                 if (!pe.isVoid()) {
                     result.add(pe);
                 }
@@ -178,7 +180,7 @@ public class DefaultPolicyParser impleme
      * @see DefaultPolicyScanner.PermissionEntry
      * @see org.apache.harmony.security.PolicyUtils
      */
-    protected PolicyEntry resolveGrant(DefaultPolicyScanner.GrantEntry ge,
+    protected PermissionGrant resolveGrant(DefaultPolicyScanner.GrantEntry ge,
             KeyStore ks, Properties system, boolean resolve) throws Exception {
 
         URL codebase = null;
@@ -222,8 +224,15 @@ public class DefaultPolicyParser impleme
                 }
             }
         }
-        return new PolicyEntry(new CodeSource(codebase, signers), principals,
-                permissions);
+        PermissionGrantBuilder pgb = new PermissionGrantBuilderImp();
+        return pgb.codeSource(new CodeSource(codebase, signers))
+                .principals(principals.toArray(new Principal[principals.size()]))
+                .permissions(permissions.toArray(new Permission[permissions.size()]))
+                .context(PermissionGrantBuilder.CODESOURCE)
+                .build();
+        
+//        return new PolicyEntry(new CodeSource(codebase, signers), principals,
+//                permissions);
     }
 
     /**

Added: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java?rev=960596&view=auto
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java (added)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java Mon Jul  5 13:28:19 2010
@@ -0,0 +1,107 @@
+/*
+ * 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.imp.security.policy.util;
+
+import org.apache.river.api.security.*;
+import java.net.URL;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.river.imp.security.policy.util.PolicyUtils;
+
+/**
+ * Immutable List of codebase URL's and CodeSource's to deny in a PermissionGrant. 
+ * Supplied to a PermissionGrantBuilder.
+ * 
+ * Applies only to Certificate[] and ClassLoader grant's, serves no use for CodeSource
+ * or PermissionDomain grants.
+ * 
+ * This is not a global list, however since it is immutable, it can be shared
+ * among PermissionGrant's to save memory. 
+ * 
+ * The user is responsible for deciding how these apply to each PermissionGrant.
+ * 
+ * Usually this will be used in combination with Certificate[] grants, to
+ * circumvent security bugs identified in known jar files by trusted developers.
+ * 
+ * Denied does not allow any permission, only Denied.
+ * 
+ * This class may be extended. The caller must have a DenyPermission before it
+ * can be added to a PermissionGrantBuilder.
+ *
+ * @author Peter Firmstone
+ */
+public class DenyImpl implements Denied {
+    private final List<URL> uri;
+    private final List<CodeSource> code;
+    
+    public DenyImpl(List<URL> denyURL, List<CodeSource> denyCode){
+        List<URL> denied = new ArrayList<URL>(denyURL.size());
+        Iterator<URL> itU = denyURL.iterator();
+        while (itU.hasNext()){
+            denied.add(PolicyUtils.normalizeURL(itU.next()));
+        }
+        uri = Collections.unmodifiableList(denied);
+        List<CodeSource> c = new ArrayList<CodeSource>(denyCode.size());
+        Iterator<CodeSource> itC = c.iterator();
+        while (itC.hasNext()){
+            c.add(normalizeCodeSource(itC.next()));
+        }
+        code = Collections.unmodifiableList(c);
+    }
+    
+    public List<URL> deniedURLs(){
+        return uri;
+    }
+    
+    public List<CodeSource> deniedCode() {
+        return code;
+    }
+    
+    public boolean allow(ProtectionDomain pd,java.security.Permission perm){
+        CodeSource cs = pd.getCodeSource();
+        cs = normalizeCodeSource(cs);
+        if (code.contains(cs)) return false;
+        URL codeSourceURL = cs.getLocation();
+        if (uri.contains(codeSourceURL)) return false;
+        return true;
+    }
+    
+    private CodeSource normalizeCodeSource(CodeSource codeSource) {
+        if (codeSource == null ) return null;
+        URL codeSourceURL = PolicyUtils.normalizeURL(codeSource.getLocation());
+        CodeSource result = codeSource;
+
+        if (codeSourceURL != codeSource.getLocation()) {
+            // URL was normalized - recreate codeSource with new URL
+            CodeSigner[] signers = codeSource.getCodeSigners();
+            if (signers == null) {
+                result = new CodeSource(codeSourceURL, codeSource
+                        .getCertificates());
+            } else {
+                result = new CodeSource(codeSourceURL, signers);
+            }
+        }
+        return result;
+    } 
+}

Propchange: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/NullPolicyParser.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/NullPolicyParser.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/NullPolicyParser.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/NullPolicyParser.java Mon Jul  5 13:28:19 2010
@@ -9,6 +9,7 @@ import java.net.URL;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Properties;
+import org.apache.river.api.security.PermissionGrant;
 
 /**
  * A null PolicyParser.
@@ -17,8 +18,7 @@ import java.util.Properties;
  */
 public class NullPolicyParser implements PolicyParser{
 
-    public Collection<PolicyEntry> parse(URL location, Properties system) throws Exception {
-        return new HashSet<PolicyEntry>();
+    public Collection<PermissionGrant> parse(URL location, Properties system) throws Exception {
+        return new HashSet<PermissionGrant>();
     }
-
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java Mon Jul  5 13:28:19 2010
@@ -18,6 +18,7 @@
 
 package org.apache.river.imp.security.policy.util;
 
+import org.apache.river.api.security.Denied;
 import org.apache.river.api.security.PermissionGrantBuilder;
 import java.lang.ref.WeakReference;
 import java.security.CodeSource;
@@ -25,14 +26,13 @@ import java.security.Permission;
 import java.security.Principal;
 import java.security.ProtectionDomain;
 import java.security.cert.Certificate;
-import org.apache.river.api.security.Deny;
 import org.apache.river.api.security.PermissionGrant;
 
 /**
  * TODO: Document and complete Serializable.
  * @author Peter Firmstone
  */
-public class PermissionGrantBuilderImp extends PermissionGrantBuilder{
+public class PermissionGrantBuilderImp implements PermissionGrantBuilder{
     private static final long serialVersionUID = 1L;
     private CodeSource cs;
     private Certificate[] certs;
@@ -40,7 +40,7 @@ public class PermissionGrantBuilderImp e
     private Principal[] principals;
     private Permission[] permissions;
     private int context;
-    private Deny deny;
+    private Denied deny;
     
     public PermissionGrantBuilderImp() {
         super();
@@ -58,7 +58,7 @@ public class PermissionGrantBuilderImp e
         principals = null;
         permissions = null;
         deny = null;
-        context = PermissionGrant.CODESOURCE;
+        context = CODESOURCE;
     }
 
     public PermissionGrantBuilder context(int context) {
@@ -93,7 +93,7 @@ public class PermissionGrantBuilderImp e
         return this;
     }
 
-    public PermissionGrantBuilder domain(WeakReference<ProtectionDomain> pd) {
+    public PermissionGrantBuilder setDomain(WeakReference<ProtectionDomain> pd) {
         domain = pd;
         return this;
     }
@@ -113,25 +113,26 @@ public class PermissionGrantBuilderImp e
         this.permissions = permissions;
         return this;
     }
-    
-    public PermissionGrantBuilder deny(Deny denied){
-        deny = denied;
-        return this;
-    }
 
     public PermissionGrant build() {
         switch (context) {
-            case PermissionGrant.CLASSLOADER:
-                return new ClassLoaderGrant(domain, principals, permissions, deny);
-            case PermissionGrant.CODESOURCE:
-                return new CodeSourceGrant(cs, principals, permissions, null);
-            case PermissionGrant.CODESOURCE_CERTS:
-                return new CertificateGrant(certs, principals, permissions, deny);
-            case PermissionGrant.PROTECTIONDOMAIN:
-                return new ProtectionDomainGrant(domain, principals, permissions, null);
+            case CLASSLOADER:
+                return new ClassLoaderGrant(domain, principals, permissions );
+            case CODESOURCE:
+                return new CodeSourceGrant(cs, principals, permissions );
+            case CODESOURCE_CERTS:
+                return new CertificateGrant(certs, principals, permissions, deny );
+            case PROTECTIONDOMAIN:
+                return new ProtectionDomainGrant(domain, principals, permissions );
             default:
                 return null;
         }
     }
 
+    @Override
+    public PermissionGrantBuilder deny(Denied denial) {
+        deny = denial;
+        return this;
+    }
+
 }

Added: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantImp.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantImp.java?rev=960596&view=auto
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantImp.java (added)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantImp.java Mon Jul  5 13:28:19 2010
@@ -0,0 +1,173 @@
+/*
+ * 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.imp.security.policy.util;
+
+import org.apache.river.api.security.*;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.util.Collection;
+
+/**
+ * PermissionGrant's are expected to be effectively immutable,
+ * threadsafe and have a good hashCode implementation to perform well in
+ * Collections.
+ * 
+ * You shouldn't pass around PermissionGrant's to just anyone as they can
+ * provide an attacker with Permission's that may have been granted.
+ * The RevokeableDynamicPolicy must be asked for the PermissionGrantBulder which creates the
+ * PermissionGrant's for a less Privileged user.  The user must first have
+ * access to a Policy.
+ * 
+ * @author Peter Firmstone
+ * @see RevokeableDynamicPolicy
+ */
+public abstract class PermissionGrantImp {
+    public PermissionGrantImp(){
+    }
+    
+    /**
+     * This is here to provide functionality for less privileged code / users who
+     * have Permission to get a Policy. For cases where that user / code doesn't
+     * have access to ProtectionDomain's or ClassLoaders.
+     * 
+     * This is equalivant to the methods below, with Privileges.
+     * 
+     * A user will still require specific GrantPermission's before being
+     * able to build a PermissionGrant.
+     * 
+     * @param clazz - The class file.
+     * @param pal - An array of Principal's
+     * @param context - PermissionGrantBuilder context constant.
+     * @return
+     */
+//    @SuppressWarnings("unchecked")
+//    public final boolean implies( final Class clazz, final Principal[] pal, final int context){
+//        AccessController.doPrivileged(new PrivilegedAction() {
+//            public Object run(){
+//                switch (context){
+//                    case CLASSLOADER: {
+//                        return implies(clazz.getClassLoader(), pal);
+//                    }
+//                    case PROTECTIONDOMAIN: {
+//                        return implies(clazz.getProtectionDomain(), pal);
+//                    }
+//                    case CODESOURCE: {
+//                        return implies(clazz.getProtectionDomain().getCodeSource(), pal);
+//                    }
+//                    case CODESOURCE_CERTS: {
+//                        return implies(clazz.getProtectionDomain()
+//                                .getCodeSource().getCertificates(),
+//                                pal);
+//                    }
+//                    default:
+//                        throw new IllegalStateException("int context unknown");
+//                }
+//            }
+//        });
+//        return false;
+//    }
+//    
+    /**
+     * A DynamicPolicy implementation can use a PermissionGrant as a container
+     * for Dynamic Grant's.  A PermissionGrant is first asked by the Policy
+     * if it applies to a Particular ProtectionDomain, if it does, the Policy
+     * calls getPermissions.
+     * 
+     * Dynamic grants can be denied to some ProtectionDomains based on
+     * CodeSource or URL's for codebases, this is to remove the possiblity of
+     * executing Permissions for vulnerable codebases, once a vulnerability
+     * is identified after the fact.
+     * 
+     * @param pd ProtectionDomain
+     * @return
+     * @see RevokeableDynamicPolicy
+     */
+    public final boolean applicable(ProtectionDomain pd){
+        return implies(pd);
+    }
+    
+    /**
+     * A DynamicPolicy implementation can use a PermissionGrant as a container
+     * for Dynamic Grant's.  A PermissionGrant is first asked by the Policy
+     * if it implies a Particular ProtectionDomain, if it does, the Policy
+     * calls getPermissions.
+     * 
+     * Only this method is utilised by the RevokeableDynamicPolicy, 
+     * for Permission checks, extending classes must implement it.
+     * 
+     * @param pd ProtectionDomain
+     * @return
+     * @see RevokeableDynamicPolicy
+     */
+    protected abstract boolean implies(ProtectionDomain pd);
+    /**
+     * Checks if this PermissionGrant applies to the ProtectionDomain with
+     * the given principals, this is useful for Subject's where a Subject's
+     * Principals are added to a ProtectionDomain by a Policy check by the
+     * AccessController and DomainCombiner.  This is not used by the Policy.
+     * This is a utility method to determine if a ProtectionDomain had a set of
+     * Principals what the effect is.  
+     * 
+     * The ProtectionDomain's internal set of Principals are ignored for 
+     * this method.
+     * 
+     * @param pd
+     * @param pal
+     * @return
+     * @see AccessController
+     * @see DomainCombiner
+     */
+    public abstract boolean implies(ProtectionDomain pd, Principal[] pal);
+    /**
+     * Checks if this PermissionGrant applies to the passed in ClassLoader
+     * and Principal's.
+     * 
+     * Note that if this method returns false, it doesn't necessarily mean
+     * that the grant will not apply to the ClassLoader, since it will depend on 
+     * the contents of the ClassLoader and that is inderterminate. It just
+     * indicates that the grant definitely does apply if it returns true.
+     * 
+     * If this method returns false, follow up using the ProtectionDomain for a
+     * more specific test, which may return true.
+     */
+    public abstract boolean implies(ClassLoader cl, Principal[] pal);
+    /**
+     * Checks if this PermissionGrant applies to the passed in CodeSource
+     * and Principal's.
+     * @param cs
+     * @return 
+     */
+    public abstract boolean implies(CodeSource codeSource, Principal[] pal);
+    /**
+     * Checks if this PermissionGrant applies to the passed in Certificate's
+     * and Principal's.
+     */
+    public abstract boolean implies(Certificate[] certs, Principal[] pal);
+    /**
+     * Provides a builder that will replicate the PermissionGrant.  Useful
+     * when you want to change the Permission's but not the
+     * context.
+     */
+    public abstract PermissionGrantBuilder getBuilderTemplate();
+}

Propchange: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantImp.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyParser.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyParser.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyParser.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyParser.java Mon Jul  5 13:28:19 2010
@@ -8,6 +8,7 @@ package org.apache.river.imp.security.po
 import java.net.URL;
 import java.util.Collection;
 import java.util.Properties;
+import org.apache.river.api.security.PermissionGrant;
 
 /**
  *
@@ -30,6 +31,6 @@ public interface PolicyParser {
      * @return a collection of PolicyEntry objects, may be empty
      * @throws Exception IO error while reading location or file syntax error
      */
-    Collection<PolicyEntry> parse(URL location, Properties system) throws Exception;
+    Collection<PermissionGrant> parse(URL location, Properties system) throws Exception;
 
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PrincipalGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PrincipalGrant.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PrincipalGrant.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PrincipalGrant.java Mon Jul  5 13:28:19 2010
@@ -19,7 +19,6 @@
 package org.apache.river.imp.security.policy.util;
 
 import org.apache.river.api.security.PermissionGrantBuilder;
-import org.apache.river.api.security.PermissionGrant;
 import java.net.URL;
 import java.security.CodeSigner;
 import java.security.CodeSource;
@@ -35,19 +34,18 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.river.api.security.Deny;
+import org.apache.river.api.security.PermissionGrant;
 
 /**
  *
  * @author Peter Firmstone.
  */
-abstract class PrincipalGrant extends PermissionGrant {
+abstract class PrincipalGrant implements PermissionGrant {
     private final Collection<Principal> principals;
     private final int hashCode;
     private final Collection<Permission> permissions;
-    private final Deny check;
     @SuppressWarnings("unchecked")
-    protected PrincipalGrant(Principal[] pals, Permission[] perm, Deny deny){
+    protected PrincipalGrant(Principal[] pals, Permission[] perm){
         if ( pals != null ){
             principals = new ArrayList<Principal>(pals.length);
             principals.addAll(Arrays.asList(pals));
@@ -60,7 +58,6 @@ abstract class PrincipalGrant extends Pe
             this.permissions = new HashSet<Permission>(perm.length);
             this.permissions.addAll(Arrays.asList(perm));
         }
-        check = deny;
         int hash = 5;
         hash = 97 * hash + (this.principals != null ? this.principals.hashCode() : 0);
         hash = 97 * hash + (this.permissions != null ? this.permissions.hashCode() : 0);
@@ -83,10 +80,6 @@ abstract class PrincipalGrant extends Pe
     public int hashCode() {
         return hashCode;
     }
-    
-    protected Deny getDenials(){
-        return check;
-    }
         
     protected boolean implies(Principal[] prs) {
         if ( principals.isEmpty()) return true;
@@ -190,13 +183,12 @@ abstract class PrincipalGrant extends Pe
     public PermissionGrantBuilder getBuilderTemplate() {
         PermissionGrantBuilder pgb = new PermissionGrantBuilderImp();
         pgb.principals(principals.toArray(new Principal[principals.size()]))
-           .grant(permissions.toArray(new Permission[permissions.size()]))
-           .denials(check);
+           .permissions(permissions.toArray(new Permission[permissions.size()]));
         return pgb;
     }
 
-    public Collection<Permission> getPermissions() {
-        return Collections.unmodifiableCollection(permissions);
+    public Permission[] getPermissions() {
+        return permissions.toArray(new Permission[permissions.size()]);
     }
     
     public boolean isVoid() {        

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ProtectionDomainGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ProtectionDomainGrant.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ProtectionDomainGrant.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/ProtectionDomainGrant.java Mon Jul  5 13:28:19 2010
@@ -27,7 +27,6 @@ import java.security.ProtectionDomain;
 import java.security.cert.Certificate;
 import java.util.Arrays;
 import java.util.List;
-import org.apache.river.api.security.Deny;
 
 /**
  *
@@ -40,8 +39,8 @@ class ProtectionDomainGrant extends Prin
     
     @SuppressWarnings("unchecked")
     ProtectionDomainGrant(WeakReference<ProtectionDomain> domain, Principal[] groups, 
-            Permission[] perm, Deny deny ){
-        super(groups, perm, deny);
+            Permission[] perm){
+        super(groups, perm);
         if (domain == null){
             hasDomain = false;
         }else{
@@ -128,9 +127,12 @@ class ProtectionDomainGrant extends Prin
     @Override
     public PermissionGrantBuilder getBuilderTemplate() {
         PermissionGrantBuilder pgb = super.getBuilderTemplate();
-        return pgb
-                .domain(domain)
-                .context(PROTECTIONDOMAIN);
+        if ( pgb instanceof PermissionGrantBuilderImp ){
+         PermissionGrantBuilderImp pgbi = (PermissionGrantBuilderImp) pgb;
+                pgbi.setDomain(domain)
+                .context(PermissionGrantBuilder.PROTECTIONDOMAIN);
+        }
+        return pgb;
     }
   
 }

Modified: incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/DefaultPolicyParserTest.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/DefaultPolicyParserTest.java?rev=960596&r1=960595&r2=960596&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/DefaultPolicyParserTest.java (original)
+++ incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/DefaultPolicyParserTest.java Mon Jul  5 13:28:19 2010
@@ -28,13 +28,17 @@ import java.io.File;
 import java.io.FileWriter;
 import java.net.URL;
 import java.security.CodeSource;
+import java.security.Permission;
 import java.security.Principal;
 import java.security.SecurityPermission;
 import java.security.cert.Certificate;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 
+import java.util.List;
 import junit.framework.TestCase;
+import org.apache.river.api.security.PermissionGrant;
 
 
 /**
@@ -70,21 +74,19 @@ public class DefaultPolicyParserTest ext
         Collection entries = parser.parse(tmp.toURI().toURL(), null);
         assertEquals(2, entries.size());
         for (Iterator iter = entries.iterator(); iter.hasNext();) {
-            PolicyEntry element = (PolicyEntry)iter.next();
-            if (element.getPermissions()
+            PermissionGrant element = (PermissionGrant)iter.next();
+            Permission[] perm = element.getPermissions();
+            List<Permission> permissions = Arrays.asList(perm);
+            if (permissions
                 .contains(new SecurityPermission("ZZZ"))) {
-                assertTrue(element.impliesCodeSource(new CodeSource(null,
-                    (Certificate[])null)));
-                assertTrue(element.impliesPrincipals(null));
-            } else if (element.getPermissions()
+                assertTrue(element.implies(new CodeSource(null,
+                    (Certificate[])null), null));
+            } else if (permissions
                 .contains(new SecurityPermission("YYY"))) {
-                assertFalse(element.impliesCodeSource(null));
-                assertFalse(element.impliesPrincipals(null));
-                assertTrue(element.impliesCodeSource(new CodeSource(new URL(
-                    "http://a.b.c/-"), (Certificate[])null)));
-                assertTrue(element
-                    .impliesPrincipals(new Principal[] { new FakePrincipal(
-                        "qqq") }));
+                assertFalse(element.implies((CodeSource) null, (Principal[]) null));
+                assertTrue(element.implies(new CodeSource(new URL(
+                    "http://a.b.c/-"), (Certificate[])null), 
+                    new Principal[] { new FakePrincipal("qqq") }));
             } else {
                 fail("Extra entry parsed");
             }