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 2013/03/14 13:13:49 UTC
svn commit: r1456399 [1/2] - in /river/jtsk/skunk/qa_refactor/trunk: ./
qa/src/com/sun/jini/qa/harness/ qa/src/com/sun/jini/test/resources/
src-doc/static/ src/com/sun/jini/jeri/internal/mux/ src/com/sun/jini/start/
src/net/jini/discovery/ src/net/jini...
Author: peter_firmstone
Date: Thu Mar 14 12:13:47 2013
New Revision: 1456399
URL: http://svn.apache.org/r1456399
Log:
Clean up new API, removed some methods and classes. Tidy up documentation in preparation for release.
Added:
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/common/
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/common/Beta.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/package.html
- copied, changed from r1455024, river/jtsk/skunk/qa_refactor/trunk/src/net/jini/io/package.html
Removed:
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/CodeSourceGrant.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/CodeSourceSetGrant.java
river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/CodeSourceGrantTest.java
river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/PermissionGrantTest.java
Modified:
river/jtsk/skunk/qa_refactor/trunk/build.xml
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/MergedPolicyProvider.java
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/resources/qa1.logging
river/jtsk/skunk/qa_refactor/trunk/src-doc/static/manpages-index.html
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupDiscovery.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/jeri/connection/ConnectionManager.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/Security.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/AbstractPolicy.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/CertificateGrant.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ConcurrentPolicyFile.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/DefaultPolicyParser.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionComparator.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrant.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilderImp.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PolicyParser.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PrincipalGrant.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicy.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicyProvider.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ScalableNestedPolicy.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/SubjectDomain.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/URIGrant.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/util/Facade.java
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/util/ResultStream.java
river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/ConcurrentPolicyFileTest.java
river/jtsk/skunk/qa_refactor/trunk/test/src/org/apache/river/api/security/PolicyEntryTest.java
Modified: river/jtsk/skunk/qa_refactor/trunk/build.xml
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/build.xml?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/build.xml (original)
+++ river/jtsk/skunk/qa_refactor/trunk/build.xml Thu Mar 14 12:13:47 2013
@@ -368,6 +368,7 @@
<package name="net.jini.url.file"/>
<package name="net.jini.url.httpmd"/>
<package name="net.jini.url.https"/>
+ <package name="org.apache.river.api.io"/>
<package name="org.apache.river.api.lookup"/>
<package name="org.apache.river.api.security"/>
<package name="org.apache.river.api.util"/>
Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/MergedPolicyProvider.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/MergedPolicyProvider.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/MergedPolicyProvider.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/MergedPolicyProvider.java Thu Mar 14 12:13:47 2013
@@ -181,14 +181,15 @@ public class MergedPolicyProvider extend
}
}
- public Collection<PermissionGrant> getPermissionGrants(ProtectionDomain domain) {
+ public List<PermissionGrant> getPermissionGrants(ProtectionDomain domain) {
if (policies.isEmpty()) throw new IllegalStateException("No policies in provider");
- Collection<PermissionGrant> perms = null;
+ List<PermissionGrant> perms = null;
Iterator<Policy> it = policies.iterator();
while (it.hasNext()){
Policy p = it.next();
if (p instanceof ScalableNestedPolicy){
- Collection<PermissionGrant> g = ((ScalableNestedPolicy)p).getPermissionGrants(domain);
+ List<PermissionGrant> g = ((ScalableNestedPolicy)p).getPermissionGrants(domain);
+ if ( !g.isEmpty() && g.get(0).isPrivileged()) return g;
if (perms == null) {
perms = g;
} else {
@@ -196,7 +197,13 @@ public class MergedPolicyProvider extend
}
} else {
if (perms == null ) perms = new LinkedList<PermissionGrant>();
- perms.add(extractGrantFromPolicy(p, domain));
+ PermissionGrant pg = extractGrantFromPolicy(p, domain);
+ if (pg.isPrivileged()){
+ perms.clear();
+ perms.add(pg);
+ return perms;
+ }
+ perms.add(pg);
}
}
return perms;
Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/resources/qa1.logging
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/resources/qa1.logging?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/resources/qa1.logging (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/resources/qa1.logging Thu Mar 14 12:13:47 2013
@@ -104,10 +104,10 @@ java.util.logging.FileHandler.level = IN
# FINEST (lowest value)
# For Everything
-sun.rmi.level = FINE
-net.jini.level = FINE
-org.apache.river.level = FINE
-com.sun.jini.level = FINE
+sun.rmi.level = INFO
+net.jini.level = INFO
+org.apache.river.level = INFO
+com.sun.jini.level = INFO
# For the LogManager
com.sun.jini.logging.LogManager.level = INFO
Modified: river/jtsk/skunk/qa_refactor/trunk/src-doc/static/manpages-index.html
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src-doc/static/manpages-index.html?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src-doc/static/manpages-index.html (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src-doc/static/manpages-index.html Thu Mar 14 12:13:47 2013
@@ -50,14 +50,12 @@ specifics for services, utilities, and t
<li><a href="api/com/sun/jini/outrigger/package-summary.html">
Outrigger</a> - a JavaSpaces service implementation.
-
- <li><a href="http://www.rio-project.org">Rio</a> -
<li><a href="api/com/sun/jini/phoenix/package-summary.html">
Phoenix</a> - a configurable Java RMI activation system daemon
<li><a href="api/com/sun/jini/reggie/package-summary.html">
- Reggie</a> - a River lookup service
+ Reggie</a> - a Jini lookup service
<p>
@@ -95,7 +93,17 @@ specifics for services, utilities, and t
</ul><a name="infrastructure"></a>
<H2>Infrastructure</H2>
<ul>
-
+<li><a href="api/org/apache/river/api/security/package-summary.html">Apache River's
+ Security Extensions</a>
+<li><a href="api/org/apache/river/api/io/package-summary.html">Distributed objects</a>
+ - an extension of the Serialization protocol, Distributed objects are themselves
+ not Serialized, instead only instructions for recreating an object remotely
+ using reflection are marshalled. This allows Distributed objects to utilised
+ public api methods for construction, avoid publishing their internal state
+ and to be immutable and safely constructed with invariants checked or
+ defensively copied using final fields.
+<li><a href="api/org/apache/river/api/lookup/package-summary.html">A next
+ generation lookup service API.</a>
<p>
</ul><a name="tools"></a>
<H2>Tools</H2>
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/Mux.java Thu Mar 14 12:13:47 2013
@@ -139,7 +139,7 @@ abstract class Mux {
private int expectedPingCookie = -1;
/** unguarded instance state */
- private volatile long startTimeout = 30000; // milliseconds
+ private volatile long startTimeout = 15000; // milliseconds
/**
* Constructs a new Mux instance for a connection accessible through
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java Thu Mar 14 12:13:47 2013
@@ -38,6 +38,7 @@ import java.security.Security;
import java.security.SecurityPermission;
import java.util.Collection;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
@@ -237,12 +238,12 @@ public class AggregatePolicyProvider
getCurrentSubPolicy().refresh();
}
- public Collection<PermissionGrant> getPermissionGrants(ProtectionDomain domain) {
+ public List<PermissionGrant> getPermissionGrants(ProtectionDomain domain) {
Policy p = getCurrentSubPolicy();
if (p instanceof ScalableNestedPolicy){
return ((ScalableNestedPolicy)p).getPermissionGrants(domain);
}
- Collection<PermissionGrant> c = new LinkedList<PermissionGrant>();
+ List<PermissionGrant> c = new LinkedList<PermissionGrant>();
c.add(extractGrantFromPolicy(p,domain));
return c;
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupDiscovery.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupDiscovery.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupDiscovery.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupDiscovery.java Thu Mar 14 12:13:47 2013
@@ -1989,17 +1989,7 @@ public class LookupDiscovery implements
rawUnicastDiscoveryConstraints =
constraints.getConstraints(
DiscoveryConstraints.unicastDiscoveryMethod);
-
-// /* Task manager */
-// TaskManager taskManager;
-// try {
-// taskManager = (TaskManager)config.getEntry(COMPONENT_NAME,
-// "taskManager",
-// TaskManager.class);
-// } catch(NoSuchEntryException e) { /* use default */
-// taskManager = new TaskManager(MAX_N_TASKS,(15*1000),1.0f);
-// }
-
+
/* ExecutorService */
ExecutorService executorServ;
try {
@@ -2135,7 +2125,7 @@ public class LookupDiscovery implements
return;
}
- /* Start threads */
+ /* threads */
try {
announcementTimerThread = Security.doPrivileged(new PrivilegedExceptionAction<AnnouncementTimerThread>() {
@@ -2160,11 +2150,27 @@ public class LookupDiscovery implements
}
if (!all_groups || !this.groups.isEmpty()) {
requestGroups(this.groups);
- }//endif
- announceeThread.start();
- announcementTimerThread.start();
- notifierThread.start();
+ }//end if
}//end constructor
+
+ /* sync on registars */
+ private boolean started = false;
+
+ /**
+ * In previous releases threads were started in the constructor, however
+ * this violates safe construction according to the JMM.
+ *
+ * @since 2.2.1
+ */
+ public void start(){
+ synchronized (registrars){
+ if (started) return;
+ announceeThread.start();
+ announcementTimerThread.start();
+ notifierThread.start();
+ started = true;
+ }
+ }
/**
* Register a listener as interested in receiving DiscoveryEvent
@@ -2191,6 +2197,7 @@ public class LookupDiscovery implements
if (terminated) {
throw new IllegalStateException("discovery terminated");
}
+ if (!started) start();
if (listeners.indexOf(l) >= 0) return; //already have this listener
listeners.add(l);
if (registrars.isEmpty()) return;//nothing to send the new listener
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/jeri/connection/ConnectionManager.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/jeri/connection/ConnectionManager.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/jeri/connection/ConnectionManager.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/jeri/connection/ConnectionManager.java Thu Mar 14 12:13:47 2013
@@ -104,11 +104,11 @@ import net.jini.jeri.OutboundRequestIter
*
* <li><code>com.sun.jini.jeri.connectionTimeout</code> - Time in
* milliseconds to leave idle client-side connections around before
- * closing them. The default value is 30000 milliseconds (30 seconds).
+ * closing them. The default value is 15000 milliseconds (15 seconds).
*
* <li><code>com.sun.jini.jeri.handshakeTimeout</code> - Time in
* milliseconds for client-side connections to wait for the server to
- * acknowledge an opening handshake. The default value is 30000 milliseconds (30 seconds).
+ * acknowledge an opening handshake. The default value is 15000 milliseconds (15 seconds).
*
* </ul>
**/
@@ -119,14 +119,14 @@ public final class ConnectionManager {
private static final long TIMEOUT =
( (Long) AccessController.doPrivileged(new GetLongAction(
"com.sun.jini.jeri.connectionTimeout",
- 30000))).longValue();
+ 15000))).longValue();
/**
* How long to wait for a server to respond to an initial client message.
*/
private static final long HANDSHAKE_TIMEOUT =
((Long) AccessController.doPrivileged(new GetLongAction(
"com.sun.jini.jeri.handshakeTimeout",
- 30000))).longValue();
+ 15000))).longValue();
/**
* ConnectionManager logger.
*/
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java Thu Mar 14 12:13:47 2013
@@ -606,8 +606,8 @@ public class ServiceDiscoveryManager {
/** Class for implementing register/lookup/notify/dropProxy/discard tasks*/
private static abstract class CacheTask implements TaskManager.Task {
- protected ProxyReg reg;
- protected long thisTaskSeqN;
+ protected final ProxyReg reg;
+ protected volatile long thisTaskSeqN;
public CacheTask(ProxyReg reg, long seqN) {
this.reg = reg;
this.thisTaskSeqN = seqN;
@@ -644,7 +644,7 @@ public class ServiceDiscoveryManager {
* lookup service.
*/
private static abstract class ServiceIdTask extends CacheTask {
- protected ServiceID thisTaskSid;
+ protected final ServiceID thisTaskSid;
ServiceIdTask(ServiceID srvcId, ProxyReg reg, long seqN) {
super(reg, seqN);
this.thisTaskSid = srvcId;
@@ -832,7 +832,7 @@ public class ServiceDiscoveryManager {
/** The Listener class for the LeaseRenewalManager. */
private final class LeaseListenerImpl implements LeaseListener {
- private ServiceRegistrar proxy;
+ private final ServiceRegistrar proxy;
public LeaseListenerImpl(ServiceRegistrar proxy) {
this.proxy = proxy;
}
@@ -948,7 +948,7 @@ public class ServiceDiscoveryManager {
/** This class requests a "snapshot" of the given registrar's state.*/
private final class LookupTask extends CacheTask {
- private EventReg eReg;
+ private final EventReg eReg;
public LookupTask(ProxyReg reg, long seqN, EventReg eReg) {
super(reg, seqN);
this.eReg = eReg;
@@ -1117,9 +1117,9 @@ public class ServiceDiscoveryManager {
* events.
*/
private final class NotifyEventTask extends ServiceIdTask {
- private ServiceID sid;
- private ServiceItem item;
- private int transition;
+ private final ServiceID sid;
+ private final ServiceItem item;
+ private final int transition;
public NotifyEventTask(ProxyReg reg,
ServiceID sid,
ServiceItem item,
@@ -1382,8 +1382,8 @@ public class ServiceDiscoveryManager {
* send NO removed event
*/
private final class NewOldServiceTask extends ServiceIdTask {
- private ServiceItem srvcItem;
- private boolean matchMatchEvent;
+ private final ServiceItem srvcItem;
+ private final boolean matchMatchEvent;
public NewOldServiceTask(ProxyReg reg,
ServiceItem item,
boolean matchMatchEvent,
@@ -1461,7 +1461,7 @@ public class ServiceDiscoveryManager {
* service.
*/
private final class UnmapProxyTask extends ServiceIdTask {
- private ServiceItemReg itemReg;
+ private final ServiceItemReg itemReg;
public UnmapProxyTask(ProxyReg reg,
ServiceItemReg itemReg,
ServiceID srvcId,
@@ -1519,7 +1519,7 @@ public class ServiceDiscoveryManager {
/* Filter current cache instance should use for secondary matching */
private ServiceItemFilter filter = null;
/* Desired lease duration to request from lookups' event mechanisms */
- private long leaseDuration;
+ private final long leaseDuration;
/* Log the time when the cache gets created. This value is used to
* calculate the time when the cache should expire.
*/
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/Security.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/Security.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/Security.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/Security.java Thu Mar 14 12:13:47 2013
@@ -1198,7 +1198,8 @@ public final class Security {
private DistributedSubjectCombiner(Subject subject){
super(subject);
- if (subject == null) throw new NullPointerException("subject cannot be null");
+ // Don't throw exception in constructor, check subject before calling constructor.
+// if (subject == null) throw new NullPointerException("subject cannot be null");
this.subject = subject;
}
@@ -1252,6 +1253,10 @@ public final class Security {
private final static CodeSource nullCS = new CodeSource(null, (Certificate[]) null);
private final Subject subject;
+ /**
+ * Visibility of Subject and it's principal set is guaranteed by final
+ * reference and safe construction of this object.
+ */
private SubjectProtectionDomain(Subject subject){
super(nullCS, new Permissions(), null, (Principal[]) subject.getPrincipals().toArray());
this.subject = subject;
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java Thu Mar 14 12:13:47 2013
@@ -40,6 +40,7 @@ import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
+import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
@@ -68,7 +69,7 @@ import org.apache.river.api.security.Rev
* cost however, that of increased memory usage.</p>
*
* <p>Due to the Java 2 Security system's static design, a Policy Provider
- * can only augment the policy files utilised, a Policy can only relax security
+ * can only augment policy files; a Policy can only relax security
* by granting additional permissions, this implementation adds an experimental
* feature for revoking permissions, however there are some caveats:</p>
*
@@ -120,7 +121,7 @@ import org.apache.river.api.security.Rev
* all other Permission's using dynamic grants.
*
* </p><p>
- * To make the best utilisation of this Policy provider, set the System property:
+ * The underlying policy provider may be set using the System property:
* </p>,<p>
* net.jini.security.policy.PolicyFileProvider.basePolicyClass =
* org.apache.river.security.concurrent.ConcurrentPolicyFile
@@ -357,9 +358,12 @@ Put the policy providers and all referen
@Override
public boolean implies(ProtectionDomain domain, Permission permission) {
if (domain == policyDomain) return policyPermissions.implies(permission);
- if (basePolicyIsDynamic || basePolicyIsRemote){
- if (basePolicy.implies(domain, permission)) return true;
- }
+ // There's not much point to this check anymore, besides, it could allow
+ // a less privileged domain in an underlying policy to be checked
+ // prior to a privileged domain in this policy.
+// if (basePolicyIsDynamic || basePolicyIsRemote){
+// if (basePolicy.implies(domain, permission)) return true;
+// }
if (permission == null) throw new NullPointerException("permission not allowed to be null");
/* If com.sun.security.provider.PolicyFile:
* Do not call implies on the base Policy, if
@@ -407,15 +411,22 @@ Put the policy providers and all referen
}
}
}else{
- Collection<PermissionGrant> grants = ((ScalableNestedPolicy) basePolicy).getPermissionGrants(domain);
- processGrants(grants, permClass, true, permissions);
- if (permissions.contains(ALL_PERMISSION)) return true;
+ List<PermissionGrant> grants = ((ScalableNestedPolicy) basePolicy).getPermissionGrants(domain);
+ if ( !grants.isEmpty() && grants.get(0).isPrivileged()) return true;
+ processGrants(grants, permClass, false, permissions);
}
Iterator<PermissionGrant> grants = dynamicPolicyGrants.iterator();
+ // Check the privileged case first.
+ while (grants.hasNext()){
+ PermissionGrant g = grants.next();
+ if (g.isPrivileged() && g.implies(domain)) return true;
+ }
+ grants = dynamicPolicyGrants.iterator();
while (grants.hasNext()){
PermissionGrant g = grants.next();
- if (g.implies(domain)){
+ if (!g.isPrivileged() && g.implies(domain)){
Collection<Permission> perms = g.getPermissions();
+ // But we only want to add relevant Permissions.
Iterator<Permission> it = perms.iterator();
while (it.hasNext()){
Permission p = it.next();
@@ -532,17 +543,34 @@ Put the policy providers and all referen
return perms;
}
- public Collection<PermissionGrant> getPermissionGrants(ProtectionDomain domain) {
- Collection<PermissionGrant> grants = null;
+ public List<PermissionGrant> getPermissionGrants(ProtectionDomain domain) {
+ List<PermissionGrant> grants = null;
if (basePolicy instanceof ScalableNestedPolicy){
grants = ((ScalableNestedPolicy)basePolicy).getPermissionGrants(domain);
+ if ( !grants.isEmpty() && grants.get(0).isPrivileged()) return grants;
} else {
grants = new LinkedList<PermissionGrant>();
- grants.add(extractGrantFromPolicy(basePolicy, domain));
+ PermissionGrant pg = extractGrantFromPolicy(basePolicy, domain);
+ grants.add(pg);
+ if (pg.isPrivileged()) return grants;
}
Iterator<PermissionGrant> it = dynamicPolicyGrants.iterator();
while (it.hasNext()){
- grants.add(it.next());
+ PermissionGrant pg = it.next();
+ /* Check privileged first */
+ if (pg.isPrivileged() && pg.implies(domain)){
+ grants.clear();
+ grants.add(pg);
+ return grants;
+ }
+ }
+ it = dynamicPolicyGrants.iterator();
+ while (it.hasNext()){
+ PermissionGrant pg = it.next();
+ /* Then check less privileged domains*/
+ if ( !pg.isPrivileged() && pg.implies(domain)){
+ grants.add(pg);
+ }
}
return grants;
}
Added: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/common/Beta.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/common/Beta.java?rev=1456399&view=auto
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/common/Beta.java (added)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/common/Beta.java Thu Mar 14 12:13:47 2013
@@ -0,0 +1,39 @@
+/*
+ * 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.common;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to indicate the annotated element is subject to change
+ * in behaviour, definition, removal.
+ */
+@Retention(RetentionPolicy.SOURCE)
+@Target({
+ ElementType.ANNOTATION_TYPE,
+ ElementType.CONSTRUCTOR,
+ ElementType.FIELD,
+ ElementType.METHOD,
+ ElementType.TYPE})
+@Documented
+public @interface Beta {
+}
\ No newline at end of file
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/SerialReflectionFactory.java Thu Mar 14 12:13:47 2013
@@ -20,6 +20,7 @@ import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@@ -34,22 +35,30 @@ import java.security.Guard;
*
* Internal state is guarded, arrays are not defensively coped.
*
+ * This is compatible with Version 2 of the Java Serialization Protocol.
+ *
* @author Peter Firmstone.
* @see Distributed
* @see DistributePermission
+ * @see Serializable
+ * @see Externalizable
*/
public final class SerialReflectionFactory implements Externalizable {
private static final long serialVersionUID = 1L;
/* Guard private state */
private static final Guard distributable = new DistributePermission();
- /* Minimal protocol to write primitives directly to stream.
+ /* Minimal protocol to write primitives directly to stream, only for parameters.
* Strings are written as Objects, since they are a special case, identical
- * strings are sent by reference not duplicates writes to stream.
- * Class is also a special case, it also is not duplicated in streams.
+ * strings are sent by reference to the first and not duplicated.
+ * Class is also a special case, it too is not duplicated.
+ *
+ * Primitives are written separately to objects, the first value written
+ * to ObjectOutput is the length of the parameter array, each parameter is
+ * proceeded by a byte header indicating its type. For null values, only the
+ * byte header is written to stream.
*
- * Only primitives are written separately, the following indicates the
- * next parameter type in the stream.
+ * This protocol is fixed and cannot be changed after release.
*/
private static final byte BOOLEAN = 0;
private static final byte BYTE = 1;
@@ -62,7 +71,6 @@ public final class SerialReflectionFacto
private static final byte OBJECT = 8;
private static final byte NULL = 9;
-
private Object classOrObject;
private String method;
private Class [] parameterTypes;
@@ -102,6 +110,9 @@ public final class SerialReflectionFacto
* Object versions of primitive parameters are writen to DataOutput
* as primitives.
* <p>
+ * Constructor parameters must either be Serializable, Externalizable or
+ * Distributed objects.
+ * <p>
*
* @param factoryClassOrObject will be used for constructor, factory static method,
* or builder Object.
@@ -157,6 +168,7 @@ public final class SerialReflectionFacto
}
}
+ // Inherit documentation
public void writeExternal(ObjectOutput out) throws IOException {
distributable.checkGuard(null);
out.writeObject(classOrObject);
@@ -197,6 +209,7 @@ public final class SerialReflectionFacto
if (o instanceof Character){
out.writeByte(CHAR);
out.writeChar(((Character)o).charValue());
+ return;
}
if (o instanceof Short){
out.writeByte(SHORT);
@@ -232,34 +245,49 @@ public final class SerialReflectionFacto
private Object readObject(ObjectInput in) throws IOException, ClassNotFoundException{
byte b = in.readByte();
switch(b){
- case 0: boolean bool = in.readBoolean();
- return Boolean.valueOf(bool);
- case 1: byte bite = in.readByte();
- return Byte.valueOf(bite);
- case 2: char ch = in.readChar();
- return Character.valueOf(ch);
- case 3: short sh = in.readShort();
- return Short.valueOf(sh);
- case 4: int i = in.readInt();
- return Integer.valueOf(i);
- case 5: long l = in.readLong();
- return Long.valueOf(l);
- case 6: float f = in.readFloat();
- return Float.valueOf(f);
- case 7: double d = in.readDouble();
- return Double.valueOf(d);
- case 8: return in.readObject();
- case 9: return null;
- default: throw new StreamCorruptedException("out of range byte read from stream");
+ case BOOLEAN: boolean bool = in.readBoolean();
+ return Boolean.valueOf(bool);
+
+ case BYTE: byte bite = in.readByte();
+ return Byte.valueOf(bite);
+
+ case CHAR: char ch = in.readChar();
+ return Character.valueOf(ch);
+
+ case SHORT: short sh = in.readShort();
+ return Short.valueOf(sh);
+
+ case INT: int i = in.readInt();
+ return Integer.valueOf(i);
+
+ case LONG: long l = in.readLong();
+ return Long.valueOf(l);
+
+ case FLOAT: float f = in.readFloat();
+ return Float.valueOf(f);
+
+ case DOUBLE: double d = in.readDouble();
+ return Double.valueOf(d);
+
+ case OBJECT: return in.readObject();
+
+ case NULL: return null;
+
+ default: throw new StreamCorruptedException("out of range byte read from stream");
}
}
+ // Inherit documentation.
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ /* If created during deserialisation, we needn't be defensive, this
+ * will never be shared with other threads and will be replaced by
+ * a fully constructed thread safe immutable object. */
if (constructed) throw new IllegalStateException("Object already constructed");
/* Don't defensively copy arrays, the object is used immediately after
* deserialization to construct the Distributed Object, the fields are
- * not accessed again, it is up to creator methods to preserve invariants.
+ * not accessed again, it is up to creator methods themselves to
+ * preserve invariants.
*/
classOrObject = in.readObject();
method = (String) in.readObject();
Copied: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/package.html (from r1455024, river/jtsk/skunk/qa_refactor/trunk/src/net/jini/io/package.html)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/package.html?p2=river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/package.html&p1=river/jtsk/skunk/qa_refactor/trunk/src/net/jini/io/package.html&r1=1455024&r2=1456399&rev=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/io/package.html (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/io/package.html Thu Mar 14 12:13:47 2013
@@ -25,65 +25,39 @@
Provides I/O interfaces and utility classes.
-<h2><code>ObjectStreamContext</code></h2>
+<h2><code>Distributed</code></h2>
-<p>The interface {@link net.jini.io.ObjectStreamContext} may be
-implemented by an object serialization stream class (a subclass of
-{@link java.io.ObjectOutputStream} or {@link
-java.io.ObjectInputStream}) to provide each object being serialized or
-deserialized with access to context information relevant to the
-overall serialization or deserialization operation. The class of an
-object that is being serialized or deserialized can test (in its
-private <code>writeObject(ObjectOutputStream)</code> or
-<code>readObject(ObjectInputStream)</code> method) if the object
-stream being used is an instance of <code>ObjectStreamContext</code>.
-If the stream class does implement that interface, the class can then
-retrieve the context information (as a {@link java.util.Collection
-Collection} of context objects) by invoking the stream's
-<code>getObjectStreamContext</code> method. The context information
-available from a given element of the collection is determined by that
-element's type. Examples of types that a context object might
-implement include {@link net.jini.io.context.ClientHost} and {@link
-net.jini.io.context.ClientSubject}.
+<p>The interface {@link org.apache.river.api.io.Distributed} may be
+implemented by an object that is required to be immutable and thread safe
+immediately after un-marshalling, <code>Distributed</code> object's do not
+implement {@link java.io.Serializable}, their fields may be private and they
+are created by a single reflective invocation of a public constructor, static
+method or <code>Serializable</code> object's builder method.
-<h2><code>MarshalOutputStream</code> and <code>MarshalInputStream</code></h2>
+<h2><code>DistributedObjectOutputStream</code> and <code>DistributedObjectInputStream</code></h2>
<p>The classes {@link net.jini.io.MarshalOutputStream} and {@link
-net.jini.io.MarshalInputStream} extend the object serialization stream
-classes {@link java.io.ObjectOutputStream} and {@link
-java.io.ObjectInputStream} to implement the dynamic class loading
-semantics of RMI argument and result marshalling and unmarshalling.
-<code>MarshalOutputStream</code> and <code>MarshalInputStream</code>
-use {@link java.rmi.server.RMIClassLoader} to get class annotations
-for marshalling and to resolve codebase annotations to {@link
-java.lang.Class} objects for unmarshalling.
-<code>MarshalInputStream</code> supports optional verification that
-the codebase annotation URLs used to resolve classes provide content
-integrity (see {@link
-net.jini.security.Security#verifyCodebaseIntegrity
-Security.verifyCodebaseIntegrity}). <code>MarshalOutputStream</code>
-and <code>MarshalInputStream</code> may be extended (in concert) to
-communicate class annotations in a way other than in the streams' own
-data. Both <code>MarshalOutputStream</code> and
-<code>MarshalInputStream</code> implement
-<code>ObjectStreamContext</code>.
-
-<h2><code>MarshalledInstance</code></h2>
-
-<p>A {@link net.jini.io.MarshalledInstance} contains an object in
-serialized form. A <code>MarshalledInstance</code> can be
-unmarshalled on demand, allowing an object to be sent in such a way
-that the receiver can control when and in what context the object is
-unmarshalled. <code>MarshalledInstance</code> provides functionality
-similar to {@link java.rmi.MarshalledObject}, but it additionally
-supports use of object stream contexts and optional verification that
-the codebase annotation URLs used to resolve classes provide content
-integrity. A convenience constructor and method are provided for
-converting between <code>MarshalledObject</code> and
-<code>MarshalledInstance</code> instances.
+net.jini.io.MarshalInputStream} extend the Distributed object serialization stream
+classes {@link org.apache.river.api.io.DistributedObjectOutputStream} and {@link
+org.apache.river.api.io.DistributeObjectInputStream} that implement replacement of
+{@link org.apache.river.api.io.Distributed} objects with
+{@link org.apache.river.api.io.SerialReflectionFactory} during marshalling and
+substitution of <code>SerialReflectionFactory</code> with an object created by
+<code>SerialReflectionFactory</code>upon unmarshalling.
+
+<h2><code>SerialReflectionFactory</code></h2>
+
+<p>A {@link org.apache.river.api.io.SerialReflectionFactory} contains Externalized
+instructions for creating an Object using reflection upon unmarshalling.
+
+<h2><code>DistributePermission</code></h2>
+
+<p>A {@link org.apache.river.api.io.DistributePermission} guards the
+ {@link java.io.Externalizable#writeExternal} method of
+ <code>SerialReflectionFactory</code>, preventing unauthorised marshalling.
-@since 2.0
-@version 2.0
+@since 2.2.1
+@version 2.2.1
</body>
</html>
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/AbstractPolicy.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/AbstractPolicy.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/AbstractPolicy.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/AbstractPolicy.java Thu Mar 14 12:13:47 2013
@@ -205,6 +205,7 @@ public abstract class AbstractPolicy ext
while (grants.hasNext()) {
PermissionGrant g = grants.next();
if (stopIfAll && g.isPrivileged()) {
+ setToAddPerms.clear();
setToAddPerms.add(ALL_PERMISSION);
return;
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/CertificateGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/CertificateGrant.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/CertificateGrant.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/CertificateGrant.java Thu Mar 14 12:13:47 2013
@@ -93,10 +93,8 @@ class CertificateGrant extends Principal
if (pd == null) return false;
CodeSource c = null;
Principal[] pals = null;
- if (pd != null){
- c = pd.getCodeSource();
- pals = getPrincipals(pd);
- }
+ c = pd.getCodeSource();
+ pals = getPrincipals(pd);
return implies(c, pals);
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ConcurrentPolicyFile.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ConcurrentPolicyFile.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ConcurrentPolicyFile.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ConcurrentPolicyFile.java Thu Mar 14 12:13:47 2013
@@ -59,14 +59,14 @@ import net.jini.security.policy.PolicyIn
/**
* <p>
- * Concurrent Policy implementation based on policy configuration files,
+ * Concurrent Policy implementation based on policy configuration URL's,
* it is intended to provide concurrent implies() for greatly improved
* throughput. Caching limits scalability and consumes shared memory,
* so no cache exists.
* </p><p>
* By default all River Policy implementations now utilise ConcurrentPolicyFile.
* </p>
- * This
+ * The default PolicyParser
* implementation recognises text files, consisting of clauses with the
* following syntax:
*
@@ -165,6 +165,13 @@ import net.jini.security.policy.PolicyIn
* string, where <i>DN </i> is a certificate's subject distinguished name.
* </dl>
* <br>
+ * If there is sufficient interest, we can implement a DENY clause,
+ * in this case DENY cannot apply to GRANT clauses that contain
+ * {@link java.security.AllPermission}, the domains to which a DENY clause
+ * would apply will be a less privileged domain. For example a user could be
+ * granted SocketPermission("*", "connect"), while a DENY clause might
+ * list specific SocketPermission domains that are disallowed, where a DENY
+ * clause has precedence over all GRANT clause Permissions except for AllPermission.
* <br>
* This implementation is thread-safe and scalable.
* @author Peter Firmstone.
@@ -215,7 +222,10 @@ public class ConcurrentPolicyFile extend
}
/**
- * Extension constructor for plugging-in a custom parser.
+ * Constructor to allow for custom policy providers, for example a database
+ * policy provider, can make administration simpler than traditional
+ * policy files.
+ *
* @param dpr
* @param comp Comparator to compare permissions.
*/
@@ -265,23 +275,23 @@ public class ConcurrentPolicyFile extend
NavigableSet<Permission> perms = new TreeSet<Permission>(comparator);
PermissionGrant [] grantRefCopy = grantArray;
int l = grantRefCopy.length;
- for ( int j =0; j < l; j++ ){
+ /* Check only privileged grants first, this allows privileged domains
+ * to avoid infinite recursion when they implement PermissionGrant
+ * and perform privileged actions during an implies call.
+ *
+ * It also ensures privileged checks are are fast.
+ */
+ for ( int j = 0; j < l; j++){
PermissionGrant ge = grantRefCopy[j];
- if (ge.implies(pd)){
- if (ge.isPrivileged()){// Don't stuff around finish early if you can.
+ if (ge.isPrivileged()){
+ if (ge.implies(pd)){
PermissionCollection pc = new Permissions();
- pc.add(new AllPermission());
+ pc.add(ALL_PERMISSION);
return pc;
}
- Collection<Permission> c = ge.getPermissions();
- Iterator<Permission> i = c.iterator();
- while (i.hasNext()){
- Permission p = i.next();
- perms.add(p);
- }
}
}
- // Don't forget to merge the static Permissions.
+ /* Merge static Permissions and check for AllPermission */
PermissionCollection staticPC = null;
if (pd != null) {
staticPC = pd.getPermissions();
@@ -297,7 +307,22 @@ public class ConcurrentPolicyFile extend
perms.add(p);
}
}
+ }
+ /* Now find less privileged cases */
+ for ( int j =0; j < l; j++ ){
+ PermissionGrant ge = grantRefCopy[j];
+ if (!ge.isPrivileged()){
+ if (ge.implies(pd)){
+ Collection<Permission> c = ge.getPermissions();
+ Iterator<Permission> i = c.iterator();
+ while (i.hasNext()){
+ Permission p = i.next();
+ perms.add(p);
+ }
+ }
+ }
}
+
return convert(perms);
}
@@ -317,8 +342,9 @@ public class ConcurrentPolicyFile extend
public PermissionCollection getPermissions(CodeSource cs) {
if (cs == null) throw new NullPointerException("CodeSource cannot be null");
// for ProtectionDomain AllPermission optimisation.
+ /* Infinite recursion is not an issue for CodeSource */
PermissionGrant [] grantRefCopy = grantArray;
- int l = grantRefCopy.length;
+ int l = grantRefCopy.length;
for ( int j =0; j < l; j++ ){
PermissionGrant ge = grantRefCopy[j];
if (ge.implies(cs, null)){ // No Principal's
@@ -344,22 +370,17 @@ public class ConcurrentPolicyFile extend
NavigableSet<Permission> perms = new TreeSet<Permission>(comparator);
PermissionGrant [] grantRefCopy = grantArray;
int l = grantRefCopy.length;
- for ( int j =0; j < l; j++ ){
+ /* Check for privileged grants first to avoid recursion when
+ * privileged domains become involved in policy decisions */
+ for (int j = 0; j < l; j++){
PermissionGrant ge = grantRefCopy[j];
- if (ge.implies(domain)){
- if (ge.isPrivileged()) return true; // Don't stuff around finish early if you can.
- Collection<Permission> c = ge.getPermissions();
- Iterator<Permission> i = c.iterator();
- while (i.hasNext()){
- Permission p = i.next();
- // Don't make it larger than necessary.
- if (klass.isInstance(permission) || permission instanceof UnresolvedPermission){
- perms.add(p);
- }
+ if (ge.isPrivileged()){
+ if (ge.implies(domain)){
+ return true;
}
}
}
- // Don't forget to merge the static Permissions.
+ /* Merge the static Permissions, check for Privileged */
PermissionCollection staticPC = null;
if (domain != null) {
staticPC =domain.getPermissions();
@@ -369,13 +390,30 @@ public class ConcurrentPolicyFile extend
Permission p = e.nextElement();
// return early if possible.
if (p instanceof AllPermission ) return true;
- // Don't make it larger than necessary, but don't worry about duplicates either.
+ // Only add relevant permissions to minimise size.
if (klass.isInstance(permission) || permission instanceof UnresolvedPermission){
perms.add(p);
}
}
}
}
+ /* Check less privileged grants */
+ for ( int j =0; j < l; j++ ){
+ PermissionGrant ge = grantRefCopy[j];
+ if (!ge.isPrivileged()){
+ if (ge.implies(domain)){
+ Collection<Permission> c = ge.getPermissions();
+ Iterator<Permission> i = c.iterator();
+ while (i.hasNext()){
+ Permission p = i.next();
+ // Only add relevant permissions to minimise size.
+ if (klass.isInstance(permission) || permission instanceof UnresolvedPermission){
+ perms.add(p);
+ }
+ }
+ }
+ }
+ }
return convert(perms).implies(permission);
}
@@ -439,16 +477,21 @@ public class ConcurrentPolicyFile extend
}
}
- public Collection<PermissionGrant> getPermissionGrants(ProtectionDomain pd) {
+ public List<PermissionGrant> getPermissionGrants(ProtectionDomain pd) {
PermissionGrant [] grants = grantArray; // copy volatile reference target.
int l = grants.length;
List<PermissionGrant> applicable = new LinkedList<PermissionGrant>();
- for (int i =0; i < l; i++){
- if (grants[i].implies(pd)){
- applicable.add(grants[i]);
+ /* First check for privileged grants */
+ for (int i = 0; i < l; i++){
+ if (grants[i].isPrivileged()){
+ if (grants[i].implies(pd)){
+ applicable.add(grants[i]);
+ return applicable;
+ }
+
}
}
- // Merge any static permissions.
+ /* Merge static permissions and check for privileged */
PermissionCollection pc = pd != null ? pd.getPermissions() : null;
if (pc != null){
PermissionGrantBuilder pgb = PermissionGrantBuilder.newBuilder();
@@ -457,17 +500,24 @@ public class ConcurrentPolicyFile extend
Collection<Permission> perms = new LinkedList<Permission>();
Enumeration<Permission> en = pc.elements();
while (en.hasMoreElements()){
- perms.add(en.nextElement());
+ Permission p = en.nextElement();
+ perms.add(p);
}
pgb.permissions(perms.toArray(new Permission[perms.size()]));
- applicable.add(pgb.build());
- }
+ PermissionGrant pg = pgb.build();
+ applicable.add(pg);
+ // Return now if privileged, to avoid infinite recursion.
+ if (pg.isPrivileged()) return applicable;
+ }
+ /* Gather less privileged grants */
+ for (int i =0; i < l; i++){
+ if (!grants[i].isPrivileged()){
+ if (grants[i].implies(pd)){
+ applicable.add(grants[i]);
+ }
+ }
+ }
+
return applicable;
}
-
-// public Collection<PermissionGrant> getPermissionGrants(boolean recursive) {
-// PermissionGrant [] grants = grantArray; // copy volatile reference target.
-// return new LinkedList<PermissionGrant>(Arrays.asList(grants));
-// }
-
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/DefaultPolicyParser.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/DefaultPolicyParser.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/DefaultPolicyParser.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/DefaultPolicyParser.java Thu Mar 14 12:13:47 2013
@@ -189,13 +189,6 @@ class DefaultPolicyParser implements Pol
PermissionGrant resolveGrant(DefaultPolicyScanner.GrantEntry ge,
KeyStore ks, Properties system, boolean resolve) throws Exception {
if ( ge == null ) return null;
- /*
- * Do we return multiple grants or do we allow a codebase array
- * in a permission grant?
- *
- * ANSWER: No we just make a CodeSourceSetGrant, that contains multiple
- * CodeSource.
- */
List<URI> codebases = new ArrayList<URI>(8);
Certificate[] signers = null;
Set<Principal> principals = new HashSet<Principal>();
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionComparator.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionComparator.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionComparator.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionComparator.java Thu Mar 14 12:13:47 2013
@@ -42,7 +42,7 @@ import java.util.Comparator;
* so that must be very fast.
*
* Note that for SocketPermissionCollection that the desired order to add to
- * SocketPermission's is in , with the most likely permissions added last.
+ * SocketPermission's is with the most likely permissions added last.
*
* HINT: Use a NavigableMap to return a reverse order iterator for
* PermissionCollection's like SocketPermissionCollection and
@@ -53,7 +53,6 @@ import java.util.Comparator;
*/
public class PermissionComparator implements Comparator<Permission>, Serializable {
private static final long serialVersionUID = 1L;
- private static final char wildcard = "*".charAt(0);
public int compare(Permission o1, Permission o2) {
if ( o1 == o2 ) return 0;
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrant.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrant.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrant.java Thu Mar 14 12:13:47 2013
@@ -35,31 +35,39 @@ import net.jini.security.GrantPermission
import org.apache.river.api.security.PermissionGrantBuilderImp.NullPermissionGrant;
/**
- * PermissionGrant implementations are expected to be immutable, non blocking,
+ * <code>PermissionGrant</code> implementations are expected to be immutable, non blocking,
* thread safe and have a good hashCode implementation to perform well in
* Collections.
- *
+ * <p>
* Developers may use decorators to alter the behaviour of existing implementations.
* Decorators should use a single transient volatile field to store the result of
* an event notification, which must be immutable, state
* may not be updated in the policy until {@link Policy#refresh()} is called.
- *
- * PermissionGrant does not implement Serializable for security reasons,
+ * It is the implementors responsibility to call refresh.
+ * <p>
+ * <code>PermissionGrant</code> does not implement <code>Serializable</code> for security reasons,
* however classes extending PermissionGrant may implement Serializable,
- * but are forced to use the Serializable Builder Pattern. Child classes
- * cannot contain circular references to themselves if they implement
- * Serializable. {@link http://wiki.apache.org/river/Serialization}
- *
- * You shouldn't pass around PermissionGrant's to just anyone; they can
- * provide an attacker with information about granted Permissions.
- *
- * Caveat Implementor: PermissionGrant's cannot perform privileged actions,
- * whilst being used by the policy to make policy decisions, any privileged
- * actions should performed prior to creating a PermissionGrant.
- * Only PermissionGrant's belonging to the same ProtectionDomain as the
- * active Policy can perform PrivilegedAction's, since the Policy caches it's
- * own domain Permissions during initialisation, it doesn't consult
- * PermissionGrant's thereafter.
+ * but are forced to use the Serializable Builder Pattern.
+ * {@link http://wiki.apache.org/river/Serialization}
+ * <p>
+ * <code>PermissionGrant</code>'s are security sensitive objects and can
+ * provide an attacker with information about granted <code>Permission</code>.
+ * For this reason, it is wise to guard references to <code>PermissionGrant</code>
+ * or to avoid storing them in object fields altogether.
+ * <p>
+ * Caveat Implementor: <code>PermissionGrant</code>'s can only make calls to other objects
+ * that themselves perform security checks during an implies call if
+ * all ProtectionDomains involved are privileged and the call is performed within
+ * {@link java.security.PrivilegedAction}. {@link java.security.PrivilegedAction}'s
+ * should generally be performed prior to creating a PermissionGrant if possible.
+ * <p>
+ * Only PermissionGrant's who's ProtectionDomain has AllPermission can perform
+ * {@link java.security.PrivilegedAction}'s during
+ * {@link java.security.Policy#implies(java.security.ProtectionDomain, java.security.Permission) }
+ * calls, since the {@link java.security.Policy} checks privileged PermissionGrant's
+ * and returns without checking less privileged PermissionGrant's that would
+ * cause an infinite recursion. Infinite recursion could be used as a denial
+ * of service by an attacker that can access an acting {@link java.security.Policy}
*
* @author Peter Firmstone
* @since 2.2.1
@@ -101,7 +109,7 @@ public abstract class PermissionGrant {
int hashcode = 7;
hashcode = 97 * hashcode + (this.perms != null ? this.perms.hashCode() : 0);
hashcode = 97 * hashcode + (this.privileged ? 1 : 0);
- hashcode = 97 * hashcode + (this.decorated != null ? this.decorated.hashCode() : 0);
+ hashcode = 97 * hashcode; // for null decorated.
this.hash = hashcode;
}
@@ -126,16 +134,60 @@ public abstract class PermissionGrant {
int hashcode = 7;
hashcode = 97 * hashcode + (this.perms != null ? this.perms.hashCode() : 0);
hashcode = 97 * hashcode + (this.privileged ? 1 : 0);
- hashcode = 97 * hashcode + (this.decorated != null ? this.decorated.hashCode() : 0);
+ hashcode = 97 * hashcode; // for decorated which is null.
this.hash = hashcode;
}
+ /**
+ * <code>PermissionGrant</code> allows for extension to enable condition or
+ * event based policy decisions. Extending classes can add functionality
+ * using the decorator pattern.
+ * <p>
+ * A privileged ProtectionDomain that contains AllPermission cannot be
+ * decorated and will throw an IllegalArgumentException. This is to
+ * prevent accidental infinite recursion; policy's that utilize PermissionGrant
+ * will check privileged PermissionGrant's first to avoid infinite recursion.
+ * <p>
+ * A decorated PermissionGrant that calls methods that perform security
+ * checks during implies, must do so from within a PrivilegedAction and
+ * all subsequent domains on the stack required to perform the PrivilegedAction
+ * must have AllPermission and to avoid infinite recursion. If possible
+ * avoid security checks while making implies determinations, by having an
+ * external event thread perform the privileged action and update a volatile
+ * variable that can be checked during an implies call without invoking another
+ * security check.
+ * <p>
+ * @param decorated PermissionGrant to be decorated.
+ * @throws IllegalArguementException if decorated is privileged
+ * @throws SecurityException if caller doesn't have {@link java.lang.RuntimePermission}
+ * "getProtectionDomain" or "getClassLoader".
+ */
protected PermissionGrant(PermissionGrant decorated){
+ this(checkInvariants(decorated), decorated);
+ }
+
+ /**
+ * Avoid finalizer attack. Object#finalize will not be called if first
+ * call in our constructor is to Object constructor.
+ *
+ * @param decorated
+ * @return
+ */
+ private static boolean checkInvariants(PermissionGrant decorated) {
PD_GUARD.checkGuard(null);
CL_GUARD.checkGuard(null);
+ if (decorated.isPrivileged()) throw
+ new IllegalArgumentException("Privileged PermissionGrant cannot be decorated");
+ return true;
+ }
+
+ /*
+ * Avoidance of finalizer attack.
+ */
+ private PermissionGrant(boolean check, PermissionGrant decorated ){
this.decorated = decorated;
perms = Collections.emptySet();
- privileged = decorated.isPrivileged();
+ privileged = false;
hash = decorated.hashCode();
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilder.java Thu Mar 14 12:13:47 2013
@@ -50,20 +50,7 @@ public abstract class PermissionGrantBui
* the ClassLoader
*/
public static final int CLASSLOADER = 0;
- /**
- * The PermissionGrant generated will apply to all classes loaded from
- * the CodeSource. This has been provided for strict compatibility
- * with the standard Java Policy, where a DNS lookup may be performed
- * to determine if CodeSource.implies(CodeSource). In addition, to
- * resolve a File URL, it will require disk access.
- *
- * This is very bad for Policy performance, it's use is discouraged,
- * so much so, it may removed.
- *
- * @deprecated use URI instead.
- */
- @Deprecated
- public static final int CODESOURCE = 1;
+
/**
* The PermissionGrant generated will apply to all classes belonging to
* the ProtectionDomain. This is actually a simplification for the
@@ -92,14 +79,21 @@ public abstract class PermissionGrantBui
/**
* The PermissionGrant generated will apply to the ProtectionDomain or
- * CodeSource who's URL is implied by the given URI. This behaves
- * similarly to CodeSource.implies(CodeSource), except no DNS lookup is
- * performed, nor file system access to verify the file exists.
+ * CodeSource who's URL is implied by the given URI. The outcome of
+ * URI comparison is identical to {@link CodeSource.implies(CodeSource)},
+ * except for item 3.4; host names are normalized according to RFC3986
+ * and compared.
*
* The DNS lookup is avoided for security and performance reasons,
* DNS is not authenticated and therefore cannot be trusted. Doing so,
* could allow an attacker to use DNS Cache poisoning to escalate
* Permission, by imitating a URL with greater privileges.
+ *
+ * CodeSource URL are converted to URI and normalized according
+ * to {@link http://www.ietf.org/rfc/rfc3986.txt} RFC3986 before being
+ * compared.
+ *
+ * @see java.security.CodeSource#implies
*/
public static final int URI = 5;
@@ -109,7 +103,8 @@ public abstract class PermissionGrantBui
/**
* resets the state for reuse, identical to a newly created
- * PermissionGrantBuilder.
+ * PermissionGrantBuilder, this step must be performed to avoid unintentional
+ * grants to previously added URI.
*/
public abstract PermissionGrantBuilder reset();
@@ -122,17 +117,14 @@ public abstract class PermissionGrantBui
* @throws IllegalStateException
*/
public abstract PermissionGrantBuilder context(int context) throws IllegalStateException;
+
/**
- * Sets the CodeSource that will receive the PermissionGrant
- * @param cs
- * @return PermissionGrantBuilder
- * @deprecated use uri instead.
+ * The URI will be added to the PermissionGrant, multiple may be specified by
+ * calling multiple times.
+ *
+ * @param uri
+ * @return
*/
- @Deprecated
- public abstract PermissionGrantBuilder codeSource(CodeSource cs);
-
- public abstract PermissionGrantBuilder multipleCodeSources();
-
public abstract PermissionGrantBuilder uri(URI uri);
/**
* Extracts ProtectionDomain
@@ -160,7 +152,7 @@ public abstract class PermissionGrantBui
*/
public abstract PermissionGrantBuilder principals(Principal[] pals);
/**
- * Sets the Permission's that will be granted.
+ * Specifies Permission's to be granted.
* @param perm
* @return
*/
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilderImp.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilderImp.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilderImp.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PermissionGrantBuilderImp.java Thu Mar 14 12:13:47 2013
@@ -54,19 +54,21 @@ class PermissionGrantBuilderImp extends
private static final long serialVersionUID = 1L;
private static final PermissionGrant nullGrant = new NullPermissionGrant();
- // Serial Form
+
+ /*@serial */
private URI[] uri;
- private CodeSource cs;
- private CodeSource[] csources;
+ /*@serial */
private Certificate[] certs;
+ /*@serial */
private Principal[] principals;
+ /*@serial */
private Permission[] permissions;
+ /*@serial */
private int context;
- private boolean hasMultipleCodeSources;
+ /*@serial */
private boolean hasDomain;
// Transient Fields
- private transient Collection<CodeSource> multipleCodeSources;
private transient Collection<URI> uris;
private transient WeakReference<ProtectionDomain> domain;
@@ -82,16 +84,12 @@ class PermissionGrantBuilderImp extends
public final PermissionGrantBuilder reset() {
uri = null;
if (uris != null) uris.clear();
- cs = null;
certs = null;
domain = null;
hasDomain = false;
principals = null;
permissions = null;
context = -1;
- multipleCodeSources = null;
- csources = null;
- hasMultipleCodeSources = false;
return this;
}
@@ -112,24 +110,6 @@ class PermissionGrantBuilderImp extends
this.uris.add(uri);
return this;
}
-
- public PermissionGrantBuilder codeSource(CodeSource cs) {
- if (hasMultipleCodeSources){
- multipleCodeSources.add(cs);
- } else {
- this.cs = cs;
- }
- return this;
- }
-
- @Override
- public PermissionGrantBuilder multipleCodeSources() {
- hasMultipleCodeSources = true;
- multipleCodeSources = new HashSet<CodeSource>();
- csources = null;
- cs = null;
- return this;
- }
public PermissionGrantBuilder clazz(Class cl) {
@@ -175,13 +155,6 @@ class PermissionGrantBuilderImp extends
if (uris != null && !uris.isEmpty() ) uri = uris.toArray(new URI[uris.size()]);
if (uri == null ) uri = new URI[0];
return new URIGrant(uri, certs, principals, permissions);
- case CODESOURCE:
- if (hasMultipleCodeSources) {
- if (multipleCodeSources != null) csources =
- multipleCodeSources.toArray(new CodeSource[multipleCodeSources.size()]);
- return new CodeSourceSetGrant(csources, principals, permissions);
- }
- return new CodeSourceGrant(cs, principals, permissions);
case CODESOURCE_CERTS:
return new CertificateGrant(certs, principals, permissions);
case PROTECTIONDOMAIN: //Dynamic grant
@@ -207,11 +180,6 @@ class PermissionGrantBuilderImp extends
}
private void writeObject(ObjectOutputStream out) throws IOException{
- if (hasMultipleCodeSources) {
- if (csources == null && multipleCodeSources != null) csources =
- multipleCodeSources.toArray(new CodeSource[multipleCodeSources.size()]);
- cs = null;
- }
if (uris != null && !uris.isEmpty()) uri = uris.toArray(new URI[uris.size()]);
out.defaultWriteObject();
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PolicyParser.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PolicyParser.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PolicyParser.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PolicyParser.java Thu Mar 14 12:13:47 2013
@@ -24,21 +24,20 @@ import java.util.Properties;
import org.apache.river.api.security.PermissionGrant;
/**
- * Based on the Apache Harmony interface of the same name, although not compatible.
+ * Parser of policy syntax.
+ *
+ * @see PermissionGrant
+ * @see URL
+ * @see Properties
+ * @see ConcurrentPolicyFile
*
* @author Peter Firmstone
*/
public interface PolicyParser {
/**
- * This is the main business method. It manages loading process as follows:
- * the associated scanner is used to parse the stream to a set of
- * {@link org.apache.river.imp.security.policy.util.DefaultPolicyScanner.GrantEntry composite tokens},
- * then this set is iterated and each token is translated to a PermissionGrant.
- * Semantically invalid tokens are ignored, the same as void PolicyEntries.
- * <br>
- * A policy file may refer to some KeyStore(s), and in this case the first
- * valid reference is initialized and used in processing tokens.
+ * Parses a given location, making use of system properties as necessary and
+ * returns a collection of <code>PermissionGrant</code>'s
*
* @param location an URL of a policy file to be loaded
* @param system system properties, used for property expansion
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PrincipalGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PrincipalGrant.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PrincipalGrant.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/PrincipalGrant.java Thu Mar 14 12:13:47 2013
@@ -78,7 +78,7 @@ class PrincipalGrant extends PermissionG
Class c = p.getClass();
String name = p.getName();
String actions = p.getActions();
- hash = 97 * hash + (c != null ? c.hashCode() : 0);
+ hash = 97 * hash + c.hashCode();
hash = 97 * hash + (name != null ? name.hashCode() : 0);
hash = 97 * hash + (actions != null ? actions.hashCode() : 0);
}
@@ -151,7 +151,7 @@ class PrincipalGrant extends PermissionG
* a PrincipalGrant is immutable and therefore shouldn't change.
* Group represents a mutable component which can change the
* result of implies. A PrincipalGrant, should
- * have the same behaviour on all calls to implies.
+ * have the same behaviour on all calls to implies, ie: be idempotent.
*
* The reason for this choice at this time; there is
* no way a Policy can be aware the PrincipalGrant
@@ -226,47 +226,9 @@ class PrincipalGrant extends PermissionG
Principal[] getPrincipals(final ProtectionDomain pd){
if (pd instanceof SubjectDomain){
final Set<Principal> principals = ((SubjectDomain) pd).getSubject().getPrincipals();
- // Synchronisation would prevent modification during array creation,
- // but it also prevents multi read,
- // lets use an iterator, catch ConcurrentModificationException
- // (which should seldom happen) sleep momentarily and try again.
- Principal[] result = null;
- Iterator<Principal> it = null;
- // This minimal synchronization ensures that array size will
- // be correct if ConcurrentModificationException is not thrown.
- synchronized (principals){
- result = new Principal[principals.size()];
- it = principals.iterator();
- }
- boolean retry = true;
- while (retry){
- try {
- int i = 0;
- while (it.hasNext()){
- result[i] = it.next();
- i++;
- }
- return result;
- } catch ( ConcurrentModificationException e){
- try {
- // sleep for modifications to finish = back off.
- Thread.currentThread().sleep(20L);
- synchronized(principals){ // try again
- result = new Principal[principals.size()];
- it = principals.iterator();
- }
- } catch (InterruptedException ex) {
- // ProtectionDomain.getPrincipals() instead.
- retry = false;
- Thread.currentThread().interrupt(); // restore interrupt.
- }
- } catch ( ArrayIndexOutOfBoundsException e) {
- retry = false;
- // ProtectionDomain.getPrincipals() instead.
- System.err.println("ArrayIndexOutOfBoundsException occured during iteration of Subject Principals");
- e.printStackTrace(System.err);
- }
- }
+ // principals is a synchronized Set, always up to date.
+ // Contention should be minimal even if Subject run on many threads.
+ return (Principal[]) principals.toArray();
}
return pd.getPrincipals();
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicy.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicy.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicy.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicy.java Thu Mar 14 12:13:47 2013
@@ -86,8 +86,6 @@ import net.jini.security.policy.Umbrella
* @see GrantPermission
* @see UmbrellaGrantPermission
* @see PolicyParser
- * @see DefaultPolicyParser
- * @see DefaultPolicyScanner
* @see PolicyPermission
*/
public interface RemotePolicy {
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicyProvider.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicyProvider.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicyProvider.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/RemotePolicyProvider.java Thu Mar 14 12:13:47 2013
@@ -30,10 +30,8 @@ import java.security.Policy;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.UnresolvedPermission;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
@@ -45,11 +43,12 @@ import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.jini.security.GrantPermission;
+import org.apache.river.api.common.Beta;
/**
- *
* @author Peter Firmstone
*/
+@Beta
public class RemotePolicyProvider extends AbstractPolicy implements RemotePolicy,
ScalableNestedPolicy{
@@ -84,7 +83,7 @@ public class RemotePolicyProvider extend
private final boolean loggable;
/**
- * Creates a new <code>DynamicPolicyProvider</code> instance that wraps
+ * Creates a new <code>RemotePolicyProvider</code> instance that wraps
* around the given non-<code>null</code> base policy object.
*
* @param basePolicy base policy object containing information about
@@ -298,8 +297,8 @@ public class RemotePolicyProvider extend
}
@Override
- public Collection<PermissionGrant> getPermissionGrants(ProtectionDomain domain) {
- Collection<PermissionGrant> grants = null;
+ public List<PermissionGrant> getPermissionGrants(ProtectionDomain domain) {
+ List<PermissionGrant> grants = null;
if (basePolicy instanceof ScalableNestedPolicy){
grants = ((ScalableNestedPolicy) basePolicy).getPermissionGrants(domain);
} else {
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ScalableNestedPolicy.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ScalableNestedPolicy.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ScalableNestedPolicy.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/ScalableNestedPolicy.java Thu Mar 14 12:13:47 2013
@@ -19,7 +19,7 @@
package org.apache.river.api.security;
import java.security.ProtectionDomain;
-import java.util.Collection;
+import java.util.List;
/**
* Policy providers can implement this interface to provide nested policies
@@ -33,16 +33,25 @@ import java.util.Collection;
public interface ScalableNestedPolicy {
/**
- * Returns a new Collection containing immutable PermissionGrant's, the
- * Collection returned is not synchronised and must not be shared with policy
+ * Returns a new List containing immutable PermissionGrant's, the
+ * List returned is not synchronised and must not be shared with policy
* internal state.
*
* Only those PermissionGrant's that imply the domain will be returned.
*
- * This allows the top level policy to gather all PermissionGrant's,
- * retrieve all relevant permissions, then sort them using PermissionComparator
- * or any other Comparator, so Permission objects are added to a PermissionCollection
- * in the most efficient order.
+ * If any PermissionGrant's are privileged (contain AllPermission), then
+ * only that one PermissionGrant should be added to the collection. If
+ * a List has a size of 1, and contains only a privileged PermissionGrant,
+ * it enables the calling policy to determine the privileged state quickly.
+ *
+ * If a policy has a privileged PermissionGrant to add to a Collection,
+ * then the Collection must be cleared before the privileged PermissionGrant
+ * is added, so the Collection only contains the privileged PermissionGrant.
+ *
+ * The top level policy gathers all PermissionGrant's,
+ * retrieves all relevant permissions, then sorts them using a
+ * PermissionComparator, so Permission objects are added to a
+ * PermissionCollection in the most efficient order.
*
* If a nested base policy doesn't support ScalableNestedPolicy, then the
* implementer should create a PermissionGrant for the domain, containing
@@ -55,6 +64,6 @@ public interface ScalableNestedPolicy {
* @param domain
* @return Collection<PermissionGrant>
*/
- public Collection<PermissionGrant> getPermissionGrants(
+ public List<PermissionGrant> getPermissionGrants(
ProtectionDomain domain);
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/SubjectDomain.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/SubjectDomain.java?rev=1456399&r1=1456398&r2=1456399&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/SubjectDomain.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/security/SubjectDomain.java Thu Mar 14 12:13:47 2013
@@ -22,7 +22,50 @@ import java.security.ProtectionDomain;
import javax.security.auth.Subject;
/**
- *
+ * A Marker interface used by {@link net.jini.security.Security} to mark
+ * a {@link java.security.ProtectionDomain} added to the stack that represents an
+ * authenticated {@link javax.security.auth.Subject} with
+ * {@link java.security.Principal}'s.
+ * <p>
+ * Typically in non-distributed systems, a <code>Subject</code> is represented
+ * by a <code>Thread</code> and all {@link java.security.Permission} granted
+ * to that <code>Subject</code> is injected into every <code>ProtectionDomain</code>
+ * present on the call stack. Code is always trusted, or at least it must be at the time the
+ * <code>Subject</code> is authenticated.
+ * <p>
+ * However in a distributed system, because code trust and Subject's are
+ * separate concerns, methods have been provided in
+ * {@link net.jini.security.Security} to prepend a <code>ProtectionDomain</code>
+ * to the stack instead of injecting Principal's into all ProtectionDomain's on
+ * the stack, this avoids mistakenly elevating privileges of less trusted
+ * code, if present on a call stack at the time the doAs subject method is called.
+ * <p>
+ * When using these methods, the security Policy needs to be written to grant
+ * Permission to code signer certificates and Principals separately.
+ * <p>
+ * For example, a RemotePolicy service is updated by an Administrator client
+ * using PermissionGrant's, however one of these grants is not signed by a
+ * trusted Certificate. Ordinarily this PermissionGrant would run with the
+ * privileges of the administrator, but because code trust and user trust
+ * should be considered separate concerns in a distributed system,
+ * the administrator is unable to make these PermissionGrant's in the
+ * presence of untrusted code.
+ * <p>
+ * These methods apply the principle of least privilege to Subject's as well
+ * as code. The privileges allowed will be the intersection of Permission
+ * granted to each ProtectionDomain on the call stack.
+ * <p>
+ * These methods require a River or Jini Policy provider to be installed. The
+ * SubjectDomain is a dynamic ProtectionDomain, it contains no Permission,
+ * it always consults the current {@link java.security.Policy}.
+ *
+ * @see net.jini.security.Security#doAs(javax.security.auth.Subject, java.security.PrivilegedAction)
+ * @see net.jini.security.Security#doAs(javax.security.auth.Subject, java.security.PrivilegedExceptionAction)
+ * @see net.jini.security.Security#doAsPrivileged(javax.security.auth.Subject, java.security.PrivilegedAction, net.jini.security.SecurityContext)
+ * @see net.jini.security.Security#doAsPrivileged(javax.security.auth.Subject, java.security.PrivilegedExceptionAction, net.jini.security.SecurityContext)
+ * @see net.jini.security.policy.DynamicPolicyProvider
+ * @see org.apache.river.api.security.ConcurrentPolicyFile
+ *
* @author Peter Firmstone
*/
public interface SubjectDomain {