Renamed CSVM-Designer to CSVM-Modelling-and-Validation.

This commit is contained in:
Achim D. Brucker 2015-05-17 21:02:17 +02:00
commit b1b3cf288a
210 changed files with 46160 additions and 0 deletions

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed 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.

44
README.md Normal file
View File

@ -0,0 +1,44 @@
# SecureBPMN
[SecureBPMN](https://www.brucker.ch/projects/securebpmn/index.en.html)
is a domain-specific modeling language that allows to model security
aspects (e.g., access control, separation of duty,
confidentiality). SecurePBPMN is defined as a meta-model that can
easily be integrated into BPMN and, thus, can be used for modeling
secure and business processes as well as secure service compositions.
## Installation
### Prerequisites
* Eclipse Helios
### Preparing the Eclipse environment
To initialize the Eclipse project structure, please do
cd src/com.sun.xacml
mvn install
cd ../org.activiti.designer.parent
mvn clean eclipse:clean
mvn eclipse:eclipse
After this, all projects can be imported into a fresh Eclipse
workspace using `File -> Import -> Existing Projects into Workspace`.
### Generate Model Classes
1. Open the folder `model` in the project `org.activiti.designer.model`
2. Open `BPMN20.genmodel`
3. Select the top level node (`bpmn2`)
4. Select `Generator -> Reload...` from the top-level menu, select
`Ecore model` and complete the wizard. While doing this, ensure
that all packages are select in the `Package Selection` screen.
5. Select the top level node (`bpmn2`)
6. Select `Generator -> Generate all` from the top-level menu
### Start Eclipse Application
Select the project `org.activiti.designer.eclipse` and select `Run as
-> Eclipse application` in the context menu (right click).
## Team
Main developer: [Achim D. Brucker](http://www.brucker.ch/)
### Contributors
* Jan Alexander
* Matthias Klink
* Raj Ruparel

5
src/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
*/target/
*/bin/
*/.classpath
*/.project
*/.settings

View File

@ -0,0 +1,12 @@
#Thu Dec 29 14:50:17 CET 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

66
src/com.sun.xacml/pom.xml Normal file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.activiti.designer</groupId>
<artifactId>org.activiti.designer.parent</artifactId>
<version>5.8.0</version>
<relativePath>../org.activiti.designer.parent/pom.xml</relativePath>
</parent>
<groupId>com.sun.xacml</groupId>
<artifactId>com.sun.xacml</artifactId>
<packaging>jar</packaging>
<version>0.1</version>
<name>com.sun.xacml</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<version>2.3.2</version>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>[4.8,)</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>[1.2,)</version>
</dependency>
<!-- dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency -->
<!-- dependency>
<groupId>jaxb</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1.5</version>
</dependency -->
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.1</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,820 @@
/*
* @(#)AbstractPolicy.java
*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.combine.CombinerElement;
import com.sun.xacml.combine.CombinerParameter;
import com.sun.xacml.combine.CombiningAlgorithm;
import com.sun.xacml.combine.CombiningAlgFactory;
import com.sun.xacml.combine.PolicyCombiningAlgorithm;
import com.sun.xacml.combine.RuleCombiningAlgorithm;
import com.sun.xacml.ctx.Attribute;
import com.sun.xacml.ctx.PolicyIssuer;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.debug.RuntimeInfo;
import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Represents an instance of an XACML policy.
*
* @since 1.0
* @author Seth Proctor
* @author Marco Barreno
* @author Ludwig Seitz
*
*/
public abstract class AbstractPolicy implements PolicyTreeElement, Cloneable {
// atributes associated with this policy
private URI idAttr;
private CombiningAlgorithm combiningAlg;
/**
* The version number for this policy. This is _not_ the XACML or
* XPath version. This is for versioning policies/policySets.
*/
private String version;
// the elements in the policy
private String description;
private PolicyIssuer policyIssuer;
private Target target;
// the default version of XPath
private String defaultVersion;
// the meta-data associated with this policy
private PolicyMetaData metaData;
// the child elements under this policy represented simply as the
// PolicyTreeElements...
private List<PolicyTreeElement> children;
// ...or the CombinerElements that are passed to combining algorithms
private List<CombinerElement> childElements;
// any obligations held by this policy
private Set<Obligation> obligations;
// the list of combiner parameters
private List<CombinerParameter> parameters;
// the maximum delegation depth authorised by this AbstractPolicy.
private int maxDelegationDepth = Constants.MAX_DELEGATION_DEPTH_UNDEFINED;
protected RuntimeInfo src;
/**
* Constructor used by <code>PolicyReference</code>, which supplies
* its own values for the methods in this class.
*/
protected AbstractPolicy() {
// Used by PolicyRefence
}
/**
* Constructor used to create a policy from concrete components.
*
* @param id the policy id
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the XACML version identifier.
* @param combiningAlg the combining algorithm to use
* @param description describes the policy or null if there is none
* @param issuer the policy's issuer, used for delegation, can be null.
* @param target the policy's target
* @param defaultVersion the XPath version to use for selectors,
* can be null.
* @param obligations the policy's obligations, can be null.
* @param parameters the policy's combiner parameters, can be null.
* @param maxDelegationDepth the maximum depth of delegation authorised
* by this policy. A value of -1 indicates
* that this was not set.
*/
protected AbstractPolicy(URI id, String version, String xacmlVersion,
CombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer,
Target target, String defaultVersion,
Set<Obligation> obligations, List<CombinerParameter> parameters,
int maxDelegationDepth) {
this.idAttr = id;
this.combiningAlg = combiningAlg;
this.description = description;
this.target = target;
this.defaultVersion = defaultVersion;
this.policyIssuer = issuer;
if (version == null) {
this.version = "1.0";
} else {
this.version = version;
}
this.metaData = new PolicyMetaData(xacmlVersion, defaultVersion);
if (obligations == null) {
this.obligations = Obligation.EMPTY_SET;
} else {
this.obligations = Collections.
unmodifiableSet(new HashSet<Obligation>(obligations));
}
if (parameters == null) {
this.parameters = CombinerParameter.EMPTY_LIST;
} else {
this.parameters = Collections.
unmodifiableList(new ArrayList<CombinerParameter>(parameters));
}
this.maxDelegationDepth = maxDelegationDepth;
}
/**
* Constructor used by child classes to initialize the shared data from
* a DOM root node.
*
* @param root the DOM root of the policy
* @param policyPrefix either "Policy" or "PolicySet"
* @param combiningName name of the field naming the combining alg
*
* @throws ParsingException if the policy is invalid
*/
protected AbstractPolicy(Node root, String policyPrefix,
String combiningName) throws ParsingException {
// get the attributes, all of which are common to Policies
NamedNodeMap attrs = root.getAttributes();
try {
// get the attribute Id
this.idAttr = new URI(attrs.getNamedItem(policyPrefix + "Id")
.getNodeValue());
} catch (Exception e) {
throw new ParsingException("Error while parsing required "
+ "attribute " + policyPrefix + "Id of a "
+ policyPrefix, e);
}
// see if there's a version
Node versionNode = attrs.getNamedItem("Version");
if (versionNode != null) {
this.version = versionNode.getNodeValue();
} else {
// assign the default version
this.version = "1.0";
}
// see if there's a MaxDelegationDepth
Node depthNode = attrs.getNamedItem("MaxDelegationDepth");
if (depthNode != null) {
this.maxDelegationDepth
= Integer.parseInt(depthNode.getNodeValue());
} else {
this.maxDelegationDepth = Constants.MAX_DELEGATION_DEPTH_UNDEFINED;
}
// now get the combining algorithm...
try {
URI algId = new URI(attrs.getNamedItem(combiningName).
getNodeValue());
CombiningAlgFactory factory = CombiningAlgFactory.getInstance();
this.combiningAlg = factory.createAlgorithm(algId);
} catch (URISyntaxException e) {
throw new ParsingException("Error parsing combining algorithm" +
" in " + policyPrefix, e);
} catch (UnknownIdentifierException e) {
throw new ParsingException("Error parsing combining algorithm" +
" in " + policyPrefix, e);
}
// ...and make sure it's the right kind
if (policyPrefix.equals("Policy")) {
if (! (this.combiningAlg instanceof RuleCombiningAlgorithm)) {
throw new ParsingException("Policy must use a Rule " +
"Combining Algorithm");
}
} else {
if (! (this.combiningAlg instanceof PolicyCombiningAlgorithm)) {
throw new ParsingException("PolicySet must use a Policy " +
"Combining Algorithm");
}
}
// do an initial pass through the elements to pull out the
// defaults, if any, so we can setup the meta-data
NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE
&& child.getLocalName().equals(
policyPrefix + "Defaults")) {
handleDefaults(child);
}
}
// with the defaults read, create the meta-data
this.metaData = new PolicyMetaData(root.getNamespaceURI(),
this.defaultVersion);
// now read the remaining policy elements
this.obligations = new HashSet<Obligation>();
this.parameters = new ArrayList<CombinerParameter>();
this.policyIssuer = null;
children = root.getChildNodes();
// now read the policy elements
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
String cname = child.getLocalName();
if (cname.equals("Description")) {
if (child.getFirstChild() != null) {
this.description = child.getFirstChild().getNodeValue();
}
} else if (cname.equals("PolicyIssuer")) {
parsePolicyIssuerAttributes(child);
} else if (cname.equals("Target")) {
this.target = Target.getInstance(child, this.metaData);
} else if (cname.equals("Obligations")) {
parseObligations(child);
} else if (cname.equals(policyPrefix + "Defaults")) {
handleDefaults(child);
} else if (cname.equals("CombinerParameters")) {
handleParameters(child);
}
}
}
// finally, make sure the obligations and parameters are immutable
this.obligations = Collections.unmodifiableSet(this.obligations);
this.parameters = Collections.unmodifiableList(this.parameters);
}
/**
* The clone method.
* FIXME: this does no deep copy on the Lists and Sets.
*
* @return a copy of this object.
*/
public Object clone() {
try {
AbstractPolicy clone = (AbstractPolicy)super.clone();
clone.idAttr = this.idAttr;
try {
clone.combiningAlg
= CombiningAlgFactory.getInstance().createAlgorithm(
this.combiningAlg.getIdentifier());
} catch (UnknownIdentifierException e) {
throw new RuntimeException("Impossible exception: "
+ e.getMessage());
}
clone.version = this.version;
clone.description = this.description;
if (this.policyIssuer != null) {
clone.policyIssuer
= (PolicyIssuer)this.policyIssuer.clone();
} else { clone.policyIssuer = null; }
clone.target = (Target)this.target.clone();
clone.defaultVersion = this.defaultVersion;
clone.metaData = this.metaData;
clone.obligations = new HashSet<Obligation>(this.obligations);
clone.parameters = new ArrayList<CombinerParameter>(this.parameters);
clone.maxDelegationDepth = this.maxDelegationDepth;
return clone;
} catch (CloneNotSupportedException e1) {// this should never happen
throw new RuntimeException("Couldn't clone AbstractPolicy");
}
}
/**
* Helper routine that parses the PolicyIssuer attributes in
* the policy or policy set
* @param root the root node of PolicyIssuer
* @throws ParsingException
*/
private void parsePolicyIssuerAttributes(Node root)
throws ParsingException {
NodeList nodes = root.getChildNodes();
Set<Attribute> issuerAttr = new HashSet<Attribute>();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE
&& node.getLocalName().equals("Attribute")) {
List<Attribute> attrs = Attribute.getInstances(node);
issuerAttr.addAll(attrs);
}
}
this.policyIssuer = new PolicyIssuer(issuerAttr);
}
/**
* Helper routine to parse the obligation data
*
* @param root The node containing the obligation data.
*
* @throws ParsingException
*/
private void parseObligations(Node root) throws ParsingException {
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE
&& node.getLocalName().equals("Obligation")) {
this.obligations.add(Obligation.getInstance(node));
}
}
}
/**
* There used to be multiple things in the defaults type, but now
* there's just the one string that must be a certain value, so it
* doesn't seem all that useful to have a class for this...we could
* always bring it back, however, if it started to do more
*
* @param root The node that contains the XPathVersion.
*/
private void handleDefaults(Node root) throws ParsingException {
this.defaultVersion = null;
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE
&& node.getLocalName().equals("XPathVersion")) {
if (node.getFirstChild() != null) {
this.defaultVersion = node.getFirstChild().getNodeValue();
} else {
throw new ParsingException("XPathVersion xml-attribute"
+ "didn't have a value");
}
}
}
}
/**
* Handles all the CombinerParameters in the policy or policy set
*
* @param root The node containing the CombinerParameters.
*
* @throws ParsingException
*/
private void handleParameters(Node root) throws ParsingException {
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE
&& node.getLocalName().equals("CombinerParameter")) {
this.parameters.add(CombinerParameter.getInstance(node));
}
}
}
/**
* Returns the id of this policy
*
* @return the policy id
*/
public URI getId() {
return this.idAttr;
}
/**
* Returns the version of this policy. If this is an XACML 1.x policy
* then this will always return <code>"1.0"</code>.
*
* @return the policy version
*/
public String getVersion() {
return this.version;
}
/**
* Returns the combining algorithm used by this policy
*
* @return the combining algorithm
*/
public CombiningAlgorithm getCombiningAlg() {
return this.combiningAlg;
}
/**
* Returns the list of input parameters for the combining algorithm. If
* this is an XACML 1.x policy then the list will always be empty.
*
* @return a <code>List</code> of <code>CombinerParameter</code>s
*/
public List<CombinerParameter> getCombiningParameters() {
return this.parameters;
}
/**
* Returns the given description of this policy or null if there is no
* description
*
* @return the description or null
*/
public String getDescription() {
return this.description;
}
/**
* Returns a <code>PolicyIssuer</code> that represents the
* PolicyIssuer for this policy.
*
* @return a <code>PolicyIssuer</code> or null
*/
public PolicyIssuer getPolicyIssuer() {
return this.policyIssuer;
}
/**
* Returns the target for this policy
*
* @return the policy's target
*/
public Target getTarget() {
return this.target;
}
/**
* Returns the XPath version to use or null if none was specified
*
* @return XPath version or null
*/
public String getDefaultVersion() {
return this.defaultVersion;
}
/**
* Returns the <code>List</code> of children under this node in the
* policy tree. Depending on what kind of policy this node represents
* the children will either be <code>AbstractPolicy</code> objects
* or <code>Rule</code>s.
*
* @return a <code>List</code> of child nodes
*/
public List<PolicyTreeElement> getChildren() {
return this.children;
}
/**
* Returns the <code>List</code> of <code>CombinerElement</code>s that
* is provided to the combining algorithm. This returns the same set
* of children that <code>getChildren</code> provides along with any
* associated combiner parameters.
*
* @return a <code>List</code> of <code>CombinerElement</code>s
*/
public List<CombinerElement> getChildElements() {
return this.childElements;
}
/**
* Returns the Set of obligations for this policy, which may be empty
*
* @return the policy's obligations
*/
public Set<Obligation> getObligations() {
return this.obligations;
}
/**
* Returns the meta-data associated with this policy
*
* @return the policy's meta data.
*/
public PolicyMetaData getMetaData() {
return this.metaData;
}
/**
*@return Returns the maximum delegation depth or
* Integer.MAX_VALUE if there is none.
*/
public int getMaxDelegationDepth() {
return this.maxDelegationDepth;
}
/**
* Given the input context sees whether or not the request matches this
* policy. This must be called by combining algorithms before they
* evaluate a policy. This is also used in the initial policy finding
* operation to determine which top-level policies might apply to the
* request.
*
* @param context the representation of the request
*
* @return the result of trying to match the policy and the request
*/
public MatchResult match(EvaluationCtx context) {
return this.target.match(context);
}
/**
* Sets the child policy tree elements for this node, which are passed
* to the combining algorithm on evaluation. The <code>List</code> must
* contain <code>CombinerElement</code>s, which in turn will contain
* <code>Rule</code>s or <code>AbstractPolicy</code>s, but may not
* contain both types of elements.
*
* @param children1 a <code>List</code> of <code>CombinerElement</code>s
* representing the child elements used by the combining
* algorithm
*/
protected void setChildren(List<CombinerElement> children1) {
// we always want a concrete list, since we're going to pass it to
// a combiner that expects a non-null input
if (children1 == null) {
this.children = PolicyTreeElement.EMPTY_LIST;
} else {
// NOTE: since this is only getting called by known child
// classes we don't check that the types are all the same
List<PolicyTreeElement> list = new ArrayList<PolicyTreeElement>();
for ( CombinerElement element : children1 ) {
list.add(element.getElement());
}
this.children = Collections.unmodifiableList(list);
this.childElements = Collections.unmodifiableList(children1);
}
}
/**
* Tries to evaluate the policy by calling the combining algorithm on
* the given policies or rules. The <code>match</code> method must always
* be called first, and must always return MATCH, before this method
* is called.
*
* @param context the representation of the request
*
* @return the result of evaluation
*/
public Result evaluate(EvaluationCtx context) {
//Need to this as parent policy set if this is a policy set
if (this instanceof PolicySet) {
context.saveParentPolicySet(this);
}
RuntimeInfo combSrc = null;
// check if runtime info is there and actually used
if ( src != null ) {
//combSrc = RuntimeInfo.getIndirectSourceLocator(src, ELEMENT_TYPE.COMBINING_ALG);
//combSrc = src.getIndirectSourceLocator(ELEMENT_TYPE.COMBINING_ALG);
combSrc = src.getIndirectRuntimeInfo(combiningAlg, ELEMENT_TYPE.COMBINING_ALG);
this.combiningAlg.setRuntimeInfo(combSrc);
}
//prepare result variable
Result result = this.combiningAlg.combine(context, this.parameters,
this.childElements);
if ( combSrc != null ) {
this.combiningAlg.unsetRuntimeInfo(combSrc);
}
if (this instanceof PolicySet) {
context.popParentPolicySet();
}
//create a set for collecting obligations
Set<Obligation> collectedObligations = new HashSet<Obligation>();
// Do we need to reduce this request to the trustedIssuer?
if (!hasTrustedIssuer()) {
if (result.getDecision() == Result.DECISION_NOT_APPLICABLE) {
// we do not need to process reduction for this result
return null;
}
context.createReductionGraph();
Result reductionResult = context.getReductionGraph().reduce(
context, result, this.idAttr);
if (reductionResult == null
|| reductionResult.getDecision()
== Result.DECISION_INDETERMINATE) {
//The reduction failed so we return this result now.
return reductionResult;
}
//check for obligations
collectedObligations.addAll(reductionResult.getObligations());
}
// add the obligations of the current policy
collectedObligations.addAll(this.obligations);
// if we have no obligations, we're done
if (collectedObligations.size() == 0) {
return result;
}
// now, see if we should add any obligations to the set
int effect = result.getDecision();
if ((effect == Result.DECISION_INDETERMINATE)
|| (effect == Result.DECISION_NOT_APPLICABLE)) {
// we didn't permit/deny, so we never return obligations
return result;
}
Iterator<Obligation> it = collectedObligations.iterator();
while (it.hasNext()) {
Obligation obligation = it.next();
if (obligation.getFulfillOn() == effect) {
result.addObligation(obligation.evaluate(context));
}
}
// finally, return the result
return result;
}
/**
* Routine used by <code>Policy</code> and <code>PolicySet</code> to
* encode the PolicyIssuer element.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
* @param indenter an object that creates indentation strings
*
* @throws UnsupportedEncodingException
*/
protected void encodePolicyIssuer(OutputStream output,
String charsetName, Indenter indenter)
throws UnsupportedEncodingException {
if (this.policyIssuer != null) {
PrintStream out = new PrintStream(output);
String indent = indenter.makeString();
out.println(indent + "<PolicyIssuer>");
indenter.in();
Iterator<Map.Entry<URI, Set<Attribute>>> it = this.policyIssuer.getAttributes().entrySet()
.iterator();
while (it.hasNext()) {
Map.Entry<URI, Set<Attribute>> entry = it.next();
Iterator<Attribute> it2 = entry.getValue().iterator();
while (it2.hasNext()) {
Attribute attr = it2.next();
attr.encode(output, charsetName, indenter);
}
}
out.println(indent + "</PolicyIssuer>");
indenter.out();
}
}
/**
* Routine used by <code>Policy</code> and <code>PolicySet</code> to
* encode some common elements.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
* @param indenter an object that creates indentation strings
*
* @throws UnsupportedEncodingException
*/
protected void encodeCommonElements(OutputStream output,
String charsetName, Indenter indenter)
throws UnsupportedEncodingException {
for ( CombinerElement element : this.childElements ) {
element.encode(output, charsetName, indenter);
}
if (this.obligations.size() != 0) {
PrintStream out = new PrintStream(output);
String indent = indenter.makeString();
out.println(indent + "<Obligations>");
indenter.in();
Iterator<Obligation> oblIt = this.obligations.iterator();
while (oblIt.hasNext()) {
oblIt.next().encode(output, charsetName, indenter);
}
out.println(indent + "</Obligations>");
indenter.out();
}
}
/**
* Method for checking if a policy was issued by the trusted issuer
*
* @return True if the PolicyIssuer is the trusted issuer
*/
public boolean hasTrustedIssuer() {
if (this.policyIssuer == null) {
return true;
}
return false;
}
/**
* Method for getting the issue date of this policy, if it was set in the
* policyIssuer member. Returns null if it has not been set.
*
* @return the date at which this policy was issued or null.
*/
public Date getIssueDate() {
if (this.policyIssuer != null) {
return this.policyIssuer.getIssueDate();
}
return null;
}
public RuntimeInfo getRuntimeInfo() {
return this.src;
}
// public void setSourceLocator(RuntimeInfo src) {
// this.src = src;
// }
/**
* Returns a copy of this abstract policy with a new isser.
* This is useful when policies are rewritten, for instance after
* a digital signature is verified, in which case the issuer
* is generated based on the signature of the policy.
* Also useful for implementing some models of revocation.
*
* @param issuer The new policy issuer.
* @return A identical copy of the abstract policy with
* a new issuer.
*/
public AbstractPolicy copyWithNewPolicyIssuer(PolicyIssuer issuer) {
AbstractPolicy newPolicy = (AbstractPolicy)clone();
newPolicy.policyIssuer = issuer;
return newPolicy;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,262 @@
/*
* @(#)Constants.java
*
* Copyright 2005-2006 Swedish Institute of Computer Science All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Swedish Institute of Computer Science or the names of
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. THE SWEDISH INSTITUE OF COMPUTER
* SCIENCE ("SICS") AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS
* SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SICS OR ITS LICENSORS BE
* LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED
* AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
* INABILITY TO USE THIS SOFTWARE, EVEN IF SICS HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import java.net.URI;
/**
* A collection of XACML constants used across various classes.
*
* @since 3.0
* @author Ludwig Seitz
*/
public class Constants {
/**
* The standard URI for listing a resource's id
*/
public static final URI RESOURCE_ID =
URI.create("urn:oasis:names:tc:xacml:1.0:resource:resource-id");
/**
* The standard URI for listing a subject's id
*/
public static final URI SUBJECT_ID =
URI.create("urn:oasis:names:tc:xacml:1.0:subject:subject-id");
/**
* The standard URI for listing a subject's id
*/
public static final URI ACTION_ID =
URI.create("urn:oasis:names:tc:xacml:1.0:action:action-id");
/**
* The standard URI for listing a resource's scope
*/
public static final URI RESOURCE_SCOPE =
URI.create("urn:oasis:names:tc:xacml:1.0:resource:scope");
/**
* The standard Subject category (compatibility code
* for XACML 2.0)
*/
public static final URI SUBJECT_CAT = URI.create(
"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject");
/**
* The standard Resource category.
*/
public static final URI RESOURCE_CAT = URI.create(
"urn:oasis:names:tc:xacml:3.0:attribute-category:resource");
/**
* The standard Resource category.
*/
public static final URI ACTION_CAT = URI.create(
"urn:oasis:names:tc:xacml:3.0:attribute-category:action");
/**
* The standard Resource category.
*/
public static final URI ENVIRONMENT_CAT = URI.create(
"urn:oasis:names:tc:xacml:3.0:attribute-category:environment");
/**
* Resource scope of Immediate (only the given resource)
*/
public static final int SCOPE_IMMEDIATE = 0;
/**
* Resource scope of Children (the given resource and its direct
* children)
*/
public static final int SCOPE_CHILDREN = 1;
/**
* Resource scope of Descendants (the given resource and all descendants
* at any depth or distance)
*/
public static final int SCOPE_DESCENDANTS = 2;
/**
* Resource scope of XPath-expression (a set of nodes selected by an
* XPath expression)
*/
public static final int SCOPE_XPATH_EXPRESSION = 3;
/**
* Resource scope of EntireHierarchy (a node and all it's descendants)
*/
public static final int SCOPE_ENTIRE_HIERARCHY = 4;
/**
* Scope of multiple elements. This applies to requests with multiple
* Resources for XACML versions < 3.0 and to requests with multiple
* Attributes elements of the same category for XACML versions >= 3.0
*/
public static final int SCOPE_MULTIPE_ELEMENTS = 5;
/**
* A reserved category for delegate matching
*/
public static final URI DELEGATE = URI.create(
"urn:oasis:names:tc:xacml:3.0:attribute-category:delegate");
/**
* A reserved category for delegate information matching
*/
public static final URI DELEGATION_INFO
= URI.create("urn:oasis:names:tc:xacml:3.0:attribute-category:"
+ "delegation-info");
/**
* The reserved URI prefix for delegated attribute matching
*/
public static final String DELEGATED =
"urn:oasis:names:tc:xacml:3.0:attribute-category:delegated:";
/**
* The reserved URI for the delegation decision
*/
public static final URI DECISION = URI.create(
"urn:oasis:names:tc:xacml:3.0:delegation:decision");
/**
* The reserved URI for the delegation depth
*/
public static final URI DELEGATION_DEPTH = URI.create(
"urn:oasis:names:tc:xacml:3.0:delegation:depth");
/**
* XACML 1.0 identifier
*/
public static final String XACML_1_0_IDENTIFIER =
"urn:oasis:names:tc:xacml:1.0:policy";
/**
* XACML 1.0 context identifier
*/
public static final String XACML_1_0_CTX_ID =
"urn:oasis:names:tc:xacml:1.0:context";
/**
* XACML 2.0 identifier
*/
public static final String XACML_2_0_IDENTIFIER =
"urn:oasis:names:tc:xacml:2.0:policy:schema:os";
/**
* XACML 1.0 context identifier
*/
public static final String XACML_2_0_CTX_ID =
"urn:oasis:names:tc:xacml:2.0:context:schema:os";
/**
* XACML 3.0 identifier
*/
public static final String XACML_3_0_IDENTIFIER =
"urn:oasis:names:tc:xacml:3.0:schema:os";
/**
* Version identifier for XACML 1.0
*/
public static final int XACML_VERSION_1_0 = 0;
/**
* Version identifier for XACML 1.1 (which isn't a formal release
* so has no namespace string, but still exists as a separate
* specification)
*/
public static final int XACML_VERSION_1_1 = 1;
/**
* Version identifier for XACML 1.2
*/
public static final int XACML_VERSION_2_0 = 2;
/**
* Version identifier for XACML 3.0
*/
public static final int XACML_VERSION_3_0 = 3;
/**
* The default version of XACML, 3.0, used if no namespace string
* is specified
*/
public static final int XACML_DEFAULT_VERSION = XACML_VERSION_3_0;
/**
* XPath 1.0 identifier
*/
public static final String XPATH_1_0_IDENTIFIER =
"http://www.w3.org/TR/1999/Rec-xpath-19991116";
/**
* Version identifier for an unspecified version of XPath
*/
public static final int XPATH_VERSION_UNSPECIFIED = 0;
/**
* Version identifier for XPath 1.0
*/
public static final int XPATH_VERSION_1_0 = 1;
/**
* Max delegation delegation depth undefined
*/
public static final int MAX_DELEGATION_DEPTH_UNDEFINED = Integer.MAX_VALUE;
/**
* System specific line separator
*/
public static final String nl = System.getProperty("line.separator");
/**
* Key for User Data available from node, describing the start line of the node in the
* xml source file. Feature must be activated.
*/
public static final String LINE_NUMBER = "startLine";
/**
* Key for User Data available from node, describing the source file of the node
*/
public static final String SOURCE_FILE = "srcFile";
}

View File

@ -0,0 +1,342 @@
/*
* @(#)EvaluationCtx.java
*
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.attr.AttributeValue;
import com.sun.xacml.attr.DateAttribute;
import com.sun.xacml.attr.DateTimeAttribute;
import com.sun.xacml.attr.TimeAttribute;
import com.sun.xacml.cond.EvaluationResult;
import com.sun.xacml.ctx.RequestElement;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.reduction.ReductionGraph;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import org.w3c.dom.Node;
/**
* Manages the context of a single policy evaluation. Typically, an instance
* is instantiated whenever the PDP gets a request and needs to perform an
* evaluation as a result. The <code>BasicEvaluationCtx</code> class
* provides a basic implementation that is used by default.
*
* @since 1.0
* @author Seth Proctor
* @author Ludwig Seitz
*/
public interface EvaluationCtx
{
/**
* Create a context for an administrative request from an
* existing context.
*
* @param decision The decision code corresponding to those in the
* <code>Result</code> class.
* @param delegate The delegate in this request (a set containing a
* single <code>RequestElement</code>).
*
* @return An administrative context for this context.
*/
public EvaluationCtx createAdminCtx(int decision, Set<RequestElement> delegate);
/**
* Creates a copy of this context with disabled attribute finder.
*
* @return A copy of this context with disabled attribute finder.
*/
public EvaluationCtx copyWithoutAttributeFinder();
/**
* Returns the DOM root of the original RequestType XML document, if
* this context is backed by an XACML Request. If this context is not
* backed by an XML representation, then an exception is thrown.
*
* @return the DOM root node
*
* @throws UnsupportedOperationException if the context is not backed
* by an XML representation
*/
public Node getRequestRoot();
/**
* Returns the resource scope, which will be one of the five fields
* denoting Immediate, Children, Descendants, XPath-expression or
* EntireHierarchy.
*
* @return the scope of the resource
*/
public int getScope();
/**
* Returns the identifier for the resource being requested.
*
* @return the resource
*/
public AttributeValue getResourceId();
/**
* Changes the value of the resource-id attribute in this context. This
* is useful when you have multiple resources (ie, a scope other than
* IMMEDIATE), and you need to keep changing only the resource-id to
* evaluate the different effective requests.
*
* @param resourceId the new resource-id value
*/
public void setResourceId(AttributeValue resourceId);
/**
* Returns the value for the current time as known by the PDP (if this
* value was also supplied in the Request, this will generally be a
* different value). Details of caching or location-based resolution
* are left to the underlying implementation.
*
* @return the current time
*/
public TimeAttribute getCurrentTime();
/**
* Returns the value for the current date as known by the PDP (if this
* value was also supplied in the Request, this will generally be a
* different value). Details of caching or location-based resolution
* are left to the underlying implementation.
*
* @return the current date
*/
public DateAttribute getCurrentDate();
/**
* Returns the value for the current dateTime as known by the PDP (if this
* value was also supplied in the Request, this will generally be a
* different value). Details of caching or location-based resolution
* are left to the underlying implementation.
*
* @return the current date
*/
public DateTimeAttribute getCurrentDateTime();
/**
* Return available attribute values of the selected category.
*
* @param category the category the attribute value(s) must be in
* @param type the type of the attribute value(s) to find
* @param id the id of the attribute value(s) to find
* @param issuer the issuer of the attribute value(s) to find or null
*
* @return a result containing a bag either empty because no values were
* found or containing at least one value, or status associated with an
* Indeterminate result
*/
public EvaluationResult getAttribute(URI category, URI type, URI id,
URI issuer);
/**
* Returns the attribute value(s) retrieved using the given XPath
* expression.
*
* @param contextPath the XPath expression to search
* @param namespaceNode the DOM node defining namespace mappings to use,
* or null if mappings come from the context root
* @param type the type of the attribute value(s) to find
* @param xpathVersion the version of XPath to use
*
* @return a result containing a bag either empty because no values were
* found or containing at least one value, or status associated with an
* Indeterminate result
*/
public EvaluationResult getAttribute(String contextPath,
Node namespaceNode, URI type,
String xpathVersion);
/**
* Get the decision.
*
* @return The <code>int</code> value of the decision according to
* the <code>Result</code> class.
*/
public int getDecision();
/**
* Get the delegation depth.
*
* @return The <code>int</code> value specifying the number of nodes
* in the reduction graph until now (not including this one).
*/
public int getDelegationDepth();
/**
* Get a whole category.
*
* @param category The name of the category.
*
* @return The <code>Set</code> of <RequestElement</code>s with
* the matching category.
*/
public Set<RequestElement> getCategory(URI category);
/**
* @return The <code>Set</code> of <code>RequestElement</code>s
* describing the attributes to be included in the result.
*/
public Set<RequestElement> getIncludedAttributes();
/**
* @return the <code>Map</code> of <code>RequestElements</code>
* defining this request.
*/
public Map<URI, Set<RequestElement>> getRequestElements();
/**
* Save the parent <code>PolicySet</code> in this evaluation context
* for doing reduction of delegated policies if that becomes necessary.
*
* @param pps the parent policy set
*/
public void saveParentPolicySet(AbstractPolicy pps);
/**
* Create a reduction graph for the current parent PolicySet.
*
*/
public void createReductionGraph();
/**
* @return The current reduction graph.
*/
public ReductionGraph getReductionGraph();
/**
* Remove the current <code>ReductionGraph</code> from the stack.
*/
public void popReductionGraph();
/**
* Get the parent <code>PolicySet</code> for this evaluation context.
*
* @return the parent policy set
*/
public AbstractPolicy getParentPolicySet();
/**
* Remove the current parent <code>PolicySet</code> from the stack
* of parent policy sets.
*/
public void popParentPolicySet();
/**
* Add new inactive PolicyId to the Map
* @param policyId the id of the new inactive policy
*/
public void addInactivePolicyId(URI policyId);
/**
* Return an unmodifiable <code>Set</code> of <code>URI</code>s of
* inactive policies
* @return the inactive policies
*/
public Set<URI> getInactivePolicyIds();
/**
* Checks whether a <code>Policy</code> or <code>PolicySet</code>
* supports a revocation of a specific Policy of PolicySet
* in this context.
*
* @param supporting The policy or policy set that could support
* a revocation.
* @param candidate The id of the policy or policy set that is candidate
* for revocation.
*
* @return true if the policy/policy set supports a revocation,
* false otherwise.
*/
public boolean supportsRevocation(AbstractPolicy supporting,
URI candidate);
/**
* Signal a new event to this EvaluationCtx.
*
* @param element The new event.
*/
public void newEvent(Object element);
/**
* Signal that an event has finished and pass the result
* which is a <code>Result</code>
*
* @param result The result of the finished event.
*/
public void closeCurrentEvent(Result result);
/**
* Signal that an event has finished and pass the result
* which is a <code>MatchResult</code>
*
* @param result The result of the finished event.
*/
public void closeCurrentEvent(MatchResult result);
/**
* Signal that an event has finished and pass the result
* which is a <code>EvaluationResult</code>
*
* @param result The result of the finished event.
*/
public void closeCurrentEvent(EvaluationResult result);
/**
* Signal that an event has finished with a <code>String</code> message.
*
* @param message The message.
*/
public void closeCurrentEvent(String message);
/**
* Signal that an event has finished with no result.
*/
public void closeCurrentEvent();
}

View File

@ -0,0 +1,139 @@
/*
* @(#)Indenter.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import java.util.Arrays;
/**
* Provides flexible indenting for XML encoding. This class generates
* strings of spaces to be prepended to lines of XML. The strings are
* formed according to a specified indent width and the given depth.
*
* @since 1.0
* @author Marco Barreno
* @author Seth Proctor
*/
public class Indenter
{
/**
* The default indentation width
*/
public static final int DEFAULT_WIDTH = 2;
// The width of one indentation level
private int width;
// the current depth
private int depth;
/**
* Constructs an <code>Indenter</code> with the default indent
* width.
*/
public Indenter() {
this(DEFAULT_WIDTH);
}
/**
* Constructs an <code>Indenter</code> with a user-supplied indent
* width.
*
* @param userWidth the number of spaces to use for each indentation level
*/
public Indenter(int userWidth) {
this.width = userWidth;
this.depth = 0;
}
/**
* Move in one width.
*/
public void in() {
this.depth += this.width;
}
/**
* Move out one width.
*/
public void out() {
this.depth -= this.width;
}
/**
* Create a <code>String</code> of spaces for indentation based on the
* current depth.
*
* @return an indent string to prepend to lines of XML
*/
public String makeString() {
// Return quickly if no indenting
if (this.depth <= 0) {
return "";
}
// Make a char array and fill it with spaces
char[] array = new char[this.depth];
Arrays.fill(array, ' ');
// Now return a string built from that char array
return new String(array);
}
/**
* Indent an input that is multilined by adding the indent at
* the beginning of every line.
*
* @param input the unindented string
*
* @return the indented string
*/
public String multilineIndent(String input) {
input = input.replaceAll(Constants.nl, Constants.nl + makeString());
input = makeString() + input;
return input;
}
/**
* @return The indentation width.
*/
public int getWidth() {
return this.width;
}
}

View File

@ -0,0 +1,11 @@
package com.sun.xacml;
import com.sun.xacml.debug.Locatable;
/**
*
*
*/
public interface MatchElement extends Locatable {
public MatchResult match(EvaluationCtx context);
}

View File

@ -0,0 +1,130 @@
/*
* @(#)MatchResult.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.ctx.Status;
/**
* This is used as the return value for the various target matching functions.
* It communicates that either the target matches the input request, the
* target doesn't match the input request, or the result is Indeterminate.
*
* @since 1.0
* @author Seth Proctor
*/
public class MatchResult
{
/**
* An integer value indicating the the target matches the request
*/
public static final int MATCH = 0;
/**
* An integer value indicating that the target doesn't match the request
*/
public static final int NO_MATCH = 1;
/**
* An integer value indicating the the result is Indeterminate
*/
public static final int INDETERMINATE = 2;
/**
* The array representing the string values for these results.
*/
public static final String[] MATCH_RESULTS = { "Match", "No_Match",
"Indeterminate"};
//
private int result;
private Status status;
/**
* Constructor that creates a <code>MatchResult</code> with no Status
*
* @param result the applicable result
*/
public MatchResult(int result) {
this(result, null);
}
/**
* Constructor that creates a <code>MatchResult</code>, including Status
* data
*
* @param result the applicable result
* @param status the error information
*
* @throws IllegalArgumentException if the input result isn't a valid value
*/
public MatchResult(int result, Status status)
throws IllegalArgumentException
{
// check if input result is a valid value
if ((result != MATCH) &&
(result != NO_MATCH) &&
(result != INDETERMINATE)) {
throw new IllegalArgumentException("Input result is not a valid" +
"value");
}
this.result = result;
this.status = status;
}
/**
* Returns the applicable result
*
* @return the applicable result
*/
public int getResult() {
return this.result;
}
/**
* Returns the status if there was an error, or null if no error occurred
*
* @return the error status data or null
*/
public Status getStatus() {
return this.status;
}
}

View File

@ -0,0 +1,369 @@
/*
* @(#)Obligation.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.attr.AttributeFactory;
import com.sun.xacml.attr.AttributeValue;
import com.sun.xacml.cond.EvaluationResult;
import com.sun.xacml.ctx.Attribute;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.debug.Locatable;
import com.sun.xacml.debug.RuntimeInfo;
import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Represents the ObligationType XML type in XACML. This also stores all the
* AttriubteAssignmentType XML types.
*
* @since 1.0
* @author Seth Proctor
*/
public class Obligation implements Locatable
{
// the obligation id
private URI id;
// effect to fulfill on, as defined in Result
private int fulfillOn;
// the attribute assignments
private List<Attribute> assignments;
// if the obligation has dynamic attribute assignments, i.e., if attribute values are assigned at runtime, default is false
private boolean dynamic_attributes;
private RuntimeInfo src;
public static final Set<Obligation> EMPTY_SET = Collections.<Obligation>emptySet();
/**
* Constructor that takes all the data associated with an obligation.
* The attribute assignment list contains <code>Attribute</code> objects,
* but only the fields used by the AttributeAssignmentType are used.
*
* @param id the obligation's id
* @param fulfillOn the effect denoting when to fulfill this obligation
* @param assignments a <code>List</code> of <code>Attribute</code>s
*/
public Obligation(URI id, int fulfillOn, List<Attribute> assignments) {
init(id, fulfillOn, assignments, false);
}
public Obligation(URI id, int fulfillOn, List<Attribute> assignments, boolean dynamic) {
init(id, fulfillOn, assignments, dynamic);
}
private void init(URI id, int fulfillOn, List<Attribute> assignments, boolean dynamic) {
this.id = id;
this.fulfillOn = fulfillOn;
this.dynamic_attributes = dynamic;
this.assignments = Collections.
unmodifiableList(new ArrayList<Attribute>(assignments));
}
private Obligation(URI id, int fulfillOn, boolean dynamic) {
this.id = id;
this.fulfillOn = fulfillOn;
this.dynamic_attributes = dynamic;
}
/**
* Creates an instance of <code>Obligation</code> based on the DOM root
* node.
*
* @param root the DOM root of the ObligationType XML type
*
* @return an instance of an obligation
*
* @throws ParsingException if the structure isn't valid
*/
public static Obligation getInstance(Node root) throws ParsingException {
RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.OBLIGATION);
if (root.getNodeType() != Node.ELEMENT_NODE) {
throw new ParsingException("Can't create an Obligation out of"
+ " a node that is not an Element node"
+ (src != null ? src.getLocationMsgForError() : ""));
}
if (!root.getLocalName().equals("Obligation")) {
throw new ParsingException("Can't create an Obligation with a "
+ root.getLocalName() + " element"
+ (src != null ? src.getLocationMsgForError() : ""));
}
URI id;
int fulfillOn = -1;
List<Attribute> assignments = new ArrayList<Attribute>();
AttributeFactory attrFactory = AttributeFactory.getInstance();
NamedNodeMap attrs = root.getAttributes();
try {
id = new URI(attrs.getNamedItem("ObligationId").getNodeValue());
} catch (Exception e) {
throw new ParsingException("Error parsing required attriubte "
+ "ObligationId" + (src != null ? src.getLocationMsgForError() : ""), e);
}
String effect = null;
try {
effect = attrs.getNamedItem("FulfillOn").getNodeValue();
} catch (Exception e) {
throw new ParsingException("Error parsing required attriubte "
+ "FulfillOn" + (src != null ? src.getLocationMsgForError() : ""), e);
}
if (effect.equals(Result.PERMIT)) {
fulfillOn = Result.DECISION_PERMIT;
} else if (effect.equals(Result.DENY)) {
fulfillOn = Result.DECISION_DENY;
} else {
throw new ParsingException("Invlid Effect type: " + effect
+ (src != null ? src.getLocationMsgForError() : ""));
}
boolean dynamic = false;
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE
&& node.getLocalName().equals("AttributeAssignment")) {
URI attrId = null;
try {
attrId =
new URI(node.getAttributes().
getNamedItem("AttributeId").getNodeValue());
AttributeValue attrValue = attrFactory.createValue(node);
dynamic |= attrValue.isDynamic();
assignments.add(new Attribute(attrId, null, attrValue));
} catch (URISyntaxException use) {
throw new ParsingException("Error parsing URI: " + use.getMessage()
+ (src != null ? src.getLocationMsgForError() : ""), use);
} catch (UnknownIdentifierException uie) {
throw new ParsingException("Unknown AttributeId: " + uie.getMessage()
+ (src != null ? src.getLocationMsgForError() : ""), uie);
} catch (Exception e) {
throw new ParsingException("Error parsing attribute " + attrId
+ "assignments"
+ (src != null ? src.getLocationMsgForError() : ""), e);
}
}
}
Obligation obligation = new Obligation(id, fulfillOn, assignments, dynamic);
if ( src != null ) {
obligation.src = src;
src.setXACMLObject(obligation);
}
return obligation;
}
/**
* Returns the id of this obligation
*
* @return the id
*/
public URI getId() {
return this.id;
}
/**
* Returns effect that will cause this obligation to be included in a
* response
*
* @return the fulfillOn effect
*/
public int getFulfillOn() {
return this.fulfillOn;
}
public RuntimeInfo getRuntimeInfo() {
return src;
}
/**
* Returns the attribute assignment data in this obligation. The
* <code>List</code> contains objects of type <code>Attribute</code>
* with only the correct attribute fields being used.
*
* @return the assignments
*/
public List<Attribute> getAssignments() {
return this.assignments;
}
/**
* Encodes this <code>Obligation</code> into its XML form and writes this
* out to the provided <code>OutputStream<code> with no indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName)
throws UnsupportedEncodingException {
encode(output, charsetName, new Indenter(0));
}
/**
* Encodes this <code>Obligation</code> into its XML form and writes this
* out to the provided <code>OutputStream<code> with indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
* @param indenter an object that creates indentation strings
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName,
Indenter indenter)
throws UnsupportedEncodingException {
PrintStream out;
if(charsetName == null) {
out = new PrintStream(output);
} else {
out = new PrintStream(output, false, charsetName);
}
String indent = indenter.makeString();
out.println(indent + "<Obligation ObligationId=\"" + this.id.toString()
+ "\" FulfillOn=\"" + Result.DECISIONS.get(this.fulfillOn)
+ "\">");
indenter.in();
Iterator<Attribute> it = this.assignments.iterator();
while (it.hasNext()) {
Attribute attr = it.next();
out.println(indenter.makeString()
+ "<AttributeAssignment AttributeId=\""
+ attr.getId().toString() + "\" DataType=\""
+ attr.getValue().getType().toString() + "\">"
+ attr.getValue().encode()
+ "</AttributeAssignment>");
}
indenter.out();
out.println(indent + "</Obligation>");
}
/**
* @param indenter
* @return the string representation of this obligation encoded in XML
*/
public String toString(Indenter indenter) {
String indent = indenter.makeString();
String result =indent + "<Obligation ObligationId=\""
+ this.id.toString() + "\" FulfillOn=\""
+ Result.DECISIONS.get(this.fulfillOn) + "\">" + Constants.nl;
indenter.in();
Iterator<Attribute> it = this.assignments.iterator();
while (it.hasNext()) {
Attribute attr = it.next();
result += indenter.makeString() +
"<AttributeAssignment AttributeId=\"" +
attr.getId().toString() + "\" DataType=\"" +
attr.getValue().getType().toString() + "\">" +
attr.getValue().encode() +
"</AttributeAssignment>" + Constants.nl;
}
indenter.out();
result += indent + "</Obligation>" + Constants.nl;
return result;
}
public Obligation evaluate(EvaluationCtx context) {
if ( ! dynamic_attributes ) {
return this;
} else {
Obligation obl = new Obligation(this.id, this.fulfillOn, this.dynamic_attributes);
List<Attribute> tmpAttr = new ArrayList<Attribute>();
for ( Attribute attr : this.assignments ) {
if ( attr.getValue().isDynamic()) {
EvaluationResult evaluationResult =attr.getValue().evaluate(context);
AttributeValue evaluated = evaluationResult.getAttributeValue();
tmpAttr.add(new Attribute(attr.getId(), attr.getIssuer(), evaluated));
} else {
tmpAttr.add(attr);
}
}
obl.assignments = Collections.unmodifiableList(tmpAttr);
// this.assignments = new ArrayList<Attribute>();
return obl;
}
}
public boolean isDynamic() {
return dynamic_attributes;
}
}

