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/11/24 21:58:55 UTC

svn commit: r1038815 - in /incubator/river/jtsk/skunk/pepe: ./ src/com/sun/jini/discovery/internal/ src/manifest/concurrent-policy-util/META-INF/services/ src/net/jini/discovery/ src/net/jini/io/ src/org/apache/river/api/constraint/ src/org/apache/rive...

Author: peter_firmstone
Date: Wed Nov 24 20:58:54 2010
New Revision: 1038815

URL: http://svn.apache.org/viewvc?rev=1038815&view=rev
Log:
Refactoring, getting ready to merge current stable trunk into pepe.

Added:
    incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.impl.security.policy.spi.RevokeableDynamicPolicySpi
      - copied, changed from r1023452, incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/constraint/
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/loader/
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/loader/EndpointCodeSource.java   (with props)
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java
      - copied, changed from r1023452, incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Denied.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/PolicyPermission.java   (with props)
Removed:
    incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Denied.java
Modified:
    incubator/river/jtsk/skunk/pepe/build.xml
    incubator/river/jtsk/skunk/pepe/src/com/sun/jini/discovery/internal/Plaintext.java
    incubator/river/jtsk/skunk/pepe/src/net/jini/discovery/IncomingUnicastResponse.java
    incubator/river/jtsk/skunk/pepe/src/net/jini/io/MarshalledInstance.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrantBuilder.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/cdc/DynamicPolicyProviderImpl.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CodeSourceGrant.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DenyImpl.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java
    incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java
    incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/api/security/PermissionGrantTest.java

Modified: incubator/river/jtsk/skunk/pepe/build.xml
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/build.xml?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/build.xml (original)
+++ incubator/river/jtsk/skunk/pepe/build.xml Wed Nov 24 20:58:54 2010
@@ -847,8 +847,8 @@
             <arg value="-cp"/>
             <arg path="${build.classes.dir}"/>
             <arg value="-files"/>
-            <arg value="org.apache.river.imp.security.policy.se.ConcurrentPolicyFile"/>
-            <arg value="org.apache.river.imp.security.policy.se.DynamicConcurrentPolicyProvider"/>
+            <arg value="org.apache.river.impl.security.policy.se.ConcurrentPolicyFile"/>
+            <arg value="org.apache.river.impl.security.policy.se.DynamicConcurrentPolicyProvider"/>
 	    <arg value="org.apache.river.api.security.DelegatePermission"/>
 	    <arg value="org.apache.river.api.security.InternetSecurityManager"/>
             <arg line="-in org.apache.river"/>
@@ -857,7 +857,7 @@
 	    <arg line="-skip org.apache.river.api.security.PermissionGrant"/>
 	    <arg line="-skip org.apache.river.api.security.PermissionGrantBuilder"/>
 	    <arg line="-skip org.apache.river.api.security.RevokePermission"/>
-            <arg line="-out org.apache.river.imp.security.policy.spi"/>
+            <arg line="-out org.apache.river.impl.security.policy.spi"/>
         </classdep>
         <delete file="${lib-ext.dir}/concurrent-policy-util.jar" quiet="true"/>
         <jar destfile="${lib-ext.dir}/concurrent-policy-util.jar"
@@ -865,7 +865,7 @@
             <fileset dir="${build.classes.dir}" 
                 includesfile="${concurrent-policy-util.deps}"/>
             <fileset dir="${src.manifest.dir}/concurrent-policy-util"
-				 includes="META-INF/services/org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi"/>
+				 includes="META-INF/services/org.apache.river.impl.security.policy.spi.RevokeableDynamicPolicySpi"/>
         </jar>
     </target>
 

