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/20 13:35:03 UTC
svn commit: r998893 - in /incubator/river/jtsk/skunk/pepe/src:
net/jini/core/lookup/ net/jini/lookup/ net/jini/security/policy/
org/apache/river/api/lookup/ org/apache/river/api/security/
org/apache/river/imp/security/policy/cdc/ org/apache/river/imp/s...
Author: peter_firmstone
Date: Mon Sep 20 11:35:03 2010
New Revision: 998893
URL: http://svn.apache.org/viewvc?rev=998893&view=rev
Log:
Remove unwanted classes, renamed and modified some existing and added more of the delegate framework.
Added:
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java
- copied, changed from r996089, incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/MarshalledServiceItem.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java
- copied, changed from r996089, incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamFilter.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java
- copied, changed from r996089, incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java
- copied, changed from r996093, incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/StreamServiceRegistrar.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/AccessControlDelegate.java (with props)
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java (with props)
incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ACCC.java
- copied, changed from r996089, incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ECM.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/util/ConcurrentCollections.java (with props)
Removed:
incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/MarshalledServiceItem.java
incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/StreamServiceRegistrar.java
incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamFilter.java
incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/ExecutionContextManager.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/Reaper.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ECM.java
Modified:
incubator/river/jtsk/skunk/pepe/src/net/jini/security/policy/DynamicPolicyProvider.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokePermission.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokeableDynamicPolicy.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java
incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java
Modified: incubator/river/jtsk/skunk/pepe/src/net/jini/security/policy/DynamicPolicyProvider.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/net/jini/security/policy/DynamicPolicyProvider.java?rev=998893&r1=998892&r2=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/net/jini/security/policy/DynamicPolicyProvider.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/net/jini/security/policy/DynamicPolicyProvider.java Mon Sep 20 11:35:03 2010
@@ -7,7 +7,7 @@ package net.jini.security.policy;
import java.util.List;
import org.apache.river.api.security.Denied;
-import org.apache.river.api.security.ExecutionContextManager;
+import org.apache.river.api.security.AccessControlDelegate;
import org.apache.river.api.security.PermissionGrantBuilder;
import org.apache.river.imp.security.policy.cdc.DynamicPolicyProviderImpl;
import java.security.AccessControlException;
@@ -325,7 +325,7 @@ public class DynamicPolicyProvider exten
return instance.getPermissionGrants();
}
- public ExecutionContextManager getExecutionContextManager() {
- return instance.getExecutionContextManager();
+ public AccessControlDelegate getAccessControlDelegate() {
+ return instance.getAccessControlDelegate();
}
}
Copied: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java (from r996089, incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/MarshalledServiceItem.java)
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java?p2=incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java&p1=incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/MarshalledServiceItem.java&r1=996089&r2=998893&rev=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/MarshalledServiceItem.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/MarshalledServiceItem.java Mon Sep 20 11:35:03 2010
@@ -3,8 +3,9 @@
* and open the template in the editor.
*/
-package net.jini.core.lookup;
+package org.apache.river.api.lookup;
+import net.jini.core.lookup.*;
import java.net.URI;
import java.security.CodeSource;
import java.util.Collection;
Copied: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java (from r996089, incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamFilter.java)
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java?p2=incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java&p1=incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamFilter.java&r1=996089&r2=998893&rev=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamFilter.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamFilter.java Mon Sep 20 11:35:03 2010
@@ -3,8 +3,9 @@
* and open the template in the editor.
*/
-package net.jini.lookup;
+package org.apache.river.api.lookup;
+import net.jini.lookup.*;
import org.apache.river.api.util.ResultStream;
import java.util.ArrayList;
import java.util.Arrays;
Copied: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java (from r996089, incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java)
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java?p2=incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java&p1=incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java&r1=996089&r2=998893&rev=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java Mon Sep 20 11:35:03 2010
@@ -3,8 +3,9 @@
* and open the template in the editor.
*/
-package net.jini.lookup;
+package org.apache.river.api.lookup;
+import org.apache.river.api.lookup.MarshalledServiceItem;
import org.apache.river.api.util.ResultStream;
import net.jini.core.lookup.*;
Copied: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java (from r996093, incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/StreamServiceRegistrar.java)
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java?p2=incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java&p1=incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/StreamServiceRegistrar.java&r1=996093&r2=998893&rev=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/net/jini/core/lookup/StreamServiceRegistrar.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/lookup/StreamServiceRegistrar.java Mon Sep 20 11:35:03 2010
@@ -15,8 +15,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.jini.core.lookup;
+package org.apache.river.api.lookup;
+import net.jini.core.lookup.*;
import java.io.IOException;
import org.apache.river.api.util.ResultStream;
Added: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/AccessControlDelegate.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/AccessControlDelegate.java?rev=998893&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/AccessControlDelegate.java (added)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/AccessControlDelegate.java Mon Sep 20 11:35:03 2010
@@ -0,0 +1,105 @@
+/*
+ * 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.security;
+
+import java.security.AccessControlException;
+import java.security.AccessControlContext;
+import java.security.Permission;
+import java.util.Collection;
+
+/**
+ * <p>
+ * An AccessControlDelegate is designed to be repeatedly called, where calling
+ * AccessController.checkPermission(Permission) is usually too great an overhead.
+ * </p><p>
+ * The AccessControlDelegate will only call
+ * AccessControlContext.checkPermission(Permission) once, for each context. This
+ * ensures checkPermission isn't re called, until the context changes, or
+ * the Permission checked by this AccessControlDelegate experiences a
+ * revoke for any dynamic ProtectionDomain using a RevokeableDynamicPolicy.
+ * </p><p>
+ * A Reaper may be submitted to the AccessControlDelegate to be executed
+ * when a Permission Revocation matching the stored Permission occurs.
+ * </p><p>
+ * Use of this class is not limited to Revokeable Permission's, although a
+ * revocation event will cause #checkPermission(Permission) to block
+ * until the revocation process is complete.
+ * </p><p>
+ * When protecting method's, the method must return from the try block.
+ * </p>
+ * @author Peter Firmstone
+ * @see RevokeableDynamicPolicy
+ * @see Permission
+ * @see AccessControlContext
+ */
+public interface AccessControlDelegate {
+
+ /**
+ * <p>
+ * This is a call made by a Security Delegate, or other Object used to
+ * control access to privileged methods or constructors, similar to the
+ * AccessController.checkPermission(Permission) call.
+ * The Permission check is optimised, however
+ * Typically a method may only be concerned with a single Permission check,
+ * but in many existing cases, the AccessController check is too expensive
+ * to be called on every method invocation. The AccessControlDelegate
+ * should optimise this call by ensuring that checkPermission(Permission) is only
+ * called once per AccessControlContext. In other words if the caller's
+ * AccessControlContext hasn't changed, then checkPermission(Permission)
+ * isn't called again as it would be assumed to succeed, unless the
+ * RevokeableDynamicPolicy revokes a Permission with the same class,
+ * in which case the Permission must be checked again.
+ * </p><p>
+ * Typically in the Java platform it isn't feasable to call
+ * AccessController.checkPermission on every invocation, as a result,
+ * there are guarded objects or security sensitive objects have
+ * SecurityManager checkPermission(Permission) called in their constructor.
+ * </p><p>
+ * AccessControlDelegate combined with Security Delegates and DelegatePermission's
+ * provides a more thorough form of protection.
+ * </p><p>
+ * AccessControlDelegate should be used for repeated
+ * calls, it caches the results from the AccessControlContext.
+ * </p><p>
+ * Clients using the AccessControlDelegate, should be careful
+ * to release references to their Permission objects,
+ * since garbage collection is relied upon to clean up cached
+ * AccessControlContext's, conversely, Permission objects, shouldn't be
+ * created in the checkPermission( new RuntimePermission("blah")) call,
+ * since this would cause the object to be created on every invocation
+ * and probably garbage collected between invocations, thrashing the cache
+ * and causing an AccessControlContext.checkPermssion(Permission) call
+ * as well.
+ * </p><p>
+ * In addition this method weakly caches the current AccessControlContext.
+ * </p><p>
+ * The AccessControlDelegate reserves special treatment of DelegatePermission's,
+ * if a ProtectionDomain doesn't have a DelegatePermission, but it does
+ * have the Permission the DelegatePermission represents, then it is allowed
+ * the DelegatePermission also.
+ * </p>
+ *
+ * @see DelegatePermission
+ * @see RevokeableDynamicPolicy
+ * @param perm Permission to be checked, if result not already in cache.
+ * @throws java.security.AccessControlException
+ * @throws java.lang.NullPointerException
+ */
+ public void checkPermission(Permission perm)
+ throws AccessControlException, NullPointerException;
+}
\ No newline at end of file
Propchange: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/AccessControlDelegate.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: 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=998893&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java (added)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java Mon Sep 20 11:35:03 2010
@@ -0,0 +1,148 @@
+/*
+ * 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.security;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A DelegatePermission represents any another Permission, called the candidate.
+ *
+ * A DelegatePermission is used by a Security Delegate in checkPermission
+ * 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.
+ *
+ * Security Delegates enable sensitive objects to be used by code that isn't
+ * fully trusted and may want to monitor, such as a
+ * file write that is limited by the number of bytes written, or a Permission
+ * to write a file, that we might decide to retract or revoke if the code
+ * does something we don't like, such as exceed a pre set limit or behave
+ * in a manner we would like to avoid, such as hogging network bandwidth.
+ *
+ * A DelegatePermission never implies it's candidate, however if a
+ * ProtectionDomain has the Permission the delegate represents, then the
+ * AccessControlDelegate, which a Security Delegate must utilise,
+ * must ensure that it is also checked.
+ *
+ * The DelegatePermissionCollection returned by newPermissionCollection() is not
+ * synchronized, this decision was made because PermissionCollection's are
+ * usually accessed from within a heterogenous PermissionCollection like
+ * Permissions that synchronizes anyway. The decision made for the
+ * PermissionCollection contract to be synchronized has been broken deliberately
+ * 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.
+ *
+ * PermissionCollection's are used mostly read only.
+ *
+ * @author Peter Firmstone
+ */
+public class DelegatePermission extends Permission{
+ private static final long serialVersionUID = 1L;
+ private final Permission permission;
+
+ public DelegatePermission(Permission p){
+ super(p.getClass().toString() + " " + p.getName());
+ permission = p;
+ }
+
+ @Override
+ public boolean implies(Permission permission) {
+ if (permission == null) return false;
+ if (!(permission instanceof DelegatePermission)) return false;
+ if ( permission.getClass() != this.getClass()) return false;
+ return this.permission.implies(((DelegatePermission) permission).getPermission());
+ }
+
+ public Permission getPermission(){
+ return permission;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) return true;
+ if (obj == null) return false;
+ if (!(obj instanceof DelegatePermission)) 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;
+ }
+
+ @Override
+ public String getActions() {
+ return permission.getActions();
+ }
+
+ @Override
+ public PermissionCollection newPermissionCollection() {
+ return new DelegatePermissionCollection();
+ }
+
+ private static class DelegatePermissionCollection extends PermissionCollection {
+ private static final long serialVersionUID = 1L;
+ private final PermissionCollection candidates;
+ private final Set<Permission> delegates;
+
+ DelegatePermissionCollection(){
+ candidates = new Permissions();
+ delegates = new HashSet<Permission>(50);
+ }
+
+ @Override
+ public void add(Permission permission) {
+ if (! (permission instanceof DelegatePermission))
+ throw new IllegalArgumentException("invalid permission: "+ permission);
+ if (isReadOnly())
+ throw new SecurityException("attempt to add a Permission to a " +
+ "readonly PermissionCollection");
+ delegates.add(permission);
+ candidates.add(((DelegatePermission) permission).getPermission());
+ }
+
+ @Override
+ public boolean implies(Permission permission) {
+ if ( !(permission instanceof DelegatePermission)) return false;
+ if ( permission == null ) return false;
+ if (delegates.contains(permission)) return true;
+ return candidates.implies(
+ ((DelegatePermission )permission).getPermission());
+ }
+
+ @Override
+ public Enumeration<Permission> elements() {
+ return Collections.enumeration(delegates);
+ }
+
+ }
+
+}
Propchange: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/DelegatePermission.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokePermission.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokePermission.java?rev=998893&r1=998892&r2=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokePermission.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokePermission.java Mon Sep 20 11:35:03 2010
@@ -30,8 +30,9 @@ public class RevokePermission extends Pe
@Override
public boolean implies(Permission permission) {
- if (permission instanceof RevokePermission) return true;
- return false;
+ if ( !(permission instanceof RevokePermission)) return false;
+ if ( permission.getClass() != this.getClass()) return false;
+ return true;
}
@Override
Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokeableDynamicPolicy.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokeableDynamicPolicy.java?rev=998893&r1=998892&r2=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokeableDynamicPolicy.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/api/security/RevokeableDynamicPolicy.java Mon Sep 20 11:35:03 2010
@@ -106,16 +106,22 @@ public interface RevokeableDynamicPolicy
*
* Instead what is needed is a permission check that is efficient enough
* to allow the methods that provide the privileged functionality to be
- * called for every method invocation. What the ExecutionContextManager
+ * called for every method invocation. What the AccessControlDelegate
* does is minimise the checkPermission calls by skipping checkPermission for
* any execution AccessControlContext that has already passed, unless
* a Permission related to the one being managed is revoked, in which case
* the cache of AccessControlContext's previously checked are cleared.
*
- * @param p Permission the ExecutionContextManager will check.
- * @return a new ExecutionContextManager instance.
+ * The AccessControlDelegate also manages special semantics required by
+ * DelegatePermission checks, which require that a ProtectionDomain, have
+ * either the DelegatePermission, or the candidate Permission which the
+ * DelegatePermission represents (contains).
+ *
+ * @see DelegatePermission
+ * @param p Permission the AccessControlDelegate will check.
+ * @return a new AccessControlDelegate instance.
*/
- public ExecutionContextManager getExecutionContextManager();
+ public AccessControlDelegate getAccessControlDelegate();
/**
*
* @return true if Revoke supported.
Modified: incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java?rev=998893&r1=998892&r2=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java Mon Sep 20 11:35:03 2010
@@ -49,7 +49,7 @@ 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.api.security.ExecutionContextManager;
+import org.apache.river.api.security.AccessControlDelegate;
import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
/**
@@ -583,7 +583,7 @@ public class DynamicPolicyProviderImpl e
throw new UnsupportedOperationException("Not supported.");
}
- public ExecutionContextManager getExecutionContextManager() {
+ public AccessControlDelegate getAccessControlDelegate() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
Copied: incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ACCC.java (from r996089, incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ECM.java)
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ACCC.java?p2=incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ACCC.java&p1=incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ECM.java&r1=996089&r2=998893&rev=998893&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ECM.java (original)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/security/policy/se/ACCC.java Mon Sep 20 11:35:03 2010
@@ -18,25 +18,31 @@
package org.apache.river.imp.security.policy.se;
+import java.lang.reflect.Field;
import java.security.AccessControlContext;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.Permission;
-import java.util.Collection;
-import java.util.Collections;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.apache.river.api.security.ExecutionContextManager;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.river.api.security.AccessControlDelegate;
+import org.apache.river.api.security.DelegatePermission;
+import org.apache.river.imp.util.ConcurrentCollections;
import org.apache.river.imp.util.ConcurrentSoftMap;
/**
- * Only a Single instance of ECM is required per policy, it is threadsafe.
+ * Only a Single instance of ACCC is required per policy, it is threadsafe.
* Threads will wait until revoke is complete.
*
* Implementers Note: It hasn't been determined if the cache should be
@@ -49,17 +55,37 @@ import org.apache.river.imp.util.Concurr
*
* @author Peter Firmstone
*/
-class ECM implements ExecutionContextManager{
-
- private final ConcurrentMap<Permission,Set<AccessControlContext>> checkedCache;
+class ACCC implements AccessControlDelegate{
+
+ private final ConcurrentMap<AccessControlContext,DelegateContextCheck> 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.
- ECM(){
- /* The clients control garbage collection, the Permission objects
- * are those passed by clients.*/
- checkedCache = new ConcurrentSoftMap<Permission, Set<AccessControlContext>>(300);
+ /* REMIND: do the DelegatePermission check and check the candidate Permission
+ * contained within is checked also.
+ *
+ * It is important that the DelegatePermission check is not expanded in
+ * the Policy, since this would exclude Static ProtectionDomain's or
+ * different Security Frameworks from working, eg OSGi.
+ *
+ * The DelegatePermission or candidate Permission have to be checked
+ * and return true for each ProtectionDomain in the AccessControlContext.
+ * This requires a slightly different algorithm than the AccessControlContext
+ * permission check.
+ *
+ * We would first have to get the current AccessControlContext from the stack,
+ * this would already have been optimised and combined.
+ *
+ * Then we would need to use reflection to access the ProtectionDomain[]
+ * context and iterate through each domain and check implies for
+ * the DelegatePermission or candidate Permission the DelegatePermission
+ * contains.
+ */
+
+ ACCC(){
+ /* Previous checks */
+ checks = new ConcurrentSoftMap<AccessControlContext,DelegateContextCheck>(40);
/* This lock guards revocation */
revokeLock = new ReentrantReadWriteLock();
rl = revokeLock.readLock();
@@ -76,13 +102,13 @@ class ECM implements ExecutionContextMan
permClasses.add(itp.next().getClass());
}
// Remove Permission's and AccessControlContexts from the checked cache.
- Iterator<Permission> keysIt = checkedCache.keySet().iterator();
- while (keysIt.hasNext()){
- Permission p = keysIt.next();
- if (permClasses.contains(p.getClass())){
- Set<AccessControlContext> a = checkedCache.get(p);
- keysIt.remove();
- }
+ Iterator<DelegateContextCheck> checkIt = checks.values().iterator();
+ while (checkIt.hasNext()){
+ DelegateContextCheck c = checkIt.next();
+ Iterator<Class> it = permClasses.iterator();
+ while (it.hasNext()){
+ c.removePermission(it.next());
+ }
}
/* We're done, go home & rest */
} finally {
@@ -90,34 +116,114 @@ class ECM implements ExecutionContextMan
}
}
- public void checkPermission(Collection<Permission> perms) throws AccessControlException {
- if (perms == null ) throw new NullPointerException("Permission Collection null");
- if (perms.isEmpty()) return; // Should we do this or is it a bug?
+ public void checkPermission(Permission perm) throws AccessControlException {
+ if (perm == null ) throw new NullPointerException("Permission Collection null");
//Thread currentThread = Thread.currentThread();
- AccessControlContext executionContext = AccessController.getContext();
- HashSet<Permission> permissions = new HashSet<Permission>(perms.size());
- permissions.addAll(perms);
+ AccessControlContext executionContext = AccessController.getContext();
rl.lock();
try {
- // checkedCache - the permission check, fast for repeated calls.
- Iterator<Permission> permiter = permissions.iterator();
- while (permiter.hasNext()){
- Permission p = permiter.next();
- Set<AccessControlContext> checked = checkedCache.get(p);
- if (checked == null ){
- checked = Collections.synchronizedSet(new HashSet<AccessControlContext>());
- Set<AccessControlContext> existed = checkedCache.putIfAbsent(p, checked);
- if (existed != null){
- checked = existed;
- }
+ // checkedCache - the permission check, fast for repeated calls.
+ //Set<AccessControlContext> checked = checkedCache.get(perm);
+ DelegateContextCheck checked = checks.get(executionContext);
+ if (checked == null ){
+ checked = new DelegateContextCheck(executionContext);
+ DelegateContextCheck existed =
+ checks.putIfAbsent(executionContext, checked);
+ if (existed != null){
+ checked = existed;
}
- if ( checked.contains(executionContext)) continue; // it's passed before.
- executionContext.checkPermission(p); // Throws AccessControlException
- // If we get here cache the AccessControlContext.
- checked.add(executionContext);
}
+ checked.checkPermission(perm); // Throws AccessControlException
} finally {
rl.unlock();
}
}
+
+ private static class DelegateContextCheck {
+ 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){
+ this.acc = acc;
+ passed = new ConcurrentHashMap<Class,Set<Permission>>();
+ /* If context is null for whatever reason, then the AccessControlContext
+ * will be consulted directly, but only for the DelegatePermission,
+ * in most cases, the context is null because only system classes
+ * are on the stack.
+ * However if there is an error, then we default to the safest
+ * action of directly consulting the AccessControlContext instead.
+ */
+ ProtectionDomain[] contx = AccessController.doPrivileged( new PrivilegedAction<ProtectionDomain[]>(){
+ public ProtectionDomain[] run() {
+ try {
+ Field field = acc.getClass().getDeclaredField("context");
+ field.setAccessible(true);
+ return (ProtectionDomain[]) field.get(acc);
+ } catch (IllegalArgumentException ex) {
+ Logger.getLogger(ACCC.class.getName()).log(Level.SEVERE, null, ex);
+ return null;
+ } catch (IllegalAccessException ex) {
+ Logger.getLogger(ACCC.class.getName()).log(Level.SEVERE, null, ex);
+ return null;
+ } catch (NoSuchFieldException ex) {
+ Logger.getLogger(ACCC.class.getName()).log(Level.SEVERE, null, ex);
+ return null;
+ } catch (SecurityException ex) {
+ Logger.getLogger(ACCC.class.getName()).log(Level.SEVERE, null, ex);
+ return null;
+ }
+ }
+ });
+ if ( contx != null ){
+ context = contx.clone();
+ }else{
+ context = null;
+ }
+ }
+
+ void checkPermission(Permission perm) throws AccessControlException {
+ if (perm == null) throw new NullPointerException("null Permission" +
+ " not allowed");
+ Set<Permission> perms = passed.get(perm.getClass());
+ if (perms.contains(perm)) return;
+ // We haven't checked this permission before!
+ if ( perm instanceof DelegatePermission ) {
+ // This throws AccessControlException when Permission not true
+ if( !implies((DelegatePermission) perm) ){
+ // context was null if we get here.
+ acc.checkPermission(perm);
+ }
+ } else {
+ acc.checkPermission(perm);
+ }
+ // If we get to here then we have permission.
+ if (perms == null ){
+ perms = ConcurrentCollections.multiReadSet(new HashSet<Permission>());
+ Set<Permission> existed = passed.putIfAbsent(perm.getClass(), perms);
+ if ( existed != null ){
+ perms = existed;
+ }
+ }
+ perms.add(perm);
+ }
+
+ private boolean implies(DelegatePermission perm) throws AccessControlException{
+ if (context == null) return false; // safe
+ int l = context.length;
+ for (int i = 0; i < l; i++){
+ if ( context[i] != null && (!context[i].implies(perm)
+ || !context[i].implies(perm.getPermission()))) {
+ throw new AccessControlException("access denied " + perm, perm);
+ }
+ }
+ return true;
+ }
+
+ void removePermission(Class c){
+ passed.remove(c);
+ }
+
+ }
}
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=998893&r1=998892&r2=998893&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 Mon Sep 20 11:35:03 2010
@@ -34,7 +34,7 @@ import net.jini.security.policy.PolicyIn
import net.jini.security.policy.UmbrellaGrantPermission;
import org.apache.river.api.security.Denied;
import org.apache.river.api.security.PermissionGrant;
-import org.apache.river.api.security.ExecutionContextManager;
+import org.apache.river.api.security.AccessControlDelegate;
import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
import org.apache.river.api.security.PermissionGrantBuilder;
import org.apache.river.api.security.RevokePermission;
@@ -162,7 +162,7 @@ public class DynamicConcurrentPolicyProv
// private final WriteLock dwl;
// private final Set<Denied> denied;
// private volatile boolean checkDenied;
- private final ECM execControlManager;
+ private final ACCC execControlManager;
public DynamicConcurrentPolicyProvider(){
@@ -180,7 +180,7 @@ public class DynamicConcurrentPolicyProv
// denied = new HashSet<Denied>(30);
// checkDenied = false;
grantLock = new Object();
- execControlManager = new ECM();
+ execControlManager = new ACCC();
}
/**
@@ -578,7 +578,7 @@ public class DynamicConcurrentPolicyProv
return grants;
}
- public ExecutionContextManager getExecutionContextManager() {
+ public AccessControlDelegate getAccessControlDelegate() {
return execControlManager;
}
Added: incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/util/ConcurrentCollections.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/util/ConcurrentCollections.java?rev=998893&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/util/ConcurrentCollections.java (added)
+++ incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/util/ConcurrentCollections.java Mon Sep 20 11:35:03 2010
@@ -0,0 +1,262 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ *
+ * @author Peter Firmstone.
+ */
+public class ConcurrentCollections {
+ // Not instantiable
+ private ConcurrentCollections() {}
+
+ public static <T> Set<T> multiReadSet(Set<T> s) {
+ return new MultiReadSet<T>(s);
+ }
+
+ public static <T> Collection<T> multiReadCollection(Collection<T> c){
+ return new MultiReadCollection<T>(c);
+ }
+
+ static class MultiReadCollection<E> implements Collection<E>, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ final Collection<E> c; // Backing Collection
+ final Object mutex; // Object on which to synchronize
+ final ReadWriteLock rwlock;
+ final Lock rl;
+ final Lock wl;
+
+ MultiReadCollection(Collection<E> c) {
+ if (c==null) {
+ throw new NullPointerException();
+ }
+ this.c = c;
+ mutex = this;
+ rwlock = new ReentrantReadWriteLock();
+ rl = rwlock.readLock();
+ wl = rwlock.writeLock();
+ }
+
+ Lock getReadLock(){
+ return rl;
+ }
+
+ Lock getWriteLock(){
+ return rl;
+ }
+
+ public int size() {
+ rl.lock();
+ try {
+ return c.size();
+ }
+ finally {
+ rl.unlock();
+ }
+ }
+ public boolean isEmpty() {
+ rl.lock();
+ try {
+ return c.isEmpty();
+ }
+ finally {
+ rl.unlock();
+ }
+ }
+ public boolean contains(Object o) {
+ rl.lock();
+ try {
+ return c.contains(o);
+ }
+ finally {
+ rl.unlock();
+ }
+ }
+ public Object[] toArray() {
+ rl.lock();
+ try {
+ return c.toArray();
+ }
+ finally {
+ rl.unlock();
+ }
+ }
+ public <T> T[] toArray(T[] a) {
+ rl.lock();
+ try {
+ return c.toArray(a);
+ }
+ finally {
+ rl.unlock();
+ }
+ }
+
+ public Iterator<E> iterator() {
+ rl.lock();
+ try {
+ return new CollectionIterator<E>(this);
+ }
+ finally {
+ rl.unlock();
+ }
+ }
+
+ public boolean add(E e) {
+ wl.lock();
+ try{
+ return c.add(e);
+ }finally{
+ wl.unlock();
+ }
+ }
+ public boolean remove(Object o) {
+ wl.lock();
+ try{
+ return c.remove(o);
+ }finally{
+ wl.unlock();
+ }
+ }
+
+ public boolean containsAll(Collection<?> coll) {
+ rl.lock();
+ try{
+ return c.containsAll(coll);
+ }finally{
+ rl.unlock();
+ }
+ }
+ public boolean addAll(Collection<? extends E> coll) {
+ wl.lock();
+ try{
+ return c.addAll(coll);
+ }finally{
+ wl.unlock();
+ }
+ }
+ public boolean removeAll(Collection<?> coll) {
+ wl.lock();
+ try{
+ return c.removeAll(coll);
+ }finally{
+ wl.unlock();
+ }
+ }
+ public boolean retainAll(Collection<?> coll) {
+ wl.lock();
+ try{
+ return c.retainAll(coll);
+ }finally{
+ wl.unlock();
+ }
+ }
+ public void clear() {
+ wl.lock();
+ try{
+ c.clear();
+ }finally{
+ wl.unlock();
+ }
+ }
+ @Override
+ public String toString() {
+ wl.lock();
+ try{
+ return c.toString();
+ }finally{
+ wl.unlock();
+ }
+ }
+ private void writeObject(ObjectOutputStream s) throws IOException {
+ rl.lock();
+ try{
+ s.defaultWriteObject();
+ }finally{
+ rl.unlock();
+ }
+ }
+ }
+
+ static class CollectionIterator<E> implements Iterator<E> {
+ final MultiReadCollection col;
+ final Iterator<E> iter;
+ volatile E element;
+ CollectionIterator(MultiReadCollection<E> c){
+ col = c;
+ Collection<E> copy = new ArrayList<E>(c.size());
+ copy.addAll(c);
+ iter = copy.iterator();
+ }
+
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ public E next() {
+ element = iter.next();
+ return element;
+ }
+
+ public void remove() {
+ col.remove(element);
+ }
+
+ }
+
+ static class MultiReadSet<E>
+ extends MultiReadCollection<E>
+ implements Set<E> {
+ private static final long serialVersionUID = 1L;
+
+ MultiReadSet(Set<E> s) {
+ super(s);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ rl.lock();
+ try{
+ return c.equals(o);
+ }finally{
+ rl.unlock();
+ }
+ }
+ @Override
+ public int hashCode() {
+ rl.lock();
+ try{
+ return c.hashCode();
+ }finally{
+ rl.unlock();
+ }
+ }
+ }
+}
Propchange: incubator/river/jtsk/skunk/pepe/src/org/apache/river/imp/util/ConcurrentCollections.java
------------------------------------------------------------------------------
svn:eol-style = native