View File

@ -0,0 +1,480 @@
/*
* @(#)PDP.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.attr.AttributeValue;
import com.sun.xacml.ctx.RequestCtx;
import com.sun.xacml.ctx.RequestElement;
import com.sun.xacml.ctx.ResponseCtx;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.ctx.Status;
import com.sun.xacml.finder.AttributeFinder;
import com.sun.xacml.finder.PolicyFinder;
import com.sun.xacml.finder.PolicyFinderResult;
import com.sun.xacml.finder.ResourceFinder;
import com.sun.xacml.finder.ResourceFinderResult;
import com.sun.xacml.finder.RevocationFinder;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.log4j.Logger;
/**
* This is the core class for the XACML engine, providing the starting point
* for request evaluation. To build an XACML policy engine, you start by
* instantiating this object.
*
* @since 1.0
* @author Seth Proctor
*/
public class PDP
{
// the single attribute finder that can be used to find external values
private AttributeFinder attributeFinder;
// the single policy finder that will be used to resolve policies
private PolicyFinder policyFinder;
// the single resource finder that will be used to resolve resources
private ResourceFinder resourceFinder;
// the single revocation finder that will be used to find and validate
// revocations
private RevocationFinder revocationFinder;
// the logger we'll use for all messages
private static final Logger logger = Logger.getLogger(PDP.class.getName());
private static String buildBy;
private static String buildTime;
static {
Properties manifest = new Properties();
try {
String classUrl = "/" + PDP.class.getCanonicalName().replaceAll("\\.", "/") + ".class";
manifest.load(new URL(PDP.class.getResource(classUrl).toString().replace(classUrl, "/META-INF/MANIFEST.MF")).openStream());
} catch (Exception e) {
// ignore.. well, doesn't work..
}
if ( manifest.containsKey("Built-By") ) {
buildBy = manifest.getProperty("Built-By");
} else {
buildBy = "unkown";
}
if ( manifest.containsKey("Built-Time") ) {
buildTime = manifest.getProperty("Built-Time");
} else {
buildTime = "unkown";
}
}
/**
* Constructs a new <code>PDP</code> object with the given configuration
* information.
*
* @param config user configuration data defining how to find policies,
* resolve external attributes, etc.
*/
public PDP(PDPConfig config) {
logger.info("creating a PDP (built by " + buildBy + " at " + buildTime + ")");
this.attributeFinder = config.getAttributeFinder();
this.policyFinder = config.getPolicyFinder();
this.policyFinder.init(config);
this.resourceFinder = config.getResourceFinder();
this.revocationFinder = config.getRevocationFinder();
}
/**
* Attempts to evaluate the request against the policies known to this
* PDP. This is really the core method of the entire XACML specification,
* and for most people will provide what you want. If you need any special
* handling, you should look at the version of this method that takes an
* <code>EvaluationCtx</code>.
* <p>
* Note that if the request is somehow invalid (it was missing a required
* attribute, it was using an unsupported scope, etc), then the result
* will be a decision of INDETERMINATE.
*
* @param request the request to evaluate
*
* @return a response paired to the request
*/
public ResponseCtx evaluate(RequestCtx request) {
// try to create the EvaluationCtx out of the request
try {
return evaluate(new BasicEvaluationCtx(request,
this.attributeFinder, this.revocationFinder));
} catch (ParsingException pe) {
logger.info("the PDP receieved an invalid request", pe);
// there was something wrong with the request, so we return
// Indeterminate with a status of syntax error...though this
// may change if a more appropriate status type exists
ArrayList<String> code = new ArrayList<String>();
code.add(Status.STATUS_SYNTAX_ERROR);
Status status = new Status(code, pe.getMessage());
return new ResponseCtx(new Result(Result.DECISION_INDETERMINATE,
status));
}
}
/**
* Uses the given <code>EvaluationCtx</code> against the available
* policies to determine a response. If you are starting with a standard
* XACML Request, then you should use the version of this method that
* takes a <code>RequestCtx</code>. This method should be used only if
* you have a real need to directly construct an evaluation context (or
* if you need to use an <code>EvaluationCtx</code> implementation other
* than <code>BasicEvaluationCtx</code>).
*
* @param context representation of the request and the context used
* for evaluation
*
* @return a response based on the contents of the context
*/
public ResponseCtx evaluate(EvaluationCtx context) {
// see if we need to call the resource finder
if (context.getScope() != Constants.SCOPE_IMMEDIATE) {
AttributeValue parent
= context.getResourceId();
ResourceFinderResult resourceResult = null;
if (context.getScope() == Constants.SCOPE_CHILDREN) {
resourceResult =
this.resourceFinder.findChildResources(parent, context);
} else if (context.getScope() == Constants.SCOPE_DESCENDANTS) {
resourceResult =
this.resourceFinder.findDescendantResources(parent,
context);
} else if (context.getScope()
== Constants.SCOPE_XPATH_EXPRESSION) {
resourceResult =
this.resourceFinder.findXPathResources(parent, context);
} else if (context.getScope()
== Constants.SCOPE_ENTIRE_HIERARCHY) {
resourceResult =
this.resourceFinder.findHierarchyResources(parent,
context);
} else if (context.getScope()
== Constants.SCOPE_MULTIPE_ELEMENTS) {
return multipleElementsEval(context);
}
// see if we actually found anything
if (resourceResult == null || resourceResult.isEmpty()) {
// this is a problem, since we couldn't find any resources
// to work on...the spec is not explicit about what kind of
// error this is, so we're treating it as a processing error
ArrayList<String> code = new ArrayList<String>();
code.add(Status.STATUS_PROCESSING_ERROR);
String msg = "Couldn't find any resources to work on.";
return new
ResponseCtx(new Result(Result.DECISION_INDETERMINATE,
new Status(code, msg),
context));
}
// setup a set to keep track of the results
HashSet<Result> results = new HashSet<Result>();
// at this point, we need to go through all the resources we
// successfully found and start collecting results
Iterator<AttributeValue> it = resourceResult.getResources().iterator();
while (it.hasNext()) {
// get the next resource, and set it in the EvaluationCtx
AttributeValue resource = it.next();
context.setResourceId(resource);
// do the evaluation, and set the resource in the result
Result result = evaluateContext(context);
result.setResource(resource.encode());
// add the result
results.add(result);
}
// now that we've done all the successes, we add all the failures
// from the finder result
Map<AttributeValue, Status> failureMap = resourceResult.getFailures();
Iterator<Map.Entry<AttributeValue, Status>> it2 = failureMap.entrySet().iterator();
while (it2.hasNext()) {
Map.Entry<AttributeValue, Status> entry = it2.next();
// get the next resource, and use it to get its Status data
Status status = entry.getValue();
// add a new result
results.add(new Result(Result.DECISION_INDETERMINATE,
status, context));
}
// return the set of results
return new ResponseCtx(results);
}
// the scope was IMMEDIATE (or missing), so we can just evaluate
// the request and return whatever we get back
return new ResponseCtx(evaluateContext(context));
}
/**
* Protected helper to handle multiple elements of same category in the
* request (generates several requests).
*
* @param context
* @return Collected responses for the multiple elements evaluation.
*/
protected ResponseCtx multipleElementsEval(EvaluationCtx context) {
// Collect the different Maps of request elements here
Map<URI, Set<RequestElement>> elements = context.getRequestElements();
Iterator<URI> iter = elements.keySet().iterator();
Set<Set<RequestElement>> setOfsets = new HashSet<Set<RequestElement>>();
while (iter.hasNext()) {
Set<RequestElement> reSet = context.getCategory(iter.next());
//Do the division
if (setOfsets.isEmpty()) {
//Create initial set of sets
Iterator<RequestElement> iter2 = reSet.iterator();
while (iter2.hasNext()) {
RequestElement re = iter2.next();
Set<RequestElement> newSet = new HashSet<RequestElement>();
newSet.add(re);
setOfsets.add(newSet);
}
} else {
Iterator<Set<RequestElement>> iter2 = setOfsets.iterator();
Set<Set<RequestElement>> newSetOfSets = new HashSet<Set<RequestElement>>();
while (iter2.hasNext()) {
Set<RequestElement> subset = iter2.next();
Iterator<RequestElement> iter3 = reSet.iterator();
while(iter3.hasNext()) {
RequestElement re = iter3.next();
Set<RequestElement> newSet = new HashSet<RequestElement>();
newSet.addAll(subset);
newSet.add(re);
newSetOfSets.add(newSet);
}
}
setOfsets = newSetOfSets;
}
}
if (setOfsets.size() < 2) {
ArrayList<String> code = new ArrayList<String>();
code.add(Status.STATUS_PROCESSING_ERROR);
String msg = "Scope set to 'multipe elements' but could"
+ " only find one/zero";
return new ResponseCtx(
new Result(Result.DECISION_INDETERMINATE,
new Status(code, msg),
context));
}
// setup a set to keep track of the results
HashSet<Result> results = new HashSet<Result>();
// at this point, we need to go through all the sets we
// successfully found and start collecting creating requests
// and collect results
Iterator<Set<RequestElement>> it = setOfsets.iterator();
while (it.hasNext()) {
// get the next set of request elements, and create a
// new request for it.
Set<RequestElement> requestElements = it.next();
RequestCtx request = new RequestCtx(requestElements, null, null);
Result result = null;
try {
context = new BasicEvaluationCtx(request,
this.attributeFinder, this.revocationFinder);
} catch (ParsingException pe) {
logger.info("the PDP receieved an invalid request",
pe);
// there was something wrong with the request, so we collect
// Indeterminate with a status of syntax error...though this
// may change if a more appropriate status type exists
ArrayList<String> code = new ArrayList<String>();
code.add(Status.STATUS_SYNTAX_ERROR);
Status status = new Status(code, pe.getMessage());
result = new Result(Result.DECISION_INDETERMINATE, status);
}
if (result == null) {// do the evaluation if nothing went wrong
result = evaluateContext(context);
}
// add the result
results.add(result);
}
// return the set of results
return new ResponseCtx(results);
}
/**
* A protected helper routine that resolves a policy for the given
* context, and then tries to evaluate based on the policy.
* Can be overrider by subclasses.
*/
protected Result evaluateContext(EvaluationCtx context) {
// first off, try to find a policy
PolicyFinderResult finderResult
= this.policyFinder.findPolicy(context);
// see if there weren't any applicable policies
if (finderResult.notApplicable()) {
return new Result(Result.DECISION_NOT_APPLICABLE,
context);
}
// see if there were any errors in trying to get a policy
if (finderResult.indeterminate()) {
return new Result(Result.DECISION_INDETERMINATE,
finderResult.getStatus(),
context);
}
// we found a valid policy
context.newEvent(finderResult.getPolicy());
Result result = finderResult.getPolicy().evaluate(context);
context.closeCurrentEvent(result);
if (result == null) {
return new Result(Result.DECISION_NOT_APPLICABLE,
context);
}
return result;
}
/**
* A utility method that wraps the functionality of the other evaluate
* method with input and output streams. This is useful if you've got
* a PDP that is taking inputs from some stream and is returning
* responses through the same stream system. If the Request is invalid,
* then this will always return a decision of INDETERMINATE.
*
* @deprecated As of 1.2 this method should not be used. Instead, you
* should do your own stream handling, and then use one of
* the other <code>evaluate</code> methods. The problem
* with this method is that it often doesn't handle stream
* termination correctly (eg, with sockets).
*
* @param input a stream that contains an XML RequestType
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform default character set
* will be used.
*
* @return a stream that contains an XML ResponseType
* @throws UnsupportedEncodingException
*/
public OutputStream evaluate(InputStream input, String charsetName)
throws UnsupportedEncodingException {
RequestCtx request = null;
ResponseCtx response = null;
try {
request = RequestCtx.getInstance(input);
} catch (Exception pe) {
// the request wasn't formed correctly
ArrayList<String> code = new ArrayList<String>();
code.add(Status.STATUS_SYNTAX_ERROR);
Status status = new Status(code, "invalid request: " +
pe.getMessage());
response =
new ResponseCtx(new Result(Result.DECISION_INDETERMINATE,
status));
}
// if we didn't have a problem above, then we should go ahead
// with the evaluation
if (response == null) {
response = evaluate(request);
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.encode(out, charsetName, new Indenter());
return out;
}
/**
* @return The <code>AttributeFinder</code>
* (used by subclasses of the PDP).
*/
protected AttributeFinder getAttributeFinder() {
return this.attributeFinder;
}
/**
* @return The <code>RevocationFinder</code>
* (used by subclasses of the PDP).
*/
protected RevocationFinder getRevocationFinder() {
return this.revocationFinder;
}
/**
* @return The <code>PolicyFinder</code>
* (used by subclasses of the PDP).
*/
protected PolicyFinder getPolicyFinder() {
return this.policyFinder;
}
// public void setEmergencyLevel(EmergencyLevel level) {
// this.curEmgLevel = level;
// }
//
// public EmergencyLevel getEmergencyLevel() {
// return this.curEmgLevel;
// }
}

View File

@ -0,0 +1,185 @@
/*
* @(#)PDPConfig.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import java.util.HashMap;
import java.util.Map;
import com.sun.xacml.finder.AttributeFinder;
import com.sun.xacml.finder.PolicyFinder;
import com.sun.xacml.finder.ResourceFinder;
import com.sun.xacml.finder.RevocationFinder;
/**
* This class is used as a container that holds configuration
* information for the PDP, which includes the <code>AttributeFinder</code>,
* <code>PolicyFinder</code>, <code>ResourceFinder</code>, and the
* <code>RevocationFinder</code> that the PDP should use.
*
* @since 1.0
* @author Seth Proctor
* @author Marco Barreno
* @author Ludwig Seitz
*/
public class PDPConfig
{
//
private AttributeFinder attributeFinder;
//
private PolicyFinder policyFinder;
//
private ResourceFinder resourceFinder;
//
private RevocationFinder revocationFinder;
private Map<String, Object> customAttr = new HashMap<String, Object>();
/**
* Constructor that creates a <code>PDPConfig</code> from components.
*
* @param attributeFinder the <code>AttributeFinder</code> that the PDP
* should use, or null if it shouldn't use any
* @param policyFinder the <code>PolicyFinder</code> that the PDP
* should use, or null if it shouldn't use any
* @param resourceFinder the <code>ResourceFinder</code> that the PDP
* should use, or null if it shouldn't use any
* @param revocationFinder The <code>RevocationFinder</code> that the PDP
* should use, or null if it shouldn't use any
*/
public PDPConfig(AttributeFinder attributeFinder,
PolicyFinder policyFinder,
ResourceFinder resourceFinder,
RevocationFinder revocationFinder) {
if (attributeFinder != null) {
this.attributeFinder = attributeFinder;
} else {
this.attributeFinder = new AttributeFinder();
}
if (policyFinder != null) {
this.policyFinder = policyFinder;
} else {
this.policyFinder = new PolicyFinder();
}
if (resourceFinder != null) {
this.resourceFinder = resourceFinder;
} else {
this.resourceFinder = new ResourceFinder();
}
if (revocationFinder != null) {
this.revocationFinder = revocationFinder;
} else {
this.revocationFinder = new RevocationFinder();
}
}
/**
* Returns the <code>AttributeFinder</code> that was configured, or
* null if none was configured
*
* @return the <code>AttributeFinder</code> or null
*/
public AttributeFinder getAttributeFinder() {
return this.attributeFinder;
}
/**
* Returns the <code>PolicyFinder</code> that was configured, or
* null if none was configured
*
* @return the <code>PolicyFinder</code> or null
*/
public PolicyFinder getPolicyFinder() {
return this.policyFinder;
}
/**
* Returns the <code>ResourceFinder</code> that was configured, or
* null if none was configured
*
* @return the <code>ResourceFinder</code> or null
*/
public ResourceFinder getResourceFinder() {
return this.resourceFinder;
}
/**
* Returns the <code>RevocationFinder</code> that was configured, or
* null if none was configured
*
* @return the <code>RevocationFinder</code> or null
*/
public RevocationFinder getRevocationFinder() {
return this.revocationFinder;
}
public void setCutomAttrs(Map<String, Object> attrs) {
if ( customAttr != null && customAttr.size() > 0 ) {
throw new RuntimeException("The custom attributes for PDPConfig may not be overwritten, if already values are stored!");
}
customAttr = attrs;
}
public void addCutomAttrs(Map<String, Object> attrs) {
if ( customAttr == null ) {
this.customAttr = attrs;
} else {
customAttr.putAll(attrs);
}
}
public void setCustomAttr(String key, Object value) {
customAttr.put(key, value);
}
public Object getCustomAttr(String key) {
return customAttr.get(key);
}
public Map<String, Object> getCustomAttrs() {
return customAttr;
}
}

View File

@ -0,0 +1,105 @@
/*
* @(#)ParsingException.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
/**
* Exception that gets thrown if any general parsing error occurs.
*
* @since 1.0
* @author Seth Proctor
*/
public class ParsingException extends Exception
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Constructs a new <code>ParsingException</code> with no message
* or cause.
*/
public ParsingException() {
//parsing exception with no message or cause.
}
/**
* Constructs a new <code>ParsingException</code> with a message,
* but no cause. The message is saved for later retrieval by the
* {@link java.lang.Throwable#getMessage() Throwable.getMessage()}
* method.
*
* @param message the detail message (<code>null</code> if nonexistent
* or unknown)
*/
public ParsingException(String message) {
super(message);
}
/**
* Constructs a new <code>ParsingException</code> with a cause,
* but no message. The cause is saved for later retrieval by the
* {@link java.lang.Throwable#getCause() Throwable.getCause()}
* method.
*
* @param cause the cause (<code>null</code> if nonexistent
* or unknown)
*/
public ParsingException(Throwable cause) {
super(cause);
}
/**
* Constructs a new <code>ParsingException</code> with a message
* and a cause. The message and cause are saved for later retrieval
* by the
* {@link java.lang.Throwable#getMessage() Throwable.getMessage()} and
* {@link java.lang.Throwable#getCause() Throwable.getCause()}
* methods.
*
* @param message the detail message (<code>null</code> if nonexistent
* or unknown)
* @param cause the cause (<code>null</code> if nonexistent
* or unknown)
*/
public ParsingException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,819 @@
/*
* @(#)Policy.java
*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.combine.CombinerElement;
import com.sun.xacml.combine.CombinerParameter;
import com.sun.xacml.combine.RuleCombinerElement;
import com.sun.xacml.combine.RuleCombiningAlgorithm;
import com.sun.xacml.cond.VariableDefinition;
import com.sun.xacml.cond.VariableManager;
import com.sun.xacml.ctx.PolicyIssuer;
import com.sun.xacml.debug.RuntimeInfo;
import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Represents one of the two top-level constructs in XACML, the PolicyType.
* This contains rules, which in turn contain most of the logic of
* a policy.
*
* @since 1.0
* @author Seth Proctor
* @author Ludwig Seitz
*/
public class Policy extends AbstractPolicy {
/**
* The <code>Set</code> of <code>VariableDefinition</code>s in this policy
*/
private Set<VariableDefinition> definitions;
/**
* Creates a new <code>Policy</code> with only the required elements.
*
* @param id the policy identifier
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
*
* @param target the <code>Target</code> for this policy
*/
public Policy(URI id, RuleCombiningAlgorithm combiningAlg, Target target) {
this(id, null, null, combiningAlg, null, null, target, null,
null, null);
}
/**
* Creates a new <code>Policy</code> with only the required elements.
*
* @param id the policy identifier
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param issuer the <code>PolicyIssuer</code> for this policy or null
* if it is the trusted issuer
* @param target the <code>Target</code> for this policy
*/
public Policy(URI id, RuleCombiningAlgorithm combiningAlg,
PolicyIssuer issuer, Target target) {
this(id, null, null, combiningAlg, null, issuer, target, null,
null, null);
}
/**
* Creates a new <code>Policy</code> with only the required elements
* plus rules.
*
* @param id the policy identifier
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param target the <code>Target</code> for this policy
* @param rules a list of <code>Rule</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, RuleCombiningAlgorithm combiningAlg, Target target,
List<Rule> rules) {
this(id, null, null, combiningAlg, null, null, target, null,
rules, null);
}
/**
* Creates a new <code>Policy</code> with only the required elements
* plus rules.
*
* @param id the policy identifier
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param issuer the <code>PolicyIssuer</code> for this policy or null
* if it is the trusted issuer
* @param target the <code>Target</code> for this policy
* @param rules a list of <code>Rule</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, RuleCombiningAlgorithm combiningAlg,
PolicyIssuer issuer, Target target, List<Rule> rules) {
this(id, null, null, combiningAlg, null, issuer, target, null,
rules, null);
}
/**
* Creates a new <code>Policy</code> with the required elements plus
* rules and a String description.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy
* @param target the <code>Target</code> for this policy
* @param rules a list of <code>Rule</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, Target target, List<Rule> rules) {
this(id, version, xacmlVersion, combiningAlg, description, null,
target, null, rules, null);
}
/**
* Creates a new <code>Policy</code> with the required elements plus
* a version, rules, and a String description. Note that the version
* is an XACML 2.0 feature.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this must
* always be null for XACML 1.x policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy
* @param issuer the <code>PolicyIssuer</code> for this policy or null
* if it is the trusted issuer
* @param target the <code>Target</code> for this policy
* @param rules a list of <code>Rule</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer, Target target,
List<Rule> rules) {
this(id, version, xacmlVersion, combiningAlg, description, issuer,
target, null, rules, null);
}
/**
* Creates a new <code>Policy</code> with the required elements plus
* rules, a String description and policy defaults.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy
* @param target the <code>Target</code> for this policy
* @param defaultVersion the XPath version to use
* @param rules a list of <code>Rule</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, Target target, String defaultVersion,
List<Rule> rules) {
this(id, version, xacmlVersion, combiningAlg, description, null,
target, defaultVersion, rules, null);
}
/**
* Creates a new <code>Policy</code> with the required elements plus
* a version, rules, a String description and policy defaults. Note that
* the version is an XACML 2.0 feature.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this must
* always be null for XACML 1.x policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy
* @param issuer the <code>PolicyIssuer</code> for this policy or null
* if it is the trusted issuer
* @param target the <code>Target</code> for this policy
* @param defaultVersion the XPath version to use
* @param rules a list of <code>Rule</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer, Target target,
String defaultVersion, List<Rule> rules) {
this(id, version, xacmlVersion, combiningAlg, description, issuer,
target, defaultVersion, rules, null);
}
/**
* Creates a new <code>Policy</code> with the required elements plus
* a version, rules, a String description, policy defaults, and
* obligations. Note that the version is an XACML 2.0 feature.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this must
* always be null for XACML 1.x policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy
* @param target the <code>Target</code> for this policy
* @param defaultVersion the XPath version to use
* @param rules a list of <code>Rule</code> objects
* @param obligations a set of <code>Obligations</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, Target target, String defaultVersion,
List<Rule> rules, Set<Obligation> obligations) {
this(id, version, xacmlVersion, combiningAlg, description, null,
target, defaultVersion, rules, obligations, null);
}
/**
* Creates a new <code>Policy</code> with the required elements plus
* rules, a String description, policy defaults, and obligations.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy
* @param issuer the <code>PolicyIssuer</code> for this policy or null
* if it is the trusted issuer
* @param target the <code>Target</code> for this policy
* @param defaultVersion the XPath version to use
* @param rules a list of <code>Rule</code> objects
* @param obligations a set of <code>Obligations</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer, Target target,
String defaultVersion, List<Rule> rules, Set<Obligation> obligations) {
this(id, version, xacmlVersion, combiningAlg, description, issuer,
target, defaultVersion, rules, obligations, null);
}
/**
* Creates a new <code>Policy</code> with the required elements plus
* a version, rules, a String description, policy defaults, obligations,
* and variable definitions. Note that the version and definitions are
* XACML 2.0 features.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this must
* always be null for XACML 1.x policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy
* @param target the <code>Target</code> for this policy
* @param defaultVersion the XPath version to use
* @param rules a list of <code>Rule</code> objects
* @param obligations a set of <code>Obligations</code> objects
* @param definitions a set of <code>VariableDefinition</code> objects
* that must provide all definitions referenced by
* all <code>VariableReference</code>s in the policy
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, Target target, String defaultVersion,
List<Rule> rules, Set<Obligation> obligations, Set<VariableDefinition> definitions) {
this(id, version, xacmlVersion, combiningAlg, description, null, target,
defaultVersion, rules, obligations, definitions);
}
/**
* Creates a new <code>Policy</code> with the required elements plus
* rules, a String description, policy defaults, obligations, and
* variable definitions.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy
* @param issuer the <code>PolicyIssuer</code> for this policy or null
* if it is the trusted issuer
* @param target the <code>Target</code> for this policy
* @param defaultVersion the XPath version to use
* @param rules a list of <code>Rule</code> objects
* @param obligations a set of <code>Obligations</code> objects
* @param definitions a set of <code>VariableDefinition</code> objects
* that must provide all definitions referenced by
* all <code>VariableReference</code>s in the policy
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer, Target target,
String defaultVersion, List<Rule> rules, Set<Obligation> obligations,
Set<VariableDefinition> definitions) {
super(id, version, xacmlVersion, combiningAlg, description, issuer,
target, defaultVersion, obligations, null,
Constants.MAX_DELEGATION_DEPTH_UNDEFINED);
List<CombinerElement> list = null;
// check that the list contains only rules
if (rules != null) {
list = new ArrayList<CombinerElement>();
Iterator<Rule> it = rules.iterator();
while (it.hasNext()) {
// Object o = it.next();
// if (! (o instanceof Rule)) {
// throw new IllegalArgumentException("non-Rule in rules");
// }
list.add(new RuleCombinerElement(it.next()));
}
}
setChildren(list);
// save the definitions
if (definitions == null) {
this.definitions = VariableDefinition.EMPTY_SET;
} else {
this.definitions = Collections.
unmodifiableSet(new HashSet<VariableDefinition>(definitions));
}
}
/**
* Creates a new <code>Policy</code> with the required and optional
* elements. If you need to provide combining algorithm parameters, you
* need to use this constructor. Note that unlike the other constructors
* in this class, the rules list is actually a list of
* <code>CombinerElement</code>s used to match a rule with any
* combiner parameters it may have.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this must
* always be null for XACML 1.x policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy or
* null if there is no description
* @param target the <code>Target</code> for this policy
* @param defaultVersion the XPath version to use or null if there is
* no default version
* @param ruleElements a list of <code>RuleCombinerElement</code> objects
* or null if there are no rules
* @param obligations a set of <code>Obligations</code> objects or null
* if there are no obligations
* @param definitions a set of <code>VariableDefinition</code> objects
* that must provide all definitions referenced by
* all <code>VariableReference</code>s in the policy
* @param parameters the <code>List</code> of
* <code>CombinerParameter</code>s provided for general
* use by the combining algorithm
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>RuleCombinerElement</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, Target target, String defaultVersion,
List<CombinerElement> ruleElements, Set<Obligation> obligations, Set<VariableDefinition> definitions,
List<CombinerParameter> parameters) {
this(id, version, xacmlVersion, combiningAlg, description, null,
target, defaultVersion, ruleElements, obligations,
definitions, parameters,
Constants.MAX_DELEGATION_DEPTH_UNDEFINED);
}
/**
* Creates a new <code>Policy</code> with the required and optional
* elements. If you need to provide combining algorithm parameters, you
* need to use this constructor. Note that unlike the other constructors
* in this class, the rules list is actually a list of
* <code>CombinerElement</code>s used to match a rule with any
* combiner parameters it may have.
*
* @param id the policy identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy or
* null if there is no description
* @param issuer the PolicyIssuer or null if this is the trusted issuer
* @param target the <code>Target</code> for this policy
* @param defaultVersion the XPath version to use or null if there is
* no default version
* @param ruleElements a list of <code>RuleCombinerElement</code> objects
* or null if there are no rules
* @param obligations a set of <code>Obligations</code> objects or null
* if there are no obligations
* @param definitions a set of <code>VariableDefinition</code> objects
* that must provide all definitions referenced by
* all <code>VariableReference</code>s in the policy
* @param parameters the <code>List</code> of
* <code>CombinerParameter</code>s provided for general
* use by the combining algorithm
* @param maxDelegationDepth the maximum delegation depth authorised
* by this policy set.
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>RuleCombinerElement</code>
*/
public Policy(URI id, String version, String xacmlVersion,
RuleCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer, Target target,
String defaultVersion, List<CombinerElement> ruleElements, Set<Obligation> obligations,
Set<VariableDefinition> definitions, List<CombinerParameter> parameters, int maxDelegationDepth) {
super(id, version, xacmlVersion, combiningAlg, description, issuer,
target, defaultVersion, obligations, parameters,
maxDelegationDepth);
// check that the list contains only RuleCombinerElements
if (ruleElements != null) {
Iterator<CombinerElement> it = ruleElements.iterator();
while (it.hasNext()) {
CombinerElement o = it.next();
if (! (o instanceof RuleCombinerElement)) {
throw new IllegalArgumentException("non-Rule in rules");
}
}
}
setChildren(ruleElements);
// save the definitions
if (definitions == null) {
this.definitions = VariableDefinition.EMPTY_SET;
} else {
this.definitions = Collections.
unmodifiableSet(new HashSet<VariableDefinition>(definitions));
}
}
/**
* Creates a new Policy based on the given root node. This is
* private since every class is supposed to use a getInstance() method
* to construct from a Node, but since we want some common code in the
* parent class, we need this functionality in a constructor.
*/
private Policy(Node root) throws ParsingException {
super(root, "Policy", "RuleCombiningAlgId");
this.src = RuntimeInfo.getRuntimeInfo(this, root, ELEMENT_TYPE.POLICY);
List<Rule> rules = new ArrayList<Rule>();
Map<String, List<CombinerParameter>> parameters = new HashMap<String, List<CombinerParameter>>();
Map<Object, Node> variableIds = new HashMap<Object, Node>();
PolicyMetaData metaData = getMetaData();
// first off, go through and look for any definitions to get their
// identifiers up front, since before we parse any references we'll
// need to know what definitions we support
NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE
&& child.getLocalName().equals("VariableDefinition")) {
String id = null;
if (child.getAttributes().getNamedItem("VariableId") != null) {
id = child.getAttributes().getNamedItem("VariableId")
.getNodeValue();
} else {
throw new ParsingException("Error while trying to parse "
+ "VariableId in a Policy");
}
// it's an error to have more than one definition with the
// same identifier
if (variableIds.containsKey(id)) {
throw new ParsingException("multiple definitions for " +
"variable " + id);
}
variableIds.put(id, child);
}
}
// now create a manager with the defined variable identifiers
VariableManager manager = new VariableManager(variableIds, metaData);
this.definitions = new HashSet<VariableDefinition>();
// next, collect the Policy-specific elements
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
String name = child.getLocalName();
if (name.equals("Rule")) {
rules.add(Rule.getInstance(child, metaData, manager));
} else if (name.equals("RuleCombinerParameters")) {
String ref = null;
if (child.getAttributes() != null) {
if (child.getAttributes().getNamedItem("RuleIdRef")
!= null) {
ref = child.getAttributes()
.getNamedItem("RuleIdRef")
.getNodeValue();
} else {
throw new ParsingException("Required xml-attribute"
+ " RuleIdRef not found");
}
} else {
throw new ParsingException("Required xml-attribute"
+ " RuleIdRef not found");
}
// if we found the parameter before than add it the end of
// the previous paramters, otherwise create a new entry
if (parameters.containsKey(ref)) {
List<CombinerParameter> list = parameters.get(ref);
parseParameters(list, child);
} else {
List<CombinerParameter> list = new ArrayList<CombinerParameter>();
parseParameters(list, child);
parameters.put(ref, list);
}
} else if (name.equals("VariableDefinition")) {
String id = null;
if (child.getAttributes() != null) {
if (child.getAttributes().getNamedItem("VariableId")
!= null) {
id = child.getAttributes()
.getNamedItem("VariableId")
.getNodeValue();
} else {
throw new ParsingException("Required xml-attribute"
+ " VariableId not found");
}
} else {
throw new ParsingException("Required xml-attribute"
+ " VariableId not found");
}
// parsing definitions is a little strange, since they can
// contain references to definitions we haven't yet parsed
// or circular references, but we still want to verify the
// references and the types...so, for each definition, we
// ask the manager though getDefinition, which takes care
// of loading any forward references, handles loops, etc.
// It also handles caching definitions, so we don't end
// up parsing the same definitions multiple times
this.definitions.add(manager.getDefinition(id));
}
}
}
this.definitions = Collections.unmodifiableSet(this.definitions);
// now make sure that we can match up any parameters we may have
// found to a cooresponding Rule...
List<CombinerElement> elements = new ArrayList<CombinerElement>();
Iterator<Rule> it = rules.iterator();
while (it.hasNext()) {
Rule rule = it.next();
String id = rule.getId().toString();
List<CombinerParameter> list = parameters.remove(id);
elements.add(new RuleCombinerElement(rule, list));
}
// ...and that there aren't extra parameters
if (! parameters.isEmpty()) {
throw new ParsingException("Unmatched parameters in Rule");
}
// finally, set the list of Rules
setChildren(elements);
}
/**
* The clone method
* FIXME: this does no deep copy on the Lists and Sets.
*
* @return a copy of this object.
*/
public Object clone() {
Policy clone = (Policy)super.clone();
clone.definitions = new HashSet<VariableDefinition>(this.definitions);
clone.setChildren(this.getChildElements());
return clone;
}
/**
* Helper method that parses out a collection of combiner parameters.
*/
private void parseParameters(List<CombinerParameter> parameters, Node root)
throws ParsingException
{
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE
&& node.getLocalName().equals("CombinerParameter")) {
parameters.add(CombinerParameter.getInstance(node));
}
}
}
/**
* Creates an instance of a <code>Policy</code> object based on a
* DOM node. The node must be the root of PolicyType XML object,
* otherwise an exception is thrown.
*
* @param root the DOM root of a PolicyType XML type
*
* @return A policy object.
*
* @throws ParsingException if the PolicyType is invalid
*/
public static Policy getInstance(Node root)
throws ParsingException {
// first off, check that it's the right kind of node
if (root.getNodeType() != Node.ELEMENT_NODE
|| ! root.getLocalName().equals("Policy")) {
throw new ParsingException("Cannot create Policy from root of " +
"type " + root.getLocalName());
}
return new Policy(root);
}
/**
* Returns the variable definitions in this Policy.
*
* @return a <code>Set</code> of <code>VariableDefinition</code>s
*/
public Set<VariableDefinition> getVariableDefinitions() {
return this.definitions;
}
/**
* Encodes this <code>Policy</code> into its XML representation and writes
* this encoding to the given <code>OutputStream</code> with no
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName)
throws UnsupportedEncodingException {
encode(output, charsetName, new Indenter(0));
}
/**
* Encodes this <code>Policy</code> into its XML representation and writes
* this encoding to the given <code>OutputStream</code> with
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
* @param indenter an object that creates indentation strings
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName,
Indenter indenter)
throws UnsupportedEncodingException {
PrintStream out;
if(charsetName == null) {
out = new PrintStream(output);
} else {
out = new PrintStream(output, false, charsetName);
}
String indent = indenter.makeString();
out.println(indent + "<Policy xmlns=\""
+ getMetaData().getXACMLIdentifier()
+ "\" PolicyId=\"" + getId().toString()
+ "\" RuleCombiningAlgId=\""
+ getCombiningAlg().getIdentifier().toString()
+ "\"");
if (getMaxDelegationDepth()
!= Constants.MAX_DELEGATION_DEPTH_UNDEFINED) {
out.println("MaxDelegationDepth=\"" + getMaxDelegationDepth()
+ "\">");
} else {
out.println(">");
}
indenter.in();
String nextIndent = indenter.makeString();
String description = getDescription();
if (description != null) {
out.println(nextIndent + "<Description>" + description +
"</Description>");
}
encodePolicyIssuer(output, charsetName, indenter);
String version = getDefaultVersion();
if (version != null) {
out.println("<PolicyDefaults><XPathVersion>" + version +
"</XPathVersion></PolicyDefaults>");
}
getTarget().encode(output, charsetName, indenter);
Iterator<VariableDefinition> it = this.definitions.iterator();
while (it.hasNext()) {
((VariableDefinition)(it.next())).encode(output, charsetName,
indenter);
}
encodeCommonElements(output, charsetName, indenter);
indenter.out();
out.println(indent + "</Policy>");
}
public RuntimeInfo getRuntimeInfo() {
return this.src;
}
}

View File

@ -0,0 +1,306 @@
/*
* @(#)PolicyMetaData.java
*
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.attr.AttributeFactory;
import com.sun.xacml.attr.AttributeFactoryProxy;
import com.sun.xacml.combine.CombiningAlgFactory;
import com.sun.xacml.combine.CombiningAlgFactoryProxy;
import com.sun.xacml.cond.FunctionFactory;
import com.sun.xacml.cond.FunctionFactoryProxy;
/**
* This is used to share polcy meta-data throughout the policy tree. Examples
* of common meta-data include the version of XACML or XPath being used in
* a policy.
*
* @since 2.0
* @author Seth Proctor
* @author Ludwig Seitz
*/
public class PolicyMetaData
{
// private mapping from XACML version number to identifier string
private static String [] xacmlIdentifiers = {
Constants.XACML_1_0_IDENTIFIER,
Constants.XACML_1_0_IDENTIFIER,
Constants.XACML_2_0_IDENTIFIER,
Constants.XACML_3_0_IDENTIFIER};
// private mapping from XPath version number to identifier string
private static String [] xpathIdentifiers = { null,
Constants.XPATH_1_0_IDENTIFIER };
// the version of XACML
private int xacmlVersion;
// the version of XPath, or null if none is specified
private int xpathVersion;
// the factories used with this policy
private AttributeFactoryProxy afProxy;
private CombiningAlgFactoryProxy cafProxy;
private FunctionFactoryProxy ffProxy;
/**
* Creates a <code>PolicyMetaData</code> instance with all the parameters
* set to their default values.
*/
public PolicyMetaData() {
this(Constants.XACML_DEFAULT_VERSION,
Constants.XPATH_VERSION_UNSPECIFIED);
}
/**
* Creates a <code>PolicyMetaData</code> instance with the given
* parameters. The default factories are assumed.
*
* @param xacmlVersion the version of XACML used in a policy
* @param xpathVersion the XPath version to use in any selectors
*/
public PolicyMetaData(int xacmlVersion, int xpathVersion) {
this(xacmlVersion, xpathVersion, null, null, null);
}
/**
* Creates a <code>PolicyMetaData</code> instance with the given
* parameters. The default factories are assumed.
*
* @param xacmlVersion the version of XACML used in a policy
* @param xpathVersion the XPath version to use in any selectors, or
* null if this is unspecified (ie, not supplied in
* the defaults section of the policy)
*
* @throws IllegalArgumentException if the identifier strings are unknown
*/
public PolicyMetaData(String xacmlVersion, String xpathVersion) {
this(xacmlVersion, xpathVersion, null, null, null);
}
/**
* Creates a <code>PolicyMetaData</code> instance with the given
* parameters. A proxy value of null implies the default factory.
*
* @param xacmlVersion the version of XACML used in a policy
* @param xpathVersion the XPath version to use in any selectors
* @param attributeFactoryProxy
* @param combiningAlgFactoryProxy
* @param functionFactoryProxy
*/
public PolicyMetaData(int xacmlVersion, int xpathVersion,
AttributeFactoryProxy attributeFactoryProxy,
CombiningAlgFactoryProxy combiningAlgFactoryProxy,
FunctionFactoryProxy functionFactoryProxy) {
this.xacmlVersion = xacmlVersion;
this.xpathVersion = xpathVersion;
proxySetup(attributeFactoryProxy, combiningAlgFactoryProxy,
functionFactoryProxy);
}
/**
* Creates a <code>PolicyMetaData</code> instance with the given
* parameters.
*
* @param xacmlVersion the version of XACML used in a policy
* @param xpathVersion the XPath version to use in any selectors, or
* null if this is unspecified (ie, not supplied in
* the defaults section of the policy)
* @param attributeFactoryProxy
* @param combiningAlgFactoryProxy
* @param functionFactoryProxy
*
* @throws IllegalArgumentException if the identifier strings are unknown
*/
public PolicyMetaData(String xacmlVersion, String xpathVersion,
AttributeFactoryProxy attributeFactoryProxy,
CombiningAlgFactoryProxy combiningAlgFactoryProxy,
FunctionFactoryProxy functionFactoryProxy) {
if (xacmlVersion == null) {
this.xacmlVersion = Constants.XACML_DEFAULT_VERSION;
} else if (xacmlVersion.equals(Constants.XACML_1_0_IDENTIFIER)) {
this.xacmlVersion = Constants.XACML_VERSION_1_0;
} else if (xacmlVersion.equals(Constants.XACML_2_0_IDENTIFIER)) {
this.xacmlVersion = Constants.XACML_VERSION_2_0;
} else if (xacmlVersion.equals(Constants.XACML_3_0_IDENTIFIER)) {
this.xacmlVersion = Constants.XACML_VERSION_3_0;
} else if (xacmlVersion.equals(Constants.XACML_1_0_CTX_ID)) {
this.xacmlVersion = Constants.XACML_VERSION_1_0;
} else if (xacmlVersion.equals(Constants.XACML_2_0_CTX_ID)) {
this.xacmlVersion = Constants.XACML_VERSION_2_0;
} else {
throw new IllegalArgumentException("Unknown XACML version " +
"string: " + xacmlVersion);
}
if (xpathVersion != null) {
if (! xpathVersion.equals(Constants.XPATH_1_0_IDENTIFIER)) {
throw new IllegalArgumentException("Unsupported XPath " +
" version: " +
xpathVersion);
}
this.xpathVersion = Constants.XPATH_VERSION_1_0;
} else {
this.xpathVersion = Constants.XPATH_VERSION_UNSPECIFIED;
}
proxySetup(attributeFactoryProxy, combiningAlgFactoryProxy,
functionFactoryProxy);
}
/**
*
*/
private void proxySetup(AttributeFactoryProxy attributeFactoryProxy,
CombiningAlgFactoryProxy combiningAlgFactoryProxy,
FunctionFactoryProxy functionFactoryProxy) {
if (attributeFactoryProxy == null) {
this.afProxy = new AttributeFactoryProxy() {
public AttributeFactory getFactory() {
return AttributeFactory.getInstance();
}
};
} else {
this.afProxy = attributeFactoryProxy;
}
if (combiningAlgFactoryProxy == null) {
this.cafProxy = new CombiningAlgFactoryProxy() {
public CombiningAlgFactory getFactory() {
return CombiningAlgFactory.getInstance();
}
};
} else {
this.cafProxy = combiningAlgFactoryProxy;
}
if (functionFactoryProxy == null) {
this.ffProxy = FunctionFactory.getInstance();
} else {
this.ffProxy = functionFactoryProxy;
}
}
/**
* Returns which version of XACML is specified in this meta-data.
*
* @return the XACML version
*/
public int getXACMLVersion() {
return this.xacmlVersion;
}
/**
* Returns the identifier string for the specified version of XACML.
*
* @return the identifier string
*/
public String getXACMLIdentifier() {
return xacmlIdentifiers[this.xacmlVersion];
}
/**
* Returns which version of XPath is specified in this meta-data.
*
* @return the XPath version or null
*/
public int getXPathVersion() {
return this.xpathVersion;
}
/**
* Returns the identifier string for the specified version of XPath, or
* null if no version is specified.
*
* @return the identifier string or null
*/
public String getXPathIdentifier() {
return xpathIdentifiers[this.xpathVersion];
}
/**
* Returns the <code>AttributeFactory</code> used by the associated
* policy.
*
* @return a <code>AttributeFactory</code>
*/
public AttributeFactory getAttributeFactory() {
return this.afProxy.getFactory();
}
/**
* Returns the <code>CombiningAlgFactory</code> used by the associated
* policy.
*
* @return a <code>CombiningAlgFactory</code>
*/
public CombiningAlgFactory getCombiningAlgFactory() {
return this.cafProxy.getFactory();
}
/**
* Returns the Target <code>FunctionFactory</code> used by the associated
* policy.
*
* @return a <code>FunctionFactory</code>
*/
public FunctionFactory getTargetFunctionFactory() {
return this.ffProxy.getTargetFactory();
}
/**
* Returns the Condition <code>FunctionFactory</code> used by the
* associated policy.
*
* @return a <code>FunctionFactory</code>
*/
public FunctionFactory getConditionFunctionFactory() {
return this.ffProxy.getConditionFactory();
}
/**
* Returns the General <code>FunctionFactory</code> used by the associated
* policy.
*
* @return a <code>FunctionFactory</code>
*/
public FunctionFactory getGeneralFunctionFactory() {
return this.ffProxy.getGeneralFactory();
}
}