Modified: incubator/river/jtsk/skunk/pepe/src/com/sun/jini/discovery/internal/Plaintext.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/com/sun/jini/discovery/internal/Plaintext.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/com/sun/jini/discovery/internal/Plaintext.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/com/sun/jini/discovery/internal/Plaintext.java Wed Nov 24 20:58:54 2010
@@ -460,6 +460,9 @@ public class Plaintext {
 	    // read LUS proxy
 	    MarshalledInstance mi = 
 		(MarshalledInstance) new ObjectInputStream(in).readObject();
+	    /* We have the opportunity to protect against unmarshalling 
+	     * attacks, this is the place to do it.
+	     */
 	    ServiceRegistrar reg = (ServiceRegistrar) mi.get(
 		defaultLoader,
 		verifyCodebaseIntegrity,

Copied: incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.impl.security.policy.spi.RevokeableDynamicPolicySpi (from r1023452, incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi)
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.impl.security.policy.spi.RevokeableDynamicPolicySpi?p2=incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.impl.security.policy.spi.RevokeableDynamicPolicySpi&p1=incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi&r1=1023452&r2=1038815&rev=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi (original)
+++ incubator/river/jtsk/skunk/pepe/src/manifest/concurrent-policy-util/META-INF/services/org.apache.river.impl.security.policy.spi.RevokeableDynamicPolicySpi Wed Nov 24 20:58:54 2010
@@ -16,4 +16,4 @@
 # limitations under the License.
 #*/
 
-org.apache.river.imp.security.policy.se.DynamicConcurrentPolicyProvider
+org.apache.river.impl.security.policy.se.DynamicConcurrentPolicyProvider

Modified: incubator/river/jtsk/skunk/pepe/src/net/jini/discovery/IncomingUnicastResponse.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/net/jini/discovery/IncomingUnicastResponse.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/net/jini/discovery/IncomingUnicastResponse.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/net/jini/discovery/IncomingUnicastResponse.java Wed Nov 24 20:58:54 2010
@@ -26,7 +26,7 @@ import net.jini.core.lookup.ServiceRegis
 /**
  * This class encapsulates the details of unmarshaling an incoming
  * unicast response.
- *
+ * 
  * @author Sun Microsystems, Inc.
  *
  * @see IncomingUnicastRequest

Modified: incubator/river/jtsk/skunk/pepe/src/net/jini/io/MarshalledInstance.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/net/jini/io/MarshalledInstance.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/net/jini/io/MarshalledInstance.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/net/jini/io/MarshalledInstance.java Wed Nov 24 20:58:54 2010
@@ -17,6 +17,7 @@
  */
 package net.jini.io;
 
+import com.sun.jini.proxy.BasicProxyTrustVerifier;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -28,10 +29,36 @@ import java.io.ObjectStreamClass;
 import java.io.ObjectStreamException;
 import java.io.OutputStream;
 import java.io.Serializable;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.ExportException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.jini.constraint.BasicMethodConstraints;
+import net.jini.core.constraint.Confidentiality;
+import net.jini.core.constraint.InvocationConstraint;
+import net.jini.core.constraint.InvocationConstraints;
+import net.jini.export.Exporter;
 import net.jini.io.context.IntegrityEnforcement;
+import net.jini.jeri.BasicJeriExporter;
+import net.jini.jeri.ProxyTrustILFactory;
+import net.jini.jeri.ssl.ConfidentialityStrength;
+import net.jini.jeri.ssl.SslServerEndpoint;
+import net.jini.security.BasicProxyPreparer;
+import net.jini.security.ProxyPreparer;
+import net.jini.security.ProxyPreparer;
+import net.jini.security.TrustVerifier;
+import net.jini.security.proxytrust.ServerProxyTrust;
+import org.apache.river.impl.util.ConcurrentWeakMap;
 
 /*
  * Implementation note: This class uses the helper class
@@ -71,6 +98,42 @@ import net.jini.io.context.IntegrityEnfo
  */
 public class MarshalledInstance implements Serializable {
 
+    /* Change this later to be read from a configuration.
+     */ 
+    private static volatile boolean verifyState = true;
+    
+    /* Hold references to a constructed MarshalledInstance until the object
+     * key is garbage collected.  It may need to hold duplicates if
+     * more than one marshalled instance is created with different annotations.
+     * MarshalledInstance references are typically thrown away soon after 
+     * serialization, so this pool is here to retain a reference to 
+     * the deserialization verifier, while the object it holds hasn't been
+     * garbage collected.
+     * DGC cannot be used since it would pose a Denial Of Service Risk.
+     */ 
+    private static final ConcurrentMap<Object,Cup> pool 
+	    = new ConcurrentWeakMap<Object,Cup>();
+    
+    /* Add an Object key, MarshalledInstance value to the pool if it
+     * doesn't already exist, if it does, return the value in the pool
+     * this will be used to avoid duplicating the exported MD.
+     * Duplicates may exist where the MarshalledInstance is equal but not
+     * fullyEqual.  This prevents an explosion of MarshalledInstance
+     * objects when they are created often.
+     */ 
+    private static MarshalledInstance addToPool(Object o, MarshalledInstance i){
+	Cup c = pool.get(o);
+	if (c == null){
+	    c = new Cup();
+	    Cup existed = pool.putIfAbsent(o, c);
+	    if ( existed != null ){
+		c = existed;
+	    }
+	}
+	MarshalledInstance existed = c.putIfAbsent(i);
+	return existed;
+    }
+    
     /**
      * @serial Bytes of serialized representation.  If <code>objBytes</code> is
      * <code>null</code> then the object marshalled was a <code>null</code>
@@ -92,6 +155,20 @@ public class MarshalledInstance implemen
      */  
     private int hash;
 
+    /**
+     * @serial  MarshalledInstance deserialization authentication and
+     * MessageDigest based verifier, may be null.  The serialized form
+     * is a remote proxy.  The creating JVM has the original remote
+     * object used for authentication and verification.
+     */
+    /* I think the implementation needs a static weak map referencing the
+     * original object, that holds a reference to a MarshalledInstance to
+     * prevent unwanted garbage collection.  When the original object goes
+     * away, so does the MarshalledInstance.
+     */
+    private AuthCheckMDIntegrity authDeserializationMDIntegrityCheck = null;
+    
+
     static final long serialVersionUID = -5187033771082433496L;
     
     /**
@@ -161,6 +238,26 @@ public class MarshalledInstance implemen
 	    h = 31 * h + objBytes[i];
 	}
 	hash = h;
+	createDeserializationIntegrityCheck();
+	MarshalledInstance exists = addToPool(obj, this);
+	if (exists != null){
+	    // we just created a duplicate marshalled instance best we share
+	    // the deserialization check so we don't have to retain too many
+	    // unnecessary strong references.
+	    authDeserializationMDIntegrityCheck 
+		    = exists.authDeserializationMDIntegrityCheck;
+	}
+    }
+    
+    private void createDeserializationIntegrityCheck(){
+	// Should we bomb out, or just leave it without a verifier?
+	try {
+	    authDeserializationMDIntegrityCheck = new IntegrityCheck(objBytes, locBytes, hash ,"SHA");
+	} catch (NoSuchAlgorithmException ex) {
+	    Logger.getLogger(MarshalledInstance.class.getName()).log(Level.SEVERE, null, ex);
+	} catch (ExportException ex) {
+	    Logger.getLogger(MarshalledInstance.class.getName()).log(Level.SEVERE, null, ex);
+	}
     }
 
     /**
@@ -207,6 +304,11 @@ public class MarshalledInstance implemen
 	objBytes = privateMO.objBytes;
 	locBytes = privateMO.locBytes;
 	hash = privateMO.hash;
+	// We shouldn't create a verifier proxy for MarshalledInstance 
+	// created from a MarshalledObject, since the actual object may
+	// not be local, how can we vouch for it if we don't have the
+	// original object?
+//	createDeserializationIntegrityCheck();
     }
     
     /**
@@ -425,13 +527,74 @@ public class MarshalledInstance implemen
     private void readObject(ObjectInputStream in)
 	throws IOException, ClassNotFoundException
     {
+	// This allows backward compatible evolution of serialized form.
 	in.defaultReadObject();
 
 	// If contained object is null, then hash and locBytes must be
 	// proper
 	//
-	if ((objBytes == null) && ((hash != 13) || (locBytes != null)))
+	if ((objBytes == null) && ((hash != 13) || (locBytes != null))) {
 	    throw new InvalidObjectException("Bad hash or annotation");
+	}
+	// Defensive copy mutable arrays.
+	objBytes = objBytes.clone();
+	locBytes = locBytes.clone();
+	// During deserialization we verify the MarshalledInstance using
+	// the proxy, for now until we get some proper tests up and
+	// running, I'm not going to require authentication.
+	// Later this will require authentication and a server
+	// minimum principal.
+	if (authDeserializationMDIntegrityCheck == null && verifyState == true ){
+	    throw new IOException("MarshalledInstance deserialization aborted" +
+		    "unable to verify state, uable to " +
+		    "authenticate or prevent codebase download denial of " +
+		    "service, missing deserialization integrity check proxy");
+	}
+	if (authDeserializationMDIntegrityCheck != null){
+	    ProxyPreparer preparer = new BasicProxyPreparer();
+	    // Don't overwrite proxy reference we might want to serialize it again.
+	    AuthCheckMDIntegrity proxy = (AuthCheckMDIntegrity) preparer.prepareProxy(authDeserializationMDIntegrityCheck);
+	    // Verify state has been transferred successfully.
+	    String algorithm = proxy.getAlgorithm();
+	    MessageDigest md = null;
+	    try{
+		md = MessageDigest.getInstance(algorithm);
+	    } catch (NoSuchAlgorithmException ex) {
+		if (verifyState == true){
+		    throw new IOException("Unable to verify state", ex);
+		} else {
+		    Logger.getLogger(MarshalledInstance.class.getName()).log(
+			    Level.SEVERE, null, ex);
+		}
+	    }
+	    if ( md != null){
+		md.update(objBytes);
+		byte[] objMD = md.digest();
+		md.reset();
+		md.update(locBytes);
+		byte[] locMD = md.digest();
+		if ( Arrays.equals(proxy.getLocMD(), locMD) 
+			&& Arrays.equals(proxy.getObjMD(), objMD)
+			&& hash == proxy.getHashCode()
+		    ) {
+		    // It would now be safe, if we have authenticated the proxy
+		    // with the minimum server principal and confirmed the 
+		    // Codebase annotation is correct, to grant DownloadPermission.
+		    // WE COULD ASSUME THAT DownloadPermission MUST BE GRANTED
+		    // IF DESERIALIZATION HAS BEEN SUCCESSFUL.
+		    // Granting DownloadPermission prevents a trusted service
+		    // from returning another proxy that we don't trust, and
+		    // having it's codebase downloaded automatically.
+		    return;
+		} else {
+		    throw new IOException("MarshalledInstance serial form is corrupt");
+		}
+	    }	
+	}
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException{
+	out.defaultWriteObject();
     }
 
     /**
@@ -601,4 +764,118 @@ public class MarshalledInstance implemen
 	    return super.resolveClass(desc);
 	}
     }
+    
+    interface AuthCheckMDIntegrity {
+	byte [] getLocMD() throws IOException;
+	byte [] getObjMD() throws IOException;
+	String getAlgorithm() throws IOException;
+	int getHashCode() throws IOException;
+}
+    
+    private static class IntegrityCheck implements AuthCheckMDIntegrity,
+	    ServerProxyTrust, Remote, Serializable {
+	private static final long serialVersionUID = 1L;
+	private final byte[] objMD;
+	private final byte[] locMD;
+	private final int hash;
+	private final String algorithm;
+	private final Object proxy;
+	IntegrityCheck(byte[] object, byte[] annotation, int hashCode,
+		String algorithm)  
+		throws NoSuchAlgorithmException, ExportException{
+	    hash = hashCode;
+	    MessageDigest md = MessageDigest.getInstance(algorithm);
+	    md.update(object);
+	    objMD = md.digest();
+	    md.reset();
+	    md.update(annotation);
+	    locMD = md.digest();
+	    this.algorithm = algorithm;
+	    /* We could get the exporter from a configuration, but that would
+	     * risk inadequate Confidentiality, worse, it may keep the vm
+	     * alive while the exporter remains exported, or worse still the
+	     * server may be subject to DOS attacks if DGC is enabled, 
+	     * which is what we're trying to avoid in the first place, 
+	     * since the proxy is used to allow the client to Authenticate 
+	     * the server to prevent DOS attacks in the client, the fix would be
+	     * worse than the original bug.
+	     * 
+	     * I'll add a configuration item later to allow for different 
+	     * secure ServerEndpoint's
+	     * 
+	     * This exported object only remains exported while a strong
+	     * reference is kept to the enclosing MarshalledInstance.  Since
+	     * it is the registrar proxy (reggie) that creates a 
+	     * MarshalledInstance, a reference would need to be maintained in the
+	     * client.
+	     */
+	    Exporter exporter = 
+		new BasicJeriExporter(
+		    SslServerEndpoint.getInstance(0),
+		    new ProxyTrustILFactory(
+			new BasicMethodConstraints(
+			    new InvocationConstraints( 
+				new InvocationConstraint[] { 
+					Confidentiality.YES,
+					ConfidentialityStrength.STRONG 
+				    }, null
+				) //End InvocationConstraints constructor
+			    )//End BasicMethodConstraints constructor
+			    , null
+			)//End ProxyTrustILFactory constructor
+			,false, false
+		    );//End BasiceJeriExporter constructor
+	    proxy = exporter.export(this);    
+	}
+
+	public TrustVerifier getProxyVerifier() throws RemoteException {
+	    return new BasicProxyTrustVerifier(proxy);
+	    //return new ProxyTrustVerifier();
+	}
+
+	public byte[] getLocMD() throws RemoteException {
+	    return locMD;
+	}
+
+	public byte[] getObjMD() throws RemoteException {
+	    return objMD;
+	}
+
+	public String getAlgorithm() throws RemoteException {
+	    return algorithm;
+	}
+
+	public int getHashCode() throws IOException {
+	    return hash;
+	}
+	
+	private Object writeReplace(){
+	    return proxy;
+	}
+	
+	// Prevent an attacker fabricating an instance.
+	private void readObject(ObjectInputStream in) 
+		throws InvalidObjectException{
+	    throw new InvalidObjectException("Proxy Required");
+	}
+	
+    }
+    
+    /* Stores unique marshalled Instance references, as defined by fullyEquals()
+     * duplicates are only added if they are not fullyEqual.
+     */ 
+    private static class Cup {
+	List<MarshalledInstance> items = new ArrayList<MarshalledInstance>(2);
+	MarshalledInstance putIfAbsent(MarshalledInstance t){
+	    synchronized (items){
+		Iterator<MarshalledInstance> it = items.iterator();
+		while (it.hasNext()){
+		   MarshalledInstance i = it.next();
+		   if (t.fullyEquals(i)) return i;
+		}
+		items.add(t);
+		return null;
+	    }
+	}
+    }
 }

