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/09/29 23:14:40 UTC
svn commit: r1002846 - in /incubator/river/jtsk/skunk/pepe: ./
src/org/apache/river/api/delegates/ src/org/apache/river/api/security/
src/org/apache/river/imp/security/policy/se/
src/org/apache/river/imp/security/policy/util/
Author: peter_firmstone
Date: Wed Sep 29 21:14:40 2010
New Revision: 1002846
URL: http://svn.apache.org/viewvc?rev=1002846&view=rev
Log:
Add FileOutputStream delegate
Modified:
incubator/river/jtsk/skunk/pepe/build.xml
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileInputStream.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileOutputStream.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/InternetSecurityManager.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/util/PolicyUtils.java
Modified: incubator/river/jtsk/skunk/pepe/build.xml
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/build.xml?rev=1002846&r1=1002845&r2=1002846&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/build.xml (original)
+++ incubator/river/jtsk/skunk/pepe/build.xml Wed Sep 29 21:14:40 2010
@@ -849,8 +849,14 @@
<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.api.security.DelegatePermission"/>
+ <arg value="org.apache.river.api.security.InternetSecurityManager"/>
<arg line="-in org.apache.river"/>
- <arg line="-out org.apache.river.api"/>
+ <arg line="-skip org.apache.river.api.security.RevokeableDynamicPolicy"/>
+ <arg line="-skip org.apache.river.api.security.Denied"/>
+ <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"/>
</classdep>
<delete file="${lib-ext.dir}/concurrent-policy-util.jar" quiet="true"/>
Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileInputStream.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileInputStream.java?rev=1002846&r1=1002845&r2=1002846&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileInputStream.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileInputStream.java Wed Sep 29 21:14:40 2010
@@ -43,7 +43,7 @@ public class FileInputStream extends jav
private final java.io.FileInputStream in;
public FileInputStream(final String name) throws FileNotFoundException {
Permission p = new FilePermission(name, SecurityConstants.FILE_READ_ACTION);
- g = new DelegatePermission(p);
+ g = DelegatePermission.get(p);
java.io.FileInputStream input = null;
try {
// Permission check is delayed.
@@ -62,7 +62,7 @@ public class FileInputStream extends jav
public FileInputStream(final File file) throws FileNotFoundException {
Permission p = new FilePermission(file.getPath(),
SecurityConstants.FILE_READ_ACTION);
- g = new DelegatePermission(p);
+ g = DelegatePermission.get(p);
java.io.FileInputStream input = null;
try {
input = AccessController.doPrivileged(
@@ -78,7 +78,7 @@ public class FileInputStream extends jav
}
public FileInputStream(final FileDescriptor fdObj) {
- g = new DelegatePermission(new RuntimePermission("readFileDescriptor"));
+ g = DelegatePermission.get(new RuntimePermission("readFileDescriptor"));
in = AccessController.doPrivileged(new PrivilegedAction<java.io.FileInputStream>() {
public java.io.FileInputStream run() {
return new java.io.FileInputStream(fdObj);
Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileOutputStream.java?rev=1002846&r1=1002845&r2=1002846&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileOutputStream.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/delegates/FileOutputStream.java Wed Sep 29 21:14:40 2010
@@ -37,7 +37,7 @@ import sun.security.util.SecurityConstan
/**
* <p>This is a simple FileOutputStream delegate to replace a java.io.FileOutputStream
- * in code that is downloaded and trust is not assurred.
+ * in code that is downloaded where trust is not assurred.
* </p><p>
* The client must have a DelegatePermission representing a FilePermission, or
* a FilePermission, the
@@ -58,7 +58,7 @@ public class FileOutputStream extends Ou
public FileOutputStream(final String name, final boolean append)
throws FileNotFoundException {
Permission p = new FilePermission(name, SecurityConstants.FILE_READ_ACTION);
- g = new DelegatePermission(p);
+ g = DelegatePermission.get(p);
java.io.FileOutputStream output = null;
try {
// Permission check is delayed.
@@ -83,7 +83,7 @@ public class FileOutputStream extends Ou
public FileOutputStream(final File file, final boolean append) throws FileNotFoundException {
Permission p = new FilePermission(file.getPath(),
SecurityConstants.FILE_READ_ACTION);
- g = new DelegatePermission(p);
+ g = DelegatePermission.get(p);
java.io.FileOutputStream output = null;
try {
output = AccessController.doPrivileged(
@@ -104,7 +104,7 @@ public class FileOutputStream extends Ou
}
public FileOutputStream(final FileDescriptor fdObj) {
- g = new DelegatePermission(new RuntimePermission("readFileDescriptor"));
+ g = DelegatePermission.get(new RuntimePermission("readFileDescriptor"));
out = AccessController.doPrivileged(new PrivilegedAction<java.io.FileOutputStream>() {
public java.io.FileOutputStream run() {
return new java.io.FileOutputStream(fdObj);
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=1002846&r1=1002845&r2=1002846&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 Sep 29 21:14:40 2010
@@ -18,6 +18,9 @@
package org.apache.river.api.security;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
@@ -25,6 +28,8 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.river.imp.util.ConcurrentWeakMap;
/**
* A DelegatePermission represents any another Permission, called the candidate.
@@ -33,8 +38,8 @@ import java.util.Set;
* 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 to
- * the object it encapsulates, to discuise it from clients.
+ * it is a wrapper class that has the interface or class type, identical, 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
* fully trusted and may want to monitor, such as a
@@ -45,7 +50,7 @@ import java.util.Set;
*
* A DelegatePermission never implies it's candidate, however if a
* ProtectionDomain has the Permission the delegate represents, then the
- * AccessControlDelegate, which a Security Delegate must utilise,
+ * InternetSecurityManager, which a Security Delegate must utilise,
* must ensure that it is also checked.
*
* The DelegatePermissionCollection returned by newPermissionCollection() is not
@@ -56,19 +61,52 @@ import java.util.Set;
* in this case, existing PermissionCollection implementatations don't cleanly
* protect their internal state with synchronization, since the Enumeration
* returned by elements() will throw a ConcurrentModificationException if in a
- * loop when Permission's are being added to a PermissionCollection.
+ * loop when Permission's are being added to a PermissionCollection. In this
+ * case external synchronization must be used.
*
* PermissionCollection's are used mostly read only.
*
+ * Serialization has been implemented so the implementation is not
+ * tied to the serialized form, instead serialization proxy's are used.
+ *
* @author Peter Firmstone
*/
-public class DelegatePermission extends Permission{
+public final class DelegatePermission extends Permission{
private static final long serialVersionUID = 1L;
+ /* Object Pool ensures that equals performs very well in collections for
+ * optimum AccessControlContext result caching and minimises memory
+ * consumption.
+ */
+ private static final ConcurrentMap<Permission,DelegatePermission> instances
+ = new ConcurrentWeakMap<Permission,DelegatePermission>();
+ /**
+ * Factory method to obtain a DelegatePermission
+ * @param p Permission to be represented.
+ * @return DelegatePermission
+ */
+ public static Permission get(Permission p){
+ DelegatePermission del = instances.get(p);
+ if ( del == null ){
+ del = new DelegatePermission(p);
+ DelegatePermission existed = instances.putIfAbsent(p, del);
+ if ( existed != null ){
+ del = existed;
+ }
+ }
+ return del;
+ }
+
private final Permission permission;
+ private final transient int hashCode;
+ /* The following null reference is for IDE code completion only */
+ private transient Permission perm = null;
- public DelegatePermission(Permission p){
+ private DelegatePermission(Permission p){
super(p.getClass().toString() + " " + p.getName());
permission = p;
+ int hash = 5;
+ hash = 41 * hash + (this.permission != null ? this.permission.hashCode() : 0);
+ hashCode = hash;
}
@Override
@@ -87,15 +125,15 @@ public class DelegatePermission extends
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null) return false;
+ if ( obj.hashCode() != hashCode ) return false;
if (!(obj instanceof DelegatePermission)) return false;
+ if ( obj.getClass() != this.getClass() ) return false;
return permission.equals(((DelegatePermission) permission).getPermission());
}
@Override
public int hashCode() {
- int hash = 5;
- hash = 41 * hash + (this.permission != null ? this.permission.hashCode() : 0);
- return hash;
+ return hashCode;
}
@Override
@@ -108,10 +146,40 @@ public class DelegatePermission extends
return new DelegatePermissionCollection();
}
+ /* Serialization Proxy */
+ private static class SerializationProxy implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private Permission perm;
+
+ SerializationProxy(Permission p){
+ perm = p;
+ }
+
+ }
+
+ /* Serialization */
+
+ private Object writeReplace() {
+ return new SerializationProxy(permission);
+ }
+
+ private void readObject(ObjectInputStream in) throws InvalidObjectException{
+ throw new InvalidObjectException("Proxy required");
+ }
+
+ private Object readResolve() {
+ // perm is the field from the Serialization proxy.
+ return get(perm);
+ }
+
+ /* PermissionCollection */
+
private static class DelegatePermissionCollection extends PermissionCollection {
private static final long serialVersionUID = 1L;
- private final PermissionCollection candidates;
+ private final transient PermissionCollection candidates;
private final Set<Permission> delegates;
+ /* IDE code completion for serialization proxy */
+ private transient Permission[] perms = null;
DelegatePermissionCollection(){
candidates = new Permissions();
@@ -143,6 +211,37 @@ public class DelegatePermission extends
return Collections.enumeration(delegates);
}
+ /* Serialization Proxy */
+ private static class CollectionSerializationProxy implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private Permission[] perms;
+
+ CollectionSerializationProxy(Set<Permission> p){
+ perms = p.toArray(new Permission[p.size()]);
+ }
+
+ }
+
+ /* Serialization */
+
+ private Object writeReplace() {
+ return new CollectionSerializationProxy(delegates);
+ }
+
+ private void readObject(ObjectInputStream in) throws InvalidObjectException{
+ throw new InvalidObjectException("Proxy required");
+ }
+
+ private Object readResolve() {
+ // perms is the field from the Serialization proxy.
+ DelegatePermissionCollection dpc = new DelegatePermissionCollection();
+ int l = perms.length;
+ for (int i = 0; i < l; i++ ){
+ dpc.add(perms[i]);
+ }
+ return dpc;
+ }
+
}
}
Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/InternetSecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/InternetSecurityManager.java?rev=1002846&r1=1002845&r2=1002846&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/InternetSecurityManager.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/InternetSecurityManager.java Wed Sep 29 21:14:40 2010
@@ -58,7 +58,7 @@ import org.apache.river.imp.util.Concurr
*/
public class InternetSecurityManager extends SecurityManager {
- private final ConcurrentMap<AccessControlContext,DelegateContextCheck> checks;
+ private final ConcurrentMap<AccessControlContext,ExecutionContextChecks> checks;
private final ReadWriteLock revokeLock;
private final Lock rl; // This lock is held briefly by callers of begin and end.
private final Lock wl; // This lock is held by revocation.
@@ -89,7 +89,7 @@ public class InternetSecurityManager ext
/* This checks adequate permission is held */
super();
/* Previous checks */
- checks = new ConcurrentSoftMap<AccessControlContext,DelegateContextCheck>(40);
+ checks = new ConcurrentSoftMap<AccessControlContext,ExecutionContextChecks>(40);
/* This lock guards revocation, although if Permission has already
* been removed from the policy then this lock isn't really necessary
*/
@@ -110,9 +110,9 @@ public class InternetSecurityManager ext
permClasses.add(itp.next().getClass());
}
// Remove Permission's and AccessControlContexts from the checked cache.
- Iterator<DelegateContextCheck> checkIt = checks.values().iterator();
+ Iterator<ExecutionContextChecks> checkIt = checks.values().iterator();
while (checkIt.hasNext()){
- DelegateContextCheck c = checkIt.next();
+ ExecutionContextChecks c = checkIt.next();
Iterator<Class> it = permClasses.iterator();
while (it.hasNext()){
c.removePermission(it.next());
@@ -140,10 +140,10 @@ public class InternetSecurityManager ext
try {
// checkedCache - the permission check, fast for repeated calls.
//Set<AccessControlContext> checked = checkedCache.get(perm);
- DelegateContextCheck checked = checks.get(executionContext);
+ ExecutionContextChecks checked = checks.get(executionContext);
if (checked == null ){
- checked = new DelegateContextCheck(executionContext);
- DelegateContextCheck existed =
+ checked = new ExecutionContextChecks(executionContext);
+ ExecutionContextChecks existed =
checks.putIfAbsent(executionContext, checked);
if (existed != null){
checked = existed;
@@ -155,13 +155,13 @@ public class InternetSecurityManager ext
}
}
- private static class DelegateContextCheck {
+ private static class ExecutionContextChecks {
private final AccessControlContext acc;
private final ConcurrentMap<Class,Set<Permission>> passed;
// The context is only consulted directly for DelegatePermission
private final ProtectionDomain[] context;
- DelegateContextCheck(final AccessControlContext acc){
+ ExecutionContextChecks(final AccessControlContext acc){
this.acc = acc;
passed = new ConcurrentHashMap<Class,Set<Permission>>();
/* If context is null for whatever reason, then the AccessControlContext
Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java?rev=1002846&r1=1002845&r2=1002846&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java Wed Sep 29 21:14:40 2010
@@ -175,11 +175,6 @@ 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;
grantLock = new Object();
SecurityManager s = System.getSecurityManager();
if (s == null) {
@@ -235,14 +230,8 @@ public class DynamicConcurrentPolicyProv
// Investigate bug 4911907, do we need to do anything more here? Is this sufficient.
if (sysDomain == null ) System.out.println("System Domain is null");
implies(sysDomain, new AllPermission());
- //PermissionCollection pc = getPermissions(sysDomain);
- //pc = PolicyUtils.toConcurrentPermissionsCopy(pc);
- //cache.putIfAbsent(sysDomain, pc);
ProtectionDomain own = this.getClass().getProtectionDomain();
implies(own, new AllPermission());
- //PermissionCollection mypc = getPermissions(own);
- //mypc = PolicyUtils.toConcurrentPermissionsCopy(mypc);
- //cache.putIfAbsent(own, mypc);
new GrantPermission(new UmbrellaGrantPermission());
}
@@ -263,11 +252,21 @@ public class DynamicConcurrentPolicyProv
public PermissionCollection getPermissions(CodeSource codesource) {
if (initialized == false) throw new RuntimeException("Object not initialized");
+ /* It is extremely important that dynamic grant's are not returned,
+ * to prevent them becoming part of the static permissions held
+ * by a ProtectionDomain. In this case during construction of a
+ * ProtectionDomain. Static Permissions are irrevocable.
+ */
return basePolicy.getPermissions(codesource);
}
public PermissionCollection getPermissions(ProtectionDomain domain) {
if (initialized == false) throw new RuntimeException("Object not initialized");
+ /* It is extremely important that dynamic grant's are not returned,
+ * to prevent them becoming part of the static permissions held
+ * by a ProtectionDomain. In this case during the merge operation
+ * performed by the ProtectionDomain.
+ */
return basePolicy.getPermissions(domain);
}
@@ -297,19 +296,35 @@ public class DynamicConcurrentPolicyProv
if ( pc != null ) {
if (pc.implies(permission)) return true;
} else {
- /* We should not be calling implies on the base Policy, if
+ /* Do not call implies on the base Policy, if
* there are UnresolvedPermission's that are undergoing resolution
* while another Permission within that collection is already
- * resolved, the Enumeration may cause a ConcurrentModificationException.
+ * resolved, the Enumeration will cause a ConcurrentModificationException.
*/
- PermissionCollection bpc = basePolicy.getPermissions(domain);
- /* Don't use the underlying policy permission collection otherwise
- * we can leak grants in to the underlying policy from our cache,
- * this could then be merged into the PermissionDomain's permission
- * cache negating the possiblity of revoking the permission. This
- * PolicyUtils method defensively copies or creates new if null.
- */
- pc = PolicyUtils.toConcurrentPermissionsCopy(bpc);
+ PermissionCollection bpc = basePolicy.getPermissions(domain);
+ /* Be mindful of static Permissions held by the
+ * ProtectionDomain, a Permission may be implied by the
+ * the combination of Permission's in the ProtectionDomain and
+ * the base policy, but not by either individually.
+ * The ProtectionDomain merge is only perfomed if
+ * ProtectionDomain.toString() is called, since this is not
+ * guaranteed and is also expensive, the merge is performed
+ * here.
+ *
+ * Furthermore it is commonly understood that when
+ * ProtectionDomain.implies(Permission) is called, it first checks
+ * it's own private Permissions, then calls Policy.implies, however
+ * this is incorrect, the Policy is checked first.
+ */
+ PermissionCollection pdpc = domain.getPermissions();
+ PermissionCollection[] p = { pdpc, bpc };
+ /* Don't use the underlying policy permission collection otherwise
+ * we can leak grants in to the underlying policy from our cache,
+ * this could then be merged into the PermissionDomain's permission
+ * cache negating the possiblity of revoking the permission. This
+ * PolicyUtils method defensively copies or creates new if null.
+ */
+ pc = PolicyUtils.mergePermissions(p);
PermissionCollection existed = cache.putIfAbsent(domain, pc);
if ( existed != null ){
pc = existed;
Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/util/PolicyUtils.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/util/PolicyUtils.java?rev=1002846&r1=1002845&r2=1002846&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/util/PolicyUtils.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/util/PolicyUtils.java Wed Sep 29 21:14:40 2010
@@ -553,8 +553,8 @@ public class PolicyUtils {
}
/**
- * Copies a common-purpose homegeneous or heterogeneous PermissionCollection
- * to a hetergeneous PermissionCollection based on ConcurrentPermissions.
+ * Merges common-purpose homegeneous or heterogeneous PermissionCollection's
+ * into a hetergeneous PermissionCollection based on ConcurrentPermissions.
*
* @param perms a PermissionCollection containing arbitrary permissions. Null
* is permitted.
@@ -563,15 +563,18 @@ public class PolicyUtils {
* is returned if parameter is null.
*/
public static PermissionCollection
- toConcurrentPermissionsCopy(PermissionCollection perms) {
+ mergePermissions(PermissionCollection[] perms) {
PermissionCollection pc = new ConcurrentPermissions();
- if (perms != null) {
- Enumeration<Permission> iter = perms.elements();
- while ( iter.hasMoreElements() ) {
- Permission element = iter.nextElement();
- pc.add(element);
- }
- }
+ int l = perms.length;
+ for (int i = 0; i < l; i++ ){
+ if (perms[i] != null) {
+ Enumeration<Permission> iter = perms[i].elements();
+ while ( iter.hasMoreElements() ) {
+ Permission element = iter.nextElement();
+ pc.add(element);
+ }
+ }
+ }
return pc;
}