View File

@ -0,0 +1,647 @@
/*
* @(#)PolicyReference.java
*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.combine.CombinerElement;
import com.sun.xacml.combine.CombiningAlgorithm;
import com.sun.xacml.ctx.PolicyIssuer;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.ctx.Status;
import com.sun.xacml.debug.RuntimeInfo;
import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE;
import com.sun.xacml.finder.PolicyFinder;
import com.sun.xacml.finder.PolicyFinderResult;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import org.apache.log4j.Logger;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* This class is used as a placeholder for the PolicyIdReference and
* PolicySetIdReference fields in a PolicySetType. When a reference is used
* in a policy set, it is telling the PDP to use an external policy in
* the current policy. Each time the PDP needs to evaluate that policy
* reference, it asks the policy finder for the policy. Typically the policy
* finder will have cached the referenced policy, so this isn't too slow.
* <p>
* NOTE: all of the accessor methods, the match method, and the evaluate method
* require this class to ask its <code>PolicyFinder</code> for the referenced
* policy, which can be a slow operation. Care should be taken, therefore in
* calling these methods too often. Also note that it's not safe to cache the
* results of these calls, since the referenced policy may change.
*
* @since 1.0
* @author Seth Proctor
* @author Ludwig Seitz
*/
public class PolicyReference extends AbstractPolicy {
/**
* Identifies this as a reference to a <code>Policy</code>
*/
public static final int POLICY_REFERENCE = 0;
/**
* Identifies this as a reference to a <code>PolicySet</code>
*/
public static final int POLICYSET_REFERENCE = 1;
// the reference
private URI reference;
// the reference type
private int policyType;
// and version constraints on this reference
private VersionConstraints constraints;
// the finder to use in finding the referenced policy
private PolicyFinder finder;
// the meta-data for the parent policy
private PolicyMetaData parentMetaData;
// the referenced policy
private AbstractPolicy referencedPolicy;
// the logger we'll use for all messages
private static final Logger logger =
Logger.getLogger(PolicyReference.class.getName());
/**
* Creates a new <code>PolicyReference</code> instance. This has no
* constraints on version matching. Note that an XACML 1.x reference may
* not have any constraints.
*
* @param reference the reference to the policy
* @param policyType one of the two fields in this class
* @param finder the <code>PolicyFinder</code> used to handle the reference
* @param parentMetaData the meta-data associated with the containing
* (parent) policy
*
* @throws IllegalArgumentException if the input policyType isn't valid
*/
public PolicyReference(URI reference, int policyType, PolicyFinder finder,
PolicyMetaData parentMetaData)
throws IllegalArgumentException
{
this(reference, policyType, new VersionConstraints(null, null, null),
finder, parentMetaData);
}
/**
* Creates a new <code>PolicyReference</code> instance with version
* constraints. Note that an XACML 1.x reference may not have any
* constraints.
*
* @param reference the reference to the policy
* @param policyType one of the two fields in this class
* @param constraints any optional constraints on the version of the
* referenced policy (this is never null, but
* it may impose no constraints, and in fact will
* never impose constraints when used from a pre-2.0
* XACML policy)
* @param finder the <code>PolicyFinder</code> used to handle the reference
* @param parentMetaData the meta-data associated with the containing
* (parent) policy
*
* @throws IllegalArgumentException if the input policyType isn't valid
*/
public PolicyReference(URI reference, int policyType,
VersionConstraints constraints, PolicyFinder finder,
PolicyMetaData parentMetaData)
throws IllegalArgumentException {
// check if input policyType is a valid value
if ((policyType != POLICY_REFERENCE) &&
(policyType != POLICYSET_REFERENCE)) {
throw new IllegalArgumentException("Input policyType is not a" +
"valid value");
}
this.reference = reference;
this.policyType = policyType;
this.constraints = constraints;
this.finder = finder;
this.parentMetaData = parentMetaData;
}
/**
* The clone method.
* FIXME: this does no deep copy on the
* contraints, finder and parentMetaData.
* Should probably _not_ do a deep copy on finder.
*
* @return a copy of this object.
*/
public Object clone() {
PolicyReference clone = (PolicyReference)super.clone();
clone.reference = this.reference;
clone.policyType = this.policyType;
clone.constraints = this.constraints;
clone.finder = this.finder;
clone.parentMetaData = this.parentMetaData;
return clone;
}
/**
* Creates an instance of a <code>PolicyReference</code> object based on
* a DOM node.
*
* @deprecated As of 2.0 you should avoid using this method and should
* instead use the version that takes a
* <code>PolicyMetaData</code> instance. This method will
* only work for XACML 1.x policies.
*
* @param root the DOM root of a PolicyIdReference or a
* PolicySetIdReference XML type
* @param finder the <code>PolicyFinder</code> used to handle the reference
*
* @return The PolicyReference object.
*
* @exception ParsingException if the node is invalid
*/
public static PolicyReference getInstance(Node root, PolicyFinder finder)
throws ParsingException
{
return getInstance(root, finder, new PolicyMetaData());
}
/**
* Creates an instance of a <code>PolicyReference</code> object based on
* a DOM node.
*
* @param root the DOM root of a PolicyIdReference or a
* PolicySetIdReference XML type
* @param finder the <code>PolicyFinder</code> used to handle the reference
* @param metaData the meta-data associated with the containing policy
*
* @return The PolicyReference object.
*
* @exception ParsingException if the node is invalid
*/
public static PolicyReference getInstance(Node root, PolicyFinder finder,
PolicyMetaData metaData)
throws ParsingException
{
URI reference = null;
int policyType;
if (root.getNodeType() != Node.ELEMENT_NODE) {
throw new ParsingException("Cannot build a PolicyReference"
+ "with a: " + root.getClass().getName() +" XML node" );
}
// see what type of reference we are
String name = root.getLocalName();
if (name.equals("PolicyIdReference")) {
policyType = POLICY_REFERENCE;
} else if (name.equals("PolicySetIdReference")) {
policyType = POLICYSET_REFERENCE;
} else {
throw new ParsingException("Unknown reference type: " + name);
}
// next get the reference
try {
reference = new URI(root.getFirstChild().getNodeValue());
} catch (Exception e) {
throw new ParsingException("Error while parsing Reference", e);
}
// now get any constraints
NamedNodeMap map = root.getAttributes();
String versionConstraint = null;
String earlyConstraint = null;
String lateConstraint = null;
Node versionNode = map.getNamedItem("Version");
if (versionNode != null) {
versionConstraint = versionNode.getNodeValue();
}
Node earlyNode = map.getNamedItem("EarliestVersion");
if (earlyNode != null) {
earlyConstraint = earlyNode.getNodeValue();
}
Node lateNode = map.getNamedItem("LatestVersion");
if (lateNode != null) {
lateConstraint = lateNode.getNodeValue();
}
VersionConstraints constraints =
new VersionConstraints(versionConstraint, earlyConstraint,
lateConstraint);
// finally, create the reference
PolicyReference policyReference = new PolicyReference(
reference, policyType, constraints, finder, metaData);
policyReference.src = RuntimeInfo.getRuntimeInfo(policyReference, root, ELEMENT_TYPE.POLICY_REFERENCE);
//policyReference.setSourceLocator(RuntimeInfo.getRuntimeInfo(policyReference, root, ELEMENT_TYPE.POLICY_REFERENCE));
return policyReference;
}
/**
* Returns the refernce identitfier used to resolve the policy.
*
* @return the reference <code>URI</code>
*/
public URI getReference() {
return this.reference;
}
/**
* Returns the version constraints associated with this reference. This
* will never be null, though the constraints may be empty.
*
* @return the version constraints
*/
public VersionConstraints getConstraints() {
return this.constraints;
}
/**
* Returns whether this is a reference to a policy or to a policy set.
*
* @return the reference type, either <code>POLICY_REFERENCE</code>
* or <code>POLICYSET_REFERENCE</code>
*/
public int getReferenceType() {
return this.policyType;
}
/**
* Returns the id of this policy. If the policy is invalid or can't be
* retrieved, then a runtime exception is thrown.
*
* @return the policy id
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public URI getId() {
return resolvePolicy(null).getId();
}
/**
* Returns the version of this policy. If the policy is invalid or can't
* be retrieved, then a runtime exception is thrown.
*
* @return the policy version
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public String getVersion() {
return resolvePolicy(null).getVersion();
}
/**
* Returns the combining algorithm used by this policy. If the policy is
* invalid or can't be retrieved, then a runtime exception is thrown.
*
* @return the combining algorithm
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public CombiningAlgorithm getCombiningAlg() {
return resolvePolicy(null).getCombiningAlg();
}
/**
* Returns the given description of this policy or null if there is no
* description. If the policy is invalid or can't be retrieved, then a
* runtime exception is thrown.
*
* @return the description or null
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public String getDescription() {
return resolvePolicy(null).getDescription();
}
/**
* Returns the PolicyIssuer if present or null if it is the trusted issuer.
*
* @return the PolicyIssuer or null
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public PolicyIssuer getPolicyIssuer() {
return resolvePolicy(null).getPolicyIssuer();
}
/**
* Returns the target for this policy. If the policy is invalid or can't be
* retrieved, then a runtime exception is thrown.
*
* @return the policy's target
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public Target getTarget() {
return resolvePolicy(null).getTarget();
}
/**
* Returns the default version for this policy. If the policy is
* invalid or can't be retrieved, then a runtime exception is thrown.
*
* @return the policy's default version
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public String getDefaultVersion() {
return resolvePolicy(null).getDefaultVersion();
}
/**
* Returns the child policy nodes under this node in the policy tree. If
* the policy is invalid or can't be retrieved, then a runtime exception
* is thrown.
*
* @return the <code>List</code> of child policy nodes
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public List<PolicyTreeElement> getChildren() {
return resolvePolicy(null).getChildren();
}
/**
* Returns the child policy nodes and their associated parameters. If
* the policy is invalid or can't be retrieved, then a runtime exception
* is thrown.
*
* @return a <code>List</code> of <code>CombinerElement</code>s
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public List<CombinerElement> getChildElements() {
return resolvePolicy(null).getChildElements();
}
/**
* Returns the Set of obligations for this policy, which may be empty if
* there are no obligations. If the policy is invalid or can't be
* retrieved, then a runtime exception is thrown.
*
* @return the policy's obligations
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public Set<Obligation> getObligations() {
return resolvePolicy(null).getObligations();
}
/**
* Returns the meta-data associated with this policy. If the policy is
* invalid or can't be retrieved, then a runtime exception is thrown.
* Note that this is the meta-data for the referenced policy, not the
* meta-data for the parent policy (which is what gets provided to the
* constructors of this class).
*
* @return the policy's meta-data
*
* @throws ProcessingException if the referenced policy can't be retrieved
*/
public PolicyMetaData getMetaData() {
return resolvePolicy(null).getMetaData();
}
/**
* Given the input context sees whether or not the request matches this
* policy. This must be called by combining algorithms before they
* evaluate a policy. This is also used in the initial policy finding
* operation to determine which top-level policies might apply to the
* request. If the policy is invalid or can't be retrieved, then a
* runtime exception is thrown.
*
* @param context the representation of the request
*
* @return the result of trying to match the policy and the request
*/
public MatchResult match(EvaluationCtx context) {
try {
return resolvePolicy(context).match(context);
} catch (ProcessingException pe) {
// this means that we couldn't resolve the policy
ArrayList<String> code = new ArrayList<String>();
code.add(Status.STATUS_PROCESSING_ERROR);
Status status = new Status(code, "couldn't resolve policy ref");
MatchResult match = new MatchResult(MatchResult.INDETERMINATE,
status);
return match;
}
}
/**
* Private helper method that tried to resolve the policy
*/
private AbstractPolicy resolvePolicy(EvaluationCtx context) {
if ( referencedPolicy != null ) {
return referencedPolicy;
}
// see if this reference was setup with a finder
if (this.finder == null) {
logger.warn("PolicyReference with id "
+ this.reference.toString() + " was queried but "
+ "was not configured with a PolicyFinder");
throw new ProcessingException("couldn't find the policy with " +
"a null finder");
}
PolicyFinderResult pfr = this.finder.findPolicy(context,
this.reference,
this.policyType,
this.constraints,
this.parentMetaData);
if (pfr.notApplicable()) {
throw new ProcessingException("couldn't resolve the policy");
}
if (pfr.indeterminate()) {
throw new ProcessingException("error resolving the policy");
}
referencedPolicy = pfr.getPolicy();
return referencedPolicy;
}
/**
* Tries to evaluate the policy by calling the combining algorithm on
* the given policies or rules. The <code>match</code> method must always
* be called first, and must always return MATCH, before this method
* is called.
*
* @param context the representation of the request
*
* @return the result of evaluation
*/
public Result evaluate(EvaluationCtx context) {
try {
resolvePolicy(context);
} catch (ProcessingException pe) {
logger.fatal("Evaluation was called for PolicyReference with not resolved Policy: This should not happen as no target can have been matched!");
List<String> codes = new Vector<String>();
codes.add(Status.STATUS_PROCESSING_ERROR);
Status errorStatus = new Status(codes);
return new Result(Result.DECISION_INDETERMINATE, errorStatus, context);
}
return referencedPolicy.evaluate(context);
//
// // if there is no finder, then we return NotApplicable
// if (this.finder == null) {
// return new Result(Result.DECISION_NOT_APPLICABLE,
// context);
// }
// PolicyFinderResult pfr = this.finder.findPolicy(this.reference,
// this.policyType,
// this.constraints,
// this.parentMetaData);
//
// // if we found nothing, then we return NotApplicable
// if (pfr.notApplicable()) {
// return new Result(Result.DECISION_NOT_APPLICABLE, context);
// }
// // if there was an error, we return that status data
// if (pfr.indeterminate()) {
// return new Result(Result.DECISION_INDETERMINATE,
// pfr.getStatus(),
// context);
// }
// // we must have found a policy
// return pfr.getPolicy().evaluate(context);
}
/**
* Encodes this <code>PolicyReference</code> into its XML representation
* and writes this encoding to the given <code>OutputStream</code> with
* no indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName)
throws UnsupportedEncodingException {
encode(output, charsetName, new Indenter(0));
}
/**
* Encodes this <code>PolicyReference</code> into its XML representation
* and writes this encoding to the given <code>OutputStream</code> with
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
* @param indenter an object that creates indentation strings
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName,
Indenter indenter)
throws UnsupportedEncodingException {
PrintStream out;
if(charsetName == null) {
out = new PrintStream(output);
} else {
out = new PrintStream(output, false, charsetName);
}
String encoded = indenter.makeString();
if (this.policyType == POLICY_REFERENCE) {
out.println(encoded + "<PolicyIdReference xmlns=\""
+ getMetaData().getXACMLIdentifier() + "\""
+ encodeConstraints()
+ ">" + this.reference.toString()
+ "</PolicyIdReference>");
} else {
out.println(encoded + "<PolicySetIdReference"
+ encodeConstraints() + ">"
+ this.reference.toString()
+ "</PolicySetIdReference>");
}
}
/**
* Private helper method that encodes the variable constraints info. Note
* that if this is a pre-2.0 policy the constraints are always null, so
* nothing will be added here.
*/
private String encodeConstraints() {
String str = "";
VersionConstraints version = getConstraints();
String v = version.getVersionConstraint();
if (v != null) {
str += " Version=\"" + v + "\"";
}
String e = version.getEarliestConstraint();
if (e != null) {
str += " EarliestVersion=\"" + e + "\"";
}
String l = version.getLatestConstraint();
if (l != null) {
str += " LatestVersion=\"" + l + "\"";
}
return str;
}
}