Added: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/loader/EndpointCodeSource.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/loader/EndpointCodeSource.java?rev=1038815&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/loader/EndpointCodeSource.java (added)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/loader/EndpointCodeSource.java Wed Nov 24 20:58:54 2010
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.api.loader;
+
+import java.net.URL;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.cert.Certificate;
+import javax.security.auth.Subject;
+import net.jini.jeri.ObjectEndpoint;
+
+/**
+ * This is probably better implemented by a Codebase Service, combined with
+ * a URL Scheme containing an ObjectEndpoint UUID, MessageDigest or a 
+ * signer Certificate.  The filename of the codebase would also be referenced.
+ * @author peter
+ */
+public class EndpointCodeSource extends CodeSource {
+    private static final long serialVersionUID = 1L;
+    private final ObjectEndpoint objEndpoint;
+    
+    public EndpointCodeSource(URL url,
+	    Certificate[] certs, ObjectEndpoint oe){
+	super(url, certs);
+	objEndpoint = oe;
+    }
+    public EndpointCodeSource(URL url, CodeSigner[] signers, ObjectEndpoint oe){
+	super(url, signers);
+	objEndpoint = oe;
+    }
+    
+    @Override
+    public boolean equals(Object o){
+	if (!(o instanceof EndpointCodeSource)) return false;
+	if ( o == this ) return true;
+	if ( o == null ) return false;
+	if ( o.hashCode() != hashCode()) return false;
+	if ( ! super.equals(o)) return false;
+	EndpointCodeSource that = (EndpointCodeSource)o;
+	if ( objEndpoint == that.objEndpoint) return true;
+	if ( objEndpoint != null  
+		&& objEndpoint.equals( that.objEndpoint ) ) return true;
+	return false;
+    }
+
+    /** The subject is not included in the hash code calculation, this is because
+     * it may mutate, from null to some Subject.  The subject is not known
+     * until after Authentication which requires the subject to be later set.
+     * 
+     * This may cause reduced performance in collections.  The subject has been
+     * excluded to retain consistent behaviour in collections.
+     */ 
+    @Override
+    public int hashCode() {
+	int hash = super.hashCode();
+	    hash = 71 * hash;
+	return hash;
+    }
+    
+    /* Other CodesSource may imply this EndpointCodeSource, however this 
+     * EndpointCodeSouce only imply's an identical EndpointCodeSource.
+     */ 
+    @Override
+    public boolean implies(CodeSource o){
+	if ( !(o instanceof EndpointCodeSource) ) return false;
+	if ( ! super.implies(o)) return false;
+	EndpointCodeSource that = (EndpointCodeSource)o;
+	if ( objEndpoint == that.objEndpoint) return true;
+	if ( objEndpoint != null  
+		&& objEndpoint.equals( that.objEndpoint ) ) return true;
+	return false;
+    }
+}

Propchange: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/loader/EndpointCodeSource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java Wed Nov 24 20:58:54 2010
@@ -38,7 +38,7 @@ import org.apache.river.impl.util.Concur
  * calls.
  * 
  * A Security Delegate does not have an interface that identifies it as a Delegate,
- * it is a wrapper class that has the interface or class type, identical, where 
+ * it is a wrapper class that has an identical interface, where 
  * practical, to the object it encapsulates, to discuise it from clients.
  * 
  * Security Delegates enable sensitive objects to be used by code that isn't

Copied: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java (from r1023452, incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Denied.java)
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java?p2=incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java&p1=incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Denied.java&r1=1023452&r2=1038815&rev=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Denied.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Exclusion.java Wed Nov 24 20:58:54 2010
@@ -22,22 +22,22 @@ import java.security.Permission;
 import java.security.ProtectionDomain;
 
 /**
- * A Denied implementation must be immutable, it will be accessed by concurrent
+ * A Exclusion 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 ProtectionDomain on any grounds, but it must be
+ * The implementation may exclude a ProtectionDomain on any grounds, but it must be
  * consistent and return the same result on every occassion.
  * 
- * Denied will be used in combination with a PermissionGrant based on
- * Code signer Certificate's to deny individual CodeSource's or URL's with
+ * Exclusion will be used in combination with a PermissionGrant based on
+ * Code signer Certificate's to exclude individual CodeSource's or URL's with
  * known vulnerabilities.
  * 
  * @author Peter Firmstone
  */