View File

@ -0,0 +1,696 @@
/*
* @(#)PolicySet.java
*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.combine.CombinerElement;
import com.sun.xacml.combine.CombinerParameter;
import com.sun.xacml.combine.PolicyCombinerElement;
import com.sun.xacml.combine.PolicyCombiningAlgorithm;
import com.sun.xacml.ctx.PolicyIssuer;
import com.sun.xacml.debug.RuntimeInfo;
import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE;
import com.sun.xacml.finder.PolicyFinder;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Represents one of the two top-level constructs in XACML, the PolicySetType.
* This can contain other policies and policy sets, and can also contain
* URIs that point to policies and policy sets.
*
* @since 1.0
* @author Seth Proctor
* @author Ludwig Seitz
*/
public class PolicySet extends AbstractPolicy {
//private static final Logger logger = Logger.getLogger(PolicySet.class);
/**
* Creates a new <code>PolicySet</code> with only the required elements.
*
* @param id the policy set identifier
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param target the <code>Target</code> for this set
*/
public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg,
Target target) {
this(id, null, null, combiningAlg, null, null, target, null, null,
null);
}
/**
* Creates a new <code>PolicySet</code> with only the required elements.
*
* @param id the policy set identifier
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param issuer the <code>PolicyIssuer</code> for this set or null if
* it is the trusted issuer
* @param target the <code>Target</code> for this set
*/
public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg,
PolicyIssuer issuer, Target target) {
this(id, null, null, combiningAlg, null, issuer, target, null, null,
null);
}
/**
* Creates a new <code>PolicySet</code> with only the required elements,
* plus some policies.
*
* @param id the policy set identifier
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param target the <code>Target</code> for this set
* @param policies a list of <code>AbstractPolicy</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of policies
* contains an object that is not an
* <code>AbstractPolicy</code>
*/
public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg,
Target target, List<PolicyTreeElement> policies) {
this(id, null, null, combiningAlg, null, null, target, policies,
null, null);
}
/**
* Creates a new <code>PolicySet</code> with only the required elements,
* plus some policies.
*
* @param id the policy set identifier
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param issuer the <code>PolicyIssuer</code> for this set or null if
* it is the trusted issuer
* @param target the <code>Target</code> for this set
* @param policies a list of <code>AbstractPolicy</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of policies
* contains an object that is not an
* <code>AbstractPolicy</code>
*/
public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg,
PolicyIssuer issuer, Target target, List<PolicyTreeElement> policies) {
this(id, null, null, combiningAlg, null, issuer, target, policies,
null, null);
}
/**
* Creates a new <code>PolicySet</code> with the required elements plus
* some policies and a String description.
*
* @param id the policy set identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param description a <code>String</code> describing the policy
* @param target the <code>Target</code> for this set
* @param policies a list of <code>AbstractPolicy</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of policies
* contains an object that is not an
* <code>AbstractPolicy</code>
*/
public PolicySet(URI id, String version, String xacmlVersion,
PolicyCombiningAlgorithm combiningAlg,
String description, Target target, List<PolicyTreeElement> policies) {
this(id, version, xacmlVersion, combiningAlg, description, null,
target, policies, null, null);
}
/**
* Creates a new <code>PolicySet</code> with the required elements plus
* some policies and a String description.
*
* @param id the policy set identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param description a <code>String</code> describing the policy
* @param issuer the <code>PolicyIssuer</code> for this set or null if
* it is the trusted issuer
* @param target the <code>Target</code> for this set
* @param policies a list of <code>AbstractPolicy</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of policies
* contains an object that is not an
* <code>AbstractPolicy</code>
*/
public PolicySet(URI id, String version, String xacmlVersion,
PolicyCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer, Target target,
List<PolicyTreeElement> policies) {
this(id, version, xacmlVersion, combiningAlg, description, issuer,
target, policies, null, null);
}
/**
* Creates a new <code>PolicySet</code> with the required elements plus
* some policies, a String description, and policy defaults.
*
* @param id the policy set identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param description a <code>String</code> describing the policy
* @param target the <code>Target</code> for this set
* @param policies a list of <code>AbstractPolicy</code> objects
* @param defaultVersion the XPath version to use
*
* @throws IllegalArgumentException if the <code>List</code> of policies
* contains an object that is not an
* <code>AbstractPolicy</code>
*/
public PolicySet(URI id, String version, String xacmlVersion,
PolicyCombiningAlgorithm combiningAlg,
String description, Target target, List<PolicyTreeElement> policies,
String defaultVersion) {
this(id, version, xacmlVersion, combiningAlg, description, null,
target, policies, defaultVersion, null);
}
/**
* Creates a new <code>PolicySet</code> with the required elements plus
* some policies, a String description, and policy defaults.
*
* @param id the policy set identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param description a <code>String</code> describing the policy
* @param issuer the <code>PolicyIssuer</code> for this set or null if
* it is the trusted issuer
* @param target the <code>Target</code> for this set
* @param policies a list of <code>AbstractPolicy</code> objects
* @param defaultVersion the XPath version to use
*
* @throws IllegalArgumentException if the <code>List</code> of policies
* contains an object that is not an
* <code>AbstractPolicy</code>
*/
public PolicySet(URI id, String version, String xacmlVersion,
PolicyCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer,
Target target, List<PolicyTreeElement> policies, String defaultVersion) {
this(id, version, xacmlVersion, combiningAlg, description, issuer,
target, policies, defaultVersion, null);
}
/**
* Creates a new <code>PolicySet</code> with the required elements plus
* some policies, a String description, policy defaults, and obligations.
*
* @param id the policy set identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param description a <code>String</code> describing the policy
* @param target the <code>Target</code> for this set
* @param policies a list of <code>AbstractPolicy</code> objects
* @param defaultVersion the XPath version to use
* @param obligations a set of <code>Obligation</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of policies
* contains an object that is not an
* <code>AbstractPolicy</code>
*/
public PolicySet(URI id, String version, String xacmlVersion,
PolicyCombiningAlgorithm combiningAlg,
String description, Target target, List<CombinerElement> policies,
String defaultVersion, Set<Obligation> obligations) {
this(id, version, xacmlVersion, combiningAlg, description, null,
target, policies, defaultVersion, obligations, null, -1);
}
/**
* Creates a new <code>PolicySet</code> with the required elements plus
* some policies, a String description, policy defaults, and obligations.
*
* @param id the policy set identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* policies in this set
* @param description a <code>String</code> describing the policy
* @param issuer the <code>PolicyIssuer</code> for this set or null if
* it is the trusted issuer
* @param target the <code>Target</code> for this set
* @param policies a list of <code>AbstractPolicy</code> objects
* @param defaultVersion the XPath version to use
* @param obligations a set of <code>Obligation</code> objects
*
* @throws IllegalArgumentException if the <code>List</code> of policies
* contains an object that is not an
* <code>AbstractPolicy</code>
*/
public PolicySet(URI id, String version, String xacmlVersion,
PolicyCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer,
Target target, List<PolicyTreeElement> policies, String defaultVersion,
Set<Obligation> obligations) {
super(id, version, xacmlVersion, combiningAlg, description, issuer,
target, defaultVersion, obligations, null,
Constants.MAX_DELEGATION_DEPTH_UNDEFINED);
List<CombinerElement> list = null;
// check that the list contains only AbstractPolicy objects
if (policies != null) {
list = new ArrayList<CombinerElement>();
Iterator<PolicyTreeElement> it = policies.iterator();
while (it.hasNext()) {
Object o = it.next();
if (! (o instanceof AbstractPolicy)) {
throw new IllegalArgumentException("non-AbstractPolicy " +
"in policies");
}
list.add(new PolicyCombinerElement((AbstractPolicy)o));
}
}
setChildren(list);
}
/**
* Creates a new <code>PolicySet</code> with the required and optional
* elements. If you need to provide combining algorithm parameters, you
* need to use this constructor. Note that unlike the other constructors
* in this class, the policies list is actually a list of
* <code>CombinerElement</code>s used to match a policy with any
* combiner parameters it may have.
*
* @param id the policy set identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy or
* null if there is no description
* @param target the <code>Target</code> for this policy
* @param policyElements a list of <code>CombinerElement</code> objects or
* null if there are no policies
* @param defaultVersion the XPath version to use or null if there is
* no default version
* @param obligations a set of <code>Obligations</code> objects or null
* if there are no obligations
* @param parameters the <code>List</code> of
* <code>CombinerParameter</code>s provided for general
* use by the combining algorithm
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public PolicySet(URI id, String version, String xacmlVersion,
PolicyCombiningAlgorithm combiningAlg,
String description, Target target,
List<CombinerElement> policyElements, String defaultVersion,
Set<Obligation> obligations, List<CombinerParameter> parameters) {
this(id, version, xacmlVersion, combiningAlg, description, null, target,
policyElements, defaultVersion, obligations, parameters,
Constants.MAX_DELEGATION_DEPTH_UNDEFINED);
}
/**
* Creates a new <code>PolicySet</code> with the required and optional
* elements. If you need to provide combining algorithm parameters, you
* need to use this constructor. Note that unlike the other constructors
* in this class, the policies list is actually a list of
* <code>CombinerElement</code>s used to match a policy with any
* combiner parameters it may have.
*
* @param id the policy set identifier
* @param version the policy version or null for the default (this is
* always null for pre-2.0 policies)
* @param xacmlVersion the xacml version identifier.
* @param combiningAlg the <code>CombiningAlgorithm</code> used on the
* rules in this set
* @param description a <code>String</code> describing the policy or
* null if there is no description
* @param issuer the <code>PolicyIssuer</code> for this set or null if
* it is the trusted issuer
* @param target the <code>Target</code> for this policy
* @param policyElements a list of <code>CombinerElement</code> objects or
* null if there are no policies
* @param defaultVersion the XPath version to use or null if there is
* no default version
* @param obligations a set of <code>Obligations</code> objects or null
* if there are no obligations
* @param parameters the <code>List</code> of
* <code>CombinerParameter</code>s provided for general
* use by the combining algorithm
* @param maxDelegationDepth the maximum delegation depth authorised
* by this policy set.
*
* @throws IllegalArgumentException if the <code>List</code> of rules
* contains an object that is not a
* <code>Rule</code>
*/
public PolicySet(URI id, String version, String xacmlVersion,
PolicyCombiningAlgorithm combiningAlg,
String description, PolicyIssuer issuer,
Target target, List<CombinerElement> policyElements,
String defaultVersion, Set<Obligation> obligations,
List<CombinerParameter> parameters, int maxDelegationDepth) {
super(id, version, xacmlVersion, combiningAlg, description, issuer,
target, defaultVersion, obligations, parameters,
maxDelegationDepth);
// check that the list contains only CombinerElements
if (policyElements != null) {
Iterator<CombinerElement> it = policyElements.iterator();
while (it.hasNext()) {
CombinerElement o = it.next();
if (! (o instanceof PolicyCombinerElement)) {
throw new IllegalArgumentException("non-AbstractPolicy " +
"in policies");
}
}
}
setChildren(policyElements);
}
/**
* Creates a new PolicySet based on the given root node. This is
* private since every class is supposed to use a getInstance() method
* to construct from a Node, but since we want some common code in the
* parent class, we need this functionality in a constructor.
*/
private PolicySet(Node root, PolicyFinder finder)
throws ParsingException {
super(root, "PolicySet", "PolicyCombiningAlgId");
List<AbstractPolicy> policies = new ArrayList<AbstractPolicy>();
Map<String, List<CombinerParameter>> policyParameters = new HashMap<String, List<CombinerParameter>>();
Map<String, List<CombinerParameter>> policySetParameters = new HashMap<String, List<CombinerParameter>>();
PolicyMetaData metaData = getMetaData();
super.src = RuntimeInfo.getRuntimeInfo(this, root, ELEMENT_TYPE.POLICY_SET);
// collect the PolicySet-specific elements
NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
String name = child.getLocalName();
if (name.equals("PolicySet")) {
policies.add(PolicySet.getInstance(child, finder));
} else if (name.equals("Policy")) {
policies.add(Policy.getInstance(child));
} else if (name.equals("PolicySetIdReference")) {
policies.add(PolicyReference.getInstance(child, finder,
metaData));
} else if (name.equals("PolicyIdReference")) {
policies.add(PolicyReference.getInstance(child, finder,
metaData));
} else if (name.equals("PolicyCombinerParameters")) {
paramaterHelper(policyParameters, child, "Policy");
} else if (name.equals("PolicySetCombinerParameters")) {
paramaterHelper(policySetParameters, child, "PolicySet");
}
}
}
// now make sure that we can match up any parameters we may have
// found to a cooresponding Policy or PolicySet...
List<CombinerElement> elements = new ArrayList<CombinerElement>();
// right now we have to go though each policy and based on several
// possible cases figure out what paranmeters might apply...but
// there should be a better way to do this
for ( AbstractPolicy policy : policies ) {
List<CombinerParameter> list = null;
if (policy instanceof Policy) {
list = policyParameters.remove(policy.getId().toString());
} else if (policy instanceof PolicySet) {
list = policySetParameters.remove(policy.getId().toString());
} else {
PolicyReference ref = (PolicyReference)policy;
String id = ref.getReference().toString();
if (ref.getReferenceType() ==
PolicyReference.POLICY_REFERENCE) {
list = policyParameters.remove(id);
} else {
list = policySetParameters.remove(id);
}
}
elements.add(new PolicyCombinerElement(policy, list));
}
// ...and that there aren't extra parameters
if (! policyParameters.isEmpty()) {
throw new ParsingException("Unmatched parameters in Policy");
}
if (! policySetParameters.isEmpty()) {
throw new ParsingException("Unmatched parameters in PolicySet");
}
// finally, set the list of Rules
setChildren(elements);
}
/**
* The clone method.
* FIXME: caution this is no deep copy in the superclass.
*
* @return a copy of this object.
*/
public Object clone() {
PolicySet clone = (PolicySet)super.clone();
clone.setChildren(this.getChildElements());
return clone;
}
/**
* Private helper method that handles parsing a collection of
* parameters
*/
private void paramaterHelper(Map<String, List<CombinerParameter>> parameters, Node root,
String prefix) throws ParsingException {
String ref = null;
if (root.getAttributes().getNamedItem(prefix + "IdRef") != null) {
ref = root.getAttributes().getNamedItem(prefix + "IdRef")
.getNodeValue();
} else {
throw new ParsingException("Required xml-attribute: "
+ prefix + "IdRef not found");
}
if (parameters.containsKey(ref)) {
List<CombinerParameter> list = parameters.get(ref);
parseParameters(list, root);
} else {
List<CombinerParameter> list = new ArrayList<CombinerParameter>();
parseParameters(list, root);
parameters.put(ref, list);
}
}
/**
* Private helper method that handles parsing a single parameter.
*/
private void parseParameters(List<CombinerParameter> parameters, Node root)
throws ParsingException
{
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE
&& node.getLocalName().equals("CombinerParameter")) {
parameters.add(CombinerParameter.getInstance(node));
}
}
}
/**
* Creates an instance of a <code>PolicySet</code> object based on a
* DOM node. The node must be the root of PolicySetType XML object,
* otherwise an exception is thrown. This <code>PolicySet</code> will
* not support references because it has no <code>PolicyFinder</code>.
*
* @param root the DOM root of a PolicySetType XML type
*
* @return The PolicySet object.
*
* @throws ParsingException if the PolicySetType is invalid
*/
public static PolicySet getInstance(Node root)
throws ParsingException {
return getInstance(root, null);
}
/**
* Creates an instance of a <code>PolicySet</code> object based on a
* DOM node. The node must be the root of PolicySetType XML object,
* otherwise an exception is thrown. The finder is used to handle
* policy references.
*
* @param root the DOM root of a PolicySetType XML type
* @param finder the <code>PolicyFinder</code> used to handle references
*
* @return The PolicySet object.
*
* @throws ParsingException if the PolicySetType is invalid
*/
public static PolicySet getInstance(Node root, PolicyFinder finder)
throws ParsingException {
// first off, check that it's the right kind of node
if (root.getNodeType() != Node.ELEMENT_NODE
&& ! root.getLocalName().equals("PolicySet")) {
throw new ParsingException("Cannot create PolicySet from root of"
+ " type " + root.getLocalName());
}
return new PolicySet(root, finder);
}
/**
* Encodes this <code>PolicySet</code> into its XML representation and
* writes this encoding to the given <code>OutputStream</code> with no
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName)
throws UnsupportedEncodingException {
encode(output, charsetName, new Indenter(0));
}
/**
* Encodes this <code>PolicySet</code> into its XML representation and
* writes this encoding to the given <code>OutputStream</code> with
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
* @param indenter an object that creates indentation strings
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName,
Indenter indenter)
throws UnsupportedEncodingException {
PrintStream out;
if(charsetName == null) {
out = new PrintStream(output);
} else {
out = new PrintStream(output, false, charsetName);
}
String indent = indenter.makeString();
out.print(indent + "<PolicySet xmlns=\""
+ getMetaData().getXACMLIdentifier()
+ "\" PolicySetId=\"" + getId().toString()
+ "\" PolicyCombiningAlgId=\""
+ getCombiningAlg().getIdentifier().toString()
+ "\"");
if (getMaxDelegationDepth()
!= Constants.MAX_DELEGATION_DEPTH_UNDEFINED) {
out.println("MaxDelegationDepth=\"" + getMaxDelegationDepth()
+ "\">");
} else {
out.println(">");
}
indenter.in();
String nextIndent = indenter.makeString();
String description = getDescription();
if (description != null) {
out.println(nextIndent + "<Description>" + description +
"</Description>");
}
encodePolicyIssuer(output, charsetName, indenter);
String version = getDefaultVersion();
if (version != null) {
out.println("<PolicySetDefaults><XPathVersion>" + version +
"</XPathVersion></PolicySetDefaults>");
}
getTarget().encode(output, charsetName, indenter);
encodeCommonElements(output, charsetName, indenter);
indenter.out();
out.println(indent + "</PolicySet>");
}
}

View File

@ -0,0 +1,149 @@
/*
* @(#)PolicyTreeElement.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.debug.Locatable;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.Collections;
import java.util.List;
/**
* This represents a single node in a policy tree. A node is either a policy
* set, a policy, or a rule. This interface is used to interact with these
* node types in a general way. Note that rules are leaf nodes in a policy
* tree as they never contain children.
*
* @since 1.1
* @author seth proctor
*/
public interface PolicyTreeElement extends Locatable
{
public static List<PolicyTreeElement> EMPTY_LIST = Collections.<PolicyTreeElement>emptyList();
/**
* Returns the <code>List</code> of <code>PolicyTreeElement</code> objects
* that are the children of this node. If this node has no children then
* this list is empty. The children are returned as a <code>List</code>
* instead of some unordered collection because in cases like combining
* or evaluation the order is often important.
*
* @return the non-null <code>List</code> of children of this node
*/
public List<PolicyTreeElement> getChildren();
/**
* Returns the given description of this element or null if
* there is no description
*
* @return the description or null
*/
public String getDescription();
/**
* Returns the id of this element
*
* @return the element's identifier
*/
public URI getId();
/**
* Returns the target for this element or null if there
* is no target
*
* @return the element's target
*/
public Target getTarget();
/**
* Given the input context sees whether or not the request matches this
* element's target. The rules for matching are different depending on
* the type of element being matched.
*
* @param context the representation of the request
*
* @return the result of trying to match this element and the request
*/
public MatchResult match(EvaluationCtx context);
/**
* Evaluates this element in the policy tree, and therefore all elements
* underneath this element. The rules for evaluation are different
* depending on the type of element being evaluated.
*
* @param context the representation of the request we're evaluating
*
* @return the result of the evaluation
*/
public Result evaluate(EvaluationCtx context);
/**
* Encodes this element into its XML representation and writes
* this encoding to the given <code>OutputStream</code> with no
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
*/
public void encode(OutputStream output, String charsetName)
throws UnsupportedEncodingException;
/**
* Encodes this element into its XML representation and writes
* this encoding to the given <code>OutputStream</code> with
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform default character set
* will be used.
* @param indenter an object that creates indentation strings
*/
public void encode(OutputStream output, String charsetName,
Indenter indenter)
throws UnsupportedEncodingException;
}