-public interface Denied {
+public interface Exclusion {
     /**
-     * Denied is used by a PermissionGrantBuilder, to filter out unwanted
+     * Exclusion is used by a PermissionGrantBuilder, to filter out unwanted
      * ProtectionDomain implies based on any set of conditions.  This is useful
      * for a PermissionGrant that generically grant's for one 
      * 
@@ -45,5 +45,5 @@ public interface Denied {
      * @param perm may be null;
      * @return
      */
-    public boolean allow(ProtectionDomain pd);
+    public boolean allows(ProtectionDomain pd);
 }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrantBuilder.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrantBuilder.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrantBuilder.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/PermissionGrantBuilder.java Wed Nov 24 20:58:54 2010
@@ -61,6 +61,10 @@ public interface PermissionGrantBuilder 
     /**
      * The PermissionGrant generated will apply to all classes loaded from
      * CodeSource's that have at a minimum the defined array Certificate[]
+     * 
+     * Note:  This isn't necessary if Certificates are passed in without
+     * a CodeSource.  The type of grant can be determined by the parameters
+     * which have been set.
      */
     public static final int CODESOURCE_CERTS = 3;
     
@@ -82,7 +86,7 @@ public interface PermissionGrantBuilder 
     
     public abstract PermissionGrantBuilder permissions(Permission[] perm);
 
-    public abstract PermissionGrantBuilder deny(Denied denial);
+    public abstract PermissionGrantBuilder exclude(Exclusion e);
     
     public abstract PermissionGrant build();
 }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/cdc/DynamicPolicyProviderImpl.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/cdc/DynamicPolicyProviderImpl.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/cdc/DynamicPolicyProviderImpl.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/cdc/DynamicPolicyProviderImpl.java Wed Nov 24 20:58:54 2010
@@ -46,7 +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.Exclusion;
 import org.apache.river.api.security.PermissionGrant;
 import org.apache.river.api.security.PermissionGrantBuilder;
 import org.apache.river.impl.security.policy.spi.RevokeableDynamicPolicySpi;

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/DynamicConcurrentPolicyProvider.java Wed Nov 24 20:58:54 2010
@@ -266,8 +266,27 @@ public class DynamicConcurrentPolicyProv
 	 * to prevent them becoming part of the static permissions held
 	 * by a ProtectionDomain. In this case during the merge operation
 	 * performed by the ProtectionDomain.
+	 * 
+	 * However we add Permission's wrapped in a PolicyPermission for
+	 * holding dynamic Permissions to print debuggin information using toString
+	 * PolicyPermission doesn't imply anything useful, it's just a
+	 * container.
 	 */
-        return basePolicy.getPermissions(domain);
+        PermissionCollection pc = basePolicy.getPermissions(domain);
+	PermissionGrant [] grantsRefCopy = pGrants; // Interim updates not seen.
+	int l = grantsRefCopy.length;
+	for ( int i = 0; i < l; i++ ){
+	    if ( grantsRefCopy[i].implies(domain) ){
+		// Only use the trusted grantCache.
+		Permission[] perm = grantCache.get(grantsRefCopy[i]);
+		int s = perm.length;
+		for ( int j = 0; j < s; j++){
+		    PolicyPermission pp = new PolicyPermission(perm[j]);
+		    pc.add(pp);
+		}
+	    }
+	}
+	return pc;	
     }
     
     /* River-26 Mark Brouwer suggested making UmbrellaPermission's expandable
@@ -287,7 +306,7 @@ public class DynamicConcurrentPolicyProv
     public boolean implies(ProtectionDomain domain, Permission permission) {
         if (initialized == false) throw new RuntimeException("Object not initialized");
         if (basePolicyIsDynamic){
-            // Total delegation revoke and deny supported only by underlying policy.
+            // Total delegation revoke and exclude supported only by underlying policy.
             return basePolicy.implies(domain, permission);
         }
 	if (permission == null) throw new NullPointerException("permission not allowed to be null");

Added: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/PolicyPermission.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/PolicyPermission.java?rev=1038815&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/PolicyPermission.java (added)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/se/PolicyPermission.java Wed Nov 24 20:58:54 2010
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.river.impl.security.policy.se;
+
+import java.security.Permission;
+
+/**
+ * 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.
+ * 
+ * @author Peter Firmstone.
+ */
+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){
+	    if ( 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 "Policy: " + perm.toString();
+    }
+
+    @Override
+    public String getActions() {
+	return "";
+    }
+
+}

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

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CertificateGrant.java Wed Nov 24 20:58:54 2010
@@ -29,21 +29,20 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import org.apache.river.api.security.Denied;
-import org.apache.river.impl.security.policy.util.DenyImpl;
+import org.apache.river.api.security.Exclusion;
 
 /**
  *
  * @author Peter Firmstone.
  */
-class CertificateGrant extends CodeSourceGrant {
+class CertificateGrant extends PrincipalGrant {
     private final Collection<Certificate> certs;
     private final int hashCode;
-    private final Denied denied;
+    private final Exclusion exclusion;
     @SuppressWarnings("unchecked")
-    CertificateGrant(Certificate[] codeSourceCerts, Principal[] pals, Permission[] perms, Denied deny){
-        super(null, pals, perms);
-        denied = deny;
+    CertificateGrant(Certificate[] codeSourceCerts, Principal[] pals, Permission[] perms, Exclusion deny){
+        super(pals, perms);
+        exclusion = deny;
          if (codeSourceCerts == null || codeSourceCerts.length == 0) {
             certs = Collections.EMPTY_SET;
         }else{
@@ -76,11 +75,12 @@ class CertificateGrant extends CodeSourc
     
     @Override
     public boolean implies(ProtectionDomain pd) {
-        if ( denied.allow(pd)){
-            Certificate[] c = null;
+	if ( !super.implies(pd)) return false;
+        if ( exclusion.allows(pd)){
+            CodeSource c = null;
             Principal[] pals = null;
             if (pd != null){
-                c = pd.getCodeSource().getCertificates();
+                c = pd.getCodeSource();
                 pals = pd.getPrincipals();
             }
             return implies(c, pals);
@@ -88,19 +88,20 @@ class CertificateGrant extends CodeSourc
         return false;
     }
     
+    // Subclasses shouldn't call this if 
     @Override
-    protected boolean impliesCertificates(Certificate[] signers){
-        if ( certs.isEmpty() ) return true;
-        if ( signers == null || signers.length == 0 ) return false;
-        List<Certificate> certificates = Arrays.asList(signers);
-        return certificates.containsAll(certs);
+    public boolean implies(ClassLoader cl, Principal[] p){
+	if ( !implies(p)) return false;
+	if ( certs.isEmpty() ) return true;
+	if ( cl == null ) return false;
+	return false;  //Indeterminate.
     }
     
-    @Override
-    protected boolean impliesCodeSource(CodeSource codeSource) {
-        if ( certs.isEmpty()) return true;
-        if (codeSource == null) return false;
-        List<Certificate> certificates = Arrays.asList(codeSource.getCertificates());
+    public boolean implies(CodeSource codeSource, Principal[] p) {
+        if ( !super.implies(codeSource, p)) return false;
+	if ( certs.isEmpty() ) return true;
+	Certificate[] signers = codeSource.getCertificates();
+	List<Certificate> certificates = Arrays.asList(signers);
         return certificates.containsAll(certs);
     }
     

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CodeSourceGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CodeSourceGrant.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CodeSourceGrant.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/CodeSourceGrant.java Wed Nov 24 20:58:54 2010
@@ -22,24 +22,20 @@ import org.apache.river.api.security.Per
 import java.security.CodeSource;
 import java.security.Permission;
 import java.security.Principal;
-import java.security.ProtectionDomain;
-import java.security.cert.Certificate;
-import java.util.Arrays;
-import java.util.List;
-import org.apache.river.impl.security.policy.util.DenyImpl;
+import org.apache.river.api.security.Exclusion;
 
 /**
  *
  * @author Peter Firmstone
  */
-class CodeSourceGrant extends PrincipalGrant {
+class CodeSourceGrant extends CertificateGrant {
     private final CodeSource cs;
     private final int hashCode;
     
     @SuppressWarnings("unchecked")
-    CodeSourceGrant(CodeSource cs, Principal[] pals, Permission[] perm){
-        super(pals, perm);
-        this.cs = normalizeCodeSource(cs);
+    CodeSourceGrant(CodeSource cs, Principal[] pals, Permission[] perm, Exclusion exclusion){
+        super( cs != null? cs.getCertificates(): null, pals, perm, exclusion);
+        this.cs = cs != null? normalizeCodeSource(cs) : null;
         int hash = 3;
         hash = 67 * hash + (this.cs != null ? this.cs.hashCode() : 0);
         hash = 67 * hash + (super.hashCode());
@@ -59,7 +55,10 @@ class CodeSourceGrant extends PrincipalG
         if (o instanceof CodeSourceGrant){
             CodeSourceGrant c = (CodeSourceGrant) o;
             if ( !super.equals(o)) return false;
-            if (cs.equals(c.cs)) return true;
+	    if ( cs == c.cs) return true;
+	    if ( cs != null ) {
+		if (cs.equals(c.cs)) return true;
+	    }
         }
         return false;
     }
@@ -69,45 +68,12 @@ class CodeSourceGrant extends PrincipalG
      * PermissionGrant implies any CodeSource; non-null CodeSource forwards to its
      * imply() method.
      */
-    protected boolean impliesCodeSource(CodeSource codeSource) {
-        if (cs == null) return true;
-        if (codeSource == null) return false;       
-        return cs.implies(normalizeCodeSource(codeSource));
-    }
-    
-    // This is only here for user comparisons
-    protected boolean impliesProtectionDomain(ProtectionDomain pd){
-        CodeSource codeSource = null;
-        if (pd != null){
-            codeSource = pd.getCodeSource();
-        }
-        return impliesCodeSource(codeSource);
-    }
-    
-    // This is only here for user comparisons
-    protected boolean impliesClassLoader(ClassLoader cl) {
-        if ( cs == null ) return true;      
-        return false;  //Indeterminate.
-    }
-    
-    // This is only here for user comparisons
-    protected boolean impliesCertificates(Certificate[] signers){
-        Certificate[] certs = cs.getCertificates();
-        if ( certs.length == 0 ) return true;
-        if ( signers == null || signers.length == 0 ) return false;
-        List<Certificate> certificates = Arrays.asList(signers);
-        return certificates.containsAll(Arrays.asList(certs));
-    }
-    
-    // This is the real deal, the Policy utilises this.
-    public boolean implies(ProtectionDomain pd) {
-        CodeSource codeSource = null;
-        Principal[] pals = null;
-        if (pd != null){
-            codeSource = pd.getCodeSource();
-            pals = pd.getPrincipals();
-        }
-        return implies(codeSource, pals);
+    @Override
+    public boolean implies(CodeSource codeSource, Principal[] p) {
+        if ( !implies(p)) return false;
+	if ( cs == null ) return true;
+	if ( codeSource == null ) return false;
+	return cs.implies(normalizeCodeSource(codeSource));
     }
 
     @Override

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DenyImpl.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DenyImpl.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DenyImpl.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/DenyImpl.java Wed Nov 24 20:58:54 2010
@@ -44,14 +44,14 @@ import org.apache.river.impl.security.po
  * 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.
+ * Exclusion does not allow any permission, only Exclusion.
  * 
  * This class may be extended. The caller must have a DenyPermission before it
  * can be added to a PermissionGrantBuilder.
  *
  * @author Peter Firmstone
  */
-public class DenyImpl implements Denied {
+public class DenyImpl implements Exclusion {
     private final List<URL> uri;
     private final List<CodeSource> code;
     
@@ -78,7 +78,7 @@ public class DenyImpl implements Denied 
         return code;
     }
     
-    public boolean allow(ProtectionDomain pd){
+    public boolean allows(ProtectionDomain pd){
         CodeSource cs = pd.getCodeSource();
         cs = normalizeCodeSource(cs);
         if (code.contains(cs)) return false;

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PermissionGrantBuilderImp.java Wed Nov 24 20:58:54 2010
@@ -18,7 +18,7 @@
 
 package org.apache.river.impl.security.policy.util;
 
-import org.apache.river.api.security.Denied;
+import org.apache.river.api.security.Exclusion;
 import org.apache.river.api.security.PermissionGrantBuilder;
 import java.lang.ref.WeakReference;
 import java.security.CodeSource;
@@ -40,7 +40,7 @@ public class PermissionGrantBuilderImp i
     private Principal[] principals;
     private Permission[] permissions;
     private int context;
-    private Denied deny;
+    private Exclusion deny;
     
     public PermissionGrantBuilderImp() {
         super();
@@ -123,7 +123,7 @@ public class PermissionGrantBuilderImp i
             case CLASSLOADER:
                 return new ClassLoaderGrant(domain, principals, permissions );
             case CODESOURCE:
-                return new CodeSourceGrant(cs, principals, permissions );
+                return new CodeSourceGrant(cs, principals, permissions ,null );
             case CODESOURCE_CERTS:
                 return new CertificateGrant(certs, principals, permissions, deny );
             case PROTECTIONDOMAIN:
@@ -133,7 +133,7 @@ public class PermissionGrantBuilderImp i
         }
     }
 
-    public PermissionGrantBuilder deny(Denied denial) {
+    public PermissionGrantBuilder exclude(Exclusion denial) {
         deny = denial;
         return this;
     }

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/PrincipalGrant.java Wed Nov 24 20:58:54 2010
@@ -26,8 +26,6 @@ import java.security.Permission;
 import java.security.Principal;
 import java.security.ProtectionDomain;
 import java.security.acl.Group;
-import java.security.cert.Certificate;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -41,12 +39,12 @@ import org.apache.river.api.security.Per
  *
  * @author Peter Firmstone.
  */
-abstract class PrincipalGrant implements PermissionGrant {
+class PrincipalGrant implements PermissionGrant {
     private final Set<Principal> principals;
     private final int hashCode;
     private final Set<Permission> permissions;
     @SuppressWarnings("unchecked")
-    protected PrincipalGrant(Principal[] pals, Permission[] perm){
+    PrincipalGrant(Principal[] pals, Permission[] perm){
         if ( pals != null ){
 	    Set<Principal> palCol = new HashSet<Principal>(pals.length);
             palCol.addAll(Arrays.asList(pals));
@@ -85,7 +83,7 @@ abstract class PrincipalGrant implements
         return hashCode;
     }
         
-    protected boolean implies(Principal[] prs) {
+    boolean implies(Principal[] prs) {
         if ( principals.isEmpty()) return true;
         if ( prs == null || prs.length == 0 ) return false;
         // PermissionGrant Principals match if equal or if they are Groups and
@@ -142,7 +140,7 @@ abstract class PrincipalGrant implements
      * @param codeSource
      * @return
      */    
-    protected CodeSource normalizeCodeSource(CodeSource codeSource) {
+    CodeSource normalizeCodeSource(CodeSource codeSource) {
         if (codeSource == null ) return null;
         URL codeSourceURL = PolicyUtils.normalizeURL(codeSource.getLocation());
         CodeSource result = codeSource;
@@ -160,30 +158,22 @@ abstract class PrincipalGrant implements
         return result;
     } 
     
-    public boolean implies(ProtectionDomain pd, Principal[] pal) {
-        return impliesProtectionDomain(pd) && implies(pal);
+    public boolean implies(ProtectionDomain pd) {
+	if (pd == null) return false;
+	if (principals.isEmpty()) return true;
+	Principal[] hasPrincipals = pd.getPrincipals();
+	return implies(hasPrincipals);
     }
     
     public boolean implies(ClassLoader cl, Principal[] pal) {
-        return impliesClassLoader(cl) && implies(pal);
+	// A null ClassLoader indicates the system domain.
+        return implies(pal);
     }
 
     public boolean implies(CodeSource codeSource, Principal[] pal) {
-        return impliesCodeSource(codeSource) && implies(pal);
+	return implies(pal);
     }
 
-    public boolean implies(Certificate[] certs, Principal[] pal) {
-        return impliesCertificates(certs) && implies(pal);
-    }
-    
-    protected abstract boolean impliesProtectionDomain(ProtectionDomain pd);
-
-    protected abstract boolean impliesCertificates(Certificate[] certs);
-
-    protected abstract boolean impliesClassLoader(ClassLoader cl);
-
-    protected abstract boolean impliesCodeSource(CodeSource codeSource);
-
     public PermissionGrantBuilder getBuilderTemplate() {
         PermissionGrantBuilder pgb = new PermissionGrantBuilderImp();
         pgb.principals(principals.toArray(new Principal[principals.size()]))

Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/impl/security/policy/util/ProtectionDomainGrant.java Wed Nov 24 20:58:54 2010
@@ -74,7 +74,16 @@ class ProtectionDomainGrant extends Prin
     }
     
     public boolean implies(ProtectionDomain pd){
-        return implies(pd, pd.getPrincipals());
+        return impliesProtectionDomain(pd) && implies(pd.getPrincipals());
+	
+    }
+    
+    public boolean implies(ClassLoader cl, Principal[] pal) {
+        return impliesClassLoader(cl) && implies(pal);
+    }
+
+    public boolean implies(CodeSource codeSource, Principal[] pal) {
+        return impliesCodeSource(codeSource) && implies(pal);
     }
     
     /*
@@ -84,7 +93,7 @@ class ProtectionDomainGrant extends Prin
      * CodeSource, in case of new PermissionDomain's created by a DomainCombiner
      */   
     // for grant
-    public boolean impliesProtectionDomain(ProtectionDomain pd) {
+    private boolean impliesProtectionDomain(ProtectionDomain pd) {
         // ProtectionDomain comparison
         if (hasDomain == false) return true;
         if (pd == null) return false;       
@@ -99,7 +108,7 @@ class ProtectionDomainGrant extends Prin
 
     // This is here for revoke and for new ProtectionDomain's created by the
     // DomainCombiner such as those in the SubjectDomainCombiner.
-    protected boolean impliesClassLoader(ClassLoader cl) {
+    private boolean impliesClassLoader(ClassLoader cl) {
         if (hasDomain == false) return true;
         if (cl == null) return false;       
         if (domain.get() == null ) return false; // hasDomain already true
@@ -107,7 +116,7 @@ class ProtectionDomainGrant extends Prin
     }
     // This is here for revoke and for new ProtectionDomain's created by the
     // DomainCombiner such as those in the SubjectDomainCombiner.
-    protected boolean impliesCodeSource(CodeSource codeSource) {
+    private boolean impliesCodeSource(CodeSource codeSource) {
         ProtectionDomain pd = domain.get();
         if (pd == null) return true;
         CodeSource cs = normalizeCodeSource(pd.getCodeSource());
@@ -115,16 +124,6 @@ class ProtectionDomainGrant extends Prin
         if (codeSource == null) return false;       
         return cs.implies(normalizeCodeSource(codeSource));
     }
-    
-    protected boolean impliesCertificates(Certificate[] signers){
-        ProtectionDomain pd = domain.get();
-        if (pd == null) return true;
-        List<Certificate> certs = Arrays.asList(pd.getCodeSource().getCertificates());
-        if ( certs.isEmpty()) return true;
-        if ( signers == null || signers.length == 0 ) return false;
-        List<Certificate> certificates = Arrays.asList(signers);
-        return certificates.containsAll(certs);    
-    }
 
     @Override
     public boolean isVoid() {        

Modified: incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/api/security/PermissionGrantTest.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/api/security/PermissionGrantTest.java?rev=1038815&r1=1038814&r2=1038815&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/api/security/PermissionGrantTest.java (original)
+++ incubator/river/jtsk/skunk/pepe/test/src/org/apache/river/api/security/PermissionGrantTest.java Wed Nov 24 20:58:54 2010
@@ -29,6 +29,8 @@ import java.security.cert.Certificate;
 import java.security.CodeSource;
 import java.security.Principal;
 
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import org.apache.river.api.security.PermissionGrant;
 import org.apache.river.api.security.PermissionGrantBuilder;
 import org.apache.river.impl.security.policy.util.PermissionGrantBuilderImp;
@@ -45,11 +47,20 @@ public class PermissionGrantTest {
             cs32, cs33;
     PermissionGrant pe0, pe10, pe11, pe12, pe13, pe20, pe21, pe22, pe23, pe30,
             pe31, pe32, pe33;
+    CertificateFactory cf;
+    Certificate[] certs1, certs2;
     
-    public PermissionGrantTest(){}
+    public PermissionGrantTest(){
+	
+    }
     
     @Before
     public void setUp() throws MalformedURLException {
+	try {
+	    cf = CertificateFactory.getInstance("X.509");
+	} catch ( CertificateException e) {
+	    cf = null;
+	}
         pgb = new PermissionGrantBuilderImp();
         cs0  = new CodeSource(null, (Certificate[]) null);
         cs10 = new CodeSource(new URL("file:"), (Certificate[]) null);