View File

@ -0,0 +1,107 @@
/*
* @(#)ProcessingException.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
/**
* Runtime exception that's thrown if any unexpected error occurs. This could
* appear, for example, if you try to match a referernced policy that can't
* be resolved.
*
* @since 1.0
* @author Seth Proctor
*/
public class ProcessingException extends RuntimeException
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Constructs a new <code>ProcessingException</code> with no message
* or cause.
*/
public ProcessingException() {
//Processing exception with no message or cause
}
/**
* Constructs a new <code>ProcessingException</code> with a message,
* but no cause. The message is saved for later retrieval by the
* {@link java.lang.Throwable#getMessage() Throwable.getMessage()}
* method.
*
* @param message the detail message (<code>null</code> if nonexistent
* or unknown)
*/
public ProcessingException(String message) {
super(message);
}
/**
* Constructs a new <code>ProcessingException</code> with a cause,
* but no message. The cause is saved for later retrieval by the
* {@link java.lang.Throwable#getCause() Throwable.getCause()}
* method.
*
* @param cause the cause (<code>null</code> if nonexistent
* or unknown)
*/
public ProcessingException(Throwable cause) {
super(cause);
}
/**
* Constructs a new <code>ProcessingException</code> with a message
* and a cause. The message and cause are saved for later retrieval
* by the
* {@link java.lang.Throwable#getMessage() Throwable.getMessage()} and
* {@link java.lang.Throwable#getCause() Throwable.getCause()}
* methods.
*
* @param message the detail message (<code>null</code> if nonexistent
* or unknown)
* @param cause the cause (<code>null</code> if nonexistent
* or unknown)
*/
public ProcessingException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,509 @@
/*
* @(#)Rule.java
*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml;
import com.sun.xacml.attr.BooleanAttribute;
import com.sun.xacml.cond.Apply;
import com.sun.xacml.cond.Condition;
import com.sun.xacml.cond.EvaluationResult;
import com.sun.xacml.cond.VariableManager;
import com.sun.xacml.ctx.Result;
import com.sun.xacml.ctx.Status;
import com.sun.xacml.debug.RuntimeInfo;
import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Represents the RuleType XACML type. This has a target for matching, and
* encapsulates the condition and all sub-operations that make up the heart
* of most policies.
*
* @since 1.0
* @author Seth Proctor
*/
public class Rule implements PolicyTreeElement
{
// the attributes associated with this Rule
private URI idAttr;
private int effectAttr;
// the elements in the rule, each of which is optional
private String description = null;
private Target target = null;
private Condition condition = null;
private RuntimeInfo src = null;
/**
* Creates a new <code>Rule</code> object for XACML 1.x and 2.0.
*
* @param id the rule's identifier
* @param effect the effect to return if the rule applies (either
* Pemit or Deny) as specified in <code>Result</code>
* @param description a textual description, or null
* @param target the rule's target, or null if the target is to be
* inherited from the encompassing policy
* @param condition the rule's condition, or null if there is none
*/
public Rule(URI id, int effect, String description, Target target,
Condition condition) {
this.idAttr = id;
this.effectAttr = effect;
this.description = description;
this.target = target;
this.condition = condition;
}
/**
* Creates a new <code>Rule</code> object for XACML 1.x and 2.0.
*
* @param id the rule's identifier
* @param effect the effect to return if the rule applies (either
* Pemit or Deny) as specified in <code>Result</code>
* @param description a textual description, or null
* @param target the rule's target, or null if the target is to be
* inherited from the encompassing policy
* @param condition the rule's condition, or null if there is none
*/
public Rule(URI id, int effect, String description, Target target,
Condition condition, RuntimeInfo src) {
this.idAttr = id;
this.effectAttr = effect;
this.description = description;
this.target = target;
this.condition = condition;
this.src = src;
}
/**
* Creates a new <code>Rule</code> object for XACML 1.x only.
*
* @deprecated As of 2.0 you should use the Constructor that accepts
* the new <code>Condition</code> class.
*
* @param id the rule's identifier
* @param effect the effect to return if the rule applies (either
* Pemit or Deny) as specified in <code>Result</code>
* @param description a textual description, or null
* @param target the rule's target, or null if the target is to be
* inherited from the encompassing policy
* @param condition the rule's condition, or null if there is none
*/
public Rule(URI id, int effect, String description, Target target,
Apply condition) {
this.idAttr = id;
this.effectAttr = effect;
this.description = description;
this.target = target;
this.condition = new Condition(condition.getFunction(),
condition.getChildren());
}
/**
* Returns a new instance of the <code>Rule</code> class based on a
* DOM node. The node must be the root of an XML RuleType.
*
* @deprecated As of 2.0 you should avoid using this method and should
* instead use the version that takes a
* <code>PolicyMetaData</code> instance. This method will
* only work for XACML 1.x policies.
*
* @param root the DOM root of a RuleType XML type
* @param xpathVersion the XPath version to use in any selectors or XPath
* functions, or null if this is unspecified (ie, not
* supplied in the defaults section of the policy)
*
* @return The Rule object.
*
* @throws ParsingException if the RuleType is invalid
*/
public static Rule getInstance(Node root, String xpathVersion)
throws ParsingException {
return getInstance(root,
new PolicyMetaData(
Constants.XACML_1_0_IDENTIFIER,
xpathVersion),
null);
}
/**
* Returns a new instance of the <code>Rule</code> class based on a
* DOM node. The node must be the root of an XML RuleType.
*
* @param root the DOM root of a RuleType XML type
* @param metaData the meta-data associated with this Rule's policy
* @param manager the <code>VariableManager</code> used to connect
* <code>VariableReference</code>s to their cooresponding
* <code>VariableDefinition<code>s
*
* @return The Rule object.
*
* @throws ParsingException if the RuleType is invalid
*/
public static Rule getInstance(Node root, PolicyMetaData metaData,
VariableManager manager) throws ParsingException {
RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.RULE);
//check if we really got a rule
if (root.getNodeType() != Node.ELEMENT_NODE) {
throw new ParsingException("Can't create a Rule from"
+ " a node that is not an element-node"
+ (src != null ? src.getLocationMsgForError() : ""));
}
if (!root.getLocalName().equals("Rule")) {
throw new ParsingException("Can't create a Rule from a "
+ root.getLocalName() + " element"
+ (src != null ? src.getLocationMsgForError() : ""));
}
URI id = null;
int effect = 0;
String description = null;
Target target = null;
Condition condition = null;
// first, get the attributes
NamedNodeMap attrs = root.getAttributes();
try {
// get the two required attrs...
id = new URI(attrs.getNamedItem("RuleId").getNodeValue());
} catch (Exception e) {
throw new ParsingException("Error parsing required attribute " +
"RuleId in a Rule"
+ (src != null ? src.getLocationMsgForError() : ""), e);
}
String str = null;
if (attrs.getNamedItem("Effect") != null) {
str = attrs.getNamedItem("Effect").getNodeValue();
} else {
throw new ParsingException("Required attribute Effect missing"
+ "while parsing a Rule"
+ (src != null ? src.getLocationMsgForError() : ""));
}
if (str.equals(Result.PERMIT)) {
effect = Result.DECISION_PERMIT;
} else if (str.equals(Result.DENY)) {
effect = Result.DECISION_DENY;
} else {
throw new ParsingException("Invalid Effect: " + effect
+ (src != null ? src.getLocationMsgForError() : ""));
}
// next, get the elements
NodeList children = root.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
String cname = child.getLocalName();
if (cname.equals("Description")) {
description = child.getFirstChild().getNodeValue();
} else if (cname.equals("Target")) {
target = Target.getInstance(child, metaData);
} else if (cname.equals("Condition")) {
condition
= Condition.getInstance(child, metaData, manager);
} else {
throw new ParsingException("Found invalid element: "
+ cname + " in Rule " + id
+ (src != null ? src.getLocationMsgForError() : ""));
}
}
}
Rule rule = new Rule(id, effect, description, target, condition, src);
if ( src != null ) {
src.setXACMLObject(rule);
}
return rule;
}
/**
* Returns the effect that this <code>Rule</code> will return from
* the evaluate method (Permit or Deny) if the request applies.
*
* @return a decision effect, as defined in <code>Result</code>
*/
public int getEffect() {
return this.effectAttr;
}
/**
* Returns the id of this <code>Rule</code>
*
* @return the rule id
*/
public URI getId() {
return this.idAttr;
}
/**
* Returns the given description of this <code>Rule</code> or null if
* there is no description
*
* @return the description or null
*/
public String getDescription() {
return this.description;
}
/**
* Returns the target for this <code>Rule</code> or null if there
* is no target
*
* @return the rule's target
*/
public Target getTarget() {
return this.target;
}
/**
* Since a rule is always a leaf in a policy tree because it can have
* no children, this always returns an empty <code>List</code>.
*
* @return a <code>List</code> with no elements
*/
public List<PolicyTreeElement> getChildren() {
return PolicyTreeElement.EMPTY_LIST;
}
/**
* Returns the condition for this <code>Rule</code> or null if there
* is no condition
*
* @return the rule's condition
*/
public Condition getCondition() {
return this.condition;
}
/**
* Given the input context sees whether or not the request matches this
* <code>Rule</code>'s <code>Target</code>. Note that unlike the matching
* done by the <code>evaluate</code> method, if the <code>Target</code>
* is missing than this will return Indeterminate. This lets you write
* your own custom matching routines for rules but lets evaluation
* proceed normally.
*
* @param context the representation of the request
*
* @return the result of trying to match this rule and the request
*/
public MatchResult match(EvaluationCtx context) {
if (this.target == null) {
ArrayList<String> code = new ArrayList<String>();
code.add(Status.STATUS_PROCESSING_ERROR);
Status status = new Status(code, "no target available for " +
"matching a rule");
return new MatchResult(MatchResult.INDETERMINATE, status);
}
return this.target.match(context);
}
/**
* Evaluates the rule against the supplied context. This will check that
* the target matches, and then try to evaluate the condition. If the
* target and condition apply, then the rule's effect is returned in
* the result.
* <p>
* Note that rules are not required to have targets. If no target is
* specified, then the rule inherits its parent's target. In the event
* that this <code>Rule</code> has no <code>Target</code> then the
* match is assumed to be true, since evaluating a policy tree to this
* level required the parent's target to match.
*
* @param context the representation of the request we're evaluating
*
* @return the result of the evaluation
*/
public Result evaluate(EvaluationCtx context) {
context.newEvent(this);
// If the Target is null then it's supposed to inherit from the
// parent policy, so we skip the matching step assuming we wouldn't
// be here unless the parent matched
if (this.target != null) {
MatchResult match = match(context);
int result = match.getResult();
// if the target didn't match, then this Rule doesn't apply
if (result == MatchResult.NO_MATCH) {
Result evalResult = new Result(Result.DECISION_NOT_APPLICABLE,
context);
context.closeCurrentEvent(evalResult);
return evalResult;
}
// if the target was indeterminate, we can't go on
if (result == MatchResult.INDETERMINATE) {
Result evalResult = new Result(Result.DECISION_INDETERMINATE,
match.getStatus(),
context);
context.closeCurrentEvent(evalResult);
return evalResult;
}
}
// if there's no condition, then we just return the effect...
if (this.condition == null) {
Result evalResult = new Result(this.effectAttr,
context);
context.closeCurrentEvent(evalResult);
return evalResult;
}
// ...otherwise we evaluate the condition
EvaluationResult result = this.condition.evaluate(context);
if (result.indeterminate()) {
// if it was INDETERMINATE, then that's what we return
Result evalResult = new Result(Result.DECISION_INDETERMINATE,
result.getStatus(),
context);
context.closeCurrentEvent(evalResult);
return evalResult;
}
// otherwise we return the effect on true, and NA on false
BooleanAttribute bool =
(BooleanAttribute)(result.getAttributeValue());
if (bool.getValue()) {
Result evalResult = new Result(this.effectAttr,
context);
context.closeCurrentEvent(evalResult);
return evalResult;
}
Result evalResult = new Result(Result.DECISION_NOT_APPLICABLE,
context);
context.closeCurrentEvent(evalResult);
return evalResult;
}
/**
* Encodes this <code>Rule</code> into its XML representation and writes
* this encoding to the given <code>OutputStream</code> with no
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName)
throws UnsupportedEncodingException {
encode(output, charsetName, new Indenter(0));
}
/**
* Encodes this <code>Rule</code> into its XML representation and writes
* this encoding to the given <code>OutputStream</code> with
* indentation.
*
* @param output a stream into which the XML-encoded data is written
* @param charsetName the character set to use in encoding of strings.
* This may be null in which case the platform
* default character set will be used.
* @param indenter an object that creates indentation strings
*
* @throws UnsupportedEncodingException
*/
public void encode(OutputStream output, String charsetName,
Indenter indenter)
throws UnsupportedEncodingException {
PrintStream out;
if(charsetName == null) {
out = new PrintStream(output);
} else {
out = new PrintStream(output, false, charsetName);
}
String indent = indenter.makeString();
out.print(indent + "<Rule RuleId=\"" + this.idAttr.toString()
+ "\" Effect=\"" + Result.DECISIONS.get(this.effectAttr)
+ "\"");
if ((this.description != null) || (this.target != null)
|| (this.condition != null)) {
// there is some content in the Rule
out.println(">");
indenter.in();
String nextIndent = indenter.makeString();
if (this.description != null) {
out.println(nextIndent + "<Description>" + this.description
+ "</Description>");
}
if (this.target != null) {
this.target.encode(output, charsetName, indenter);
}
if (this.condition != null) {
this.condition.encode(output, charsetName, indenter);
}
indenter.out();
out.println(indent + "</Rule>");
} else {
// the Rule is empty, so close the tag and we're done
out.println("/>");
}
}
public RuntimeInfo getRuntimeInfo() {
return this.src;
}
}

View File

@ -0,0 +1,390 @@
/*
* @(#)Target.java
*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.